* Patches by Xianghua Xiao, 15 Oct 2003:
- Added Motorola CPU 8540/8560 support (cpu/85xx) - Added Motorola MPC8540ADS board support (board/mpc8540ads) - Added Motorola MPC8560ADS board support (board/mpc8560ads) * Minor code cleanup
This commit is contained in:
@@ -157,14 +157,14 @@ static void pkt_print (struct usb_device * dev, unsigned long pipe, void * buffe
|
||||
|
||||
dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d/%d stat:%#lx",
|
||||
str,
|
||||
sohci_get_current_frame_number (dev),
|
||||
usb_pipedevice (pipe),
|
||||
usb_pipeendpoint (pipe),
|
||||
usb_pipeout (pipe)? 'O': 'I',
|
||||
usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"):
|
||||
(usb_pipecontrol (pipe)? "CTRL": "BULK"),
|
||||
purb->actual_length,
|
||||
transfer_len, dev->status);
|
||||
sohci_get_current_frame_number (dev),
|
||||
usb_pipedevice (pipe),
|
||||
usb_pipeendpoint (pipe),
|
||||
usb_pipeout (pipe)? 'O': 'I',
|
||||
usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"):
|
||||
(usb_pipecontrol (pipe)? "CTRL": "BULK"),
|
||||
purb->actual_length,
|
||||
transfer_len, dev->status);
|
||||
#ifdef OHCI_VERBOSE_DEBUG
|
||||
if (!small) {
|
||||
int i, len;
|
||||
@@ -585,7 +585,7 @@ static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe)
|
||||
|
||||
if (ed->state == ED_NEW) {
|
||||
ed->hwINFO = m32_swap (OHCI_ED_SKIP); /* skip ed */
|
||||
/* dummy td; end of td list for ed */
|
||||
/* dummy td; end of td list for ed */
|
||||
td = td_alloc (usb_dev);
|
||||
ed->hwTailP = m32_swap (td);
|
||||
ed->hwHeadP = ed->hwTailP;
|
||||
@@ -669,13 +669,13 @@ static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buf
|
||||
void *data;
|
||||
int cnt = 0;
|
||||
__u32 info = 0;
|
||||
unsigned int toggle = 0;
|
||||
unsigned int toggle = 0;
|
||||
|
||||
/* OHCI handles the DATA-toggles itself, we just use the USB-toggle bits for reseting */
|
||||
if(usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) {
|
||||
toggle = TD_T_TOGGLE;
|
||||
if(usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) {
|
||||
toggle = TD_T_TOGGLE;
|
||||
} else {
|
||||
toggle = TD_T_DATA0;
|
||||
toggle = TD_T_DATA0;
|
||||
usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 1);
|
||||
}
|
||||
urb->td_cnt = 0;
|
||||
@@ -731,11 +731,11 @@ static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buf
|
||||
static void dl_transfer_length(td_t * td)
|
||||
{
|
||||
__u32 tdINFO, tdBE, tdCBP;
|
||||
urb_priv_t *lurb_priv = &urb_priv;
|
||||
urb_priv_t *lurb_priv = &urb_priv;
|
||||
|
||||
tdINFO = m32_swap (td->hwINFO);
|
||||
tdBE = m32_swap (td->hwBE);
|
||||
tdCBP = m32_swap (td->hwCBP);
|
||||
tdBE = m32_swap (td->hwBE);
|
||||
tdCBP = m32_swap (td->hwCBP);
|
||||
|
||||
|
||||
if (!(usb_pipetype (lurb_priv->pipe) == PIPE_CONTROL &&
|
||||
@@ -759,7 +759,7 @@ static td_t * dl_reverse_done_list (ohci_t *ohci)
|
||||
__u32 td_list_hc;
|
||||
td_t *td_rev = NULL;
|
||||
td_t *td_list = NULL;
|
||||
urb_priv_t *lurb_priv = NULL;
|
||||
urb_priv_t *lurb_priv = NULL;
|
||||
|
||||
td_list_hc = m32_swap (ohci->hcca->done_head) & 0xfffffff0;
|
||||
ohci->hcca->done_head = 0;
|
||||
@@ -794,42 +794,42 @@ static td_t * dl_reverse_done_list (ohci_t *ohci)
|
||||
/* td done list */
|
||||
static int dl_done_list (ohci_t *ohci, td_t *td_list)
|
||||
{
|
||||
td_t *td_list_next = NULL;
|
||||
td_t *td_list_next = NULL;
|
||||
ed_t *ed;
|
||||
int cc = 0;
|
||||
int stat = 0;
|
||||
/* urb_t *urb; */
|
||||
urb_priv_t *lurb_priv;
|
||||
__u32 tdINFO, edHeadP, edTailP;
|
||||
__u32 tdINFO, edHeadP, edTailP;
|
||||
|
||||
while (td_list) {
|
||||
td_list_next = td_list->next_dl_td;
|
||||
while (td_list) {
|
||||
td_list_next = td_list->next_dl_td;
|
||||
|
||||
lurb_priv = &urb_priv;
|
||||
tdINFO = m32_swap (td_list->hwINFO);
|
||||
lurb_priv = &urb_priv;
|
||||
tdINFO = m32_swap (td_list->hwINFO);
|
||||
|
||||
ed = td_list->ed;
|
||||
ed = td_list->ed;
|
||||
|
||||
dl_transfer_length(td_list);
|
||||
dl_transfer_length(td_list);
|
||||
|
||||
/* error code of transfer */
|
||||
cc = TD_CC_GET (tdINFO);
|
||||
/* error code of transfer */
|
||||
cc = TD_CC_GET (tdINFO);
|
||||
if (cc != 0) {
|
||||
dbg("ConditionCode %#x", cc);
|
||||
stat = cc_to_error[cc];
|
||||
}
|
||||
|
||||
if (ed->state != ED_NEW) {
|
||||
edHeadP = m32_swap (ed->hwHeadP) & 0xfffffff0;
|
||||
edTailP = m32_swap (ed->hwTailP);
|
||||
if (ed->state != ED_NEW) {
|
||||
edHeadP = m32_swap (ed->hwHeadP) & 0xfffffff0;
|
||||
edTailP = m32_swap (ed->hwTailP);
|
||||
|
||||
/* unlink eds if they are not busy */
|
||||
if ((edHeadP == edTailP) && (ed->state == ED_OPER))
|
||||
ep_unlink (ohci, ed);
|
||||
}
|
||||
if ((edHeadP == edTailP) && (ed->state == ED_OPER))
|
||||
ep_unlink (ohci, ed);
|
||||
}
|
||||
|
||||
td_list = td_list_next;
|
||||
}
|
||||
td_list = td_list_next;
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
@@ -851,9 +851,9 @@ static __u8 root_hub_dev_des[] =
|
||||
0x00, /* __u16 idVendor; */
|
||||
0x00,
|
||||
0x00, /* __u16 idProduct; */
|
||||
0x00,
|
||||
0x00,
|
||||
0x00, /* __u16 bcdDevice; */
|
||||
0x00,
|
||||
0x00,
|
||||
0x00, /* __u8 iManufacturer; */
|
||||
0x01, /* __u8 iProduct; */
|
||||
0x00, /* __u8 iSerialNumber; */
|
||||
@@ -872,7 +872,7 @@ static __u8 root_hub_config_des[] =
|
||||
0x01, /* __u8 bConfigurationValue; */
|
||||
0x00, /* __u8 iConfiguration; */
|
||||
0x40, /* __u8 bmAttributes;
|
||||
Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
|
||||
Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
|
||||
0x00, /* __u8 MaxPower; */
|
||||
|
||||
/* interface */
|
||||
@@ -890,9 +890,9 @@ static __u8 root_hub_config_des[] =
|
||||
0x07, /* __u8 ep_bLength; */
|
||||
0x05, /* __u8 ep_bDescriptorType; Endpoint */
|
||||
0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */
|
||||
0x03, /* __u8 ep_bmAttributes; Interrupt */
|
||||
0x02, /* __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */
|
||||
0x00,
|
||||
0x03, /* __u8 ep_bmAttributes; Interrupt */
|
||||
0x02, /* __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */
|
||||
0x00,
|
||||
0xff /* __u8 ep_bInterval; 255 ms */
|
||||
};
|
||||
|
||||
@@ -984,7 +984,7 @@ static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
|
||||
int stat = 0;
|
||||
__u32 datab[4];
|
||||
__u8 *data_buf = (__u8 *)datab;
|
||||
__u16 bmRType_bReq;
|
||||
__u16 bmRType_bReq;
|
||||
__u16 wValue;
|
||||
__u16 wIndex;
|
||||
__u16 wLength;
|
||||
@@ -1176,7 +1176,7 @@ pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe));
|
||||
len = min_t(int, len, leni);
|
||||
if (data != data_buf)
|
||||
memcpy (data, data_buf, len);
|
||||
dev->act_len = len;
|
||||
dev->act_len = len;
|
||||
dev->status = stat;
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -1226,7 +1226,7 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
|
||||
|
||||
wait_ms(10);
|
||||
/* ohci_dump_status(&gohci); */
|
||||
|
||||
|
||||
/* allow more time for a BULK device to react - some are slow */
|
||||
#define BULK_TO 5000 /* timeout in milliseconds */
|
||||
if (usb_pipetype (pipe) == PIPE_BULK)
|
||||
@@ -1277,7 +1277,7 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
|
||||
}
|
||||
|
||||
dev->status = stat;
|
||||
dev->act_len = transfer_len;
|
||||
dev->act_len = transfer_len;
|
||||
|
||||
#ifdef DEBUG
|
||||
pkt_print(dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", usb_pipein(pipe));
|
||||
@@ -1362,7 +1362,7 @@ static int hc_reset (ohci_t *ohci)
|
||||
ohci->slot_name,
|
||||
readl (&ohci->regs->control));
|
||||
|
||||
/* Reset USB (needed by some controllers) */
|
||||
/* Reset USB (needed by some controllers) */
|
||||
writel (0, &ohci->regs->control);
|
||||
|
||||
/* HC Reset requires max 10 us delay */
|
||||
@@ -1385,8 +1385,8 @@ static int hc_reset (ohci_t *ohci)
|
||||
|
||||
static int hc_start (ohci_t * ohci)
|
||||
{
|
||||
__u32 mask;
|
||||
unsigned int fminterval;
|
||||
__u32 mask;
|
||||
unsigned int fminterval;
|
||||
|
||||
ohci->disabled = 1;
|
||||
|
||||
@@ -1398,16 +1398,16 @@ static int hc_start (ohci_t * ohci)
|
||||
|
||||
writel ((__u32)ohci->hcca, &ohci->regs->hcca); /* a reset clears this */
|
||||
|
||||
fminterval = 0x2edf;
|
||||
fminterval = 0x2edf;
|
||||
writel ((fminterval * 9) / 10, &ohci->regs->periodicstart);
|
||||
fminterval |= ((((fminterval - 210) * 6) / 7) << 16);
|
||||
writel (fminterval, &ohci->regs->fminterval);
|
||||
writel (0x628, &ohci->regs->lsthresh);
|
||||
|
||||
/* start controller operations */
|
||||
ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
|
||||
/* start controller operations */
|
||||
ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
|
||||
ohci->disabled = 0;
|
||||
writel (ohci->hc_control, &ohci->regs->control);
|
||||
writel (ohci->hc_control, &ohci->regs->control);
|
||||
|
||||
/* disable all interrupts */
|
||||
mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD |
|
||||
@@ -1447,7 +1447,7 @@ hc_interrupt (void)
|
||||
{
|
||||
ohci_t *ohci = &gohci;
|
||||
struct ohci_regs *regs = ohci->regs;
|
||||
int ints;
|
||||
int ints;
|
||||
int stat = -1;
|
||||
|
||||
if ((ohci->hcca->done_head != 0) && !(m32_swap (ohci->hcca->done_head) & 0x01)) {
|
||||
@@ -1534,17 +1534,17 @@ int usb_lowlevel_init(void)
|
||||
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
|
||||
/*
|
||||
* Set the 48 MHz UPLL clocking. Values are taken from
|
||||
* "PLL value selection guide", 6-23, s3c2400_UM.pdf.
|
||||
*/
|
||||
clk_power->UPLLCON = ((40 << 12) + (1 << 4) + 2);
|
||||
gpio->MISCCR |= 0x8; /* 1 = use pads related USB for USB host */
|
||||
/*
|
||||
* Set the 48 MHz UPLL clocking. Values are taken from
|
||||
* "PLL value selection guide", 6-23, s3c2400_UM.pdf.
|
||||
*/
|
||||
clk_power->UPLLCON = ((40 << 12) + (1 << 4) + 2);
|
||||
gpio->MISCCR |= 0x8; /* 1 = use pads related USB for USB host */
|
||||
|
||||
/*
|
||||
* Enable USB host clock.
|
||||
*/
|
||||
clk_power->CLKCON |= (1 << 4);
|
||||
/*
|
||||
* Enable USB host clock.
|
||||
*/
|
||||
clk_power->CLKCON |= (1 << 4);
|
||||
|
||||
memset (&gohci, 0, sizeof (ohci_t));
|
||||
memset (&urb_priv, 0, sizeof (urb_priv_t));
|
||||
@@ -1568,7 +1568,7 @@ int usb_lowlevel_init(void)
|
||||
}
|
||||
ptd = gtd;
|
||||
gohci.hcca = phcca;
|
||||
memset (phcca, 0, sizeof (struct ohci_hcca));
|
||||
memset (phcca, 0, sizeof (struct ohci_hcca));
|
||||
|
||||
gohci.disabled = 1;
|
||||
gohci.sleeping = 0;
|
||||
@@ -1580,8 +1580,8 @@ int usb_lowlevel_init(void)
|
||||
|
||||
if (hc_reset (&gohci) < 0) {
|
||||
hc_release_ohci (&gohci);
|
||||
/* Initialization failed */
|
||||
clk_power->CLKCON &= ~(1 << 4);
|
||||
/* Initialization failed */
|
||||
clk_power->CLKCON &= ~(1 << 4);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1592,8 +1592,8 @@ int usb_lowlevel_init(void)
|
||||
if (hc_start (&gohci) < 0) {
|
||||
err ("can't start usb-%s", gohci.slot_name);
|
||||
hc_release_ohci (&gohci);
|
||||
/* Initialization failed */
|
||||
clk_power->CLKCON &= ~(1 << 4);
|
||||
/* Initialization failed */
|
||||
clk_power->CLKCON &= ~(1 << 4);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -224,7 +224,6 @@ struct ohci_regs {
|
||||
#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */
|
||||
|
||||
|
||||
|
||||
/* Virtual Root HUB */
|
||||
struct virt_root_hub {
|
||||
int devnum; /* Address of Root Hub endpoint */
|
||||
|
||||
@@ -79,7 +79,6 @@ int disable_interrupts (void)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void bad_mode (void)
|
||||
{
|
||||
panic ("Resetting CPU ...\n");
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include <version.h>
|
||||
|
||||
@@ -144,7 +143,7 @@ reset:
|
||||
msr cpsr,r0
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* turn off the watchdog, unlock/diable sequence
|
||||
*/
|
||||
mov r1, #0xF5
|
||||
@@ -154,9 +153,6 @@ reset:
|
||||
strh r1, [r0]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* mask all IRQs by setting all bits in the INTMR - default
|
||||
*/
|
||||
@@ -411,7 +407,7 @@ fiq:
|
||||
.globl reset_cpu
|
||||
reset_cpu:
|
||||
ldr r1, rstctl1 /* get clkm1 reset ctl */
|
||||
mov r3, #0x0
|
||||
mov r3, #0x0
|
||||
strh r3, [r1] /* clear it */
|
||||
mov r3, #0x8
|
||||
strh r3, [r1] /* force dsp+arm reset */
|
||||
|
||||
@@ -60,7 +60,6 @@ int disable_interrupts (void)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void bad_mode (void)
|
||||
{
|
||||
panic ("Resetting CPU ...\n");
|
||||
|
||||
@@ -31,37 +31,37 @@
|
||||
#include <version.h>
|
||||
#include <asm/arch/ixp425.h>
|
||||
|
||||
#define MMU_Control_M 0x001 // Enable MMU
|
||||
#define MMU_Control_A 0x002 // Enable address alignment faults
|
||||
#define MMU_Control_C 0x004 // Enable cache
|
||||
#define MMU_Control_W 0x008 // Enable write-buffer
|
||||
#define MMU_Control_P 0x010 // Compatability: 32 bit code
|
||||
#define MMU_Control_D 0x020 // Compatability: 32 bit data
|
||||
#define MMU_Control_L 0x040 // Compatability:
|
||||
#define MMU_Control_B 0x080 // Enable Big-Endian
|
||||
#define MMU_Control_S 0x100 // Enable system protection
|
||||
#define MMU_Control_R 0x200 // Enable ROM protection
|
||||
#define MMU_Control_I 0x1000 // Enable Instruction cache
|
||||
#define MMU_Control_X 0x2000 // Set interrupt vectors at 0xFFFF0000
|
||||
#define MMU_Control_M 0x001 /* Enable MMU */
|
||||
#define MMU_Control_A 0x002 /* Enable address alignment faults */
|
||||
#define MMU_Control_C 0x004 /* Enable cache */
|
||||
#define MMU_Control_W 0x008 /* Enable write-buffer */
|
||||
#define MMU_Control_P 0x010 /* Compatability: 32 bit code */
|
||||
#define MMU_Control_D 0x020 /* Compatability: 32 bit data */
|
||||
#define MMU_Control_L 0x040 /* Compatability: */
|
||||
#define MMU_Control_B 0x080 /* Enable Big-Endian */
|
||||
#define MMU_Control_S 0x100 /* Enable system protection */
|
||||
#define MMU_Control_R 0x200 /* Enable ROM protection */
|
||||
#define MMU_Control_I 0x1000 /* Enable Instruction cache */
|
||||
#define MMU_Control_X 0x2000 /* Set interrupt vectors at 0xFFFF0000 */
|
||||
#define MMU_Control_Init (MMU_Control_P|MMU_Control_D|MMU_Control_L)
|
||||
|
||||
|
||||
/*
|
||||
* Macro definitions
|
||||
*/
|
||||
// Delay a bit
|
||||
.macro DELAY_FOR cycles, reg0
|
||||
ldr \reg0, =\cycles
|
||||
subs \reg0, \reg0, #1
|
||||
subne pc, pc, #0xc
|
||||
.endm
|
||||
/* Delay a bit */
|
||||
.macro DELAY_FOR cycles, reg0
|
||||
ldr \reg0, =\cycles
|
||||
subs \reg0, \reg0, #1
|
||||
subne pc, pc, #0xc
|
||||
.endm
|
||||
|
||||
// wait for coprocessor write complete
|
||||
.macro CPWAIT reg
|
||||
mrc p15,0,\reg,c2,c0,0
|
||||
mov \reg,\reg
|
||||
sub pc,pc,#4
|
||||
.endm
|
||||
/* wait for coprocessor write complete */
|
||||
.macro CPWAIT reg
|
||||
mrc p15,0,\reg,c2,c0,0
|
||||
mov \reg,\reg
|
||||
sub pc,pc,#4
|
||||
.endm
|
||||
|
||||
.globl _start
|
||||
_start: b reset
|
||||
@@ -160,15 +160,15 @@ reset:
|
||||
/* disable mmu, set big-endian */
|
||||
mov r0, #0xf8
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
CPWAIT r0
|
||||
CPWAIT r0
|
||||
|
||||
/* invalidate I & D caches & BTB */
|
||||
mcr p15, 0, r0, c7, c7, 0
|
||||
CPWAIT r0
|
||||
|
||||
/* invalidate I & Data TLB */
|
||||
mcr p15, 0, r0, c8, c7, 0
|
||||
CPWAIT r0
|
||||
mcr p15, 0, r0, c8, c7, 0
|
||||
CPWAIT r0
|
||||
|
||||
/* drain write and fill buffers */
|
||||
mcr p15, 0, r0, c7, c10, 4
|
||||
@@ -185,7 +185,7 @@ reset:
|
||||
ldr r2, =IXP425_EXP_CS0
|
||||
str r1, [r2]
|
||||
|
||||
/* make sure flash is visible at 0 */
|
||||
/* make sure flash is visible at 0 */
|
||||
ldr r2, =IXP425_EXP_CFG0
|
||||
ldr r1, [r2]
|
||||
orr r1, r1, #0x80000000
|
||||
@@ -204,7 +204,7 @@ reset:
|
||||
mov r1, #3
|
||||
ldr r4, =IXP425_SDR_IR
|
||||
str r1, [r4]
|
||||
DELAY_FOR 0x4000, r0
|
||||
DELAY_FOR 0x4000, r0
|
||||
|
||||
/* set SDRAM internal refresh val */
|
||||
ldr r1, =CFG_SDRAM_REFRESH_CNT
|
||||
@@ -235,31 +235,31 @@ reset:
|
||||
DELAY_FOR 0x4000, r0
|
||||
|
||||
/* copy */
|
||||
mov r0, #0
|
||||
mov r4, r0
|
||||
add r2, r0, #0x40000
|
||||
mov r0, #0
|
||||
mov r4, r0
|
||||
add r2, r0, #0x40000
|
||||
mov r1, #0x10000000
|
||||
mov r5, r1
|
||||
mov r5, r1
|
||||
|
||||
30:
|
||||
ldr r3, [r0], #4
|
||||
str r3, [r1], #4
|
||||
cmp r0, r2
|
||||
bne 30b
|
||||
ldr r3, [r0], #4
|
||||
str r3, [r1], #4
|
||||
cmp r0, r2
|
||||
bne 30b
|
||||
|
||||
/* invalidate I & D caches & BTB */
|
||||
mcr p15, 0, r0, c7, c7, 0
|
||||
CPWAIT r0
|
||||
|
||||
/* invalidate I & Data TLB */
|
||||
mcr p15, 0, r0, c8, c7, 0
|
||||
CPWAIT r0
|
||||
mcr p15, 0, r0, c8, c7, 0
|
||||
CPWAIT r0
|
||||
|
||||
/* drain write and fill buffers */
|
||||
mcr p15, 0, r0, c7, c10, 4
|
||||
CPWAIT r0
|
||||
|
||||
/* move flash to 0x50000000 */
|
||||
/* move flash to 0x50000000 */
|
||||
ldr r2, =IXP425_EXP_CFG0
|
||||
ldr r1, [r2]
|
||||
bic r1, r1, #0x80000000
|
||||
@@ -273,14 +273,14 @@ reset:
|
||||
nop
|
||||
|
||||
/* invalidate I & Data TLB */
|
||||
mcr p15, 0, r0, c8, c7, 0
|
||||
CPWAIT r0
|
||||
mcr p15, 0, r0, c8, c7, 0
|
||||
CPWAIT r0
|
||||
|
||||
/* enable I cache */
|
||||
mrc p15, 0, r0, c1, c0, 0
|
||||
orr r0, r0, #MMU_Control_I
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
CPWAIT r0
|
||||
/* enable I cache */
|
||||
mrc p15, 0, r0, c1, c0, 0
|
||||
orr r0, r0, #MMU_Control_I
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
CPWAIT r0
|
||||
|
||||
mrs r0,cpsr /* set the cpu to SVC32 mode */
|
||||
bic r0,r0,#0x1f /* (superviser mode, M=10011) */
|
||||
@@ -331,8 +331,6 @@ clbss_l:str r2, [r0] /* clear loop... */
|
||||
_start_armboot: .word start_armboot
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* Interrupt handling */
|
||||
|
||||
@@ -847,7 +847,7 @@ int mpc5xxx_fec_initialize(bd_t * bis)
|
||||
|
||||
/*
|
||||
* Try to set the mac address now. The fec mac address is
|
||||
* a garbage after reset. When not using fec for booting
|
||||
* a garbage after reset. When not using fec for booting
|
||||
* the Linux fec driver will try to work with this garbage.
|
||||
*/
|
||||
tmp = getenv("ethaddr");
|
||||
|
||||
@@ -133,13 +133,13 @@ static int do_address(uchar chip, char rdwr_flag)
|
||||
mpc_reg_out(®s->mcr, I2C_TX, I2C_TX);
|
||||
mpc_reg_out(®s->mdr, chip, 0);
|
||||
|
||||
if (wait_for_pin(&status)) {
|
||||
return -2;
|
||||
}
|
||||
if (wait_for_pin(&status)) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (status & I2C_RXAK) {
|
||||
return -3;
|
||||
}
|
||||
if (status & I2C_RXAK) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -250,7 +250,7 @@ static int mpc_get_fdr(int speed)
|
||||
ipb = gd->ipb_clk;
|
||||
for (i = 7; i >= 0; i--) {
|
||||
for (j = 7; j >= 0; j--) {
|
||||
scl = 2 * (scltap[j].scl2tap +
|
||||
scl = 2 * (scltap[j].scl2tap +
|
||||
(SCL_Tap[i] - 1) * scltap[j].tap2tap + 2);
|
||||
if (ipb <= speed*scl) {
|
||||
if ((speed*scl - ipb) < bestmatch) {
|
||||
@@ -344,13 +344,13 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
|
||||
xaddr[2] = (addr >> 8) & 0xFF;
|
||||
xaddr[3] = addr & 0xFF;
|
||||
|
||||
if (wait_for_bb()) {
|
||||
if (wait_for_bb()) {
|
||||
printf("i2c_write: bus is busy\n");
|
||||
goto Done;
|
||||
}
|
||||
|
||||
mpc_reg_out(®s->mcr, I2C_STA, I2C_STA);
|
||||
if (do_address(chip, 0)) {
|
||||
mpc_reg_out(®s->mcr, I2C_STA, I2C_STA);
|
||||
if (do_address(chip, 0)) {
|
||||
printf("i2c_write: failed to address chip\n");
|
||||
goto Done;
|
||||
}
|
||||
|
||||
@@ -101,22 +101,22 @@ void pci_mpc5xxx_init (struct pci_controller *hose)
|
||||
|
||||
/* GPIO Multiplexing - enable PCI */
|
||||
*(vu_long *)MPC5XXX_GPS_PORT_CONFIG &= ~(1 << 15);
|
||||
|
||||
|
||||
/* Set host bridge as pci master and enable memory decoding */
|
||||
*(vu_long *)MPC5XXX_PCI_CMD |=
|
||||
PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
|
||||
|
||||
|
||||
/* Set maximum latency timer */
|
||||
*(vu_long *)MPC5XXX_PCI_CFG |= (0xf800);
|
||||
|
||||
/* Set cache line size */
|
||||
*(vu_long *)MPC5XXX_PCI_CFG = (*(vu_long *)MPC5XXX_PCI_CFG & ~0xff) |
|
||||
(CFG_CACHELINE_SIZE / 4);
|
||||
|
||||
|
||||
/* Map MBAR to PCI space */
|
||||
*(vu_long *)MPC5XXX_PCI_BAR0 = CFG_MBAR;
|
||||
*(vu_long *)MPC5XXX_PCI_TBATR1 = CFG_MBAR | 1;
|
||||
|
||||
|
||||
/* Map RAM to PCI space */
|
||||
*(vu_long *)MPC5XXX_PCI_BAR1 = CONFIG_PCI_MEMORY_BUS | (1 << 3);
|
||||
*(vu_long *)MPC5XXX_PCI_TBATR1 = CONFIG_PCI_MEMORY_PHYS | 1;
|
||||
@@ -133,14 +133,14 @@ void pci_mpc5xxx_init (struct pci_controller *hose)
|
||||
/* Enable piplining */
|
||||
*(vu_long *)(MPC5XXX_XLBARB + 0x40) &= ~(1 << 31);
|
||||
#endif
|
||||
|
||||
|
||||
/* Disable interrupts from PCI controller */
|
||||
*(vu_long *)MPC5XXX_PCI_GSCR &= ~(7 << 12);
|
||||
*(vu_long *)MPC5XXX_PCI_ICR &= ~(7 << 24);
|
||||
|
||||
|
||||
/* Disable initiator windows */
|
||||
*(vu_long *)MPC5XXX_PCI_IWCR = 0;
|
||||
|
||||
|
||||
/* Map PCI memory to physical space */
|
||||
*(vu_long *)MPC5XXX_PCI_IW0BTAR = CONFIG_PCI_MEM_PHYS |
|
||||
(((CONFIG_PCI_MEM_SIZE - 1) >> 8) & 0x00ff0000) |
|
||||
@@ -166,7 +166,7 @@ void pci_mpc5xxx_init (struct pci_controller *hose)
|
||||
pci_hose_write_config_byte_via_dword,
|
||||
pci_hose_write_config_word_via_dword,
|
||||
mpc5200_write_config_dword);
|
||||
|
||||
|
||||
udelay(1000);
|
||||
|
||||
#ifdef CONFIG_PCI_SCAN_SHOW
|
||||
|
||||
@@ -233,7 +233,7 @@ static int fec_init(struct eth_device* dev, bd_t *bis)
|
||||
/* 28.9 - (3): connect FCC's tx and rx clocks */
|
||||
immr->im_cpmux.cmx_uar = 0;
|
||||
immr->im_cpmux.cmx_fcr = (immr->im_cpmux.cmx_fcr & ~info->cmxfcr_mask) |
|
||||
info->cmxfcr_value;
|
||||
info->cmxfcr_value;
|
||||
|
||||
/* 28.9 - (4): GFMR: disable tx/rx, CCITT CRC, Mode Ethernet */
|
||||
immr->im_fcc[info->ether_index].fcc_gfmr =
|
||||
@@ -378,7 +378,7 @@ int fec_initialize(bd_t *bis)
|
||||
memset(dev, 0, sizeof *dev);
|
||||
|
||||
sprintf(dev->name, "FCC%d ETHERNET",
|
||||
ether_fcc_info[i].ether_index + 1);
|
||||
ether_fcc_info[i].ether_index + 1);
|
||||
dev->priv = ðer_fcc_info[i];
|
||||
dev->init = fec_init;
|
||||
dev->halt = fec_halt;
|
||||
@@ -652,10 +652,10 @@ eth_loopback_test (void)
|
||||
#if defined(CONFIG_HYMOD)
|
||||
/*
|
||||
* Attention: this is board-specific
|
||||
* 0, FCC1
|
||||
* 1, FCC2
|
||||
* 2, FCC3
|
||||
*/
|
||||
* 0, FCC1
|
||||
* 1, FCC2
|
||||
* 2, FCC3
|
||||
*/
|
||||
# define FCC_START_LOOP 0
|
||||
# define FCC_END_LOOP 2
|
||||
|
||||
@@ -677,8 +677,8 @@ eth_loopback_test (void)
|
||||
#elif defined(CONFIG_SBC8260) || defined(CONFIG_SACSng)
|
||||
/*
|
||||
* Attention: this is board-specific
|
||||
* 1, FCC2
|
||||
*/
|
||||
* 1, FCC2
|
||||
*/
|
||||
# define FCC_START_LOOP 1
|
||||
# define FCC_END_LOOP 1
|
||||
|
||||
|
||||
45
cpu/mpc85xx/Makefile
Normal file
45
cpu/mpc85xx/Makefile
Normal file
@@ -0,0 +1,45 @@
|
||||
#
|
||||
# (C) Copyright 2002,2003 Motorola Inc.
|
||||
# Xianghua Xiao,X.Xiao@motorola.com
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = lib$(CPU).a
|
||||
|
||||
START = start.o resetvec.o
|
||||
COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o tsec.o \
|
||||
pci.o serial_scc.o commproc.o ether_fcc.o i2c.o spd_sdram.o
|
||||
OBJS = $(COBJS)
|
||||
|
||||
all: .depend $(START) $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(AR) crv $@ $(OBJS)
|
||||
|
||||
#########################################################################
|
||||
|
||||
.depend: Makefile $(START:.o=.S) $(AOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
$(CC) -M $(CFLAGS) $(START:.o=.S) $(AOBJS:.o=.S) $(COBJS:.o=.c) > $@
|
||||
|
||||
sinclude .depend
|
||||
|
||||
#########################################################################
|
||||
214
cpu/mpc85xx/commproc.c
Normal file
214
cpu/mpc85xx/commproc.c
Normal file
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Adapted for Motorola MPC8560 chips
|
||||
* Xianghua Xiao <x.xiao@motorola.com>
|
||||
*
|
||||
* This file is based on "arch/ppc/8260_io/commproc.c" - here is it's
|
||||
* copyright notice:
|
||||
*
|
||||
* General Purpose functions for the global management of the
|
||||
* 8220 Communication Processor Module.
|
||||
* Copyright (c) 1999 Dan Malek (dmalek@jlc.net)
|
||||
* Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com)
|
||||
* 2.3.99 Updates
|
||||
* Copyright (c) 2003 Motorola,Inc.
|
||||
*
|
||||
* In addition to the individual control of the communication
|
||||
* channels, there are a few functions that globally affect the
|
||||
* communication processor.
|
||||
*
|
||||
* Buffer descriptors must be allocated from the dual ported memory
|
||||
* space. The allocator for that is here. When the communication
|
||||
* process is reset, we reclaim the memory available. There is
|
||||
* currently no deallocator for this memory.
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <asm/cpm_85xx.h>
|
||||
|
||||
#if defined(CONFIG_MPC8560)
|
||||
/*
|
||||
* because we have stack and init data in dual port ram
|
||||
* we must reduce the size
|
||||
*/
|
||||
#undef CPM_DATAONLY_SIZE
|
||||
#define CPM_DATAONLY_SIZE ((uint)(8 * 1024) - CPM_DATAONLY_BASE)
|
||||
|
||||
void
|
||||
m8560_cpm_reset(void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
volatile ulong count;
|
||||
|
||||
gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET);
|
||||
|
||||
/* Reclaim the DP memory for our use.
|
||||
*/
|
||||
gd->dp_alloc_base = CPM_DATAONLY_BASE;
|
||||
gd->dp_alloc_top = gd->dp_alloc_base + CPM_DATAONLY_SIZE;
|
||||
|
||||
/*
|
||||
* Reset CPM
|
||||
*/
|
||||
immr->im_cpm.im_cpm_cp.cpcr = CPM_CR_RST;
|
||||
count = 0;
|
||||
do { /* Spin until command processed */
|
||||
__asm__ __volatile__ ("eieio");
|
||||
} while ((immr->im_cpm.im_cpm_cp.cpcr & CPM_CR_FLG) && ++count < 1000000);
|
||||
}
|
||||
|
||||
/* Allocate some memory from the dual ported ram.
|
||||
* To help protocols with object alignment restrictions, we do that
|
||||
* if they ask.
|
||||
*/
|
||||
uint
|
||||
m8560_cpm_dpalloc(uint size, uint align)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
uint retloc;
|
||||
uint align_mask, off;
|
||||
uint savebase;
|
||||
|
||||
align_mask = align - 1;
|
||||
savebase = gd->dp_alloc_base;
|
||||
|
||||
if ((off = (gd->dp_alloc_base & align_mask)) != 0)
|
||||
gd->dp_alloc_base += (align - off);
|
||||
|
||||
if ((off = size & align_mask) != 0)
|
||||
size += align - off;
|
||||
|
||||
if ((gd->dp_alloc_base + size) >= gd->dp_alloc_top) {
|
||||
gd->dp_alloc_base = savebase;
|
||||
panic("m8560_cpm_dpalloc: ran out of dual port ram!");
|
||||
}
|
||||
|
||||
retloc = gd->dp_alloc_base;
|
||||
gd->dp_alloc_base += size;
|
||||
|
||||
memset((void *)&(immr->im_cpm.im_dprambase[retloc]), 0, size);
|
||||
|
||||
return(retloc);
|
||||
}
|
||||
|
||||
/* We also own one page of host buffer space for the allocation of
|
||||
* UART "fifos" and the like.
|
||||
*/
|
||||
uint
|
||||
m8560_cpm_hostalloc(uint size, uint align)
|
||||
{
|
||||
/* the host might not even have RAM yet - just use dual port RAM */
|
||||
return (m8560_cpm_dpalloc(size, align));
|
||||
}
|
||||
|
||||
/* Set a baud rate generator. This needs lots of work. There are
|
||||
* eight BRGs, which can be connected to the CPM channels or output
|
||||
* as clocks. The BRGs are in two different block of internal
|
||||
* memory mapped space.
|
||||
* The baud rate clock is the system clock divided by something.
|
||||
* It was set up long ago during the initial boot phase and is
|
||||
* is given to us.
|
||||
* Baud rate clocks are zero-based in the driver code (as that maps
|
||||
* to port numbers). Documentation uses 1-based numbering.
|
||||
*/
|
||||
#define BRG_INT_CLK gd->brg_clk
|
||||
#define BRG_UART_CLK ((BRG_INT_CLK + 15) / 16)
|
||||
|
||||
/* This function is used by UARTS, or anything else that uses a 16x
|
||||
* oversampled clock.
|
||||
*/
|
||||
void
|
||||
m8560_cpm_setbrg(uint brg, uint rate)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
volatile uint *bp;
|
||||
|
||||
/* This is good enough to get SMCs running.....
|
||||
*/
|
||||
if (brg < 4) {
|
||||
bp = (uint *)&(immr->im_cpm.im_cpm_brg1.brgc1);
|
||||
}
|
||||
else {
|
||||
bp = (uint *)&(immr->im_cpm.im_cpm_brg2.brgc5);
|
||||
brg -= 4;
|
||||
}
|
||||
bp += brg;
|
||||
*bp = (((((BRG_UART_CLK+rate-1)/rate)-1)&0xfff)<<1)|CPM_BRG_EN;
|
||||
}
|
||||
|
||||
/* This function is used to set high speed synchronous baud rate
|
||||
* clocks.
|
||||
*/
|
||||
void
|
||||
m8560_cpm_fastbrg(uint brg, uint rate, int div16)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
volatile uint *bp;
|
||||
|
||||
/* This is good enough to get SMCs running.....
|
||||
*/
|
||||
if (brg < 4) {
|
||||
bp = (uint *)&(immr->im_cpm.im_cpm_brg1.brgc1);
|
||||
}
|
||||
else {
|
||||
bp = (uint *)&(immr->im_cpm.im_cpm_brg2.brgc5);
|
||||
brg -= 4;
|
||||
}
|
||||
bp += brg;
|
||||
*bp = (((((BRG_INT_CLK+rate-1)/rate)-1)&0xfff)<<1)|CPM_BRG_EN;
|
||||
if (div16)
|
||||
*bp |= CPM_BRG_DIV16;
|
||||
}
|
||||
|
||||
/* This function is used to set baud rate generators using an external
|
||||
* clock source and 16x oversampling.
|
||||
*/
|
||||
|
||||
void
|
||||
m8560_cpm_extcbrg(uint brg, uint rate, uint extclk, int pinsel)
|
||||
{
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
volatile uint *bp;
|
||||
|
||||
if (brg < 4) {
|
||||
bp = (uint *)&(immr->im_cpm.im_cpm_brg1.brgc1);
|
||||
}
|
||||
else {
|
||||
bp = (uint *)&(immr->im_cpm.im_cpm_brg2.brgc5);
|
||||
brg -= 4;
|
||||
}
|
||||
bp += brg;
|
||||
*bp = ((((((extclk/16)+rate-1)/rate)-1)&0xfff)<<1)|CPM_BRG_EN;
|
||||
if (pinsel == 0)
|
||||
*bp |= CPM_BRG_EXTC_CLK3_9;
|
||||
else
|
||||
*bp |= CPM_BRG_EXTC_CLK5_15;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_POST
|
||||
|
||||
void post_word_store (ulong a)
|
||||
{
|
||||
volatile ulong *save_addr =
|
||||
(volatile ulong *)(CFG_IMMR + CPM_POST_WORD_ADDR);
|
||||
|
||||
*save_addr = a;
|
||||
}
|
||||
|
||||
ulong post_word_load (void)
|
||||
{
|
||||
volatile ulong *save_addr =
|
||||
(volatile ulong *)(CFG_IMMR + CPM_POST_WORD_ADDR);
|
||||
|
||||
return *save_addr;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST */
|
||||
|
||||
#endif /* CONFIG_MPC8560 */
|
||||
26
cpu/mpc85xx/config.mk
Normal file
26
cpu/mpc85xx/config.mk
Normal file
@@ -0,0 +1,26 @@
|
||||
#
|
||||
# (C) Copyright 2002,2003 Motorola Inc.
|
||||
# Xianghua Xiao, X.Xiao@motorola.com
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
PLATFORM_RELFLAGS += -mrelocatable -ffixed-r14 -meabi
|
||||
|
||||
PLATFORM_CPPFLAGS += -DCONFIG_MPC85xx -DCONFIG_E500 -ffixed-r2 -ffixed-r29 -Wa,-me500 -msoft-float
|
||||
151
cpu/mpc85xx/cpu.c
Normal file
151
cpu/mpc85xx/cpu.c
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* (C) Copyright 2002, 2003 Motorola Inc.
|
||||
* Xianghua Xiao (X.Xiao@motorola.com)
|
||||
*
|
||||
* (C) Copyright 2000
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <watchdog.h>
|
||||
#include <command.h>
|
||||
#include <asm/cache.h>
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
int checkcpu (void)
|
||||
{
|
||||
uint pir = get_pir();
|
||||
uint pvr = get_pvr();
|
||||
|
||||
printf("Motorola PowerPC ProcessorID=%08x Rev. ",pir);
|
||||
switch(pvr) {
|
||||
default:
|
||||
printf("PVR=%08x", pvr);
|
||||
break;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
|
||||
{
|
||||
/*
|
||||
* Initiate hard reset in debug control register DBCR0
|
||||
* Make sure MSR[DE] = 1
|
||||
*/
|
||||
__asm__ __volatile__("lis 3, 0x7000" ::: "r3");
|
||||
mtspr(DBCR0,3);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get timebase clock frequency
|
||||
*/
|
||||
unsigned long get_tbclk (void)
|
||||
{
|
||||
|
||||
sys_info_t sys_info;
|
||||
|
||||
get_sys_info(&sys_info);
|
||||
return ((sys_info.freqSystemBus + 3L) / 4L);
|
||||
}
|
||||
|
||||
|
||||
#if defined(CONFIG_WATCHDOG)
|
||||
void
|
||||
watchdog_reset(void)
|
||||
{
|
||||
int re_enable = disable_interrupts();
|
||||
reset_85xx_watchdog();
|
||||
if (re_enable) enable_interrupts();
|
||||
}
|
||||
|
||||
void
|
||||
reset_85xx_watchdog(void)
|
||||
{
|
||||
/*
|
||||
* Clear TSR(WIS) bit by writing 1
|
||||
*/
|
||||
unsigned long val;
|
||||
val = mfspr(tsr);
|
||||
val |= 0x40000000;
|
||||
mtspr(tsr, val);
|
||||
}
|
||||
#endif /* CONFIG_WATCHDOG */
|
||||
|
||||
#if defined(CONFIG_DDR_ECC)
|
||||
__inline__ void dcbz(const void* addr)
|
||||
{
|
||||
__asm__ __volatile__ ("dcbz 0,%0" :: "r" (addr));
|
||||
}
|
||||
|
||||
__inline__ void dcbf(const void* addr)
|
||||
{
|
||||
__asm__ __volatile__ ("dcbf 0,%0" :: "r" (addr));
|
||||
}
|
||||
|
||||
void dma_init(void) {
|
||||
volatile immap_t *immap = (immap_t *)CFG_IMMR;
|
||||
volatile ccsr_dma_t *dma = &immap->im_dma;
|
||||
|
||||
dma->satr0 = 0x02c40000;
|
||||
dma->datr0 = 0x02c40000;
|
||||
asm("sync; isync; msync");
|
||||
return;
|
||||
}
|
||||
|
||||
uint dma_check(void) {
|
||||
volatile immap_t *immap = (immap_t *)CFG_IMMR;
|
||||
volatile ccsr_dma_t *dma = &immap->im_dma;
|
||||
volatile uint status = dma->sr0;
|
||||
|
||||
/* While the channel is busy, spin */
|
||||
while((status & 4) == 4) {
|
||||
status = dma->sr0;
|
||||
}
|
||||
|
||||
if (status != 0) {
|
||||
printf ("DMA Error: status = %x\n", status);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int dma_xfer(void *dest, uint count, void *src) {
|
||||
volatile immap_t *immap = (immap_t *)CFG_IMMR;
|
||||
volatile ccsr_dma_t *dma = &immap->im_dma;
|
||||
|
||||
dma->dar0 = (uint) dest;
|
||||
dma->sar0 = (uint) src;
|
||||
dma->bcr0 = count;
|
||||
dma->mr0 = 0xf000004;
|
||||
asm("sync;isync;msync");
|
||||
dma->mr0 = 0xf000005;
|
||||
asm("sync;isync;msync");
|
||||
return dma_check();
|
||||
}
|
||||
#endif
|
||||
205
cpu/mpc85xx/cpu_init.c
Normal file
205
cpu/mpc85xx/cpu_init.c
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* (C) Copyright 2003 Motorola Inc.
|
||||
* Modified by Xianghua Xiao, X.Xiao@motorola.com
|
||||
*
|
||||
* (C) Copyright 2000
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <watchdog.h>
|
||||
#include <asm/processor.h>
|
||||
#include <ioports.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#ifdef CONFIG_MPC8560
|
||||
static void config_8560_ioports (volatile immap_t * immr)
|
||||
{
|
||||
int portnum;
|
||||
|
||||
for (portnum = 0; portnum < 4; portnum++) {
|
||||
uint pmsk = 0,
|
||||
ppar = 0,
|
||||
psor = 0,
|
||||
pdir = 0,
|
||||
podr = 0,
|
||||
pdat = 0;
|
||||
iop_conf_t *iopc = (iop_conf_t *) & iop_conf_tab[portnum][0];
|
||||
iop_conf_t *eiopc = iopc + 32;
|
||||
uint msk = 1;
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
* index 0 refers to pin 31,
|
||||
* index 31 refers to pin 0
|
||||
*/
|
||||
while (iopc < eiopc) {
|
||||
if (iopc->conf) {
|
||||
pmsk |= msk;
|
||||
if (iopc->ppar)
|
||||
ppar |= msk;
|
||||
if (iopc->psor)
|
||||
psor |= msk;
|
||||
if (iopc->pdir)
|
||||
pdir |= msk;
|
||||
if (iopc->podr)
|
||||
podr |= msk;
|
||||
if (iopc->pdat)
|
||||
pdat |= msk;
|
||||
}
|
||||
|
||||
msk <<= 1;
|
||||
iopc++;
|
||||
}
|
||||
|
||||
if (pmsk != 0) {
|
||||
volatile ioport_t *iop = ioport_addr (immr, portnum);
|
||||
uint tpmsk = ~pmsk;
|
||||
|
||||
/*
|
||||
* the (somewhat confused) paragraph at the
|
||||
* bottom of page 35-5 warns that there might
|
||||
* be "unknown behaviour" when programming
|
||||
* PSORx and PDIRx, if PPARx = 1, so I
|
||||
* decided this meant I had to disable the
|
||||
* dedicated function first, and enable it
|
||||
* last.
|
||||
*/
|
||||
iop->ppar &= tpmsk;
|
||||
iop->psor = (iop->psor & tpmsk) | psor;
|
||||
iop->podr = (iop->podr & tpmsk) | podr;
|
||||
iop->pdat = (iop->pdat & tpmsk) | pdat;
|
||||
iop->pdir = (iop->pdir & tpmsk) | pdir;
|
||||
iop->ppar |= ppar;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Breathe some life into the CPU...
|
||||
*
|
||||
* Set up the memory map
|
||||
* initialize a bunch of registers
|
||||
*/
|
||||
|
||||
void cpu_init_f (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
volatile immap_t *immap = (immap_t *)CFG_IMMR;
|
||||
volatile ccsr_lbc_t *memctl = &immap->im_lbc;
|
||||
extern void m8560_cpm_reset (void);
|
||||
|
||||
/* Pointer is writable since we allocated a register for it */
|
||||
gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET);
|
||||
|
||||
/* Clear initial global data */
|
||||
memset ((void *) gd, 0, sizeof (gd_t));
|
||||
|
||||
|
||||
#ifdef CONFIG_MPC8560
|
||||
config_8560_ioports(immap);
|
||||
#endif
|
||||
|
||||
/* Map banks 0 and 1 to the FLASH banks 0 and 1 at preliminary
|
||||
* addresses - these have to be modified later when FLASH size
|
||||
* has been determined
|
||||
*/
|
||||
#if defined(CFG_OR0_REMAP)
|
||||
memctl->or0 = CFG_OR0_REMAP;
|
||||
#endif
|
||||
#if defined(CFG_OR1_REMAP)
|
||||
memctl->or1 = CFG_OR1_REMAP;
|
||||
#endif
|
||||
|
||||
/* now restrict to preliminary range */
|
||||
#if defined(CFG_BR0_PRELIM) && defined(CFG_OR0_PRELIM)
|
||||
memctl->br0 = CFG_BR0_PRELIM;
|
||||
memctl->or0 = CFG_OR0_PRELIM;
|
||||
#endif
|
||||
|
||||
#if defined(CFG_BR1_PRELIM) && defined(CFG_OR1_PRELIM)
|
||||
memctl->or1 = CFG_OR1_PRELIM;
|
||||
memctl->br1 = CFG_BR1_PRELIM;
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_MPC85xx)
|
||||
#if defined(CFG_BR2_PRELIM) && defined(CFG_OR2_PRELIM)
|
||||
memctl->or2 = CFG_OR2_PRELIM;
|
||||
memctl->br2 = CFG_BR2_PRELIM;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(CFG_BR3_PRELIM) && defined(CFG_OR3_PRELIM)
|
||||
memctl->or3 = CFG_OR3_PRELIM;
|
||||
memctl->br3 = CFG_BR3_PRELIM;
|
||||
#endif
|
||||
|
||||
#if defined(CFG_BR4_PRELIM) && defined(CFG_OR4_PRELIM)
|
||||
memctl->or4 = CFG_OR4_PRELIM;
|
||||
memctl->br4 = CFG_BR4_PRELIM;
|
||||
#endif
|
||||
|
||||
#if defined(CFG_BR5_PRELIM) && defined(CFG_OR5_PRELIM)
|
||||
memctl->or5 = CFG_OR5_PRELIM;
|
||||
memctl->br5 = CFG_BR5_PRELIM;
|
||||
#endif
|
||||
|
||||
#if defined(CFG_BR6_PRELIM) && defined(CFG_OR6_PRELIM)
|
||||
memctl->or6 = CFG_OR6_PRELIM;
|
||||
memctl->br6 = CFG_BR6_PRELIM;
|
||||
#endif
|
||||
|
||||
#if defined(CFG_BR7_PRELIM) && defined(CFG_OR7_PRELIM)
|
||||
memctl->or7 = CFG_OR7_PRELIM;
|
||||
memctl->br7 = CFG_BR7_PRELIM;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MPC8560)
|
||||
m8560_cpm_reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* We initialize L2 as cache here.
|
||||
*/
|
||||
int cpu_init_r (void)
|
||||
{
|
||||
#if defined(CONFIG_L2_CACHE)
|
||||
volatile immap_t *immap = (immap_t *)CFG_IMMR;
|
||||
volatile ccsr_l2cache_t *l2cache = &immap->im_l2cache;
|
||||
volatile uint temp;
|
||||
|
||||
asm("msync;isync");
|
||||
l2cache->l2ctl = 0x68000000; /* invalidate */
|
||||
temp = l2cache->l2ctl;
|
||||
asm("msync;isync");
|
||||
l2cache->l2ctl = 0xa8000000; /* enable 256KB L2 cache */
|
||||
temp = l2cache->l2ctl;
|
||||
asm("msync;isync");
|
||||
|
||||
printf("L2 cache enabled: 256KB\n");
|
||||
#else
|
||||
printf("L2 cache disabled.\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
461
cpu/mpc85xx/ether_fcc.c
Normal file
461
cpu/mpc85xx/ether_fcc.c
Normal file
@@ -0,0 +1,461 @@
|
||||
/*
|
||||
* MPC8560 FCC Fast Ethernet
|
||||
* Copyright (c) 2003 Motorola,Inc.
|
||||
* Xianghua Xiao, (X.Xiao@motorola.com)
|
||||
*
|
||||
* Copyright (c) 2000 MontaVista Software, Inc. Dan Malek (dmalek@jlc.net)
|
||||
*
|
||||
* (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* MPC8560 FCC Fast Ethernet
|
||||
* Basic ET HW initialization and packet RX/TX routines
|
||||
*
|
||||
* This code will not perform the IO port configuration. This should be
|
||||
* done in the iop_conf_t structure specific for the board.
|
||||
*
|
||||
* TODO:
|
||||
* add a PHY driver to do the negotiation
|
||||
* reflect negotiation results in FPSMR
|
||||
* look for ways to configure the board specific stuff elsewhere, eg.
|
||||
* config_xxx.h or the board directory
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/cpm_85xx.h>
|
||||
#include <command.h>
|
||||
#include <config.h>
|
||||
#include <net.h>
|
||||
|
||||
#if defined(CONFIG_MPC8560)
|
||||
|
||||
#if defined(CONFIG_ETHER_ON_FCC) && (CONFIG_COMMANDS & CFG_CMD_NET) && \
|
||||
defined(CONFIG_NET_MULTI)
|
||||
|
||||
static struct ether_fcc_info_s
|
||||
{
|
||||
int ether_index;
|
||||
int proff_enet;
|
||||
ulong cpm_cr_enet_sblock;
|
||||
ulong cpm_cr_enet_page;
|
||||
ulong cmxfcr_mask;
|
||||
ulong cmxfcr_value;
|
||||
}
|
||||
ether_fcc_info[] =
|
||||
{
|
||||
#ifdef CONFIG_ETHER_ON_FCC1
|
||||
{
|
||||
0,
|
||||
PROFF_FCC1,
|
||||
CPM_CR_FCC1_SBLOCK,
|
||||
CPM_CR_FCC1_PAGE,
|
||||
CFG_CMXFCR_MASK1,
|
||||
CFG_CMXFCR_VALUE1
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ETHER_ON_FCC2
|
||||
{
|
||||
1,
|
||||
PROFF_FCC2,
|
||||
CPM_CR_FCC2_SBLOCK,
|
||||
CPM_CR_FCC2_PAGE,
|
||||
CFG_CMXFCR_MASK2,
|
||||
CFG_CMXFCR_VALUE2
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ETHER_ON_FCC3
|
||||
{
|
||||
2,
|
||||
PROFF_FCC3,
|
||||
CPM_CR_FCC3_SBLOCK,
|
||||
CPM_CR_FCC3_PAGE,
|
||||
CFG_CMXFCR_MASK3,
|
||||
CFG_CMXFCR_VALUE3
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
/* Maximum input DMA size. Must be a should(?) be a multiple of 4. */
|
||||
#define PKT_MAXDMA_SIZE 1520
|
||||
|
||||
/* The FCC stores dest/src/type, data, and checksum for receive packets. */
|
||||
#define PKT_MAXBUF_SIZE 1518
|
||||
#define PKT_MINBUF_SIZE 64
|
||||
|
||||
/* Maximum input buffer size. Must be a multiple of 32. */
|
||||
#define PKT_MAXBLR_SIZE 1536
|
||||
|
||||
#define TOUT_LOOP 1000000
|
||||
|
||||
#define TX_BUF_CNT 2
|
||||
|
||||
static uint rxIdx; /* index of the current RX buffer */
|
||||
static uint txIdx; /* index of the current TX buffer */
|
||||
|
||||
/*
|
||||
* FCC Ethernet Tx and Rx buffer descriptors.
|
||||
* Provide for Double Buffering
|
||||
* Note: PKTBUFSRX is defined in net.h
|
||||
*/
|
||||
|
||||
typedef volatile struct rtxbd {
|
||||
cbd_t rxbd[PKTBUFSRX];
|
||||
cbd_t txbd[TX_BUF_CNT];
|
||||
} RTXBD;
|
||||
|
||||
/* Good news: the FCC supports external BDs! */
|
||||
#ifdef __GNUC__
|
||||
static RTXBD rtx __attribute__ ((aligned(8)));
|
||||
#else
|
||||
#error "rtx must be 64-bit aligned"
|
||||
#endif
|
||||
|
||||
#define ET_DEBUG
|
||||
|
||||
static int fec_send(struct eth_device* dev, volatile void *packet, int length)
|
||||
{
|
||||
int i = 0;
|
||||
int result = 0;
|
||||
|
||||
if (length <= 0) {
|
||||
printf("fec: bad packet size: %d\n", length);
|
||||
goto out;
|
||||
}
|
||||
|
||||
for(i=0; rtx.txbd[txIdx].cbd_sc & BD_ENET_TX_READY; i++) {
|
||||
if (i >= TOUT_LOOP) {
|
||||
printf("fec: tx buffer not ready\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
rtx.txbd[txIdx].cbd_bufaddr = (uint)packet;
|
||||
rtx.txbd[txIdx].cbd_datlen = length;
|
||||
rtx.txbd[txIdx].cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_LAST | \
|
||||
BD_ENET_TX_TC );
|
||||
|
||||
for(i=0; rtx.txbd[txIdx].cbd_sc & BD_ENET_TX_READY; i++) {
|
||||
if (i >= TOUT_LOOP) {
|
||||
printf("fec: tx error\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ET_DEBUG
|
||||
printf("cycles: 0x%x txIdx=0x%04x status: 0x%04x\n", i, txIdx,rtx.txbd[txIdx].cbd_sc);
|
||||
printf("packets at 0x%08x, length_in_bytes=0x%x\n",(uint)packet,length);
|
||||
for(i=0;i<(length/16 + 1);i++) {
|
||||
printf("%08x %08x %08x %08x\n",*((uint *)rtx.txbd[txIdx].cbd_bufaddr+i*4),\
|
||||
*((uint *)rtx.txbd[txIdx].cbd_bufaddr + i*4 + 1),*((uint *)rtx.txbd[txIdx].cbd_bufaddr + i*4 + 2), \
|
||||
*((uint *)rtx.txbd[txIdx].cbd_bufaddr + i*4 + 3));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* return only status bits */
|
||||
result = rtx.txbd[txIdx].cbd_sc & BD_ENET_TX_STATS;
|
||||
txIdx = (txIdx + 1) % TX_BUF_CNT;
|
||||
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
|
||||
static int fec_recv(struct eth_device* dev)
|
||||
{
|
||||
int length;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (rtx.rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) {
|
||||
length = -1;
|
||||
break; /* nothing received - leave for() loop */
|
||||
}
|
||||
length = rtx.rxbd[rxIdx].cbd_datlen;
|
||||
|
||||
if (rtx.rxbd[rxIdx].cbd_sc & 0x003f) {
|
||||
printf("fec: rx error %04x\n", rtx.rxbd[rxIdx].cbd_sc);
|
||||
}
|
||||
else {
|
||||
/* Pass the packet up to the protocol layers. */
|
||||
NetReceive(NetRxPackets[rxIdx], length - 4);
|
||||
}
|
||||
|
||||
|
||||
/* Give the buffer back to the FCC. */
|
||||
rtx.rxbd[rxIdx].cbd_datlen = 0;
|
||||
|
||||
/* wrap around buffer index when necessary */
|
||||
if ((rxIdx + 1) >= PKTBUFSRX) {
|
||||
rtx.rxbd[PKTBUFSRX - 1].cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
|
||||
rxIdx = 0;
|
||||
}
|
||||
else {
|
||||
rtx.rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY;
|
||||
rxIdx++;
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
static int fec_init(struct eth_device* dev, bd_t *bis)
|
||||
{
|
||||
struct ether_fcc_info_s * info = dev->priv;
|
||||
int i;
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
volatile ccsr_cpm_cp_t *cp = &(immr->im_cpm.im_cpm_cp);
|
||||
fcc_enet_t *pram_ptr;
|
||||
unsigned long mem_addr;
|
||||
|
||||
#if 0
|
||||
mii_discover_phy();
|
||||
#endif
|
||||
|
||||
/* 28.9 - (1-2): ioports have been set up already */
|
||||
|
||||
/* 28.9 - (3): connect FCC's tx and rx clocks */
|
||||
immr->im_cpm.im_cpm_mux.cmxuar = 0; /* ATM */
|
||||
immr->im_cpm.im_cpm_mux.cmxfcr = (immr->im_cpm.im_cpm_mux.cmxfcr & ~info->cmxfcr_mask) |
|
||||
info->cmxfcr_value;
|
||||
|
||||
/* 28.9 - (4): GFMR: disable tx/rx, CCITT CRC, set Mode Ethernet */
|
||||
if(info->ether_index == 0) {
|
||||
immr->im_cpm.im_cpm_fcc1.gfmr = FCC_GFMR_MODE_ENET | FCC_GFMR_TCRC_32;
|
||||
} else if (info->ether_index == 1) {
|
||||
immr->im_cpm.im_cpm_fcc2.gfmr = FCC_GFMR_MODE_ENET | FCC_GFMR_TCRC_32;
|
||||
} else if (info->ether_index == 2) {
|
||||
immr->im_cpm.im_cpm_fcc3.gfmr = FCC_GFMR_MODE_ENET | FCC_GFMR_TCRC_32;
|
||||
}
|
||||
|
||||
/* 28.9 - (5): FPSMR: enable full duplex, select CCITT CRC for Ethernet,MII */
|
||||
if(info->ether_index == 0) {
|
||||
immr->im_cpm.im_cpm_fcc1.fpsmr = CFG_FCC_PSMR | FCC_PSMR_ENCRC;
|
||||
} else if (info->ether_index == 1){
|
||||
immr->im_cpm.im_cpm_fcc2.fpsmr = CFG_FCC_PSMR | FCC_PSMR_ENCRC;
|
||||
} else if (info->ether_index == 2){
|
||||
immr->im_cpm.im_cpm_fcc3.fpsmr = CFG_FCC_PSMR | FCC_PSMR_ENCRC;
|
||||
}
|
||||
|
||||
/* 28.9 - (6): FDSR: Ethernet Syn */
|
||||
if(info->ether_index == 0) {
|
||||
immr->im_cpm.im_cpm_fcc1.fdsr = 0xD555;
|
||||
} else if (info->ether_index == 1) {
|
||||
immr->im_cpm.im_cpm_fcc2.fdsr = 0xD555;
|
||||
} else if (info->ether_index == 2) {
|
||||
immr->im_cpm.im_cpm_fcc3.fdsr = 0xD555;
|
||||
}
|
||||
|
||||
/* reset indeces to current rx/tx bd (see eth_send()/eth_rx()) */
|
||||
rxIdx = 0;
|
||||
txIdx = 0;
|
||||
|
||||
/* Setup Receiver Buffer Descriptors */
|
||||
for (i = 0; i < PKTBUFSRX; i++)
|
||||
{
|
||||
rtx.rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
|
||||
rtx.rxbd[i].cbd_datlen = 0;
|
||||
rtx.rxbd[i].cbd_bufaddr = (uint)NetRxPackets[i];
|
||||
}
|
||||
rtx.rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
|
||||
|
||||
/* Setup Ethernet Transmitter Buffer Descriptors */
|
||||
for (i = 0; i < TX_BUF_CNT; i++)
|
||||
{
|
||||
rtx.txbd[i].cbd_sc = 0;
|
||||
rtx.txbd[i].cbd_datlen = 0;
|
||||
rtx.txbd[i].cbd_bufaddr = 0;
|
||||
}
|
||||
rtx.txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
|
||||
|
||||
/* 28.9 - (7): initialize parameter ram */
|
||||
pram_ptr = (fcc_enet_t *)&(immr->im_cpm.im_dprambase[info->proff_enet]);
|
||||
|
||||
/* clear whole structure to make sure all reserved fields are zero */
|
||||
memset((void*)pram_ptr, 0, sizeof(fcc_enet_t));
|
||||
|
||||
/*
|
||||
* common Parameter RAM area
|
||||
*
|
||||
* Allocate space in the reserved FCC area of DPRAM for the
|
||||
* internal buffers. No one uses this space (yet), so we
|
||||
* can do this. Later, we will add resource management for
|
||||
* this area. CPM_FCC_SPECIAL_BASE: 0xb000.
|
||||
*/
|
||||
mem_addr = CPM_FCC_SPECIAL_BASE + ((info->ether_index) * 64);
|
||||
pram_ptr->fen_genfcc.fcc_riptr = mem_addr;
|
||||
pram_ptr->fen_genfcc.fcc_tiptr = mem_addr+32;
|
||||
/*
|
||||
* Set maximum bytes per receive buffer.
|
||||
* It must be a multiple of 32.
|
||||
*/
|
||||
pram_ptr->fen_genfcc.fcc_mrblr = PKT_MAXBLR_SIZE; /* 1536 */
|
||||
/* localbus SDRAM should be preferred */
|
||||
pram_ptr->fen_genfcc.fcc_rstate = (CPMFCR_GBL | CPMFCR_EB |
|
||||
CFG_CPMFCR_RAMTYPE) << 24;
|
||||
pram_ptr->fen_genfcc.fcc_rbase = (unsigned int)(&rtx.rxbd[rxIdx]);
|
||||
pram_ptr->fen_genfcc.fcc_rbdstat = 0;
|
||||
pram_ptr->fen_genfcc.fcc_rbdlen = 0;
|
||||
pram_ptr->fen_genfcc.fcc_rdptr = 0;
|
||||
/* localbus SDRAM should be preferred */
|
||||
pram_ptr->fen_genfcc.fcc_tstate = (CPMFCR_GBL | CPMFCR_EB |
|
||||
CFG_CPMFCR_RAMTYPE) << 24;
|
||||
pram_ptr->fen_genfcc.fcc_tbase = (unsigned int)(&rtx.txbd[txIdx]);
|
||||
pram_ptr->fen_genfcc.fcc_tbdstat = 0;
|
||||
pram_ptr->fen_genfcc.fcc_tbdlen = 0;
|
||||
pram_ptr->fen_genfcc.fcc_tdptr = 0;
|
||||
|
||||
/* protocol-specific area */
|
||||
pram_ptr->fen_statbuf = 0x0;
|
||||
pram_ptr->fen_cmask = 0xdebb20e3; /* CRC mask */
|
||||
pram_ptr->fen_cpres = 0xffffffff; /* CRC preset */
|
||||
pram_ptr->fen_crcec = 0;
|
||||
pram_ptr->fen_alec = 0;
|
||||
pram_ptr->fen_disfc = 0;
|
||||
pram_ptr->fen_retlim = 15; /* Retry limit threshold */
|
||||
pram_ptr->fen_retcnt = 0;
|
||||
pram_ptr->fen_pper = 0;
|
||||
pram_ptr->fen_boffcnt = 0;
|
||||
pram_ptr->fen_gaddrh = 0;
|
||||
pram_ptr->fen_gaddrl = 0;
|
||||
pram_ptr->fen_mflr = PKT_MAXBUF_SIZE; /* maximum frame length register */
|
||||
/*
|
||||
* Set Ethernet station address.
|
||||
*
|
||||
* This is supplied in the board information structure, so we
|
||||
* copy that into the controller.
|
||||
* So far we have only been given one Ethernet address. We make
|
||||
* it unique by setting a few bits in the upper byte of the
|
||||
* non-static part of the address.
|
||||
*/
|
||||
#define ea eth_get_dev()->enetaddr
|
||||
pram_ptr->fen_paddrh = (ea[5] << 8) + ea[4];
|
||||
pram_ptr->fen_paddrm = (ea[3] << 8) + ea[2];
|
||||
pram_ptr->fen_paddrl = (ea[1] << 8) + ea[0];
|
||||
#undef ea
|
||||
pram_ptr->fen_ibdcount = 0;
|
||||
pram_ptr->fen_ibdstart = 0;
|
||||
pram_ptr->fen_ibdend = 0;
|
||||
pram_ptr->fen_txlen = 0;
|
||||
pram_ptr->fen_iaddrh = 0; /* disable hash */
|
||||
pram_ptr->fen_iaddrl = 0;
|
||||
pram_ptr->fen_minflr = PKT_MINBUF_SIZE; /* minimum frame length register: 64 */
|
||||
/* pad pointer. use tiptr since we don't need a specific padding char */
|
||||
pram_ptr->fen_padptr = pram_ptr->fen_genfcc.fcc_tiptr;
|
||||
pram_ptr->fen_maxd1 = PKT_MAXDMA_SIZE; /* maximum DMA1 length:1520 */
|
||||
pram_ptr->fen_maxd2 = PKT_MAXDMA_SIZE; /* maximum DMA2 length:1520 */
|
||||
|
||||
#if defined(ET_DEBUG)
|
||||
printf("parm_ptr(0xff788500) = %p\n",pram_ptr);
|
||||
printf("pram_ptr->fen_genfcc.fcc_rbase %08x\n",
|
||||
pram_ptr->fen_genfcc.fcc_rbase);
|
||||
printf("pram_ptr->fen_genfcc.fcc_tbase %08x\n",
|
||||
pram_ptr->fen_genfcc.fcc_tbase);
|
||||
#endif
|
||||
|
||||
/* 28.9 - (8)(9): clear out events in FCCE */
|
||||
/* 28.9 - (9): FCCM: mask all events */
|
||||
if(info->ether_index == 0) {
|
||||
immr->im_cpm.im_cpm_fcc1.fcce = ~0x0;
|
||||
immr->im_cpm.im_cpm_fcc1.fccm = 0;
|
||||
} else if (info->ether_index == 1) {
|
||||
immr->im_cpm.im_cpm_fcc2.fcce = ~0x0;
|
||||
immr->im_cpm.im_cpm_fcc2.fccm = 0;
|
||||
} else if (info->ether_index == 2) {
|
||||
immr->im_cpm.im_cpm_fcc3.fcce = ~0x0;
|
||||
immr->im_cpm.im_cpm_fcc3.fccm = 0;
|
||||
}
|
||||
|
||||
/* 28.9 - (10-12): we don't use ethernet interrupts */
|
||||
|
||||
/* 28.9 - (13)
|
||||
*
|
||||
* Let's re-initialize the channel now. We have to do it later
|
||||
* than the manual describes because we have just now finished
|
||||
* the BD initialization.
|
||||
*/
|
||||
cp->cpcr = mk_cr_cmd(info->cpm_cr_enet_page,
|
||||
info->cpm_cr_enet_sblock,
|
||||
0x0c,
|
||||
CPM_CR_INIT_TRX) | CPM_CR_FLG;
|
||||
do {
|
||||
__asm__ __volatile__ ("eieio");
|
||||
} while (cp->cpcr & CPM_CR_FLG);
|
||||
|
||||
/* 28.9 - (14): enable tx/rx in gfmr */
|
||||
if(info->ether_index == 0) {
|
||||
immr->im_cpm.im_cpm_fcc1.gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR;
|
||||
} else if (info->ether_index == 1) {
|
||||
immr->im_cpm.im_cpm_fcc2.gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR;
|
||||
} else if (info->ether_index == 2) {
|
||||
immr->im_cpm.im_cpm_fcc3.gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fec_halt(struct eth_device* dev)
|
||||
{
|
||||
struct ether_fcc_info_s * info = dev->priv;
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
|
||||
/* write GFMR: disable tx/rx */
|
||||
if(info->ether_index == 0) {
|
||||
immr->im_cpm.im_cpm_fcc1.gfmr &= ~(FCC_GFMR_ENT | FCC_GFMR_ENR);
|
||||
} else if(info->ether_index == 1) {
|
||||
immr->im_cpm.im_cpm_fcc2.gfmr &= ~(FCC_GFMR_ENT | FCC_GFMR_ENR);
|
||||
} else if(info->ether_index == 2) {
|
||||
immr->im_cpm.im_cpm_fcc3.gfmr &= ~(FCC_GFMR_ENT | FCC_GFMR_ENR);
|
||||
}
|
||||
}
|
||||
|
||||
int fec_initialize(bd_t *bis)
|
||||
{
|
||||
struct eth_device* dev;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); i++)
|
||||
{
|
||||
dev = (struct eth_device*) malloc(sizeof *dev);
|
||||
memset(dev, 0, sizeof *dev);
|
||||
|
||||
sprintf(dev->name, "FCC%d ETHERNET",
|
||||
ether_fcc_info[i].ether_index + 1);
|
||||
dev->priv = ðer_fcc_info[i];
|
||||
dev->init = fec_init;
|
||||
dev->halt = fec_halt;
|
||||
dev->send = fec_send;
|
||||
dev->recv = fec_recv;
|
||||
|
||||
eth_register(dev);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ETHER_ON_FCC && CFG_CMD_NET && CONFIG_NET_MULTI */
|
||||
|
||||
#endif /* CONFIG_MPC8560 */
|
||||
288
cpu/mpc85xx/i2c.c
Normal file
288
cpu/mpc85xx/i2c.c
Normal file
@@ -0,0 +1,288 @@
|
||||
/*
|
||||
* (C) Copyright 2003,Motorola Inc.
|
||||
* Xianghua Xiao <x.xiao@motorola.com>
|
||||
* Adapted for Motorola 85xx chip.
|
||||
*
|
||||
* (C) Copyright 2003
|
||||
* Gleb Natapov <gnatapov@mrv.com>
|
||||
* Some bits are taken from linux driver writen by adrian@humboldt.co.uk
|
||||
*
|
||||
* Hardware I2C driver for MPC107 PCI bridge.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
|
||||
#define DEBUG
|
||||
|
||||
#if defined(DEBUG)
|
||||
#define DEB(x) x
|
||||
#else
|
||||
#define DEB(x)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HARD_I2C
|
||||
#include <i2c.h>
|
||||
|
||||
#define TIMEOUT (CFG_HZ/4)
|
||||
|
||||
#define I2C_Addr ((unsigned *)(CFG_CCSRBAR + 0x3000))
|
||||
|
||||
#define I2CADR &I2C_Addr[0]
|
||||
#define I2CFDR &I2C_Addr[1]
|
||||
#define I2CCCR &I2C_Addr[2]
|
||||
#define I2CCSR &I2C_Addr[3]
|
||||
#define I2CCDR &I2C_Addr[4]
|
||||
#define I2CDFSRR &I2C_Addr[5]
|
||||
|
||||
#define I2C_READ 1
|
||||
#define I2C_WRITE 0
|
||||
|
||||
/* taken from linux include/asm-ppc/io.h */
|
||||
inline unsigned in_le32(volatile unsigned *addr)
|
||||
{
|
||||
unsigned ret;
|
||||
|
||||
__asm__ __volatile__("lwbrx %0,0,%1;\n"
|
||||
"twi 0,%0,0;\n"
|
||||
"isync" : "=r" (ret) :
|
||||
"r" (addr), "m" (*addr));
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline void out_le32(volatile unsigned *addr, int val)
|
||||
{
|
||||
__asm__ __volatile__("stwbrx %1,0,%2; eieio" : "=m" (*addr) :
|
||||
"r" (val), "r" (addr));
|
||||
}
|
||||
|
||||
#define writel(val, addr) out_le32(addr, val)
|
||||
#define readl(addr) in_le32(addr)
|
||||
|
||||
void
|
||||
i2c_init(int speed, int slaveadd)
|
||||
{
|
||||
/* stop I2C controller */
|
||||
writel (0x0, I2CCCR);
|
||||
/* set clock */
|
||||
writel (0x3f, I2CFDR);
|
||||
/* set default filter */
|
||||
writel (0x10,I2CDFSRR);
|
||||
/* write slave address */
|
||||
writel (slaveadd, I2CADR);
|
||||
/* clear status register */
|
||||
writel (0x0, I2CCSR);
|
||||
/* start I2C controller */
|
||||
writel (MPC85xx_I2CCR_MEN, I2CCCR);
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
i2c_wait4bus (void)
|
||||
{
|
||||
ulong timeval = get_timer (0);
|
||||
|
||||
while (readl (I2CCSR) & MPC85xx_I2CSR_MBB)
|
||||
if (get_timer (timeval) > TIMEOUT)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
i2c_wait (int write)
|
||||
{
|
||||
u32 csr;
|
||||
ulong timeval = get_timer (0);
|
||||
|
||||
do
|
||||
{
|
||||
csr = readl (I2CCSR);
|
||||
|
||||
if (!(csr & MPC85xx_I2CSR_MIF))
|
||||
continue;
|
||||
|
||||
writel (0x0, I2CCSR);
|
||||
|
||||
if (csr & MPC85xx_I2CSR_MAL)
|
||||
{
|
||||
DEB(printf ("i2c_wait: MAL\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(csr & MPC85xx_I2CSR_MCF))
|
||||
{
|
||||
DEB(printf ("i2c_wait: unfinished\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (write == I2C_WRITE && (csr & MPC85xx_I2CSR_RXAK))
|
||||
{
|
||||
DEB(printf ("i2c_wait: No RXACK\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} while (get_timer (timeval) < TIMEOUT);
|
||||
|
||||
DEB(printf ("i2c_wait: timed out\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
i2c_write_addr (u8 dev, u8 dir, int rsta)
|
||||
{
|
||||
writel (MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA | MPC85xx_I2CCR_MTX |
|
||||
(rsta?MPC85xx_I2CCR_RSTA:0), I2CCCR);
|
||||
|
||||
writel ((dev << 1) | dir, I2CCDR);
|
||||
|
||||
if (i2c_wait (I2C_WRITE) < 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
__i2c_write (u8 *data, int length)
|
||||
{
|
||||
int i;
|
||||
|
||||
writel (MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA | MPC85xx_I2CCR_MTX, I2CCCR);
|
||||
|
||||
for (i=0; i < length; i++)
|
||||
{
|
||||
writel (data[i], I2CCDR);
|
||||
|
||||
if (i2c_wait (I2C_WRITE) < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
__i2c_read (u8 *data, int length)
|
||||
{
|
||||
int i;
|
||||
|
||||
writel (MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA |
|
||||
((length == 1) ? MPC85xx_I2CCR_TXAK : 0), I2CCCR);
|
||||
|
||||
/* dummy read */
|
||||
readl (I2CCDR);
|
||||
|
||||
for (i=0; i < length; i++)
|
||||
{
|
||||
if (i2c_wait (I2C_READ) < 0)
|
||||
break;
|
||||
|
||||
/* Generate ack on last next to last byte */
|
||||
if (i == length - 2)
|
||||
writel (MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA |
|
||||
MPC85xx_I2CCR_TXAK, I2CCCR);
|
||||
|
||||
/* Generate stop on last byte */
|
||||
if (i == length - 1)
|
||||
writel (MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_TXAK, I2CCCR);
|
||||
|
||||
data[i] = readl (I2CCDR);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int
|
||||
i2c_read (u8 dev, uint addr, int alen, u8 *data, int length)
|
||||
{
|
||||
int i = 0;
|
||||
u8 *a = (u8*)&addr;
|
||||
|
||||
if (i2c_wait4bus () < 0)
|
||||
goto exit;
|
||||
|
||||
if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
|
||||
goto exit;
|
||||
|
||||
if (__i2c_write (&a[4 - alen], alen) != alen)
|
||||
goto exit;
|
||||
|
||||
if (i2c_write_addr (dev, I2C_READ, 1) == 0)
|
||||
goto exit;
|
||||
|
||||
i = __i2c_read (data, length);
|
||||
|
||||
exit:
|
||||
writel (MPC85xx_I2CCR_MEN, I2CCCR);
|
||||
|
||||
return !(i == length);
|
||||
}
|
||||
|
||||
int
|
||||
i2c_write (u8 dev, uint addr, int alen, u8 *data, int length)
|
||||
{
|
||||
int i = 0;
|
||||
u8 *a = (u8*)&addr;
|
||||
|
||||
if (i2c_wait4bus () < 0)
|
||||
goto exit;
|
||||
|
||||
if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
|
||||
goto exit;
|
||||
|
||||
if (__i2c_write (&a[4 - alen], alen) != alen)
|
||||
goto exit;
|
||||
|
||||
i = __i2c_write (data, length);
|
||||
|
||||
exit:
|
||||
writel (MPC85xx_I2CCR_MEN, I2CCCR);
|
||||
|
||||
return !(i == length);
|
||||
}
|
||||
|
||||
int i2c_probe (uchar chip)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
/*
|
||||
* Try to read the first location of the chip. The underlying
|
||||
* driver doesn't appear to support sending just the chip address
|
||||
* and looking for an <ACK> back.
|
||||
*/
|
||||
udelay(10000);
|
||||
return i2c_read (chip, 0, 1, (char *)&tmp, 1);
|
||||
}
|
||||
|
||||
uchar i2c_reg_read (uchar i2c_addr, uchar reg)
|
||||
{
|
||||
char buf[1];
|
||||
|
||||
i2c_read (i2c_addr, reg, 1, buf, 1);
|
||||
|
||||
return (buf[0]);
|
||||
}
|
||||
|
||||
void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)
|
||||
{
|
||||
i2c_write (i2c_addr, reg, 1, &val, 1);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_HARD_I2C */
|
||||
138
cpu/mpc85xx/interrupts.c
Normal file
138
cpu/mpc85xx/interrupts.c
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* (C) Copyright 2000-2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* (C) Copyright 2002 (440 port)
|
||||
* Scott McNutt, Artesyn Communication Producs, smcnutt@artsyncp.com
|
||||
*
|
||||
* (C) Copyright 2003 Motorola Inc. (MPC85xx port)
|
||||
* Xianghua Xiao (X.Xiao@motorola.com)
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <watchdog.h>
|
||||
#include <command.h>
|
||||
#include <asm/processor.h>
|
||||
#include <ppc_asm.tmpl>
|
||||
|
||||
unsigned decrementer_count; /* count value for 1e6/HZ microseconds */
|
||||
|
||||
static __inline__ unsigned long get_msr(void)
|
||||
{
|
||||
unsigned long msr;
|
||||
|
||||
asm volatile("mfmsr %0" : "=r" (msr) :);
|
||||
return msr;
|
||||
}
|
||||
|
||||
static __inline__ void set_msr(unsigned long msr)
|
||||
{
|
||||
asm volatile("mtmsr %0" : : "r" (msr));
|
||||
asm volatile("isync");
|
||||
}
|
||||
|
||||
void enable_interrupts (void)
|
||||
{
|
||||
set_msr (get_msr() | MSR_EE);
|
||||
}
|
||||
|
||||
/* returns flag if MSR_EE was set before */
|
||||
int disable_interrupts (void)
|
||||
{
|
||||
ulong msr = get_msr();
|
||||
set_msr (msr & ~MSR_EE);
|
||||
return ((msr & MSR_EE) != 0);
|
||||
}
|
||||
|
||||
/* interrupt is not supported yet */
|
||||
int interrupt_init (void)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Install and free a interrupt handler. Not implemented yet.
|
||||
*/
|
||||
|
||||
void
|
||||
irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
irq_free_handler(int vec)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
volatile ulong timestamp = 0;
|
||||
|
||||
/*
|
||||
* timer_interrupt - gets called when the decrementer overflows,
|
||||
* with interrupts disabled.
|
||||
* Trivial implementation - no need to be really accurate.
|
||||
*/
|
||||
void timer_interrupt(struct pt_regs *regs)
|
||||
{
|
||||
printf ("*** Timer Interrupt *** ");
|
||||
timestamp++;
|
||||
|
||||
#if defined(CONFIG_WATCHDOG)
|
||||
if ((timestamp % 1000) == 0)
|
||||
reset_85xx_watchdog();
|
||||
#endif /* CONFIG_WATCHDOG */
|
||||
}
|
||||
|
||||
void reset_timer (void)
|
||||
{
|
||||
timestamp = 0;
|
||||
}
|
||||
|
||||
ulong get_timer (ulong base)
|
||||
{
|
||||
return (timestamp - base);
|
||||
}
|
||||
|
||||
void set_timer (ulong t)
|
||||
{
|
||||
timestamp = t;
|
||||
}
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_IRQ)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* irqinfo - print information about PCI devices,not implemented.
|
||||
*
|
||||
*/
|
||||
int
|
||||
do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
printf ("\nInterrupt-unsupported:\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_COMMANDS & CFG_CMD_IRQ */
|
||||
107
cpu/mpc85xx/pci.c
Normal file
107
cpu/mpc85xx/pci.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (C) 2003 Motorola Inc.
|
||||
* Xianghua Xiao (x.xiao@motorola.com)
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* PCI Configuration space access support for MPC85xx PCI Bridge
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <asm/cpm_85xx.h>
|
||||
#include <pci.h>
|
||||
|
||||
#if defined(CONFIG_PCI)
|
||||
/*
|
||||
* Initialize PCI Devices, report devices found.
|
||||
*/
|
||||
#ifndef CONFIG_PCI_PNP
|
||||
static struct pci_config_table pci_mpc85xxads_config_table[] = {
|
||||
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_IDSEL_NUMBER, PCI_ANY_ID,
|
||||
pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
|
||||
PCI_ENET0_MEMADDR,
|
||||
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
|
||||
{ }
|
||||
};
|
||||
#endif
|
||||
|
||||
struct pci_controller local_hose = {
|
||||
#ifndef CONFIG_PCI_PNP
|
||||
config_table: pci_mpc85xxads_config_table,
|
||||
#endif
|
||||
};
|
||||
|
||||
void pci_init_board(void)
|
||||
{
|
||||
struct pci_controller* hose = (struct pci_controller *)&local_hose;
|
||||
volatile immap_t *immap = (immap_t *)CFG_CCSRBAR;
|
||||
volatile ccsr_pcix_t *pcix = &immap->im_pcix;
|
||||
|
||||
u16 reg16;
|
||||
|
||||
hose->first_busno = 0;
|
||||
hose->last_busno = 0xff;
|
||||
|
||||
pci_set_region(hose->regions + 0,
|
||||
CFG_PCI_MEM_BASE,
|
||||
CFG_PCI_MEM_PHYS,
|
||||
(CFG_PCI_MEM_SIZE/2),
|
||||
PCI_REGION_MEM);
|
||||
|
||||
pci_set_region(hose->regions + 1,
|
||||
(CFG_PCI_MEM_BASE+0x08000000),
|
||||
(CFG_PCI_MEM_PHYS+0x08000000),
|
||||
0x1000000, /* 16M */
|
||||
PCI_REGION_IO);
|
||||
|
||||
hose->region_count = 2;
|
||||
|
||||
pci_setup_indirect(hose,
|
||||
(CFG_IMMR+0x8000),
|
||||
(CFG_IMMR+0x8004));
|
||||
|
||||
pci_register_hose(hose);
|
||||
|
||||
hose->last_busno = pci_hose_scan(hose);
|
||||
|
||||
pci_read_config_word (PCI_BDF(0,0,0), PCI_COMMAND, ®16);
|
||||
reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
|
||||
pci_write_config_word(PCI_BDF(0,0,0), PCI_COMMAND, reg16);
|
||||
|
||||
/* Clear non-reserved bits in status register */
|
||||
pci_write_config_word(PCI_BDF(0,0,0), PCI_STATUS, 0xffff);
|
||||
pci_write_config_byte(PCI_BDF(0,0,0), PCI_LATENCY_TIMER,0x80);
|
||||
|
||||
pcix->potar1 = (CFG_PCI_MEM_BASE >> 12) & 0x000fffff;
|
||||
pcix->potear1 = 0x00000000;
|
||||
pcix->powbar1 = (CFG_PCI_MEM_BASE >> 12) & 0x000fffff;
|
||||
pcix->powbear1 = 0x00000000;
|
||||
pcix->powar1 = 0x8004401a; /* 128M MEM space */
|
||||
pcix->potar2 = ((CFG_PCI_MEM_BASE + 0x08000000) >> 12) & 0x000fffff;
|
||||
pcix->potear2 = 0x00000000;
|
||||
pcix->powbar2 = ((CFG_PCI_MEM_BASE + 0x08000000) >> 12) && 0x000fffff;
|
||||
pcix->powbear2 = 0x00000000;
|
||||
pcix->powar2 = 0x80088017; /* 16M IO space */
|
||||
pcix->pitar1 = 0x00000000;
|
||||
pcix->piwbar1 = 0x00000000;
|
||||
pcix->piwar1 = 0xa0F5501f;
|
||||
|
||||
}
|
||||
#endif /* CONFIG_PCI */
|
||||
2
cpu/mpc85xx/resetvec.S
Normal file
2
cpu/mpc85xx/resetvec.S
Normal file
@@ -0,0 +1,2 @@
|
||||
.section .resetvec,"ax"
|
||||
b _start_e500
|
||||
274
cpu/mpc85xx/serial_scc.c
Normal file
274
cpu/mpc85xx/serial_scc.c
Normal file
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* (C) Copyright 2003 Motorola Inc.
|
||||
* Xianghua Xiao (X.Xiao@motorola.com)
|
||||
* Modified based on 8260 for 8560.
|
||||
*
|
||||
* (C) Copyright 2000
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*
|
||||
* Hacked for MPC8260 by Murray.Jensen@cmst.csiro.au, 19-Oct-00.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Minimal serial functions needed to use one of the SCC ports
|
||||
* as serial console interface.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/cpm_85xx.h>
|
||||
|
||||
#if defined(CONFIG_MPC8560)
|
||||
#if defined(CONFIG_CONS_ON_SCC)
|
||||
|
||||
#if CONFIG_CONS_INDEX == 1 /* Console on SCC1 */
|
||||
|
||||
#define SCC_INDEX 0
|
||||
#define PROFF_SCC PROFF_SCC1
|
||||
#define CMXSCR_MASK (CMXSCR_GR1|CMXSCR_SC1|\
|
||||
CMXSCR_RS1CS_MSK|CMXSCR_TS1CS_MSK)
|
||||
#define CMXSCR_VALUE (CMXSCR_RS1CS_BRG1|CMXSCR_TS1CS_BRG1)
|
||||
#define CPM_CR_SCC_PAGE CPM_CR_SCC1_PAGE
|
||||
#define CPM_CR_SCC_SBLOCK CPM_CR_SCC1_SBLOCK
|
||||
|
||||
#elif CONFIG_CONS_INDEX == 2 /* Console on SCC2 */
|
||||
|
||||
#define SCC_INDEX 1
|
||||
#define PROFF_SCC PROFF_SCC2
|
||||
#define CMXSCR_MASK (CMXSCR_GR2|CMXSCR_SC2|\
|
||||
CMXSCR_RS2CS_MSK|CMXSCR_TS2CS_MSK)
|
||||
#define CMXSCR_VALUE (CMXSCR_RS2CS_BRG2|CMXSCR_TS2CS_BRG2)
|
||||
#define CPM_CR_SCC_PAGE CPM_CR_SCC2_PAGE
|
||||
#define CPM_CR_SCC_SBLOCK CPM_CR_SCC2_SBLOCK
|
||||
|
||||
#elif CONFIG_CONS_INDEX == 3 /* Console on SCC3 */
|
||||
|
||||
#define SCC_INDEX 2
|
||||
#define PROFF_SCC PROFF_SCC3
|
||||
#define CMXSCR_MASK (CMXSCR_GR3|CMXSCR_SC3|\
|
||||
CMXSCR_RS3CS_MSK|CMXSCR_TS3CS_MSK)
|
||||
#define CMXSCR_VALUE (CMXSCR_RS3CS_BRG3|CMXSCR_TS3CS_BRG3)
|
||||
#define CPM_CR_SCC_PAGE CPM_CR_SCC3_PAGE
|
||||
#define CPM_CR_SCC_SBLOCK CPM_CR_SCC3_SBLOCK
|
||||
|
||||
#elif CONFIG_CONS_INDEX == 4 /* Console on SCC4 */
|
||||
|
||||
#define SCC_INDEX 3
|
||||
#define PROFF_SCC PROFF_SCC4
|
||||
#define CMXSCR_MASK (CMXSCR_GR4|CMXSCR_SC4|\
|
||||
CMXSCR_RS4CS_MSK|CMXSCR_TS4CS_MSK)
|
||||
#define CMXSCR_VALUE (CMXSCR_RS4CS_BRG4|CMXSCR_TS4CS_BRG4)
|
||||
#define CPM_CR_SCC_PAGE CPM_CR_SCC4_PAGE
|
||||
#define CPM_CR_SCC_SBLOCK CPM_CR_SCC4_SBLOCK
|
||||
|
||||
#else
|
||||
|
||||
#error "console not correctly defined"
|
||||
|
||||
#endif
|
||||
|
||||
int serial_init (void)
|
||||
{
|
||||
volatile immap_t *im = (immap_t *)CFG_IMMR;
|
||||
volatile ccsr_cpm_scc_t *sp;
|
||||
volatile scc_uart_t *up;
|
||||
volatile cbd_t *tbdf, *rbdf;
|
||||
volatile ccsr_cpm_cp_t *cp = &(im->im_cpm.im_cpm_cp);
|
||||
uint dpaddr;
|
||||
|
||||
/* initialize pointers to SCC */
|
||||
|
||||
sp = (ccsr_cpm_scc_t *) &(im->im_cpm.im_cpm_scc[SCC_INDEX]);
|
||||
up = (scc_uart_t *)&(im->im_cpm.im_dprambase[PROFF_SCC]);
|
||||
|
||||
/* Disable transmitter/receiver.
|
||||
*/
|
||||
sp->gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
|
||||
|
||||
/* put the SCC channel into NMSI (non multiplexd serial interface)
|
||||
* mode and wire the selected SCC Tx and Rx clocks to BRGx (15-15).
|
||||
*/
|
||||
im->im_cpm.im_cpm_mux.cmxscr = \
|
||||
(im->im_cpm.im_cpm_mux.cmxscr&~CMXSCR_MASK)|CMXSCR_VALUE;
|
||||
|
||||
/* Set up the baud rate generator.
|
||||
*/
|
||||
serial_setbrg ();
|
||||
|
||||
/* Allocate space for two buffer descriptors in the DP ram.
|
||||
* damm: allocating space after the two buffers for rx/tx data
|
||||
*/
|
||||
|
||||
dpaddr = m8560_cpm_dpalloc((2 * sizeof (cbd_t)) + 2, 16);
|
||||
|
||||
/* Set the physical address of the host memory buffers in
|
||||
* the buffer descriptors.
|
||||
*/
|
||||
rbdf = (cbd_t *)&(im->im_cpm.im_dprambase[dpaddr]);
|
||||
rbdf->cbd_bufaddr = (uint) (rbdf+2);
|
||||
rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
|
||||
tbdf = rbdf + 1;
|
||||
tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1;
|
||||
tbdf->cbd_sc = BD_SC_WRAP;
|
||||
|
||||
/* Set up the uart parameters in the parameter ram.
|
||||
*/
|
||||
up->scc_genscc.scc_rbase = dpaddr;
|
||||
up->scc_genscc.scc_tbase = dpaddr+sizeof(cbd_t);
|
||||
up->scc_genscc.scc_rfcr = CPMFCR_EB;
|
||||
up->scc_genscc.scc_tfcr = CPMFCR_EB;
|
||||
up->scc_genscc.scc_mrblr = 1;
|
||||
up->scc_maxidl = 0;
|
||||
up->scc_brkcr = 1;
|
||||
up->scc_parec = 0;
|
||||
up->scc_frmec = 0;
|
||||
up->scc_nosec = 0;
|
||||
up->scc_brkec = 0;
|
||||
up->scc_uaddr1 = 0;
|
||||
up->scc_uaddr2 = 0;
|
||||
up->scc_toseq = 0;
|
||||
up->scc_char1 = up->scc_char2 = up->scc_char3 = up->scc_char4 = 0x8000;
|
||||
up->scc_char5 = up->scc_char6 = up->scc_char7 = up->scc_char8 = 0x8000;
|
||||
up->scc_rccm = 0xc0ff;
|
||||
|
||||
/* Mask all interrupts and remove anything pending.
|
||||
*/
|
||||
sp->sccm = 0;
|
||||
sp->scce = 0xffff;
|
||||
|
||||
/* Set 8 bit FIFO, 16 bit oversampling and UART mode.
|
||||
*/
|
||||
sp->gsmrh = SCC_GSMRH_RFW; /* 8 bit FIFO */
|
||||
sp->gsmrl = \
|
||||
SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16 | SCC_GSMRL_MODE_UART;
|
||||
|
||||
/* Set CTS no flow control, 1 stop bit, 8 bit character length,
|
||||
* normal async UART mode, no parity
|
||||
*/
|
||||
sp->psmr = SCU_PSMR_CL;
|
||||
|
||||
/* execute the "Init Rx and Tx params" CP command.
|
||||
*/
|
||||
|
||||
while (cp->cpcr & CPM_CR_FLG) /* wait if cp is busy */
|
||||
;
|
||||
|
||||
cp->cpcr = mk_cr_cmd(CPM_CR_SCC_PAGE, CPM_CR_SCC_SBLOCK,
|
||||
0, CPM_CR_INIT_TRX) | CPM_CR_FLG;
|
||||
|
||||
while (cp->cpcr & CPM_CR_FLG) /* wait if cp is busy */
|
||||
;
|
||||
|
||||
/* Enable transmitter/receiver.
|
||||
*/
|
||||
sp->gsmrl |= SCC_GSMRL_ENR | SCC_GSMRL_ENT;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
serial_setbrg (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#if defined(CONFIG_CONS_USE_EXTC)
|
||||
m8560_cpm_extcbrg(SCC_INDEX, gd->baudrate,
|
||||
CONFIG_CONS_EXTC_RATE, CONFIG_CONS_EXTC_PINSEL);
|
||||
#else
|
||||
m8560_cpm_setbrg(SCC_INDEX, gd->baudrate);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
serial_putc(const char c)
|
||||
{
|
||||
volatile scc_uart_t *up;
|
||||
volatile cbd_t *tbdf;
|
||||
volatile immap_t *im;
|
||||
|
||||
if (c == '\n')
|
||||
serial_putc ('\r');
|
||||
|
||||
im = (immap_t *)CFG_IMMR;
|
||||
up = (scc_uart_t *)&(im->im_cpm.im_dprambase[PROFF_SCC]);
|
||||
tbdf = (cbd_t *)&(im->im_cpm.im_dprambase[up->scc_genscc.scc_tbase]);
|
||||
|
||||
/* Wait for last character to go.
|
||||
*/
|
||||
while (tbdf->cbd_sc & BD_SC_READY)
|
||||
;
|
||||
|
||||
/* Load the character into the transmit buffer.
|
||||
*/
|
||||
*(volatile char *)tbdf->cbd_bufaddr = c;
|
||||
tbdf->cbd_datlen = 1;
|
||||
tbdf->cbd_sc |= BD_SC_READY;
|
||||
}
|
||||
|
||||
void
|
||||
serial_puts (const char *s)
|
||||
{
|
||||
while (*s) {
|
||||
serial_putc (*s++);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
serial_getc(void)
|
||||
{
|
||||
volatile cbd_t *rbdf;
|
||||
volatile scc_uart_t *up;
|
||||
volatile immap_t *im;
|
||||
unsigned char c;
|
||||
|
||||
im = (immap_t *)CFG_IMMR;
|
||||
up = (scc_uart_t *)&(im->im_cpm.im_dprambase[PROFF_SCC]);
|
||||
rbdf = (cbd_t *)&(im->im_cpm.im_dprambase[up->scc_genscc.scc_rbase]);
|
||||
|
||||
/* Wait for character to show up.
|
||||
*/
|
||||
while (rbdf->cbd_sc & BD_SC_EMPTY)
|
||||
;
|
||||
|
||||
/* Grab the char and clear the buffer again.
|
||||
*/
|
||||
c = *(volatile unsigned char *)rbdf->cbd_bufaddr;
|
||||
rbdf->cbd_sc |= BD_SC_EMPTY;
|
||||
|
||||
return (c);
|
||||
}
|
||||
|
||||
int
|
||||
serial_tstc()
|
||||
{
|
||||
volatile cbd_t *rbdf;
|
||||
volatile scc_uart_t *up;
|
||||
volatile immap_t *im;
|
||||
|
||||
im = (immap_t *)CFG_IMMR;
|
||||
up = (scc_uart_t *)&(im->im_cpm.im_dprambase[PROFF_SCC]);
|
||||
rbdf = (cbd_t *)&(im->im_cpm.im_dprambase[up->scc_genscc.scc_rbase]);
|
||||
|
||||
return ((rbdf->cbd_sc & BD_SC_EMPTY) == 0);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_CONS_ON_SCC */
|
||||
|
||||
#endif /* CONFIG_MPC8560 */
|
||||
308
cpu/mpc85xx/spd_sdram.c
Normal file
308
cpu/mpc85xx/spd_sdram.c
Normal file
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* (C) Copyright 2003 Motorola Inc.
|
||||
* Xianghua Xiao (X.Xiao@motorola.com)
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/processor.h>
|
||||
#include <i2c.h>
|
||||
#include <spd.h>
|
||||
#include <asm/mmu.h>
|
||||
|
||||
#ifdef CONFIG_SPD_EEPROM
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#if defined(DEBUG)
|
||||
#define DEB(x) x
|
||||
#else
|
||||
#define DEB(x)
|
||||
#endif
|
||||
|
||||
#define ns2clk(ns) ((ns) / (2000000000 /get_bus_freq(0) + 1))
|
||||
|
||||
long int spd_sdram(void) {
|
||||
volatile immap_t *immap = (immap_t *)CFG_IMMR;
|
||||
volatile ccsr_ddr_t *ddr = &immap->im_ddr;
|
||||
volatile ccsr_local_ecm_t *ecm = &immap->im_local_ecm;
|
||||
spd_eeprom_t spd;
|
||||
unsigned int memsize,tmp,tmp1,tmp2;
|
||||
unsigned char caslat;
|
||||
|
||||
i2c_read (SPD_EEPROM_ADDRESS, 0, 1, (uchar *) & spd, sizeof (spd));
|
||||
|
||||
if ( spd.nrows > 2 ) {
|
||||
printf("DDR:Only two chip selects are supported on ADS.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( spd.nrow_addr < 12 || spd.nrow_addr > 14 || spd.ncol_addr < 8 || spd.ncol_addr > 11) {
|
||||
printf("DDR:Row or Col number unsupported.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ddr->cs0_bnds = ((spd.row_dens>>2) - 1);
|
||||
ddr->cs0_config = ( 1<<31 | (spd.nrow_addr-12)<<8 | (spd.ncol_addr-8) );
|
||||
DEB(printf("\n"));
|
||||
DEB(printf("cs0_bnds = 0x%08x\n",ddr->cs0_bnds));
|
||||
DEB(printf("cs0_config = 0x%08x\n",ddr->cs0_config));
|
||||
if ( spd.nrows == 2 ) {
|
||||
ddr->cs1_bnds = ((spd.row_dens<<14) | ((spd.row_dens>>1) - 1));
|
||||
ddr->cs1_config = ( 1<<31 | (spd.nrow_addr-12)<<8 | (spd.ncol_addr-8) );
|
||||
DEB(printf("cs1_bnds = 0x%08x\n",ddr->cs1_bnds));
|
||||
DEB(printf("cs1_config = 0x%08x\n",ddr->cs1_config));
|
||||
}
|
||||
|
||||
memsize = spd.nrows * (4 * spd.row_dens);
|
||||
if( spd.mem_type == 0x07 ) {
|
||||
printf("DDR module detected, total size:%dMB.\n",memsize);
|
||||
} else {
|
||||
printf("No DDR module found!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(memsize) {
|
||||
case 16:
|
||||
tmp = 7; /* TLB size */
|
||||
tmp1 = 1; /* TLB entry number */
|
||||
tmp2 = 23; /* Local Access Window size */
|
||||
break;
|
||||
case 32:
|
||||
tmp = 7;
|
||||
tmp1 = 2;
|
||||
tmp2 = 24;
|
||||
break;
|
||||
case 64:
|
||||
tmp = 8;
|
||||
tmp1 = 1;
|
||||
tmp2 = 25;
|
||||
break;
|
||||
case 128:
|
||||
tmp = 8;
|
||||
tmp1 = 2;
|
||||
tmp2 = 26;
|
||||
break;
|
||||
case 256:
|
||||
tmp = 9;
|
||||
tmp1 = 1;
|
||||
tmp2 = 27;
|
||||
break;
|
||||
case 512:
|
||||
tmp = 9;
|
||||
tmp1 = 2;
|
||||
tmp2 = 28;
|
||||
break;
|
||||
case 1024:
|
||||
tmp = 10;
|
||||
tmp1 = 1;
|
||||
tmp2 = 29;
|
||||
break;
|
||||
default:
|
||||
printf("DDR:we only added support 16M,32M,64M,128M,256M,512M and 1G DDR I.\n");
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* configure DDR TLB to TLB1 Entry 4,5 */
|
||||
mtspr(MAS0, TLB1_MAS0(1,4,0));
|
||||
mtspr(MAS1, TLB1_MAS1(1,1,0,0,tmp));
|
||||
mtspr(MAS2, TLB1_MAS2(((CFG_DDR_SDRAM_BASE>>12) & 0xfffff),0,0,0,0,0,0,0,0));
|
||||
mtspr(MAS3, TLB1_MAS3(((CFG_DDR_SDRAM_BASE>>12) & 0xfffff),0,0,0,0,0,1,0,1,0,1));
|
||||
asm volatile("isync;msync;tlbwe;isync");
|
||||
DEB(printf("DDR:MAS0=0x%08x\n",TLB1_MAS0(1,4,0)));
|
||||
DEB(printf("DDR:MAS1=0x%08x\n",TLB1_MAS1(1,1,0,0,tmp)));
|
||||
DEB(printf("DDR:MAS2=0x%08x\n",TLB1_MAS2(((CFG_DDR_SDRAM_BASE>>12) \
|
||||
& 0xfffff),0,0,0,0,0,0,0,0)));
|
||||
DEB(printf("DDR:MAS3=0x%08x\n",TLB1_MAS3(((CFG_DDR_SDRAM_BASE>>12) \
|
||||
& 0xfffff),0,0,0,0,0,1,0,1,0,1)));
|
||||
|
||||
if(tmp1 == 2) {
|
||||
mtspr(MAS0, TLB1_MAS0(1,5,0));
|
||||
mtspr(MAS1, TLB1_MAS1(1,1,0,0,tmp));
|
||||
mtspr(MAS2, TLB1_MAS2((((CFG_DDR_SDRAM_BASE+(memsize*1024*1024)/2)>>12) \
|
||||
& 0xfffff),0,0,0,0,0,0,0,0));
|
||||
mtspr(MAS3, TLB1_MAS3((((CFG_DDR_SDRAM_BASE+(memsize*1024*1024)/2)>>12) \
|
||||
& 0xfffff),0,0,0,0,0,1,0,1,0,1));
|
||||
asm volatile("isync;msync;tlbwe;isync");
|
||||
DEB(printf("DDR:MAS0=0x%08x\n",TLB1_MAS0(1,5,0)));
|
||||
DEB(printf("DDR:MAS1=0x%08x\n",TLB1_MAS1(1,1,0,0,tmp)));
|
||||
DEB(printf("DDR:MAS2=0x%08x\n",TLB1_MAS2((((CFG_DDR_SDRAM_BASE \
|
||||
+(memsize*1024*1024)/2)>>12) & 0xfffff),0,0,0,0,0,0,0,0)));
|
||||
DEB(printf("DDR:MAS3=0x%08x\n",TLB1_MAS3((((CFG_DDR_SDRAM_BASE \
|
||||
+(memsize*1024*1024)/2)>>12) & 0xfffff),0,0,0,0,0,1,0,1,0,1)));
|
||||
}
|
||||
|
||||
#if defined(CONFIG_RAM_AS_FLASH)
|
||||
ecm->lawbar2 = ((CFG_DDR_SDRAM_BASE>>12) & 0xfffff);
|
||||
ecm->lawar2 = (LAWAR_EN | LAWAR_TRGT_IF_DDR | (LAWAR_SIZE & tmp2));
|
||||
DEB(printf("DDR:LAWBAR2=0x%08x\n",ecm->lawbar2));
|
||||
DEB(printf("DDR:LARAR2=0x%08x\n",ecm->lawar2));
|
||||
#else
|
||||
ecm->lawbar1 = ((CFG_DDR_SDRAM_BASE>>12) & 0xfffff);
|
||||
ecm->lawar1 = (LAWAR_EN | LAWAR_TRGT_IF_DDR | (LAWAR_SIZE & tmp2));
|
||||
DEB(printf("DDR:LAWBAR1=0x%08x\n",ecm->lawbar1));
|
||||
DEB(printf("DDR:LARAR1=0x%08x\n",ecm->lawar1));
|
||||
#endif
|
||||
|
||||
tmp = 20000/(((spd.clk_cycle & 0xF0) >> 4) * 10 + (spd.clk_cycle & 0x0f));
|
||||
DEB(printf("DDR:Module maximum data rate is: %dMhz\n",tmp));
|
||||
|
||||
/* find the largest CAS */
|
||||
if(spd.cas_lat & 0x40) {
|
||||
caslat = 7;
|
||||
} else if (spd.cas_lat & 0x20) {
|
||||
caslat = 6;
|
||||
} else if (spd.cas_lat & 0x10) {
|
||||
caslat = 5;
|
||||
} else if (spd.cas_lat & 0x08) {
|
||||
caslat = 4;
|
||||
} else if (spd.cas_lat & 0x04) {
|
||||
caslat = 3;
|
||||
} else if (spd.cas_lat & 0x02) {
|
||||
caslat = 2;
|
||||
} else if (spd.cas_lat & 0x01) {
|
||||
caslat = 1;
|
||||
} else {
|
||||
printf("DDR:no valid CAS Latency information.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmp1 = get_bus_freq(0)/1000000;
|
||||
if(tmp1<230 && tmp1>=90 && tmp>=230) { /* 90~230 range, treated as DDR 200 */
|
||||
if(spd.clk_cycle3 == 0xa0) caslat -= 2;
|
||||
else if(spd.clk_cycle2 == 0xa0) caslat--;
|
||||
} else if(tmp1<280 && tmp1>=230 && tmp>=280) { /* 230-280 range, treated as DDR 266 */
|
||||
if(spd.clk_cycle3 == 0x75) caslat -= 2;
|
||||
else if(spd.clk_cycle2 == 0x75) caslat--;
|
||||
} else if(tmp1<350 && tmp1>=280 && tmp>=350) { /* 280~350 range, treated as DDR 333 */
|
||||
if(spd.clk_cycle3 == 0x60) caslat -= 2;
|
||||
else if(spd.clk_cycle2 == 0x60) caslat--;
|
||||
} else if(tmp1<90 || tmp1 >=350) { /* DDR rate out-of-range */
|
||||
printf("DDR:platform frequency is not fit for DDR rate\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* note: caslat must also be programmed into ddr->sdram_mode register */
|
||||
/* note: WRREC(Twr) and WRTORD(Twtr) are not in SPD,use conservative value here */
|
||||
#if 1
|
||||
ddr->timing_cfg_1 = (((ns2clk(spd.trp/4) & 0x07) << 28 ) | \
|
||||
((ns2clk(spd.tras) & 0x0f ) << 24 ) | \
|
||||
((ns2clk(spd.trcd/4) & 0x07) << 20 ) | \
|
||||
((caslat & 0x07)<< 16 ) | \
|
||||
(((ns2clk(spd.sset[6]) - 8) & 0x0f) << 12 ) | \
|
||||
( 0x300 ) | \
|
||||
((ns2clk(spd.trrd/4) & 0x07) << 4) | 1);
|
||||
#else
|
||||
ddr->timing_cfg_1 = 0x37344321;
|
||||
caslat = 4;
|
||||
#endif
|
||||
DEB(printf("DDR:timing_cfg_1=0x%08x\n",ddr->timing_cfg_1));
|
||||
|
||||
/* note: hand-coded value for timing_cfg_2, see Errata DDR1*/
|
||||
#if defined(CONFIG_MPC85xx_REV1)
|
||||
ddr->timing_cfg_2 = 0x00000800;
|
||||
#endif
|
||||
DEB(printf("DDR:timing_cfg_2=0x%08x\n",ddr->timing_cfg_2));
|
||||
|
||||
/* only DDR I is supported, DDR I and II have different mode-register-set definition */
|
||||
/* burst length is always 4 */
|
||||
switch(caslat) {
|
||||
case 2:
|
||||
ddr->sdram_mode = 0x52; /* 1.5 */
|
||||
break;
|
||||
case 3:
|
||||
ddr->sdram_mode = 0x22; /* 2.0 */
|
||||
break;
|
||||
case 4:
|
||||
ddr->sdram_mode = 0x62; /* 2.5 */
|
||||
break;
|
||||
case 5:
|
||||
ddr->sdram_mode = 0x32; /* 3.0 */
|
||||
break;
|
||||
default:
|
||||
printf("DDR:only CAS Latency 1.5,2.0,2.5,3.0 is supported.\n");
|
||||
return 0;
|
||||
}
|
||||
DEB(printf("DDR:sdram_mode=0x%08x\n",ddr->sdram_mode));
|
||||
|
||||
switch(spd.refresh) {
|
||||
case 0x00:
|
||||
case 0x80:
|
||||
tmp = ns2clk(15625);
|
||||
break;
|
||||
case 0x01:
|
||||
case 0x81:
|
||||
tmp = ns2clk(3900);
|
||||
break;
|
||||
case 0x02:
|
||||
case 0x82:
|
||||
tmp = ns2clk(7800);
|
||||
break;
|
||||
case 0x03:
|
||||
case 0x83:
|
||||
tmp = ns2clk(31300);
|
||||
break;
|
||||
case 0x04:
|
||||
case 0x84:
|
||||
tmp = ns2clk(62500);
|
||||
break;
|
||||
case 0x05:
|
||||
case 0x85:
|
||||
tmp = ns2clk(125000);
|
||||
break;
|
||||
default:
|
||||
tmp = 0x512;
|
||||
break;
|
||||
}
|
||||
|
||||
/* set BSTOPRE to 0x100 for page mode, if auto-charge is used, set BSTOPRE = 0 */
|
||||
ddr->sdram_interval = ((tmp & 0x3fff) << 16) | 0x100;
|
||||
DEB(printf("DDR:sdram_interval=0x%08x\n",ddr->sdram_interval));
|
||||
|
||||
/* is this an ECC DDR chip? */
|
||||
#if defined(CONFIG_DDR_ECC)
|
||||
if(spd.config == 0x02) {
|
||||
ddr->err_disable = 0x0000000d;
|
||||
ddr->err_sbe = 0x00ff0000;
|
||||
}
|
||||
DEB(printf("DDR:err_disable=0x%08x\n",ddr->err_disable));
|
||||
DEB(printf("DDR:err_sbe=0x%08x\n",ddr->err_sbe));
|
||||
#endif
|
||||
asm("sync;isync;msync");
|
||||
|
||||
udelay(500);
|
||||
|
||||
/* registered or unbuffered? */
|
||||
#if defined(CONFIG_DDR_ECC)
|
||||
ddr->sdram_cfg = (spd.config == 0x02)?0x20000000:0x0;
|
||||
#endif
|
||||
ddr->sdram_cfg = 0xc2000000|((spd.mod_attr == 0x20) ? 0x0 : \
|
||||
((spd.mod_attr == 0x26) ? 0x10000000:0x0));
|
||||
asm("sync;isync;msync");
|
||||
|
||||
udelay(500);
|
||||
|
||||
DEB(printf("DDR:sdram_cfg=0x%08x\n",ddr->sdram_cfg));
|
||||
|
||||
return (memsize*1024*1024);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SPD_EEPROM */
|
||||
124
cpu/mpc85xx/speed.c
Normal file
124
cpu/mpc85xx/speed.c
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* (C) Copyright 2003 Motorola Inc.
|
||||
* Xianghua Xiao, (X.Xiao@motorola.com)
|
||||
*
|
||||
* (C) Copyright 2000
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <ppc_asm.tmpl>
|
||||
#include <asm/processor.h>
|
||||
|
||||
/* --------------------------------------------------------------- */
|
||||
|
||||
#define ONE_BILLION 1000000000
|
||||
|
||||
void get_sys_info (sys_info_t * sysInfo)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *)CFG_IMMR;
|
||||
volatile ccsr_gur_t *gur = &immap->im_gur;
|
||||
uint plat_ratio,e500_ratio;
|
||||
|
||||
plat_ratio = (gur->porpllsr) & 0x0000003e;
|
||||
plat_ratio >>= 1;
|
||||
switch(plat_ratio) {
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
case 0x0a:
|
||||
case 0x0c:
|
||||
case 0x10:
|
||||
sysInfo->freqSystemBus = plat_ratio * CONFIG_SYS_CLK_FREQ;
|
||||
break;
|
||||
default:
|
||||
sysInfo->freqSystemBus = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
e500_ratio = (gur->porpllsr) & 0x003f0000;
|
||||
e500_ratio >>= 16;
|
||||
switch(e500_ratio) {
|
||||
case 0x04:
|
||||
sysInfo->freqProcessor = 2*sysInfo->freqSystemBus;
|
||||
break;
|
||||
case 0x05:
|
||||
sysInfo->freqProcessor = 5*sysInfo->freqSystemBus/2;
|
||||
break;
|
||||
case 0x06:
|
||||
sysInfo->freqProcessor = 3*sysInfo->freqSystemBus;
|
||||
break;
|
||||
case 0x07:
|
||||
sysInfo->freqProcessor = 7*sysInfo->freqSystemBus/2;
|
||||
break;
|
||||
default:
|
||||
sysInfo->freqProcessor = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int get_clocks (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
sys_info_t sys_info;
|
||||
#if defined(CONFIG_MPC8560)
|
||||
volatile immap_t *immap = (immap_t *) CFG_IMMR;
|
||||
uint sccr, dfbrg;
|
||||
|
||||
/* set VCO = 4 * BRG */
|
||||
immap->im_cpm.im_cpm_intctl.sccr &= 0xfffffffc;
|
||||
sccr = immap->im_cpm.im_cpm_intctl.sccr;
|
||||
dfbrg = (sccr & SCCR_DFBRG_MSK) >> SCCR_DFBRG_SHIFT;
|
||||
#endif
|
||||
get_sys_info (&sys_info);
|
||||
gd->cpu_clk = sys_info.freqProcessor;
|
||||
gd->bus_clk = sys_info.freqSystemBus;
|
||||
#if defined(CONFIG_MPC8560)
|
||||
gd->vco_out = 2*sys_info.freqSystemBus;
|
||||
gd->cpm_clk = gd->vco_out / 2;
|
||||
gd->scc_clk = gd->vco_out / 4;
|
||||
gd->brg_clk = gd->vco_out / (1 << (2 * (dfbrg + 1)));
|
||||
#endif
|
||||
|
||||
if(gd->cpu_clk != 0) return (0);
|
||||
else return (1);
|
||||
}
|
||||
|
||||
|
||||
/********************************************
|
||||
* get_bus_freq
|
||||
* return system bus freq in Hz
|
||||
*********************************************/
|
||||
ulong get_bus_freq (ulong dummy)
|
||||
{
|
||||
ulong val;
|
||||
|
||||
sys_info_t sys_info;
|
||||
|
||||
get_sys_info (&sys_info);
|
||||
val = sys_info.freqSystemBus;
|
||||
|
||||
return val;
|
||||
}
|
||||
1156
cpu/mpc85xx/start.S
Normal file
1156
cpu/mpc85xx/start.S
Normal file
File diff suppressed because it is too large
Load Diff
272
cpu/mpc85xx/traps.c
Normal file
272
cpu/mpc85xx/traps.c
Normal file
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* linux/arch/ppc/kernel/traps.c
|
||||
*
|
||||
* Copyright (C) 2003 Motorola
|
||||
* Modified by Xianghua Xiao(x.xiao@motorola.com)
|
||||
*
|
||||
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
|
||||
*
|
||||
* Modified by Cort Dougan (cort@cs.nmt.edu)
|
||||
* and Paul Mackerras (paulus@cs.anu.edu.au)
|
||||
*
|
||||
* (C) Copyright 2000
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file handles the architecture-dependent parts of hardware exceptions
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
|
||||
int (*debugger_exception_handler)(struct pt_regs *) = 0;
|
||||
#endif
|
||||
|
||||
/* Returns 0 if exception not found and fixup otherwise. */
|
||||
extern unsigned long search_exception_table(unsigned long);
|
||||
|
||||
/* THIS NEEDS CHANGING to use the board info structure.
|
||||
*/
|
||||
#define END_OF_MEM (CFG_SDRAM_SIZE * 1024 * 1024)
|
||||
|
||||
|
||||
static __inline__ void set_tsr(unsigned long val)
|
||||
{
|
||||
asm volatile("mtspr 0x150, %0" : : "r" (val));
|
||||
}
|
||||
|
||||
static __inline__ unsigned long get_esr(void)
|
||||
{
|
||||
unsigned long val;
|
||||
asm volatile("mfspr %0, 0x03e" : "=r" (val) :);
|
||||
return val;
|
||||
}
|
||||
|
||||
#define ESR_MCI 0x80000000
|
||||
#define ESR_PIL 0x08000000
|
||||
#define ESR_PPR 0x04000000
|
||||
#define ESR_PTR 0x02000000
|
||||
#define ESR_DST 0x00800000
|
||||
#define ESR_DIZ 0x00400000
|
||||
#define ESR_U0F 0x00008000
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
|
||||
extern void do_bedbug_breakpoint(struct pt_regs *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Trap & Exception support
|
||||
*/
|
||||
|
||||
void
|
||||
print_backtrace(unsigned long *sp)
|
||||
{
|
||||
int cnt = 0;
|
||||
unsigned long i;
|
||||
|
||||
printf("Call backtrace: ");
|
||||
while (sp) {
|
||||
if ((uint)sp > END_OF_MEM)
|
||||
break;
|
||||
|
||||
i = sp[1];
|
||||
if (cnt++ % 7 == 0)
|
||||
printf("\n");
|
||||
printf("%08lX ", i);
|
||||
if (cnt > 32) break;
|
||||
sp = (unsigned long *)*sp;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void show_regs(struct pt_regs * regs)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DAR: %08lX\n",
|
||||
regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
|
||||
printf("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
|
||||
regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
|
||||
regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
|
||||
regs->msr&MSR_IR ? 1 : 0,
|
||||
regs->msr&MSR_DR ? 1 : 0);
|
||||
|
||||
printf("\n");
|
||||
for (i = 0; i < 32; i++) {
|
||||
if ((i % 8) == 0)
|
||||
{
|
||||
printf("GPR%02d: ", i);
|
||||
}
|
||||
|
||||
printf("%08lX ", regs->gpr[i]);
|
||||
if ((i % 8) == 7)
|
||||
{
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_exception(int signr, struct pt_regs *regs)
|
||||
{
|
||||
show_regs(regs);
|
||||
print_backtrace((unsigned long *)regs->gpr[1]);
|
||||
panic("Exception in kernel pc %lx signal %d",regs->nip,signr);
|
||||
}
|
||||
|
||||
void
|
||||
CritcalInputException(struct pt_regs *regs)
|
||||
{
|
||||
panic("Critical Input Exception");
|
||||
}
|
||||
|
||||
void
|
||||
MachineCheckException(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long fixup;
|
||||
|
||||
/* Probing PCI using config cycles cause this exception
|
||||
* when a device is not present. Catch it and return to
|
||||
* the PCI exception handler.
|
||||
*/
|
||||
if ((fixup = search_exception_table(regs->nip)) != 0) {
|
||||
regs->nip = fixup;
|
||||
return;
|
||||
}
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
|
||||
if (debugger_exception_handler && (*debugger_exception_handler)(regs))
|
||||
return;
|
||||
#endif
|
||||
|
||||
printf("Machine check in kernel mode.\n");
|
||||
printf("Caused by (from msr): ");
|
||||
printf("regs %p ",regs);
|
||||
switch( regs->msr & 0x0000F000)
|
||||
{
|
||||
case (1<<12) :
|
||||
printf("Machine check signal - probably due to mm fault\n"
|
||||
"with mmu off\n");
|
||||
break;
|
||||
case (1<<13) :
|
||||
printf("Transfer error ack signal\n");
|
||||
break;
|
||||
case (1<<14) :
|
||||
printf("Data parity signal\n");
|
||||
break;
|
||||
case (1<<15) :
|
||||
printf("Address parity signal\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown values in msr\n");
|
||||
}
|
||||
show_regs(regs);
|
||||
print_backtrace((unsigned long *)regs->gpr[1]);
|
||||
panic("machine check");
|
||||
}
|
||||
|
||||
void
|
||||
AlignmentException(struct pt_regs *regs)
|
||||
{
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
|
||||
if (debugger_exception_handler && (*debugger_exception_handler)(regs))
|
||||
return;
|
||||
#endif
|
||||
|
||||
show_regs(regs);
|
||||
print_backtrace((unsigned long *)regs->gpr[1]);
|
||||
panic("Alignment Exception");
|
||||
}
|
||||
|
||||
void
|
||||
ProgramCheckException(struct pt_regs *regs)
|
||||
{
|
||||
long esr_val;
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
|
||||
if (debugger_exception_handler && (*debugger_exception_handler)(regs))
|
||||
return;
|
||||
#endif
|
||||
|
||||
show_regs(regs);
|
||||
|
||||
esr_val = get_esr();
|
||||
if( esr_val & ESR_PIL )
|
||||
printf( "** Illegal Instruction **\n" );
|
||||
else if( esr_val & ESR_PPR )
|
||||
printf( "** Privileged Instruction **\n" );
|
||||
else if( esr_val & ESR_PTR )
|
||||
printf( "** Trap Instruction **\n" );
|
||||
|
||||
print_backtrace((unsigned long *)regs->gpr[1]);
|
||||
panic("Program Check Exception");
|
||||
}
|
||||
|
||||
void
|
||||
PITException(struct pt_regs *regs)
|
||||
{
|
||||
/*
|
||||
* Reset PIT interrupt
|
||||
*/
|
||||
set_tsr(0x0c000000);
|
||||
|
||||
/*
|
||||
* Call timer_interrupt routine in interrupts.c
|
||||
*/
|
||||
timer_interrupt(NULL);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
UnknownException(struct pt_regs *regs)
|
||||
{
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
|
||||
if (debugger_exception_handler && (*debugger_exception_handler)(regs))
|
||||
return;
|
||||
#endif
|
||||
|
||||
printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
|
||||
regs->nip, regs->msr, regs->trap);
|
||||
_exception(0, regs);
|
||||
}
|
||||
|
||||
void
|
||||
DebugException(struct pt_regs *regs)
|
||||
{
|
||||
printf("Debugger trap at @ %lx\n", regs->nip );
|
||||
show_regs(regs);
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
|
||||
do_bedbug_breakpoint( regs );
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Probe an address by reading. If not present, return -1, otherwise
|
||||
* return 0.
|
||||
*/
|
||||
int
|
||||
addr_probe(uint *addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
441
cpu/mpc85xx/tsec.c
Normal file
441
cpu/mpc85xx/tsec.c
Normal file
@@ -0,0 +1,441 @@
|
||||
/*
|
||||
* tsec.c
|
||||
* Motorola Three Speed Ethernet Controller driver
|
||||
*
|
||||
* This software may be used and distributed according to the
|
||||
* terms of the GNU Public License, Version 2, incorporated
|
||||
* herein by reference.
|
||||
*
|
||||
* (C) Copyright 2003, Motorola, Inc.
|
||||
* maintained by Xianghua Xiao (x.xiao@motorola.com)
|
||||
* author Andy Fleming
|
||||
*
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <mpc85xx.h>
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
#include <net.h>
|
||||
#include <command.h>
|
||||
|
||||
#if defined(CONFIG_TSEC_ENET)
|
||||
#include "tsec.h"
|
||||
|
||||
#define TX_BUF_CNT 2
|
||||
|
||||
#undef TSEC_DEBUG
|
||||
#ifdef TSEC_DEBUG
|
||||
#define DBGPRINT(x) printf(x)
|
||||
#else
|
||||
#define DBGPRINT(x)
|
||||
#endif
|
||||
|
||||
static uint rxIdx; /* index of the current RX buffer */
|
||||
static uint txIdx; /* index of the current TX buffer */
|
||||
|
||||
typedef volatile struct rtxbd {
|
||||
txbd8_t txbd[TX_BUF_CNT];
|
||||
rxbd8_t rxbd[PKTBUFSRX];
|
||||
} RTXBD;
|
||||
|
||||
#ifdef __GNUC__
|
||||
static RTXBD rtx __attribute__ ((aligned(8)));
|
||||
#else
|
||||
#error "rtx must be 64-bit aligned"
|
||||
#endif
|
||||
|
||||
static int tsec_send(struct eth_device* dev, volatile void *packet, int length);
|
||||
static int tsec_recv(struct eth_device* dev);
|
||||
static int tsec_init(struct eth_device* dev, bd_t * bd);
|
||||
static void tsec_halt(struct eth_device* dev);
|
||||
static void init_registers(tsec_t *regs);
|
||||
static void startup_tsec(tsec_t *regs);
|
||||
static void init_phy(tsec_t *regs);
|
||||
|
||||
/* Initialize device structure. returns 0 on failure, 1 on
|
||||
* success */
|
||||
int tsec_initialize(bd_t *bis)
|
||||
{
|
||||
struct eth_device* dev;
|
||||
int i;
|
||||
|
||||
dev = (struct eth_device*) malloc(sizeof *dev);
|
||||
|
||||
if(dev == NULL)
|
||||
return 0;
|
||||
|
||||
memset(dev, 0, sizeof *dev);
|
||||
|
||||
sprintf(dev->name, "MOTOROLA ETHERNET");
|
||||
dev->iobase = 0;
|
||||
dev->priv = 0;
|
||||
dev->init = tsec_init;
|
||||
dev->halt = tsec_halt;
|
||||
dev->send = tsec_send;
|
||||
dev->recv = tsec_recv;
|
||||
|
||||
/* Tell u-boot to get the addr from the env */
|
||||
for(i=0;i<6;i++)
|
||||
dev->enetaddr[i] = 0;
|
||||
|
||||
eth_register(dev);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Initializes data structures and registers for the controller,
|
||||
* and brings the interface up */
|
||||
int tsec_init(struct eth_device* dev, bd_t * bd)
|
||||
{
|
||||
tsec_t *regs;
|
||||
uint tempval;
|
||||
char tmpbuf[MAC_ADDR_LEN];
|
||||
int i;
|
||||
|
||||
regs = (tsec_t *)(TSEC_BASE_ADDR);
|
||||
|
||||
/* Make sure the controller is stopped */
|
||||
tsec_halt(dev);
|
||||
|
||||
/* Reset the MAC */
|
||||
regs->maccfg1 |= MACCFG1_SOFT_RESET;
|
||||
|
||||
/* Clear MACCFG1[Soft_Reset] */
|
||||
regs->maccfg1 &= ~(MACCFG1_SOFT_RESET);
|
||||
|
||||
/* Init MACCFG2. Defaults to GMII/MII */
|
||||
regs->maccfg2 = MACCFG2_INIT_SETTINGS;
|
||||
|
||||
/* Init ECNTRL */
|
||||
regs->ecntrl = ECNTRL_INIT_SETTINGS;
|
||||
|
||||
/* Copy the station address into the address registers.
|
||||
* Backwards, because little endian MACS are dumb */
|
||||
for(i=0;i<MAC_ADDR_LEN;i++) {
|
||||
tmpbuf[MAC_ADDR_LEN - 1 - i] = bd->bi_enetaddr[i];
|
||||
}
|
||||
(uint)(regs->macstnaddr1) = *((uint *)(tmpbuf));
|
||||
|
||||
tempval = *((uint *)(tmpbuf +4));
|
||||
|
||||
(uint)(regs->macstnaddr2) = tempval;
|
||||
|
||||
/* Initialize the PHY */
|
||||
init_phy(regs);
|
||||
|
||||
/* reset the indices to zero */
|
||||
rxIdx = 0;
|
||||
txIdx = 0;
|
||||
|
||||
/* Clear out (for the most part) the other registers */
|
||||
init_registers(regs);
|
||||
|
||||
/* Ready the device for tx/rx */
|
||||
startup_tsec(regs);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Reads from the register at offset in the PHY at phyid, */
|
||||
/* using the register set defined in regbase. It waits until the */
|
||||
/* bits in the miimstat are valid (miimind notvalid bit cleared), */
|
||||
/* and then passes those bits on to the variable specified in */
|
||||
/* value */
|
||||
/* Before it does the read, it needs to clear the command field */
|
||||
uint read_phy_reg(tsec_t *regbase, uint phyid, uint offset)
|
||||
{
|
||||
uint value;
|
||||
|
||||
/* Put the address of the phy, and the register number into
|
||||
* MIIMADD
|
||||
*/
|
||||
regbase->miimadd = (phyid << 8) | offset;
|
||||
|
||||
/* Clear the command register, and wait */
|
||||
regbase->miimcom = 0;
|
||||
asm("msync");
|
||||
|
||||
/* Initiate a read command, and wait */
|
||||
regbase->miimcom = MIIM_READ_COMMAND;
|
||||
asm("msync");
|
||||
|
||||
/* Wait for the the indication that the read is done */
|
||||
while((regbase->miimind & (MIIMIND_NOTVALID | MIIMIND_BUSY)));
|
||||
|
||||
/* Grab the value read from the PHY */
|
||||
value = regbase->miimstat;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Setup the PHY */
|
||||
static void init_phy(tsec_t *regs)
|
||||
{
|
||||
uint testval;
|
||||
unsigned int timeout = TSEC_TIMEOUT;
|
||||
|
||||
/* Assign a Physical address to the TBI */
|
||||
regs->tbipa=TBIPA_VALUE;
|
||||
|
||||
/* reset the management interface */
|
||||
regs->miimcfg=MIIMCFG_RESET;
|
||||
|
||||
regs->miimcfg=MIIMCFG_INIT_VALUE;
|
||||
|
||||
/* Wait until the bus is free */
|
||||
while(regs->miimind & MIIMIND_BUSY);
|
||||
|
||||
#ifdef CONFIG_PHY_CIS8201
|
||||
/* override PHY config settings */
|
||||
write_phy_reg(regs, 0, MIIM_AUX_CONSTAT, MIIM_AUXCONSTAT_INIT);
|
||||
|
||||
/* Set up interface mode */
|
||||
write_phy_reg(regs, 0, MIIM_EXT_CON1, MIIM_EXTCON1_INIT);
|
||||
#endif
|
||||
|
||||
/* Set the PHY to gigabit, full duplex, Auto-negotiate */
|
||||
write_phy_reg(regs, 0, MIIM_CONTROL, MIIM_CONTROL_INIT);
|
||||
|
||||
/* Wait until TBI_STATUS indicates AN is done */
|
||||
DBGPRINT("Waiting for Auto-negotiation to complete\n");
|
||||
testval=read_phy_reg(regs, 0, MIIM_TBI_STATUS);
|
||||
|
||||
while((!(testval & MIIM_TBI_STATUS_AN_DONE))&& timeout--) {
|
||||
testval=read_phy_reg(regs, 0, MIIM_TBI_STATUS);
|
||||
}
|
||||
|
||||
if(testval & MIIM_TBI_STATUS_AN_DONE)
|
||||
DBGPRINT("Auto-negotiation done\n");
|
||||
else
|
||||
DBGPRINT("Auto-negotiation timed-out.\n");
|
||||
|
||||
#ifdef CONFIG_PHY_CIS8201
|
||||
/* Find out what duplexity (duplicity?) we have */
|
||||
/* Read it twice to make sure */
|
||||
testval=read_phy_reg(regs, 0, MIIM_AUX_CONSTAT);
|
||||
|
||||
if(testval & MIIM_AUXCONSTAT_DUPLEX) {
|
||||
DBGPRINT("Enet starting in full duplex\n");
|
||||
regs->maccfg2 |= MACCFG2_FULL_DUPLEX;
|
||||
} else {
|
||||
DBGPRINT("Enet starting in half duplex\n");
|
||||
regs->maccfg2 &= ~MACCFG2_FULL_DUPLEX;
|
||||
}
|
||||
|
||||
/* Also, we look to see what speed we are at
|
||||
* if Gigabit, MACCFG2 goes in GMII, otherwise,
|
||||
* MII mode.
|
||||
*/
|
||||
if((testval & MIIM_AUXCONSTAT_SPEED) != MIIM_AUXCONSTAT_GBIT) {
|
||||
if((testval & MIIM_AUXCONSTAT_SPEED) == MIIM_AUXCONSTAT_100)
|
||||
DBGPRINT("Enet starting in 100BT\n");
|
||||
else
|
||||
DBGPRINT("Enet starting in 10BT\n");
|
||||
|
||||
/* mark the mode in MACCFG2 */
|
||||
regs->maccfg2 = ((regs->maccfg2&~(MACCFG2_IF)) | MACCFG2_MII);
|
||||
} else {
|
||||
DBGPRINT("Enet starting in 1000BT\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PHY_M88E1011
|
||||
/* Read the PHY to see what speed and duplex we are */
|
||||
testval=read_phy_reg(regs, 0, MIIM_PHY_STATUS);
|
||||
|
||||
timeout = TSEC_TIMEOUT;
|
||||
while((!(testval & MIIM_PHYSTAT_SPDDONE)) && timeout--) {
|
||||
testval = read_phy_reg(regs,0,MIIM_PHY_STATUS);
|
||||
}
|
||||
|
||||
if(!(testval & MIIM_PHYSTAT_SPDDONE))
|
||||
DBGPRINT("Enet: Speed not resolved\n");
|
||||
|
||||
testval=read_phy_reg(regs, 0, MIIM_PHY_STATUS);
|
||||
if(testval & MIIM_PHYSTAT_DUPLEX) {
|
||||
DBGPRINT("Enet starting in Full Duplex\n");
|
||||
regs->maccfg2 |= MACCFG2_FULL_DUPLEX;
|
||||
} else {
|
||||
DBGPRINT("Enet starting in Half Duplex\n");
|
||||
regs->maccfg2 &= ~MACCFG2_FULL_DUPLEX;
|
||||
}
|
||||
|
||||
if(!((testval&MIIM_PHYSTAT_SPEED) == MIIM_PHYSTAT_GBIT)) {
|
||||
if((testval & MIIM_PHYSTAT_SPEED) == MIIM_PHYSTAT_100)
|
||||
DBGPRINT("Enet starting in 100BT\n");
|
||||
else
|
||||
DBGPRINT("Enet starting in 10BT\n");
|
||||
|
||||
regs->maccfg2 = ((regs->maccfg2&~(MACCFG2_IF)) | MACCFG2_MII);
|
||||
} else {
|
||||
DBGPRINT("Enet starting in 1000BT\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void init_registers(tsec_t *regs)
|
||||
{
|
||||
/* Clear IEVENT */
|
||||
regs->ievent = IEVENT_INIT_CLEAR;
|
||||
|
||||
regs->imask = IMASK_INIT_CLEAR;
|
||||
|
||||
regs->hash.iaddr0 = 0;
|
||||
regs->hash.iaddr1 = 0;
|
||||
regs->hash.iaddr2 = 0;
|
||||
regs->hash.iaddr3 = 0;
|
||||
regs->hash.iaddr4 = 0;
|
||||
regs->hash.iaddr5 = 0;
|
||||
regs->hash.iaddr6 = 0;
|
||||
regs->hash.iaddr7 = 0;
|
||||
|
||||
regs->hash.gaddr0 = 0;
|
||||
regs->hash.gaddr1 = 0;
|
||||
regs->hash.gaddr2 = 0;
|
||||
regs->hash.gaddr3 = 0;
|
||||
regs->hash.gaddr4 = 0;
|
||||
regs->hash.gaddr5 = 0;
|
||||
regs->hash.gaddr6 = 0;
|
||||
regs->hash.gaddr7 = 0;
|
||||
|
||||
regs->rctrl = 0x00000000;
|
||||
|
||||
/* Init RMON mib registers */
|
||||
memset((void *)&(regs->rmon), 0, sizeof(rmon_mib_t));
|
||||
|
||||
regs->rmon.cam1 = 0xffffffff;
|
||||
regs->rmon.cam2 = 0xffffffff;
|
||||
|
||||
regs->mrblr = MRBLR_INIT_SETTINGS;
|
||||
|
||||
regs->minflr = MINFLR_INIT_SETTINGS;
|
||||
|
||||
regs->attr = ATTR_INIT_SETTINGS;
|
||||
regs->attreli = ATTRELI_INIT_SETTINGS;
|
||||
|
||||
}
|
||||
|
||||
static void startup_tsec(tsec_t *regs)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Point to the buffer descriptors */
|
||||
regs->tbase = (unsigned int)(&rtx.txbd[txIdx]);
|
||||
regs->rbase = (unsigned int)(&rtx.rxbd[rxIdx]);
|
||||
|
||||
/* Initialize the Rx Buffer descriptors */
|
||||
for (i = 0; i < PKTBUFSRX; i++) {
|
||||
rtx.rxbd[i].status = RXBD_EMPTY;
|
||||
rtx.rxbd[i].length = 0;
|
||||
rtx.rxbd[i].bufPtr = (uint)NetRxPackets[i];
|
||||
}
|
||||
rtx.rxbd[PKTBUFSRX -1].status |= RXBD_WRAP;
|
||||
|
||||
/* Initialize the TX Buffer Descriptors */
|
||||
for(i=0; i<TX_BUF_CNT; i++) {
|
||||
rtx.txbd[i].status = 0;
|
||||
rtx.txbd[i].length = 0;
|
||||
rtx.txbd[i].bufPtr = 0;
|
||||
}
|
||||
rtx.txbd[TX_BUF_CNT -1].status |= TXBD_WRAP;
|
||||
|
||||
/* Enable Transmit and Receive */
|
||||
regs->maccfg1 |= (MACCFG1_RX_EN | MACCFG1_TX_EN);
|
||||
|
||||
/* Tell the DMA it is clear to go */
|
||||
regs->dmactrl |= DMACTRL_INIT_SETTINGS;
|
||||
regs->tstat = TSTAT_CLEAR_THALT;
|
||||
regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS);
|
||||
}
|
||||
|
||||
/* This returns the status bits of the device. The return value
|
||||
* is never checked, and this is what the 8260 driver did, so we
|
||||
* do the same. Presumably, this would be zero if there were no
|
||||
* errors */
|
||||
static int tsec_send(struct eth_device* dev, volatile void *packet, int length)
|
||||
{
|
||||
int i;
|
||||
int result = 0;
|
||||
tsec_t * regs = (tsec_t *)(TSEC_BASE_ADDR);
|
||||
|
||||
/* Find an empty buffer descriptor */
|
||||
for(i=0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
|
||||
if (i >= TOUT_LOOP) {
|
||||
DBGPRINT("tsec: tx buffers full\n");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
rtx.txbd[txIdx].bufPtr = (uint)packet;
|
||||
rtx.txbd[txIdx].length = length;
|
||||
rtx.txbd[txIdx].status |= (TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT);
|
||||
|
||||
/* Tell the DMA to go */
|
||||
regs->tstat = TSTAT_CLEAR_THALT;
|
||||
|
||||
/* Wait for buffer to be transmitted */
|
||||
for(i=0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
|
||||
if (i >= TOUT_LOOP) {
|
||||
DBGPRINT("tsec: tx error\n");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
txIdx = (txIdx + 1) % TX_BUF_CNT;
|
||||
result = rtx.txbd[txIdx].status & TXBD_STATS;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int tsec_recv(struct eth_device* dev)
|
||||
{
|
||||
int length;
|
||||
tsec_t *regs = (tsec_t *)(TSEC_BASE_ADDR);
|
||||
|
||||
while(!(rtx.rxbd[rxIdx].status & RXBD_EMPTY)) {
|
||||
|
||||
length = rtx.rxbd[rxIdx].length;
|
||||
|
||||
/* Send the packet up if there were no errors */
|
||||
if (!(rtx.rxbd[rxIdx].status & RXBD_STATS)) {
|
||||
NetReceive(NetRxPackets[rxIdx], length - 4);
|
||||
}
|
||||
|
||||
rtx.rxbd[rxIdx].length = 0;
|
||||
|
||||
/* Set the wrap bit if this is the last element in the list */
|
||||
rtx.rxbd[rxIdx].status = RXBD_EMPTY | (((rxIdx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0);
|
||||
|
||||
rxIdx = (rxIdx + 1) % PKTBUFSRX;
|
||||
}
|
||||
|
||||
if(regs->ievent&IEVENT_BSY) {
|
||||
regs->ievent = IEVENT_BSY;
|
||||
regs->rstat = RSTAT_CLEAR_RHALT;
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void tsec_halt(struct eth_device* dev)
|
||||
{
|
||||
tsec_t *regs = (tsec_t *)(TSEC_BASE_ADDR);
|
||||
|
||||
regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS);
|
||||
regs->dmactrl |= (DMACTRL_GRS | DMACTRL_GTS);
|
||||
|
||||
while(!(regs->ievent & (IEVENT_GRSC | IEVENT_GTSC)));
|
||||
|
||||
regs->maccfg1 &= ~(MACCFG1_TX_EN | MACCFG1_RX_EN);
|
||||
|
||||
}
|
||||
#endif /* CONFIG_TSEC_ENET */
|
||||
393
cpu/mpc85xx/tsec.h
Normal file
393
cpu/mpc85xx/tsec.h
Normal file
@@ -0,0 +1,393 @@
|
||||
/*
|
||||
* tsec.h
|
||||
*
|
||||
* Driver for the Motorola Triple Speed Ethernet Controller
|
||||
*
|
||||
* This software may be used and distributed according to the
|
||||
* terms of the GNU Public License, Version 2, incorporated
|
||||
* herein by reference.
|
||||
*
|
||||
* (C) Copyright 2003, Motorola, Inc.
|
||||
* maintained by Xianghua Xiao (x.xiao@motorola.com)
|
||||
* author Andy Fleming
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __TSEC_H
|
||||
#define __TSEC_H
|
||||
|
||||
#include <net.h>
|
||||
#include <mpc85xx.h>
|
||||
|
||||
#define TSEC_BASE_ADDR (CFG_IMMR + 0x24000)
|
||||
#define TSEC_MEM_SIZE 0x01000
|
||||
|
||||
#define MAC_ADDR_LEN 6
|
||||
|
||||
#define TSEC_TIMEOUT 1000000
|
||||
#define TOUT_LOOP 1000000
|
||||
|
||||
/* MAC register bits */
|
||||
#define MACCFG1_SOFT_RESET 0x80000000
|
||||
#define MACCFG1_RESET_RX_MC 0x00080000
|
||||
#define MACCFG1_RESET_TX_MC 0x00040000
|
||||
#define MACCFG1_RESET_RX_FUN 0x00020000
|
||||
#define MACCFG1_RESET_TX_FUN 0x00010000
|
||||
#define MACCFG1_LOOPBACK 0x00000100
|
||||
#define MACCFG1_RX_FLOW 0x00000020
|
||||
#define MACCFG1_TX_FLOW 0x00000010
|
||||
#define MACCFG1_SYNCD_RX_EN 0x00000008
|
||||
#define MACCFG1_RX_EN 0x00000004
|
||||
#define MACCFG1_SYNCD_TX_EN 0x00000002
|
||||
#define MACCFG1_TX_EN 0x00000001
|
||||
|
||||
#define MACCFG2_INIT_SETTINGS 0x00007205
|
||||
#define MACCFG2_FULL_DUPLEX 0x00000001
|
||||
#define MACCFG2_IF 0x00000300
|
||||
#define MACCFG2_MII 0x00000100
|
||||
|
||||
#define ECNTRL_INIT_SETTINGS 0x00001000
|
||||
#define ECNTRL_TBI_MODE 0x00000020
|
||||
|
||||
#define TBIPA_VALUE 0x1f
|
||||
#define MIIMCFG_INIT_VALUE 0x00000003
|
||||
#define MIIMCFG_RESET 0x80000000
|
||||
|
||||
#define MIIMIND_BUSY 0x00000001
|
||||
#define MIIMIND_NOTVALID 0x00000004
|
||||
|
||||
#define MIIM_TBICON 0x11
|
||||
#define MIIM_TBICON_GMII 0x00000010
|
||||
#define MIIM_TBICON_AN 0x00000100
|
||||
|
||||
#define MIIM_CONTROL 0x00
|
||||
#define MIIM_CONTROL_INIT 0x00001140
|
||||
#define MIIM_ANEN 0x00001000
|
||||
|
||||
#define MIIM_TBI_STATUS 0x1
|
||||
#define MIIM_TBI_STATUS_AN_DONE 0x00000020
|
||||
|
||||
#define MIIM_TBI_ANEX 0x6
|
||||
#define MIIM_TBI_ANEX_NP 0x00000004
|
||||
#define MIIM_TBI_ANEX_PRX 0x00000002
|
||||
|
||||
#define MIIM_TBI_ANLPBPA 0x5
|
||||
#define MIIM_TBI_ANLPBPA_HALF 0x00000040
|
||||
#define MIIM_TBI_ANLPBPA_FULL 0x00000020
|
||||
|
||||
#ifdef CONFIG_PHY_CIS8201
|
||||
#define MIIM_AUX_CONSTAT 0x1c
|
||||
#define MIIM_AUXCONSTAT_INIT 0x0004
|
||||
#define MIIM_AUXCONSTAT_DUPLEX 0x0020
|
||||
#define MIIM_AUXCONSTAT_SPEED 0x0018
|
||||
#define MIIM_AUXCONSTAT_GBIT 0x0010
|
||||
#define MIIM_AUXCONSTAT_100 0x0008
|
||||
|
||||
#define MIIM_EXT_CON1 0x17
|
||||
#define MIIM_EXTCON1_INIT 0x0000
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PHY_M88E1011
|
||||
#define MIIM_ANAR 0x04
|
||||
#define MIIM_ANAR_ADVERTISEMENT 0x01e1
|
||||
|
||||
#define MIIM_GBIT_CON 0x09
|
||||
#define MIIM_GBIT_CON_ADVERT 0x1e00
|
||||
|
||||
#define MIIM_PHY_STATUS 0x11
|
||||
#define MIIM_PHYSTAT_SPEED 0xc000
|
||||
#define MIIM_PHYSTAT_GBIT 0x8000
|
||||
#define MIIM_PHYSTAT_100 0x4000
|
||||
#define MIIM_PHYSTAT_DUPLEX 0x2000
|
||||
#define MIIM_PHYSTAT_SPDDONE 0x0800
|
||||
#define MIIM_PHYSTAT_LINK 0x0400
|
||||
#endif
|
||||
|
||||
#define MIIM_READ_COMMAND 0x00000001
|
||||
|
||||
#define MRBLR_INIT_SETTINGS PKTSIZE_ALIGN
|
||||
|
||||
#define MINFLR_INIT_SETTINGS 0x00000040
|
||||
|
||||
#define DMACTRL_INIT_SETTINGS 0x000000c3
|
||||
#define DMACTRL_GRS 0x00000010
|
||||
#define DMACTRL_GTS 0x00000008
|
||||
|
||||
#define TSTAT_CLEAR_THALT 0x80000000
|
||||
#define RSTAT_CLEAR_RHALT 0x00800000
|
||||
|
||||
/* Write value to the PHY at phyid to the register at offset, */
|
||||
/* using the register space defined in regbase. Note that */
|
||||
/* miimcfg needs to have the clock speed setup correctly. This */
|
||||
/* macro will wait until the write is done before it finishes */
|
||||
#define write_phy_reg(regbase, phyid, offset, value) do { \
|
||||
int timeout=1000000; \
|
||||
regbase->miimadd = (phyid << 8) | offset; \
|
||||
regbase->miimcon = value; \
|
||||
asm("msync"); \
|
||||
while((regbase->miimind & MIIMIND_BUSY) && timeout--); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define IEVENT_INIT_CLEAR 0xffffffff
|
||||
#define IEVENT_BABR 0x80000000
|
||||
#define IEVENT_RXC 0x40000000
|
||||
#define IEVENT_BSY 0x20000000
|
||||
#define IEVENT_EBERR 0x10000000
|
||||
#define IEVENT_MSRO 0x04000000
|
||||
#define IEVENT_GTSC 0x02000000
|
||||
#define IEVENT_BABT 0x01000000
|
||||
#define IEVENT_TXC 0x00800000
|
||||
#define IEVENT_TXE 0x00400000
|
||||
#define IEVENT_TXB 0x00200000
|
||||
#define IEVENT_TXF 0x00100000
|
||||
#define IEVENT_IE 0x00080000
|
||||
#define IEVENT_LC 0x00040000
|
||||
#define IEVENT_CRL 0x00020000
|
||||
#define IEVENT_XFUN 0x00010000
|
||||
#define IEVENT_RXB0 0x00008000
|
||||
#define IEVENT_GRSC 0x00000100
|
||||
#define IEVENT_RXF0 0x00000080
|
||||
|
||||
#define IMASK_INIT_CLEAR 0x00000000
|
||||
#define IMASK_TXEEN 0x00400000
|
||||
#define IMASK_TXBEN 0x00200000
|
||||
#define IMASK_TXFEN 0x00100000
|
||||
#define IMASK_RXFEN0 0x00000080
|
||||
|
||||
|
||||
/* Default Attribute fields */
|
||||
#define ATTR_INIT_SETTINGS 0x000000c0
|
||||
#define ATTRELI_INIT_SETTINGS 0x00000000
|
||||
|
||||
|
||||
/* TxBD status field bits */
|
||||
#define TXBD_READY 0x8000
|
||||
#define TXBD_PADCRC 0x4000
|
||||
#define TXBD_WRAP 0x2000
|
||||
#define TXBD_INTERRUPT 0x1000
|
||||
#define TXBD_LAST 0x0800
|
||||
#define TXBD_CRC 0x0400
|
||||
#define TXBD_DEF 0x0200
|
||||
#define TXBD_HUGEFRAME 0x0080
|
||||
#define TXBD_LATECOLLISION 0x0080
|
||||
#define TXBD_RETRYLIMIT 0x0040
|
||||
#define TXBD_RETRYCOUNTMASK 0x003c
|
||||
#define TXBD_UNDERRUN 0x0002
|
||||
#define TXBD_STATS 0x03ff
|
||||
|
||||
/* RxBD status field bits */
|
||||
#define RXBD_EMPTY 0x8000
|
||||
#define RXBD_RO1 0x4000
|
||||
#define RXBD_WRAP 0x2000
|
||||
#define RXBD_INTERRUPT 0x1000
|
||||
#define RXBD_LAST 0x0800
|
||||
#define RXBD_FIRST 0x0400
|
||||
#define RXBD_MISS 0x0100
|
||||
#define RXBD_BROADCAST 0x0080
|
||||
#define RXBD_MULTICAST 0x0040
|
||||
#define RXBD_LARGE 0x0020
|
||||
#define RXBD_NONOCTET 0x0010
|
||||
#define RXBD_SHORT 0x0008
|
||||
#define RXBD_CRCERR 0x0004
|
||||
#define RXBD_OVERRUN 0x0002
|
||||
#define RXBD_TRUNCATED 0x0001
|
||||
#define RXBD_STATS 0x003f
|
||||
|
||||
typedef struct txbd8
|
||||
{
|
||||
ushort status; /* Status Fields */
|
||||
ushort length; /* Buffer length */
|
||||
uint bufPtr; /* Buffer Pointer */
|
||||
} txbd8_t;
|
||||
|
||||
typedef struct rxbd8
|
||||
{
|
||||
ushort status; /* Status Fields */
|
||||
ushort length; /* Buffer Length */
|
||||
uint bufPtr; /* Buffer Pointer */
|
||||
} rxbd8_t;
|
||||
|
||||
typedef struct rmon_mib
|
||||
{
|
||||
/* Transmit and Receive Counters */
|
||||
uint tr64; /* Transmit and Receive 64-byte Frame Counter */
|
||||
uint tr127; /* Transmit and Receive 65-127 byte Frame Counter */
|
||||
uint tr255; /* Transmit and Receive 128-255 byte Frame Counter */
|
||||
uint tr511; /* Transmit and Receive 256-511 byte Frame Counter */
|
||||
uint tr1k; /* Transmit and Receive 512-1023 byte Frame Counter */
|
||||
uint trmax; /* Transmit and Receive 1024-1518 byte Frame Counter */
|
||||
uint trmgv; /* Transmit and Receive 1519-1522 byte Good VLAN Frame */
|
||||
/* Receive Counters */
|
||||
uint rbyt; /* Receive Byte Counter */
|
||||
uint rpkt; /* Receive Packet Counter */
|
||||
uint rfcs; /* Receive FCS Error Counter */
|
||||
uint rmca; /* Receive Multicast Packet (Counter) */
|
||||
uint rbca; /* Receive Broadcast Packet */
|
||||
uint rxcf; /* Receive Control Frame Packet */
|
||||
uint rxpf; /* Receive Pause Frame Packet */
|
||||
uint rxuo; /* Receive Unknown OP Code */
|
||||
uint raln; /* Receive Alignment Error */
|
||||
uint rflr; /* Receive Frame Length Error */
|
||||
uint rcde; /* Receive Code Error */
|
||||
uint rcse; /* Receive Carrier Sense Error */
|
||||
uint rund; /* Receive Undersize Packet */
|
||||
uint rovr; /* Receive Oversize Packet */
|
||||
uint rfrg; /* Receive Fragments */
|
||||
uint rjbr; /* Receive Jabber */
|
||||
uint rdrp; /* Receive Drop */
|
||||
/* Transmit Counters */
|
||||
uint tbyt; /* Transmit Byte Counter */
|
||||
uint tpkt; /* Transmit Packet */
|
||||
uint tmca; /* Transmit Multicast Packet */
|
||||
uint tbca; /* Transmit Broadcast Packet */
|
||||
uint txpf; /* Transmit Pause Control Frame */
|
||||
uint tdfr; /* Transmit Deferral Packet */
|
||||
uint tedf; /* Transmit Excessive Deferral Packet */
|
||||
uint tscl; /* Transmit Single Collision Packet */
|
||||
/* (0x2_n700) */
|
||||
uint tmcl; /* Transmit Multiple Collision Packet */
|
||||
uint tlcl; /* Transmit Late Collision Packet */
|
||||
uint txcl; /* Transmit Excessive Collision Packet */
|
||||
uint tncl; /* Transmit Total Collision */
|
||||
|
||||
uint res2;
|
||||
|
||||
uint tdrp; /* Transmit Drop Frame */
|
||||
uint tjbr; /* Transmit Jabber Frame */
|
||||
uint tfcs; /* Transmit FCS Error */
|
||||
uint txcf; /* Transmit Control Frame */
|
||||
uint tovr; /* Transmit Oversize Frame */
|
||||
uint tund; /* Transmit Undersize Frame */
|
||||
uint tfrg; /* Transmit Fragments Frame */
|
||||
/* General Registers */
|
||||
uint car1; /* Carry Register One */
|
||||
uint car2; /* Carry Register Two */
|
||||
uint cam1; /* Carry Register One Mask */
|
||||
uint cam2; /* Carry Register Two Mask */
|
||||
} rmon_mib_t;
|
||||
|
||||
typedef struct tsec_hash_regs
|
||||
{
|
||||
uint iaddr0; /* Individual Address Register 0 */
|
||||
uint iaddr1; /* Individual Address Register 1 */
|
||||
uint iaddr2; /* Individual Address Register 2 */
|
||||
uint iaddr3; /* Individual Address Register 3 */
|
||||
uint iaddr4; /* Individual Address Register 4 */
|
||||
uint iaddr5; /* Individual Address Register 5 */
|
||||
uint iaddr6; /* Individual Address Register 6 */
|
||||
uint iaddr7; /* Individual Address Register 7 */
|
||||
uint res1[24];
|
||||
uint gaddr0; /* Group Address Register 0 */
|
||||
uint gaddr1; /* Group Address Register 1 */
|
||||
uint gaddr2; /* Group Address Register 2 */
|
||||
uint gaddr3; /* Group Address Register 3 */
|
||||
uint gaddr4; /* Group Address Register 4 */
|
||||
uint gaddr5; /* Group Address Register 5 */
|
||||
uint gaddr6; /* Group Address Register 6 */
|
||||
uint gaddr7; /* Group Address Register 7 */
|
||||
uint res2[24];
|
||||
} tsec_hash_t;
|
||||
|
||||
typedef struct tsec
|
||||
{
|
||||
/* General Control and Status Registers (0x2_n000) */
|
||||
uint res000[4];
|
||||
|
||||
uint ievent; /* Interrupt Event */
|
||||
uint imask; /* Interrupt Mask */
|
||||
uint edis; /* Error Disabled */
|
||||
uint res01c;
|
||||
uint ecntrl; /* Ethernet Control */
|
||||
uint minflr; /* Minimum Frame Length */
|
||||
uint ptv; /* Pause Time Value */
|
||||
uint dmactrl; /* DMA Control */
|
||||
uint tbipa; /* TBI PHY Address */
|
||||
|
||||
uint res034[3];
|
||||
uint res040[48];
|
||||
|
||||
/* Transmit Control and Status Registers (0x2_n100) */
|
||||
uint tctrl; /* Transmit Control */
|
||||
uint tstat; /* Transmit Status */
|
||||
uint res108;
|
||||
uint tbdlen; /* Tx BD Data Length */
|
||||
uint res110[5];
|
||||
uint ctbptr; /* Current TxBD Pointer */
|
||||
uint res128[23];
|
||||
uint tbptr; /* TxBD Pointer */
|
||||
uint res188[30];
|
||||
/* (0x2_n200) */
|
||||
uint res200;
|
||||
uint tbase; /* TxBD Base Address */
|
||||
uint res208[42];
|
||||
uint ostbd; /* Out of Sequence TxBD */
|
||||
uint ostbdp; /* Out of Sequence Tx Data Buffer Pointer */
|
||||
uint res2b8[18];
|
||||
|
||||
/* Receive Control and Status Registers (0x2_n300) */
|
||||
uint rctrl; /* Receive Control */
|
||||
uint rstat; /* Receive Status */
|
||||
uint res308;
|
||||
uint rbdlen; /* RxBD Data Length */
|
||||
uint res310[4];
|
||||
uint res320;
|
||||
uint crbptr; /* Current Receive Buffer Pointer */
|
||||
uint res328[6];
|
||||
uint mrblr; /* Maximum Receive Buffer Length */
|
||||
uint res344[16];
|
||||
uint rbptr; /* RxBD Pointer */
|
||||
uint res388[30];
|
||||
/* (0x2_n400) */
|
||||
uint res400;
|
||||
uint rbase; /* RxBD Base Address */
|
||||
uint res408[62];
|
||||
|
||||
/* MAC Registers (0x2_n500) */
|
||||
uint maccfg1; /* MAC Configuration #1 */
|
||||
uint maccfg2; /* MAC Configuration #2 */
|
||||
uint ipgifg; /* Inter Packet Gap/Inter Frame Gap */
|
||||
uint hafdup; /* Half-duplex */
|
||||
uint maxfrm; /* Maximum Frame */
|
||||
uint res514;
|
||||
uint res518;
|
||||
|
||||
uint res51c;
|
||||
|
||||
uint miimcfg; /* MII Management: Configuration */
|
||||
uint miimcom; /* MII Management: Command */
|
||||
uint miimadd; /* MII Management: Address */
|
||||
uint miimcon; /* MII Management: Control */
|
||||
uint miimstat; /* MII Management: Status */
|
||||
uint miimind; /* MII Management: Indicators */
|
||||
|
||||
uint res538;
|
||||
|
||||
uint ifstat; /* Interface Status */
|
||||
uint macstnaddr1; /* Station Address, part 1 */
|
||||
uint macstnaddr2; /* Station Address, part 2 */
|
||||
uint res548[46];
|
||||
|
||||
/* (0x2_n600) */
|
||||
uint res600[32];
|
||||
|
||||
/* RMON MIB Registers (0x2_n680-0x2_n73c) */
|
||||
rmon_mib_t rmon;
|
||||
uint res740[48];
|
||||
|
||||
/* Hash Function Registers (0x2_n800) */
|
||||
tsec_hash_t hash;
|
||||
|
||||
uint res900[128];
|
||||
|
||||
/* Pattern Registers (0x2_nb00) */
|
||||
uint resb00[62];
|
||||
uint attr; /* Default Attribute Register */
|
||||
uint attreli; /* Default Attribute Extract Length and Index */
|
||||
|
||||
/* TSEC Future Expansion Space (0x2_nc00-0x2_nffc) */
|
||||
uint resc00[256];
|
||||
} tsec_t;
|
||||
|
||||
#endif /* __TSEC_H */
|
||||
@@ -80,7 +80,7 @@ static int check_CPU (long clock, uint pvr, uint immr)
|
||||
|
||||
switch (k) {
|
||||
#ifdef CONFIG_MPC866_et_al
|
||||
/* MPC866P/MPC866T/MPC859T/MPC859DSL/MPC852T */
|
||||
/* MPC866P/MPC866T/MPC859T/MPC859DSL/MPC852T */
|
||||
case 0x08000003: pre = 'M'; suf = ""; m = 1; break;
|
||||
#else
|
||||
case 0x00020001: pre = 'p'; suf = ""; break;
|
||||
@@ -130,9 +130,9 @@ static int check_CPU (long clock, uint pvr, uint immr)
|
||||
putc ('\n');
|
||||
|
||||
#ifdef DEBUG
|
||||
if(clock != measure_gclk()) {
|
||||
printf ("clock %ldHz != %dHz\n", clock, measure_gclk());
|
||||
}
|
||||
if(clock != measure_gclk()) {
|
||||
printf ("clock %ldHz != %dHz\n", clock, measure_gclk());
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@@ -485,15 +485,15 @@ unsigned long get_tbclk (void)
|
||||
}
|
||||
#define PLPRCR_val(a) (((CFG_PLPRCR) & PLPRCR_ ## a ## _MSK) >> PLPRCR_ ## a ## _SHIFT)
|
||||
#ifdef CONFIG_MPC866_et_al
|
||||
/* MFN
|
||||
MFI + -------
|
||||
MFD + 1
|
||||
factor = -----------------
|
||||
(PDF + 1) * 2^S
|
||||
*/
|
||||
/* MFN
|
||||
MFI + -------
|
||||
MFD + 1
|
||||
factor = -----------------
|
||||
(PDF + 1) * 2^S
|
||||
*/
|
||||
|
||||
factor = (PLPRCR_val(MFI) + PLPRCR_val(MFN)/(PLPRCR_val(MFD)+1))/
|
||||
(PLPRCR_val(PDF)+1) / (1<<PLPRCR_val(S));
|
||||
(PLPRCR_val(PDF)+1) / (1<<PLPRCR_val(S));
|
||||
#else
|
||||
factor = PLPRCR_val(MF)+1;
|
||||
#endif
|
||||
|
||||
@@ -89,10 +89,10 @@ unsigned long measure_gclk(void)
|
||||
ulong msr_val;
|
||||
|
||||
#ifdef CONFIG_MPC866_et_al
|
||||
/* dont use OSCM, only use EXTCLK/512 */
|
||||
immr->im_clkrst.car_sccr |= SCCR_RTSEL | SCCR_RTDIV;
|
||||
/* dont use OSCM, only use EXTCLK/512 */
|
||||
immr->im_clkrst.car_sccr |= SCCR_RTSEL | SCCR_RTDIV;
|
||||
#else
|
||||
immr->im_clkrst.car_sccr &= ~(SCCR_RTSEL | SCCR_RTDIV);
|
||||
immr->im_clkrst.car_sccr &= ~(SCCR_RTSEL | SCCR_RTDIV);
|
||||
#endif
|
||||
|
||||
/* Reset + Stop Timer 2, no cascading
|
||||
@@ -161,7 +161,7 @@ unsigned long measure_gclk(void)
|
||||
immr->im_sit.sit_piscr &= ~PISCR_PTE;
|
||||
|
||||
#ifdef CONFIG_MPC866_et_al
|
||||
/* not using OSCM, using XIN, so scale appropriately */
|
||||
/* not using OSCM, using XIN, so scale appropriately */
|
||||
return (((timer2_val + 2) / 4) * (CFG_8XX_XIN/512))/8192 * 100000L;
|
||||
#else
|
||||
return ((timer2_val + 2) / 4) * 100000L; /* convert to Hz */
|
||||
|
||||
@@ -22,4 +22,3 @@
|
||||
#
|
||||
|
||||
PLATFORM_RELFLAGS +=
|
||||
|
||||
|
||||
@@ -481,7 +481,7 @@ mmc_init(int verbose)
|
||||
MMC_CLKRT = 0; /* 20 MHz */
|
||||
resp = mmc_cmd(7, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1);
|
||||
|
||||
fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */
|
||||
fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user