summaryrefslogtreecommitdiff
path: root/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'cpu')
-rw-r--r--cpu/ixp/npe/npe.c8
-rw-r--r--cpu/ixp/serial.c22
-rw-r--r--cpu/mpc512x/cpu.c21
-rw-r--r--cpu/mpc512x/fec.c2
-rw-r--r--cpu/mpc512x/i2c.c12
-rw-r--r--cpu/mpc512x/serial.c2
-rw-r--r--cpu/mpc512x/speed.c4
-rw-r--r--cpu/mpc5xx/u-boot.lds2
-rw-r--r--cpu/mpc5xxx/fec.c7
-rw-r--r--cpu/mpc5xxx/firmware_sc_task_bestcomm.impl.S8
-rw-r--r--cpu/mpc5xxx/u-boot-customlayout.lds2
-rw-r--r--cpu/mpc5xxx/u-boot.lds2
-rw-r--r--cpu/mpc8220/u-boot.lds2
-rw-r--r--cpu/mpc824x/u-boot.lds2
-rw-r--r--cpu/mpc8260/ether_scc.c9
-rw-r--r--cpu/mpc8260/u-boot.lds2
-rw-r--r--cpu/mpc83xx/Makefile2
-rw-r--r--cpu/mpc83xx/cpu.c348
-rw-r--r--cpu/mpc83xx/cpu_init.c6
-rw-r--r--cpu/mpc83xx/fdt.c78
-rw-r--r--cpu/mpc83xx/pci.c83
-rw-r--r--cpu/mpc83xx/spd_sdram.c11
-rw-r--r--cpu/mpc83xx/speed.c201
-rw-r--r--cpu/mpc83xx/start.S2
-rw-r--r--cpu/mpc83xx/u-boot.lds2
-rw-r--r--cpu/mpc85xx/fdt.c5
-rw-r--r--cpu/mpc85xx/spd_sdram.c23
-rw-r--r--cpu/mpc85xx/start.S9
-rw-r--r--cpu/mpc86xx/cpu.c15
-rw-r--r--cpu/mpc86xx/spd_sdram.c11
-rw-r--r--cpu/mpc8xx/cpu.c16
-rw-r--r--cpu/mpc8xx/cpu_init.c6
-rw-r--r--cpu/mpc8xx/fec.c113
-rw-r--r--cpu/mpc8xx/serial.c21
-rw-r--r--cpu/mpc8xx/upatch.c94
-rw-r--r--cpu/ppc4xx/40x_spd_sdram.c2
-rw-r--r--cpu/ppc4xx/440spe_pcie.h174
-rw-r--r--cpu/ppc4xx/44x_spd_ddr.c15
-rw-r--r--cpu/ppc4xx/44x_spd_ddr2.c127
-rw-r--r--cpu/ppc4xx/4xx_enet.c367
-rw-r--r--cpu/ppc4xx/4xx_pci.c (renamed from cpu/ppc4xx/405gp_pci.c)15
-rw-r--r--cpu/ppc4xx/4xx_pcie.c (renamed from cpu/ppc4xx/440spe_pcie.c)849
-rw-r--r--cpu/ppc4xx/4xx_uart.c (renamed from cpu/ppc4xx/serial.c)543
-rw-r--r--cpu/ppc4xx/Makefile43
-rw-r--r--cpu/ppc4xx/cache.S233
-rw-r--r--cpu/ppc4xx/commproc.c14
-rw-r--r--cpu/ppc4xx/cpu.c114
-rw-r--r--cpu/ppc4xx/cpu_init.c23
-rw-r--r--cpu/ppc4xx/denali_data_eye.c389
-rw-r--r--cpu/ppc4xx/denali_spd_ddr2.c1254
-rw-r--r--cpu/ppc4xx/fdt.c64
-rw-r--r--cpu/ppc4xx/gpio.c177
-rw-r--r--cpu/ppc4xx/interrupts.c22
-rw-r--r--cpu/ppc4xx/iop480_uart.c238
-rw-r--r--cpu/ppc4xx/kgdb.S8
-rw-r--r--cpu/ppc4xx/miiphy.c211
-rw-r--r--cpu/ppc4xx/ndfc.c3
-rw-r--r--cpu/ppc4xx/speed.c233
-rw-r--r--cpu/ppc4xx/start.S288
-rw-r--r--cpu/ppc4xx/tlb.c88
-rw-r--r--cpu/ppc4xx/usb.c18
-rw-r--r--cpu/ppc4xx/usbdev.c2
-rw-r--r--cpu/ppc4xx/vecnum.h299
-rw-r--r--cpu/pxa/start.S38
-rw-r--r--cpu/pxa/usb.c16
65 files changed, 4513 insertions, 2507 deletions
diff --git a/cpu/ixp/npe/npe.c b/cpu/ixp/npe/npe.c
index 7e4af44105..a33b956975 100644
--- a/cpu/ixp/npe/npe.c
+++ b/cpu/ixp/npe/npe.c
@@ -408,25 +408,25 @@ static int npe_init(struct eth_device *dev, bd_t * bis)
if (ixEthAccPortRxCallbackRegister(p_npe->eth_id, npe_rx_callback,
(u32)p_npe) != IX_ETH_ACC_SUCCESS) {
printf("can't register RX callback!\n");
- return 0;
+ return -1;
}
if (ixEthAccPortTxDoneCallbackRegister(p_npe->eth_id, npe_tx_callback,
(u32)p_npe) != IX_ETH_ACC_SUCCESS) {
printf("can't register TX callback!\n");
- return 0;
+ return -1;
}
npe_set_mac_address(dev);
if (ixEthAccPortEnable(p_npe->eth_id) != IX_ETH_ACC_SUCCESS) {
printf("can't enable port!\n");
- return 0;
+ return -1;
}
p_npe->active = 1;
- return 1;
+ return 0;
}
#if 0 /* test-only: probably have to deal with it when booting linux (for a clean state) */
diff --git a/cpu/ixp/serial.c b/cpu/ixp/serial.c
index 2015958571..cf520b699e 100644
--- a/cpu/ixp/serial.c
+++ b/cpu/ixp/serial.c
@@ -31,6 +31,13 @@
#include <common.h>
#include <asm/arch/ixp425.h>
+/*
+ * 14.7456 MHz
+ * Baud Rate = --------------
+ * 16 x Divisor
+ */
+#define SERIAL_CLOCK 921600
+
DECLARE_GLOBAL_DATA_PTR;
void serial_setbrg (void)
@@ -38,18 +45,8 @@ void serial_setbrg (void)
unsigned int quot = 0;
int uart = CFG_IXP425_CONSOLE;
- if (gd->baudrate == 1200)
- quot = 192;
- else if (gd->baudrate == 9600)
- quot = 96;
- else if (gd->baudrate == 19200)
- quot = 48;
- else if (gd->baudrate == 38400)
- quot = 24;
- else if (gd->baudrate == 57600)
- quot = 16;
- else if (gd->baudrate == 115200)
- quot = 8;
+ if ((gd->baudrate <= SERIAL_CLOCK) && (SERIAL_CLOCK % gd->baudrate == 0))
+ quot = SERIAL_CLOCK / gd->baudrate;
else
hang ();
@@ -65,7 +62,6 @@ void serial_setbrg (void)
IER(uart) = IER_UUE;
}
-
/*
* Initialise the serial port with the given baudrate. The settings
* are always 8 data bits, no parity, 1 stop bit, no start bits.
diff --git a/cpu/mpc512x/cpu.c b/cpu/mpc512x/cpu.c
index accae6e066..6421a511e4 100644
--- a/cpu/mpc512x/cpu.c
+++ b/cpu/mpc512x/cpu.c
@@ -32,6 +32,10 @@
#include <mpc512x.h>
#include <asm/processor.h>
+#if defined(CONFIG_OF_LIBFDT)
+#include <fdt_support.h>
+#endif
+
DECLARE_GLOBAL_DATA_PTR;
int checkcpu (void)
@@ -125,3 +129,20 @@ void watchdog_reset (void)
enable_interrupts ();
}
#endif
+
+#ifdef CONFIG_OF_LIBFDT
+void ft_cpu_setup(void *blob, bd_t *bd)
+{
+ char * cpu_path = "/cpus/" OF_CPU;
+ char * eth_path = "/" OF_SOC "/ethernet@2800";
+
+ do_fixup_by_path_u32(blob, cpu_path, "timebase-frequency", OF_TBCLK, 1);
+ do_fixup_by_path_u32(blob, cpu_path, "bus-frequency", bd->bi_busfreq, 1);
+ do_fixup_by_path_u32(blob, cpu_path, "ref-frequency", CFG_MPC512X_CLKIN, 1);
+ do_fixup_by_path_u32(blob, cpu_path, "clock-frequency", bd->bi_intfreq, 1);
+ do_fixup_by_path_u32(blob, "/" OF_SOC, "bus-frequency", bd->bi_ipsfreq, 1);
+ do_fixup_by_path_u32(blob, "/" OF_SOC, "ref-frequency", CFG_MPC512X_CLKIN, 1);
+ do_fixup_by_path(blob, eth_path, "address", bd->bi_enetaddr, 6, 0);
+ do_fixup_by_path(blob, eth_path, "local-mac-address", bd->bi_enetaddr, 6, 0);
+}
+#endif
diff --git a/cpu/mpc512x/fec.c b/cpu/mpc512x/fec.c
index 675b7a2e09..c226a8a5a2 100644
--- a/cpu/mpc512x/fec.c
+++ b/cpu/mpc512x/fec.c
@@ -299,7 +299,7 @@ int mpc512x_fec_init_phy (struct eth_device *dev, bd_t * bis)
* Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
* and do not drop the Preamble.
*/
- fec->eth->mii_speed = (((gd->ipb_clk / 1000000) / 5) + 1) << 1;
+ fec->eth->mii_speed = (((gd->ips_clk / 1000000) / 5) + 1) << 1;
/*
* Reset PHY, then delay 300ns
diff --git a/cpu/mpc512x/i2c.c b/cpu/mpc512x/i2c.c
index 00e28d6404..56ba443726 100644
--- a/cpu/mpc512x/i2c.c
+++ b/cpu/mpc512x/i2c.c
@@ -236,7 +236,7 @@ static int mpc_get_fdr (int speed)
if (fdr == -1) {
ulong best_speed = 0;
ulong divider;
- ulong ipb, scl;
+ ulong ips, scl;
ulong bestmatch = 0xffffffffUL;
int best_i = 0, best_j = 0, i, j;
int SCL_Tap[] = { 9, 10, 12, 15, 5, 6, 7, 8};
@@ -251,18 +251,18 @@ static int mpc_get_fdr (int speed)
{126, 128}
};
- ipb = gd->ipb_clk;
+ ips = gd->ips_clk;
for (i = 7; i >= 0; i--) {
for (j = 7; j >= 0; j--) {
scl = 2 * (scltap[j].scl2tap +
(SCL_Tap[i] - 1) * scltap[j].tap2tap
+ 2);
- if (ipb <= speed*scl) {
- if ((speed*scl - ipb) < bestmatch) {
- bestmatch = speed*scl - ipb;
+ if (ips <= speed*scl) {
+ if ((speed*scl - ips) < bestmatch) {
+ bestmatch = speed*scl - ips;
best_i = i;
best_j = j;
- best_speed = ipb/scl;
+ best_speed = ips/scl;
}
}
}
diff --git a/cpu/mpc512x/serial.c b/cpu/mpc512x/serial.c
index 200ff2c496..8a214041ad 100644
--- a/cpu/mpc512x/serial.c
+++ b/cpu/mpc512x/serial.c
@@ -86,7 +86,7 @@ int serial_init(void)
psc->mode = PSC_MODE_1_STOPBIT;
/* calculate dividor for setting PSC CTUR and CTLR registers */
- baseclk = (gd->ipb_clk + 8) / 16;
+ baseclk = (gd->ips_clk + 8) / 16;
div = (baseclk + (gd->baudrate / 2)) / gd->baudrate;
psc->ctur = (div >> 8) & 0xff;
diff --git a/cpu/mpc512x/speed.c b/cpu/mpc512x/speed.c
index a609827387..99e3495c2f 100644
--- a/cpu/mpc512x/speed.c
+++ b/cpu/mpc512x/speed.c
@@ -96,7 +96,7 @@ int get_clocks (void)
ips_clk = 0;
}
- gd->ipb_clk = ips_clk;
+ gd->ips_clk = ips_clk;
gd->csb_clk = csb_clk;
gd->cpu_clk = core_clk;
gd->bus_clk = csb_clk;
@@ -118,7 +118,7 @@ int do_clocks (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
printf ("Clock configuration:\n");
printf (" CPU: %4d MHz\n", gd->cpu_clk / 1000000);
printf (" Coherent System Bus: %4d MHz\n", gd->csb_clk / 1000000);
- printf (" IPS Bus: %4d MHz\n", gd->ipb_clk / 1000000);
+ printf (" IPS Bus: %4d MHz\n", gd->ips_clk / 1000000);
printf (" DDR: %4d MHz\n", 2 * gd->csb_clk / 1000000);
return 0;
}
diff --git a/cpu/mpc5xx/u-boot.lds b/cpu/mpc5xx/u-boot.lds
index 5b03fef66c..ca1de954cd 100644
--- a/cpu/mpc5xx/u-boot.lds
+++ b/cpu/mpc5xx/u-boot.lds
@@ -121,7 +121,7 @@ SECTIONS
__init_end = .;
__bss_start = .;
- .bss :
+ .bss (NOLOAD) :
{
*(.sbss) *(.scommon)
*(.dynbss)
diff --git a/cpu/mpc5xxx/fec.c b/cpu/mpc5xxx/fec.c
index 1d3da779a7..2aded1a5f1 100644
--- a/cpu/mpc5xxx/fec.c
+++ b/cpu/mpc5xxx/fec.c
@@ -288,13 +288,13 @@ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis)
* Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
* and do not drop the Preamble.
*/
- fec->eth->mii_speed = (((gd->ipb_clk >> 20) / 5) << 1); /* No MII for 7-wire mode */
+ fec->eth->mii_speed = (((gd->ipb_clk >> 20) / 5) << 1); /* No MII for 7-wire mode */
}
/*
* Set Opcode/Pause Duration Register
*/
- fec->eth->op_pause = 0x00010020; /*FIXME0xffff0020; */
+ fec->eth->op_pause = 0x00010020; /*FIXME 0xffff0020; */
/*
* Set Rx FIFO alarm and granularity value
@@ -902,7 +902,8 @@ int mpc5xxx_fec_initialize(bd_t * bis)
defined(CONFIG_TOP5200) || \
defined(CONFIG_TQM5200) || \
defined(CONFIG_UC101) || \
- defined(CONFIG_V38B)
+ defined(CONFIG_V38B) || \
+ defined(CONFIG_MUNICES)
# ifndef CONFIG_FEC_10MBIT
fec->xcv_type = MII100;
# else
diff --git a/cpu/mpc5xxx/firmware_sc_task_bestcomm.impl.S b/cpu/mpc5xxx/firmware_sc_task_bestcomm.impl.S
index 1d83fe26d9..a07c776993 100644
--- a/cpu/mpc5xxx/firmware_sc_task_bestcomm.impl.S
+++ b/cpu/mpc5xxx/firmware_sc_task_bestcomm.impl.S
@@ -23,7 +23,7 @@ scEthernetRecv_Entry: /* Task 0 */
.long 0x00000000
.long 0x00000000
.long scEthernetRecv_CSave - taskTable /* Task 0 context save space */
-.long 0xf0000000
+.long CFG_MBAR
.globl scEthernetXmit_Entry
scEthernetXmit_Entry: /* Task 1 */
.long scEthernetXmit_TDT - taskTable /* Task 1 Descriptor Table */
@@ -33,7 +33,7 @@ scEthernetXmit_Entry: /* Task 1 */
.long 0x00000000
.long 0x00000000
.long scEthernetXmit_CSave - taskTable /* Task 1 context save space */
-.long 0xf0000000
+.long CFG_MBAR
.globl scEthernetRecv_TDT
@@ -151,7 +151,7 @@ scEthernetRecv_VarTab: /* Task 0 Variable Table */
.long 0x00000000 /* var[6] */
.long 0x00000000 /* var[7] */
.long 0x00000000 /* var[8] */
-.long 0xf0008800 /* var[9] */
+.long (CFG_MBAR + 0x8800) /* var[9] */
.long 0x00000008 /* var[10] */
.long 0x0000000c /* var[11] */
.long 0x80000000 /* var[12] */
@@ -190,7 +190,7 @@ scEthernetXmit_VarTab: /* Task 1 Variable Table */
.long 0x00000000 /* var[8] */
.long 0x00000000 /* var[9] */
.long 0x00000000 /* var[10] */
-.long 0xf0008800 /* var[11] */
+.long (CFG_MBAR + 0x8800) /* var[11] */
.long 0x00000000 /* var[12] */
.long 0x80000000 /* var[13] */
.long 0x10000000 /* var[14] */
diff --git a/cpu/mpc5xxx/u-boot-customlayout.lds b/cpu/mpc5xxx/u-boot-customlayout.lds
index 123a14c5aa..4e10ddbcc2 100644
--- a/cpu/mpc5xxx/u-boot-customlayout.lds
+++ b/cpu/mpc5xxx/u-boot-customlayout.lds
@@ -124,7 +124,7 @@ SECTIONS
__init_end = .;
__bss_start = .;
- .bss :
+ .bss (NOLOAD) :
{
*(.sbss) *(.scommon)
*(.dynbss)
diff --git a/cpu/mpc5xxx/u-boot.lds b/cpu/mpc5xxx/u-boot.lds
index 78818a49eb..bb2747b6d7 100644
--- a/cpu/mpc5xxx/u-boot.lds
+++ b/cpu/mpc5xxx/u-boot.lds
@@ -113,7 +113,7 @@ SECTIONS
__init_end = .;
__bss_start = .;
- .bss :
+ .bss (NOLOAD) :
{
*(.sbss) *(.scommon)
*(.dynbss)
diff --git a/cpu/mpc8220/u-boot.lds b/cpu/mpc8220/u-boot.lds
index 889bc77d2f..98b0a79244 100644
--- a/cpu/mpc8220/u-boot.lds
+++ b/cpu/mpc8220/u-boot.lds
@@ -113,7 +113,7 @@ SECTIONS
__init_end = .;
__bss_start = .;
- .bss :
+ .bss (NOLOAD) :
{
*(.sbss) *(.scommon)
*(.dynbss)
diff --git a/cpu/mpc824x/u-boot.lds b/cpu/mpc824x/u-boot.lds
index c90d1e9457..036e61b908 100644
--- a/cpu/mpc824x/u-boot.lds
+++ b/cpu/mpc824x/u-boot.lds
@@ -113,7 +113,7 @@ SECTIONS
__init_end = .;
__bss_start = .;
- .bss :
+ .bss (NOLOAD) :
{
*(.sbss) *(.scommon)
*(.dynbss)
diff --git a/cpu/mpc8260/ether_scc.c b/cpu/mpc8260/ether_scc.c
index e56839d3aa..633d053914 100644
--- a/cpu/mpc8260/ether_scc.c
+++ b/cpu/mpc8260/ether_scc.c
@@ -77,7 +77,9 @@
#define TX_BUF_CNT 2
-#define TOUT_LOOP 1000000
+#if !defined(CFG_SCC_TOUT_LOOP)
+ #define CFG_SCC_TOUT_LOOP 1000000
+#endif
static char txbuf[TX_BUF_CNT][ DBUF_LENGTH ];
@@ -109,7 +111,7 @@ int eth_send(volatile void *packet, int length)
}
for(i=0; rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY; i++) {
- if (i >= TOUT_LOOP) {
+ if (i >= CFG_SCC_TOUT_LOOP) {
puts ("scc: tx buffer not ready\n");
goto out;
}
@@ -121,7 +123,7 @@ int eth_send(volatile void *packet, int length)
BD_ENET_TX_WRAP);
for(i=0; rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY; i++) {
- if (i >= TOUT_LOOP) {
+ if (i >= CFG_SCC_TOUT_LOOP) {
puts ("scc: tx error\n");
goto out;
}
@@ -262,7 +264,6 @@ int eth_init(bd_t *bis)
pram_ptr->sen_taddrm = 0x0; /* Tmp Address (unused) */
pram_ptr->sen_taddrl = 0x0; /* Tmp Address (LSB) (unused) */
-
/* 24.21 - (19): Initialize RxBD */
for (i = 0; i < PKTBUFSRX; i++)
{
diff --git a/cpu/mpc8260/u-boot.lds b/cpu/mpc8260/u-boot.lds
index 3e84f234d7..8384549283 100644
--- a/cpu/mpc8260/u-boot.lds
+++ b/cpu/mpc8260/u-boot.lds
@@ -113,7 +113,7 @@ SECTIONS
__init_end = .;
__bss_start = .;
- .bss :
+ .bss (NOLOAD) :
{
*(.sbss) *(.scommon)
*(.dynbss)
diff --git a/cpu/mpc83xx/Makefile b/cpu/mpc83xx/Makefile
index 2329970051..94a3cb8334 100644
--- a/cpu/mpc83xx/Makefile
+++ b/cpu/mpc83xx/Makefile
@@ -29,7 +29,7 @@ LIB = $(obj)lib$(CPU).a
START = start.o
COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o \
- spd_sdram.o ecc.o qe_io.o pci.o
+ spd_sdram.o ecc.o qe_io.o pci.o fdt.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c
index f1ea17d5a5..bff3cefda9 100644
--- a/cpu/mpc83xx/cpu.c
+++ b/cpu/mpc83xx/cpu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2006 Freescale Semiconductor, Inc.
+ * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -31,12 +31,7 @@
#include <command.h>
#include <mpc83xx.h>
#include <asm/processor.h>
-#if defined(CONFIG_OF_FLAT_TREE)
-#include <ft_build.h>
-#elif defined(CONFIG_OF_LIBFDT)
#include <libfdt.h>
-#include <fdt_support.h>
-#endif
DECLARE_GLOBAL_DATA_PTR;
@@ -65,6 +60,10 @@ int checkcpu(void)
printf("e300c3, ");
break;
+ case PVR_E300C4:
+ printf("e300c4, ");
+ break;
+
default:
printf("Unknown core, ");
}
@@ -149,6 +148,36 @@ int checkcpu(void)
case SPR_8313E_REV10:
puts("MPC8313E, ");
break;
+ case SPR_8315E_REV10:
+ puts("MPC8315E, ");
+ break;
+ case SPR_8315_REV10:
+ puts("MPC8315, ");
+ break;
+ case SPR_8314E_REV10:
+ puts("MPC8314E, ");
+ break;
+ case SPR_8314_REV10:
+ puts("MPC8314, ");
+ break;
+ case SPR_8379E_REV10:
+ puts("MPC8379E, ");
+ break;
+ case SPR_8379_REV10:
+ puts("MPC8379, ");
+ break;
+ case SPR_8378E_REV10:
+ puts("MPC8378E, ");
+ break;
+ case SPR_8378_REV10:
+ puts("MPC8378, ");
+ break;
+ case SPR_8377E_REV10:
+ puts("MPC8377E, ");
+ break;
+ case SPR_8377_REV10:
+ puts("MPC8377, ");
+ break;
default:
printf("Rev: Unknown revision number:%08x\n"
"Warning: Unsupported cpu revision!\n",spridr);
@@ -325,313 +354,6 @@ void watchdog_reset (void)
}
#endif
-#if defined(CONFIG_OF_LIBFDT)
-
-/*
- * "Setter" functions used to add/modify FDT entries.
- */
-static int fdt_set_eth0(void *blob, int nodeoffset, const char *name, bd_t *bd)
-{
- /* Fix it up if it exists, don't create it if it doesn't exist */
- if (fdt_get_property(blob, nodeoffset, name, 0)) {
- return fdt_setprop(blob, nodeoffset, name, bd->bi_enetaddr, 6);
- }
- return 0;
-}
-#ifdef CONFIG_HAS_ETH1
-/* second onboard ethernet port */
-static int fdt_set_eth1(void *blob, int nodeoffset, const char *name, bd_t *bd)
-{
- /* Fix it up if it exists, don't create it if it doesn't exist */
- if (fdt_get_property(blob, nodeoffset, name, 0)) {
- return fdt_setprop(blob, nodeoffset, name, bd->bi_enet1addr, 6);
- }
- return 0;
-}
-#endif
-#ifdef CONFIG_HAS_ETH2
-/* third onboard ethernet port */
-static int fdt_set_eth2(void *blob, int nodeoffset, const char *name, bd_t *bd)
-{
- /* Fix it up if it exists, don't create it if it doesn't exist */
- if (fdt_get_property(blob, nodeoffset, name, 0)) {
- return fdt_setprop(blob, nodeoffset, name, bd->bi_enet2addr, 6);
- }
- return 0;
-}
-#endif
-#ifdef CONFIG_HAS_ETH3
-/* fourth onboard ethernet port */
-static int fdt_set_eth3(void *blob, int nodeoffset, const char *name, bd_t *bd)
-{
- /* Fix it up if it exists, don't create it if it doesn't exist */
- if (fdt_get_property(blob, nodeoffset, name, 0)) {
- return fdt_setprop(blob, nodeoffset, name, bd->bi_enet3addr, 6);
- }
- return 0;
-}
-#endif
-
-static int fdt_set_busfreq(void *blob, int nodeoffset, const char *name, bd_t *bd)
-{
- u32 tmp;
- /* Create or update the property */
- tmp = cpu_to_be32(bd->bi_busfreq);
- return fdt_setprop(blob, nodeoffset, name, &tmp, sizeof(tmp));
-}
-
-static int fdt_set_tbfreq(void *blob, int nodeoffset, const char *name, bd_t *bd)
-{
- u32 tmp;
- /* Create or update the property */
- tmp = cpu_to_be32(OF_TBCLK);
- return fdt_setprop(blob, nodeoffset, name, &tmp, sizeof(tmp));
-}
-
-
-static int fdt_set_clockfreq(void *blob, int nodeoffset, const char *name, bd_t *bd)
-{
- u32 tmp;
- /* Create or update the property */
- tmp = cpu_to_be32(gd->core_clk);
- return fdt_setprop(blob, nodeoffset, name, &tmp, sizeof(tmp));
-}
-
-#ifdef CONFIG_QE
-static int fdt_set_qe_busfreq(void *blob, int nodeoffset, const char *name, bd_t *bd)
-{
- u32 tmp;
- /* Create or update the property */
- tmp = cpu_to_be32(gd->qe_clk);
- return fdt_setprop(blob, nodeoffset, name, &tmp, sizeof(tmp));
-}
-
-static int fdt_set_qe_brgfreq(void *blob, int nodeoffset, const char *name, bd_t *bd)
-{
- u32 tmp;
- /* Create or update the property */
- tmp = cpu_to_be32(gd->brg_clk);
- return fdt_setprop(blob, nodeoffset, name, &tmp, sizeof(tmp));
-}
-#endif
-
-/*
- * Fixups to the fdt.
- */
-static const struct {
- char *node;
- char *prop;
- int (*set_fn)(void *blob, int nodeoffset, const char *name, bd_t *bd);
-} fixup_props[] = {
- { "/cpus/" OF_CPU,
- "timebase-frequency",
- fdt_set_tbfreq
- },
- { "/cpus/" OF_CPU,
- "bus-frequency",
- fdt_set_busfreq
- },
- { "/cpus/" OF_CPU,
- "clock-frequency",
- fdt_set_clockfreq
- },
- { "/" OF_SOC,
- "bus-frequency",
- fdt_set_busfreq
- },
- { "/" OF_SOC "/serial@4500",
- "clock-frequency",
- fdt_set_busfreq
- },
- { "/" OF_SOC "/serial@4600",
- "clock-frequency",
- fdt_set_busfreq
- },
-#ifdef CONFIG_TSEC1
- { "/" OF_SOC "/ethernet@24000",
- "mac-address",
- fdt_set_eth0
- },
- { "/" OF_SOC "/ethernet@24000",
- "local-mac-address",
- fdt_set_eth0
- },
-#endif
-#ifdef CONFIG_TSEC2
- { "/" OF_SOC "/ethernet@25000",
- "mac-address",
- fdt_set_eth1
- },
- { "/" OF_SOC "/ethernet@25000",
- "local-mac-address",
- fdt_set_eth1
- },
-#endif
-#ifdef CONFIG_QE
- { "/" OF_QE,
- "brg-frequency",
- fdt_set_qe_brgfreq
- },
- { "/" OF_QE,
- "bus-frequency",
- fdt_set_qe_busfreq
- },
-#ifdef CONFIG_UEC_ETH1
-#if CFG_UEC1_UCC_NUM == 0 /* UCC1 */
- { "/" OF_QE "/ucc@2000",
- "mac-address",
- fdt_set_eth0
- },
- { "/" OF_QE "/ucc@2000",
- "local-mac-address",
- fdt_set_eth0
- },
-#elif CFG_UEC1_UCC_NUM == 2 /* UCC3 */
- { "/" OF_QE "/ucc@2200",
- "mac-address",
- fdt_set_eth0
- },
- { "/" OF_QE "/ucc@2200",
- "local-mac-address",
- fdt_set_eth0
- },
-#endif
-#endif /* CONFIG_UEC_ETH1 */
-#ifdef CONFIG_UEC_ETH2
-#if CFG_UEC2_UCC_NUM == 1 /* UCC2 */
- { "/" OF_QE "/ucc@3000",
- "mac-address",
- fdt_set_eth1
- },
- { "/" OF_QE "/ucc@3000",
- "local-mac-address",
- fdt_set_eth1
- },
-#elif CFG_UEC2_UCC_NUM == 3 /* UCC4 */
- { "/" OF_QE "/ucc@3200",
- "mac-address",
- fdt_set_eth1
- },
- { "/" OF_QE "/ucc@3200",
- "local-mac-address",
- fdt_set_eth1
- },
-#endif
-#endif /* CONFIG_UEC_ETH2 */
-#endif /* CONFIG_QE */
-};
-
-void
-ft_cpu_setup(void *blob, bd_t *bd)
-{
- int nodeoffset;
- int err;
- int j;
-
- for (j = 0; j < (sizeof(fixup_props) / sizeof(fixup_props[0])); j++) {
- nodeoffset = fdt_path_offset(blob, fixup_props[j].node);
- if (nodeoffset >= 0) {
- err = fixup_props[j].set_fn(blob, nodeoffset,
- fixup_props[j].prop, bd);
- if (err < 0)
- debug("Problem setting %s = %s: %s\n",
- fixup_props[j].node, fixup_props[j].prop,
- fdt_strerror(err));
- } else {
- debug("Couldn't find %s: %s\n",
- fixup_props[j].node, fdt_strerror(nodeoffset));
- }
- }
-
- fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
-}
-#elif defined(CONFIG_OF_FLAT_TREE)
-void
-ft_cpu_setup(void *blob, bd_t *bd)
-{
- u32 *p;
- int len;
- ulong clock;
-
- clock = bd->bi_busfreq;
- p = ft_get_prop(blob, "/cpus/" OF_CPU "/bus-frequency", &len);
- if (p != NULL)
- *p = cpu_to_be32(clock);
-
- p = ft_get_prop(blob, "/" OF_SOC "/bus-frequency", &len);
- if (p != NULL)
- *p = cpu_to_be32(clock);
-
- p = ft_get_prop(blob, "/" OF_SOC "/serial@4500/clock-frequency", &len);
- if (p != NULL)
- *p = cpu_to_be32(clock);
-
- p = ft_get_prop(blob, "/" OF_SOC "/serial@4600/clock-frequency", &len);
- if (p != NULL)
- *p = cpu_to_be32(clock);
-
-#ifdef CONFIG_TSEC1
- p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/mac-address", &len);
- if (p != NULL)
- memcpy(p, bd->bi_enetaddr, 6);
-
- p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/local-mac-address", &len);
- if (p != NULL)
- memcpy(p, bd->bi_enetaddr, 6);
-#endif
-
-#ifdef CONFIG_TSEC2
- p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/mac-address", &len);
- if (p != NULL)
- memcpy(p, bd->bi_enet1addr, 6);
-
- p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/local-mac-address", &len);
- if (p != NULL)
- memcpy(p, bd->bi_enet1addr, 6);
-#endif
-
-#ifdef CONFIG_UEC_ETH1
-#if CFG_UEC1_UCC_NUM == 0 /* UCC1 */
- p = ft_get_prop(blob, "/" OF_QE "/ucc@2000/mac-address", &len);
- if (p != NULL)
- memcpy(p, bd->bi_enetaddr, 6);
-
- p = ft_get_prop(blob, "/" OF_QE "/ucc@2000/local-mac-address", &len);
- if (p != NULL)
- memcpy(p, bd->bi_enetaddr, 6);
-#elif CFG_UEC1_UCC_NUM == 2 /* UCC3 */
- p = ft_get_prop(blob, "/" OF_QE "/ucc@2200/mac-address", &len);
- if (p != NULL)
- memcpy(p, bd->bi_enetaddr, 6);
-
- p = ft_get_prop(blob, "/" OF_QE "/ucc@2200/local-mac-address", &len);
- if (p != NULL)
- memcpy(p, bd->bi_enetaddr, 6);
-#endif
-#endif
-
-#ifdef CONFIG_UEC_ETH2
-#if CFG_UEC2_UCC_NUM == 1 /* UCC2 */
- p = ft_get_prop(blob, "/" OF_QE "/ucc@3000/mac-address", &len);
- if (p != NULL)
- memcpy(p, bd->bi_enet1addr, 6);
-
- p = ft_get_prop(blob, "/" OF_QE "/ucc@3000/local-mac-address", &len);
- if (p != NULL)
- memcpy(p, bd->bi_enet1addr, 6);
-#elif CFG_UEC2_UCC_NUM == 3 /* UCC4 */
- p = ft_get_prop(blob, "/" OF_QE "/ucc@3200/mac-address", &len);
- if (p != NULL)
- memcpy(p, bd->bi_enet1addr, 6);
-
- p = ft_get_prop(blob, "/" OF_QE "/ucc@3200/local-mac-address", &len);
- if (p != NULL)
- memcpy(p, bd->bi_enet1addr, 6);
-#endif
-#endif
-}
-#endif
-
#if defined(CONFIG_DDR_ECC)
void dma_init(void)
{
diff --git a/cpu/mpc83xx/cpu_init.c b/cpu/mpc83xx/cpu_init.c
index 722497966a..2b92be01ad 100644
--- a/cpu/mpc83xx/cpu_init.c
+++ b/cpu/mpc83xx/cpu_init.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2006 Freescale Semiconductor, Inc.
+ * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -155,6 +155,10 @@ void cpu_init_f (volatile immap_t * im)
#ifdef CFG_DDRCDR
im->sysconf.ddrcdr = CFG_DDRCDR;
#endif
+ /* Output buffer impedance register */
+#ifdef CFG_OBIR
+ im->sysconf.obir = CFG_OBIR;
+#endif
#ifdef CONFIG_QE
/* Config QE ioports */
diff --git a/cpu/mpc83xx/fdt.c b/cpu/mpc83xx/fdt.c
new file mode 100644
index 0000000000..909171fd4f
--- /dev/null
+++ b/cpu/mpc83xx/fdt.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2007 Freescale Semiconductor, Inc.
+ *
+ * (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>
+
+#if defined(CONFIG_OF_LIBFDT)
+
+#include <libfdt.h>
+#include <fdt_support.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void ft_cpu_setup(void *blob, bd_t *bd)
+{
+#if defined(CONFIG_HAS_ETH0) || defined(CONFIG_HAS_ETH1) ||\
+ defined(CONFIG_HAS_ETH2) || defined(CONFIG_HAS_ETH3)
+ fdt_fixup_ethernet(blob, bd);
+#endif
+
+ do_fixup_by_prop_u32(blob, "device_type", "cpu", 4,
+ "timebase-frequency", (bd->bi_busfreq / 4), 1);
+ do_fixup_by_prop_u32(blob, "device_type", "cpu", 4,
+ "bus-frequency", bd->bi_busfreq, 1);
+ do_fixup_by_prop_u32(blob, "device_type", "cpu", 4,
+ "clock-frequency", gd->core_clk, 1);
+ do_fixup_by_prop_u32(blob, "device_type", "soc", 4,
+ "bus-frequency", bd->bi_busfreq, 1);
+#ifdef CONFIG_QE
+ do_fixup_by_prop_u32(blob, "device_type", "qe", 4,
+ "bus-frequency", gd->qe_clk, 1);
+ do_fixup_by_prop_u32(blob, "device_type", "qe", 4,
+ "brg-frequency", gd->brg_clk, 1);
+ do_fixup_by_compat_u32(blob, "fsl,qe",
+ "clock-frequency", gd->qe_clk, 1);
+ do_fixup_by_compat_u32(blob, "fsl,qe",
+ "bus-frequency", gd->qe_clk, 1);
+ do_fixup_by_compat_u32(blob, "fsl,qe",
+ "brg-frequency", gd->brg_clk, 1);
+#endif
+
+#ifdef CFG_NS16550
+ do_fixup_by_compat_u32(blob, "ns16550",
+ "clock-frequency", bd->bi_busfreq, 1);
+#endif
+
+#ifdef CONFIG_CPM2
+ do_fixup_by_compat_u32(blob, "fsl,cpm2-scc-uart",
+ "current-speed", bd->bi_baudrate, 1);
+
+ do_fixup_by_compat_u32(blob, "fsl,cpm2-brg",
+ "clock-frequency", bd->bi_brgfreq, 1);
+#endif
+
+ fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
+}
+#endif /* CONFIG_OF_LIBFDT */
diff --git a/cpu/mpc83xx/pci.c b/cpu/mpc83xx/pci.c
index 0defb0ec89..18558db537 100644
--- a/cpu/mpc83xx/pci.c
+++ b/cpu/mpc83xx/pci.c
@@ -28,8 +28,7 @@
#if defined(CONFIG_OF_LIBFDT)
#include <libfdt.h>
-#elif defined(CONFIG_OF_FLAT_TREE)
-#include <ft_build.h>
+#include <fdt_support.h>
#endif
#include <asm/mpc8349_pci.h>
@@ -173,63 +172,41 @@ void mpc83xx_pci_init(int num_buses, struct pci_region **reg, int warmboot)
void ft_pci_setup(void *blob, bd_t *bd)
{
int nodeoffset;
- int err;
int tmp[2];
+ const char *path;
if (pci_num_buses < 1)
return;
- nodeoffset = fdt_path_offset(blob, "/" OF_SOC "/pci@8500");
+ nodeoffset = fdt_path_offset(blob, "/aliases");
if (nodeoffset >= 0) {
- tmp[0] = cpu_to_be32(pci_hose[0].first_busno);
- tmp[1] = cpu_to_be32(pci_hose[0].last_busno);
- err = fdt_setprop(blob, nodeoffset, "bus-range",
- tmp, sizeof(tmp));
-
- tmp[0] = cpu_to_be32(gd->pci_clk);
- err = fdt_setprop(blob, nodeoffset, "clock-frequency",
- tmp, sizeof(tmp[0]));
- }
-
- if (pci_num_buses < 2)
- return;
-
- nodeoffset = fdt_path_offset(blob, "/" OF_SOC "/pci@8600");
- if (nodeoffset >= 0) {
- tmp[0] = cpu_to_be32(pci_hose[0].first_busno);
- tmp[1] = cpu_to_be32(pci_hose[0].last_busno);
- err = fdt_setprop(blob, nodeoffset, "bus-range",
- tmp, sizeof(tmp));
-
- tmp[0] = cpu_to_be32(gd->pci_clk);
- err = fdt_setprop(blob, nodeoffset, "clock-frequency",
- tmp, sizeof(tmp[0]));
- }
-}
-#elif CONFIG_OF_FLAT_TREE
-void ft_pci_setup(void *blob, bd_t *bd)
-{
- u32 *p;
- int len;
-
- if (pci_num_buses < 1)
- return;
-
- p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8500/bus-range", &len);
- if (p) {
- p[0] = pci_hose[0].first_busno;
- p[1] = pci_hose[0].last_busno;
- }
-
- if (pci_num_buses < 2)
- return;
-
- p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8600/bus-range", &len);
- if (p) {
- p[0] = pci_hose[1].first_busno;
- p[1] = pci_hose[1].last_busno;
+ path = fdt_getprop(blob, nodeoffset, "pci0", NULL);
+ if (path) {
+ tmp[0] = cpu_to_be32(pci_hose[0].first_busno);
+ tmp[1] = cpu_to_be32(pci_hose[0].last_busno);
+ do_fixup_by_path(blob, path, "bus-range",
+ &tmp, sizeof(tmp), 1);
+
+ tmp[0] = cpu_to_be32(gd->pci_clk);
+ do_fixup_by_path(blob, path, "clock-frequency",
+ &tmp, sizeof(tmp[0]), 1);
+ }
+
+ if (pci_num_buses < 2)
+ return;
+
+ path = fdt_getprop(blob, nodeoffset, "pci1", NULL);
+ if (path) {
+ tmp[0] = cpu_to_be32(pci_hose[0].first_busno);
+ tmp[1] = cpu_to_be32(pci_hose[0].last_busno);
+ do_fixup_by_path(blob, path, "bus-range",
+ &tmp, sizeof(tmp), 1);
+
+ tmp[0] = cpu_to_be32(gd->pci_clk);
+ do_fixup_by_path(blob, path, "clock-frequency",
+ &tmp, sizeof(tmp[0]), 1);
+ }
}
}
-#endif /* CONFIG_OF_FLAT_TREE */
-
+#endif /* CONFIG_OF_LIBFDT */
#endif /* CONFIG_83XX_GENERIC_PCI */
diff --git a/cpu/mpc83xx/spd_sdram.c b/cpu/mpc83xx/spd_sdram.c
index ee2d0385e4..0acca47717 100644
--- a/cpu/mpc83xx/spd_sdram.c
+++ b/cpu/mpc83xx/spd_sdram.c
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2006 Freescale Semiconductor, Inc.
+ * (C) Copyright 2006-2007 Freescale Semiconductor, Inc.
*
* (C) Copyright 2006
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
@@ -198,6 +198,7 @@ long int spd_sdram()
if(spd.mem_type == SPD_MEMTYPE_DDR2) {
immap->sysconf.ddrcdr = CFG_DDRCDR_VALUE;
}
+ udelay(50000);
#endif
/*
@@ -573,10 +574,10 @@ long int spd_sdram()
*/
cpo = 0;
if (spd.mem_type == SPD_MEMTYPE_DDR2) {
- if (effective_data_rate == 266 || effective_data_rate == 333) {
+ if (effective_data_rate == 266) {
+ cpo = 0x4; /* READ_LAT + 1/2 */
+ } else if (effective_data_rate == 333 || effective_data_rate == 400) {
cpo = 0x7; /* READ_LAT + 5/4 */
- } else if (effective_data_rate == 400) {
- cpo = 0x9; /* READ_LAT + 7/4 */
} else {
/* Automatic calibration */
cpo = 0x1f;
@@ -705,9 +706,11 @@ long int spd_sdram()
* SDRAM Cfg 2
*/
odt_cfg = 0;
+#ifndef CONFIG_NEVER_ASSERT_ODT_TO_CPU
if (odt_rd_cfg | odt_wr_cfg) {
odt_cfg = 0x2; /* ODT to IOs during reads */
}
+#endif
if (spd.mem_type == SPD_MEMTYPE_DDR2) {
ddr->sdram_cfg2 = (0
| (0 << 26) /* True DQS */
diff --git a/cpu/mpc83xx/speed.c b/cpu/mpc83xx/speed.c
index cba57fadb9..4f5a866181 100644
--- a/cpu/mpc83xx/speed.c
+++ b/cpu/mpc83xx/speed.c
@@ -2,7 +2,7 @@
* (C) Copyright 2000-2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
- * Copyright (C) 2004-2006 Freescale Semiconductor, Inc.
+ * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -100,7 +100,7 @@ int get_clocks(void)
u32 lcrr;
u32 csb_clk;
-#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X)
+#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X) || defined(CONFIG_MPC837X)
u32 tsec1_clk;
u32 tsec2_clk;
u32 usbdr_clk;
@@ -113,6 +113,12 @@ int get_clocks(void)
#if !defined(CONFIG_MPC832X)
u32 i2c2_clk;
#endif
+#if defined(CONFIG_MPC8315)
+ u32 tdm_clk;
+#endif
+#if defined(CONFIG_MPC837X)
+ u32 sdhc_clk;
+#endif
u32 enc_clk;
u32 lbiu_clk;
u32 lclk_clk;
@@ -126,6 +132,13 @@ int get_clocks(void)
u32 qe_clk;
u32 brg_clk;
#endif
+#if defined(CONFIG_MPC837X)
+ u32 pciexp1_clk;
+ u32 pciexp2_clk;
+#endif
+#if defined(CONFIG_MPC837X) || defined(CONFIG_MPC8315)
+ u32 sata_clk;
+#endif
if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im)
return -1;
@@ -151,7 +164,7 @@ int get_clocks(void)
sccr = im->clk.sccr;
-#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X)
+#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X) || defined(CONFIG_MPC837X)
switch ((sccr & SCCR_TSEC1CM) >> SCCR_TSEC1CM_SHIFT) {
case 0:
tsec1_clk = 0;
@@ -167,7 +180,7 @@ int get_clocks(void)
break;
default:
/* unkown SCCR_TSEC1CM value */
- return -4;
+ return -2;
}
switch ((sccr & SCCR_USBDRCM) >> SCCR_USBDRCM_SHIFT) {
@@ -185,11 +198,11 @@ int get_clocks(void)
break;
default:
/* unkown SCCR_USBDRCM value */
- return -8;
+ return -3;
}
#endif
-#if defined(CONFIG_MPC834X)
+#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC837X) || defined(CONFIG_MPC8315)
switch ((sccr & SCCR_TSEC2CM) >> SCCR_TSEC2CM_SHIFT) {
case 0:
tsec2_clk = 0;
@@ -205,11 +218,18 @@ int get_clocks(void)
break;
default:
/* unkown SCCR_TSEC2CM value */
- return -5;
+ return -4;
}
+#elif defined(CONFIG_MPC8313)
+ tsec2_clk = tsec1_clk;
- i2c1_clk = tsec2_clk;
+ if (!(sccr & SCCR_TSEC1ON))
+ tsec1_clk = 0;
+ if (!(sccr & SCCR_TSEC2ON))
+ tsec2_clk = 0;
+#endif
+#if defined(CONFIG_MPC834X)
switch ((sccr & SCCR_USBMPHCM) >> SCCR_USBMPHCM_SHIFT) {
case 0:
usbmph_clk = 0;
@@ -225,7 +245,7 @@ int get_clocks(void)
break;
default:
/* unkown SCCR_USBMPHCM value */
- return -7;
+ return -5;
}
if (usbmph_clk != 0 && usbdr_clk != 0 && usbmph_clk != usbdr_clk) {
@@ -233,41 +253,138 @@ int get_clocks(void)
* USB DR clock is not disabled then
* USB MPH & USB DR must have the same rate
*/
- return -9;
+ return -6;
+ }
+#endif
+ switch ((sccr & SCCR_ENCCM) >> SCCR_ENCCM_SHIFT) {
+ case 0:
+ enc_clk = 0;
+ break;
+ case 1:
+ enc_clk = csb_clk;
+ break;
+ case 2:
+ enc_clk = csb_clk / 2;
+ break;
+ case 3:
+ enc_clk = csb_clk / 3;
+ break;
+ default:
+ /* unkown SCCR_ENCCM value */
+ return -7;
}
-#elif defined(CONFIG_MPC831X)
- tsec2_clk = tsec1_clk;
- if (!(sccr & SCCR_TSEC1ON))
- tsec1_clk = 0;
- if (!(sccr & SCCR_TSEC2ON))
- tsec2_clk = 0;
+#if defined(CONFIG_MPC837X)
+ switch ((sccr & SCCR_SDHCCM) >> SCCR_SDHCCM_SHIFT) {
+ case 0:
+ sdhc_clk = 0;
+ break;
+ case 1:
+ sdhc_clk = csb_clk;
+ break;
+ case 2:
+ sdhc_clk = csb_clk / 2;
+ break;
+ case 3:
+ sdhc_clk = csb_clk / 3;
+ break;
+ default:
+ /* unkown SCCR_SDHCCM value */
+ return -8;
+ }
+#endif
+#if defined(CONFIG_MPC8315)
+ switch ((sccr & SCCR_TDMCM) >> SCCR_TDMCM_SHIFT) {
+ case 0:
+ tdm_clk = 0;
+ break;
+ case 1:
+ tdm_clk = csb_clk;
+ break;
+ case 2:
+ tdm_clk = csb_clk / 2;
+ break;
+ case 3:
+ tdm_clk = csb_clk / 3;
+ break;
+ default:
+ /* unkown SCCR_TDMCM value */
+ return -8;
+ }
#endif
-#if !defined(CONFIG_MPC834X)
+#if defined(CONFIG_MPC834X)
+ i2c1_clk = tsec2_clk;
+#elif defined(CONFIG_MPC8360)
i2c1_clk = csb_clk;
+#elif defined(CONFIG_MPC832X)
+ i2c1_clk = enc_clk;
+#elif defined(CONFIG_MPC831X)
+ i2c1_clk = enc_clk;
+#elif defined(CONFIG_MPC837X)
+ i2c1_clk = sdhc_clk;
#endif
#if !defined(CONFIG_MPC832X)
- i2c2_clk = csb_clk; /* i2c-2 clk is equal to csb clk */
+ i2c2_clk = csb_clk; /* i2c-2 clk is equal to csb clk */
#endif
- switch ((sccr & SCCR_ENCCM) >> SCCR_ENCCM_SHIFT) {
+#if defined(CONFIG_MPC837X)
+ switch ((sccr & SCCR_PCIEXP1CM) >> SCCR_PCIEXP1CM_SHIFT) {
case 0:
- enc_clk = 0;
+ pciexp1_clk = 0;
break;
case 1:
- enc_clk = csb_clk;
+ pciexp1_clk = csb_clk;
break;
case 2:
- enc_clk = csb_clk / 2;
+ pciexp1_clk = csb_clk / 2;
break;
case 3:
- enc_clk = csb_clk / 3;
+ pciexp1_clk = csb_clk / 3;
break;
default:
- /* unkown SCCR_ENCCM value */
- return -6;
+ /* unkown SCCR_PCIEXP1CM value */
+ return -9;
+ }
+
+ switch ((sccr & SCCR_PCIEXP2CM) >> SCCR_PCIEXP2CM_SHIFT) {
+ case 0:
+ pciexp2_clk = 0;
+ break;
+ case 1:
+ pciexp2_clk = csb_clk;
+ break;
+ case 2:
+ pciexp2_clk = csb_clk / 2;
+ break;
+ case 3:
+ pciexp2_clk = csb_clk / 3;
+ break;
+ default:
+ /* unkown SCCR_PCIEXP2CM value */
+ return -10;
}
+#endif
+
+#if defined(CONFIG_MPC837X) || defined(CONFIG_MPC8315)
+ switch ((sccr & SCCR_SATA1CM) >> SCCR_SATA1CM_SHIFT) {
+ case 0:
+ sata_clk = 0;
+ break;
+ case 1:
+ sata_clk = csb_clk;
+ break;
+ case 2:
+ sata_clk = csb_clk / 2;
+ break;
+ case 3:
+ sata_clk = csb_clk / 3;
+ break;
+ default:
+ /* unkown SCCR_SATA1CM value */
+ return -11;
+ }
+#endif
lbiu_clk = csb_clk *
(1 + ((im->reset.rcwl & HRCWL_LBIUCM) >> HRCWL_LBIUCM_SHIFT));
@@ -280,7 +397,7 @@ int get_clocks(void)
break;
default:
/* unknown lcrr */
- return -10;
+ return -12;
}
ddr_clk = csb_clk *
@@ -316,7 +433,7 @@ int get_clocks(void)
break;
default:
/* unkown core to csb ratio */
- return -12;
+ return -13;
}
#if defined(CONFIG_MPC8360) || defined(CONFIG_MPC832X)
@@ -327,7 +444,7 @@ int get_clocks(void)
#endif
gd->csb_clk = csb_clk;
-#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X)
+#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X) || defined(CONFIG_MPC837X)
gd->tsec1_clk = tsec1_clk;
gd->tsec2_clk = tsec2_clk;
gd->usbdr_clk = usbdr_clk;
@@ -335,6 +452,12 @@ int get_clocks(void)
#if defined(CONFIG_MPC834X)
gd->usbmph_clk = usbmph_clk;
#endif
+#if defined(CONFIG_MPC8315)
+ gd->tdm_clk = tdm_clk;
+#endif
+#if defined(CONFIG_MPC837X)
+ gd->sdhc_clk = sdhc_clk;
+#endif
gd->core_clk = core_clk;
gd->i2c1_clk = i2c1_clk;
#if !defined(CONFIG_MPC832X)
@@ -351,6 +474,13 @@ int get_clocks(void)
gd->qe_clk = qe_clk;
gd->brg_clk = brg_clk;
#endif
+#if defined(CONFIG_MPC837X)
+ gd->pciexp1_clk = pciexp1_clk;
+ gd->pciexp2_clk = pciexp2_clk;
+#endif
+#if defined(CONFIG_MPC837X) || defined(CONFIG_MPC8315)
+ gd->sata_clk = sata_clk;
+#endif
gd->pci_clk = pci_sync_in;
gd->cpu_clk = gd->core_clk;
gd->bus_clk = gd->csb_clk;
@@ -387,7 +517,13 @@ int do_clocks (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
#if !defined(CONFIG_MPC832X)
printf(" I2C2: %4d MHz\n", gd->i2c2_clk / 1000000);
#endif
-#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X)
+#if defined(CONFIG_MPC8315)
+ printf(" TDM: %4d MHz\n", gd->tdm_clk / 1000000);
+#endif
+#if defined(CONFIG_MPC837X)
+ printf(" SDHC: %4d MHz\n", gd->sdhc_clk / 1000000);
+#endif
+#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X) || defined(CONFIG_MPC837X)
printf(" TSEC1: %4d MHz\n", gd->tsec1_clk / 1000000);
printf(" TSEC2: %4d MHz\n", gd->tsec2_clk / 1000000);
printf(" USB DR: %4d MHz\n", gd->usbdr_clk / 1000000);
@@ -395,6 +531,13 @@ int do_clocks (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
#if defined(CONFIG_MPC834X)
printf(" USB MPH: %4d MHz\n", gd->usbmph_clk / 1000000);
#endif
+#if defined(CONFIG_MPC837X)
+ printf(" PCIEXP1: %4d MHz\n", gd->pciexp1_clk / 1000000);
+ printf(" PCIEXP2: %4d MHz\n", gd->pciexp2_clk / 1000000);
+#endif
+#if defined(CONFIG_MPC837X) || defined(CONFIG_MPC8315)
+ printf(" SATA: %4d MHz\n", gd->sata_clk / 1000000);
+#endif
return 0;
}
diff --git a/cpu/mpc83xx/start.S b/cpu/mpc83xx/start.S
index 496c8a5861..1dfbf62239 100644
--- a/cpu/mpc83xx/start.S
+++ b/cpu/mpc83xx/start.S
@@ -462,7 +462,7 @@ init_e300_core: /* time t 10 */
li r4, 0x556C
sth r4, SWSRR@l(r3)
- li r4, 0xAA39
+ li r4, -0x55C7
sth r4, SWSRR@l(r3)
#else
/* Disable Wathcdog */
diff --git a/cpu/mpc83xx/u-boot.lds b/cpu/mpc83xx/u-boot.lds
index 937c87a27c..8da6f14725 100644
--- a/cpu/mpc83xx/u-boot.lds
+++ b/cpu/mpc83xx/u-boot.lds
@@ -110,7 +110,7 @@ SECTIONS
__init_end = .;
__bss_start = .;
- .bss :
+ .bss (NOLOAD) :
{
*(.sbss) *(.scommon)
*(.dynbss)
diff --git a/cpu/mpc85xx/fdt.c b/cpu/mpc85xx/fdt.c
index 737a6c485a..0ce17e7f57 100644
--- a/cpu/mpc85xx/fdt.c
+++ b/cpu/mpc85xx/fdt.c
@@ -43,8 +43,11 @@ void ft_cpu_setup(void *blob, bd_t *bd)
do_fixup_by_prop_u32(blob, "device_type", "soc", 4,
"bus-frequency", bd->bi_busfreq, 1);
#ifdef CONFIG_QE
- do_fixup_by_prop_u32(blob, "device_type", "soc", 4,
+ do_fixup_by_prop_u32(blob, "device_type", "qe", 4,
"bus-frequency", bd->bi_busfreq, 1);
+ do_fixup_by_prop_u32(blob, "device_type", "qe", 4,
+ "brg-frequency", bd->bi_busfreq / 2, 1);
+ fdt_fixup_qe_firmware(blob);
#endif
#ifdef CFG_NS16550
diff --git a/cpu/mpc85xx/spd_sdram.c b/cpu/mpc85xx/spd_sdram.c
index 553f736a56..adc9c4dd40 100644
--- a/cpu/mpc85xx/spd_sdram.c
+++ b/cpu/mpc85xx/spd_sdram.c
@@ -1071,22 +1071,19 @@ setup_laws_and_tlbs(unsigned int memsize)
ram_tlb_address = (unsigned int)CFG_DDR_SDRAM_BASE;
while (ram_tlb_address < (memsize * 1024 * 1024)
&& ram_tlb_index < 16) {
- mtspr(MAS0, TLB1_MAS0(1, ram_tlb_index, 0));
- mtspr(MAS1, TLB1_MAS1(1, 1, 0, 0, tlb_size));
- mtspr(MAS2, TLB1_MAS2(E500_TLB_EPN(ram_tlb_address),
- 0, 0, 0, 0, 0, 0, 0, 0));
- mtspr(MAS3, TLB1_MAS3(E500_TLB_RPN(ram_tlb_address),
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 1));
+ mtspr(MAS0, FSL_BOOKE_MAS0(1, ram_tlb_index, 0));
+ mtspr(MAS1, FSL_BOOKE_MAS1(1, 1, 0, 0, tlb_size));
+ mtspr(MAS2, FSL_BOOKE_MAS2(ram_tlb_address, 0));
+ mtspr(MAS3, FSL_BOOKE_MAS3(ram_tlb_address, 0,
+ (MAS3_SX|MAS3_SW|MAS3_SR)));
asm volatile("isync;msync;tlbwe;isync");
- debug("DDR: MAS0=0x%08x\n", TLB1_MAS0(1, ram_tlb_index, 0));
- debug("DDR: MAS1=0x%08x\n", TLB1_MAS1(1, 1, 0, 0, tlb_size));
- debug("DDR: MAS2=0x%08x\n",
- TLB1_MAS2(E500_TLB_EPN(ram_tlb_address),
- 0, 0, 0, 0, 0, 0, 0, 0));
+ debug("DDR: MAS0=0x%08x\n", FSL_BOOKE_MAS0(1, ram_tlb_index, 0));
+ debug("DDR: MAS1=0x%08x\n", FSL_BOOKE_MAS1(1, 1, 0, 0, tlb_size));
+ debug("DDR: MAS2=0x%08x\n", FSL_BOOKE_MAS2(ram_tlb_address, 0));
debug("DDR: MAS3=0x%08x\n",
- TLB1_MAS3(E500_TLB_RPN(ram_tlb_address),
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 1));
+ FSL_BOOKE_MAS3(ram_tlb_address, 0,
+ (MAS3_SX|MAS3_SW|MAS3_SR)));
ram_tlb_address += (0x1000 << ((tlb_size - 1) * 2));
ram_tlb_index++;
diff --git a/cpu/mpc85xx/start.S b/cpu/mpc85xx/start.S
index b769ef8a76..b489d2ff0c 100644
--- a/cpu/mpc85xx/start.S
+++ b/cpu/mpc85xx/start.S
@@ -268,7 +268,10 @@ _start_e500:
*/
lis r3,CFG_INIT_RAM_ADDR@h
ori r3,r3,CFG_INIT_RAM_ADDR@l
- li r2,(CFG_DCACHE_SIZE / (2 * CFG_CACHELINE_SIZE))
+ mfspr r2, L1CFG0
+ andi. r2, r2, 0x1ff
+ /* cache size * 1024 / (2 * L1 line size) */
+ slwi r2, r2, (10 - 1 - L1_CACHE_SHIFT)
mtctr r2
li r0,0
1:
@@ -1061,7 +1064,9 @@ unlock_ram_in_cache:
/* invalidate the INIT_RAM section */
lis r3,(CFG_INIT_RAM_ADDR & ~31)@h
ori r3,r3,(CFG_INIT_RAM_ADDR & ~31)@l
- li r4,(CFG_DCACHE_SIZE / (2 * CFG_CACHELINE_SIZE))
+ mfspr r4,L1CFG0
+ andi. r4,r4,0x1ff
+ slwi r4,r4,(10 - 1 - L1_CACHE_SHIFT)
mtctr r4
1: icbi r0,r3
dcbi r0,r3
diff --git a/cpu/mpc86xx/cpu.c b/cpu/mpc86xx/cpu.c
index d83bedd6e0..11354d38da 100644
--- a/cpu/mpc86xx/cpu.c
+++ b/cpu/mpc86xx/cpu.c
@@ -41,6 +41,8 @@ checkcpu(void)
uint major, minor;
uint lcrr; /* local bus clock ratio register */
uint clkdiv; /* clock divider portion of lcrr */
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile ccsr_gur_t *gur = &immap->im_gur;
puts("Freescale PowerPC\n");
@@ -54,8 +56,14 @@ checkcpu(void)
switch (ver) {
case PVR_VER(PVR_86xx):
- puts("E600");
- break;
+ {
+ uint msscr0 = mfspr(MSSCR0);
+ printf("E600 Core %d", (msscr0 & 0x20) ? 1 : 0 );
+ if (gur->pordevsr & MPC86xx_PORDEVSR_CORE1TE)
+ puts("\n Core1Translation Enabled");
+ debug(" (MSSCR0=%x, PORDEVSR=%x)", msscr0, gur->pordevsr);
+ }
+ break;
default:
puts("Unknown");
break;
@@ -76,6 +84,9 @@ checkcpu(void)
puts("8641");
}
break;
+ case SVR_8610:
+ puts("8610");
+ break;
default:
puts("Unknown");
break;
diff --git a/cpu/mpc86xx/spd_sdram.c b/cpu/mpc86xx/spd_sdram.c
index 265e033fb3..54e40f1f50 100644
--- a/cpu/mpc86xx/spd_sdram.c
+++ b/cpu/mpc86xx/spd_sdram.c
@@ -196,7 +196,7 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num,
spd_eeprom_t spd;
unsigned int n_ranks;
unsigned int rank_density;
- unsigned int odt_rd_cfg, odt_wr_cfg;
+ unsigned int odt_rd_cfg, odt_wr_cfg, ba_bits;
unsigned int odt_cfg, mode_odt_enable;
unsigned int refresh_clk;
#ifdef MPC86xx_DDR_SDRAM_CLK_CNTL
@@ -321,6 +321,10 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num,
odt_wr_cfg = 1; /* Assert ODT on writes to CS0 */
}
+ ba_bits = 0;
+ if (spd.nbanks == 0x8)
+ ba_bits = 1;
+
#ifdef CONFIG_DDR_INTERLEAVE
if (dimm_num != 1) {
@@ -357,6 +361,7 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num,
#endif
| (odt_rd_cfg << 20)
| (odt_wr_cfg << 16)
+ | (ba_bits << 14)
| (spd.nrow_addr - 12) << 8
| (spd.ncol_addr - 8) );
@@ -386,6 +391,7 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num,
ddr->cs0_config = ( 1 << 31
| (odt_rd_cfg << 20)
| (odt_wr_cfg << 16)
+ | (ba_bits << 14)
| (spd.nrow_addr - 12) << 8
| (spd.ncol_addr - 8) );
@@ -403,6 +409,7 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num,
ddr->cs1_config = ( 1<<31
| (odt_rd_cfg << 20)
| (odt_wr_cfg << 16)
+ | (ba_bits << 14)
| (spd.nrow_addr - 12) << 8
| (spd.ncol_addr - 8) );
debug("DDR: cs1_bnds = 0x%08x\n", ddr->cs1_bnds);
@@ -422,6 +429,7 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num,
ddr->cs2_config = ( 1 << 31
| (odt_rd_cfg << 20)
| (odt_wr_cfg << 16)
+ | (ba_bits << 14)
| (spd.nrow_addr - 12) << 8
| (spd.ncol_addr - 8) );
@@ -439,6 +447,7 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num,
ddr->cs3_config = ( 1<<31
| (odt_rd_cfg << 20)
| (odt_wr_cfg << 16)
+ | (ba_bits << 14)
| (spd.nrow_addr - 12) << 8
| (spd.ncol_addr - 8) );
debug("DDR: cs3_bnds = 0x%08x\n", ddr->cs3_bnds);
diff --git a/cpu/mpc8xx/cpu.c b/cpu/mpc8xx/cpu.c
index 97112f03da..c878352512 100644
--- a/cpu/mpc8xx/cpu.c
+++ b/cpu/mpc8xx/cpu.c
@@ -39,6 +39,12 @@
#include <mpc8xx.h>
#include <asm/cache.h>
+#if defined(CONFIG_OF_LIBFDT)
+#include <libfdt.h>
+#include <libfdt_env.h>
+#include <fdt_support.h>
+#endif
+
DECLARE_GLOBAL_DATA_PTR;
static char *cpu_warning = "\n " \
@@ -632,3 +638,13 @@ void reset_8xx_watchdog (volatile immap_t * immr)
#endif /* CONFIG_WATCHDOG */
/* ------------------------------------------------------------------------- */
+#if defined(CONFIG_OF_LIBFDT)
+void ft_cpu_setup (void *blob, bd_t *bd)
+{
+ char * cpu_path = "/cpus/" OF_CPU;
+
+ do_fixup_by_path_u32(blob, cpu_path, "bus-frequency", bd->bi_busfreq, 1);
+ do_fixup_by_path_u32(blob, cpu_path, "timebase-frequency", OF_TBCLK, 1);
+ do_fixup_by_path_u32(blob, cpu_path, "clock-frequency", bd->bi_intfreq, 1);
+}
+#endif /* CONFIG_OF_LIBFDT */
diff --git a/cpu/mpc8xx/cpu_init.c b/cpu/mpc8xx/cpu_init.c
index c79e5780ad..fb3414aae2 100644
--- a/cpu/mpc8xx/cpu_init.c
+++ b/cpu/mpc8xx/cpu_init.c
@@ -31,7 +31,8 @@
DECLARE_GLOBAL_DATA_PTR;
#endif
-#if defined(CFG_I2C_UCODE_PATCH) || defined(CFG_SPI_UCODE_PATCH)
+#if defined(CFG_I2C_UCODE_PATCH) || defined(CFG_SPI_UCODE_PATCH) || \
+ defined(CFG_SMC_UCODE_PATCH)
void cpm_load_patch (volatile immap_t * immr);
#endif
@@ -253,7 +254,8 @@ void cpu_init_f (volatile immap_t * immr)
immr->im_cpm.cp_rccr = CFG_RCCR;
#endif
-#if defined(CFG_I2C_UCODE_PATCH) || defined(CFG_SPI_UCODE_PATCH)
+#if defined(CFG_I2C_UCODE_PATCH) || defined(CFG_SPI_UCODE_PATCH) || \
+ defined(CFG_SMC_UCODE_PATCH)
cpm_load_patch (immr); /* load mpc8xx microcode patch */
#endif
}
diff --git a/cpu/mpc8xx/fec.c b/cpu/mpc8xx/fec.c
index 08a3715812..37eb481ff1 100644
--- a/cpu/mpc8xx/fec.c
+++ b/cpu/mpc8xx/fec.c
@@ -143,6 +143,9 @@ static int fec_send(struct eth_device* dev, volatile void *packet, int length);
static int fec_recv(struct eth_device* dev);
static int fec_init(struct eth_device* dev, bd_t * bd);
static void fec_halt(struct eth_device* dev);
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+static void __mii_init(void);
+#endif
int fec_initialize(bd_t *bis)
{
@@ -539,6 +542,30 @@ static void fec_pin_init(int fecidx)
}
}
+static int fec_reset(volatile fec_t *fecp)
+{
+ int i;
+
+ /* Whack a reset.
+ * A delay is required between a reset of the FEC block and
+ * initialization of other FEC registers because the reset takes
+ * some time to complete. If you don't delay, subsequent writes
+ * to FEC registers might get killed by the reset routine which is
+ * still in progress.
+ */
+
+ fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET;
+ for (i = 0;
+ (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
+ ++i) {
+ udelay (1);
+ }
+ if (i == FEC_RESET_DELAY)
+ return -1;
+
+ return 0;
+}
+
static int fec_init (struct eth_device *dev, bd_t * bd)
{
struct ether_fcc_info_s *efis = dev->priv;
@@ -573,23 +600,17 @@ static int fec_init (struct eth_device *dev, bd_t * bd)
#endif /* CONFIG_FADS */
}
- /* Whack a reset.
- * A delay is required between a reset of the FEC block and
- * initialization of other FEC registers because the reset takes
- * some time to complete. If you don't delay, subsequent writes
- * to FEC registers might get killed by the reset routine which is
- * still in progress.
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+ /* the MII interface is connected to FEC1
+ * so for the miiphy_xxx function to work we must
+ * call mii_init since fec_halt messes the thing up
*/
- fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET;
- for (i = 0;
- (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
- ++i) {
- udelay (1);
- }
- if (i == FEC_RESET_DELAY) {
+ if (efis->ether_index != 0)
+ __mii_init();
+#endif
+
+ if (fec_reset(fecp) < 0)
printf ("FEC_RESET_DELAY timeout\n");
- return 0;
- }
/* We use strictly polling mode only
*/
@@ -603,7 +624,7 @@ static int fec_init (struct eth_device *dev, bd_t * bd)
/* Set station address
*/
-#define ea eth_get_dev()->enetaddr
+#define ea dev->enetaddr
fecp->fec_addr_low = (ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]);
fecp->fec_addr_high = (ea[4] << 8) | (ea[5]);
#undef ea
@@ -708,7 +729,7 @@ static int fec_init (struct eth_device *dev, bd_t * bd)
if (efis->actual_phy_addr == -1) {
printf ("Unable to discover phy!\n");
- return 0;
+ return -1;
}
#else
efis->actual_phy_addr = -1;
@@ -716,15 +737,8 @@ static int fec_init (struct eth_device *dev, bd_t * bd)
} else {
efis->actual_phy_addr = efis->phy_addr;
}
-#if defined(CONFIG_MII) && defined(CONFIG_RMII)
-
- /* the MII interface is connected to FEC1
- * so for the miiphy_xxx function to work we must
- * call mii_init since fec_halt messes the thing up
- */
- if (efis->ether_index != 0)
- mii_init();
+#if defined(CONFIG_MII) && defined(CONFIG_RMII)
/*
* adapt the RMII speed to the speed of the phy
*/
@@ -751,7 +765,7 @@ static int fec_init (struct eth_device *dev, bd_t * bd)
efis->initialized = 1;
- return 1;
+ return 0;
}
@@ -874,15 +888,14 @@ static int mii_discover_phy(struct eth_device *dev)
udelay(10000); /* wait 10ms */
}
for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) {
- phytype = mii_send(mk_mii_read(phyno, PHY_PHYIDR1));
+ phytype = mii_send(mk_mii_read(phyno, PHY_PHYIDR2));
#ifdef ET_DEBUG
printf("PHY type 0x%x pass %d type ", phytype, pass);
#endif
if (phytype != 0xffff) {
phyaddr = phyno;
- phytype <<= 16;
phytype |= mii_send(mk_mii_read(phyno,
- PHY_PHYIDR2));
+ PHY_PHYIDR1)) << 16;
#ifdef ET_DEBUG
printf("PHY @ 0x%x pass %d type ",phyno,pass);
@@ -929,36 +942,17 @@ static int mii_discover_phy(struct eth_device *dev)
#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && !defined(CONFIG_BITBANGMII)
/****************************************************************************
- * mii_init -- Initialize the MII for MII command without ethernet
+ * mii_init -- Initialize the MII via FEC 1 for MII command without ethernet
* This function is a subset of eth_init
****************************************************************************
*/
-void mii_init (void)
+static void __mii_init(void)
{
volatile immap_t *immr = (immap_t *) CFG_IMMR;
volatile fec_t *fecp = &(immr->im_cpm.cp_fec);
- int i, j;
- for (j = 0; j < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); j++) {
-
- /* Whack a reset.
- * A delay is required between a reset of the FEC block and
- * initialization of other FEC registers because the reset takes
- * some time to complete. If you don't delay, subsequent writes
- * to FEC registers might get killed by the reset routine which is
- * still in progress.
- */
-
- fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET;
- for (i = 0;
- (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
- ++i) {
- udelay (1);
- }
- if (i == FEC_RESET_DELAY) {
+ if (fec_reset(fecp) < 0)
printf ("FEC_RESET_DELAY timeout\n");
- return;
- }
/* We use strictly polling mode only
*/
@@ -968,14 +962,21 @@ void mii_init (void)
*/
fecp->fec_ievent = 0xffc0;
- /* Setup the pin configuration of the FEC(s)
- */
- fec_pin_init(ether_fcc_info[i].ether_index);
-
/* Now enable the transmit and receive processing
*/
fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN;
- }
+}
+
+void mii_init (void)
+{
+ int i;
+
+ __mii_init();
+
+ /* Setup the pin configuration of the FEC(s)
+ */
+ for (i = 0; i < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); i++)
+ fec_pin_init(ether_fcc_info[i].ether_index);
}
/*****************************************************************************
diff --git a/cpu/mpc8xx/serial.c b/cpu/mpc8xx/serial.c
index 68804cc439..ad0229999f 100644
--- a/cpu/mpc8xx/serial.c
+++ b/cpu/mpc8xx/serial.c
@@ -124,6 +124,12 @@ static int smc_init (void)
sp = (smc_t *) &(cp->cp_smc[SMC_INDEX]);
up = (smc_uart_t *) &cp->cp_dparam[PROFF_SMC];
+#ifdef CFG_SMC_UCODE_PATCH
+ up = (smc_uart_t *) &cp->cp_dpmem[up->smc_rpbase];
+#else
+ /* Disable relocation */
+ up->smc_rpbase = 0;
+#endif
/* Disable transmitter/receiver.
*/
@@ -212,6 +218,12 @@ static int smc_init (void)
up->smc_tbase = dpaddr+sizeof(cbd_t);
up->smc_rfcr = SMC_EB;
up->smc_tfcr = SMC_EB;
+#if defined (CFG_SMC_UCODE_PATCH)
+ up->smc_rbptr = up->smc_rbase;
+ up->smc_tbptr = up->smc_tbase;
+ up->smc_rstate = 0;
+ up->smc_tstate = 0;
+#endif
#if defined(CONFIG_MBX)
board_serial_init();
@@ -288,6 +300,9 @@ smc_putc(const char c)
smc_putc ('\r');
up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
+#ifdef CFG_SMC_UCODE_PATCH
+ up = (smc_uart_t *) &cpmp->cp_dpmem[up->smc_rpbase];
+#endif
tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
@@ -326,6 +341,9 @@ smc_getc(void)
unsigned char c;
up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
+#ifdef CFG_SMC_UCODE_PATCH
+ up = (smc_uart_t *) &cpmp->cp_dpmem[up->smc_rpbase];
+#endif
rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
@@ -351,6 +369,9 @@ smc_tstc(void)
volatile cpm8xx_t *cpmp = &(im->im_cpm);
up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
+#ifdef CFG_SMC_UCODE_PATCH
+ up = (smc_uart_t *) &cpmp->cp_dpmem[up->smc_rpbase];
+#endif
rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
diff --git a/cpu/mpc8xx/upatch.c b/cpu/mpc8xx/upatch.c
index eccff645e3..4d6c522467 100644
--- a/cpu/mpc8xx/upatch.c
+++ b/cpu/mpc8xx/upatch.c
@@ -1,7 +1,8 @@
#include <common.h>
#include <commproc.h>
-#if defined(CFG_I2C_UCODE_PATCH) || defined(CFG_SPI_UCODE_PATCH)
+#if defined(CFG_I2C_UCODE_PATCH) || defined(CFG_SPI_UCODE_PATCH) || \
+ defined(CFG_SMC_UCODE_PATCH)
static void UcodeCopy (volatile cpm8xx_t *cpm);
@@ -32,13 +33,29 @@ void cpm_load_patch (volatile immap_t *immr)
}
#endif
+#ifdef CFG_SMC_UCODE_PATCH
+ {
+ volatile smc_uart_t *up = (smc_uart_t *) & immr->im_cpm.cp_dparam[PROFF_SMC1];
+ /* Activate the microcode per the instructions in the microcode manual */
+ /* NOTE: We're only relocating the SMC parameters. */
+ immr->im_cpm.cp_cpmcr1 = 0x8080; /* Write Trap register 1 value */
+ immr->im_cpm.cp_cpmcr2 = 0x8088; /* Write Trap register 2 value */
+ up->smc_rpbase = CFG_SMC_DPMEM_OFFSET; /* Where to relocte SMC params */
+ }
+#endif
+
/*
* Enable DPRAM microcode to execute from the first 512 bytes
* and a 256 byte extension of DPRAM.
*/
+#ifdef CFG_SMC_UCODE_PATCH
+ immr->im_cpm.cp_rccr |= 0x0002;
+#else
immr->im_cpm.cp_rccr |= 0x0001;
+#endif
}
+#if defined(CFG_I2C_UCODE_PATCH) || defined(CFG_SPI_UCODE_PATCh)
static ulong patch_2000[] = {
0x7FFFEFD9, 0x3FFD0000, 0x7FFB49F7, 0x7FF90000,
0x5FEFADF7, 0x5F88ADF7, 0x5FEFAFF7, 0x5F88AFF7,
@@ -82,6 +99,81 @@ static ulong patch_2F00[] = {
0x35931497, 0x35376956, 0xBD697B9D, 0x96931313,
0x19797937, 0x69350000,
};
+#else
+
+static ulong patch_2000[] = {
+ 0x3fff0000, 0x3ffd0000, 0x3ffb0000, 0x3ff90000,
+ 0x5fefeff8, 0x5f91eff8, 0x3ff30000, 0x3ff10000,
+ 0x3a11e710, 0xedf0ccb9, 0xf318ed66, 0x7f0e5fe2,
+ 0x7fedbb38, 0x3afe7468, 0x7fedf4d8, 0x8ffbb92d,
+ 0xb83b77fd, 0xb0bb5eb9, 0xdfda7fed, 0x90bde74d,
+ 0x6f0dcbd3, 0xe7decfed, 0xcb50cfed, 0xcfeddf6d,
+ 0x914d4f74, 0x5eaedfcb, 0x9ee0e7df, 0xefbb6ffb,
+ 0xe7ef7f0e, 0x9ee57fed, 0xebb7effa, 0xeb30affb,
+ 0x7fea90b3, 0x7e0cf09f, 0xbffff318, 0x5fffdfff,
+ 0xac35efea, 0x7fce1fc1, 0xe2ff5fbd, 0xaffbe2ff,
+ 0x5fbfaffb, 0xf9a87d0f, 0xaef8770f, 0x7d0fb0a2,
+ 0xeffbbfff, 0xcfef5fba, 0x7d0fbfff, 0x5fba4cf8,
+ 0x7fddd09b, 0x49f847fd, 0x7efdf097, 0x7fedfffd,
+ 0x7dfdf093, 0xef7e7e1e, 0x5fba7f0e, 0x3a11e710,
+ 0xedf0cc87, 0xfb18ad0a, 0x1f85bbb8, 0x74283b7e,
+ 0x7375e4bb, 0x2ab64fb8, 0x5c7de4bb, 0x32fdffbf,
+ 0x5f0843f8, 0x7ce3e1bb, 0xe74f7ded, 0x6f0f4fe8,
+ 0xc7ba32be, 0x73f2efeb, 0x600b4f78, 0xe5bb760b,
+ 0x5388aef8, 0x4ef80b6a, 0xcfef9ee5, 0xabf8751f,
+ 0xefef5b88, 0x741f4fe8, 0x751e760d, 0x7fdb70dd,
+ 0x741cafce, 0xefcc7fce, 0x751e7088, 0x741ce7bb,
+ 0x334ecfed, 0xafdbefeb, 0xe5bb760b, 0x53ceaef8,
+ 0xafe8e7eb, 0x4bf8771e, 0x7e007fed, 0x4fcbe2cc,
+ 0x7fbc3085, 0x7b0f7a0f, 0x34b177fd, 0xb0e75e93,
+ 0xdf313e3b, 0xaf78741f, 0x741f30cc, 0xcfef5f08,
+ 0x741f3e88, 0xafb8771e, 0x5f437fed, 0x0bafe2cc,
+ 0x741ccfec, 0xe5ca53a9, 0x6fcb4f74, 0x5e89df27,
+ 0x2a923d14, 0x4b8fdf0c, 0x751f741c, 0x6c1eeffa,
+ 0xefea7fce, 0x6ffc309a, 0xefec3fca, 0x308fdf0a,
+ 0xadf85e7a, 0xaf7daefd, 0x5e7adf0a, 0x5e7aafdd,
+ 0x761f1088, 0x1e7c7efd, 0x3089fffe, 0x4908fb18,
+ 0x5fffdfff, 0xafbbf0f7, 0x4ef85f43, 0xadf81489,
+ 0x7a0f7089, 0xcfef5089, 0x7a0fdf0c, 0x5e7cafed,
+ 0xbc6e780f, 0xefef780f, 0xefef790f, 0xa7f85eeb,
+ 0xffef790f, 0xefef790f, 0x1489df0a, 0x5e7aadfd,
+ 0x5f09fffb, 0xe79aded9, 0xeff96079, 0x607ae79a,
+ 0xded8eff9, 0x60795edb, 0x607acfef, 0xefefefdf,
+ 0xefbfef7f, 0xeeffedff, 0xebffe7ff, 0xafefafdf,
+ 0xafbfaf7f, 0xaeffadff, 0xabffa7ff, 0x6fef6fdf,
+ 0x6fbf6f7f, 0x6eff6dff, 0x6bff67ff, 0x2fef2fdf,
+ 0x2fbf2f7f, 0x2eff2dff, 0x2bff27ff, 0x4e08fd1f,
+ 0xe5ff6e0f, 0xaff87eef, 0x7e0ffdef, 0xf11f6079,
+ 0xabf8f51e, 0x7e0af11c, 0x37cfae16, 0x7fec909a,
+ 0xadf8efdc, 0xcfeae52f, 0x7d0fe12b, 0xf11c6079,
+ 0x7e0a4df8, 0xcfea5ea0, 0x7d0befec, 0xcfea5ea2,
+ 0xe522efdc, 0x5ea2cfda, 0x4e08fd1f, 0x6e0faff8,
+ 0x7c1f761f, 0xfdeff91f, 0x6079abf8, 0x761cee00,
+ 0xf91f2bfb, 0xefefcfec, 0xf91f6079, 0x761c27fb,
+ 0xefdf5e83, 0xcfdc7fdd, 0x50f84bf8, 0x47fd7c1f,
+ 0x761ccfcf, 0x7eef7fed, 0x7dfd70ef, 0xef7e7f1e,
+ 0x771efb18, 0x6079e722, 0xe6bbe5bb, 0x2e66e5bb,
+ 0x600b2ee1, 0xe2bbe2bb, 0xe2bbe2bb, 0x2f5ee2bb,
+ 0xe2bb2ff9, 0x6079e2bb,
+};
+
+static ulong patch_2F00[] = {
+ 0x30303030, 0x3e3e3030, 0xaf79b9b3, 0xbaa3b979,
+ 0x9693369f, 0x79f79777, 0x97333fff, 0xfb3b9e9f,
+ 0x79b91d11, 0x9e13f3ff, 0x3f9b6bd9, 0xe173d136,
+ 0x695669d1, 0x697b3daf, 0x79b93a3a, 0x3f979f91,
+ 0x379ff976, 0xf99777fd, 0x9779737d, 0xe9d6bbf9,
+ 0xbfffd9df, 0x97f7fd97, 0x6f7b9bff, 0xf9bd9683,
+ 0x397db973, 0xd97b3b9f, 0xd7f9f733, 0x9993bb9e,
+ 0xe1f9ef93, 0x73773337, 0xb936917d, 0x11f87379,
+ 0xb979d336, 0x8b7ded73, 0x1b7d9337, 0x31f3f22f,
+ 0x3f2327ee, 0xeeeeeeee, 0xeeeeeeee, 0xeeeeeeee,
+ 0xeeeeee4b, 0xf4fbdbd2, 0x58bb1878, 0x577fdfd2,
+ 0xd573b773, 0xf7374b4f, 0xbdbd25b8, 0xb177d2d1,
+ 0x7376856b, 0xbfdd687b, 0xdd2fff8f, 0x78ffff8f,
+ 0xf22f0000,
+};
+#endif
static void UcodeCopy (volatile cpm8xx_t *cpm)
{
diff --git a/cpu/ppc4xx/40x_spd_sdram.c b/cpu/ppc4xx/40x_spd_sdram.c
index 19c4f764e3..42fd7fb872 100644
--- a/cpu/ppc4xx/40x_spd_sdram.c
+++ b/cpu/ppc4xx/40x_spd_sdram.c
@@ -148,7 +148,7 @@ long int spd_sdram(int(read_spd)(uint addr))
int t_rc;
int min_cas;
- PPC405_SYS_INFO sys_info;
+ PPC4xx_SYS_INFO sys_info;
unsigned long bus_period_x_10;
/*
diff --git a/cpu/ppc4xx/440spe_pcie.h b/cpu/ppc4xx/440spe_pcie.h
deleted file mode 100644
index 38745eb797..0000000000
--- a/cpu/ppc4xx/440spe_pcie.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (c) 2005 Cisco Systems. All rights reserved.
- * Roland Dreier <rolandd@cisco.com>
- *
- * 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.
- */
-
-#include <ppc4xx.h>
-#ifndef __440SPE_PCIE_H
-#define __440SPE_PCIE_H
-
-#define mdelay(n) ({unsigned long __ms=(n); while (__ms--) udelay(1000);})
-
-#define DCRN_SDR0_CFGADDR 0x00e
-#define DCRN_SDR0_CFGDATA 0x00f
-
-#define DCRN_PCIE0_BASE 0x100
-#define DCRN_PCIE1_BASE 0x120
-#define DCRN_PCIE2_BASE 0x140
-#define PCIE0 DCRN_PCIE0_BASE
-#define PCIE1 DCRN_PCIE1_BASE
-#define PCIE2 DCRN_PCIE2_BASE
-
-#define DCRN_PEGPL_CFGBAH(base) (base + 0x00)
-#define DCRN_PEGPL_CFGBAL(base) (base + 0x01)
-#define DCRN_PEGPL_CFGMSK(base) (base + 0x02)
-#define DCRN_PEGPL_MSGBAH(base) (base + 0x03)
-#define DCRN_PEGPL_MSGBAL(base) (base + 0x04)
-#define DCRN_PEGPL_MSGMSK(base) (base + 0x05)
-#define DCRN_PEGPL_OMR1BAH(base) (base + 0x06)
-#define DCRN_PEGPL_OMR1BAL(base) (base + 0x07)
-#define DCRN_PEGPL_OMR1MSKH(base) (base + 0x08)
-#define DCRN_PEGPL_OMR1MSKL(base) (base + 0x09)
-#define DCRN_PEGPL_REGBAH(base) (base + 0x12)
-#define DCRN_PEGPL_REGBAL(base) (base + 0x13)
-#define DCRN_PEGPL_REGMSK(base) (base + 0x14)
-#define DCRN_PEGPL_SPECIAL(base) (base + 0x15)
-#define DCRN_PEGPL_CFG(base) (base + 0x16)
-
-/*
- * System DCRs (SDRs)
- */
-#define PESDR0_PLLLCT1 0x03a0
-#define PESDR0_PLLLCT2 0x03a1
-#define PESDR0_PLLLCT3 0x03a2
-
-#define PESDR0_UTLSET1 0x0300
-#define PESDR0_UTLSET2 0x0301
-#define PESDR0_DLPSET 0x0302
-#define PESDR0_LOOP 0x0303
-#define PESDR0_RCSSET 0x0304
-#define PESDR0_RCSSTS 0x0305
-#define PESDR0_HSSL0SET1 0x0306
-#define PESDR0_HSSL0SET2 0x0307
-#define PESDR0_HSSL0STS 0x0308
-#define PESDR0_HSSL1SET1 0x0309
-#define PESDR0_HSSL1SET2 0x030a
-#define PESDR0_HSSL1STS 0x030b
-#define PESDR0_HSSL2SET1 0x030c
-#define PESDR0_HSSL2SET2 0x030d
-#define PESDR0_HSSL2STS 0x030e
-#define PESDR0_HSSL3SET1 0x030f
-#define PESDR0_HSSL3SET2 0x0310
-#define PESDR0_HSSL3STS 0x0311
-#define PESDR0_HSSL4SET1 0x0312
-#define PESDR0_HSSL4SET2 0x0313
-#define PESDR0_HSSL4STS 0x0314
-#define PESDR0_HSSL5SET1 0x0315
-#define PESDR0_HSSL5SET2 0x0316
-#define PESDR0_HSSL5STS 0x0317
-#define PESDR0_HSSL6SET1 0x0318
-#define PESDR0_HSSL6SET2 0x0319
-#define PESDR0_HSSL6STS 0x031a
-#define PESDR0_HSSL7SET1 0x031b
-#define PESDR0_HSSL7SET2 0x031c
-#define PESDR0_HSSL7STS 0x031d
-#define PESDR0_HSSCTLSET 0x031e
-#define PESDR0_LANE_ABCD 0x031f
-#define PESDR0_LANE_EFGH 0x0320
-
-#define PESDR1_UTLSET1 0x0340
-#define PESDR1_UTLSET2 0x0341
-#define PESDR1_DLPSET 0x0342
-#define PESDR1_LOOP 0x0343
-#define PESDR1_RCSSET 0x0344
-#define PESDR1_RCSSTS 0x0345
-#define PESDR1_HSSL0SET1 0x0346
-#define PESDR1_HSSL0SET2 0x0347
-#define PESDR1_HSSL0STS 0x0348
-#define PESDR1_HSSL1SET1 0x0349
-#define PESDR1_HSSL1SET2 0x034a
-#define PESDR1_HSSL1STS 0x034b
-#define PESDR1_HSSL2SET1 0x034c
-#define PESDR1_HSSL2SET2 0x034d
-#define PESDR1_HSSL2STS 0x034e
-#define PESDR1_HSSL3SET1 0x034f
-#define PESDR1_HSSL3SET2 0x0350
-#define PESDR1_HSSL3STS 0x0351
-#define PESDR1_HSSCTLSET 0x0352
-#define PESDR1_LANE_ABCD 0x0353
-
-#define PESDR2_UTLSET1 0x0370
-#define PESDR2_UTLSET2 0x0371
-#define PESDR2_DLPSET 0x0372
-#define PESDR2_LOOP 0x0373
-#define PESDR2_RCSSET 0x0374
-#define PESDR2_RCSSTS 0x0375
-#define PESDR2_HSSL0SET1 0x0376
-#define PESDR2_HSSL0SET2 0x0377
-#define PESDR2_HSSL0STS 0x0378
-#define PESDR2_HSSL1SET1 0x0379
-#define PESDR2_HSSL1SET2 0x037a
-#define PESDR2_HSSL1STS 0x037b
-#define PESDR2_HSSL2SET1 0x037c
-#define PESDR2_HSSL2SET2 0x037d
-#define PESDR2_HSSL2STS 0x037e
-#define PESDR2_HSSL3SET1 0x037f
-#define PESDR2_HSSL3SET2 0x0380
-#define PESDR2_HSSL3STS 0x0381
-#define PESDR2_HSSCTLSET 0x0382
-#define PESDR2_LANE_ABCD 0x0383
-
-/*
- * UTL register offsets
- */
-#define PEUTL_PBBSZ 0x20
-#define PEUTL_OPDBSZ 0x68
-#define PEUTL_IPHBSZ 0x70
-#define PEUTL_IPDBSZ 0x78
-#define PEUTL_OUTTR 0x90
-#define PEUTL_INTR 0x98
-#define PEUTL_PCTL 0xa0
-#define PEUTL_RCIRQEN 0xb8
-
-/*
- * Config space register offsets
- */
-#define PECFG_BAR0LMPA 0x210
-#define PECFG_BAR0HMPA 0x214
-#define PECFG_BAR1MPA 0x218
-#define PECFG_BAR2MPA 0x220
-
-#define PECFG_PIMEN 0x33c
-#define PECFG_PIM0LAL 0x340
-#define PECFG_PIM0LAH 0x344
-#define PECFG_PIM1LAL 0x348
-#define PECFG_PIM1LAH 0x34c
-#define PECFG_PIM01SAL 0x350
-#define PECFG_PIM01SAH 0x354
-
-#define PECFG_POM0LAL 0x380
-#define PECFG_POM0LAH 0x384
-
-#define SDR_READ(offset) ({\
- mtdcr(DCRN_SDR0_CFGADDR, offset); \
- mfdcr(DCRN_SDR0_CFGDATA);})
-
-#define SDR_WRITE(offset, data) ({\
- mtdcr(DCRN_SDR0_CFGADDR, offset); \
- mtdcr(DCRN_SDR0_CFGDATA,data);})
-
-#define GPL_DMER_MASK_DISA 0x02000000
-
-int ppc440spe_init_pcie(void);
-int ppc440spe_init_pcie_rootport(int port);
-void yucca_setup_pcie_fpga_rootpoint(int port);
-void ppc440spe_setup_pcie_rootpoint(struct pci_controller *hose, int port);
-int ppc440spe_setup_pcie_endpoint(struct pci_controller *hose, int port);
-int yucca_pcie_card_present(int port);
-int pcie_hose_scan(struct pci_controller *hose, int bus);
-#endif /* __440SPE_PCIE_H */
diff --git a/cpu/ppc4xx/44x_spd_ddr.c b/cpu/ppc4xx/44x_spd_ddr.c
index 4a4c6f29ed..b9cf5cbfcc 100644
--- a/cpu/ppc4xx/44x_spd_ddr.c
+++ b/cpu/ppc4xx/44x_spd_ddr.c
@@ -251,10 +251,10 @@ void spd_ddr_init_hang (void) __attribute__((weak, alias("__spd_ddr_init_hang"))
* memory.
*
* If at some time this restriction doesn't apply anymore, just define
- * CFG_ENABLE_SDRAM_CACHE in the board config file and this code should setup
+ * CONFIG_4xx_DCACHE in the board config file and this code should setup
* everything correctly.
*/
-#ifdef CFG_ENABLE_SDRAM_CACHE
+#ifdef CONFIG_4xx_DCACHE
#define MY_TLB_WORD2_I_ENABLE 0 /* enable caching on SDRAM */
#else
#define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE /* disable caching on SDRAM */
@@ -345,7 +345,7 @@ long int spd_sdram(void) {
*/
check_volt_type(dimm_populated, iic0_dimm_addr, num_dimm_banks);
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP)
+#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
/*
* Soft-reset SDRAM controller.
*/
@@ -645,7 +645,7 @@ static void program_rtr(unsigned long *dimm_populated,
unsigned char refresh_rate_type;
unsigned long refresh_interval;
unsigned long sdram_rtr;
- PPC440_SYS_INFO sys_info;
+ PPC4xx_SYS_INFO sys_info;
/*
* get the board info
@@ -721,7 +721,7 @@ static void program_tr0(unsigned long *dimm_populated,
unsigned long tcyc_2_0_ns_x_10;
unsigned long tcyc_reg;
unsigned long bus_period_x_10;
- PPC440_SYS_INFO sys_info;
+ PPC4xx_SYS_INFO sys_info;
unsigned long residue;
/*
@@ -1065,7 +1065,7 @@ static void program_tr1(void)
unsigned char window_found;
unsigned char fail_found;
unsigned char pass_found;
- PPC440_SYS_INFO sys_info;
+ PPC4xx_SYS_INFO sys_info;
/*
* get the board info
@@ -1197,9 +1197,6 @@ static void program_tr1(void)
}
rdclt_average = ((max_start + max_end) >> 1);
- if (rdclt_average >= 0x60)
- while (1)
- ;
if (rdclt_average < 0) {
rdclt_average = 0;
diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c
index 67ba5bdef2..3ac2cdcf7f 100644
--- a/cpu/ppc4xx/44x_spd_ddr2.c
+++ b/cpu/ppc4xx/44x_spd_ddr2.c
@@ -3,7 +3,7 @@
* This SPD SDRAM detection code supports AMCC PPC44x cpu's with a
* DDR2 controller (non Denali Core). Those are 440SP/SPe.
*
- * (C) Copyright 2007
+ * (C) Copyright 2007-2008
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* COPYRIGHT AMCC CORPORATION 2004
@@ -111,8 +111,6 @@
#define NUMMEMWORDS 8
#define NUMLOOPS 64 /* memory test loops */
-#undef CONFIG_ECC_ERROR_RESET /* test-only: see description below, at check_ecc() */
-
/*
* This DDR2 setup code can dynamically setup the TLB entries for the DDR2 memory
* region. Right now the cache should still be disabled in U-Boot because of the
@@ -120,10 +118,10 @@
* memory.
*
* If at some time this restriction doesn't apply anymore, just define
- * CFG_ENABLE_SDRAM_CACHE in the board config file and this code should setup
+ * CONFIG_4xx_DCACHE in the board config file and this code should setup
* everything correctly.
*/
-#ifdef CFG_ENABLE_SDRAM_CACHE
+#ifdef CONFIG_4xx_DCACHE
#define MY_TLB_WORD2_I_ENABLE 0 /* enable caching on SDRAM */
#else
#define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE /* disable caching on SDRAM */
@@ -623,7 +621,7 @@ static void get_spd_info(unsigned long *dimm_populated,
void board_add_ram_info(int use_default)
{
- PPC440_SYS_INFO board_cfg;
+ PPC4xx_SYS_INFO board_cfg;
u32 val;
if (is_ecc_enabled())
@@ -741,7 +739,7 @@ static void check_frequency(unsigned long *dimm_populated,
unsigned long calc_cycle_time;
unsigned long sdram_freq;
unsigned long sdr_ddrpll;
- PPC440_SYS_INFO board_cfg;
+ PPC4xx_SYS_INFO board_cfg;
/*------------------------------------------------------------------
* Get the board configuration info.
@@ -1353,7 +1351,7 @@ static void program_mode(unsigned long *dimm_populated,
unsigned long max_4_0_tcyc_ns_x_100;
unsigned long max_5_0_tcyc_ns_x_100;
unsigned long cycle_time_ns_x_100[3];
- PPC440_SYS_INFO board_cfg;
+ PPC4xx_SYS_INFO board_cfg;
unsigned char cas_2_0_available;
unsigned char cas_2_5_available;
unsigned char cas_3_0_available;
@@ -1640,7 +1638,7 @@ static void program_rtr(unsigned long *dimm_populated,
unsigned char *iic0_dimm_addr,
unsigned long num_dimm_banks)
{
- PPC440_SYS_INFO board_cfg;
+ PPC4xx_SYS_INFO board_cfg;
unsigned long max_refresh_rate;
unsigned long dimm_num;
unsigned long refresh_rate_type;
@@ -1737,7 +1735,7 @@ static void program_tr(unsigned long *dimm_populated,
unsigned long sdram_freq;
unsigned long sdr_ddrpll;
- PPC440_SYS_INFO board_cfg;
+ PPC4xx_SYS_INFO board_cfg;
/*------------------------------------------------------------------
* Get the board configuration info.
@@ -2048,14 +2046,10 @@ static void program_bxcf(unsigned long *dimm_populated,
/*------------------------------------------------------------------
* Set the BxCF regs. First, wipe out the bank config registers.
*-----------------------------------------------------------------*/
- mtdcr(SDRAMC_CFGADDR, SDRAM_MB0CF);
- mtdcr(SDRAMC_CFGDATA, 0x00000000);
- mtdcr(SDRAMC_CFGADDR, SDRAM_MB1CF);
- mtdcr(SDRAMC_CFGDATA, 0x00000000);
- mtdcr(SDRAMC_CFGADDR, SDRAM_MB2CF);
- mtdcr(SDRAMC_CFGDATA, 0x00000000);
- mtdcr(SDRAMC_CFGADDR, SDRAM_MB3CF);
- mtdcr(SDRAMC_CFGDATA, 0x00000000);
+ mtsdram(SDRAM_MB0CF, 0x00000000);
+ mtsdram(SDRAM_MB1CF, 0x00000000);
+ mtsdram(SDRAM_MB2CF, 0x00000000);
+ mtsdram(SDRAM_MB3CF, 0x00000000);
mode = SDRAM_BXCF_M_BE_ENABLE;
@@ -2107,8 +2101,9 @@ static void program_bxcf(unsigned long *dimm_populated,
bank_0_populated = 1;
for (ind_rank = 0; ind_rank < num_ranks; ind_rank++) {
- mtdcr(SDRAMC_CFGADDR, SDRAM_MB0CF + ((dimm_num + bank_0_populated + ind_rank) << 2));
- mtdcr(SDRAMC_CFGDATA, mode);
+ mtsdram(SDRAM_MB0CF +
+ ((dimm_num + bank_0_populated + ind_rank) << 2),
+ mode);
}
}
}
@@ -2271,39 +2266,6 @@ static void program_ecc(unsigned long *dimm_populated,
return;
}
-#ifdef CONFIG_ECC_ERROR_RESET
-/*
- * Check for ECC errors and reset board upon any error here
- *
- * On the Katmai 440SPe eval board, from time to time, the first
- * lword write access after DDR2 initializazion with ECC checking
- * enabled, leads to an ECC error. I couldn't find a configuration
- * without this happening. On my board with the current setup it
- * happens about 1 from 10 times.
- *
- * The ECC modules used for testing are:
- * - Kingston ValueRAM KVR667D2E5/512 (tested with 1 and 2 DIMM's)
- *
- * This has to get fixed for the Katmai and tested for the other
- * board (440SP/440SPe) that will eventually use this code in the
- * future.
- *
- * 2007-03-01, sr
- */
-static void check_ecc(void)
-{
- u32 val;
-
- mfsdram(SDRAM_ECCCR, val);
- if (val != 0) {
- printf("\nECC error: MCIF0_ECCES=%08lx MQ0_ESL=%08lx address=%08lx\n",
- val, mfdcr(0x4c), mfdcr(0x4e));
- printf("ECC error occured, resetting board...\n");
- do_reset(NULL, 0, 0, NULL);
- }
-}
-#endif
-
static void wait_ddr_idle(void)
{
u32 val;
@@ -2378,15 +2340,6 @@ static void program_ecc_addr(unsigned long start_address,
sync();
eieio();
wait_ddr_idle();
-
-#ifdef CONFIG_ECC_ERROR_RESET
- /*
- * One write to 0 is enough to trigger this ECC error
- * (see description above)
- */
- out_be32(0, 0x12345678);
- check_ecc();
-#endif
}
}
#endif
@@ -2412,17 +2365,10 @@ static void program_DQS_calibration(unsigned long *dimm_populated,
* Read sample cycle auto-update enable
*-----------------------------------------------------------------*/
- /*
- * Modified for the Katmai platform: with some DIMMs, the DDR2
- * controller automatically selects the T2 read cycle, but this
- * proves unreliable. Go ahead and force the DDR2 controller
- * to use the T4 sample and disable the automatic update of the
- * RDSS field.
- */
mfsdram(SDRAM_RDCC, val);
mtsdram(SDRAM_RDCC,
(val & ~(SDRAM_RDCC_RDSS_MASK | SDRAM_RDCC_RSAE_MASK))
- | (SDRAM_RDCC_RDSS_T4 | SDRAM_RDCC_RSAE_DISABLE));
+ | SDRAM_RDCC_RSAE_ENABLE);
/*------------------------------------------------------------------
* Program RQDC register
@@ -2515,10 +2461,7 @@ static void DQS_calibration_process(void)
{
unsigned long rfdc_reg;
unsigned long rffd;
- unsigned long rqdc_reg;
- unsigned long rqfd;
unsigned long val;
- long rqfd_average;
long rffd_average;
long max_start;
long min_end;
@@ -2536,10 +2479,14 @@ static void DQS_calibration_process(void)
long max_end;
unsigned char fail_found;
unsigned char pass_found;
+#if !defined(CONFIG_DDR_RQDC_FIXED)
+ u32 rqdc_reg;
+ u32 rqfd;
u32 rqfd_start;
+ u32 rqfd_average;
+ int loopi = 0;
char str[] = "Auto calibration -";
char slash[] = "\\|/-\\|/-";
- int loopi = 0;
/*------------------------------------------------------------------
* Test to determine the best read clock delay tuning bits.
@@ -2574,6 +2521,16 @@ calibration_loop:
mfsdram(SDRAM_RQDC, rqdc_reg);
mtsdram(SDRAM_RQDC, (rqdc_reg & ~SDRAM_RQDC_RQFD_MASK) |
SDRAM_RQDC_RQFD_ENCODE(rqfd_start));
+#else /* CONFIG_DDR_RQDC_FIXED */
+ /*
+ * On Katmai the complete auto-calibration somehow doesn't seem to
+ * produce the best results, meaning optimal values for RQFD/RFFD.
+ * This was discovered by GDA using a high bandwidth scope,
+ * analyzing the DDR2 signals. GDA provided a fixed value for RQFD,
+ * so now on Katmai "only" RFFD is auto-calibrated.
+ */
+ mtsdram(SDRAM_RQDC, CONFIG_DDR_RQDC_FIXED);
+#endif /* CONFIG_DDR_RQDC_FIXED */
max_start = 0;
min_end = 0;
@@ -2658,6 +2615,7 @@ calibration_loop:
/* now fix RFDC[RFFD] found and find RQDC[RQFD] */
mtsdram(SDRAM_RFDC, rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(rffd_average));
+#if !defined(CONFIG_DDR_RQDC_FIXED)
max_pass_length = 0;
max_start = 0;
max_end = 0;
@@ -2730,8 +2688,6 @@ calibration_loop:
spd_ddr_init_hang ();
}
- blank_string(strlen(str));
-
if (rqfd_average < 0)
rqfd_average = 0;
@@ -2742,12 +2698,31 @@ calibration_loop:
(rqdc_reg & ~SDRAM_RQDC_RQFD_MASK) |
SDRAM_RQDC_RQFD_ENCODE(rqfd_average));
+ blank_string(strlen(str));
+#endif /* CONFIG_DDR_RQDC_FIXED */
+
+ /*
+ * Now complete RDSS configuration as mentioned on page 7 of the AMCC
+ * PowerPC440SP/SPe DDR2 application note:
+ * "DDR1/DDR2 Initialization Sequence and Dynamic Tuning"
+ */
+ mfsdram(SDRAM_RTSR, val);
+ if ((val & SDRAM_RTSR_TRK1SM_MASK) == SDRAM_RTSR_TRK1SM_ATPLS1) {
+ mfsdram(SDRAM_RDCC, val);
+ if ((val & SDRAM_RDCC_RDSS_MASK) != SDRAM_RDCC_RDSS_T4) {
+ val += 0x40000000;
+ mtsdram(SDRAM_RDCC, val);
+ }
+ }
+
mfsdram(SDRAM_DLCR, val);
debug("%s[%d] DLCR: 0x%08X\n", __FUNCTION__, __LINE__, val);
mfsdram(SDRAM_RQDC, val);
debug("%s[%d] RQDC: 0x%08X\n", __FUNCTION__, __LINE__, val);
mfsdram(SDRAM_RFDC, val);
debug("%s[%d] RFDC: 0x%08X\n", __FUNCTION__, __LINE__, val);
+ mfsdram(SDRAM_RDCC, val);
+ debug("%s[%d] RDCC: 0x%08X\n", __FUNCTION__, __LINE__, val);
}
#else /* calibration test with hardvalues */
/*-----------------------------------------------------------------------------+
diff --git a/cpu/ppc4xx/4xx_enet.c b/cpu/ppc4xx/4xx_enet.c
index 71a9e372da..44659ffcd9 100644
--- a/cpu/ppc4xx/4xx_enet.c
+++ b/cpu/ppc4xx/4xx_enet.c
@@ -81,13 +81,16 @@
#include <common.h>
#include <net.h>
#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/cache.h>
+#include <asm/mmu.h>
#include <commproc.h>
#include <ppc4xx.h>
#include <ppc4xx_enet.h>
#include <405_mal.h>
#include <miiphy.h>
#include <malloc.h>
-#include "vecnum.h"
+#include <asm/ppc4xx-intvec.h>
/*
* Only compile for platform with AMCC EMAC ethernet controller and
@@ -105,7 +108,7 @@
#endif
#define EMAC_RESET_TIMEOUT 1000 /* 1000 ms reset timeout */
-#define PHY_AUTONEGOTIATE_TIMEOUT 4000 /* 4000 ms autonegotiate timeout */
+#define PHY_AUTONEGOTIATE_TIMEOUT 5000 /* 5000 ms autonegotiate timeout */
/* Ethernet Transmit and Receive Buffers */
/* AS.HARNOIS
@@ -133,13 +136,15 @@
#define BI_PHYMODE_GMII 3
#define BI_PHYMODE_RTBI 4
#define BI_PHYMODE_TBI 5
-#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_405EX)
#define BI_PHYMODE_SMII 6
#define BI_PHYMODE_MII 7
#endif
-#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || \
- defined(CONFIG_440GRX) || defined(CONFIG_440SP)
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_405EX)
#define SDR0_MFR_ETH_CLK_SEL_V(n) ((0x01<<27) / (n+1))
#endif
@@ -156,7 +161,14 @@ struct eth_device *emac0_dev = NULL;
/*
* Get count of EMAC devices (doesn't have to be the max. possible number
* supported by the cpu)
+ *
+ * CONFIG_BOARD_EMAC_COUNT added so now a "dynamic" way to configure the
+ * EMAC count is possible. As it is needed for the Kilauea/Haleakala
+ * 405EX/405EXr eval board, using the same binary.
*/
+#if defined(CONFIG_BOARD_EMAC_COUNT)
+#define LAST_EMAC_NUM board_emac_count()
+#else /* CONFIG_BOARD_EMAC_COUNT */
#if defined(CONFIG_HAS_ETH3)
#define LAST_EMAC_NUM 4
#elif defined(CONFIG_HAS_ETH2)
@@ -166,12 +178,23 @@ struct eth_device *emac0_dev = NULL;
#else
#define LAST_EMAC_NUM 1
#endif
+#endif /* CONFIG_BOARD_EMAC_COUNT */
/* normal boards start with EMAC0 */
#if !defined(CONFIG_EMAC_NR_START)
#define CONFIG_EMAC_NR_START 0
#endif
+#if defined(CONFIG_405EX) || defined(CONFIG_440EPX)
+#define ETH_IRQ_NUM(dev) (VECNUM_ETH0 + ((dev)))
+#else
+#define ETH_IRQ_NUM(dev) (VECNUM_ETH0 + ((dev) * 2))
+#endif
+
+#define MAL_RX_DESC_SIZE 2048
+#define MAL_TX_DESC_SIZE 2048
+#define MAL_ALLOC_SIZE (MAL_TX_DESC_SIZE + MAL_RX_DESC_SIZE)
+
/*-----------------------------------------------------------------------------+
* Prototypes and externals.
*-----------------------------------------------------------------------------*/
@@ -189,6 +212,8 @@ extern int emac4xx_miiphy_read (char *devname, unsigned char addr,
extern int emac4xx_miiphy_write (char *devname, unsigned char addr,
unsigned char reg, unsigned short value);
+int board_emac_count(void);
+
/*-----------------------------------------------------------------------------+
| ppc_4xx_eth_halt
| Disable MAL channel, and EMACn
@@ -197,11 +222,13 @@ static void ppc_4xx_eth_halt (struct eth_device *dev)
{
EMAC_4XX_HW_PST hw_p = dev->priv;
uint32_t failsafe = 10000;
-#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#if defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_405EX)
unsigned long mfr;
#endif
- out32 (EMAC_IER + hw_p->hw_addr, 0x00000000); /* disable emac interrupts */
+ out_be32((void *)EMAC_IER + hw_p->hw_addr, 0x00000000); /* disable emac interrupts */
/* 1st reset MAL channel */
/* Note: writing a 0 to a channel has no effect */
@@ -221,16 +248,20 @@ static void ppc_4xx_eth_halt (struct eth_device *dev)
}
/* EMAC RESET */
-#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#if defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_405EX)
/* provide clocks for EMAC internal loopback */
mfsdr (sdr_mfr, mfr);
mfr |= SDR0_MFR_ETH_CLK_SEL_V(hw_p->devnum);
mtsdr(sdr_mfr, mfr);
#endif
- out32 (EMAC_M0 + hw_p->hw_addr, EMAC_M0_SRST);
+ out_be32((void *)EMAC_M0 + hw_p->hw_addr, EMAC_M0_SRST);
-#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#if defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_405EX)
/* remove clocks for EMAC internal loopback */
mfsdr (sdr_mfr, mfr);
mfr &= ~SDR0_MFR_ETH_CLK_SEL_V(hw_p->devnum);
@@ -329,8 +360,8 @@ int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
/* Ensure we setup mdio for this devnum and ONLY this devnum */
zmiifer |= (ZMII_FER_MDI) << ZMII_FER_V(devnum);
- out32 (ZMII_FER, zmiifer);
- out32 (RGMII_FER, rmiifer);
+ out_be32((void *)ZMII_FER, zmiifer);
+ out_be32((void *)RGMII_FER, rmiifer);
return ((int)pfc1);
}
@@ -348,31 +379,31 @@ int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
switch (pfc1) {
case SDR0_PFC1_SELECT_CONFIG_2:
/* 1 x GMII port */
- out32 (ZMII_FER, 0x00);
- out32 (RGMII_FER, 0x00000037);
+ out_be32((void *)ZMII_FER, 0x00);
+ out_be32((void *)RGMII_FER, 0x00000037);
bis->bi_phymode[0] = BI_PHYMODE_GMII;
bis->bi_phymode[1] = BI_PHYMODE_NONE;
break;
case SDR0_PFC1_SELECT_CONFIG_4:
/* 2 x RGMII ports */
- out32 (ZMII_FER, 0x00);
- out32 (RGMII_FER, 0x00000055);
+ out_be32((void *)ZMII_FER, 0x00);
+ out_be32((void *)RGMII_FER, 0x00000055);
bis->bi_phymode[0] = BI_PHYMODE_RGMII;
bis->bi_phymode[1] = BI_PHYMODE_RGMII;
break;
case SDR0_PFC1_SELECT_CONFIG_6:
/* 2 x SMII ports */
- out32 (ZMII_FER,
- ((ZMII_FER_SMII) << ZMII_FER_V(0)) |
- ((ZMII_FER_SMII) << ZMII_FER_V(1)));
- out32 (RGMII_FER, 0x00000000);
+ out_be32((void *)ZMII_FER,
+ ((ZMII_FER_SMII) << ZMII_FER_V(0)) |
+ ((ZMII_FER_SMII) << ZMII_FER_V(1)));
+ out_be32((void *)RGMII_FER, 0x00000000);
bis->bi_phymode[0] = BI_PHYMODE_SMII;
bis->bi_phymode[1] = BI_PHYMODE_SMII;
break;
case SDR0_PFC1_SELECT_CONFIG_1_2:
/* only 1 x MII supported */
- out32 (ZMII_FER, (ZMII_FER_MII) << ZMII_FER_V(0));
- out32 (RGMII_FER, 0x00000000);
+ out_be32((void *)ZMII_FER, (ZMII_FER_MII) << ZMII_FER_V(0));
+ out_be32((void *)RGMII_FER, 0x00000000);
bis->bi_phymode[0] = BI_PHYMODE_MII;
bis->bi_phymode[1] = BI_PHYMODE_NONE;
break;
@@ -381,17 +412,55 @@ int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
}
/* Ensure we setup mdio for this devnum and ONLY this devnum */
- zmiifer = in32 (ZMII_FER);
+ zmiifer = in_be32((void *)ZMII_FER);
zmiifer |= (ZMII_FER_MDI) << ZMII_FER_V(devnum);
- out32 (ZMII_FER, zmiifer);
+ out_be32((void *)ZMII_FER, zmiifer);
return ((int)0x0);
}
#endif /* CONFIG_440EPX */
+#if defined(CONFIG_405EX)
+int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
+{
+ u32 gmiifer = 0;
+
+ /*
+ * Right now only 2*RGMII is supported. Please extend when needed.
+ * sr - 2007-09-19
+ */
+ switch (1) {
+ case 1:
+ /* 2 x RGMII ports */
+ out_be32((void *)RGMII_FER, 0x00000055);
+ bis->bi_phymode[0] = BI_PHYMODE_RGMII;
+ bis->bi_phymode[1] = BI_PHYMODE_RGMII;
+ break;
+ case 2:
+ /* 2 x SMII ports */
+ break;
+ default:
+ break;
+ }
+
+ /* Ensure we setup mdio for this devnum and ONLY this devnum */
+ gmiifer = in_be32((void *)RGMII_FER);
+ gmiifer |= (1 << (19-devnum));
+ out_be32((void *)RGMII_FER, gmiifer);
+
+ return ((int)0x0);
+}
+#endif /* CONFIG_405EX */
+
+static inline void *malloc_aligned(u32 size, u32 align)
+{
+ return (void *)(((u32)malloc(size + align) + align - 1) &
+ ~(align - 1));
+}
+
static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
{
- int i, j;
+ int i;
unsigned long reg = 0;
unsigned long msr;
unsigned long speed;
@@ -402,18 +471,22 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
unsigned short reg_short;
#if defined(CONFIG_440GX) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
- defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_405EX)
sys_info_t sysinfo;
#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
- defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_405EX)
int ethgroup = -1;
#endif
#endif
#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
- defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_405EX)
unsigned long mfr;
#endif
-
+ u32 bd_cached;
+ u32 bd_uncached = 0;
EMAC_4XX_HW_PST hw_p = dev->priv;
@@ -426,7 +499,8 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
#if defined(CONFIG_440GX) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
- defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_405EX)
/* Need to get the OPB frequency so we can access the PHY */
get_sys_info (&sysinfo);
#endif
@@ -476,53 +550,57 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
/* NOTE: Therefore, disable all other EMACS, since we handle */
/* NOTE: only one emac at a time */
reg = 0;
- out32 (ZMII_FER, 0);
+ out_be32((void *)ZMII_FER, 0);
udelay (100);
#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
- out32 (ZMII_FER, (ZMII_FER_RMII | ZMII_FER_MDI) << ZMII_FER_V (devnum));
+ out_be32((void *)ZMII_FER, (ZMII_FER_RMII | ZMII_FER_MDI) << ZMII_FER_V (devnum));
#elif defined(CONFIG_440GX) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
ethgroup = ppc_4xx_eth_setup_bridge(devnum, bis);
#elif defined(CONFIG_440GP)
/* set RMII mode */
- out32 (ZMII_FER, ZMII_RMII | ZMII_MDI0);
+ out_be32((void *)ZMII_FER, ZMII_RMII | ZMII_MDI0);
#else
if ((devnum == 0) || (devnum == 1)) {
- out32 (ZMII_FER, (ZMII_FER_SMII | ZMII_FER_MDI) << ZMII_FER_V (devnum));
+ out_be32((void *)ZMII_FER, (ZMII_FER_SMII | ZMII_FER_MDI) << ZMII_FER_V (devnum));
} else { /* ((devnum == 2) || (devnum == 3)) */
- out32 (ZMII_FER, ZMII_FER_MDI << ZMII_FER_V (devnum));
- out32 (RGMII_FER, ((RGMII_FER_RGMII << RGMII_FER_V (2)) |
- (RGMII_FER_RGMII << RGMII_FER_V (3))));
+ out_be32((void *)ZMII_FER, ZMII_FER_MDI << ZMII_FER_V (devnum));
+ out_be32((void *)RGMII_FER, ((RGMII_FER_RGMII << RGMII_FER_V (2)) |
+ (RGMII_FER_RGMII << RGMII_FER_V (3))));
}
#endif
- out32 (ZMII_SSR, ZMII_SSR_SP << ZMII_SSR_V(devnum));
+ out_be32((void *)ZMII_SSR, ZMII_SSR_SP << ZMII_SSR_V(devnum));
#endif /* defined(CONFIG_440) && !defined(CONFIG_440SP) */
+#if defined(CONFIG_405EX)
+ ethgroup = ppc_4xx_eth_setup_bridge(devnum, bis);
+#endif
__asm__ volatile ("eieio");
/* reset emac so we have access to the phy */
-#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
- defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_405EX)
/* provide clocks for EMAC internal loopback */
mfsdr (sdr_mfr, mfr);
mfr |= SDR0_MFR_ETH_CLK_SEL_V(devnum);
mtsdr(sdr_mfr, mfr);
#endif
- out32 (EMAC_M0 + hw_p->hw_addr, EMAC_M0_SRST);
- __asm__ volatile ("eieio");
+ out_be32((void *)EMAC_M0 + hw_p->hw_addr, EMAC_M0_SRST);
failsafe = 1000;
- while ((in32 (EMAC_M0 + hw_p->hw_addr) & (EMAC_M0_SRST)) && failsafe) {
+ while ((in_be32((void *)EMAC_M0 + hw_p->hw_addr) & (EMAC_M0_SRST)) && failsafe) {
udelay (1000);
failsafe--;
}
if (failsafe <= 0)
printf("\nProblem resetting EMAC!\n");
-#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
- defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_405EX)
/* remove clocks for EMAC internal loopback */
mfsdr (sdr_mfr, mfr);
mfr &= ~SDR0_MFR_ETH_CLK_SEL_V(devnum);
@@ -531,7 +609,8 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
#if defined(CONFIG_440GX) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
- defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_405EX)
/* Whack the M1 register */
mode_reg = 0x0;
mode_reg &= ~0x00000038;
@@ -545,7 +624,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
else
mode_reg |= EMAC_M1_OBCI_GT100;
- out32 (EMAC_M1 + hw_p->hw_addr, mode_reg);
+ out_be32((void *)EMAC_M1 + hw_p->hw_addr, mode_reg);
#endif /* defined(CONFIG_440GX) || defined(CONFIG_440SP) */
/* wait for PHY to complete auto negotiation */
@@ -591,7 +670,8 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
#if defined(CONFIG_440GX) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
- defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_405EX)
#if defined(CONFIG_CIS8201_PHY)
/*
@@ -702,11 +782,11 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
#endif
/* Set ZMII/RGMII speed according to the phy link speed */
- reg = in32 (ZMII_SSR);
+ reg = in_be32((void *)ZMII_SSR);
if ( (speed == 100) || (speed == 1000) )
- out32 (ZMII_SSR, reg | (ZMII_SSR_SP << ZMII_SSR_V (devnum)));
+ out_be32((void *)ZMII_SSR, reg | (ZMII_SSR_SP << ZMII_SSR_V (devnum)));
else
- out32 (ZMII_SSR, reg & (~(ZMII_SSR_SP << ZMII_SSR_V (devnum))));
+ out_be32((void *)ZMII_SSR, reg & (~(ZMII_SSR_SP << ZMII_SSR_V (devnum))));
if ((devnum == 2) || (devnum == 3)) {
if (speed == 1000)
@@ -719,11 +799,12 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
printf("Error in RGMII Speed\n");
return -1;
}
- out32 (RGMII_SSR, reg);
+ out_be32((void *)RGMII_SSR, reg);
}
#endif /* defined(CONFIG_440) && !defined(CONFIG_440SP) */
-#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_405EX)
if (speed == 1000)
reg = (RGMII_SSR_SP_1000MBPS << RGMII_SSR_V (devnum));
else if (speed == 100)
@@ -734,13 +815,14 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
printf("Error in RGMII Speed\n");
return -1;
}
- out32 (RGMII_SSR, reg);
+ out_be32((void *)RGMII_SSR, reg);
#endif
/* set the Mal configuration reg */
#if defined(CONFIG_440GX) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
- defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_405EX)
mtdcr (malmcr, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA |
MAL_CR_PLBLT_DEFAULT | MAL_CR_EOPIE | 0x00330000);
#else
@@ -751,91 +833,58 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
}
#endif
- /* Free "old" buffers */
- if (hw_p->alloc_tx_buf)
- free (hw_p->alloc_tx_buf);
- if (hw_p->alloc_rx_buf)
- free (hw_p->alloc_rx_buf);
-
/*
* Malloc MAL buffer desciptors, make sure they are
* aligned on cache line boundary size
* (401/403/IOP480 = 16, 405 = 32)
* and doesn't cross cache block boundaries.
*/
- hw_p->alloc_tx_buf =
- (mal_desc_t *) malloc ((sizeof (mal_desc_t) * NUM_TX_BUFF) +
- ((2 * CFG_CACHELINE_SIZE) - 2));
- if (NULL == hw_p->alloc_tx_buf)
- return -1;
- if (((int) hw_p->alloc_tx_buf & CACHELINE_MASK) != 0) {
- hw_p->tx =
- (mal_desc_t *) ((int) hw_p->alloc_tx_buf +
- CFG_CACHELINE_SIZE -
- ((int) hw_p->
- alloc_tx_buf & CACHELINE_MASK));
- } else {
- hw_p->tx = hw_p->alloc_tx_buf;
- }
+ if (hw_p->first_init == 0) {
+ debug("*** Allocating descriptor memory ***\n");
- hw_p->alloc_rx_buf =
- (mal_desc_t *) malloc ((sizeof (mal_desc_t) * NUM_RX_BUFF) +
- ((2 * CFG_CACHELINE_SIZE) - 2));
- if (NULL == hw_p->alloc_rx_buf) {
- free(hw_p->alloc_tx_buf);
- hw_p->alloc_tx_buf = NULL;
- return -1;
- }
+ bd_cached = (u32)malloc_aligned(MAL_ALLOC_SIZE, 4096);
+ if (!bd_cached) {
+ printf("%s: Error allocating MAL descriptor buffers!\n");
+ return -1;
+ }
- if (((int) hw_p->alloc_rx_buf & CACHELINE_MASK) != 0) {
- hw_p->rx =
- (mal_desc_t *) ((int) hw_p->alloc_rx_buf +
- CFG_CACHELINE_SIZE -
- ((int) hw_p->
- alloc_rx_buf & CACHELINE_MASK));
- } else {
- hw_p->rx = hw_p->alloc_rx_buf;
+#ifdef CONFIG_4xx_DCACHE
+ flush_dcache_range(bd_cached, bd_cached + MAL_ALLOC_SIZE);
+ bd_uncached = bis->bi_memsize;
+ program_tlb(bd_cached, bd_uncached, MAL_ALLOC_SIZE,
+ TLB_WORD2_I_ENABLE);
+#else
+ bd_uncached = bd_cached;
+#endif
+ hw_p->tx_phys = bd_cached;
+ hw_p->rx_phys = bd_cached + MAL_TX_DESC_SIZE;
+ hw_p->tx = (mal_desc_t *)(bd_uncached);
+ hw_p->rx = (mal_desc_t *)(bd_uncached + MAL_TX_DESC_SIZE);
+ debug("hw_p->tx=%08x, hw_p->rx=%08x\n", hw_p->tx, hw_p->rx);
}
for (i = 0; i < NUM_TX_BUFF; i++) {
hw_p->tx[i].ctrl = 0;
hw_p->tx[i].data_len = 0;
- if (hw_p->first_init == 0) {
- hw_p->txbuf_ptr =
- (char *) malloc (ENET_MAX_MTU_ALIGNED);
- if (NULL == hw_p->txbuf_ptr) {
- free(hw_p->alloc_rx_buf);
- free(hw_p->alloc_tx_buf);
- hw_p->alloc_rx_buf = NULL;
- hw_p->alloc_tx_buf = NULL;
- for(j = 0; j < i; j++) {
- free(hw_p->tx[i].data_ptr);
- hw_p->tx[i].data_ptr = NULL;
- }
- }
- }
+ if (hw_p->first_init == 0)
+ hw_p->txbuf_ptr = malloc_aligned(MAL_ALLOC_SIZE,
+ L1_CACHE_BYTES);
hw_p->tx[i].data_ptr = hw_p->txbuf_ptr;
if ((NUM_TX_BUFF - 1) == i)
hw_p->tx[i].ctrl |= MAL_TX_CTRL_WRAP;
hw_p->tx_run[i] = -1;
-#if 0
- printf ("TX_BUFF %d @ 0x%08lx\n", i,
- (ulong) hw_p->tx[i].data_ptr);
-#endif
+ debug("TX_BUFF %d @ 0x%08lx\n", i, (u32)hw_p->tx[i].data_ptr);
}
for (i = 0; i < NUM_RX_BUFF; i++) {
hw_p->rx[i].ctrl = 0;
hw_p->rx[i].data_len = 0;
- /* rx[i].data_ptr = (char *) &rx_buff[i]; */
- hw_p->rx[i].data_ptr = (char *) NetRxPackets[i];
+ hw_p->rx[i].data_ptr = (char *)NetRxPackets[i];
if ((NUM_RX_BUFF - 1) == i)
hw_p->rx[i].ctrl |= MAL_RX_CTRL_WRAP;
hw_p->rx[i].ctrl |= MAL_RX_CTRL_EMPTY | MAL_RX_CTRL_INTR;
hw_p->rx_ready[i] = -1;
-#if 0
- printf ("RX_BUFF %d @ 0x%08lx\n", i, (ulong) hw_p->rx[i].data_ptr);
-#endif
+ debug("RX_BUFF %d @ 0x%08lx\n", i, (u32)hw_p->rx[i].data_ptr);
}
reg = 0x00000000;
@@ -844,7 +893,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
reg = reg << 8;
reg |= dev->enetaddr[1];
- out32 (EMAC_IAH + hw_p->hw_addr, reg);
+ out_be32((void *)EMAC_IAH + hw_p->hw_addr, reg);
reg = 0x00000000;
reg |= dev->enetaddr[2]; /* set low address */
@@ -855,21 +904,21 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
reg = reg << 8;
reg |= dev->enetaddr[5];
- out32 (EMAC_IAL + hw_p->hw_addr, reg);
+ out_be32((void *)EMAC_IAL + hw_p->hw_addr, reg);
switch (devnum) {
case 1:
/* setup MAL tx & rx channel pointers */
#if defined (CONFIG_405EP) || defined (CONFIG_440EP) || defined (CONFIG_440GR)
- mtdcr (maltxctp2r, hw_p->tx);
+ mtdcr (maltxctp2r, hw_p->tx_phys);
#else
- mtdcr (maltxctp1r, hw_p->tx);
+ mtdcr (maltxctp1r, hw_p->tx_phys);
#endif
#if defined(CONFIG_440)
mtdcr (maltxbattr, 0x0);
mtdcr (malrxbattr, 0x0);
#endif
- mtdcr (malrxctp1r, hw_p->rx);
+ mtdcr (malrxctp1r, hw_p->rx_phys);
/* set RX buffer size */
mtdcr (malrcbs1, ENET_MAX_MTU_ALIGNED / 16);
break;
@@ -878,17 +927,17 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
/* setup MAL tx & rx channel pointers */
mtdcr (maltxbattr, 0x0);
mtdcr (malrxbattr, 0x0);
- mtdcr (maltxctp2r, hw_p->tx);
- mtdcr (malrxctp2r, hw_p->rx);
+ mtdcr (maltxctp2r, hw_p->tx_phys);
+ mtdcr (malrxctp2r, hw_p->rx_phys);
/* set RX buffer size */
mtdcr (malrcbs2, ENET_MAX_MTU_ALIGNED / 16);
break;
case 3:
/* setup MAL tx & rx channel pointers */
mtdcr (maltxbattr, 0x0);
- mtdcr (maltxctp3r, hw_p->tx);
+ mtdcr (maltxctp3r, hw_p->tx_phys);
mtdcr (malrxbattr, 0x0);
- mtdcr (malrxctp3r, hw_p->rx);
+ mtdcr (malrxctp3r, hw_p->rx_phys);
/* set RX buffer size */
mtdcr (malrcbs3, ENET_MAX_MTU_ALIGNED / 16);
break;
@@ -900,8 +949,8 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
mtdcr (maltxbattr, 0x0);
mtdcr (malrxbattr, 0x0);
#endif
- mtdcr (maltxctp0r, hw_p->tx);
- mtdcr (malrxctp0r, hw_p->rx);
+ mtdcr (maltxctp0r, hw_p->tx_phys);
+ mtdcr (malrxctp0r, hw_p->rx_phys);
/* set RX buffer size */
mtdcr (malrcbs0, ENET_MAX_MTU_ALIGNED / 16);
break;
@@ -916,10 +965,10 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
mtdcr (malrxcasr, (MAL_TXRX_CASR >> hw_p->devnum));
/* set transmit enable & receive enable */
- out32 (EMAC_M0 + hw_p->hw_addr, EMAC_M0_TXE | EMAC_M0_RXE);
+ out_be32((void *)EMAC_M0 + hw_p->hw_addr, EMAC_M0_TXE | EMAC_M0_RXE);
/* set receive fifo to 4k and tx fifo to 2k */
- mode_reg = in32 (EMAC_M1 + hw_p->hw_addr);
+ mode_reg = in_be32((void *)EMAC_M1 + hw_p->hw_addr);
mode_reg |= EMAC_M1_RFS_4K | EMAC_M1_TX_FIFO_2K;
/* set speed */
@@ -940,46 +989,46 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
if (duplex == FULL)
mode_reg = mode_reg | 0x80000000 | EMAC_M1_IST;
- out32 (EMAC_M1 + hw_p->hw_addr, mode_reg);
+ out_be32((void *)EMAC_M1 + hw_p->hw_addr, mode_reg);
/* Enable broadcast and indvidual address */
/* TBS: enabling runts as some misbehaved nics will send runts */
- out32 (EMAC_RXM + hw_p->hw_addr, EMAC_RMR_BAE | EMAC_RMR_IAE);
+ out_be32((void *)EMAC_RXM + hw_p->hw_addr, EMAC_RMR_BAE | EMAC_RMR_IAE);
/* we probably need to set the tx mode1 reg? maybe at tx time */
/* set transmit request threshold register */
- out32 (EMAC_TRTR + hw_p->hw_addr, 0x18000000); /* 256 byte threshold */
+ out_be32((void *)EMAC_TRTR + hw_p->hw_addr, 0x18000000); /* 256 byte threshold */
/* set receive low/high water mark register */
#if defined(CONFIG_440)
/* 440s has a 64 byte burst length */
- out32 (EMAC_RX_HI_LO_WMARK + hw_p->hw_addr, 0x80009000);
+ out_be32((void *)EMAC_RX_HI_LO_WMARK + hw_p->hw_addr, 0x80009000);
#else
/* 405s have a 16 byte burst length */
- out32 (EMAC_RX_HI_LO_WMARK + hw_p->hw_addr, 0x0f002000);
+ out_be32((void *)EMAC_RX_HI_LO_WMARK + hw_p->hw_addr, 0x0f002000);
#endif /* defined(CONFIG_440) */
- out32 (EMAC_TXM1 + hw_p->hw_addr, 0xf8640000);
+ out_be32((void *)EMAC_TXM1 + hw_p->hw_addr, 0xf8640000);
/* Set fifo limit entry in tx mode 0 */
- out32 (EMAC_TXM0 + hw_p->hw_addr, 0x00000003);
+ out_be32((void *)EMAC_TXM0 + hw_p->hw_addr, 0x00000003);
/* Frame gap set */
- out32 (EMAC_I_FRAME_GAP_REG + hw_p->hw_addr, 0x00000008);
+ out_be32((void *)EMAC_I_FRAME_GAP_REG + hw_p->hw_addr, 0x00000008);
/* Set EMAC IER */
hw_p->emac_ier = EMAC_ISR_PTLE | EMAC_ISR_BFCS | EMAC_ISR_ORE | EMAC_ISR_IRE;
if (speed == _100BASET)
hw_p->emac_ier = hw_p->emac_ier | EMAC_ISR_SYE;
- out32 (EMAC_ISR + hw_p->hw_addr, 0xffffffff); /* clear pending interrupts */
- out32 (EMAC_IER + hw_p->hw_addr, hw_p->emac_ier);
+ out_be32((void *)EMAC_ISR + hw_p->hw_addr, 0xffffffff); /* clear pending interrupts */
+ out_be32((void *)EMAC_IER + hw_p->hw_addr, hw_p->emac_ier);
if (hw_p->first_init == 0) {
/*
* Connect interrupt service routines
*/
- irq_install_handler (VECNUM_ETH0 + (hw_p->devnum * 2),
- (interrupt_handler_t *) enetInt, dev);
+ irq_install_handler(ETH_IRQ_NUM(hw_p->devnum),
+ (interrupt_handler_t *) enetInt, dev);
}
mtmsr (msr); /* enable interrupts again */
@@ -987,7 +1036,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
hw_p->bis = bis;
hw_p->first_init = 1;
- return (1);
+ return 0;
}
@@ -1015,6 +1064,7 @@ static int ppc_4xx_eth_send (struct eth_device *dev, volatile void *ptr,
/* memcpy ((void *) &tx_buff[tx_slot], (const void *) ptr, len); */
memcpy ((void *) hw_p->txbuf_ptr, (const void *) ptr, len);
+ flush_dcache_range((u32)hw_p->txbuf_ptr, (u32)hw_p->txbuf_ptr + len);
/*-----------------------------------------------------------------------+
* set TX Buffer busy, and send it
@@ -1030,8 +1080,8 @@ static int ppc_4xx_eth_send (struct eth_device *dev, volatile void *ptr,
__asm__ volatile ("eieio");
- out32 (EMAC_TXM0 + hw_p->hw_addr,
- in32 (EMAC_TXM0 + hw_p->hw_addr) | EMAC_TXM0_GNP0);
+ out_be32((void *)EMAC_TXM0 + hw_p->hw_addr,
+ in_be32((void *)EMAC_TXM0 + hw_p->hw_addr) | EMAC_TXM0_GNP0);
#ifdef INFO_4XX_ENET
hw_p->stats.pkts_tx++;
#endif
@@ -1041,7 +1091,7 @@ static int ppc_4xx_eth_send (struct eth_device *dev, volatile void *ptr,
*-----------------------------------------------------------------------*/
time_start = get_timer (0);
while (1) {
- temp_txm0 = in32 (EMAC_TXM0 + hw_p->hw_addr);
+ temp_txm0 = in_be32((void *)EMAC_TXM0 + hw_p->hw_addr);
/* loop until either TINT turns on or 3 seconds elapse */
if ((temp_txm0 & EMAC_TXM0_GNP0) != 0) {
/* transmit is done, so now check for errors
@@ -1059,7 +1109,7 @@ static int ppc_4xx_eth_send (struct eth_device *dev, volatile void *ptr,
}
-#if defined (CONFIG_440)
+#if defined (CONFIG_440) || defined(CONFIG_405EX)
#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
/*
@@ -1073,7 +1123,8 @@ static int ppc_4xx_eth_send (struct eth_device *dev, volatile void *ptr,
#define UIC0SR uic0sr
#endif
-#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_405EX)
#define UICMSR_ETHX uic0msr
#define UICSR_ETHX uic0sr
#else
@@ -1149,7 +1200,7 @@ int enetInt (struct eth_device *dev)
/* port by port dispatch of emac interrupts */
if (hw_p->devnum == 0) {
if (UIC_ETH0 & my_uicmsr_ethx) { /* look for EMAC errors */
- emac_isr = in32 (EMAC_ISR + hw_p->hw_addr);
+ emac_isr = in_be32((void *)EMAC_ISR + hw_p->hw_addr);
if ((hw_p->emac_ier & emac_isr) != 0) {
emac_err (dev, emac_isr);
serviced = 1;
@@ -1168,7 +1219,7 @@ int enetInt (struct eth_device *dev)
#if !defined(CONFIG_440SP)
if (hw_p->devnum == 1) {
if (UIC_ETH1 & my_uicmsr_ethx) { /* look for EMAC errors */
- emac_isr = in32 (EMAC_ISR + hw_p->hw_addr);
+ emac_isr = in_be32((void *)EMAC_ISR + hw_p->hw_addr);
if ((hw_p->emac_ier & emac_isr) != 0) {
emac_err (dev, emac_isr);
serviced = 1;
@@ -1186,7 +1237,7 @@ int enetInt (struct eth_device *dev)
#if defined (CONFIG_440GX)
if (hw_p->devnum == 2) {
if (UIC_ETH2 & my_uic2msr) { /* look for EMAC errors */
- emac_isr = in32 (EMAC_ISR + hw_p->hw_addr);
+ emac_isr = in_be32((void *)EMAC_ISR + hw_p->hw_addr);
if ((hw_p->emac_ier & emac_isr) != 0) {
emac_err (dev, emac_isr);
serviced = 1;
@@ -1204,7 +1255,7 @@ int enetInt (struct eth_device *dev)
if (hw_p->devnum == 3) {
if (UIC_ETH3 & my_uic2msr) { /* look for EMAC errors */
- emac_isr = in32 (EMAC_ISR + hw_p->hw_addr);
+ emac_isr = in_be32((void *)EMAC_ISR + hw_p->hw_addr);
if ((hw_p->emac_ier & emac_isr) != 0) {
emac_err (dev, emac_isr);
serviced = 1;
@@ -1316,7 +1367,7 @@ int enetInt (struct eth_device *dev)
/* port by port dispatch of emac interrupts */
if ((SEL_UIC_DEF(hw_p->devnum) & my_uicmsr) != 0) { /* look for EMAC errors */
- emac_isr = in32 (EMAC_ISR + hw_p->hw_addr);
+ emac_isr = in_be32((void *)EMAC_ISR + hw_p->hw_addr);
if ((hw_p->emac_ier & emac_isr) != 0) {
emac_err (dev, emac_isr);
serviced = 1;
@@ -1390,7 +1441,7 @@ static void emac_err (struct eth_device *dev, unsigned long isr)
EMAC_4XX_HW_PST hw_p = dev->priv;
printf ("EMAC%d error occured.... ISR = %lx\n", hw_p->devnum, isr);
- out32 (EMAC_ISR + hw_p->hw_addr, isr);
+ out_be32((void *)EMAC_ISR + hw_p->hw_addr, isr);
}
/*-----------------------------------------------------------------------------+
@@ -1513,6 +1564,9 @@ static int ppc_4xx_eth_rx (struct eth_device *dev)
/* Pass the packet up to the protocol layers. */
/* NetReceive(NetRxPackets[rxIdx], length - 4); */
/* NetReceive(NetRxPackets[i], length); */
+ invalidate_dcache_range((u32)hw_p->rx[user_index].data_ptr,
+ (u32)hw_p->rx[user_index].data_ptr +
+ length - 4);
NetReceive (NetRxPackets[user_index], length - 4);
/* Free Recv Buffer */
hw_p->rx[user_index].ctrl |= MAL_RX_CTRL_EMPTY;
@@ -1601,7 +1655,11 @@ int ppc_4xx_eth_initialize (bd_t * bis)
bis->bi_phynum[3] = CONFIG_PHY3_ADDR;
bis->bi_phymode[2] = 2;
bis->bi_phymode[3] = 2;
+#endif
+#if defined(CONFIG_440GX) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_405EX)
ppc_4xx_eth_setup_bridge(0, bis);
#endif
@@ -1649,7 +1707,9 @@ int ppc_4xx_eth_initialize (bd_t * bis)
if (0 == virgin) {
/* set the MAL IER ??? names may change with new spec ??? */
-#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#if defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_405EX)
mal_ier =
MAL_IER_PT | MAL_IER_PRE | MAL_IER_PWE |
MAL_IER_DE | MAL_IER_OTE | MAL_IER_OE | MAL_IER_PE ;
@@ -1695,7 +1755,8 @@ int ppc_4xx_eth_initialize (bd_t * bis)
#endif
#endif
} /* end for each supported device */
- return (1);
+
+ return 0;
}
#if !defined(CONFIG_NET_MULTI)
diff --git a/cpu/ppc4xx/405gp_pci.c b/cpu/ppc4xx/4xx_pci.c
index 282e7a1ba4..a5b9690bec 100644
--- a/cpu/ppc4xx/405gp_pci.c
+++ b/cpu/ppc4xx/4xx_pci.c
@@ -72,7 +72,7 @@
#include <common.h>
#include <command.h>
#if !defined(CONFIG_440)
-#include <405gp_pci.h>
+#include <asm/4xx_pci.h>
#endif
#include <asm/processor.h>
#include <pci.h>
@@ -339,7 +339,7 @@ void pci_405gp_init(struct pci_controller *hose)
}
/*
- * drivers/pci.c skips every host bridge but the 405GP since it could
+ * drivers/pci/pci.c skips every host bridge but the 405GP since it could
* be set as an Adapter.
*
* I (Andrew May) don't know what we should do here, but I don't want
@@ -592,4 +592,15 @@ void pci_init_board(void)
}
#endif /* CONFIG_440 */
+
+#if defined(CONFIG_405EX)
+void pci_init_board(void)
+{
+#ifdef CONFIG_PCI_SCAN_SHOW
+ printf("PCI: Bus Dev VenId DevId Class Int\n");
+#endif
+ pcie_setup_hoses(0);
+}
+#endif /* CONFIG_405EX */
+
#endif /* CONFIG_PCI */
diff --git a/cpu/ppc4xx/440spe_pcie.c b/cpu/ppc4xx/4xx_pcie.c
index 3eac0ae62c..3af9862bff 100644
--- a/cpu/ppc4xx/440spe_pcie.c
+++ b/cpu/ppc4xx/4xx_pcie.c
@@ -20,15 +20,21 @@
*
*/
+/* define DEBUG for debugging output (obviously ;-)) */
+#if 0
+#define DEBUG
+#endif
+
#include <asm/processor.h>
#include <asm-ppc/io.h>
#include <ppc4xx.h>
#include <common.h>
#include <pci.h>
-#if defined(CONFIG_440SPE) && defined(CONFIG_PCI)
+#if (defined(CONFIG_440SPE) || defined(CONFIG_405EX)) && \
+ defined(CONFIG_PCI)
-#include "440spe_pcie.h"
+#include <asm/4xx_pcie.h>
enum {
PTYPE_ENDPOINT = 0x0,
@@ -40,6 +46,20 @@ enum {
LNKW_X8 = 0x8
};
+static int validate_endpoint(struct pci_controller *hose)
+{
+ if (hose->cfg_data == (u8 *)CFG_PCIE0_CFGBASE)
+ return (is_end_point(0));
+ else if (hose->cfg_data == (u8 *)CFG_PCIE1_CFGBASE)
+ return (is_end_point(1));
+#if CFG_PCIE_NR_PORTS > 2
+ else if (hose->cfg_data == (u8 *)CFG_PCIE2_CFGBASE)
+ return (is_end_point(2));
+#endif
+
+ return 0;
+}
+
static u8* pcie_get_base(struct pci_controller *hose, unsigned int devfn)
{
u8 *base = (u8*)hose->cfg_data;
@@ -50,8 +70,10 @@ static u8* pcie_get_base(struct pci_controller *hose, unsigned int devfn)
base = (u8*)CFG_PCIE0_XCFGBASE;
if (hose->cfg_data == (u8*)CFG_PCIE1_CFGBASE)
base = (u8*)CFG_PCIE1_XCFGBASE;
+#if CFG_PCIE_NR_PORTS > 2
if (hose->cfg_data == (u8*)CFG_PCIE2_CFGBASE)
base = (u8*)CFG_PCIE2_XCFGBASE;
+#endif
}
return base;
@@ -63,8 +85,10 @@ static void pcie_dmer_disable(void)
mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE0_BASE)) | GPL_DMER_MASK_DISA);
mtdcr (DCRN_PEGPL_CFG(DCRN_PCIE1_BASE),
mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE1_BASE)) | GPL_DMER_MASK_DISA);
+#if CFG_PCIE_NR_PORTS > 2
mtdcr (DCRN_PEGPL_CFG(DCRN_PCIE2_BASE),
mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE2_BASE)) | GPL_DMER_MASK_DISA);
+#endif
}
static void pcie_dmer_enable(void)
@@ -73,8 +97,10 @@ static void pcie_dmer_enable(void)
mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE0_BASE)) & ~GPL_DMER_MASK_DISA);
mtdcr (DCRN_PEGPL_CFG (DCRN_PCIE1_BASE),
mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE1_BASE)) & ~GPL_DMER_MASK_DISA);
+#if CFG_PCIE_NR_PORTS > 2
mtdcr (DCRN_PEGPL_CFG (DCRN_PCIE2_BASE),
mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE2_BASE)) & ~GPL_DMER_MASK_DISA);
+#endif
}
static int pcie_read_config(struct pci_controller *hose, unsigned int devfn,
@@ -83,6 +109,9 @@ static int pcie_read_config(struct pci_controller *hose, unsigned int devfn,
u8 *address;
*val = 0;
+ if (validate_endpoint(hose))
+ return 0; /* No upstream config access */
+
/*
* Bus numbers are relative to hose->first_busno
*/
@@ -115,6 +144,7 @@ static int pcie_read_config(struct pci_controller *hose, unsigned int devfn,
*/
pcie_dmer_disable ();
+ debug("%s: cfg_data=%08x offset=%08x\n", __func__, hose->cfg_data, offset);
switch (len) {
case 1:
*val = in_8(hose->cfg_data + offset);
@@ -137,6 +167,9 @@ static int pcie_write_config(struct pci_controller *hose, unsigned int devfn,
u8 *address;
+ if (validate_endpoint(hose))
+ return 0; /* No upstream config access */
+
/*
* Bus numbers are relative to hose->first_busno
*/
@@ -222,7 +255,8 @@ int pcie_write_config_dword(struct pci_controller *hose,pci_dev_t dev,int offset
return pcie_write_config(hose,(u32)dev,offset,3,(u32 )val);
}
-static void ppc440spe_setup_utl(u32 port) {
+#if defined(CONFIG_440SPE)
+static void ppc4xx_setup_utl(u32 port) {
volatile void *utl_base = NULL;
@@ -333,7 +367,7 @@ static int check_error(void)
/*
* Initialize PCI Express core
*/
-int ppc440spe_init_pcie(void)
+int ppc4xx_init_pcie(void)
{
int time_out = 20;
@@ -366,13 +400,223 @@ int ppc440spe_init_pcie(void)
}
return 0;
}
+#else
+static void ppc4xx_setup_utl(u32 port)
+{
+ u32 utl_base;
+
+ /*
+ * Map UTL registers at 0xef4f_n000 (4K 0xfff mask) PEGPLn_REGMSK
+ */
+ switch (port) {
+ case 0:
+ mtdcr(DCRN_PEGPL_REGBAH(PCIE0), 0x00000000);
+ mtdcr(DCRN_PEGPL_REGBAL(PCIE0), CFG_PCIE0_UTLBASE);
+ mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0x00007001); /* 4k region, valid */
+ mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0);
+ break;
+
+ case 1:
+ mtdcr(DCRN_PEGPL_REGBAH(PCIE1), 0x00000000);
+ mtdcr(DCRN_PEGPL_REGBAL(PCIE1), CFG_PCIE1_UTLBASE);
+ mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0x00007001); /* 4k region, valid */
+ mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0);
+
+ break;
+ }
+ utl_base = (port==0) ? CFG_PCIE0_UTLBASE : CFG_PCIE1_UTLBASE;
+
+ /*
+ * Set buffer allocations and then assert VRB and TXE.
+ */
+ out_be32((u32 *)(utl_base + PEUTL_OUTTR), 0x02000000);
+ out_be32((u32 *)(utl_base + PEUTL_INTR), 0x02000000);
+ out_be32((u32 *)(utl_base + PEUTL_OPDBSZ), 0x04000000);
+ out_be32((u32 *)(utl_base + PEUTL_PBBSZ), 0x21000000);
+ out_be32((u32 *)(utl_base + PEUTL_IPHBSZ), 0x02000000);
+ out_be32((u32 *)(utl_base + PEUTL_IPDBSZ), 0x04000000);
+ out_be32((u32 *)(utl_base + PEUTL_RCIRQEN), 0x00f00000);
+ out_be32((u32 *)(utl_base + PEUTL_PCTL), 0x80800066);
+
+ out_be32((u32 *)(utl_base + PEUTL_PBCTL), 0x0800000c);
+ out_be32((u32 *)(utl_base + PEUTL_RCSTA),
+ in_be32((u32 *)(utl_base + PEUTL_RCSTA)) | 0x000040000);
+}
+
+int ppc4xx_init_pcie(void)
+{
+ /*
+ * Nothing to do on 405EX
+ */
+ return 0;
+}
+#endif
/*
- * Yucca board as End point and root point setup
+ * Board-specific pcie initialization
+ * Platform code can reimplement ppc4xx_init_pcie_port_hw() if needed
+ */
+
+/*
+ * Initialize various parts of the PCI Express core for our port:
+ *
+ * - Set as a root port and enable max width
+ * (PXIE0 -> X8, PCIE1 and PCIE2 -> X4).
+ * - Set up UTL configuration.
+ * - Increase SERDES drive strength to levels suggested by AMCC.
+ * - De-assert RSTPYN, RSTDL and RSTGU.
+ *
+ * NOTICE for 440SPE revB chip: PESDRn_UTLSET2 is not set - we leave it
+ * with default setting 0x11310000. The register has new fields,
+ * PESDRn_UTLSET2[LKINE] in particular: clearing it leads to PCIE core
+ * hang.
+ */
+#if defined(CONFIG_440SPE)
+int __ppc4xx_init_pcie_port_hw(int port, int rootport)
+{
+ u32 val = 1 << 24;
+ u32 utlset1;
+
+ if (rootport) {
+ val = PTYPE_ROOT_PORT << 20;
+ utlset1 = 0x21222222;
+ } else {
+ val = PTYPE_LEGACY_ENDPOINT << 20;
+ utlset1 = 0x20222222;
+ }
+
+ if (port == 0)
+ val |= LNKW_X8 << 12;
+ else
+ val |= LNKW_X4 << 12;
+
+ SDR_WRITE(SDRN_PESDR_DLPSET(port), val);
+ SDR_WRITE(SDRN_PESDR_UTLSET1(port), utlset1);
+ if (!ppc440spe_revB())
+ SDR_WRITE(SDRN_PESDR_UTLSET2(port), 0x11000000);
+ SDR_WRITE(SDRN_PESDR_HSSL0SET1(port), 0x35000000);
+ SDR_WRITE(SDRN_PESDR_HSSL1SET1(port), 0x35000000);
+ SDR_WRITE(SDRN_PESDR_HSSL2SET1(port), 0x35000000);
+ SDR_WRITE(SDRN_PESDR_HSSL3SET1(port), 0x35000000);
+ if (port == 0) {
+ SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
+ }
+ SDR_WRITE(SDRN_PESDR_RCSSET(port), (SDR_READ(SDRN_PESDR_RCSSET(port)) &
+ ~(1 << 24 | 1 << 16)) | 1 << 12);
+
+ return 0;
+}
+#endif /* CONFIG_440SPE */
+
+#if defined(CONFIG_405EX)
+int __ppc4xx_init_pcie_port_hw(int port, int rootport)
+{
+ u32 val;
+
+ if (rootport)
+ val = 0x00401000;
+ else
+ val = 0x00101000;
+
+ SDR_WRITE(SDRN_PESDR_DLPSET(port), val);
+ SDR_WRITE(SDRN_PESDR_UTLSET1(port), 0x00000000);
+ SDR_WRITE(SDRN_PESDR_UTLSET2(port), 0x01010000);
+ SDR_WRITE(SDRN_PESDR_PHYSET1(port), 0x720F0000);
+ SDR_WRITE(SDRN_PESDR_PHYSET2(port), 0x70600003);
+
+ /* Assert the PE0_PHY reset */
+ SDR_WRITE(SDRN_PESDR_RCSSET(port), 0x01010000);
+ udelay(1000);
+
+ /* deassert the PE0_hotreset */
+ if (is_end_point(port))
+ SDR_WRITE(SDRN_PESDR_RCSSET(port), 0x01111000);
+ else
+ SDR_WRITE(SDRN_PESDR_RCSSET(port), 0x01101000);
+
+ /* poll for phy !reset */
+ while (!(SDR_READ(SDRN_PESDR_PHYSTA(port)) & 0x00001000))
+ ;
+
+ /* deassert the PE0_gpl_utl_reset */
+ SDR_WRITE(SDRN_PESDR_RCSSET(port), 0x00101000);
+
+ if (port == 0)
+ mtdcr(DCRN_PEGPL_CFG(PCIE0), 0x10000000); /* guarded on */
+ else
+ mtdcr(DCRN_PEGPL_CFG(PCIE1), 0x10000000); /* guarded on */
+
+ return 0;
+}
+#endif /* CONFIG_405EX */
+
+int ppc4xx_init_pcie_port_hw(int port, int rootport)
+__attribute__((weak, alias("__ppc4xx_init_pcie_port_hw")));
+
+/*
+ * We map PCI Express configuration access into the 512MB regions
+ *
+ * NOTICE: revB is very strict about PLB real addressess and ranges to
+ * be mapped for config space; it seems to only work with d_nnnn_nnnn
+ * range (hangs the core upon config transaction attempts when set
+ * otherwise) while revA uses c_nnnn_nnnn.
+ *
+ * For revA:
+ * PCIE0: 0xc_4000_0000
+ * PCIE1: 0xc_8000_0000
+ * PCIE2: 0xc_c000_0000
+ *
+ * For revB:
+ * PCIE0: 0xd_0000_0000
+ * PCIE1: 0xd_2000_0000
+ * PCIE2: 0xd_4000_0000
+ *
+ * For 405EX:
+ * PCIE0: 0xa000_0000
+ * PCIE1: 0xc000_0000
+ */
+static inline u64 ppc4xx_get_cfgaddr(int port)
+{
+#if defined(CONFIG_405EX)
+ if (port == 0)
+ return (u64)CFG_PCIE0_CFGBASE;
+ else
+ return (u64)CFG_PCIE1_CFGBASE;
+#endif
+#if defined(CONFIG_440SPE)
+ if (ppc440spe_revB()) {
+ switch (port) {
+ default: /* to satisfy compiler */
+ case 0:
+ return 0x0000000d00000000ULL;
+ case 1:
+ return 0x0000000d20000000ULL;
+ case 2:
+ return 0x0000000d40000000ULL;
+ }
+ } else {
+ switch (port) {
+ default: /* to satisfy compiler */
+ case 0:
+ return 0x0000000c40000000ULL;
+ case 1:
+ return 0x0000000c80000000ULL;
+ case 2:
+ return 0x0000000cc0000000ULL;
+ }
+ }
+#endif
+}
+
+/*
+ * 4xx boards as end point and root point setup
* and
* testing inbound and out bound windows
*
- * YUCCA board can be plugged into another yucca board or you can get PCI-E
+ * 4xx boards can be plugged into another 4xx boards or you can get PCI-E
* cable which can be used to setup loop back from one port to another port.
* Please rememeber that unless there is a endpoint plugged in to root port it
* will not initialize. It is the same in case of endpoint , unless there is
@@ -386,110 +630,47 @@ int ppc440spe_init_pcie(void)
* /proc/bus/pci/devices. Where you can see the configuration registers
* of end point device attached to the port.
*
- * Enpoint cofiguration can be verified by connecting Yucca board to any
- * host or another yucca board. Then try to scan the device. In case of
+ * Enpoint cofiguration can be verified by connecting 4xx board to any
+ * host or another 4xx board. Then try to scan the device. In case of
* linux use "lspci" or appripriate os command.
*
- * How do I verify the inbound and out bound windows ?(yucca to yucca)
+ * How do I verify the inbound and out bound windows ? (4xx to 4xx)
* in this configuration inbound and outbound windows are setup to access
* sram memroy area. SRAM is at 0x4 0000 0000 , on PLB bus. This address
* is mapped at 0x90000000. From u-boot prompt write data 0xb000 0000,
* This is waere your POM(PLB out bound memory window) mapped. then
- * read the data from other yucca board's u-boot prompt at address
+ * read the data from other 4xx board's u-boot prompt at address
* 0x9000 0000(SRAM). Data should match.
* In case of inbound , write data to u-boot command prompt at 0xb000 0000
* which is mapped to 0x4 0000 0000. Now on rootpoint yucca u-boot prompt check
* data at 0x9000 0000(SRAM).Data should match.
*/
-int ppc440spe_init_pcie_rootport(int port)
+int ppc4xx_init_pcie_port(int port, int rootport)
{
static int core_init;
volatile u32 val = 0;
int attempts;
+ u64 addr;
+ u32 low, high;
if (!core_init) {
- ++core_init;
- if (ppc440spe_init_pcie())
+ if (ppc4xx_init_pcie())
return -1;
+ ++core_init;
}
/*
- * Initialize various parts of the PCI Express core for our port:
- *
- * - Set as a root port and enable max width
- * (PXIE0 -> X8, PCIE1 and PCIE2 -> X4).
- * - Set up UTL configuration.
- * - Increase SERDES drive strength to levels suggested by AMCC.
- * - De-assert RSTPYN, RSTDL and RSTGU.
- *
- * NOTICE for revB chip: PESDRn_UTLSET2 is not set - we leave it with
- * default setting 0x11310000. The register has new fields,
- * PESDRn_UTLSET2[LKINE] in particular: clearing it leads to PCIE core
- * hang.
+ * Initialize various parts of the PCI Express core for our port
*/
- switch (port) {
- case 0:
- SDR_WRITE(PESDR0_DLPSET, 1 << 24 | PTYPE_ROOT_PORT << 20 | LNKW_X8 << 12);
-
- SDR_WRITE(PESDR0_UTLSET1, 0x21222222);
- if (!ppc440spe_revB())
- SDR_WRITE(PESDR0_UTLSET2, 0x11000000);
- SDR_WRITE(PESDR0_HSSL0SET1, 0x35000000);
- SDR_WRITE(PESDR0_HSSL1SET1, 0x35000000);
- SDR_WRITE(PESDR0_HSSL2SET1, 0x35000000);
- SDR_WRITE(PESDR0_HSSL3SET1, 0x35000000);
- SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
- SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
- SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
- SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
- SDR_WRITE(PESDR0_RCSSET,
- (SDR_READ(PESDR0_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
- break;
+ ppc4xx_init_pcie_port_hw(port, rootport);
- case 1:
- SDR_WRITE(PESDR1_DLPSET, 1 << 24 | PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
- SDR_WRITE(PESDR1_UTLSET1, 0x21222222);
- if (!ppc440spe_revB())
- SDR_WRITE(PESDR1_UTLSET2, 0x11000000);
- SDR_WRITE(PESDR1_HSSL0SET1, 0x35000000);
- SDR_WRITE(PESDR1_HSSL1SET1, 0x35000000);
- SDR_WRITE(PESDR1_HSSL2SET1, 0x35000000);
- SDR_WRITE(PESDR1_HSSL3SET1, 0x35000000);
- SDR_WRITE(PESDR1_RCSSET,
- (SDR_READ(PESDR1_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
- break;
-
- case 2:
- SDR_WRITE(PESDR2_DLPSET, 1 << 24 | PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
- SDR_WRITE(PESDR2_UTLSET1, 0x21222222);
- if (!ppc440spe_revB())
- SDR_WRITE(PESDR2_UTLSET2, 0x11000000);
- SDR_WRITE(PESDR2_HSSL0SET1, 0x35000000);
- SDR_WRITE(PESDR2_HSSL1SET1, 0x35000000);
- SDR_WRITE(PESDR2_HSSL2SET1, 0x35000000);
- SDR_WRITE(PESDR2_HSSL3SET1, 0x35000000);
- SDR_WRITE(PESDR2_RCSSET,
- (SDR_READ(PESDR2_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
- break;
- }
/*
* Notice: the following delay has critical impact on device
* initialization - if too short (<50ms) the link doesn't get up.
*/
mdelay(100);
- switch (port) {
- case 0:
- val = SDR_READ(PESDR0_RCSSTS);
- break;
- case 1:
- val = SDR_READ(PESDR1_RCSSTS);
- break;
- case 2:
- val = SDR_READ(PESDR2_RCSSTS);
- break;
- }
-
+ val = SDR_READ(SDRN_PESDR_RCSSTS(port));
if (val & (1 << 20)) {
printf("PCIE%d: PGRST failed %08x\n", port, val);
return -1;
@@ -498,18 +679,7 @@ int ppc440spe_init_pcie_rootport(int port)
/*
* Verify link is up
*/
- val = 0;
- switch (port) {
- case 0:
- val = SDR_READ(PESDR0_LOOP);
- break;
- case 1:
- val = SDR_READ(PESDR1_LOOP);
- break;
- case 2:
- val = SDR_READ(PESDR2_LOOP);
- break;
- }
+ val = SDR_READ(SDRN_PESDR_LOOP(port));
if (!(val & 0x00001000)) {
printf("PCIE%d: link is not up.\n", port);
return -1;
@@ -520,331 +690,75 @@ int ppc440spe_init_pcie_rootport(int port)
* We use default settings for revB chip.
*/
if (!ppc440spe_revB())
- ppc440spe_setup_utl(port);
+ ppc4xx_setup_utl(port);
/*
* We map PCI Express configuration access into the 512MB regions
- *
- * NOTICE: revB is very strict about PLB real addressess and ranges to
- * be mapped for config space; it seems to only work with d_nnnn_nnnn
- * range (hangs the core upon config transaction attempts when set
- * otherwise) while revA uses c_nnnn_nnnn.
- *
- * For revA:
- * PCIE0: 0xc_4000_0000
- * PCIE1: 0xc_8000_0000
- * PCIE2: 0xc_c000_0000
- *
- * For revB:
- * PCIE0: 0xd_0000_0000
- * PCIE1: 0xd_2000_0000
- * PCIE2: 0xd_4000_0000
*/
+ addr = ppc4xx_get_cfgaddr(port);
+ low = U64_TO_U32_LOW(addr);
+ high = U64_TO_U32_HIGH(addr);
switch (port) {
case 0:
- if (ppc440spe_revB()) {
- mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000d);
- mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x00000000);
- } else {
- /* revA */
- mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c);
- mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000);
- }
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), high);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), low);
mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */
break;
-
case 1:
- if (ppc440spe_revB()) {
- mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000d);
- mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x20000000);
- } else {
- mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c);
- mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000);
- }
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), high);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), low);
mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
break;
-
+#if CFG_PCIE_NR_PORTS > 2
case 2:
- if (ppc440spe_revB()) {
- mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000d);
- mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0x40000000);
- } else {
- mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c);
- mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000);
- }
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), high);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), low);
mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
break;
+#endif
}
/*
* Check for VC0 active and assert RDY.
*/
attempts = 10;
- switch (port) {
- case 0:
- while(!(SDR_READ(PESDR0_RCSSTS) & (1 << 16))) {
- if (!(attempts--)) {
- printf("PCIE0: VC0 not active\n");
- return -1;
- }
- mdelay(1000);
- }
- SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20);
- break;
- case 1:
- while(!(SDR_READ(PESDR1_RCSSTS) & (1 << 16))) {
- if (!(attempts--)) {
- printf("PCIE1: VC0 not active\n");
- return -1;
- }
- mdelay(1000);
- }
-
- SDR_WRITE(PESDR1_RCSSET, SDR_READ(PESDR1_RCSSET) | 1 << 20);
- break;
- case 2:
- while(!(SDR_READ(PESDR2_RCSSTS) & (1 << 16))) {
- if (!(attempts--)) {
- printf("PCIE2: VC0 not active\n");
- return -1;
- }
- mdelay(1000);
+ while(!(SDR_READ(SDRN_PESDR_RCSSTS(port)) & (1 << 16))) {
+ if (!(attempts--)) {
+ printf("PCIE%d: VC0 not active\n", port);
+ return -1;
}
-
- SDR_WRITE(PESDR2_RCSSET, SDR_READ(PESDR2_RCSSET) | 1 << 20);
- break;
+ mdelay(1000);
}
+ SDR_WRITE(SDRN_PESDR_RCSSET(port),
+ SDR_READ(SDRN_PESDR_RCSSET(port)) | 1 << 20);
mdelay(100);
return 0;
}
-int ppc440spe_init_pcie_endport(int port)
+int ppc4xx_init_pcie_rootport(int port)
{
- static int core_init;
- volatile u32 val = 0;
- int attempts;
-
- if (!core_init) {
- ++core_init;
- if (ppc440spe_init_pcie())
- return -1;
- }
-
- /*
- * Initialize various parts of the PCI Express core for our port:
- *
- * - Set as a end port and enable max width
- * (PXIE0 -> X8, PCIE1 and PCIE2 -> X4).
- * - Set up UTL configuration.
- * - Increase SERDES drive strength to levels suggested by AMCC.
- * - De-assert RSTPYN, RSTDL and RSTGU.
- *
- * NOTICE for revB chip: PESDRn_UTLSET2 is not set - we leave it with
- * default setting 0x11310000. The register has new fields,
- * PESDRn_UTLSET2[LKINE] in particular: clearing it leads to PCIE core
- * hang.
- */
- switch (port) {
- case 0:
- SDR_WRITE(PESDR0_DLPSET, 1 << 24 | PTYPE_LEGACY_ENDPOINT << 20 | LNKW_X8 << 12);
-
- SDR_WRITE(PESDR0_UTLSET1, 0x20222222);
- if (!ppc440spe_revB())
- SDR_WRITE(PESDR0_UTLSET2, 0x11000000);
- SDR_WRITE(PESDR0_HSSL0SET1, 0x35000000);
- SDR_WRITE(PESDR0_HSSL1SET1, 0x35000000);
- SDR_WRITE(PESDR0_HSSL2SET1, 0x35000000);
- SDR_WRITE(PESDR0_HSSL3SET1, 0x35000000);
- SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
- SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
- SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
- SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
- SDR_WRITE(PESDR0_RCSSET,
- (SDR_READ(PESDR0_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
- break;
-
- case 1:
- SDR_WRITE(PESDR1_DLPSET, 1 << 24 | PTYPE_LEGACY_ENDPOINT << 20 | LNKW_X4 << 12);
- SDR_WRITE(PESDR1_UTLSET1, 0x20222222);
- if (!ppc440spe_revB())
- SDR_WRITE(PESDR1_UTLSET2, 0x11000000);
- SDR_WRITE(PESDR1_HSSL0SET1, 0x35000000);
- SDR_WRITE(PESDR1_HSSL1SET1, 0x35000000);
- SDR_WRITE(PESDR1_HSSL2SET1, 0x35000000);
- SDR_WRITE(PESDR1_HSSL3SET1, 0x35000000);
- SDR_WRITE(PESDR1_RCSSET,
- (SDR_READ(PESDR1_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
- break;
-
- case 2:
- SDR_WRITE(PESDR2_DLPSET, 1 << 24 | PTYPE_LEGACY_ENDPOINT << 20 | LNKW_X4 << 12);
- SDR_WRITE(PESDR2_UTLSET1, 0x20222222);
- if (!ppc440spe_revB())
- SDR_WRITE(PESDR2_UTLSET2, 0x11000000);
- SDR_WRITE(PESDR2_HSSL0SET1, 0x35000000);
- SDR_WRITE(PESDR2_HSSL1SET1, 0x35000000);
- SDR_WRITE(PESDR2_HSSL2SET1, 0x35000000);
- SDR_WRITE(PESDR2_HSSL3SET1, 0x35000000);
- SDR_WRITE(PESDR2_RCSSET,
- (SDR_READ(PESDR2_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
- break;
- }
- /*
- * Notice: the following delay has critical impact on device
- * initialization - if too short (<50ms) the link doesn't get up.
- */
- mdelay(100);
-
- switch (port) {
- case 0: val = SDR_READ(PESDR0_RCSSTS); break;
- case 1: val = SDR_READ(PESDR1_RCSSTS); break;
- case 2: val = SDR_READ(PESDR2_RCSSTS); break;
- }
-
- if (val & (1 << 20)) {
- printf("PCIE%d: PGRST failed %08x\n", port, val);
- return -1;
- }
-
- /*
- * Verify link is up
- */
- val = 0;
- switch (port)
- {
- case 0:
- val = SDR_READ(PESDR0_LOOP);
- break;
- case 1:
- val = SDR_READ(PESDR1_LOOP);
- break;
- case 2:
- val = SDR_READ(PESDR2_LOOP);
- break;
- }
- if (!(val & 0x00001000)) {
- printf("PCIE%d: link is not up.\n", port);
- return -1;
- }
-
- /*
- * Setup UTL registers - but only on revA!
- * We use default settings for revB chip.
- */
- if (!ppc440spe_revB())
- ppc440spe_setup_utl(port);
-
- /*
- * We map PCI Express configuration access into the 512MB regions
- *
- * NOTICE: revB is very strict about PLB real addressess and ranges to
- * be mapped for config space; it seems to only work with d_nnnn_nnnn
- * range (hangs the core upon config transaction attempts when set
- * otherwise) while revA uses c_nnnn_nnnn.
- *
- * For revA:
- * PCIE0: 0xc_4000_0000
- * PCIE1: 0xc_8000_0000
- * PCIE2: 0xc_c000_0000
- *
- * For revB:
- * PCIE0: 0xd_0000_0000
- * PCIE1: 0xd_2000_0000
- * PCIE2: 0xd_4000_0000
- */
- switch (port) {
- case 0:
- if (ppc440spe_revB()) {
- mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000d);
- mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x00000000);
- } else {
- /* revA */
- mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c);
- mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000);
- }
- mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */
- break;
-
- case 1:
- if (ppc440spe_revB()) {
- mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000d);
- mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x20000000);
- } else {
- mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c);
- mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000);
- }
- mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
- break;
-
- case 2:
- if (ppc440spe_revB()) {
- mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000d);
- mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0x40000000);
- } else {
- mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c);
- mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000);
- }
- mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
- break;
- }
-
- /*
- * Check for VC0 active and assert RDY.
- */
- attempts = 10;
- switch (port) {
- case 0:
- while(!(SDR_READ(PESDR0_RCSSTS) & (1 << 16))) {
- if (!(attempts--)) {
- printf("PCIE0: VC0 not active\n");
- return -1;
- }
- mdelay(1000);
- }
- SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20);
- break;
- case 1:
- while(!(SDR_READ(PESDR1_RCSSTS) & (1 << 16))) {
- if (!(attempts--)) {
- printf("PCIE1: VC0 not active\n");
- return -1;
- }
- mdelay(1000);
- }
-
- SDR_WRITE(PESDR1_RCSSET, SDR_READ(PESDR1_RCSSET) | 1 << 20);
- break;
- case 2:
- while(!(SDR_READ(PESDR2_RCSSTS) & (1 << 16))) {
- if (!(attempts--)) {
- printf("PCIE2: VC0 not active\n");
- return -1;
- }
- mdelay(1000);
- }
-
- SDR_WRITE(PESDR2_RCSSET, SDR_READ(PESDR2_RCSSET) | 1 << 20);
- break;
- }
- mdelay(100);
+ return ppc4xx_init_pcie_port(port, 1);
+}
- return 0;
+int ppc4xx_init_pcie_endport(int port)
+{
+ return ppc4xx_init_pcie_port(port, 0);
}
-void ppc440spe_setup_pcie_rootpoint(struct pci_controller *hose, int port)
+void ppc4xx_setup_pcie_rootpoint(struct pci_controller *hose, int port)
{
volatile void *mbase = NULL;
volatile void *rmbase = NULL;
pci_set_ops(hose,
- pcie_read_config_byte,
- pcie_read_config_word,
- pcie_read_config_dword,
- pcie_write_config_byte,
- pcie_write_config_word,
- pcie_write_config_dword);
+ pcie_read_config_byte,
+ pcie_read_config_word,
+ pcie_read_config_dword,
+ pcie_write_config_byte,
+ pcie_write_config_word,
+ pcie_write_config_dword);
switch (port) {
case 0:
@@ -857,11 +771,13 @@ void ppc440spe_setup_pcie_rootpoint(struct pci_controller *hose, int port)
rmbase = (u32 *)CFG_PCIE1_CFGBASE;
hose->cfg_data = (u8 *)CFG_PCIE1_CFGBASE;
break;
+#if CFG_PCIE_NR_PORTS > 2
case 2:
mbase = (u32 *)CFG_PCIE2_XCFGBASE;
rmbase = (u32 *)CFG_PCIE2_CFGBASE;
hose->cfg_data = (u8 *)CFG_PCIE2_CFGBASE;
break;
+#endif
}
/*
@@ -878,33 +794,53 @@ void ppc440spe_setup_pcie_rootpoint(struct pci_controller *hose, int port)
* subregions and to enable the outbound translation.
*/
out_le32(mbase + PECFG_POM0LAH, 0x00000000);
- out_le32(mbase + PECFG_POM0LAL, 0x00000000);
+ out_le32(mbase + PECFG_POM0LAL, CFG_PCIE_MEMBASE +
+ port * CFG_PCIE_MEMSIZE);
+ debug("PECFG_POM0LA=%08x.%08x\n", in_le32(mbase + PECFG_POM0LAH),
+ in_le32(mbase + PECFG_POM0LAL));
switch (port) {
case 0:
- mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), 0x0000000d);
- mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), CFG_PCIE_MEMBASE +
- port * CFG_PCIE_MEMSIZE);
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), CFG_PCIE_ADDR_HIGH);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), CFG_PCIE_MEMBASE +
+ port * CFG_PCIE_MEMSIZE);
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
- ~(CFG_PCIE_MEMSIZE - 1) | 3);
+ ~(CFG_PCIE_MEMSIZE - 1) | 3);
+ debug("0:PEGPL_OMR1BA=%08x.%08x MSK=%08x.%08x\n",
+ mfdcr(DCRN_PEGPL_OMR1BAH(PCIE0)),
+ mfdcr(DCRN_PEGPL_OMR1BAL(PCIE0)),
+ mfdcr(DCRN_PEGPL_OMR1MSKH(PCIE0)),
+ mfdcr(DCRN_PEGPL_OMR1MSKL(PCIE0)));
break;
case 1:
- mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), 0x0000000d);
- mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), (CFG_PCIE_MEMBASE +
- port * CFG_PCIE_MEMSIZE));
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), CFG_PCIE_ADDR_HIGH);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), CFG_PCIE_MEMBASE +
+ port * CFG_PCIE_MEMSIZE);
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
- ~(CFG_PCIE_MEMSIZE - 1) | 3);
- break;
+ ~(CFG_PCIE_MEMSIZE - 1) | 3);
+ debug("1:PEGPL_OMR1BA=%08x.%08x MSK=%08x.%08x\n",
+ mfdcr(DCRN_PEGPL_OMR1BAH(PCIE1)),
+ mfdcr(DCRN_PEGPL_OMR1BAL(PCIE1)),
+ mfdcr(DCRN_PEGPL_OMR1MSKH(PCIE1)),
+ mfdcr(DCRN_PEGPL_OMR1MSKL(PCIE1)));
+ break;
+#if CFG_PCIE_NR_PORTS > 2
case 2:
- mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), 0x0000000d);
- mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), (CFG_PCIE_MEMBASE +
- port * CFG_PCIE_MEMSIZE));
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), CFG_PCIE_ADDR_HIGH);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), CFG_PCIE_MEMBASE +
+ port * CFG_PCIE_MEMSIZE);
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
- ~(CFG_PCIE_MEMSIZE - 1) | 3);
+ ~(CFG_PCIE_MEMSIZE - 1) | 3);
+ debug("2:PEGPL_OMR1BA=%08x.%08x MSK=%08x.%08x\n",
+ mfdcr(DCRN_PEGPL_OMR1BAH(PCIE2)),
+ mfdcr(DCRN_PEGPL_OMR1BAL(PCIE2)),
+ mfdcr(DCRN_PEGPL_OMR1MSKH(PCIE2)),
+ mfdcr(DCRN_PEGPL_OMR1MSKL(PCIE2)));
break;
+#endif
}
/* Set up 16GB inbound memory window at 0 */
@@ -917,41 +853,26 @@ void ppc440spe_setup_pcie_rootpoint(struct pci_controller *hose, int port)
out_le32(mbase + PECFG_PIM01SAL, 0x00000000);
out_le32(mbase + PECFG_PIM0LAL, 0);
out_le32(mbase + PECFG_PIM0LAH, 0);
- out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
- out_le32(mbase + PECFG_PIM1LAH, 0x00000004);
+ out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
+ out_le32(mbase + PECFG_PIM1LAH, 0x00000004);
out_le32(mbase + PECFG_PIMEN, 0x1);
/* Enable I/O, Mem, and Busmaster cycles */
out_le16((u16 *)(mbase + PCI_COMMAND),
in_le16((u16 *)(mbase + PCI_COMMAND)) |
PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
- printf("PCIE:%d successfully set as rootpoint\n",port);
/* Set Device and Vendor Id */
- switch (port) {
- case 0:
- out_le16(mbase + 0x200, 0xaaa0);
- out_le16(mbase + 0x202, 0xbed0);
- break;
- case 1:
- out_le16(mbase + 0x200, 0xaaa1);
- out_le16(mbase + 0x202, 0xbed1);
- break;
- case 2:
- out_le16(mbase + 0x200, 0xaaa2);
- out_le16(mbase + 0x202, 0xbed2);
- break;
- default:
- out_le16(mbase + 0x200, 0xaaa3);
- out_le16(mbase + 0x202, 0xbed3);
- }
+ out_le16(mbase + 0x200, 0xaaa0 + port);
+ out_le16(mbase + 0x202, 0xbed0 + port);
/* Set Class Code to PCI-PCI bridge and Revision Id to 1 */
out_le32(mbase + 0x208, 0x06040001);
+ printf("PCIE%d: successfully set as root-complex\n", port);
}
-int ppc440spe_setup_pcie_endpoint(struct pci_controller *hose, int port)
+int ppc4xx_setup_pcie_endpoint(struct pci_controller *hose, int port)
{
volatile void *mbase = NULL;
int attempts = 0;
@@ -973,10 +894,12 @@ int ppc440spe_setup_pcie_endpoint(struct pci_controller *hose, int port)
mbase = (u32 *)CFG_PCIE1_XCFGBASE;
hose->cfg_data = (u8 *)CFG_PCIE1_CFGBASE;
break;
+#if defined(CFG_PCIE2_CFGBASE)
case 2:
mbase = (u32 *)CFG_PCIE2_XCFGBASE;
hose->cfg_data = (u8 *)CFG_PCIE2_CFGBASE;
break;
+#endif
}
/*
@@ -990,77 +913,73 @@ int ppc440spe_setup_pcie_endpoint(struct pci_controller *hose, int port)
switch (port) {
case 0:
- mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), 0x0000000d);
- mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), CFG_PCIE_MEMBASE +
- port * CFG_PCIE_MEMSIZE);
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), CFG_PCIE_ADDR_HIGH);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), CFG_PCIE_MEMBASE +
+ port * CFG_PCIE_MEMSIZE);
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
- ~(CFG_PCIE_MEMSIZE - 1) | 3);
+ ~(CFG_PCIE_MEMSIZE - 1) | 3);
break;
case 1:
- mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), 0x0000000d);
- mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), (CFG_PCIE_MEMBASE +
- port * CFG_PCIE_MEMSIZE));
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), CFG_PCIE_ADDR_HIGH);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), CFG_PCIE_MEMBASE +
+ port * CFG_PCIE_MEMSIZE);
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
- ~(CFG_PCIE_MEMSIZE - 1) | 3);
+ ~(CFG_PCIE_MEMSIZE - 1) | 3);
break;
+#if CFG_PCIE_NR_PORTS > 2
case 2:
- mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), 0x0000000d);
- mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), (CFG_PCIE_MEMBASE +
- port * CFG_PCIE_MEMSIZE));
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), CFG_PCIE_ADDR_HIGH);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), CFG_PCIE_MEMBASE +
+ port * CFG_PCIE_MEMSIZE);
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
- ~(CFG_PCIE_MEMSIZE - 1) | 3);
+ ~(CFG_PCIE_MEMSIZE - 1) | 3);
break;
+#endif
}
- /* Set up 16GB inbound memory window at 0 */
+ /* Set up 64MB inbound memory window at 0 */
out_le32(mbase + PCI_BASE_ADDRESS_0, 0);
out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
- out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffc);
- out_le32(mbase + PECFG_BAR0LMPA, 0);
- out_le32(mbase + PECFG_PIM0LAL, 0x00000000);
- out_le32(mbase + PECFG_PIM0LAH, 0x00000004); /* pointing to SRAM */
+
+ out_le32(mbase + PECFG_PIM01SAH, 0xffffffff);
+ out_le32(mbase + PECFG_PIM01SAL, 0xfc000000);
+
+ /* Setup BAR0 */
+ out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffff);
+ out_le32(mbase + PECFG_BAR0LMPA, 0xfc000000 | PCI_BASE_ADDRESS_MEM_TYPE_64);
+
+ /* Disable BAR1 & BAR2 */
+ out_le32(mbase + PECFG_BAR1MPA, 0);
+ out_le32(mbase + PECFG_BAR2HMPA, 0);
+ out_le32(mbase + PECFG_BAR2LMPA, 0);
+
+ out_le32(mbase + PECFG_PIM0LAL, U64_TO_U32_LOW(CFG_PCIE_INBOUND_BASE));
+ out_le32(mbase + PECFG_PIM0LAH, U64_TO_U32_HIGH(CFG_PCIE_INBOUND_BASE));
out_le32(mbase + PECFG_PIMEN, 0x1);
/* Enable I/O, Mem, and Busmaster cycles */
out_le16((u16 *)(mbase + PCI_COMMAND),
- in_le16((u16 *)(mbase + PCI_COMMAND)) |
- PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
- out_le16(mbase + 0x200,0xcaad); /* Setting vendor ID */
- out_le16(mbase + 0x202,0xfeed); /* Setting device ID */
+ in_le16((u16 *)(mbase + PCI_COMMAND)) |
+ PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+ out_le16(mbase + 0x200, 0xcaad); /* Setting vendor ID */
+ out_le16(mbase + 0x202, 0xfeed); /* Setting device ID */
+
+ /* Set Class Code to Processor/PPC */
+ out_le32(mbase + 0x208, 0x0b200001);
+
attempts = 10;
- switch (port) {
- case 0:
- while (!(SDR_READ(PESDR0_RCSSTS) & (1 << 8))) {
- if (!(attempts--)) {
- printf("PCIE0: BMEN is not active\n");
- return -1;
- }
- mdelay(1000);
- }
- break;
- case 1:
- while (!(SDR_READ(PESDR1_RCSSTS) & (1 << 8))) {
- if (!(attempts--)) {
- printf("PCIE1: BMEN is not active\n");
- return -1;
- }
- mdelay(1000);
- }
- break;
- case 2:
- while (!(SDR_READ(PESDR2_RCSSTS) & (1 << 8))) {
- if (!(attempts--)) {
- printf("PCIE2: BMEN is not active\n");
- return -1;
- }
- mdelay(1000);
+ while(!(SDR_READ(SDRN_PESDR_RCSSTS(port)) & (1 << 8))) {
+ if (!(attempts--)) {
+ printf("PCIE%d: BME not active\n", port);
+ return -1;
}
- break;
+ mdelay(1000);
}
- printf("PCIE:%d successfully set as endpoint\n",port);
+
+ printf("PCIE%d: successfully set as endpoint\n", port);
return 0;
}
diff --git a/cpu/ppc4xx/serial.c b/cpu/ppc4xx/4xx_uart.c
index 60712b151e..3d1124e0b2 100644
--- a/cpu/ppc4xx/serial.c
+++ b/cpu/ppc4xx/4xx_uart.c
@@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
-/*------------------------------------------------------------------------------+ */
+
/*
* This source code has been made available to you by IBM on an AS-IS
* basis. Anyone receiving this source is licensed under IBM
@@ -40,16 +40,13 @@
* COPYRIGHT I B M CORPORATION 1995
* LICENSED MATERIAL - PROGRAM PROPERTY OF I B M
*/
-/*------------------------------------------------------------------------------- */
-/*
- * Travis Sawyer 15 September 2004
- * Added CONFIG_SERIAL_MULTI support
- */
+
#include <common.h>
#include <commproc.h>
#include <asm/processor.h>
+#include <asm/io.h>
#include <watchdog.h>
-#include "vecnum.h"
+#include <asm/ppc4xx-intvec.h>
#ifdef CONFIG_SERIAL_MULTI
#include <serial.h>
@@ -61,212 +58,9 @@
DECLARE_GLOBAL_DATA_PTR;
-/*****************************************************************************/
-#ifdef CONFIG_IOP480
-
-#define SPU_BASE 0x40000000
-
-#define spu_LineStat_rc 0x00 /* Line Status Register (Read/Clear) */
-#define spu_LineStat_w 0x04 /* Line Status Register (Set) */
-#define spu_Handshk_rc 0x08 /* Handshake Status Register (Read/Clear) */
-#define spu_Handshk_w 0x0c /* Handshake Status Register (Set) */
-#define spu_BRateDivh 0x10 /* Baud rate divisor high */
-#define spu_BRateDivl 0x14 /* Baud rate divisor low */
-#define spu_CtlReg 0x18 /* Control Register */
-#define spu_RxCmd 0x1c /* Rx Command Register */
-#define spu_TxCmd 0x20 /* Tx Command Register */
-#define spu_RxBuff 0x24 /* Rx data buffer */
-#define spu_TxBuff 0x24 /* Tx data buffer */
-
-/*-----------------------------------------------------------------------------+
- | Line Status Register.
- +-----------------------------------------------------------------------------*/
-#define asyncLSRport1 0x40000000
-#define asyncLSRport1set 0x40000004
-#define asyncLSRDataReady 0x80
-#define asyncLSRFramingError 0x40
-#define asyncLSROverrunError 0x20
-#define asyncLSRParityError 0x10
-#define asyncLSRBreakInterrupt 0x08
-#define asyncLSRTxHoldEmpty 0x04
-#define asyncLSRTxShiftEmpty 0x02
-
-/*-----------------------------------------------------------------------------+
- | Handshake Status Register.
- +-----------------------------------------------------------------------------*/
-#define asyncHSRport1 0x40000008
-#define asyncHSRport1set 0x4000000c
-#define asyncHSRDsr 0x80
-#define asyncLSRCts 0x40
-
-/*-----------------------------------------------------------------------------+
- | Control Register.
- +-----------------------------------------------------------------------------*/
-#define asyncCRport1 0x40000018
-#define asyncCRNormal 0x00
-#define asyncCRLoopback 0x40
-#define asyncCRAutoEcho 0x80
-#define asyncCRDtr 0x20
-#define asyncCRRts 0x10
-#define asyncCRWordLength7 0x00
-#define asyncCRWordLength8 0x08
-#define asyncCRParityDisable 0x00
-#define asyncCRParityEnable 0x04
-#define asyncCREvenParity 0x00
-#define asyncCROddParity 0x02
-#define asyncCRStopBitsOne 0x00
-#define asyncCRStopBitsTwo 0x01
-#define asyncCRDisableDtrRts 0x00
-
-/*-----------------------------------------------------------------------------+
- | Receiver Command Register.
- +-----------------------------------------------------------------------------*/
-#define asyncRCRport1 0x4000001c
-#define asyncRCRDisable 0x00
-#define asyncRCREnable 0x80
-#define asyncRCRIntDisable 0x00
-#define asyncRCRIntEnabled 0x20
-#define asyncRCRDMACh2 0x40
-#define asyncRCRDMACh3 0x60
-#define asyncRCRErrorInt 0x10
-#define asyncRCRPauseEnable 0x08
-
-/*-----------------------------------------------------------------------------+
- | Transmitter Command Register.
- +-----------------------------------------------------------------------------*/
-#define asyncTCRport1 0x40000020
-#define asyncTCRDisable 0x00
-#define asyncTCREnable 0x80
-#define asyncTCRIntDisable 0x00
-#define asyncTCRIntEnabled 0x20
-#define asyncTCRDMACh2 0x40
-#define asyncTCRDMACh3 0x60
-#define asyncTCRTxEmpty 0x10
-#define asyncTCRErrorInt 0x08
-#define asyncTCRStopPause 0x04
-#define asyncTCRBreakGen 0x02
-
-/*-----------------------------------------------------------------------------+
- | Miscellanies defines.
- +-----------------------------------------------------------------------------*/
-#define asyncTxBufferport1 0x40000024
-#define asyncRxBufferport1 0x40000024
-#define asyncDLABLsbport1 0x40000014
-#define asyncDLABMsbport1 0x40000010
-#define asyncXOFFchar 0x13
-#define asyncXONchar 0x11
-
-/*
- * Minimal serial functions needed to use one of the SMC ports
- * as serial console interface.
- */
-
-int serial_init (void)
-{
- volatile char val;
- unsigned short br_reg;
-
- br_reg = ((((CONFIG_CPUCLOCK * 1000000) / 16) / gd->baudrate) - 1);
-
- /*
- * Init onboard UART
- */
- out8 (SPU_BASE + spu_LineStat_rc, 0x78); /* Clear all bits in Line Status Reg */
- out8 (SPU_BASE + spu_BRateDivl, (br_reg & 0x00ff)); /* Set baud rate divisor... */
- out8 (SPU_BASE + spu_BRateDivh, ((br_reg & 0xff00) >> 8)); /* ... */
- out8 (SPU_BASE + spu_CtlReg, 0x08); /* Set 8 bits, no parity and 1 stop bit */
- out8 (SPU_BASE + spu_RxCmd, 0xb0); /* Enable Rx */
- out8 (SPU_BASE + spu_TxCmd, 0x9c); /* Enable Tx */
- out8 (SPU_BASE + spu_Handshk_rc, 0xff); /* Clear Handshake */
- val = in8 (SPU_BASE + spu_RxBuff); /* Dummy read, to clear receiver */
-
- return (0);
-}
-
-void serial_setbrg (void)
-{
- unsigned short br_reg;
-
- br_reg = ((((CONFIG_CPUCLOCK * 1000000) / 16) / gd->baudrate) - 1);
-
- out8 (SPU_BASE + spu_BRateDivl, (br_reg & 0x00ff)); /* Set baud rate divisor... */
- out8 (SPU_BASE + spu_BRateDivh, ((br_reg & 0xff00) >> 8)); /* ... */
-}
-
-void serial_putc (const char c)
-{
- if (c == '\n')
- serial_putc ('\r');
-
- /* load status from handshake register */
- if (in8 (SPU_BASE + spu_Handshk_rc) != 00)
- out8 (SPU_BASE + spu_Handshk_rc, 0xff); /* Clear Handshake */
-
- out8 (SPU_BASE + spu_TxBuff, c); /* Put char */
-
- while ((in8 (SPU_BASE + spu_LineStat_rc) & 04) != 04) {
- if (in8 (SPU_BASE + spu_Handshk_rc) != 00)
- out8 (SPU_BASE + spu_Handshk_rc, 0xff); /* Clear Handshake */
- }
-}
-
-void serial_puts (const char *s)
-{
- while (*s) {
- serial_putc (*s++);
- }
-}
-
-int serial_getc ()
-{
- unsigned char status = 0;
-
- while (1) {
- status = in8 (asyncLSRport1);
- if ((status & asyncLSRDataReady) != 0x0) {
- break;
- }
- if ((status & ( asyncLSRFramingError |
- asyncLSROverrunError |
- asyncLSRParityError |
- asyncLSRBreakInterrupt )) != 0) {
- (void) out8 (asyncLSRport1,
- asyncLSRFramingError |
- asyncLSROverrunError |
- asyncLSRParityError |
- asyncLSRBreakInterrupt );
- }
- }
- return (0x000000ff & (int) in8 (asyncRxBufferport1));
-}
-
-int serial_tstc ()
-{
- unsigned char status;
-
- status = in8 (asyncLSRport1);
- if ((status & asyncLSRDataReady) != 0x0) {
- return (1);
- }
- if ((status & ( asyncLSRFramingError |
- asyncLSROverrunError |
- asyncLSRParityError |
- asyncLSRBreakInterrupt )) != 0) {
- (void) out8 (asyncLSRport1,
- asyncLSRFramingError |
- asyncLSROverrunError |
- asyncLSRParityError |
- asyncLSRBreakInterrupt);
- }
- return 0;
-}
-
-#endif /* CONFIG_IOP480 */
-
-/*****************************************************************************/
#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \
- defined(CONFIG_440)
+ defined(CONFIG_405EX) || defined(CONFIG_440)
#if defined(CONFIG_440)
#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
@@ -318,6 +112,15 @@ int serial_tstc ()
#define UCR0_UDIV_POS 0
#define UCR1_UDIV_POS 8
#define UDIV_MAX 127
+#elif defined(CONFIG_405EX)
+#define UART0_BASE 0xef600200
+#define UART1_BASE 0xef600300
+#define CR0_MASK 0x000000ff
+#define CR0_EXTCLK_ENA 0x00800000
+#define CR0_UDIV_POS 0
+#define UDIV_SUBTRACT 0
+#define UART0_SDR sdr_uart0
+#define UART1_SDR sdr_uart1
#else /* CONFIG_405GP || CONFIG_405CR */
#define UART0_BASE 0xef600300
#define UART1_BASE 0xef600400
@@ -336,12 +139,6 @@ int serial_tstc ()
#define ACTING_UART1_BASE UART1_BASE
#endif
-#if defined(CONFIG_SERIAL_MULTI)
-#define UART_BASE dev_base
-#else
-#define UART_BASE ACTING_UART0_BASE
-#endif
-
#if defined(CONFIG_405EP) && defined(CFG_EXT_SERIAL_CLOCK)
#error "External serial clock not supported on AMCC PPC405EP!"
#endif
@@ -362,7 +159,6 @@ int serial_tstc ()
/*-----------------------------------------------------------------------------+
| Line Status Register.
+-----------------------------------------------------------------------------*/
-/*#define asyncLSRport1 ACTING_UART0_BASE+0x05 */
#define asyncLSRDataReady1 0x01
#define asyncLSROverrunError1 0x02
#define asyncLSRParityError1 0x04
@@ -372,12 +168,6 @@ int serial_tstc ()
#define asyncLSRTxShiftEmpty1 0x40
#define asyncLSRRxFifoError1 0x80
-/*-----------------------------------------------------------------------------+
- | Miscellanies defines.
- +-----------------------------------------------------------------------------*/
-/*#define asyncTxBufferport1 ACTING_UART0_BASE+0x00 */
-/*#define asyncRxBufferport1 ACTING_UART0_BASE+0x00 */
-
#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
/*-----------------------------------------------------------------------------+
| Fifo
@@ -391,7 +181,36 @@ typedef struct {
volatile static serial_buffer_t buf_info;
#endif
-#if defined(CONFIG_440) && !defined(CFG_EXT_SERIAL_CLOCK)
+static void serial_init_common(u32 base, u32 udiv, u16 bdiv)
+{
+ PPC4xx_SYS_INFO sys_info;
+ u8 val;
+
+ get_sys_info(&sys_info);
+
+ /* Correct UART frequency in bd-info struct now that
+ * the UART divisor is available
+ */
+#ifdef CFG_EXT_SERIAL_CLOCK
+ gd->uart_clk = CFG_EXT_SERIAL_CLOCK;
+#else
+ gd->uart_clk = sys_info.freqUART / udiv;
+#endif
+
+ out_8((u8 *)base + UART_LCR, 0x80); /* set DLAB bit */
+ out_8((u8 *)base + UART_DLL, bdiv); /* set baudrate divisor */
+ out_8((u8 *)base + UART_DLM, bdiv >> 8); /* set baudrate divisor */
+ out_8((u8 *)base + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
+ out_8((u8 *)base + UART_FCR, 0x00); /* disable FIFO */
+ out_8((u8 *)base + UART_MCR, 0x00); /* no modem control DTR RTS */
+ val = in_8((u8 *)base + UART_LSR); /* clear line status */
+ val = in_8((u8 *)base + UART_RBR); /* read receive buffer */
+ out_8((u8 *)base + UART_SCR, 0x00); /* set scratchpad */
+ out_8((u8 *)base + UART_IER, 0x00); /* set interrupt enable reg */
+}
+
+#if (defined(CONFIG_440) || defined(CONFIG_405EX)) && \
+ !defined(CFG_EXT_SERIAL_CLOCK)
static void serial_divs (int baudrate, unsigned long *pudiv,
unsigned short *pbdiv)
{
@@ -457,8 +276,8 @@ static void serial_divs (int baudrate, unsigned long *pudiv,
get_sys_info(&sysinfo);
plloutb = ((CONFIG_SYS_CLK_FREQ * ((cpr_pllc & PLLC_SRC_MASK) ?
- sysinfo.pllFwdDivB : sysinfo.pllFwdDiv) * sysinfo.pllFbkDiv) /
- sysinfo.pllFwdDivB);
+ sysinfo.pllFwdDivB : sysinfo.pllFwdDiv) *
+ sysinfo.pllFbkDiv) / sysinfo.pllFwdDivB);
udiv = 256; /* Assume lowest possible serial clk */
div = plloutb / (16 * baudrate); /* total divisor */
umin = (plloutb / get_OPB_freq()) << 1; /* 2 x OPB divisor */
@@ -496,16 +315,11 @@ static void serial_divs (int baudrate, unsigned long *pudiv,
*/
#if defined(CONFIG_440)
-#if defined(CONFIG_SERIAL_MULTI)
-int serial_init_dev (unsigned long dev_base)
-#else
-int serial_init(void)
-#endif
+int serial_init_dev(unsigned long base)
{
unsigned long reg;
unsigned long udiv;
unsigned short bdiv;
- volatile char val;
#ifdef CFG_EXT_SERIAL_CLOCK
unsigned long tmp;
#endif
@@ -543,36 +357,46 @@ int serial_init(void)
MTREG(UART3_SDR, reg);
#endif
- out8(UART_BASE + UART_LCR, 0x80); /* set DLAB bit */
- out8(UART_BASE + UART_DLL, bdiv); /* set baudrate divisor */
- out8(UART_BASE + UART_DLM, bdiv >> 8); /* set baudrate divisor */
- out8(UART_BASE + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
- out8(UART_BASE + UART_FCR, 0x00); /* disable FIFO */
- out8(UART_BASE + UART_MCR, 0x00); /* no modem control DTR RTS */
- val = in8(UART_BASE + UART_LSR); /* clear line status */
- val = in8(UART_BASE + UART_RBR); /* read receive buffer */
- out8(UART_BASE + UART_SCR, 0x00); /* set scratchpad */
- out8(UART_BASE + UART_IER, 0x00); /* set interrupt enable reg */
+ serial_init_common(base, udiv, bdiv);
return (0);
}
#else /* !defined(CONFIG_440) */
-#if defined(CONFIG_SERIAL_MULTI)
-int serial_init_dev (unsigned long dev_base)
-#else
-int serial_init (void)
-#endif
+int serial_init_dev (unsigned long base)
{
unsigned long reg;
unsigned long tmp;
unsigned long clk;
unsigned long udiv;
unsigned short bdiv;
- volatile char val;
-#if defined(CONFIG_405EZ)
+#ifdef CONFIG_405EX
+ clk = tmp = 0;
+ mfsdr(UART0_SDR, reg);
+ reg &= ~CR0_MASK;
+#ifdef CFG_EXT_SERIAL_CLOCK
+ reg |= CR0_EXTCLK_ENA;
+ udiv = 1;
+ tmp = gd->baudrate * 16;
+ bdiv = (CFG_EXT_SERIAL_CLOCK + tmp / 2) / tmp;
+#else
+ serial_divs(gd->baudrate, &udiv, &bdiv);
+#endif
+ reg |= (udiv - UDIV_SUBTRACT) << CR0_UDIV_POS; /* set the UART divisor */
+
+ /*
+ * Configure input clock to baudrate generator for all
+ * available serial ports here
+ */
+ mtsdr(UART0_SDR, reg);
+
+#if defined(UART1_SDR)
+ mtsdr(UART1_SDR, reg);
+#endif
+
+#elif defined(CONFIG_405EZ)
serial_divs(gd->baudrate, &udiv, &bdiv);
clk = tmp = reg = 0;
#else
@@ -608,81 +432,44 @@ int serial_init (void)
#endif /* CONFIG_405EP */
tmp = gd->baudrate * udiv * 16;
bdiv = (clk + tmp / 2) / tmp;
-#endif /* CONFIG_405EZ */
-
- out8(UART_BASE + UART_LCR, 0x80); /* set DLAB bit */
- out8(UART_BASE + UART_DLL, bdiv); /* set baudrate divisor */
- out8(UART_BASE + UART_DLM, bdiv >> 8); /* set baudrate divisor */
- out8(UART_BASE + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
- out8(UART_BASE + UART_FCR, 0x00); /* disable FIFO */
- out8(UART_BASE + UART_MCR, 0x00); /* no modem control DTR RTS */
- val = in8(UART_BASE + UART_LSR); /* clear line status */
- val = in8(UART_BASE + UART_RBR); /* read receive buffer */
- out8(UART_BASE + UART_SCR, 0x00); /* set scratchpad */
- out8(UART_BASE + UART_IER, 0x00); /* set interrupt enable reg */
+#endif /* CONFIG_405EX */
+
+ serial_init_common(base, udiv, bdiv);
return (0);
}
#endif /* if defined(CONFIG_440) */
-#if defined(CONFIG_SERIAL_MULTI)
-void serial_setbrg_dev (unsigned long dev_base)
-#else
-void serial_setbrg (void)
-#endif
+void serial_setbrg_dev(unsigned long base)
{
-#if defined(CONFIG_SERIAL_MULTI)
- serial_init_dev(dev_base);
-#else
- serial_init();
-#endif
+ serial_init_dev(base);
}
-#if defined(CONFIG_SERIAL_MULTI)
-void serial_putc_dev (unsigned long dev_base, const char c)
-#else
-void serial_putc (const char c)
-#endif
+void serial_putc_dev(unsigned long base, const char c)
{
int i;
if (c == '\n')
-#if defined(CONFIG_SERIAL_MULTI)
- serial_putc_dev (dev_base, '\r');
-#else
- serial_putc ('\r');
-#endif
+ serial_putc_dev(base, '\r');
/* check THRE bit, wait for transmiter available */
for (i = 1; i < 3500; i++) {
- if ((in8 (UART_BASE + UART_LSR) & 0x20) == 0x20)
+ if ((in_8((u8 *)base + UART_LSR) & 0x20) == 0x20)
break;
udelay (100);
}
- out8 (UART_BASE + UART_THR, c); /* put character out */
+
+ out_8((u8 *)base + UART_THR, c); /* put character out */
}
-#if defined(CONFIG_SERIAL_MULTI)
-void serial_puts_dev (unsigned long dev_base, const char *s)
-#else
-void serial_puts (const char *s)
-#endif
+void serial_puts_dev (unsigned long base, const char *s)
{
- while (*s) {
-#if defined(CONFIG_SERIAL_MULTI)
- serial_putc_dev (dev_base, *s++);
-#else
- serial_putc (*s++);
-#endif
- }
+ while (*s)
+ serial_putc_dev (base, *s++);
}
-#if defined(CONFIG_SERIAL_MULTI)
-int serial_getc_dev (unsigned long dev_base)
-#else
-int serial_getc (void)
-#endif
+int serial_getc_dev (unsigned long base)
{
unsigned char status = 0;
@@ -690,46 +477,45 @@ int serial_getc (void)
#if defined(CONFIG_HW_WATCHDOG)
WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */
#endif /* CONFIG_HW_WATCHDOG */
- status = in8 (UART_BASE + UART_LSR);
- if ((status & asyncLSRDataReady1) != 0x0) {
+
+ status = in_8((u8 *)base + UART_LSR);
+ if ((status & asyncLSRDataReady1) != 0x0)
break;
- }
+
if ((status & ( asyncLSRFramingError1 |
asyncLSROverrunError1 |
asyncLSRParityError1 |
asyncLSRBreakInterrupt1 )) != 0) {
- out8 (UART_BASE + UART_LSR,
+ out_8((u8 *)base + UART_LSR,
asyncLSRFramingError1 |
asyncLSROverrunError1 |
asyncLSRParityError1 |
asyncLSRBreakInterrupt1);
}
}
- return (0x000000ff & (int) in8 (UART_BASE));
+
+ return (0x000000ff & (int) in_8((u8 *)base));
}
-#if defined(CONFIG_SERIAL_MULTI)
-int serial_tstc_dev (unsigned long dev_base)
-#else
-int serial_tstc (void)
-#endif
+int serial_tstc_dev (unsigned long base)
{
unsigned char status;
- status = in8 (UART_BASE + UART_LSR);
- if ((status & asyncLSRDataReady1) != 0x0) {
+ status = in_8((u8 *)base + UART_LSR);
+ if ((status & asyncLSRDataReady1) != 0x0)
return (1);
- }
+
if ((status & ( asyncLSRFramingError1 |
asyncLSROverrunError1 |
asyncLSRParityError1 |
asyncLSRBreakInterrupt1 )) != 0) {
- out8 (UART_BASE + UART_LSR,
+ out_8((u8 *)base + UART_LSR,
asyncLSRFramingError1 |
asyncLSROverrunError1 |
asyncLSRParityError1 |
asyncLSRBreakInterrupt1);
}
+
return 0;
}
@@ -742,11 +528,11 @@ void serial_isr (void *arg)
const int rx_get = buf_info.rx_get;
int rx_put = buf_info.rx_put;
- if (rx_get <= rx_put) {
+ if (rx_get <= rx_put)
space = CONFIG_SERIAL_SOFTWARE_FIFO - (rx_put - rx_get);
- } else {
+ else
space = rx_get - rx_put;
- }
+
while (serial_tstc_dev (ACTING_UART0_BASE)) {
c = serial_getc_dev (ACTING_UART0_BASE);
if (space) {
@@ -757,8 +543,9 @@ void serial_isr (void *arg)
rx_put = 0;
if (space < CONFIG_SERIAL_SOFTWARE_FIFO / 4) {
/* Stop flow by setting RTS inactive */
- out8 (ACTING_UART0_BASE + UART_MCR,
- in8 (ACTING_UART0_BASE + UART_MCR) & (0xFF ^ 0x02));
+ out_8((u8 *)ACTING_UART0_BASE + UART_MCR,
+ in_8((u8 *)ACTING_UART0_BASE + UART_MCR) &
+ (0xFF ^ 0x02));
}
}
buf_info.rx_put = rx_put;
@@ -771,35 +558,35 @@ void serial_buffered_init (void)
buf_info.rx_put = 0;
buf_info.rx_get = 0;
- if (in8 (ACTING_UART0_BASE + UART_MSR) & 0x10) {
+ if (in_8((u8 *)ACTING_UART0_BASE + UART_MSR) & 0x10)
serial_puts ("Check CTS signal present on serial port: OK.\n");
- } else {
+ else
serial_puts ("WARNING: CTS signal not present on serial port.\n");
- }
irq_install_handler ( VECNUM_U0 /*UART0 */ /*int vec */ ,
serial_isr /*interrupt_handler_t *handler */ ,
(void *) &buf_info /*void *arg */ );
/* Enable "RX Data Available" Interrupt on UART */
- /* out8(ACTING_UART0_BASE + UART_IER, in8(ACTING_UART0_BASE + UART_IER) |0x01); */
- out8 (ACTING_UART0_BASE + UART_IER, 0x01);
+ out_8(ACTING_UART0_BASE + UART_IER, 0x01);
/* Set DTR active */
- out8 (ACTING_UART0_BASE + UART_MCR, in8 (ACTING_UART0_BASE + UART_MCR) | 0x01);
+ out_8(ACTING_UART0_BASE + UART_MCR,
+ in_8((u8 *)ACTING_UART0_BASE + UART_MCR) | 0x01);
/* Start flow by setting RTS active */
- out8 (ACTING_UART0_BASE + UART_MCR, in8 (ACTING_UART0_BASE + UART_MCR) | 0x02);
+ out_8(ACTING_UART0_BASE + UART_MCR,
+ in_8((u8 *)ACTING_UART0_BASE + UART_MCR) | 0x02);
/* Setup UART FIFO: RX trigger level: 4 byte, Enable FIFO */
- out8 (ACTING_UART0_BASE + UART_FCR, (1 << 6) | 1);
+ out_8(ACTING_UART0_BASE + UART_FCR, (1 << 6) | 1);
}
void serial_buffered_putc (const char c)
{
/* Wait for CTS */
#if defined(CONFIG_HW_WATCHDOG)
- while (!(in8 (ACTING_UART0_BASE + UART_MSR) & 0x10))
+ while (!(in_8((u8 *)ACTING_UART0_BASE + UART_MSR) & 0x10))
WATCHDOG_RESET ();
#else
- while (!(in8 (ACTING_UART0_BASE + UART_MSR) & 0x10));
+ while (!(in_8((u8 *)ACTING_UART0_BASE + UART_MSR) & 0x10));
#endif
serial_putc (c);
}
@@ -828,14 +615,15 @@ int serial_buffered_getc (void)
buf_info.rx_get = rx_get;
rx_put = buf_info.rx_put;
- if (rx_get <= rx_put) {
+ if (rx_get <= rx_put)
space = CONFIG_SERIAL_SOFTWARE_FIFO - (rx_put - rx_get);
- } else {
+ else
space = rx_get - rx_put;
- }
+
if (space > CONFIG_SERIAL_SOFTWARE_FIFO / 2) {
/* Start flow by setting RTS active */
- out8 (ACTING_UART0_BASE + UART_MCR, in8 (ACTING_UART0_BASE + UART_MCR) | 0x02);
+ out_8(ACTING_UART0_BASE + UART_MCR,
+ in_8((u8 *)ACTING_UART0_BASE + UART_MCR) | 0x02);
}
return c;
@@ -860,8 +648,8 @@ int serial_buffered_tstc (void)
#if (CONFIG_KGDB_SER_INDEX & 2)
void kgdb_serial_init (void)
{
- volatile char val;
- unsigned short br_reg;
+ u8 val;
+ u16 br_reg;
get_clocks ();
br_reg = (((((gd->cpu_clk / 16) / 18) * 10) / CONFIG_KGDB_BAUDRATE) +
@@ -869,16 +657,16 @@ void kgdb_serial_init (void)
/*
* Init onboard 16550 UART
*/
- out8 (ACTING_UART1_BASE + UART_LCR, 0x80); /* set DLAB bit */
- out8 (ACTING_UART1_BASE + UART_DLL, (br_reg & 0x00ff)); /* set divisor for 9600 baud */
- out8 (ACTING_UART1_BASE + UART_DLM, ((br_reg & 0xff00) >> 8)); /* set divisor for 9600 baud */
- out8 (ACTING_UART1_BASE + UART_LCR, 0x03); /* line control 8 bits no parity */
- out8 (ACTING_UART1_BASE + UART_FCR, 0x00); /* disable FIFO */
- out8 (ACTING_UART1_BASE + UART_MCR, 0x00); /* no modem control DTR RTS */
- val = in8 (ACTING_UART1_BASE + UART_LSR); /* clear line status */
- val = in8 (ACTING_UART1_BASE + UART_RBR); /* read receive buffer */
- out8 (ACTING_UART1_BASE + UART_SCR, 0x00); /* set scratchpad */
- out8 (ACTING_UART1_BASE + UART_IER, 0x00); /* set interrupt enable reg */
+ out_8((u8 *)ACTING_UART1_BASE + UART_LCR, 0x80); /* set DLAB bit */
+ out_8((u8 *)ACTING_UART1_BASE + UART_DLL, (br_reg & 0x00ff)); /* set divisor for 9600 baud */
+ out_8((u8 *)ACTING_UART1_BASE + UART_DLM, ((br_reg & 0xff00) >> 8)); /* set divisor for 9600 baud */
+ out_8((u8 *)ACTING_UART1_BASE + UART_LCR, 0x03); /* line control 8 bits no parity */
+ out_8((u8 *)ACTING_UART1_BASE + UART_FCR, 0x00); /* disable FIFO */
+ out_8((u8 *)ACTING_UART1_BASE + UART_MCR, 0x00); /* no modem control DTR RTS */
+ val = in_8((u8 *)ACTING_UART1_BASE + UART_LSR); /* clear line status */
+ val = in_8((u8 *)ACTING_UART1_BASE + UART_RBR); /* read receive buffer */
+ out_8((u8 *)ACTING_UART1_BASE + UART_SCR, 0x00); /* set scratchpad */
+ out_8((u8 *)ACTING_UART1_BASE + UART_IER, 0x00); /* set interrupt enable reg */
}
void putDebugChar (const char c)
@@ -886,17 +674,16 @@ void putDebugChar (const char c)
if (c == '\n')
serial_putc ('\r');
- out8 (ACTING_UART1_BASE + UART_THR, c); /* put character out */
+ out_8((u8 *)ACTING_UART1_BASE + UART_THR, c); /* put character out */
/* check THRE bit, wait for transfer done */
- while ((in8 (ACTING_UART1_BASE + UART_LSR) & 0x20) != 0x20);
+ while ((in_8((u8 *)ACTING_UART1_BASE + UART_LSR) & 0x20) != 0x20);
}
void putDebugStr (const char *s)
{
- while (*s) {
+ while (*s)
serial_putc (*s++);
- }
}
int getDebugChar (void)
@@ -904,22 +691,23 @@ int getDebugChar (void)
unsigned char status = 0;
while (1) {
- status = in8 (ACTING_UART1_BASE + UART_LSR);
- if ((status & asyncLSRDataReady1) != 0x0) {
+ status = in_8((u8 *)ACTING_UART1_BASE + UART_LSR);
+ if ((status & asyncLSRDataReady1) != 0x0)
break;
- }
- if ((status & ( asyncLSRFramingError1 |
- asyncLSROverrunError1 |
- asyncLSRParityError1 |
- asyncLSRBreakInterrupt1 )) != 0) {
- out8 (ACTING_UART1_BASE + UART_LSR,
+
+ if ((status & (asyncLSRFramingError1 |
+ asyncLSROverrunError1 |
+ asyncLSRParityError1 |
+ asyncLSRBreakInterrupt1 )) != 0) {
+ out_8((u8 *)ACTING_UART1_BASE + UART_LSR,
asyncLSRFramingError1 |
asyncLSROverrunError1 |
asyncLSRParityError1 |
asyncLSRBreakInterrupt1);
}
}
- return (0x000000ff & (int) in8 (ACTING_UART1_BASE));
+
+ return (0x000000ff & (int) in_8((u8 *)ACTING_UART1_BASE));
}
void kgdb_interruptible (int yes)
@@ -967,10 +755,12 @@ int serial1_init(void)
{
return (serial_init_dev(UART1_BASE));
}
+
void serial0_setbrg (void)
{
serial_setbrg_dev(UART0_BASE);
}
+
void serial1_setbrg (void)
{
serial_setbrg_dev(UART1_BASE);
@@ -985,6 +775,7 @@ void serial1_putc(const char c)
{
serial_putc_dev(UART1_BASE, c);
}
+
void serial0_puts(const char *s)
{
serial_puts_dev(UART0_BASE, s);
@@ -1004,6 +795,7 @@ int serial1_getc(void)
{
return(serial_getc_dev(UART1_BASE));
}
+
int serial0_tstc(void)
{
return (serial_tstc_dev(UART0_BASE));
@@ -1037,6 +829,39 @@ struct serial_device serial1_device =
serial1_putc,
serial1_puts,
};
+#else
+/*
+ * Wrapper functions
+ */
+int serial_init(void)
+{
+ return serial_init_dev(ACTING_UART0_BASE);
+}
+
+void serial_setbrg(void)
+{
+ serial_setbrg_dev(ACTING_UART0_BASE);
+}
+
+void serial_putc(const char c)
+{
+ serial_putc_dev(ACTING_UART0_BASE, c);
+}
+
+void serial_puts(const char *s)
+{
+ serial_puts_dev(ACTING_UART0_BASE, s);
+}
+
+int serial_getc(void)
+{
+ return serial_getc_dev(ACTING_UART0_BASE);
+}
+
+int serial_tstc(void)
+{
+ return serial_tstc_dev(ACTING_UART0_BASE);
+}
#endif /* CONFIG_SERIAL_MULTI */
#endif /* CONFIG_405GP || CONFIG_405CR */
diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile
index af9da5b95f..178c5c6742 100644
--- a/cpu/ppc4xx/Makefile
+++ b/cpu/ppc4xx/Makefile
@@ -25,15 +25,40 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).a
-START = start.o resetvec.o kgdb.o
-SOBJS = dcr.o
-COBJS = 405gp_pci.o 440spe_pcie.o 4xx_enet.o \
- bedbug_405.o commproc.o \
- cpu.o cpu_init.o gpio.o i2c.o interrupts.o \
- miiphy.o ndfc.o sdram.o serial.o \
- 40x_spd_sdram.o 44x_spd_ddr.o 44x_spd_ddr2.o speed.o \
- tlb.o traps.o usb_ohci.o usb.o usbdev.o \
- 440spe_pcie.o
+START := resetvec.o
+START += start.o
+
+SOBJS := cache.o
+SOBJS += dcr.o
+SOBJS += kgdb.o
+
+COBJS := 40x_spd_sdram.o
+COBJS += 44x_spd_ddr.o
+COBJS += 44x_spd_ddr2.o
+COBJS += 4xx_enet.o
+COBJS += 4xx_pci.o
+COBJS += 4xx_pcie.o
+COBJS += 4xx_uart.o
+COBJS += bedbug_405.o
+COBJS += commproc.o
+COBJS += cpu.o
+COBJS += cpu_init.o
+COBJS += denali_data_eye.o
+COBJS += denali_spd_ddr2.o
+COBJS += fdt.o
+COBJS += gpio.o
+COBJS += i2c.o
+COBJS += interrupts.o
+COBJS += iop480_uart.o
+COBJS += miiphy.o
+COBJS += ndfc.o
+COBJS += sdram.o
+COBJS += speed.o
+COBJS += tlb.o
+COBJS += traps.o
+COBJS += usb.o
+COBJS += usb_ohci.o
+COBJS += usbdev.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/cpu/ppc4xx/cache.S b/cpu/ppc4xx/cache.S
new file mode 100644
index 0000000000..5124dec77f
--- /dev/null
+++ b/cpu/ppc4xx/cache.S
@@ -0,0 +1,233 @@
+/*
+ * This file contains miscellaneous low-level functions.
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras.
+ *
+ * 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.
+ *
+ */
+
+#include <config.h>
+#include <config.h>
+#include <ppc4xx.h>
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+/*
+ * Flush instruction cache.
+ */
+_GLOBAL(invalidate_icache)
+ iccci r0,r0
+ isync
+ blr
+
+/*
+ * Write any modified data cache blocks out to memory
+ * and invalidate the corresponding instruction cache blocks.
+ *
+ * flush_icache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(flush_icache_range)
+ li r5,L1_CACHE_BYTES-1
+ andc r3,r3,r5
+ subf r4,r3,r4
+ add r4,r4,r5
+ srwi. r4,r4,L1_CACHE_SHIFT
+ beqlr
+ mtctr r4
+ mr r6,r3
+1: dcbst 0,r3
+ addi r3,r3,L1_CACHE_BYTES
+ bdnz 1b
+ sync /* wait for dcbst's to get to ram */
+ mtctr r4
+2: icbi 0,r6
+ addi r6,r6,L1_CACHE_BYTES
+ bdnz 2b
+ sync /* additional sync needed on g4 */
+ isync
+ blr
+
+/*
+ * Write any modified data cache blocks out to memory.
+ * Does not invalidate the corresponding cache lines (especially for
+ * any corresponding instruction cache).
+ *
+ * clean_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(clean_dcache_range)
+ li r5,L1_CACHE_BYTES-1
+ andc r3,r3,r5
+ subf r4,r3,r4
+ add r4,r4,r5
+ srwi. r4,r4,L1_CACHE_SHIFT
+ beqlr
+ mtctr r4
+
+1: dcbst 0,r3
+ addi r3,r3,L1_CACHE_BYTES
+ bdnz 1b
+ sync /* wait for dcbst's to get to ram */
+ blr
+
+/*
+ * Write any modified data cache blocks out to memory and invalidate them.
+ * Does not invalidate the corresponding instruction cache blocks.
+ *
+ * flush_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(flush_dcache_range)
+ li r5,L1_CACHE_BYTES-1
+ andc r3,r3,r5
+ subf r4,r3,r4
+ add r4,r4,r5
+ srwi. r4,r4,L1_CACHE_SHIFT
+ beqlr
+ mtctr r4
+
+1: dcbf 0,r3
+ addi r3,r3,L1_CACHE_BYTES
+ bdnz 1b
+ sync /* wait for dcbst's to get to ram */
+ blr
+
+/*
+ * Like above, but invalidate the D-cache. This is used by the 8xx
+ * to invalidate the cache so the PPC core doesn't get stale data
+ * from the CPM (no cache snooping here :-).
+ *
+ * invalidate_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(invalidate_dcache_range)
+ li r5,L1_CACHE_BYTES-1
+ andc r3,r3,r5
+ subf r4,r3,r4
+ add r4,r4,r5
+ srwi. r4,r4,L1_CACHE_SHIFT
+ beqlr
+ mtctr r4
+
+1: dcbi 0,r3
+ addi r3,r3,L1_CACHE_BYTES
+ bdnz 1b
+ sync /* wait for dcbi's to get to ram */
+ blr
+
+/*
+ * 40x cores have 8K or 16K dcache and 32 byte line size.
+ * 44x has a 32K dcache and 32 byte line size.
+ * 8xx has 1, 2, 4, 8K variants.
+ * For now, cover the worst case of the 44x.
+ * Must be called with external interrupts disabled.
+ */
+#define CACHE_NWAYS 64
+#define CACHE_NLINES 32
+
+_GLOBAL(flush_dcache)
+ li r4,(2 * CACHE_NWAYS * CACHE_NLINES)
+ mtctr r4
+ lis r5,0
+1: lwz r3,0(r5) /* Load one word from every line */
+ addi r5,r5,L1_CACHE_BYTES
+ bdnz 1b
+ sync
+ blr
+
+_GLOBAL(invalidate_dcache)
+ addi r6,0,0x0000 /* clear GPR 6 */
+ /* Do loop for # of dcache congruence classes. */
+ lis r7,(CFG_DCACHE_SIZE / L1_CACHE_BYTES / 2)@ha /* TBS for large sized cache */
+ ori r7,r7,(CFG_DCACHE_SIZE / L1_CACHE_BYTES / 2)@l
+ /* NOTE: dccci invalidates both */
+ mtctr r7 /* ways in the D cache */
+..dcloop:
+ dccci 0,r6 /* invalidate line */
+ addi r6,r6,L1_CACHE_BYTES /* bump to next line */
+ bdnz ..dcloop
+ sync
+ blr
+
+/*
+ * Cache functions.
+ *
+ * NOTE: currently the 440s run with dcache _disabled_ once relocated to DRAM,
+ * although for some cache-ralated calls stubs have to be provided to satisfy
+ * symbols resolution.
+ * Icache-related functions are used in POST framework.
+ *
+ */
+#ifdef CONFIG_440
+
+ .globl dcache_disable
+ .globl icache_disable
+ .globl icache_enable
+dcache_disable:
+icache_disable:
+icache_enable:
+ blr
+
+ .globl dcache_status
+ .globl icache_status
+dcache_status:
+icache_status:
+ mr r3, 0
+ blr
+
+#else /* CONFIG_440 */
+
+ .globl icache_enable
+icache_enable:
+ mflr r8
+ bl invalidate_icache
+ mtlr r8
+ isync
+ addis r3,r0, 0xc000 /* set bit 0 */
+ mticcr r3
+ blr
+
+ .globl icache_disable
+icache_disable:
+ addis r3,r0, 0x0000 /* clear bit 0 */
+ mticcr r3
+ isync
+ blr
+
+ .globl icache_status
+icache_status:
+ mficcr r3
+ srwi r3, r3, 31 /* >>31 => select bit 0 */
+ blr
+
+ .globl dcache_enable
+dcache_enable:
+ mflr r8
+ bl invalidate_dcache
+ mtlr r8
+ isync
+ addis r3,r0, 0x8000 /* set bit 0 */
+ mtdccr r3
+ blr
+
+ .globl dcache_disable
+dcache_disable:
+ mflr r8
+ bl flush_dcache
+ mtlr r8
+ addis r3,r0, 0x0000 /* clear bit 0 */
+ mtdccr r3
+ blr
+
+ .globl dcache_status
+dcache_status:
+ mfdccr r3
+ srwi r3, r3, 31 /* >>31 => select bit 0 */
+ blr
+
+#endif /* CONFIG_440 */
diff --git a/cpu/ppc4xx/commproc.c b/cpu/ppc4xx/commproc.c
index 68aab5b7ea..22156dd9de 100644
--- a/cpu/ppc4xx/commproc.c
+++ b/cpu/ppc4xx/commproc.c
@@ -26,10 +26,21 @@
#include <common.h>
#include <commproc.h>
-
+#include <asm/io.h>
#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER)
+#if defined(CFG_POST_ALT_WORD_ADDR)
+void post_word_store (ulong a)
+{
+ out_be32((void *)CFG_POST_ALT_WORD_ADDR, a);
+}
+
+ulong post_word_load (void)
+{
+ return in_be32((void *)CFG_POST_ALT_WORD_ADDR);
+}
+#else /* CFG_POST_ALT_WORD_ADDR */
void post_word_store (ulong a)
{
volatile void *save_addr = (volatile void *)(CFG_OCM_DATA_ADDR + CFG_POST_WORD_ADDR);
@@ -41,6 +52,7 @@ ulong post_word_load (void)
volatile void *save_addr = (volatile void *)(CFG_OCM_DATA_ADDR + CFG_POST_WORD_ADDR);
return *(volatile ulong *) save_addr;
}
+#endif /* CFG_POST_ALT_WORD_ADDR */
#endif /* CONFIG_POST || CONFIG_LOGBUFFER*/
diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c
index c07bc0c325..9e9c685afe 100644
--- a/cpu/ppc4xx/cpu.c
+++ b/cpu/ppc4xx/cpu.c
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2000-2006
+ * (C) Copyright 2000-2007
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
@@ -37,22 +37,9 @@
#include <asm/cache.h>
#include <ppc4xx.h>
-#if !defined(CONFIG_405)
DECLARE_GLOBAL_DATA_PTR;
-#endif
-#if defined(CONFIG_BOARD_RESET)
void board_reset(void);
-#endif
-
-#if defined(CONFIG_440)
-#define FREQ_EBC (sys_info.freqEPB)
-#elif defined(CONFIG_405EZ)
-#define FREQ_EBC ((CONFIG_SYS_CLK_FREQ * sys_info.pllFbkDiv) / \
- sys_info.pllExtBusDiv)
-#else
-#define FREQ_EBC (sys_info.freqPLB / sys_info.pllExtBusDiv)
-#endif
#if defined(CONFIG_405GP) || \
defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
@@ -60,7 +47,7 @@ void board_reset(void);
#define PCI_ASYNC
-int pci_async_enabled(void)
+static int pci_async_enabled(void)
{
#if defined(CONFIG_405GP)
return (mfdcr(strap) & PSR_PCI_ASYNC_EN);
@@ -76,8 +63,9 @@ int pci_async_enabled(void)
}
#endif
-#if defined(CONFIG_PCI) && !defined(CONFIG_IOP480) && !defined(CONFIG_405)
-int pci_arbiter_enabled(void)
+#if defined(CONFIG_PCI) && !defined(CONFIG_IOP480) && \
+ !defined(CONFIG_405) && !defined(CONFIG_405EX)
+static int pci_arbiter_enabled(void)
{
#if defined(CONFIG_405GP)
return (mfdcr(strap) & PSR_PCI_ARBIT_EN);
@@ -107,14 +95,10 @@ int pci_arbiter_enabled(void)
}
#endif
-#if defined(CONFIG_405EP) || defined(CONFIG_440GX) || \
- defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
- defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
- defined(CONFIG_440SP) || defined(CONFIG_440SPE)
-
+#if defined(CONFIG_405EP)
#define I2C_BOOTROM
-int i2c_bootrom_enabled(void)
+static int i2c_bootrom_enabled(void)
{
#if defined(CONFIG_405EP)
return (mfdcr(cpc0_boot) & CPC0_BOOT_SEP);
@@ -207,6 +191,21 @@ static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', \
'I', 'x', 'K', 'L', 'M', 'N', 'O', 'P' };
#endif
+#if defined(CONFIG_405EX)
+#define SDR0_PINSTP_SHIFT 29
+static char *bootstrap_str[] = {
+ "EBC (8 bits)",
+ "EBC (16 bits)",
+ "EBC (16 bits)",
+ "NAND (8 bits)",
+ "NAND (8 bits)",
+ "I2C (Addr 0x54)",
+ "EBC (8 bits)",
+ "I2C (Addr 0x52)",
+};
+static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'G', 'F', 'H' };
+#endif
+
#if defined(SDR0_PINSTP_SHIFT)
static int bootstrap_option(void)
{
@@ -219,7 +218,19 @@ static int bootstrap_option(void)
#if defined(CONFIG_440)
-static int do_chip_reset(unsigned long sys0, unsigned long sys1);
+static int do_chip_reset (unsigned long sys0, unsigned long sys1)
+{
+ /* Changes to cpc0_sys0 and cpc0_sys1 require chip
+ * reset.
+ */
+ mtdcr (cntrl0, mfdcr (cntrl0) | 0x80000000); /* Set SWE */
+ mtdcr (cpc0_sys0, sys0);
+ mtdcr (cpc0_sys1, sys1);
+ mtdcr (cntrl0, mfdcr (cntrl0) & ~0x80000000); /* Clr SWE */
+ mtspr (dbcr0, 0x20000000); /* Reset the chip */
+
+ return 1;
+}
#endif
@@ -241,7 +252,8 @@ int checkcpu (void)
puts("AMCC PowerPC 4");
#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
- defined(CONFIG_405EP) || defined(CONFIG_405EZ)
+ defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \
+ defined(CONFIG_405EX)
puts("05");
#endif
#if defined(CONFIG_440)
@@ -293,6 +305,26 @@ int checkcpu (void)
puts("EZ Rev. A");
break;
+ case PVR_405EX1_RA:
+ puts("EX Rev. A");
+ strcpy(addstr, "Security support");
+ break;
+
+ case PVR_405EX2_RA:
+ puts("EX Rev. A");
+ strcpy(addstr, "No Security support");
+ break;
+
+ case PVR_405EXR1_RA:
+ puts("EXr Rev. A");
+ strcpy(addstr, "Security support");
+ break;
+
+ case PVR_405EXR2_RA:
+ puts("EXr Rev. A");
+ strcpy(addstr, "No Security support");
+ break;
+
#if defined(CONFIG_440)
case PVR_440GP_RB:
puts("GP Rev. B");
@@ -424,7 +456,7 @@ int checkcpu (void)
printf (" at %s MHz (PLB=%lu, OPB=%lu, EBC=%lu MHz)\n", strmhz(buf, clock),
sys_info.freqPLB / 1000000,
get_OPB_freq() / 1000000,
- FREQ_EBC / 1000000);
+ sys_info.freqEBC / 1000000);
if (addstr[0] != 0)
printf(" %s\n", addstr);
@@ -437,7 +469,7 @@ int checkcpu (void)
printf ("Boot ROM Location %s\n", bootstrap_str[bootstrap_option()]);
#endif /* SDR0_PINSTP_SHIFT */
-#if defined(CONFIG_PCI)
+#if defined(CONFIG_PCI) && !defined(CONFIG_405EX)
printf (" Internal PCI arbiter %sabled", pci_arbiter_enabled() ? "en" : "dis");
#endif
@@ -450,11 +482,11 @@ int checkcpu (void)
}
#endif
-#if defined(CONFIG_PCI)
+#if defined(CONFIG_PCI) && !defined(CONFIG_405EX)
putc('\n');
#endif
-#if defined(CONFIG_405EP) || defined(CONFIG_405EZ)
+#if defined(CONFIG_405EP) || defined(CONFIG_405EZ) || defined(CONFIG_405EX)
printf (" 16 kB I-Cache 16 kB D-Cache");
#elif defined(CONFIG_440)
printf (" 32 kB I-Cache 32 kB D-Cache");
@@ -478,7 +510,6 @@ int checkcpu (void)
return 0;
}
-#if defined (CONFIG_440SPE)
int ppc440spe_revB() {
unsigned int pvr;
@@ -488,7 +519,6 @@ int ppc440spe_revB() {
else
return 0;
}
-#endif
/* ------------------------------------------------------------------------- */
@@ -510,22 +540,6 @@ int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
return 1;
}
-#if defined(CONFIG_440)
-static int do_chip_reset (unsigned long sys0, unsigned long sys1)
-{
- /* Changes to cpc0_sys0 and cpc0_sys1 require chip
- * reset.
- */
- mtdcr (cntrl0, mfdcr (cntrl0) | 0x80000000); /* Set SWE */
- mtdcr (cpc0_sys0, sys0);
- mtdcr (cpc0_sys1, sys1);
- mtdcr (cntrl0, mfdcr (cntrl0) & ~0x80000000); /* Clr SWE */
- mtspr (dbcr0, 0x20000000); /* Reset the chip */
-
- return 1;
-}
-#endif
-
/*
* Get timebase clock frequency
@@ -545,16 +559,14 @@ unsigned long get_tbclk (void)
#if defined(CONFIG_WATCHDOG)
-void
-watchdog_reset(void)
+void watchdog_reset(void)
{
int re_enable = disable_interrupts();
reset_4xx_watchdog();
if (re_enable) enable_interrupts();
}
-void
-reset_4xx_watchdog(void)
+void reset_4xx_watchdog(void)
{
/*
* Clear TSR(WIS) bit
diff --git a/cpu/ppc4xx/cpu_init.c b/cpu/ppc4xx/cpu_init.c
index 351da36e85..2e0dd6f062 100644
--- a/cpu/ppc4xx/cpu_init.c
+++ b/cpu/ppc4xx/cpu_init.c
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2000-2006
+ * (C) Copyright 2000-2007
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
@@ -112,7 +112,7 @@ cpu_init_f (void)
unsigned long val;
#endif
-#if defined(CONFIG_405EP)
+#if (defined(CONFIG_405EP) || defined (CONFIG_405EX)) && !defined(CFG_4xx_GPIO_TABLE)
/*
* GPIO0 setup (select GPIO or alternate function)
*/
@@ -128,17 +128,30 @@ cpu_init_f (void)
out32(GPIO0_ISR1L, CFG_GPIO0_ISR1L);
out32(GPIO0_TSRH, CFG_GPIO0_TSRH); /* three-state select */
out32(GPIO0_TSRL, CFG_GPIO0_TSRL);
+#if defined(CFG_GPIO0_ISR2H)
+ out32(GPIO0_ISR2H, CFG_GPIO0_ISR2H);
+ out32(GPIO0_ISR2L, CFG_GPIO0_ISR2L);
+#endif
+#if defined (CFG_GPIO0_TCR)
out32(GPIO0_TCR, CFG_GPIO0_TCR); /* enable output driver for outputs */
+#endif
+#if defined (CONFIG_405EP)
/*
* Set EMAC noise filter bits
*/
mtdcr(cpc0_epctl, CPC0_EPRCSR_E0NFE | CPC0_EPRCSR_E1NFE);
+
+ /*
+ * Enable the internal PCI arbiter
+ */
+ mtdcr(cpc0_pci, mfdcr(cpc0_pci) | CPC0_PCI_HOST_CFG_EN | CPC0_PCI_ARBIT_EN);
+#endif /* CONFIG_405EP */
#endif /* CONFIG_405EP */
-#if defined(CFG_440_GPIO_TABLE)
+#if defined(CFG_4xx_GPIO_TABLE)
gpio_set_chip_configuration();
-#endif /* CFG_440_GPIO_TABLE */
+#endif /* CFG_4xx_GPIO_TABLE */
/*
* External Bus Controller (EBC) Setup
@@ -146,7 +159,7 @@ cpu_init_f (void)
#if (defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
#if (defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \
- defined(CONFIG_405))
+ defined(CONFIG_405EX) || defined(CONFIG_405))
/*
* Move the next instructions into icache, since these modify the flash
* we are running from!
diff --git a/cpu/ppc4xx/denali_data_eye.c b/cpu/ppc4xx/denali_data_eye.c
new file mode 100644
index 0000000000..967e61bd41
--- /dev/null
+++ b/cpu/ppc4xx/denali_data_eye.c
@@ -0,0 +1,389 @@
+/*
+ * cpu/ppc4xx/denali_data_eye.c
+ * Extracted from board/amcc/sequoia/sdram.c by Larry Johnson <lrj@acm.org>.
+ *
+ * (C) Copyright 2006
+ * Sylvie Gohl, AMCC/IBM, gohl.sylvie@fr.ibm.com
+ * Jacqueline Pira-Ferriol, AMCC/IBM, jpira-ferriol@fr.ibm.com
+ * Thierry Roman, AMCC/IBM, thierry_roman@fr.ibm.com
+ * Alain Saurel, AMCC/IBM, alain.saurel@fr.ibm.com
+ * Robert Snyder, AMCC/IBM, rob.snyder@fr.ibm.com
+ *
+ * (C) Copyright 2006-2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * 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
+ */
+
+/* define DEBUG for debugging output (obviously ;-)) */
+#if 0
+#define DEBUG
+#endif
+
+#include <common.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <ppc4xx.h>
+
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+/*-----------------------------------------------------------------------------+
+ * denali_wait_for_dlllock.
+ +----------------------------------------------------------------------------*/
+int denali_wait_for_dlllock(void)
+{
+ u32 val;
+ int wait;
+
+ /* -----------------------------------------------------------+
+ * Wait for the DCC master delay line to finish calibration
+ * ----------------------------------------------------------*/
+ for (wait = 0; wait != 0xffff; ++wait) {
+ mfsdram(DDR0_17, val);
+ if (DDR0_17_DLLLOCKREG_DECODE(val)) {
+ /* dlllockreg bit on */
+ return 0;
+ }
+ }
+ debug("0x%04x: DDR0_17 Value (dlllockreg bit): 0x%08x\n", wait, val);
+ debug("Waiting for dlllockreg bit to raise\n");
+ return -1;
+}
+
+#if defined(CONFIG_DDR_DATA_EYE)
+#define DDR_DCR_BASE 0x10
+#define ddrcfga (DDR_DCR_BASE+0x0) /* DDR configuration address reg */
+#define ddrcfgd (DDR_DCR_BASE+0x1) /* DDR configuration data reg */
+
+/*-----------------------------------------------------------------------------+
+ * wait_for_dram_init_complete.
+ +----------------------------------------------------------------------------*/
+static int wait_for_dram_init_complete(void)
+{
+ unsigned long val;
+ int wait = 0;
+
+ /* --------------------------------------------------------------+
+ * Wait for 'DRAM initialization complete' bit in status register
+ * -------------------------------------------------------------*/
+ mtdcr(ddrcfga, DDR0_00);
+
+ while (wait != 0xffff) {
+ val = mfdcr(ddrcfgd);
+ if ((val & DDR0_00_INT_STATUS_BIT6) == DDR0_00_INT_STATUS_BIT6)
+ /* 'DRAM initialization complete' bit */
+ return 0;
+ else
+ wait++;
+ }
+ debug("DRAM initialization complete bit in status register did not "
+ "rise\n");
+ return -1;
+}
+
+#define NUM_TRIES 64
+#define NUM_READS 10
+
+/*-----------------------------------------------------------------------------+
+ * denali_core_search_data_eye.
+ +----------------------------------------------------------------------------*/
+void denali_core_search_data_eye(void)
+{
+ int k, j;
+ u32 val;
+ u32 wr_dqs_shift, dqs_out_shift, dll_dqs_delay_X;
+ u32 max_passing_cases = 0, wr_dqs_shift_with_max_passing_cases = 0;
+ u32 passing_cases = 0, dll_dqs_delay_X_sw_val = 0;
+ u32 dll_dqs_delay_X_start_window = 0, dll_dqs_delay_X_end_window = 0;
+ volatile u32 *ram_pointer;
+ u32 test[NUM_TRIES] = {
+ 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
+ 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
+ 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
+ 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
+ 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
+ 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
+ 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
+ 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
+ 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
+ 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
+ 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
+ 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
+ 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55
+ };
+
+ ram_pointer = (volatile u32 *)(CFG_SDRAM_BASE);
+
+ for (wr_dqs_shift = 64; wr_dqs_shift < 96; wr_dqs_shift++) {
+ /* for (wr_dqs_shift=1; wr_dqs_shift<96; wr_dqs_shift++) { */
+
+ /* -----------------------------------------------------------+
+ * De-assert 'start' parameter.
+ * ----------------------------------------------------------*/
+ mtdcr(ddrcfga, DDR0_02);
+ val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) |
+ DDR0_02_START_OFF;
+ mtdcr(ddrcfgd, val);
+
+ /* -----------------------------------------------------------+
+ * Set 'wr_dqs_shift'
+ * ----------------------------------------------------------*/
+ mtdcr(ddrcfga, DDR0_09);
+ val = (mfdcr(ddrcfgd) & ~DDR0_09_WR_DQS_SHIFT_MASK) |
+ DDR0_09_WR_DQS_SHIFT_ENCODE(wr_dqs_shift);
+ mtdcr(ddrcfgd, val);
+
+ /* -----------------------------------------------------------+
+ * Set 'dqs_out_shift' = wr_dqs_shift + 32
+ * ----------------------------------------------------------*/
+ dqs_out_shift = wr_dqs_shift + 32;
+ mtdcr(ddrcfga, DDR0_22);
+ val = (mfdcr(ddrcfgd) & ~DDR0_22_DQS_OUT_SHIFT_MASK) |
+ DDR0_22_DQS_OUT_SHIFT_ENCODE(dqs_out_shift);
+ mtdcr(ddrcfgd, val);
+
+ passing_cases = 0;
+
+ for (dll_dqs_delay_X = 1; dll_dqs_delay_X < 64;
+ dll_dqs_delay_X++) {
+ /* for (dll_dqs_delay_X=1; dll_dqs_delay_X<128;
+ dll_dqs_delay_X++) { */
+ /* -----------------------------------------------------------+
+ * Set 'dll_dqs_delay_X'.
+ * ----------------------------------------------------------*/
+ /* dll_dqs_delay_0 */
+ mtdcr(ddrcfga, DDR0_17);
+ val = (mfdcr(ddrcfgd) & ~DDR0_17_DLL_DQS_DELAY_0_MASK)
+ | DDR0_17_DLL_DQS_DELAY_0_ENCODE(dll_dqs_delay_X);
+ mtdcr(ddrcfgd, val);
+ /* dll_dqs_delay_1 to dll_dqs_delay_4 */
+ mtdcr(ddrcfga, DDR0_18);
+ val = (mfdcr(ddrcfgd) & ~DDR0_18_DLL_DQS_DELAY_X_MASK)
+ | DDR0_18_DLL_DQS_DELAY_4_ENCODE(dll_dqs_delay_X)
+ | DDR0_18_DLL_DQS_DELAY_3_ENCODE(dll_dqs_delay_X)
+ | DDR0_18_DLL_DQS_DELAY_2_ENCODE(dll_dqs_delay_X)
+ | DDR0_18_DLL_DQS_DELAY_1_ENCODE(dll_dqs_delay_X);
+ mtdcr(ddrcfgd, val);
+ /* dll_dqs_delay_5 to dll_dqs_delay_8 */
+ mtdcr(ddrcfga, DDR0_19);
+ val = (mfdcr(ddrcfgd) & ~DDR0_19_DLL_DQS_DELAY_X_MASK)
+ | DDR0_19_DLL_DQS_DELAY_8_ENCODE(dll_dqs_delay_X)
+ | DDR0_19_DLL_DQS_DELAY_7_ENCODE(dll_dqs_delay_X)
+ | DDR0_19_DLL_DQS_DELAY_6_ENCODE(dll_dqs_delay_X)
+ | DDR0_19_DLL_DQS_DELAY_5_ENCODE(dll_dqs_delay_X);
+ mtdcr(ddrcfgd, val);
+ /* clear any ECC errors */
+ mtdcr(ddrcfga, DDR0_00);
+ mtdcr(ddrcfgd,
+ mfdcr(ddrcfgd) | DDR0_00_INT_ACK_ENCODE(0x3C));
+
+ sync();
+ eieio();
+
+ /* -----------------------------------------------------------+
+ * Assert 'start' parameter.
+ * ----------------------------------------------------------*/
+ mtdcr(ddrcfga, DDR0_02);
+ val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) |
+ DDR0_02_START_ON;
+ mtdcr(ddrcfgd, val);
+
+ sync();
+ eieio();
+
+ /* -----------------------------------------------------------+
+ * Wait for the DCC master delay line to finish calibration
+ * ----------------------------------------------------------*/
+ if (denali_wait_for_dlllock() != 0) {
+ printf("dll lock did not occur !!!\n");
+ printf("denali_core_search_data_eye!!!\n");
+ printf("wr_dqs_shift = %d - dll_dqs_delay_X = "
+ "%d\n", wr_dqs_shift, dll_dqs_delay_X);
+ hang();
+ }
+ sync();
+ eieio();
+
+ if (wait_for_dram_init_complete() != 0) {
+ printf("dram init complete did not occur!!!\n");
+ printf("denali_core_search_data_eye!!!\n");
+ printf("wr_dqs_shift = %d - dll_dqs_delay_X = "
+ "%d\n", wr_dqs_shift, dll_dqs_delay_X);
+ hang();
+ }
+ udelay(100); /* wait 100us to ensure init is really completed !!! */
+
+ /* write values */
+ for (j = 0; j < NUM_TRIES; j++) {
+ ram_pointer[j] = test[j];
+
+ /* clear any cache at ram location */
+ __asm__("dcbf 0,%0": :"r"(&ram_pointer[j]));
+ }
+
+ /* read values back */
+ for (j = 0; j < NUM_TRIES; j++) {
+ for (k = 0; k < NUM_READS; k++) {
+ /* clear any cache at ram location */
+ __asm__("dcbf 0,%0": :"r"(&ram_pointer
+ [j]));
+
+ if (ram_pointer[j] != test[j])
+ break;
+ }
+
+ /* read error */
+ if (k != NUM_READS)
+ break;
+ }
+
+ /* See if the dll_dqs_delay_X value passed. */
+ mtdcr(ddrcfga, DDR0_00);
+ if (j < NUM_TRIES
+ || (DDR0_00_INT_STATUS_DECODE(mfdcr(ddrcfgd)) &
+ 0x3F)) {
+ /* Failed */
+ passing_cases = 0;
+ /* break; */
+ } else {
+ /* Passed */
+ if (passing_cases == 0)
+ dll_dqs_delay_X_sw_val =
+ dll_dqs_delay_X;
+ passing_cases++;
+ if (passing_cases >= max_passing_cases) {
+ max_passing_cases = passing_cases;
+ wr_dqs_shift_with_max_passing_cases =
+ wr_dqs_shift;
+ dll_dqs_delay_X_start_window =
+ dll_dqs_delay_X_sw_val;
+ dll_dqs_delay_X_end_window =
+ dll_dqs_delay_X;
+ }
+ }
+
+ /* -----------------------------------------------------------+
+ * De-assert 'start' parameter.
+ * ----------------------------------------------------------*/
+ mtdcr(ddrcfga, DDR0_02);
+ val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) |
+ DDR0_02_START_OFF;
+ mtdcr(ddrcfgd, val);
+ } /* for (dll_dqs_delay_X=0; dll_dqs_delay_X<128; dll_dqs_delay_X++) */
+ } /* for (wr_dqs_shift=0; wr_dqs_shift<96; wr_dqs_shift++) */
+
+ /* -----------------------------------------------------------+
+ * Largest passing window is now detected.
+ * ----------------------------------------------------------*/
+
+ /* Compute dll_dqs_delay_X value */
+ dll_dqs_delay_X = (dll_dqs_delay_X_end_window +
+ dll_dqs_delay_X_start_window) / 2;
+ wr_dqs_shift = wr_dqs_shift_with_max_passing_cases;
+
+ debug("DQS calibration - Window detected:\n");
+ debug("max_passing_cases = %d\n", max_passing_cases);
+ debug("wr_dqs_shift = %d\n", wr_dqs_shift);
+ debug("dll_dqs_delay_X = %d\n", dll_dqs_delay_X);
+ debug("dll_dqs_delay_X window = %d - %d\n",
+ dll_dqs_delay_X_start_window, dll_dqs_delay_X_end_window);
+
+ /* -----------------------------------------------------------+
+ * De-assert 'start' parameter.
+ * ----------------------------------------------------------*/
+ mtdcr(ddrcfga, DDR0_02);
+ val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_OFF;
+ mtdcr(ddrcfgd, val);
+
+ /* -----------------------------------------------------------+
+ * Set 'wr_dqs_shift'
+ * ----------------------------------------------------------*/
+ mtdcr(ddrcfga, DDR0_09);
+ val = (mfdcr(ddrcfgd) & ~DDR0_09_WR_DQS_SHIFT_MASK)
+ | DDR0_09_WR_DQS_SHIFT_ENCODE(wr_dqs_shift);
+ mtdcr(ddrcfgd, val);
+ debug("DDR0_09=0x%08lx\n", val);
+
+ /* -----------------------------------------------------------+
+ * Set 'dqs_out_shift' = wr_dqs_shift + 32
+ * ----------------------------------------------------------*/
+ dqs_out_shift = wr_dqs_shift + 32;
+ mtdcr(ddrcfga, DDR0_22);
+ val = (mfdcr(ddrcfgd) & ~DDR0_22_DQS_OUT_SHIFT_MASK)
+ | DDR0_22_DQS_OUT_SHIFT_ENCODE(dqs_out_shift);
+ mtdcr(ddrcfgd, val);
+ debug("DDR0_22=0x%08lx\n", val);
+
+ /* -----------------------------------------------------------+
+ * Set 'dll_dqs_delay_X'.
+ * ----------------------------------------------------------*/
+ /* dll_dqs_delay_0 */
+ mtdcr(ddrcfga, DDR0_17);
+ val = (mfdcr(ddrcfgd) & ~DDR0_17_DLL_DQS_DELAY_0_MASK)
+ | DDR0_17_DLL_DQS_DELAY_0_ENCODE(dll_dqs_delay_X);
+ mtdcr(ddrcfgd, val);
+ debug("DDR0_17=0x%08lx\n", val);
+
+ /* dll_dqs_delay_1 to dll_dqs_delay_4 */
+ mtdcr(ddrcfga, DDR0_18);
+ val = (mfdcr(ddrcfgd) & ~DDR0_18_DLL_DQS_DELAY_X_MASK)
+ | DDR0_18_DLL_DQS_DELAY_4_ENCODE(dll_dqs_delay_X)
+ | DDR0_18_DLL_DQS_DELAY_3_ENCODE(dll_dqs_delay_X)
+ | DDR0_18_DLL_DQS_DELAY_2_ENCODE(dll_dqs_delay_X)
+ | DDR0_18_DLL_DQS_DELAY_1_ENCODE(dll_dqs_delay_X);
+ mtdcr(ddrcfgd, val);
+ debug("DDR0_18=0x%08lx\n", val);
+
+ /* dll_dqs_delay_5 to dll_dqs_delay_8 */
+ mtdcr(ddrcfga, DDR0_19);
+ val = (mfdcr(ddrcfgd) & ~DDR0_19_DLL_DQS_DELAY_X_MASK)
+ | DDR0_19_DLL_DQS_DELAY_8_ENCODE(dll_dqs_delay_X)
+ | DDR0_19_DLL_DQS_DELAY_7_ENCODE(dll_dqs_delay_X)
+ | DDR0_19_DLL_DQS_DELAY_6_ENCODE(dll_dqs_delay_X)
+ | DDR0_19_DLL_DQS_DELAY_5_ENCODE(dll_dqs_delay_X);
+ mtdcr(ddrcfgd, val);
+ debug("DDR0_19=0x%08lx\n", val);
+
+ /* -----------------------------------------------------------+
+ * Assert 'start' parameter.
+ * ----------------------------------------------------------*/
+ mtdcr(ddrcfga, DDR0_02);
+ val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_ON;
+ mtdcr(ddrcfgd, val);
+
+ sync();
+ eieio();
+
+ /* -----------------------------------------------------------+
+ * Wait for the DCC master delay line to finish calibration
+ * ----------------------------------------------------------*/
+ if (denali_wait_for_dlllock() != 0) {
+ printf("dll lock did not occur !!!\n");
+ hang();
+ }
+ sync();
+ eieio();
+
+ if (wait_for_dram_init_complete() != 0) {
+ printf("dram init complete did not occur !!!\n");
+ hang();
+ }
+ udelay(100); /* wait 100us to ensure init is really completed !!! */
+}
+#endif /* defined(CONFIG_DDR_DATA_EYE) */
+#endif /* defined(CONFIG_440EPX) || defined(CONFIG_440GRX) */
diff --git a/cpu/ppc4xx/denali_spd_ddr2.c b/cpu/ppc4xx/denali_spd_ddr2.c
new file mode 100644
index 0000000000..825bc2139c
--- /dev/null
+++ b/cpu/ppc4xx/denali_spd_ddr2.c
@@ -0,0 +1,1254 @@
+/*
+ * cpu/ppc4xx/denali_spd_ddr2.c
+ * This SPD SDRAM detection code supports AMCC PPC44x CPUs with a Denali-core
+ * DDR2 controller, specifically the 440EPx/GRx.
+ *
+ * (C) Copyright 2007
+ * Larry Johnson, lrj@acm.org.
+ *
+ * Based primarily on cpu/ppc4xx/4xx_spd_ddr2.c, which is...
+ *
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * COPYRIGHT AMCC CORPORATION 2004
+ *
+ * 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
+ *
+ */
+
+/* define DEBUG for debugging output (obviously ;-)) */
+#if 0
+#define DEBUG
+#endif
+
+#include <common.h>
+#include <command.h>
+#include <ppc4xx.h>
+#include <i2c.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/mmu.h>
+
+#if defined(CONFIG_SPD_EEPROM) && \
+ (defined(CONFIG_440EPX) || defined(CONFIG_440GRX))
+
+/*-----------------------------------------------------------------------------+
+ * Defines
+ *-----------------------------------------------------------------------------*/
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define MAXDIMMS 2
+#define MAXRANKS 2
+
+#define ONE_BILLION 1000000000
+
+#define MULDIV64(m1, m2, d) (u32)(((u64)(m1) * (u64)(m2)) / (u64)(d))
+
+#define DLL_DQS_DELAY 0x19
+#define DLL_DQS_BYPASS 0x0B
+#define DQS_OUT_SHIFT 0x7F
+
+/*
+ * This DDR2 setup code can dynamically setup the TLB entries for the DDR2 memory
+ * region. Right now the cache should still be disabled in U-Boot because of the
+ * EMAC driver, that need it's buffer descriptor to be located in non cached
+ * memory.
+ *
+ * If at some time this restriction doesn't apply anymore, just define
+ * CFG_ENABLE_SDRAM_CACHE in the board config file and this code should setup
+ * everything correctly.
+ */
+#if defined(CFG_ENABLE_SDRAM_CACHE)
+#define MY_TLB_WORD2_I_ENABLE 0 /* enable caching on SDRAM */
+#else
+#define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE /* disable caching on SDRAM */
+#endif
+
+/*-----------------------------------------------------------------------------+
+ * Prototypes
+ *-----------------------------------------------------------------------------*/
+extern int denali_wait_for_dlllock(void);
+extern void denali_core_search_data_eye(void);
+extern void dcbz_area(u32 start_address, u32 num_bytes);
+extern void dflush(void);
+
+/*
+ * Board-specific Platform code can reimplement spd_ddr_init_hang () if needed
+ */
+void __spd_ddr_init_hang(void)
+{
+ hang();
+}
+void spd_ddr_init_hang(void)
+ __attribute__ ((weak, alias("__spd_ddr_init_hang")));
+
+#if defined(DEBUG)
+static void print_mcsr(void)
+{
+ printf("MCSR = 0x%08X\n", mfspr(SPRN_MCSR));
+}
+
+static void denali_sdram_register_dump(void)
+{
+ unsigned int sdram_data;
+
+ printf("\n Register Dump:\n");
+ mfsdram(DDR0_00, sdram_data);
+ printf(" DDR0_00 = 0x%08X", sdram_data);
+ mfsdram(DDR0_01, sdram_data);
+ printf(" DDR0_01 = 0x%08X\n", sdram_data);
+ mfsdram(DDR0_02, sdram_data);
+ printf(" DDR0_02 = 0x%08X", sdram_data);
+ mfsdram(DDR0_03, sdram_data);
+ printf(" DDR0_03 = 0x%08X\n", sdram_data);
+ mfsdram(DDR0_04, sdram_data);
+ printf(" DDR0_04 = 0x%08X", sdram_data);
+ mfsdram(DDR0_05, sdram_data);
+ printf(" DDR0_05 = 0x%08X\n", sdram_data);
+ mfsdram(DDR0_06, sdram_data);
+ printf(" DDR0_06 = 0x%08X", sdram_data);
+ mfsdram(DDR0_07, sdram_data);
+ printf(" DDR0_07 = 0x%08X\n", sdram_data);
+ mfsdram(DDR0_08, sdram_data);
+ printf(" DDR0_08 = 0x%08X", sdram_data);
+ mfsdram(DDR0_09, sdram_data);
+ printf(" DDR0_09 = 0x%08X\n", sdram_data);
+ mfsdram(DDR0_10, sdram_data);
+ printf(" DDR0_10 = 0x%08X", sdram_data);
+ mfsdram(DDR0_11, sdram_data);
+ printf(" DDR0_11 = 0x%08X\n", sdram_data);
+ mfsdram(DDR0_12, sdram_data);
+ printf(" DDR0_12 = 0x%08X", sdram_data);
+ mfsdram(DDR0_14, sdram_data);
+ printf(" DDR0_14 = 0x%08X\n", sdram_data);
+ mfsdram(DDR0_17, sdram_data);
+ printf(" DDR0_17 = 0x%08X", sdram_data);
+ mfsdram(DDR0_18, sdram_data);
+ printf(" DDR0_18 = 0x%08X\n", sdram_data);
+ mfsdram(DDR0_19, sdram_data);
+ printf(" DDR0_19 = 0x%08X", sdram_data);
+ mfsdram(DDR0_20, sdram_data);
+ printf(" DDR0_20 = 0x%08X\n", sdram_data);
+ mfsdram(DDR0_21, sdram_data);
+ printf(" DDR0_21 = 0x%08X", sdram_data);
+ mfsdram(DDR0_22, sdram_data);
+ printf(" DDR0_22 = 0x%08X\n", sdram_data);
+ mfsdram(DDR0_23, sdram_data);
+ printf(" DDR0_23 = 0x%08X", sdram_data);
+ mfsdram(DDR0_24, sdram_data);
+ printf(" DDR0_24 = 0x%08X\n", sdram_data);
+ mfsdram(DDR0_25, sdram_data);
+ printf(" DDR0_25 = 0x%08X", sdram_data);
+ mfsdram(DDR0_26, sdram_data);
+ printf(" DDR0_26 = 0x%08X\n", sdram_data);
+ mfsdram(DDR0_27, sdram_data);
+ printf(" DDR0_27 = 0x%08X", sdram_data);
+ mfsdram(DDR0_28, sdram_data);
+ printf(" DDR0_28 = 0x%08X\n", sdram_data);
+ mfsdram(DDR0_31, sdram_data);
+ printf(" DDR0_31 = 0x%08X", sdram_data);
+ mfsdram(DDR0_32, sdram_data);
+ printf(" DDR0_32 = 0x%08X\n", sdram_data);
+ mfsdram(DDR0_33, sdram_data);
+ printf(" DDR0_33 = 0x%08X", sdram_data);
+ mfsdram(DDR0_34, sdram_data);
+ printf(" DDR0_34 = 0x%08X\n", sdram_data);
+ mfsdram(DDR0_35, sdram_data);
+ printf(" DDR0_35 = 0x%08X", sdram_data);
+ mfsdram(DDR0_36, sdram_data);
+ printf(" DDR0_36 = 0x%08X\n", sdram_data);
+ mfsdram(DDR0_37, sdram_data);
+ printf(" DDR0_37 = 0x%08X", sdram_data);
+ mfsdram(DDR0_38, sdram_data);
+ printf(" DDR0_38 = 0x%08X\n", sdram_data);
+ mfsdram(DDR0_39, sdram_data);
+ printf(" DDR0_39 = 0x%08X", sdram_data);
+ mfsdram(DDR0_40, sdram_data);
+ printf(" DDR0_40 = 0x%08X\n", sdram_data);
+ mfsdram(DDR0_41, sdram_data);
+ printf(" DDR0_41 = 0x%08X", sdram_data);
+ mfsdram(DDR0_42, sdram_data);
+ printf(" DDR0_42 = 0x%08X\n", sdram_data);
+ mfsdram(DDR0_43, sdram_data);
+ printf(" DDR0_43 = 0x%08X", sdram_data);
+ mfsdram(DDR0_44, sdram_data);
+ printf(" DDR0_44 = 0x%08X\n", sdram_data);
+}
+#else
+static inline void denali_sdram_register_dump(void)
+{
+}
+
+inline static void print_mcsr(void)
+{
+}
+#endif /* defined(DEBUG) */
+
+static int is_ecc_enabled(void)
+{
+ u32 val;
+
+ mfsdram(DDR0_22, val);
+ return 0x3 == DDR0_22_CTRL_RAW_DECODE(val);
+}
+
+static unsigned char spd_read(u8 chip, unsigned int addr)
+{
+ u8 data[2];
+
+ if (0 != i2c_probe(chip) || 0 != i2c_read(chip, addr, 1, data, 1)) {
+ debug("spd_read(0x%02X, 0x%02X) failed\n", chip, addr);
+ return 0;
+ }
+ debug("spd_read(0x%02X, 0x%02X) returned 0x%02X\n",
+ chip, addr, data[0]);
+ return data[0];
+}
+
+static unsigned long get_tcyc(unsigned char reg)
+{
+ /*
+ * Byte 9, et al: Cycle time for CAS Latency=X, is split into two
+ * nibbles: the higher order nibble (bits 4-7) designates the cycle time
+ * to a granularity of 1ns; the value presented by the lower order
+ * nibble (bits 0-3) has a granularity of .1ns and is added to the value
+ * designated by the higher nibble. In addition, four lines of the lower
+ * order nibble are assigned to support +.25, +.33, +.66, and +.75.
+ */
+
+ unsigned char subfield_b = reg & 0x0F;
+
+ switch (subfield_b & 0x0F) {
+ case 0x0:
+ case 0x1:
+ case 0x2:
+ case 0x3:
+ case 0x4:
+ case 0x5:
+ case 0x6:
+ case 0x7:
+ case 0x8:
+ case 0x9:
+ return 1000 * (reg >> 4) + 100 * subfield_b;
+ case 0xA:
+ return 1000 * (reg >> 4) + 250;
+ case 0xB:
+ return 1000 * (reg >> 4) + 333;
+ case 0xC:
+ return 1000 * (reg >> 4) + 667;
+ case 0xD:
+ return 1000 * (reg >> 4) + 750;
+ }
+ return 0;
+}
+
+/*------------------------------------------------------------------
+ * Find the installed DIMMs, make sure that the are DDR2, and fill
+ * in the dimm_ranks array. Then dimm_ranks[dimm_num] > 0 iff the
+ * DIMM and dimm_num is present.
+ * Note: Because there are only two chip-select lines, it is assumed
+ * that a board with a single socket can support two ranks on that
+ * socket, while a board with two sockets can support only one rank
+ * on each socket.
+ *-----------------------------------------------------------------*/
+static void get_spd_info(unsigned long dimm_ranks[],
+ unsigned long *ranks,
+ unsigned char const iic0_dimm_addr[],
+ unsigned long num_dimm_banks)
+{
+ unsigned long dimm_num;
+ unsigned long dimm_found = FALSE;
+ unsigned long const max_ranks_per_dimm = (1 == num_dimm_banks) ? 2 : 1;
+ unsigned char num_of_bytes;
+ unsigned char total_size;
+
+ *ranks = 0;
+ for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+ num_of_bytes = 0;
+ total_size = 0;
+
+ num_of_bytes = spd_read(iic0_dimm_addr[dimm_num], 0);
+ total_size = spd_read(iic0_dimm_addr[dimm_num], 1);
+ if ((num_of_bytes != 0) && (total_size != 0)) {
+ unsigned char const dimm_type =
+ spd_read(iic0_dimm_addr[dimm_num], 2);
+
+ unsigned long ranks_on_dimm =
+ (spd_read(iic0_dimm_addr[dimm_num], 5) & 0x07) + 1;
+
+ if (8 != dimm_type) {
+ switch (dimm_type) {
+ case 1:
+ printf("ERROR: Standard Fast Page Mode "
+ "DRAM DIMM");
+ break;
+ case 2:
+ printf("ERROR: EDO DIMM");
+ break;
+ case 3:
+ printf("ERROR: Pipelined Nibble DIMM");
+ break;
+ case 4:
+ printf("ERROR: SDRAM DIMM");
+ break;
+ case 5:
+ printf("ERROR: Multiplexed ROM DIMM");
+ break;
+ case 6:
+ printf("ERROR: SGRAM DIMM");
+ break;
+ case 7:
+ printf("ERROR: DDR1 DIMM");
+ break;
+ default:
+ printf("ERROR: Unknown DIMM (type %d)",
+ (unsigned int)dimm_type);
+ break;
+ }
+ printf(" detected in slot %lu.\n", dimm_num);
+ printf("Only DDR2 SDRAM DIMMs are supported."
+ "\n");
+ printf("Replace the module with a DDR2 DIMM."
+ "\n\n");
+ spd_ddr_init_hang();
+ }
+ dimm_found = TRUE;
+ debug("DIMM slot %lu: populated with %lu-rank DDR2 DIMM"
+ "\n", dimm_num, ranks_on_dimm);
+ if (ranks_on_dimm > max_ranks_per_dimm) {
+ printf("WARNING: DRAM DIMM in slot %lu has %lu "
+ "ranks.\n");
+ if (1 == max_ranks_per_dimm) {
+ printf("Only one rank will be used.\n");
+ } else {
+ printf
+ ("Only two ranks will be used.\n");
+ }
+ ranks_on_dimm = max_ranks_per_dimm;
+ }
+ dimm_ranks[dimm_num] = ranks_on_dimm;
+ *ranks += ranks_on_dimm;
+ } else {
+ dimm_ranks[dimm_num] = 0;
+ debug("DIMM slot %lu: Not populated\n", dimm_num);
+ }
+ }
+ if (dimm_found == FALSE) {
+ printf("ERROR: No memory installed.\n");
+ printf("Install at least one DDR2 DIMM.\n\n");
+ spd_ddr_init_hang();
+ }
+ debug("Total number of ranks = %d\n", *ranks);
+}
+
+/*------------------------------------------------------------------
+ * For the memory DIMMs installed, this routine verifies that
+ * frequency previously calculated is supported.
+ *-----------------------------------------------------------------*/
+static void check_frequency(unsigned long *dimm_ranks,
+ unsigned char const iic0_dimm_addr[],
+ unsigned long num_dimm_banks,
+ unsigned long sdram_freq)
+{
+ unsigned long dimm_num;
+ unsigned long cycle_time;
+ unsigned long calc_cycle_time;
+
+ /*
+ * calc_cycle_time is calculated from DDR frequency set by board/chip
+ * and is expressed in picoseconds to match the way DIMM cycle time is
+ * calculated below.
+ */
+ calc_cycle_time = MULDIV64(ONE_BILLION, 1000, sdram_freq);
+
+ for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+ if (dimm_ranks[dimm_num]) {
+ cycle_time =
+ get_tcyc(spd_read(iic0_dimm_addr[dimm_num], 9));
+ debug("cycle_time=%d ps\n", cycle_time);
+
+ if (cycle_time > (calc_cycle_time + 10)) {
+ /*
+ * the provided sdram cycle_time is too small
+ * for the available DIMM cycle_time. The
+ * additionnal 10ps is here to accept a small
+ * incertainty.
+ */
+ printf
+ ("ERROR: DRAM DIMM detected with cycle_time %d ps in "
+ "slot %d \n while calculated cycle time is %d ps.\n",
+ (unsigned int)cycle_time,
+ (unsigned int)dimm_num,
+ (unsigned int)calc_cycle_time);
+ printf
+ ("Replace the DIMM, or change DDR frequency via "
+ "strapping bits.\n\n");
+ spd_ddr_init_hang();
+ }
+ }
+ }
+}
+
+/*------------------------------------------------------------------
+ * This routine gets size information for the installed memory
+ * DIMMs.
+ *-----------------------------------------------------------------*/
+static void get_dimm_size(unsigned long dimm_ranks[],
+ unsigned char const iic0_dimm_addr[],
+ unsigned long num_dimm_banks,
+ unsigned long *const rows,
+ unsigned long *const banks,
+ unsigned long *const cols, unsigned long *const width)
+{
+ unsigned long dimm_num;
+
+ *rows = 0;
+ *banks = 0;
+ *cols = 0;
+ *width = 0;
+ for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+ if (dimm_ranks[dimm_num]) {
+ unsigned long t;
+
+ /* Rows */
+ t = spd_read(iic0_dimm_addr[dimm_num], 3);
+ if (0 == *rows) {
+ *rows = t;
+ } else if (t != *rows) {
+ printf("ERROR: DRAM DIMM modules do not all "
+ "have the same number of rows.\n\n");
+ spd_ddr_init_hang();
+ }
+ /* Banks */
+ t = spd_read(iic0_dimm_addr[dimm_num], 17);
+ if (0 == *banks) {
+ *banks = t;
+ } else if (t != *banks) {
+ printf("ERROR: DRAM DIMM modules do not all "
+ "have the same number of banks.\n\n");
+ spd_ddr_init_hang();
+ }
+ /* Columns */
+ t = spd_read(iic0_dimm_addr[dimm_num], 4);
+ if (0 == *cols) {
+ *cols = t;
+ } else if (t != *cols) {
+ printf("ERROR: DRAM DIMM modules do not all "
+ "have the same number of columns.\n\n");
+ spd_ddr_init_hang();
+ }
+ /* Data width */
+ t = spd_read(iic0_dimm_addr[dimm_num], 6);
+ if (0 == *width) {
+ *width = t;
+ } else if (t != *width) {
+ printf("ERROR: DRAM DIMM modules do not all "
+ "have the same data width.\n\n");
+ spd_ddr_init_hang();
+ }
+ }
+ }
+ debug("Number of rows = %d\n", *rows);
+ debug("Number of columns = %d\n", *cols);
+ debug("Number of banks = %d\n", *banks);
+ debug("Data width = %d\n", *width);
+ if (*rows > 14) {
+ printf("ERROR: DRAM DIMM modules have %lu address rows.\n",
+ *rows);
+ printf("Only modules with 14 or fewer rows are supported.\n\n");
+ spd_ddr_init_hang();
+ }
+ if (4 != *banks && 8 != *banks) {
+ printf("ERROR: DRAM DIMM modules have %lu banks.\n", *banks);
+ printf("Only modules with 4 or 8 banks are supported.\n\n");
+ spd_ddr_init_hang();
+ }
+ if (*cols > 12) {
+ printf("ERROR: DRAM DIMM modules have %lu address columns.\n",
+ *cols);
+ printf("Only modules with 12 or fewer columns are "
+ "supported.\n\n");
+ spd_ddr_init_hang();
+ }
+ if (32 != *width && 40 != *width && 64 != *width && 72 != *width) {
+ printf("ERROR: DRAM DIMM modules have a width of %lu bit.\n",
+ *width);
+ printf("Only modules with widths of 32, 40, 64, and 72 bits "
+ "are supported.\n\n");
+ spd_ddr_init_hang();
+ }
+}
+
+/*------------------------------------------------------------------
+ * Only 1.8V modules are supported. This routine verifies this.
+ *-----------------------------------------------------------------*/
+static void check_voltage_type(unsigned long dimm_ranks[],
+ unsigned char const iic0_dimm_addr[],
+ unsigned long num_dimm_banks)
+{
+ unsigned long dimm_num;
+ unsigned long voltage_type;
+
+ for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+ if (dimm_ranks[dimm_num]) {
+ voltage_type = spd_read(iic0_dimm_addr[dimm_num], 8);
+ if (0x05 != voltage_type) { /* 1.8V for DDR2 */
+ printf("ERROR: Slot %lu provides 1.8V for DDR2 "
+ "DIMMs.\n", dimm_num);
+ switch (voltage_type) {
+ case 0x00:
+ printf("This DIMM is 5.0 Volt/TTL.\n");
+ break;
+ case 0x01:
+ printf("This DIMM is LVTTL.\n");
+ break;
+ case 0x02:
+ printf("This DIMM is 1.5 Volt.\n");
+ break;
+ case 0x03:
+ printf("This DIMM is 3.3 Volt/TTL.\n");
+ break;
+ case 0x04:
+ printf("This DIMM is 2.5 Volt.\n");
+ break;
+ default:
+ printf("This DIMM is an unknown "
+ "voltage.\n");
+ break;
+ }
+ printf("Replace it with a 1.8V DDR2 DIMM.\n\n");
+ spd_ddr_init_hang();
+ }
+ }
+ }
+}
+
+static void program_ddr0_03(unsigned long dimm_ranks[],
+ unsigned char const iic0_dimm_addr[],
+ unsigned long num_dimm_banks,
+ unsigned long sdram_freq,
+ unsigned long rows, unsigned long *cas_latency)
+{
+ unsigned long dimm_num;
+ unsigned long cas_index;
+ unsigned long cycle_2_0_clk;
+ unsigned long cycle_3_0_clk;
+ unsigned long cycle_4_0_clk;
+ unsigned long cycle_5_0_clk;
+ unsigned long max_2_0_tcyc_ps = 100;
+ unsigned long max_3_0_tcyc_ps = 100;
+ unsigned long max_4_0_tcyc_ps = 100;
+ unsigned long max_5_0_tcyc_ps = 100;
+ unsigned char cas_available = 0x3C; /* value for DDR2 */
+ u32 ddr0_03 = DDR0_03_BSTLEN_ENCODE(0x2) | DDR0_03_INITAREF_ENCODE(0x2);
+ unsigned int const tcyc_addr[3] = { 9, 23, 25 };
+
+ /*------------------------------------------------------------------
+ * Get the board configuration info.
+ *-----------------------------------------------------------------*/
+ debug("sdram_freq = %d\n", sdram_freq);
+
+ /*------------------------------------------------------------------
+ * Handle the timing. We need to find the worst case timing of all
+ * the dimm modules installed.
+ *-----------------------------------------------------------------*/
+ /* loop through all the DIMM slots on the board */
+ for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+ /* If a dimm is installed in a particular slot ... */
+ if (dimm_ranks[dimm_num]) {
+ unsigned char const cas_bit =
+ spd_read(iic0_dimm_addr[dimm_num], 18);
+ unsigned char cas_mask;
+
+ cas_available &= cas_bit;
+ for (cas_mask = 0x80; cas_mask; cas_mask >>= 1) {
+ if (cas_bit & cas_mask)
+ break;
+ }
+ debug("cas_bit (SPD byte 18) = %02X, cas_mask = %02X\n",
+ cas_bit, cas_mask);
+
+ for (cas_index = 0; cas_index < 3;
+ cas_mask >>= 1, cas_index++) {
+ unsigned long cycle_time_ps;
+
+ if (!(cas_available & cas_mask)) {
+ continue;
+ }
+ cycle_time_ps =
+ get_tcyc(spd_read(iic0_dimm_addr[dimm_num],
+ tcyc_addr[cas_index]));
+
+ debug("cas_index = %d: cycle_time_ps = %d\n",
+ cas_index, cycle_time_ps);
+ /*
+ * DDR2 devices use the following bitmask for CAS latency:
+ * Bit 7 6 5 4 3 2 1 0
+ * TBD 6.0 5.0 4.0 3.0 2.0 TBD TBD
+ */
+ switch (cas_mask) {
+ case 0x20:
+ max_5_0_tcyc_ps =
+ max(max_5_0_tcyc_ps, cycle_time_ps);
+ break;
+ case 0x10:
+ max_4_0_tcyc_ps =
+ max(max_4_0_tcyc_ps, cycle_time_ps);
+ break;
+ case 0x08:
+ max_3_0_tcyc_ps =
+ max(max_3_0_tcyc_ps, cycle_time_ps);
+ break;
+ case 0x04:
+ max_2_0_tcyc_ps =
+ max(max_2_0_tcyc_ps, cycle_time_ps);
+ break;
+ }
+ }
+ }
+ }
+ debug("cas_available (bit map) = 0x%02X\n", cas_available);
+
+ /*------------------------------------------------------------------
+ * Set the SDRAM mode, SDRAM_MMODE
+ *-----------------------------------------------------------------*/
+
+ /* add 10 here because of rounding problems */
+ cycle_2_0_clk = MULDIV64(ONE_BILLION, 1000, max_2_0_tcyc_ps) + 10;
+ cycle_3_0_clk = MULDIV64(ONE_BILLION, 1000, max_3_0_tcyc_ps) + 10;
+ cycle_4_0_clk = MULDIV64(ONE_BILLION, 1000, max_4_0_tcyc_ps) + 10;
+ cycle_5_0_clk = MULDIV64(ONE_BILLION, 1000, max_5_0_tcyc_ps) + 10;
+ debug("cycle_2_0_clk = %d\n", cycle_2_0_clk);
+ debug("cycle_3_0_clk = %d\n", cycle_3_0_clk);
+ debug("cycle_4_0_clk = %d\n", cycle_4_0_clk);
+ debug("cycle_5_0_clk = %d\n", cycle_5_0_clk);
+
+ if ((cas_available & 0x04) && (sdram_freq <= cycle_2_0_clk)) {
+ *cas_latency = 2;
+ ddr0_03 |= DDR0_03_CASLAT_ENCODE(0x2) |
+ DDR0_03_CASLAT_LIN_ENCODE(0x4);
+ } else if ((cas_available & 0x08) && (sdram_freq <= cycle_3_0_clk)) {
+ *cas_latency = 3;
+ ddr0_03 |= DDR0_03_CASLAT_ENCODE(0x3) |
+ DDR0_03_CASLAT_LIN_ENCODE(0x6);
+ } else if ((cas_available & 0x10) && (sdram_freq <= cycle_4_0_clk)) {
+ *cas_latency = 4;
+ ddr0_03 |= DDR0_03_CASLAT_ENCODE(0x4) |
+ DDR0_03_CASLAT_LIN_ENCODE(0x8);
+ } else if ((cas_available & 0x20) && (sdram_freq <= cycle_5_0_clk)) {
+ *cas_latency = 5;
+ ddr0_03 |= DDR0_03_CASLAT_ENCODE(0x5) |
+ DDR0_03_CASLAT_LIN_ENCODE(0xA);
+ } else {
+ printf("ERROR: Cannot find a supported CAS latency with the "
+ "installed DIMMs.\n");
+ printf("Only DDR2 DIMMs with CAS latencies of 2.0, 3.0, 4.0, "
+ "and 5.0 are supported.\n");
+ printf("Make sure the PLB speed is within the supported range "
+ "of the DIMMs.\n");
+ printf("sdram_freq=%d cycle2=%d cycle3=%d cycle4=%d "
+ "cycle5=%d\n\n", sdram_freq, cycle_2_0_clk,
+ cycle_3_0_clk, cycle_4_0_clk, cycle_5_0_clk);
+ spd_ddr_init_hang();
+ }
+ debug("CAS latency = %d\n", *cas_latency);
+ mtsdram(DDR0_03, ddr0_03);
+}
+
+static void program_ddr0_04(unsigned long dimm_ranks[],
+ unsigned char const iic0_dimm_addr[],
+ unsigned long num_dimm_banks,
+ unsigned long sdram_freq)
+{
+ unsigned long dimm_num;
+ unsigned long t_rc_ps = 0;
+ unsigned long t_rrd_ps = 0;
+ unsigned long t_rtp_ps = 0;
+ unsigned long t_rc_clk;
+ unsigned long t_rrd_clk;
+ unsigned long t_rtp_clk;
+
+ /*------------------------------------------------------------------
+ * Handle the timing. We need to find the worst case timing of all
+ * the dimm modules installed.
+ *-----------------------------------------------------------------*/
+ /* loop through all the DIMM slots on the board */
+ for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+ /* If a dimm is installed in a particular slot ... */
+ if (dimm_ranks[dimm_num]) {
+ unsigned long ps;
+
+ /* tRC */
+ ps = 1000 * spd_read(iic0_dimm_addr[dimm_num], 41);
+ switch (spd_read(iic0_dimm_addr[dimm_num], 40) >> 4) {
+ case 0x1:
+ ps += 250;
+ break;
+ case 0x2:
+ ps += 333;
+ break;
+ case 0x3:
+ ps += 500;
+ break;
+ case 0x4:
+ ps += 667;
+ break;
+ case 0x5:
+ ps += 750;
+ break;
+ }
+ t_rc_ps = max(t_rc_ps, ps);
+ /* tRRD */
+ ps = 250 * spd_read(iic0_dimm_addr[dimm_num], 28);
+ t_rrd_ps = max(t_rrd_ps, ps);
+ /* tRTP */
+ ps = 250 * spd_read(iic0_dimm_addr[dimm_num], 38);
+ t_rtp_ps = max(t_rtp_ps, ps);
+ }
+ }
+ debug("t_rc_ps = %d\n", t_rc_ps);
+ t_rc_clk = (MULDIV64(sdram_freq, t_rc_ps, ONE_BILLION) + 999) / 1000;
+ debug("t_rrd_ps = %d\n", t_rrd_ps);
+ t_rrd_clk = (MULDIV64(sdram_freq, t_rrd_ps, ONE_BILLION) + 999) / 1000;
+ debug("t_rtp_ps = %d\n", t_rtp_ps);
+ t_rtp_clk = (MULDIV64(sdram_freq, t_rtp_ps, ONE_BILLION) + 999) / 1000;
+ mtsdram(DDR0_04, DDR0_04_TRC_ENCODE(t_rc_clk) |
+ DDR0_04_TRRD_ENCODE(t_rrd_clk) |
+ DDR0_04_TRTP_ENCODE(t_rtp_clk));
+}
+
+static void program_ddr0_05(unsigned long dimm_ranks[],
+ unsigned char const iic0_dimm_addr[],
+ unsigned long num_dimm_banks,
+ unsigned long sdram_freq)
+{
+ unsigned long dimm_num;
+ unsigned long t_rp_ps = 0;
+ unsigned long t_ras_ps = 0;
+ unsigned long t_rp_clk;
+ unsigned long t_ras_clk;
+ u32 ddr0_05 = DDR0_05_TMRD_ENCODE(0x2) | DDR0_05_TEMRS_ENCODE(0x2);
+
+ /*------------------------------------------------------------------
+ * Handle the timing. We need to find the worst case timing of all
+ * the dimm modules installed.
+ *-----------------------------------------------------------------*/
+ /* loop through all the DIMM slots on the board */
+ for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+ /* If a dimm is installed in a particular slot ... */
+ if (dimm_ranks[dimm_num]) {
+ unsigned long ps;
+
+ /* tRP */
+ ps = 250 * spd_read(iic0_dimm_addr[dimm_num], 27);
+ t_rp_ps = max(t_rp_ps, ps);
+ /* tRAS */
+ ps = 1000 * spd_read(iic0_dimm_addr[dimm_num], 30);
+ t_ras_ps = max(t_ras_ps, ps);
+ }
+ }
+ debug("t_rp_ps = %d\n", t_rp_ps);
+ t_rp_clk = (MULDIV64(sdram_freq, t_rp_ps, ONE_BILLION) + 999) / 1000;
+ debug("t_ras_ps = %d\n", t_ras_ps);
+ t_ras_clk = (MULDIV64(sdram_freq, t_ras_ps, ONE_BILLION) + 999) / 1000;
+ mtsdram(DDR0_05, ddr0_05 | DDR0_05_TRP_ENCODE(t_rp_clk) |
+ DDR0_05_TRAS_MIN_ENCODE(t_ras_clk));
+}
+
+static void program_ddr0_06(unsigned long dimm_ranks[],
+ unsigned char const iic0_dimm_addr[],
+ unsigned long num_dimm_banks,
+ unsigned long sdram_freq)
+{
+ unsigned long dimm_num;
+ unsigned char spd_40;
+ unsigned long t_wtr_ps = 0;
+ unsigned long t_rfc_ps = 0;
+ unsigned long t_wtr_clk;
+ unsigned long t_rfc_clk;
+ u32 ddr0_06 =
+ DDR0_06_WRITEINTERP_ENCODE(0x1) | DDR0_06_TDLL_ENCODE(200);
+
+ /*------------------------------------------------------------------
+ * Handle the timing. We need to find the worst case timing of all
+ * the dimm modules installed.
+ *-----------------------------------------------------------------*/
+ /* loop through all the DIMM slots on the board */
+ for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+ /* If a dimm is installed in a particular slot ... */
+ if (dimm_ranks[dimm_num]) {
+ unsigned long ps;
+
+ /* tWTR */
+ ps = 250 * spd_read(iic0_dimm_addr[dimm_num], 37);
+ t_wtr_ps = max(t_wtr_ps, ps);
+ /* tRFC */
+ ps = 1000 * spd_read(iic0_dimm_addr[dimm_num], 42);
+ spd_40 = spd_read(iic0_dimm_addr[dimm_num], 40);
+ ps += 256000 * (spd_40 & 0x01);
+ switch ((spd_40 & 0x0E) >> 1) {
+ case 0x1:
+ ps += 250;
+ break;
+ case 0x2:
+ ps += 333;
+ break;
+ case 0x3:
+ ps += 500;
+ break;
+ case 0x4:
+ ps += 667;
+ break;
+ case 0x5:
+ ps += 750;
+ break;
+ }
+ t_rfc_ps = max(t_rfc_ps, ps);
+ }
+ }
+ debug("t_wtr_ps = %d\n", t_wtr_ps);
+ t_wtr_clk = (MULDIV64(sdram_freq, t_wtr_ps, ONE_BILLION) + 999) / 1000;
+ debug("t_rfc_ps = %d\n", t_rfc_ps);
+ t_rfc_clk = (MULDIV64(sdram_freq, t_rfc_ps, ONE_BILLION) + 999) / 1000;
+ mtsdram(DDR0_06, ddr0_06 | DDR0_06_TWTR_ENCODE(t_wtr_clk) |
+ DDR0_06_TRFC_ENCODE(t_rfc_clk));
+}
+
+static void program_ddr0_10(unsigned long dimm_ranks[], unsigned long ranks)
+{
+ unsigned long csmap;
+
+ if (2 == ranks) {
+ /* Both chip selects in use */
+ csmap = 0x03;
+ } else {
+ /* One chip select in use */
+ csmap = (1 == dimm_ranks[0]) ? 0x1 : 0x2;
+ }
+ mtsdram(DDR0_10, DDR0_10_WRITE_MODEREG_ENCODE(0x0) |
+ DDR0_10_CS_MAP_ENCODE(csmap) |
+ DDR0_10_OCD_ADJUST_PUP_CS_0_ENCODE(0));
+}
+
+static void program_ddr0_11(unsigned long sdram_freq)
+{
+ unsigned long const t_xsnr_ps = 200000; /* 200 ns */
+ unsigned long t_xsnr_clk;
+
+ debug("t_xsnr_ps = %d\n", t_xsnr_ps);
+ t_xsnr_clk =
+ (MULDIV64(sdram_freq, t_xsnr_ps, ONE_BILLION) + 999) / 1000;
+ mtsdram(DDR0_11, DDR0_11_SREFRESH_ENCODE(0) |
+ DDR0_11_TXSNR_ENCODE(t_xsnr_clk) | DDR0_11_TXSR_ENCODE(200));
+}
+
+static void program_ddr0_22(unsigned long dimm_ranks[],
+ unsigned char const iic0_dimm_addr[],
+ unsigned long num_dimm_banks, unsigned long width)
+{
+#if defined(CONFIG_DDR_ECC)
+ unsigned long dimm_num;
+ unsigned long ecc_available = width >= 64;
+ u32 ddr0_22 = DDR0_22_DQS_OUT_SHIFT_BYPASS_ENCODE(0x26) |
+ DDR0_22_DQS_OUT_SHIFT_ENCODE(DQS_OUT_SHIFT) |
+ DDR0_22_DLL_DQS_BYPASS_8_ENCODE(DLL_DQS_BYPASS);
+
+ /* loop through all the DIMM slots on the board */
+ for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+ /* If a dimm is installed in a particular slot ... */
+ if (dimm_ranks[dimm_num]) {
+ /* Check for ECC */
+ if (0 == (spd_read(iic0_dimm_addr[dimm_num], 11) &
+ 0x02)) {
+ ecc_available = FALSE;
+ }
+ }
+ }
+ if (ecc_available) {
+ debug("ECC found on all DIMMs present\n");
+ mtsdram(DDR0_22, ddr0_22 | DDR0_22_CTRL_RAW_ENCODE(0x3));
+ } else {
+ debug("ECC not found on some or all DIMMs present\n");
+ mtsdram(DDR0_22, ddr0_22 | DDR0_22_CTRL_RAW_ENCODE(0x0));
+ }
+#else
+ mtsdram(DDR0_22, DDR0_22_CTRL_RAW_ENCODE(0x0) |
+ DDR0_22_DQS_OUT_SHIFT_BYPASS_ENCODE(0x26) |
+ DDR0_22_DQS_OUT_SHIFT_ENCODE(DQS_OUT_SHIFT) |
+ DDR0_22_DLL_DQS_BYPASS_8_ENCODE(DLL_DQS_BYPASS));
+#endif /* defined(CONFIG_DDR_ECC) */
+}
+
+static void program_ddr0_24(unsigned long ranks)
+{
+ u32 ddr0_24 = DDR0_24_RTT_PAD_TERMINATION_ENCODE(0x1) | /* 75 ohm */
+ DDR0_24_ODT_RD_MAP_CS1_ENCODE(0x0);
+
+ if (2 == ranks) {
+ /* Both chip selects in use */
+ ddr0_24 |= DDR0_24_ODT_WR_MAP_CS1_ENCODE(0x1) |
+ DDR0_24_ODT_WR_MAP_CS0_ENCODE(0x2);
+ } else {
+ /* One chip select in use */
+ /* One of the two fields added to ddr0_24 is a "don't care" */
+ ddr0_24 |= DDR0_24_ODT_WR_MAP_CS1_ENCODE(0x2) |
+ DDR0_24_ODT_WR_MAP_CS0_ENCODE(0x1);
+ }
+ mtsdram(DDR0_24, ddr0_24);
+}
+
+static void program_ddr0_26(unsigned long sdram_freq)
+{
+ unsigned long const t_ref_ps = 7800000; /* 7.8 us. refresh */
+ /* TODO: check definition of tRAS_MAX */
+ unsigned long const t_ras_max_ps = 9 * t_ref_ps;
+ unsigned long t_ras_max_clk;
+ unsigned long t_ref_clk;
+
+ /* Round down t_ras_max_clk and t_ref_clk */
+ debug("t_ras_max_ps = %d\n", t_ras_max_ps);
+ t_ras_max_clk = MULDIV64(sdram_freq, t_ras_max_ps, ONE_BILLION) / 1000;
+ debug("t_ref_ps = %d\n", t_ref_ps);
+ t_ref_clk = MULDIV64(sdram_freq, t_ref_ps, ONE_BILLION) / 1000;
+ mtsdram(DDR0_26, DDR0_26_TRAS_MAX_ENCODE(t_ras_max_clk) |
+ DDR0_26_TREF_ENCODE(t_ref_clk));
+}
+
+static void program_ddr0_27(unsigned long sdram_freq)
+{
+ unsigned long const t_init_ps = 200000000; /* 200 us. init */
+ unsigned long t_init_clk;
+
+ debug("t_init_ps = %d\n", t_init_ps);
+ t_init_clk =
+ (MULDIV64(sdram_freq, t_init_ps, ONE_BILLION) + 999) / 1000;
+ mtsdram(DDR0_27, DDR0_27_EMRS_DATA_ENCODE(0x0000) |
+ DDR0_27_TINIT_ENCODE(t_init_clk));
+}
+
+static void program_ddr0_43(unsigned long dimm_ranks[],
+ unsigned char const iic0_dimm_addr[],
+ unsigned long num_dimm_banks,
+ unsigned long sdram_freq,
+ unsigned long cols, unsigned long banks)
+{
+ unsigned long dimm_num;
+ unsigned long t_wr_ps = 0;
+ unsigned long t_wr_clk;
+ u32 ddr0_43 = DDR0_43_APREBIT_ENCODE(10) |
+ DDR0_43_COLUMN_SIZE_ENCODE(12 - cols) |
+ DDR0_43_EIGHT_BANK_MODE_ENCODE(8 == banks ? 1 : 0);
+
+ /*------------------------------------------------------------------
+ * Handle the timing. We need to find the worst case timing of all
+ * the dimm modules installed.
+ *-----------------------------------------------------------------*/
+ /* loop through all the DIMM slots on the board */
+ for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+ /* If a dimm is installed in a particular slot ... */
+ if (dimm_ranks[dimm_num]) {
+ unsigned long ps;
+
+ ps = 250 * spd_read(iic0_dimm_addr[dimm_num], 36);
+ t_wr_ps = max(t_wr_ps, ps);
+ }
+ }
+ debug("t_wr_ps = %d\n", t_wr_ps);
+ t_wr_clk = (MULDIV64(sdram_freq, t_wr_ps, ONE_BILLION) + 999) / 1000;
+ mtsdram(DDR0_43, ddr0_43 | DDR0_43_TWR_ENCODE(t_wr_clk));
+}
+
+static void program_ddr0_44(unsigned long dimm_ranks[],
+ unsigned char const iic0_dimm_addr[],
+ unsigned long num_dimm_banks,
+ unsigned long sdram_freq)
+{
+ unsigned long dimm_num;
+ unsigned long t_rcd_ps = 0;
+ unsigned long t_rcd_clk;
+
+ /*------------------------------------------------------------------
+ * Handle the timing. We need to find the worst case timing of all
+ * the dimm modules installed.
+ *-----------------------------------------------------------------*/
+ /* loop through all the DIMM slots on the board */
+ for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
+ /* If a dimm is installed in a particular slot ... */
+ if (dimm_ranks[dimm_num]) {
+ unsigned long ps;
+
+ ps = 250 * spd_read(iic0_dimm_addr[dimm_num], 29);
+ t_rcd_ps = max(t_rcd_ps, ps);
+ }
+ }
+ debug("t_rcd_ps = %d\n", t_rcd_ps);
+ t_rcd_clk = (MULDIV64(sdram_freq, t_rcd_ps, ONE_BILLION) + 999) / 1000;
+ mtsdram(DDR0_44, DDR0_44_TRCD_ENCODE(t_rcd_clk));
+}
+
+/*-----------------------------------------------------------------------------+
+ * initdram. Initializes the 440EPx/GPx DDR SDRAM controller.
+ * Note: This routine runs from flash with a stack set up in the chip's
+ * sram space. It is important that the routine does not require .sbss, .bss or
+ * .data sections. It also cannot call routines that require these sections.
+ *-----------------------------------------------------------------------------*/
+/*-----------------------------------------------------------------------------
+ * Function: initdram
+ * Description: Configures SDRAM memory banks for DDR operation.
+ * Auto Memory Configuration option reads the DDR SDRAM EEPROMs
+ * via the IIC bus and then configures the DDR SDRAM memory
+ * banks appropriately. If Auto Memory Configuration is
+ * not used, it is assumed that no DIMM is plugged
+ *-----------------------------------------------------------------------------*/
+long int initdram(int board_type)
+{
+ unsigned char const iic0_dimm_addr[] = SPD_EEPROM_ADDRESS;
+ unsigned long dimm_ranks[MAXDIMMS];
+ unsigned long ranks;
+ unsigned long rows;
+ unsigned long banks;
+ unsigned long cols;
+ unsigned long width;
+ unsigned long const sdram_freq = get_bus_freq(0);
+ unsigned long const num_dimm_banks = sizeof(iic0_dimm_addr); /* on board dimm banks */
+ unsigned long cas_latency = 0; /* to quiet initialization warning */
+ unsigned long dram_size;
+
+ debug("\nEntering initdram()\n");
+
+ /*------------------------------------------------------------------
+ * Stop the DDR-SDRAM controller.
+ *-----------------------------------------------------------------*/
+ mtsdram(DDR0_02, DDR0_02_START_ENCODE(0));
+
+ /*
+ * Make sure I2C controller is initialized
+ * before continuing.
+ */
+ /* switch to correct I2C bus */
+ I2C_SET_BUS(CFG_SPD_BUS_NUM);
+ i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
+
+ /*------------------------------------------------------------------
+ * Clear out the serial presence detect buffers.
+ * Perform IIC reads from the dimm. Fill in the spds.
+ * Check to see if the dimm slots are populated
+ *-----------------------------------------------------------------*/
+ get_spd_info(dimm_ranks, &ranks, iic0_dimm_addr, num_dimm_banks);
+
+ /*------------------------------------------------------------------
+ * Check the frequency supported for the dimms plugged.
+ *-----------------------------------------------------------------*/
+ check_frequency(dimm_ranks, iic0_dimm_addr, num_dimm_banks, sdram_freq);
+
+ /*------------------------------------------------------------------
+ * Check and get size information.
+ *-----------------------------------------------------------------*/
+ get_dimm_size(dimm_ranks, iic0_dimm_addr, num_dimm_banks, &rows, &banks,
+ &cols, &width);
+
+ /*------------------------------------------------------------------
+ * Check the voltage type for the dimms plugged.
+ *-----------------------------------------------------------------*/
+ check_voltage_type(dimm_ranks, iic0_dimm_addr, num_dimm_banks);
+
+ /*------------------------------------------------------------------
+ * Program registers for SDRAM controller.
+ *-----------------------------------------------------------------*/
+ mtsdram(DDR0_00, DDR0_00_DLL_INCREMENT_ENCODE(0x19) |
+ DDR0_00_DLL_START_POINT_DECODE(0x0A));
+
+ mtsdram(DDR0_01, DDR0_01_PLB0_DB_CS_LOWER_ENCODE(0x01) |
+ DDR0_01_PLB0_DB_CS_UPPER_ENCODE(0x00) |
+ DDR0_01_INT_MASK_ENCODE(0xFF));
+
+ program_ddr0_03(dimm_ranks, iic0_dimm_addr, num_dimm_banks, sdram_freq,
+ rows, &cas_latency);
+
+ program_ddr0_04(dimm_ranks, iic0_dimm_addr, num_dimm_banks, sdram_freq);
+
+ program_ddr0_05(dimm_ranks, iic0_dimm_addr, num_dimm_banks, sdram_freq);
+
+ program_ddr0_06(dimm_ranks, iic0_dimm_addr, num_dimm_banks, sdram_freq);
+
+ /*------------------------------------------------------------------
+ * TODO: tFAW not found in SPD. Value of 13 taken from Sequoia
+ * board SDRAM, but may be overly concervate.
+ *-----------------------------------------------------------------*/
+ mtsdram(DDR0_07, DDR0_07_NO_CMD_INIT_ENCODE(0) |
+ DDR0_07_TFAW_ENCODE(13) |
+ DDR0_07_AUTO_REFRESH_MODE_ENCODE(1) |
+ DDR0_07_AREFRESH_ENCODE(0));
+
+ mtsdram(DDR0_08, DDR0_08_WRLAT_ENCODE(cas_latency - 1) |
+ DDR0_08_TCPD_ENCODE(200) | DDR0_08_DQS_N_EN_ENCODE(0) |
+ DDR0_08_DDRII_ENCODE(1));
+
+ mtsdram(DDR0_09, DDR0_09_OCD_ADJUST_PDN_CS_0_ENCODE(0x00) |
+ DDR0_09_RTT_0_ENCODE(0x1) |
+ DDR0_09_WR_DQS_SHIFT_BYPASS_ENCODE(0x1D) |
+ DDR0_09_WR_DQS_SHIFT_ENCODE(DQS_OUT_SHIFT - 0x20));
+
+ program_ddr0_10(dimm_ranks, ranks);
+
+ program_ddr0_11(sdram_freq);
+
+ mtsdram(DDR0_12, DDR0_12_TCKE_ENCODE(3));
+
+ mtsdram(DDR0_14, DDR0_14_DLL_BYPASS_MODE_ENCODE(0) |
+ DDR0_14_REDUC_ENCODE(width <= 40 ? 1 : 0) |
+ DDR0_14_REG_DIMM_ENABLE_ENCODE(0));
+
+ mtsdram(DDR0_17, DDR0_17_DLL_DQS_DELAY_0_ENCODE(DLL_DQS_DELAY));
+
+ mtsdram(DDR0_18, DDR0_18_DLL_DQS_DELAY_4_ENCODE(DLL_DQS_DELAY) |
+ DDR0_18_DLL_DQS_DELAY_3_ENCODE(DLL_DQS_DELAY) |
+ DDR0_18_DLL_DQS_DELAY_2_ENCODE(DLL_DQS_DELAY) |
+ DDR0_18_DLL_DQS_DELAY_1_ENCODE(DLL_DQS_DELAY));
+
+ mtsdram(DDR0_19, DDR0_19_DLL_DQS_DELAY_8_ENCODE(DLL_DQS_DELAY) |
+ DDR0_19_DLL_DQS_DELAY_7_ENCODE(DLL_DQS_DELAY) |
+ DDR0_19_DLL_DQS_DELAY_6_ENCODE(DLL_DQS_DELAY) |
+ DDR0_19_DLL_DQS_DELAY_5_ENCODE(DLL_DQS_DELAY));
+
+ mtsdram(DDR0_20, DDR0_20_DLL_DQS_BYPASS_3_ENCODE(DLL_DQS_BYPASS) |
+ DDR0_20_DLL_DQS_BYPASS_2_ENCODE(DLL_DQS_BYPASS) |
+ DDR0_20_DLL_DQS_BYPASS_1_ENCODE(DLL_DQS_BYPASS) |
+ DDR0_20_DLL_DQS_BYPASS_0_ENCODE(DLL_DQS_BYPASS));
+
+ mtsdram(DDR0_21, DDR0_21_DLL_DQS_BYPASS_7_ENCODE(DLL_DQS_BYPASS) |
+ DDR0_21_DLL_DQS_BYPASS_6_ENCODE(DLL_DQS_BYPASS) |
+ DDR0_21_DLL_DQS_BYPASS_5_ENCODE(DLL_DQS_BYPASS) |
+ DDR0_21_DLL_DQS_BYPASS_4_ENCODE(DLL_DQS_BYPASS));
+
+ program_ddr0_22(dimm_ranks, iic0_dimm_addr, num_dimm_banks, width);
+
+ mtsdram(DDR0_23, DDR0_23_ODT_RD_MAP_CS0_ENCODE(0x0) |
+ DDR0_23_FWC_ENCODE(0));
+
+ program_ddr0_24(ranks);
+
+ program_ddr0_26(sdram_freq);
+
+ program_ddr0_27(sdram_freq);
+
+ mtsdram(DDR0_28, DDR0_28_EMRS3_DATA_ENCODE(0x0000) |
+ DDR0_28_EMRS2_DATA_ENCODE(0x0000));
+
+ mtsdram(DDR0_31, DDR0_31_XOR_CHECK_BITS_ENCODE(0x0000));
+
+ mtsdram(DDR0_42, DDR0_42_ADDR_PINS_DECODE(14 - rows) |
+ DDR0_42_CASLAT_LIN_GATE_ENCODE(2 * cas_latency));
+
+ program_ddr0_43(dimm_ranks, iic0_dimm_addr, num_dimm_banks, sdram_freq,
+ cols, banks);
+
+ program_ddr0_44(dimm_ranks, iic0_dimm_addr, num_dimm_banks, sdram_freq);
+
+ denali_sdram_register_dump();
+
+ dram_size = (width >= 64) ? 8 : 4;
+ dram_size *= 1 << cols;
+ dram_size *= banks;
+ dram_size *= 1 << rows;
+ dram_size *= ranks;
+ debug("dram_size = %lu\n", dram_size);
+
+ /* Start the SDRAM controler */
+ mtsdram(DDR0_02, DDR0_02_START_ENCODE(1));
+ denali_wait_for_dlllock();
+
+#if defined(CONFIG_DDR_DATA_EYE)
+ /* -----------------------------------------------------------+
+ * Perform data eye search if requested.
+ * ----------------------------------------------------------*/
+ program_tlb(0, CFG_SDRAM_BASE, dram_size, TLB_WORD2_I_ENABLE);
+ denali_core_search_data_eye();
+ denali_sdram_register_dump();
+ remove_tlb(CFG_SDRAM_BASE, dram_size);
+#endif
+
+#if defined(CONFIG_ZERO_SDRAM) || defined(CONFIG_DDR_ECC)
+ program_tlb(0, CFG_SDRAM_BASE, dram_size, 0);
+ sync();
+ eieio();
+ /* Zero the memory */
+ debug("Zeroing SDRAM...");
+ dcbz_area(CFG_SDRAM_BASE, dram_size);
+ dflush();
+ debug("Completed\n");
+ sync();
+ eieio();
+ remove_tlb(CFG_SDRAM_BASE, dram_size);
+
+#if defined(CONFIG_DDR_ECC)
+ /*
+ * If ECC is enabled, clear and enable interrupts
+ */
+ if (is_ecc_enabled()) {
+ u32 val;
+
+ sync();
+ eieio();
+ /* Clear error status */
+ mfsdram(DDR0_00, val);
+ mtsdram(DDR0_00, val | DDR0_00_INT_ACK_ALL);
+ /* Set 'int_mask' parameter to functionnal value */
+ mfsdram(DDR0_01, val);
+ mtsdram(DDR0_01, (val & ~DDR0_01_INT_MASK_MASK) |
+ DDR0_01_INT_MASK_ALL_OFF);
+#if defined(CONFIG_DDR_DATA_EYE)
+ /*
+ * Running denali_core_search_data_eye() when ECC is enabled
+ * causes non-ECC machine checks. This clears them.
+ */
+ print_mcsr();
+ mtspr(SPRN_MCSR, mfspr(SPRN_MCSR));
+ print_mcsr();
+#endif
+ sync();
+ eieio();
+ }
+#endif /* defined(CONFIG_DDR_ECC) */
+#endif /* defined(CONFIG_ZERO_SDRAM) || defined(CONFIG_DDR_ECC) */
+
+ program_tlb(0, CFG_SDRAM_BASE, dram_size, MY_TLB_WORD2_I_ENABLE);
+ return dram_size;
+}
+
+void board_add_ram_info(int use_default)
+{
+ u32 val;
+
+ printf(" (ECC");
+ if (!is_ecc_enabled()) {
+ printf(" not");
+ }
+ printf(" enabled, %d MHz", (2 * get_bus_freq(0)) / 1000000);
+
+ mfsdram(DDR0_03, val);
+ printf(", CL%d)", DDR0_03_CASLAT_LIN_DECODE(val) >> 1);
+}
+#endif /* CONFIG_SPD_EEPROM */
diff --git a/cpu/ppc4xx/fdt.c b/cpu/ppc4xx/fdt.c
new file mode 100644
index 0000000000..afcb974068
--- /dev/null
+++ b/cpu/ppc4xx/fdt.c
@@ -0,0 +1,64 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@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>
+#include <ppc4xx.h>
+
+#if defined(CONFIG_OF_LIBFDT)
+#include <libfdt.h>
+#include <libfdt_env.h>
+#include <fdt_support.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void ft_cpu_setup(void *blob, bd_t *bd)
+{
+ sys_info_t sys_info;
+
+ get_sys_info(&sys_info);
+
+ do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, "timebase-frequency",
+ bd->bi_intfreq, 1);
+ do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, "clock-frequency",
+ bd->bi_intfreq, 1);
+ do_fixup_by_path_u32(blob, "/plb", "clock-frequency", sys_info.freqPLB, 1);
+ do_fixup_by_path_u32(blob, "/plb/opb", "clock-frequency", sys_info.freqOPB, 1);
+ do_fixup_by_path_u32(blob, "/plb/opb/ebc", "clock-frequency",
+ sys_info.freqEBC, 1);
+ fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
+
+ /*
+ * Setup all baudrates for the UARTs
+ */
+ do_fixup_by_compat_u32(blob, "ns16550", "clock-frequency", gd->uart_clk, 1);
+
+ /*
+ * Fixup all ethernet nodes
+ * Note: aliases in the dts are required for this
+ */
+ fdt_fixup_ethernet(blob, bd);
+}
+#endif /* CONFIG_OF_LIBFDT */
diff --git a/cpu/ppc4xx/gpio.c b/cpu/ppc4xx/gpio.c
index 50f2fdf113..37d3fa8ef7 100644
--- a/cpu/ppc4xx/gpio.c
+++ b/cpu/ppc4xx/gpio.c
@@ -26,8 +26,8 @@
#include <asm/io.h>
#include <asm/gpio.h>
-#if defined(CFG_440_GPIO_TABLE)
-gpio_param_s gpio_tab[GPIO_GROUP_MAX][GPIO_MAX] = CFG_440_GPIO_TABLE;
+#if defined(CFG_4xx_GPIO_TABLE)
+gpio_param_s const gpio_tab[GPIO_GROUP_MAX][GPIO_MAX] = CFG_4xx_GPIO_TABLE;
#endif
#if defined(GPIO0_OSRL)
@@ -47,7 +47,7 @@ void gpio_config(int pin, int in_out, int gpio_alt, int out_val)
}
if (pin >= GPIO_MAX/2) {
- offs2 = 0x100;
+ offs2 = 0x4;
pin2 = (pin - GPIO_MAX/2) << 1;
}
@@ -55,10 +55,10 @@ void gpio_config(int pin, int in_out, int gpio_alt, int out_val)
mask2 = 0xc0000000 >> (pin2 << 1);
/* first set TCR to 0 */
- out32(GPIO0_TCR + offs, in32(GPIO0_TCR + offs) & ~mask);
+ out_be32((void *)GPIO0_TCR + offs, in_be32((void *)GPIO0_TCR + offs) & ~mask);
if (in_out == GPIO_OUT) {
- val = in32(GPIO0_OSRL + offs + offs2) & ~mask2;
+ val = in_be32((void *)GPIO0_OSRL + offs + offs2) & ~mask2;
switch (gpio_alt) {
case GPIO_ALT1:
val |= GPIO_ALT1_SEL >> pin2;
@@ -70,20 +70,23 @@ void gpio_config(int pin, int in_out, int gpio_alt, int out_val)
val |= GPIO_ALT3_SEL >> pin2;
break;
}
- out32(GPIO0_OSRL + offs + offs2, val);
+ out_be32((void *)GPIO0_OSRL + offs + offs2, val);
/* setup requested output value */
if (out_val == GPIO_OUT_0)
- out32(GPIO0_OR + offs, in32(GPIO0_OR + offs) & ~mask);
+ out_be32((void *)GPIO0_OR + offs,
+ in_be32((void *)GPIO0_OR + offs) & ~mask);
else if (out_val == GPIO_OUT_1)
- out32(GPIO0_OR + offs, in32(GPIO0_OR + offs) | mask);
+ out_be32((void *)GPIO0_OR + offs,
+ in_be32((void *)GPIO0_OR + offs) | mask);
/* now configure TCR to drive output if selected */
- out32(GPIO0_TCR + offs, in32(GPIO0_TCR + offs) | mask);
+ out_be32((void *)GPIO0_TCR + offs,
+ in_be32((void *)GPIO0_TCR + offs) | mask);
} else {
- val = in32(GPIO0_ISR1L + offs + offs2) & ~mask2;
+ val = in_be32((void *)GPIO0_ISR1L + offs + offs2) & ~mask2;
val |= GPIO_IN_SEL >> pin2;
- out32(GPIO0_ISR1L + offs + offs2, val);
+ out_be32((void *)GPIO0_ISR1L + offs + offs2, val);
}
}
#endif /* GPIO_OSRL */
@@ -98,9 +101,11 @@ void gpio_write_bit(int pin, int val)
}
if (val)
- out32(GPIO0_OR + offs, in32(GPIO0_OR + offs) | GPIO_VAL(pin));
+ out_be32((void *)GPIO0_OR + offs,
+ in_be32((void *)GPIO0_OR + offs) | GPIO_VAL(pin));
else
- out32(GPIO0_OR + offs, in32(GPIO0_OR + offs) & ~GPIO_VAL(pin));
+ out_be32((void *)GPIO0_OR + offs,
+ in_be32((void *)GPIO0_OR + offs) & ~GPIO_VAL(pin));
}
int gpio_read_out_bit(int pin)
@@ -112,10 +117,22 @@ int gpio_read_out_bit(int pin)
pin -= GPIO_MAX;
}
- return (in32(GPIO0_OR + offs) & GPIO_VAL(pin) ? 1 : 0);
+ return (in_be32((void *)GPIO0_OR + offs) & GPIO_VAL(pin) ? 1 : 0);
}
-#if defined(CFG_440_GPIO_TABLE)
+int gpio_read_in_bit(int pin)
+{
+ u32 offs = 0;
+
+ if (pin >= GPIO_MAX) {
+ offs = 0x100;
+ pin -= GPIO_MAX;
+ }
+
+ return (in_be32((void *)GPIO0_IR + offs) & GPIO_VAL(pin) ? 1 : 0);
+}
+
+#if defined(CFG_4xx_GPIO_TABLE)
void gpio_set_chip_configuration(void)
{
unsigned char i=0, j=0, offs=0, gpio_core;
@@ -141,24 +158,24 @@ void gpio_set_chip_configuration(void)
break;
case GPIO_ALT1:
- reg = in32(GPIO_IS1(core_add+offs))
+ reg = in_be32((void *)GPIO_IS1(core_add+offs))
& ~(GPIO_MASK >> (j*2));
reg = reg | (GPIO_IN_SEL >> (j*2));
- out32(GPIO_IS1(core_add+offs), reg);
+ out_be32((void *)GPIO_IS1(core_add+offs), reg);
break;
case GPIO_ALT2:
- reg = in32(GPIO_IS2(core_add+offs))
+ reg = in_be32((void *)GPIO_IS2(core_add+offs))
& ~(GPIO_MASK >> (j*2));
reg = reg | (GPIO_IN_SEL >> (j*2));
- out32(GPIO_IS2(core_add+offs), reg);
+ out_be32((void *)GPIO_IS2(core_add+offs), reg);
break;
case GPIO_ALT3:
- reg = in32(GPIO_IS3(core_add+offs))
+ reg = in_be32((void *)GPIO_IS3(core_add+offs))
& ~(GPIO_MASK >> (j*2));
reg = reg | (GPIO_IN_SEL >> (j*2));
- out32(GPIO_IS3(core_add+offs), reg);
+ out_be32((void *)GPIO_IS3(core_add+offs), reg);
break;
}
}
@@ -166,89 +183,73 @@ void gpio_set_chip_configuration(void)
if ((gpio_tab[gpio_core][i].in_out == GPIO_OUT) ||
(gpio_tab[gpio_core][i].in_out == GPIO_BI)) {
+ u32 gpio_alt_sel = 0;
+
switch (gpio_tab[gpio_core][i].alt_nb) {
case GPIO_SEL:
- if (gpio_core == GPIO0) {
- /*
- * Setup output value
- * 1 -> high level
- * 0 -> low level
- * else -> don't touch
- */
- reg = in32(GPIO0_OR);
- if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_1)
- reg |= (0x80000000 >> (i));
- else if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_0)
- reg &= ~(0x80000000 >> (i));
- out32(GPIO0_OR, reg);
-
- reg = in32(GPIO0_TCR) | (0x80000000 >> (i));
- out32(GPIO0_TCR, reg);
- }
-
-#ifdef GPIO1
- if (gpio_core == GPIO1) {
- /*
- * Setup output value
- * 1 -> high level
- * 0 -> low level
- * else -> don't touch
- */
- reg = in32(GPIO1_OR);
- if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_1)
- reg |= (0x80000000 >> (i));
- else if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_0)
- reg &= ~(0x80000000 >> (i));
- out32(GPIO1_OR, reg);
-
- reg = in32(GPIO1_TCR) | (0x80000000 >> (i));
- out32(GPIO1_TCR, reg);
- }
-#endif /* GPIO1 */
-
- reg = in32(GPIO_OS(core_add+offs))
+ /*
+ * Setup output value
+ * 1 -> high level
+ * 0 -> low level
+ * else -> don't touch
+ */
+ reg = in_be32((void *)GPIO_OR(core_add));
+ if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_1)
+ reg |= (0x80000000 >> (i));
+ else if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_0)
+ reg &= ~(0x80000000 >> (i));
+ out_be32((void *)GPIO_OR(core_add), reg);
+
+ reg = in_be32((void *)GPIO_TCR(core_add)) |
+ (0x80000000 >> (i));
+ out_be32((void *)GPIO_TCR(core_add), reg);
+
+ reg = in_be32((void *)GPIO_OS(core_add+offs))
& ~(GPIO_MASK >> (j*2));
- out32(GPIO_OS(core_add+offs), reg);
- reg = in32(GPIO_TS(core_add+offs))
+ out_be32((void *)GPIO_OS(core_add+offs), reg);
+ reg = in_be32((void *)GPIO_TS(core_add+offs))
& ~(GPIO_MASK >> (j*2));
- out32(GPIO_TS(core_add+offs), reg);
+ out_be32((void *)GPIO_TS(core_add+offs), reg);
break;
case GPIO_ALT1:
- reg = in32(GPIO_OS(core_add+offs))
- & ~(GPIO_MASK >> (j*2));
- reg = reg | (GPIO_ALT1_SEL >> (j*2));
- out32(GPIO_OS(core_add+offs), reg);
- reg = in32(GPIO_TS(core_add+offs))
- & ~(GPIO_MASK >> (j*2));
- reg = reg | (GPIO_ALT1_SEL >> (j*2));
- out32(GPIO_TS(core_add+offs), reg);
+ gpio_alt_sel = GPIO_ALT1_SEL;
break;
case GPIO_ALT2:
- reg = in32(GPIO_OS(core_add+offs))
- & ~(GPIO_MASK >> (j*2));
- reg = reg | (GPIO_ALT2_SEL >> (j*2));
- out32(GPIO_OS(core_add+offs), reg);
- reg = in32(GPIO_TS(core_add+offs))
- & ~(GPIO_MASK >> (j*2));
- reg = reg | (GPIO_ALT2_SEL >> (j*2));
- out32(GPIO_TS(core_add+offs), reg);
+ gpio_alt_sel = GPIO_ALT2_SEL;
break;
case GPIO_ALT3:
- reg = in32(GPIO_OS(core_add+offs))
- & ~(GPIO_MASK >> (j*2));
- reg = reg | (GPIO_ALT3_SEL >> (j*2));
- out32(GPIO_OS(core_add+offs), reg);
- reg = in32(GPIO_TS(core_add+offs))
- & ~(GPIO_MASK >> (j*2));
- reg = reg | (GPIO_ALT3_SEL >> (j*2));
- out32(GPIO_TS(core_add+offs), reg);
+ gpio_alt_sel = GPIO_ALT3_SEL;
break;
}
+
+ if (0 != gpio_alt_sel) {
+ reg = in_be32((void *)GPIO_OS(core_add+offs))
+ & ~(GPIO_MASK >> (j*2));
+ reg = reg | (gpio_alt_sel >> (j*2));
+ out_be32((void *)GPIO_OS(core_add+offs), reg);
+
+ if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_1) {
+ reg = in_be32((void *)GPIO_TCR(core_add))
+ | (0x80000000 >> (i));
+ out_be32((void *)GPIO_TCR(core_add), reg);
+ reg = in_be32((void *)GPIO_TS(core_add+offs))
+ & ~(GPIO_MASK >> (j*2));
+ out_be32((void *)GPIO_TS(core_add+offs), reg);
+ } else {
+ reg = in_be32((void *)GPIO_TCR(core_add))
+ & ~(0x80000000 >> (i));
+ out_be32((void *)GPIO_TCR(core_add), reg);
+ reg = in_be32((void *)GPIO_TS(core_add+offs))
+ & ~(GPIO_MASK >> (j*2));
+ reg = reg | (gpio_alt_sel >> (j*2));
+ out_be32((void *)GPIO_TS(core_add+offs), reg);
+ }
+ }
}
}
}
}
-#endif /* CFG_440_GPIO_TABLE */
+#endif /* CFG_4xx_GPIO_TABLE */
diff --git a/cpu/ppc4xx/interrupts.c b/cpu/ppc4xx/interrupts.c
index ca565cc3e0..2f3dc326b4 100644
--- a/cpu/ppc4xx/interrupts.c
+++ b/cpu/ppc4xx/interrupts.c
@@ -34,7 +34,7 @@
#include <ppc4xx.h>
#include <ppc_asm.tmpl>
#include <commproc.h>
-#include "vecnum.h"
+#include <asm/ppc4xx-intvec.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -52,7 +52,7 @@ struct irq_action {
static struct irq_action irq_vecs[32];
void uic0_interrupt( void * parms); /* UIC0 handler */
-#if defined(CONFIG_440)
+#if defined(CONFIG_440) || defined(CONFIG_405EX)
static struct irq_action irq_vecs1[32]; /* For UIC1 */
void uic1_interrupt( void * parms); /* UIC1 handler */
@@ -116,7 +116,7 @@ int interrupt_init_cpu (unsigned *decrementer_count)
irq_vecs[vec].handler = NULL;
irq_vecs[vec].arg = NULL;
irq_vecs[vec].count = 0;
-#if defined(CONFIG_440)
+#if defined(CONFIG_440) || defined(CONFIG_405EX)
irq_vecs1[vec].handler = NULL;
irq_vecs1[vec].arg = NULL;
irq_vecs1[vec].count = 0;
@@ -172,7 +172,7 @@ int interrupt_init_cpu (unsigned *decrementer_count)
*/
set_evpr(0x00000000);
-#if defined(CONFIG_440)
+#if defined(CONFIG_440) || defined(CONFIG_405EX)
#if !defined(CONFIG_440GX)
/* Install the UIC1 handlers */
irq_install_handler(VECNUM_UIC1NC, uic1_interrupt, 0);
@@ -378,7 +378,7 @@ void uic0_interrupt( void * parms)
#endif /* CONFIG_440GX */
-#if defined(CONFIG_440)
+#if defined(CONFIG_440) || defined(CONFIG_405EX)
/* Handler for UIC1 interrupt */
void uic1_interrupt( void * parms)
{
@@ -525,7 +525,7 @@ void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg)
struct irq_action *irqa = irq_vecs;
int i = vec;
-#if defined(CONFIG_440)
+#if defined(CONFIG_440) || defined(CONFIG_405EX)
#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
if ((vec > 31) && (vec < 64)) {
@@ -553,7 +553,7 @@ void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg)
irqa[i].handler = handler;
irqa[i].arg = arg;
-#if defined(CONFIG_440)
+#if defined(CONFIG_440) || defined(CONFIG_405EX)
#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
if ((vec > 31) && (vec < 64))
@@ -577,7 +577,7 @@ void irq_free_handler (int vec)
struct irq_action *irqa = irq_vecs;
int i = vec;
-#if defined(CONFIG_440)
+#if defined(CONFIG_440) || defined(CONFIG_405EX)
#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
if ((vec > 31) && (vec < 64)) {
@@ -599,7 +599,7 @@ void irq_free_handler (int vec)
vec, irq_vecs[vec].handler);
#endif
-#if defined(CONFIG_440)
+#if defined(CONFIG_440) || defined(CONFIG_405EX)
#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
if ((vec > 31) && (vec < 64))
@@ -641,7 +641,7 @@ do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int vec;
printf ("\nInterrupt-Information:\n");
-#if defined(CONFIG_440)
+#if defined(CONFIG_440) || defined(CONFIG_405EX)
printf ("\nUIC 0\n");
#endif
printf ("Nr Routine Arg Count\n");
@@ -656,7 +656,7 @@ do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
}
}
-#if defined(CONFIG_440)
+#if defined(CONFIG_440) || defined(CONFIG_405EX)
printf ("\nUIC 1\n");
printf ("Nr Routine Arg Count\n");
diff --git a/cpu/ppc4xx/iop480_uart.c b/cpu/ppc4xx/iop480_uart.c
new file mode 100644
index 0000000000..3af0767c55
--- /dev/null
+++ b/cpu/ppc4xx/iop480_uart.c
@@ -0,0 +1,238 @@
+/*
+ * (C) Copyright 2000-2006
+ * 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 <commproc.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <watchdog.h>
+#include <asm/ppc4xx-intvec.h>
+
+#ifdef CONFIG_SERIAL_MULTI
+#include <serial.h>
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_IOP480
+
+#define SPU_BASE 0x40000000
+
+#define spu_LineStat_rc 0x00 /* Line Status Register (Read/Clear) */
+#define spu_LineStat_w 0x04 /* Line Status Register (Set) */
+#define spu_Handshk_rc 0x08 /* Handshake Status Register (Read/Clear) */
+#define spu_Handshk_w 0x0c /* Handshake Status Register (Set) */
+#define spu_BRateDivh 0x10 /* Baud rate divisor high */
+#define spu_BRateDivl 0x14 /* Baud rate divisor low */
+#define spu_CtlReg 0x18 /* Control Register */
+#define spu_RxCmd 0x1c /* Rx Command Register */
+#define spu_TxCmd 0x20 /* Tx Command Register */
+#define spu_RxBuff 0x24 /* Rx data buffer */
+#define spu_TxBuff 0x24 /* Tx data buffer */
+
+/*-----------------------------------------------------------------------------+
+ | Line Status Register.
+ +-----------------------------------------------------------------------------*/
+#define asyncLSRport1 0x40000000
+#define asyncLSRport1set 0x40000004
+#define asyncLSRDataReady 0x80
+#define asyncLSRFramingError 0x40
+#define asyncLSROverrunError 0x20
+#define asyncLSRParityError 0x10
+#define asyncLSRBreakInterrupt 0x08
+#define asyncLSRTxHoldEmpty 0x04
+#define asyncLSRTxShiftEmpty 0x02
+
+/*-----------------------------------------------------------------------------+
+ | Handshake Status Register.
+ +-----------------------------------------------------------------------------*/
+#define asyncHSRport1 0x40000008
+#define asyncHSRport1set 0x4000000c
+#define asyncHSRDsr 0x80
+#define asyncLSRCts 0x40
+
+/*-----------------------------------------------------------------------------+
+ | Control Register.
+ +-----------------------------------------------------------------------------*/
+#define asyncCRport1 0x40000018
+#define asyncCRNormal 0x00
+#define asyncCRLoopback 0x40
+#define asyncCRAutoEcho 0x80
+#define asyncCRDtr 0x20
+#define asyncCRRts 0x10
+#define asyncCRWordLength7 0x00
+#define asyncCRWordLength8 0x08
+#define asyncCRParityDisable 0x00
+#define asyncCRParityEnable 0x04
+#define asyncCREvenParity 0x00
+#define asyncCROddParity 0x02
+#define asyncCRStopBitsOne 0x00
+#define asyncCRStopBitsTwo 0x01
+#define asyncCRDisableDtrRts 0x00
+
+/*-----------------------------------------------------------------------------+
+ | Receiver Command Register.
+ +-----------------------------------------------------------------------------*/
+#define asyncRCRport1 0x4000001c
+#define asyncRCRDisable 0x00
+#define asyncRCREnable 0x80
+#define asyncRCRIntDisable 0x00
+#define asyncRCRIntEnabled 0x20
+#define asyncRCRDMACh2 0x40
+#define asyncRCRDMACh3 0x60
+#define asyncRCRErrorInt 0x10
+#define asyncRCRPauseEnable 0x08
+
+/*-----------------------------------------------------------------------------+
+ | Transmitter Command Register.
+ +-----------------------------------------------------------------------------*/
+#define asyncTCRport1 0x40000020
+#define asyncTCRDisable 0x00
+#define asyncTCREnable 0x80
+#define asyncTCRIntDisable 0x00
+#define asyncTCRIntEnabled 0x20
+#define asyncTCRDMACh2 0x40
+#define asyncTCRDMACh3 0x60
+#define asyncTCRTxEmpty 0x10
+#define asyncTCRErrorInt 0x08
+#define asyncTCRStopPause 0x04
+#define asyncTCRBreakGen 0x02
+
+/*-----------------------------------------------------------------------------+
+ | Miscellanies defines.
+ +-----------------------------------------------------------------------------*/
+#define asyncTxBufferport1 0x40000024
+#define asyncRxBufferport1 0x40000024
+#define asyncDLABLsbport1 0x40000014
+#define asyncDLABMsbport1 0x40000010
+#define asyncXOFFchar 0x13
+#define asyncXONchar 0x11
+
+/*
+ * Minimal serial functions needed to use one of the SMC ports
+ * as serial console interface.
+ */
+
+int serial_init (void)
+{
+ volatile char val;
+ unsigned short br_reg;
+
+ br_reg = ((((CONFIG_CPUCLOCK * 1000000) / 16) / gd->baudrate) - 1);
+
+ /*
+ * Init onboard UART
+ */
+ out_8((u8 *)SPU_BASE + spu_LineStat_rc, 0x78); /* Clear all bits in Line Status Reg */
+ out_8((u8 *)SPU_BASE + spu_BRateDivl, (br_reg & 0x00ff)); /* Set baud rate divisor... */
+ out_8((u8 *)SPU_BASE + spu_BRateDivh, ((br_reg & 0xff00) >> 8)); /* ... */
+ out_8((u8 *)SPU_BASE + spu_CtlReg, 0x08); /* Set 8 bits, no parity and 1 stop bit */
+ out_8((u8 *)SPU_BASE + spu_RxCmd, 0xb0); /* Enable Rx */
+ out_8((u8 *)SPU_BASE + spu_TxCmd, 0x9c); /* Enable Tx */
+ out_8((u8 *)SPU_BASE + spu_Handshk_rc, 0xff); /* Clear Handshake */
+ val = in_8((u8 *)SPU_BASE + spu_RxBuff); /* Dummy read, to clear receiver */
+
+ return (0);
+}
+
+void serial_setbrg (void)
+{
+ unsigned short br_reg;
+
+ br_reg = ((((CONFIG_CPUCLOCK * 1000000) / 16) / gd->baudrate) - 1);
+
+ out_8((u8 *)SPU_BASE + spu_BRateDivl,
+ (br_reg & 0x00ff)); /* Set baud rate divisor... */
+ out_8((u8 *)SPU_BASE + spu_BRateDivh,
+ ((br_reg & 0xff00) >> 8)); /* ... */
+}
+
+void serial_putc (const char c)
+{
+ if (c == '\n')
+ serial_putc ('\r');
+
+ /* load status from handshake register */
+ if (in_8((u8 *)SPU_BASE + spu_Handshk_rc) != 00)
+ out_8((u8 *)SPU_BASE + spu_Handshk_rc, 0xff); /* Clear Handshake */
+
+ out_8((u8 *)SPU_BASE + spu_TxBuff, c); /* Put char */
+
+ while ((in_8((u8 *)SPU_BASE + spu_LineStat_rc) & 04) != 04) {
+ if (in_8((u8 *)SPU_BASE + spu_Handshk_rc) != 00)
+ out_8((u8 *)SPU_BASE + spu_Handshk_rc, 0xff); /* Clear Handshake */
+ }
+}
+
+void serial_puts (const char *s)
+{
+ while (*s) {
+ serial_putc (*s++);
+ }
+}
+
+int serial_getc ()
+{
+ unsigned char status = 0;
+
+ while (1) {
+ status = in_8((u8 *)asyncLSRport1);
+ if ((status & asyncLSRDataReady) != 0x0) {
+ break;
+ }
+ if ((status & ( asyncLSRFramingError |
+ asyncLSROverrunError |
+ asyncLSRParityError |
+ asyncLSRBreakInterrupt )) != 0) {
+ (void) out_8((u8 *)asyncLSRport1,
+ asyncLSRFramingError |
+ asyncLSROverrunError |
+ asyncLSRParityError |
+ asyncLSRBreakInterrupt );
+ }
+ }
+ return (0x000000ff & (int) in_8((u8 *)asyncRxBufferport1));
+}
+
+int serial_tstc ()
+{
+ unsigned char status;
+
+ status = in_8((u8 *)asyncLSRport1);
+ if ((status & asyncLSRDataReady) != 0x0) {
+ return (1);
+ }
+ if ((status & ( asyncLSRFramingError |
+ asyncLSROverrunError |
+ asyncLSRParityError |
+ asyncLSRBreakInterrupt )) != 0) {
+ (void) out_8((u8 *)asyncLSRport1,
+ asyncLSRFramingError |
+ asyncLSROverrunError |
+ asyncLSRParityError |
+ asyncLSRBreakInterrupt);
+ }
+ return 0;
+}
+
+#endif /* CONFIG_IOP480 */
diff --git a/cpu/ppc4xx/kgdb.S b/cpu/ppc4xx/kgdb.S
index 8c4bbf2e4d..42b9546d3d 100644
--- a/cpu/ppc4xx/kgdb.S
+++ b/cpu/ppc4xx/kgdb.S
@@ -56,21 +56,21 @@ kgdb_flush_cache_all:
.globl kgdb_flush_cache_range
kgdb_flush_cache_range:
- li r5,CFG_CACHELINE_SIZE-1
+ li r5,L1_CACHE_BYTES-1
andc r3,r3,r5
subf r4,r3,r4
add r4,r4,r5
- srwi. r4,r4,CFG_CACHELINE_SHIFT
+ srwi. r4,r4,L1_CACHE_SHIFT
beqlr
mtctr r4
mr r6,r3
1: dcbst 0,r3
- addi r3,r3,CFG_CACHELINE_SIZE
+ addi r3,r3,L1_CACHE_BYTES
bdnz 1b
sync /* wait for dcbst's to get to ram */
mtctr r4
2: icbi 0,r6
- addi r6,r6,CFG_CACHELINE_SIZE
+ addi r6,r6,L1_CACHE_BYTES
bdnz 2b
SYNC
blr
diff --git a/cpu/ppc4xx/miiphy.c b/cpu/ppc4xx/miiphy.c
index 6b98025308..4216f0bd41 100644
--- a/cpu/ppc4xx/miiphy.c
+++ b/cpu/ppc4xx/miiphy.c
@@ -27,23 +27,11 @@
|
| Author: Mark Wisner
|
- | Change Activity-
- |
- | Date Description of Change BY
- | --------- --------------------- ---
- | 05-May-99 Created MKW
- | 01-Jul-99 Changed clock setting of sta_reg from 66Mhz to 50Mhz to
- | better match OPB speed. Also modified delay times. JWB
- | 29-Jul-99 Added Full duplex support MKW
- | 24-Aug-99 Removed printf from dp83843_duplex() JWB
- | 19-Jul-00 Ported to esd cpci405 sr
- | 23-Dec-03 Ported from miiphy.c to 440GX Travis Sawyer TBS
- | <travis.sawyer@sandburst.com>
- |
+-----------------------------------------------------------------------------*/
#include <common.h>
#include <asm/processor.h>
+#include <asm/io.h>
#include <ppc_asm.tmpl>
#include <commproc.h>
#include <ppc4xx_enet.h>
@@ -60,7 +48,6 @@ void miiphy_dump (char *devname, unsigned char addr)
unsigned long i;
unsigned short data;
-
for (i = 0; i < 0x1A; i++) {
if (miiphy_read (devname, addr, i, &data)) {
printf ("read error for reg %lx\n", i);
@@ -75,15 +62,86 @@ void miiphy_dump (char *devname, unsigned char addr)
} /* end for loop */
} /* end dump */
-
/***********************************************************/
/* (Re)start autonegotiation */
/***********************************************************/
int phy_setup_aneg (char *devname, unsigned char addr)
{
- unsigned short ctl, adv;
+ u16 bmcr;
+
+#if defined(CONFIG_PHY_DYNAMIC_ANEG)
+ /*
+ * Set up advertisement based on capablilities reported by the PHY.
+ * This should work for both copper and fiber.
+ */
+ u16 bmsr;
+#if defined(CONFIG_PHY_GIGE)
+ u16 exsr = 0x0000;
+#endif
+
+ miiphy_read (devname, addr, PHY_BMSR, &bmsr);
+
+#if defined(CONFIG_PHY_GIGE)
+ if (bmsr & PHY_BMSR_EXT_STAT)
+ miiphy_read (devname, addr, PHY_EXSR, &exsr);
+
+ if (exsr & (PHY_EXSR_1000XF | PHY_EXSR_1000XH)) {
+ /* 1000BASE-X */
+ u16 anar = 0x0000;
+
+ if (exsr & PHY_EXSR_1000XF)
+ anar |= PHY_X_ANLPAR_FD;
+
+ if (exsr & PHY_EXSR_1000XH)
+ anar |= PHY_X_ANLPAR_HD;
+
+ miiphy_write (devname, addr, PHY_ANAR, anar);
+ } else
+#endif
+ {
+ u16 anar, btcr;
+
+ miiphy_read (devname, addr, PHY_ANAR, &anar);
+ anar &= ~(0x5000 | PHY_ANLPAR_T4 | PHY_ANLPAR_TXFD |
+ PHY_ANLPAR_TX | PHY_ANLPAR_10FD | PHY_ANLPAR_10);
+
+ miiphy_read (devname, addr, PHY_1000BTCR, &btcr);
+ btcr &= ~(0x00FF | PHY_1000BTCR_1000FD | PHY_1000BTCR_1000HD);
+
+ if (bmsr & PHY_BMSR_100T4)
+ anar |= PHY_ANLPAR_T4;
+
+ if (bmsr & PHY_BMSR_100TXF)
+ anar |= PHY_ANLPAR_TXFD;
+
+ if (bmsr & PHY_BMSR_100TXH)
+ anar |= PHY_ANLPAR_TX;
+
+ if (bmsr & PHY_BMSR_10TF)
+ anar |= PHY_ANLPAR_10FD;
+
+ if (bmsr & PHY_BMSR_10TH)
+ anar |= PHY_ANLPAR_10;
+
+ miiphy_write (devname, addr, PHY_ANAR, anar);
+
+#if defined(CONFIG_PHY_GIGE)
+ if (exsr & PHY_EXSR_1000TF)
+ btcr |= PHY_1000BTCR_1000FD;
+
+ if (exsr & PHY_EXSR_1000TH)
+ btcr |= PHY_1000BTCR_1000HD;
+
+ miiphy_write (devname, addr, PHY_1000BTCR, btcr);
+#endif
+ }
+
+#else /* defined(CONFIG_PHY_DYNAMIC_ANEG) */
+ /*
+ * Set up standard advertisement
+ */
+ u16 adv;
- /* Setup standard advertise */
miiphy_read (devname, addr, PHY_ANAR, &adv);
adv |= (PHY_ANLPAR_ACK | PHY_ANLPAR_RF | PHY_ANLPAR_T4 |
PHY_ANLPAR_TXFD | PHY_ANLPAR_TX | PHY_ANLPAR_10FD |
@@ -94,15 +152,16 @@ int phy_setup_aneg (char *devname, unsigned char addr)
adv |= (0x0300);
miiphy_write (devname, addr, PHY_1000BTCR, adv);
+#endif /* defined(CONFIG_PHY_DYNAMIC_ANEG) */
+
/* Start/Restart aneg */
- miiphy_read (devname, addr, PHY_BMCR, &ctl);
- ctl |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);
- miiphy_write (devname, addr, PHY_BMCR, ctl);
+ miiphy_read (devname, addr, PHY_BMCR, &bmcr);
+ bmcr |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);
+ miiphy_write (devname, addr, PHY_BMCR, bmcr);
return 0;
}
-
/***********************************************************/
/* read a phy reg and return the value with a rc */
/***********************************************************/
@@ -113,57 +172,70 @@ unsigned int miiphy_getemac_offset (void)
unsigned long eoffset;
/* Need to find out which mdi port we're using */
- zmii = in32 (ZMII_FER);
+ zmii = in_be32((void *)ZMII_FER);
- if (zmii & (ZMII_FER_MDI << ZMII_FER_V (0))) {
+ if (zmii & (ZMII_FER_MDI << ZMII_FER_V (0)))
/* using port 0 */
eoffset = 0;
- } else if (zmii & (ZMII_FER_MDI << ZMII_FER_V (1))) {
+
+ else if (zmii & (ZMII_FER_MDI << ZMII_FER_V (1)))
/* using port 1 */
eoffset = 0x100;
- } else if (zmii & (ZMII_FER_MDI << ZMII_FER_V (2))) {
+
+ else if (zmii & (ZMII_FER_MDI << ZMII_FER_V (2)))
/* using port 2 */
eoffset = 0x400;
- } else if (zmii & (ZMII_FER_MDI << ZMII_FER_V (3))) {
+
+ else if (zmii & (ZMII_FER_MDI << ZMII_FER_V (3)))
/* using port 3 */
eoffset = 0x600;
- } else {
+
+ else {
/* None of the mdi ports are enabled! */
/* enable port 0 */
zmii |= ZMII_FER_MDI << ZMII_FER_V (0);
- out32 (ZMII_FER, zmii);
+ out_be32((void *)ZMII_FER, zmii);
eoffset = 0;
/* need to soft reset port 0 */
- zmii = in32 (EMAC_M0);
+ zmii = in_be32((void *)EMAC_M0);
zmii |= EMAC_M0_SRST;
- out32 (EMAC_M0, zmii);
+ out_be32((void *)EMAC_M0, zmii);
}
return (eoffset);
#else
+
+#if defined(CONFIG_NET_MULTI) && defined(CONFIG_405EX)
+ unsigned long rgmii;
+ int devnum = 1;
+
+ rgmii = in_be32((void *)RGMII_FER);
+ if (rgmii & (1 << (19 - devnum)))
+ return 0x100;
+#endif
+
return 0;
#endif
}
-
-int emac4xx_miiphy_read (char *devname, unsigned char addr,
- unsigned char reg, unsigned short *value)
+int emac4xx_miiphy_read (char *devname, unsigned char addr, unsigned char reg,
+ unsigned short *value)
{
unsigned long sta_reg; /* STA scratch area */
unsigned long i;
unsigned long emac_reg;
-
emac_reg = miiphy_getemac_offset ();
/* see if it is ready for 1000 nsec */
i = 0;
/* see if it is ready for sec */
- while ((in32 (EMAC_STACR + emac_reg) & EMAC_STACR_OC) == EMAC_STACR_OC_MASK) {
+ while ((in_be32((void *)EMAC_STACR + emac_reg) & EMAC_STACR_OC) ==
+ EMAC_STACR_OC_MASK) {
udelay (7);
if (i > 5) {
#ifdef ET_DEBUG
- sta_reg = in32 (EMAC_STACR + emac_reg);
+ sta_reg = in_be32((void *)EMAC_STACR + emac_reg);
printf ("read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */
printf ("read err 1\n");
#endif
@@ -174,11 +246,12 @@ int emac4xx_miiphy_read (char *devname, unsigned char addr,
sta_reg = reg; /* reg address */
/* set clock (50Mhz) and read flags */
#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
- defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
-#if defined(CONFIG_IBM_EMAC4_V4) /* EMAC4 V4 changed bit setting */
- sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_READ;
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_405EX)
+#if defined(CONFIG_IBM_EMAC4_V4) /* EMAC4 V4 changed bit setting */
+ sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_READ;
#else
- sta_reg |= EMAC_STACR_READ;
+ sta_reg |= EMAC_STACR_READ;
#endif
#else
sta_reg = (sta_reg | EMAC_STACR_READ) & ~EMAC_STACR_CLK_100MHZ;
@@ -186,49 +259,47 @@ int emac4xx_miiphy_read (char *devname, unsigned char addr,
#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && \
!defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
- !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
+ !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX) && \
+ !defined(CONFIG_405EX)
sta_reg = sta_reg | CONFIG_PHY_CLK_FREQ;
#endif
sta_reg = sta_reg | (addr << 5); /* Phy address */
sta_reg = sta_reg | EMAC_STACR_OC_MASK; /* new IBM emac v4 */
- out32 (EMAC_STACR + emac_reg, sta_reg);
+ out_be32((void *)EMAC_STACR + emac_reg, sta_reg);
#ifdef ET_DEBUG
printf ("a2: write: EMAC_STACR=0x%0x\n", sta_reg); /* test-only */
#endif
- sta_reg = in32 (EMAC_STACR + emac_reg);
+ sta_reg = in_be32((void *)EMAC_STACR + emac_reg);
#ifdef ET_DEBUG
- printf ("a21: read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */
+ printf ("a21: read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */
#endif
i = 0;
while ((sta_reg & EMAC_STACR_OC) == EMAC_STACR_OC_MASK) {
udelay (7);
- if (i > 5) {
+ if (i > 5)
return -1;
- }
+
i++;
- sta_reg = in32 (EMAC_STACR + emac_reg);
+ sta_reg = in_be32((void *)EMAC_STACR + emac_reg);
#ifdef ET_DEBUG
printf ("a22: read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */
#endif
}
- if ((sta_reg & EMAC_STACR_PHYE) != 0) {
+ if ((sta_reg & EMAC_STACR_PHYE) != 0)
return -1;
- }
- *value = *(short *) (&sta_reg);
+ *value = *(short *)(&sta_reg);
return 0;
-
} /* phy_read */
-
/***********************************************************/
/* write a phy reg and return the value with a rc */
/***********************************************************/
-int emac4xx_miiphy_write (char *devname, unsigned char addr,
- unsigned char reg, unsigned short value)
+int emac4xx_miiphy_write (char *devname, unsigned char addr, unsigned char reg,
+ unsigned short value)
{
unsigned long sta_reg; /* STA scratch area */
unsigned long i;
@@ -238,9 +309,11 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr,
/* see if it is ready for 1000 nsec */
i = 0;
- while ((in32 (EMAC_STACR + emac_reg) & EMAC_STACR_OC) == EMAC_STACR_OC_MASK) {
+ while ((in_be32((void *)EMAC_STACR + emac_reg) & EMAC_STACR_OC) ==
+ EMAC_STACR_OC_MASK) {
if (i > 5)
return -1;
+
udelay (7);
i++;
}
@@ -248,11 +321,12 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr,
sta_reg = reg; /* reg address */
/* set clock (50Mhz) and read flags */
#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
- defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
-#if defined(CONFIG_IBM_EMAC4_V4) /* EMAC4 V4 changed bit setting */
- sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_WRITE;
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_405EX)
+#if defined(CONFIG_IBM_EMAC4_V4) /* EMAC4 V4 changed bit setting */
+ sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_WRITE;
#else
- sta_reg |= EMAC_STACR_WRITE;
+ sta_reg |= EMAC_STACR_WRITE;
#endif
#else
sta_reg = (sta_reg | EMAC_STACR_WRITE) & ~EMAC_STACR_CLK_100MHZ;
@@ -260,27 +334,29 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr,
#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && \
!defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
- !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
+ !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX) && \
+ !defined(CONFIG_405EX)
sta_reg = sta_reg | CONFIG_PHY_CLK_FREQ; /* Set clock frequency (PLB freq. dependend) */
#endif
- sta_reg = sta_reg | ((unsigned long) addr << 5);/* Phy address */
- sta_reg = sta_reg | EMAC_STACR_OC_MASK; /* new IBM emac v4 */
+ sta_reg = sta_reg | ((unsigned long)addr << 5); /* Phy address */
+ sta_reg = sta_reg | EMAC_STACR_OC_MASK; /* new IBM emac v4 */
memcpy (&sta_reg, &value, 2); /* put in data */
- out32 (EMAC_STACR + emac_reg, sta_reg);
+ out_be32((void *)EMAC_STACR + emac_reg, sta_reg);
/* wait for completion */
i = 0;
- sta_reg = in32 (EMAC_STACR + emac_reg);
+ sta_reg = in_be32((void *)EMAC_STACR + emac_reg);
#ifdef ET_DEBUG
- printf ("a31: read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */
+ printf ("a31: read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */
#endif
while ((sta_reg & EMAC_STACR_OC) == EMAC_STACR_OC_MASK) {
udelay (7);
if (i > 5)
return -1;
+
i++;
- sta_reg = in32 (EMAC_STACR + emac_reg);
+ sta_reg = in_be32((void *)EMAC_STACR + emac_reg);
#ifdef ET_DEBUG
printf ("a32: read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */
#endif
@@ -288,6 +364,7 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr,
if ((sta_reg & EMAC_STACR_PHYE) != 0)
return -1;
+
return 0;
-} /* phy_write */
+} /* phy_write */
diff --git a/cpu/ppc4xx/ndfc.c b/cpu/ppc4xx/ndfc.c
index 398457726f..ec1b38cffa 100644
--- a/cpu/ppc4xx/ndfc.c
+++ b/cpu/ppc4xx/ndfc.c
@@ -34,7 +34,7 @@
#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY) && \
(defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
- defined(CONFIG_405EZ))
+ defined(CONFIG_405EZ) || defined(CONFIG_405EX))
#include <nand.h>
#include <linux/mtd/ndfc.h>
@@ -222,6 +222,7 @@ int board_nand_init(struct nand_chip *nand)
*/
board_nand_select_device(nand, cs);
out_be32((u32 *)(base + NDFC_BCFG0 + (cs << 2)), 0x80002222);
+
return 0;
}
diff --git a/cpu/ppc4xx/speed.c b/cpu/ppc4xx/speed.c
index da5330a360..90066142de 100644
--- a/cpu/ppc4xx/speed.c
+++ b/cpu/ppc4xx/speed.c
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2000
+ * (C) Copyright 2000-2007
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
@@ -37,7 +37,7 @@ DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_405GP) || defined(CONFIG_405CR)
-void get_sys_info (PPC405_SYS_INFO * sysInfo)
+void get_sys_info (PPC4xx_SYS_INFO * sysInfo)
{
unsigned long pllmr;
unsigned long sysClkPeriodPs = ONE_BILLION / (CONFIG_SYS_CLK_FREQ / 1000);
@@ -162,6 +162,8 @@ void get_sys_info (PPC405_SYS_INFO * sysInfo)
sysInfo->freqProcessor = sysInfo->freqPLB * sysInfo->pllPlbDiv;
}
}
+
+ sysInfo->freqUART = sysInfo->freqProcessor;
}
@@ -173,7 +175,7 @@ ulong get_OPB_freq (void)
{
ulong val = 0;
- PPC405_SYS_INFO sys_info;
+ PPC4xx_SYS_INFO sys_info;
get_sys_info (&sys_info);
val = sys_info.freqPLB / sys_info.pllOpbDiv;
@@ -189,7 +191,7 @@ ulong get_OPB_freq (void)
ulong get_PCI_freq (void)
{
ulong val;
- PPC405_SYS_INFO sys_info;
+ PPC4xx_SYS_INFO sys_info;
get_sys_info (&sys_info);
val = sys_info.freqPLB / sys_info.pllPciDiv;
@@ -216,7 +218,7 @@ void get_sys_info (sys_info_t *sysInfo)
*/
/* Decode CPR0_PLLD0 for divisors */
- mfclk(clk_plld, reg);
+ mfcpr(clk_plld, reg);
temp = (reg & PLLD_FWDVA_MASK) >> 16;
sysInfo->pllFwdDivA = temp ? temp : 16;
temp = (reg & PLLD_FWDVB_MASK) >> 8;
@@ -225,19 +227,19 @@ void get_sys_info (sys_info_t *sysInfo)
sysInfo->pllFbkDiv = temp ? temp : 32;
lfdiv = reg & PLLD_LFBDV_MASK;
- mfclk(clk_opbd, reg);
+ mfcpr(clk_opbd, reg);
temp = (reg & OPBDDV_MASK) >> 24;
sysInfo->pllOpbDiv = temp ? temp : 4;
- mfclk(clk_perd, reg);
+ mfcpr(clk_perd, reg);
temp = (reg & PERDV_MASK) >> 24;
sysInfo->pllExtBusDiv = temp ? temp : 8;
- mfclk(clk_primbd, reg);
+ mfcpr(clk_primbd, reg);
temp = (reg & PRBDV_MASK) >> 24;
prbdv0 = temp ? temp : 8;
- mfclk(clk_spcid, reg);
+ mfcpr(clk_spcid, reg);
temp = (reg & SPCID_MASK) >> 24;
sysInfo->pllPciDiv = temp ? temp : 4;
@@ -246,7 +248,7 @@ void get_sys_info (sys_info_t *sysInfo)
temp = (reg & PLLSYS0_SEL_MASK) >> 27;
if (temp == 0) { /* PLL output */
/* Figure which pll to use */
- mfclk(clk_pllc, reg);
+ mfcpr(clk_pllc, reg);
temp = (reg & PLLC_SRC_MASK) >> 29;
if (!temp) /* PLLOUTA */
m = sysInfo->pllFbkDiv * lfdiv * sysInfo->pllFwdDivA;
@@ -263,8 +265,9 @@ void get_sys_info (sys_info_t *sysInfo)
sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA;
sysInfo->freqPLB = sysInfo->freqVCOMhz/sysInfo->pllFwdDivB/prbdv0;
sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
- sysInfo->freqEPB = sysInfo->freqPLB/sysInfo->pllExtBusDiv;
+ sysInfo->freqEBC = sysInfo->freqPLB/sysInfo->pllExtBusDiv;
sysInfo->freqPCI = sysInfo->freqPLB/sysInfo->pllPciDiv;
+ sysInfo->freqUART = sysInfo->freqPLB;
/* Figure which timer source to use */
if (mfspr(ccr1) & 0x0080) { /* External Clock, assume same as SYS_CLK */
@@ -277,6 +280,7 @@ void get_sys_info (sys_info_t *sysInfo)
else /* Internal clock */
sysInfo->freqTmrClk = sysInfo->freqProcessor;
}
+
/********************************************
* get_PCI_freq
* return PCI bus freq in Hz
@@ -317,8 +321,8 @@ void get_sys_info (sys_info_t * sysInfo)
if( get_pvr() == PVR_440GP_RB ) /* Rev B divs an extra 2 -- geez! */
sysInfo->freqPLB >>= 1;
sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
- sysInfo->freqEPB = sysInfo->freqOPB/sysInfo->pllExtBusDiv;
-
+ sysInfo->freqEBC = sysInfo->freqOPB/sysInfo->pllExtBusDiv;
+ sysInfo->freqUART = sysInfo->freqPLB;
}
#else
void get_sys_info (sys_info_t * sysInfo)
@@ -393,7 +397,7 @@ void get_sys_info (sys_info_t * sysInfo)
sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA;
sysInfo->freqPLB = sysInfo->freqVCOMhz/sysInfo->pllFwdDivB/prbdv0;
sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
- sysInfo->freqEPB = sysInfo->freqOPB/sysInfo->pllExtBusDiv;
+ sysInfo->freqEBC = sysInfo->freqOPB/sysInfo->pllExtBusDiv;
#if defined(CONFIG_YUCCA)
/* Determine PCI Clock Period */
@@ -403,7 +407,7 @@ void get_sys_info (sys_info_t * sysInfo)
sysInfo->freqDDR = ((sysInfo->freqPLB) * SDR0_DDR0_DDRM_DECODE(sdr_ddrpll));
#endif
-
+ sysInfo->freqUART = sysInfo->freqPLB;
}
#endif
@@ -632,7 +636,8 @@ extern void get_sys_info (sys_info_t * sysInfo);
extern ulong get_PCI_freq (void);
#elif defined(CONFIG_AP1000)
-void get_sys_info (sys_info_t * sysInfo) {
+void get_sys_info (sys_info_t * sysInfo)
+{
sysInfo->freqProcessor = 240 * 1000 * 1000;
sysInfo->freqPLB = 80 * 1000 * 1000;
sysInfo->freqPCI = 33 * 1000 * 1000;
@@ -640,17 +645,16 @@ void get_sys_info (sys_info_t * sysInfo) {
#elif defined(CONFIG_405)
-void get_sys_info (sys_info_t * sysInfo) {
-
+void get_sys_info (sys_info_t * sysInfo)
+{
sysInfo->freqVCOMhz=3125000;
sysInfo->freqProcessor=12*1000*1000;
sysInfo->freqPLB=50*1000*1000;
sysInfo->freqPCI=66*1000*1000;
-
}
#elif defined(CONFIG_405EP)
-void get_sys_info (PPC405_SYS_INFO * sysInfo)
+void get_sys_info (PPC4xx_SYS_INFO * sysInfo)
{
unsigned long pllmr0;
unsigned long pllmr1;
@@ -678,9 +682,8 @@ void get_sys_info (PPC405_SYS_INFO * sysInfo)
* Determine FBK_DIV.
*/
sysInfo->pllFbkDiv = ((pllmr1 & PLLMR1_FBMUL_MASK) >> 20);
- if (sysInfo->pllFbkDiv == 0) {
+ if (sysInfo->pllFbkDiv == 0)
sysInfo->pllFbkDiv = 16;
- }
/*
* Determine PLB_DIV.
@@ -733,6 +736,10 @@ void get_sys_info (PPC405_SYS_INFO * sysInfo)
* Determine PLB clock frequency
*/
sysInfo->freqPLB = sysInfo->freqProcessor / sysInfo->pllPlbDiv;
+
+ sysInfo->freqEBC = sysInfo->freqPLB / sysInfo->pllExtBusDiv;
+
+ sysInfo->freqUART = sysInfo->freqProcessor * pllmr0_ccdv;
}
@@ -744,7 +751,7 @@ ulong get_OPB_freq (void)
{
ulong val = 0;
- PPC405_SYS_INFO sys_info;
+ PPC4xx_SYS_INFO sys_info;
get_sys_info (&sys_info);
val = sys_info.freqPLB / sys_info.pllOpbDiv;
@@ -760,7 +767,7 @@ ulong get_OPB_freq (void)
ulong get_PCI_freq (void)
{
ulong val;
- PPC405_SYS_INFO sys_info;
+ PPC4xx_SYS_INFO sys_info;
get_sys_info (&sys_info);
val = sys_info.freqPLB / sys_info.pllPciDiv;
@@ -768,7 +775,7 @@ ulong get_PCI_freq (void)
}
#elif defined(CONFIG_405EZ)
-void get_sys_info (PPC405_SYS_INFO * sysInfo)
+void get_sys_info (PPC4xx_SYS_INFO * sysInfo)
{
unsigned long cpr_plld;
unsigned long cpr_pllc;
@@ -806,6 +813,7 @@ void get_sys_info (PPC405_SYS_INFO * sysInfo)
* Read CPR_PRIMAD register
*/
mfcpr(cprprimad, cpr_primad);
+
/*
* Determine PLB_DIV.
*/
@@ -856,6 +864,11 @@ void get_sys_info (PPC405_SYS_INFO * sysInfo)
*/
sysInfo->freqPLB = (CONFIG_SYS_CLK_FREQ * m) /
sysInfo->pllFwdDiv / sysInfo->pllPlbDiv;
+
+ sysInfo->freqEBC = (CONFIG_SYS_CLK_FREQ * sysInfo->pllFbkDiv) /
+ sysInfo->pllExtBusDiv;
+
+ sysInfo->freqUART = sysInfo->freqVCOHz;
}
/********************************************
@@ -866,7 +879,7 @@ ulong get_OPB_freq (void)
{
ulong val = 0;
- PPC405_SYS_INFO sys_info;
+ PPC4xx_SYS_INFO sys_info;
get_sys_info (&sys_info);
val = (CONFIG_SYS_CLK_FREQ * sys_info.pllFbkDiv) / sys_info.pllOpbDiv;
@@ -874,13 +887,176 @@ ulong get_OPB_freq (void)
return val;
}
+#elif defined(CONFIG_405EX)
+
+/*
+ * TODO: We need to get the CPR registers and calculate these values correctly!!!!
+ * We need the specs!!!!
+ */
+static unsigned char get_fbdv(unsigned char index)
+{
+ unsigned char ret = 0;
+ /* This is table should be 256 bytes.
+ * Only take first 52 values.
+ */
+ unsigned char fbdv_tb[] = {
+ 0x00, 0xff, 0x7f, 0xfd,
+ 0x7a, 0xf5, 0x6a, 0xd5,
+ 0x2a, 0xd4, 0x29, 0xd3,
+ 0x26, 0xcc, 0x19, 0xb3,
+ 0x67, 0xce, 0x1d, 0xbb,
+ 0x77, 0xee, 0x5d, 0xba,
+ 0x74, 0xe9, 0x52, 0xa5,
+ 0x4b, 0x96, 0x2c, 0xd8,
+ 0x31, 0xe3, 0x46, 0x8d,
+ 0x1b, 0xb7, 0x6f, 0xde,
+ 0x3d, 0xfb, 0x76, 0xed,
+ 0x5a, 0xb5, 0x6b, 0xd6,
+ 0x2d, 0xdb, 0x36, 0xec,
+
+ };
+
+ if ((index & 0x7f) == 0)
+ return 1;
+ while (ret < sizeof (fbdv_tb)) {
+ if (fbdv_tb[ret] == index)
+ break;
+ ret++;
+ }
+ ret++;
+
+ return ret;
+}
+
+#define PLL_FBK_PLL_LOCAL 0
+#define PLL_FBK_CPU 1
+#define PLL_FBK_PERCLK 5
+
+void get_sys_info (sys_info_t * sysInfo)
+{
+ unsigned long sysClkPeriodPs = ONE_BILLION / (CONFIG_SYS_CLK_FREQ / 1000);
+ unsigned long m = 1;
+ unsigned int tmp;
+ unsigned char fwdva[16] = {
+ 1, 2, 14, 9, 4, 11, 16, 13,
+ 12, 5, 6, 15, 10, 7, 8, 3,
+ };
+ unsigned char sel, cpudv0, plb2xDiv;
+
+ mfcpr(cpr0_plld, tmp);
+
+ /*
+ * Determine forward divider A
+ */
+ sysInfo->pllFwdDiv = fwdva[((tmp >> 16) & 0x0f)]; /* FWDVA */
+
+ /*
+ * Determine FBK_DIV.
+ */
+ sysInfo->pllFbkDiv = get_fbdv(((tmp >> 24) & 0x0ff)); /* FBDV */
+
+ /*
+ * Determine PLBDV0
+ */
+ sysInfo->pllPlbDiv = 2;
+
+ /*
+ * Determine PERDV0
+ */
+ mfcpr(cpr0_perd, tmp);
+ tmp = (tmp >> 24) & 0x03;
+ sysInfo->pllExtBusDiv = (tmp == 0) ? 4 : tmp;
+
+ /*
+ * Determine OPBDV0
+ */
+ mfcpr(cpr0_opbd, tmp);
+ tmp = (tmp >> 24) & 0x03;
+ sysInfo->pllOpbDiv = (tmp == 0) ? 4 : tmp;
+
+ /* Determine PLB2XDV0 */
+ mfcpr(cpr0_plbd, tmp);
+ tmp = (tmp >> 16) & 0x07;
+ plb2xDiv = (tmp == 0) ? 8 : tmp;
+
+ /* Determine CPUDV0 */
+ mfcpr(cpr0_cpud, tmp);
+ tmp = (tmp >> 24) & 0x07;
+ cpudv0 = (tmp == 0) ? 8 : tmp;
+
+ /* Determine SEL(5:7) in CPR0_PLLC */
+ mfcpr(cpr0_pllc, tmp);
+ sel = (tmp >> 24) & 0x07;
+
+ /*
+ * Determine the M factor
+ * PLL local: M = FBDV
+ * CPU clock: M = FBDV * FWDVA * CPUDV0
+ * PerClk : M = FBDV * FWDVA * PLB2XDV0 * PLBDV0(2) * OPBDV0 * PERDV0
+ *
+ */
+ switch (sel) {
+ case PLL_FBK_CPU:
+ m = sysInfo->pllFwdDiv * cpudv0;
+ break;
+ case PLL_FBK_PERCLK:
+ m = sysInfo->pllFwdDiv * plb2xDiv * 2
+ * sysInfo->pllOpbDiv * sysInfo->pllExtBusDiv;
+ break;
+ case PLL_FBK_PLL_LOCAL:
+ break;
+ default:
+ printf("%s unknown m\n", __FUNCTION__);
+ return;
+
+ }
+ m *= sysInfo->pllFbkDiv;
+
+ /*
+ * Determine VCO clock frequency
+ */
+ sysInfo->freqVCOHz = (1000000000000LL * (unsigned long long)m) /
+ (unsigned long long)sysClkPeriodPs;
+
+ /*
+ * Determine CPU clock frequency
+ */
+ sysInfo->freqProcessor = sysInfo->freqVCOHz / (sysInfo->pllFwdDiv * cpudv0);
+
+ /*
+ * Determine PLB clock frequency, ddr1x should be the same
+ */
+ sysInfo->freqPLB = sysInfo->freqVCOHz / (sysInfo->pllFwdDiv * plb2xDiv * 2);
+ sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
+ sysInfo->freqDDR = sysInfo->freqPLB;
+ sysInfo->freqEBC = sysInfo->freqOPB / sysInfo->pllExtBusDiv;
+ sysInfo->freqUART = sysInfo->freqPLB;
+}
+
+/********************************************
+ * get_OPB_freq
+ * return OPB bus freq in Hz
+ *********************************************/
+ulong get_OPB_freq (void)
+{
+ ulong val = 0;
+
+ PPC4xx_SYS_INFO sys_info;
+
+ get_sys_info (&sys_info);
+ val = sys_info.freqPLB / sys_info.pllOpbDiv;
+
+ return val;
+}
+
#endif
int get_clocks (void)
{
#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \
- defined(CONFIG_440) || defined(CONFIG_405)
+ defined(CONFIG_405EX) || defined(CONFIG_405) || \
+ defined(CONFIG_440)
sys_info_t sys_info;
get_sys_info (&sys_info);
@@ -907,7 +1083,8 @@ ulong get_bus_freq (ulong dummy)
#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \
- defined(CONFIG_440) || defined(CONFIG_405)
+ defined(CONFIG_405EX) || defined(CONFIG_405) || \
+ defined(CONFIG_440)
sys_info_t sys_info;
get_sys_info (&sys_info);
diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S
index 9626b65c88..77c2aa4117 100644
--- a/cpu/ppc4xx/start.S
+++ b/cpu/ppc4xx/start.S
@@ -636,6 +636,33 @@ _start:
dcbz r0,r3
addi r3,r3,32
bdnz ..d_ag
+
+ /*
+ * Lock the init-ram/stack in d-cache, so that other regions
+ * may use d-cache as well
+ * Note, that this current implementation locks exactly 4k
+ * of d-cache, so please make sure that you don't define a
+ * bigger init-ram area. Take a look at the lwmon5 440EPx
+ * implementation as a reference.
+ */
+ msync
+ isync
+ /* 8. set TFLOOR/NFLOOR to 8 (-> 8*16*32 bytes locked -> 4k) */
+ lis r1,0x0201
+ ori r1,r1,0xf808
+ mtspr dvlim,r1
+ lis r1,0x0808
+ ori r1,r1,0x0808
+ mtspr dnv0,r1
+ mtspr dnv1,r1
+ mtspr dnv2,r1
+ mtspr dnv3,r1
+ mtspr dtv0,r1
+ mtspr dtv1,r1
+ mtspr dtv2,r1
+ mtspr dtv3,r1
+ msync
+ isync
#endif /* CFG_INIT_RAM_DCACHE */
/* 440EP & 440GR are only 440er PPC's without internal SRAM */
@@ -800,7 +827,7 @@ _start:
/*----------------------------------------------------------------------- */
/* Enable two 128MB cachable regions. */
/*----------------------------------------------------------------------- */
- addis r1,r0,0x8000
+ addis r1,r0,0xc000
addi r1,r1,0x0001
mticcr r1 /* instruction cache */
@@ -823,12 +850,23 @@ _start:
/*****************************************************************************/
#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \
- defined(CONFIG_405)
+ defined(CONFIG_405EX) || defined(CONFIG_405)
/*----------------------------------------------------------------------- */
/* Clear and set up some registers. */
/*----------------------------------------------------------------------- */
addi r4,r0,0x0000
+#if !defined(CONFIG_405EX)
mtspr sgr,r4
+#else
+ /*
+ * On 405EX, completely clearing the SGR leads to PPC hangup
+ * upon PCIe configuration access. The PCIe memory regions
+ * need to be guarded!
+ */
+ lis r3,0x0000
+ ori r3,r3,0x7FFC
+ mtspr sgr,r3
+#endif
mtspr dcwr,r4
mtesr r4 /* clear Exception Syndrome Reg */
mttcr r4 /* clear Timer Control Reg */
@@ -851,7 +889,7 @@ _start:
/*----------------------------------------------------------------------- */
/* Enable two 128MB cachable regions. */
/*----------------------------------------------------------------------- */
- lis r4,0x8000
+ lis r4,0xc000
ori r4,r4,0x0001
mticcr r4 /* instruction cache */
isync
@@ -860,12 +898,34 @@ _start:
ori r4,r4,0x0000
mtdccr r4 /* data cache */
-#if !(defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
+#if !(defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR)) || defined(CONFIG_405EX)
/*----------------------------------------------------------------------- */
/* Tune the speed and size for flash CS0 */
/*----------------------------------------------------------------------- */
bl ext_bus_cntlr_init
#endif
+#if !(defined(CFG_INIT_DCACHE_CS) || defined(CFG_TEMP_STACK_OCM))
+ /*
+ * Boards like the Kilauea (405EX) don't have OCM and can't use
+ * DCache for init-ram. So setup stack here directly after the
+ * SDRAM is initialized.
+ */
+ lis r1, CFG_INIT_RAM_ADDR@h
+ ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack in SDRAM */
+
+ li r0, 0 /* Make room for stack frame header and */
+ stwu r0, -4(r1) /* clear final stack frame so that */
+ stwu r0, -4(r1) /* stack backtraces terminate cleanly */
+ /*
+ * Set up a dummy frame to store reset vector as return address.
+ * this causes stack underflow to reset board.
+ */
+ stwu r1, -8(r1) /* Save back chain and move SP */
+ lis r0, RESET_VECTOR@h /* Address of reset vector */
+ ori r0, r0, RESET_VECTOR@l
+ stwu r1, -8(r1) /* Save back chain and move SP */
+ stw r0, +12(r1) /* Save return addr (underflow vect) */
+#endif /* !(CFG_INIT_DCACHE_CS || !CFG_TEM_STACK_OCM) */
#if defined(CONFIG_405EP)
/*----------------------------------------------------------------------- */
@@ -983,7 +1043,7 @@ start_ram:
ori r4,r4,0xa000
mtdcr ebccfgd,r4
- /* turn on data chache for this region */
+ /* turn on data cache for this region */
lis r4,0x0080
mtdccr r4
@@ -1049,30 +1109,6 @@ start_ram:
/*----------------------------------------------------------------------- */
bl sdram_init
- /*
- * Setup temporary stack pointer only for boards
- * that do not use SDRAM SPD I2C stuff since it
- * is already initialized to use DCACHE or OCM
- * stacks.
- */
-#if !(defined(CFG_INIT_DCACHE_CS) || defined(CFG_TEMP_STACK_OCM))
- lis r1, CFG_INIT_RAM_ADDR@h
- ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack in SDRAM */
-
- li r0, 0 /* Make room for stack frame header and */
- stwu r0, -4(r1) /* clear final stack frame so that */
- stwu r0, -4(r1) /* stack backtraces terminate cleanly */
- /*
- * Set up a dummy frame to store reset vector as return address.
- * this causes stack underflow to reset board.
- */
- stwu r1, -8(r1) /* Save back chain and move SP */
- lis r0, RESET_VECTOR@h /* Address of reset vector */
- ori r0, r0, RESET_VECTOR@l
- stwu r1, -8(r1) /* Save back chain and move SP */
- stw r0, +12(r1) /* Save return addr (underflow vect) */
-#endif /* !(CFG_INIT_DCACHE_CS || !CFG_TEM_STACK_OCM) */
-
#ifdef CONFIG_NAND_SPL
bl nand_boot /* will not return */
#else
@@ -1211,111 +1247,6 @@ mck_return:
#endif /* CONFIG_440 */
-/*
- * Cache functions.
- *
- * NOTE: currently the 440s run with dcache _disabled_ once relocated to DRAM,
- * although for some cache-ralated calls stubs have to be provided to satisfy
- * symbols resolution.
- * Icache-related functions are used in POST framework.
- *
- */
-#ifdef CONFIG_440
- .globl dcache_disable
- .globl icache_disable
- .globl icache_enable
-dcache_disable:
-icache_disable:
-icache_enable:
- blr
-
- .globl dcache_status
- .globl icache_status
-dcache_status:
-icache_status:
- mr r3, 0
- blr
-#else
-flush_dcache:
- addis r9,r0,0x0002 /* set mask for EE and CE msr bits */
- ori r9,r9,0x8000
- mfmsr r12 /* save msr */
- andc r9,r12,r9
- mtmsr r9 /* disable EE and CE */
- addi r10,r0,0x0001 /* enable data cache for unused memory */
- mfdccr r9 /* region 0xF8000000-0xFFFFFFFF via */
- or r10,r10,r9 /* bit 31 in dccr */
- mtdccr r10
-
- /* do loop for # of congruence classes. */
- lis r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha /* TBS: for large cache sizes */
- ori r10,r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
- lis r11,(CFG_DCACHE_SIZE / 2)@ha /* D cache set size - 2 way sets */
- ori r11,r11,(CFG_DCACHE_SIZE / 2)@l /* D cache set size - 2 way sets */
- mtctr r10
- addi r10,r0,(0xE000-0x10000) /* start at 0xFFFFE000 */
- add r11,r10,r11 /* add to get to other side of cache line */
-..flush_dcache_loop:
- lwz r3,0(r10) /* least recently used side */
- lwz r3,0(r11) /* the other side */
- dccci r0,r11 /* invalidate both sides */
- addi r10,r10,CFG_CACHELINE_SIZE /* bump to next line */
- addi r11,r11,CFG_CACHELINE_SIZE /* bump to next line */
- bdnz ..flush_dcache_loop
- sync /* allow memory access to complete */
- mtdccr r9 /* restore dccr */
- mtmsr r12 /* restore msr */
- blr
-
- .globl icache_enable
-icache_enable:
- mflr r8
- bl invalidate_icache
- mtlr r8
- isync
- addis r3,r0, 0x8000 /* set bit 0 */
- mticcr r3
- blr
-
- .globl icache_disable
-icache_disable:
- addis r3,r0, 0x0000 /* clear bit 0 */
- mticcr r3
- isync
- blr
-
- .globl icache_status
-icache_status:
- mficcr r3
- srwi r3, r3, 31 /* >>31 => select bit 0 */
- blr
-
- .globl dcache_enable
-dcache_enable:
- mflr r8
- bl invalidate_dcache
- mtlr r8
- isync
- addis r3,r0, 0x8000 /* set bit 0 */
- mtdccr r3
- blr
-
- .globl dcache_disable
-dcache_disable:
- mflr r8
- bl flush_dcache
- mtlr r8
- addis r3,r0, 0x0000 /* clear bit 0 */
- mtdccr r3
- blr
-
- .globl dcache_status
-dcache_status:
- mfdccr r3
- srwi r3, r3, 31 /* >>31 => select bit 0 */
- blr
-#endif
-
.globl get_pvr
get_pvr:
mfspr r3, PVR
@@ -1421,6 +1352,51 @@ ppcSync:
*/
.globl relocate_code
relocate_code:
+#ifdef CONFIG_4xx_DCACHE
+ /*
+ * We need to flush the Init Data before the dcache will be
+ * invalidated
+ */
+
+ /* save regs */
+ mr r9,r3
+ mr r10,r4
+ mr r11,r5
+
+ mr r3,r4
+ addi r4,r4,0x200 /* should be enough for init data */
+ bl flush_dcache_range
+
+ /* restore regs */
+ mr r3,r9
+ mr r4,r10
+ mr r5,r11
+#endif
+
+#ifdef CFG_INIT_RAM_DCACHE
+ /*
+ * Unlock the previously locked d-cache
+ */
+ msync
+ isync
+ /* set TFLOOR/NFLOOR to 0 again */
+ lis r6,0x0001
+ ori r6,r6,0xf800
+ mtspr dvlim,r6
+ lis r6,0x0000
+ ori r6,r6,0x0000
+ mtspr dnv0,r6
+ mtspr dnv1,r6
+ mtspr dnv2,r6
+ mtspr dnv3,r6
+ mtspr dtv0,r6
+ mtspr dtv1,r6
+ mtspr dtv2,r6
+ mtspr dtv3,r6
+ msync
+ isync
+#endif /* CFG_INIT_RAM_DCACHE */
+
#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
defined(CONFIG_440SP) || defined(CONFIG_440SPE)
@@ -1432,7 +1408,11 @@ relocate_code:
dccci 0,0 /* Invalidate data cache, now no longer our stack */
sync
isync
- addi r1,r0,0x0000 /* TLB entry #0 */
+#ifdef CFG_TLB_FOR_BOOT_FLASH
+ addi r1,r0,CFG_TLB_FOR_BOOT_FLASH /* Use defined TLB */
+#else
+ addi r1,r0,0x0000 /* Default TLB entry is #0 */
+#endif
tlbre r0,r1,0x0002 /* Read contents */
ori r0,r0,0x0c00 /* Or in the inhibit, write through bit */
tlbwe r0,r1,0x0002 /* Save it out */
@@ -1448,7 +1428,7 @@ relocate_code:
ori r4, r4, CFG_MONITOR_BASE@l
lwz r5, GOT(__init_end)
sub r5, r5, r4
- li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
+ li r6, L1_CACHE_BYTES /* Cache Line Size */
/*
* Fix GOT pointer:
@@ -1566,16 +1546,25 @@ clear_bss:
lwz r4,GOT(_end)
cmplw 0, r3, r4
- beq 6f
+ beq 7f
li r0, 0
-5:
+
+ andi. r5, r4, 3
+ beq 6f
+ sub r4, r4, r5
+ mtctr r5
+ mr r5, r4
+5: stb r0, 0(r5)
+ addi r5, r5, 1
+ bdnz 5b
+6:
stw r0, 0(r3)
addi r3, r3, 4
cmplw 0, r3, r4
- bne 5b
-6:
+ bne 6b
+7:
mr r3, r9 /* Init Data pointer */
mr r4, r10 /* Destination Address */
bl board_init_r
@@ -1711,6 +1700,7 @@ trap_reloc:
rlwinm r8,r9,0,15,13
rlwinm r8,r8,0,17,15
mtmsr r8
+ mfspr r8,dvlim
addi r3,r0,0x0000
mtspr dvlim,r3
mfspr r3,ivpr
@@ -1725,6 +1715,7 @@ trap_reloc:
..ag: dcbf r0,r3
addi r3,r3,-32
bdnz ..ag
+ mtspr dvlim,r8
sync
mtmsr r9
blr
@@ -1768,23 +1759,6 @@ in32:
lwz 3,0x0000(3)
blr
-invalidate_icache:
- iccci r0,r0 /* for 405, iccci invalidates the */
- blr /* entire I cache */
-
-invalidate_dcache:
- addi r6,0,0x0000 /* clear GPR 6 */
- /* Do loop for # of dcache congruence classes. */
- lis r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha /* TBS for large sized cache */
- ori r7, r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
- /* NOTE: dccci invalidates both */
- mtctr r7 /* ways in the D cache */
-..dcloop:
- dccci 0,r6 /* invalidate line */
- addi r6,r6, CFG_CACHELINE_SIZE /* bump to next line */
- bdnz ..dcloop
- blr
-
/**************************************************************************/
/* PPC405EP specific stuff */
/**************************************************************************/
diff --git a/cpu/ppc4xx/tlb.c b/cpu/ppc4xx/tlb.c
index 098694caf4..ed493f1a71 100644
--- a/cpu/ppc4xx/tlb.c
+++ b/cpu/ppc4xx/tlb.c
@@ -26,6 +26,7 @@
#if defined(CONFIG_440)
#include <ppc440.h>
+#include <asm/cache.h>
#include <asm/io.h>
#include <asm/mmu.h>
@@ -42,7 +43,6 @@ void remove_tlb(u32 vaddr, u32 size)
u32 tlb_vaddr;
u32 tlb_size = 0;
- /* First, find the index of a TLB entry not being used */
for (i=0; i<PPC4XX_TLB_SIZE; i++) {
tlb_word0_value = mftlb1(i);
tlb_vaddr = TLB_WORD0_EPN_DECODE(tlb_word0_value);
@@ -96,6 +96,92 @@ void remove_tlb(u32 vaddr, u32 size)
asm("isync");
}
+/*
+ * Change the I attribute (cache inhibited) of a TLB or multiple TLB's.
+ * This function is used to either turn cache on or off in a specific
+ * memory area.
+ */
+void change_tlb(u32 vaddr, u32 size, u32 tlb_word2_i_value)
+{
+ int i;
+ u32 tlb_word0_value;
+ u32 tlb_word2_value;
+ u32 tlb_vaddr;
+ u32 tlb_size = 0;
+
+ for (i=0; i<PPC4XX_TLB_SIZE; i++) {
+ tlb_word0_value = mftlb1(i);
+ tlb_vaddr = TLB_WORD0_EPN_DECODE(tlb_word0_value);
+ if (((tlb_word0_value & TLB_WORD0_V_MASK) == TLB_WORD0_V_ENABLE) &&
+ (tlb_vaddr >= vaddr)) {
+ /*
+ * TLB is enabled and start address is lower or equal
+ * than the area we are looking for. Now we only have
+ * to check the size/end address for a match.
+ */
+ switch (tlb_word0_value & TLB_WORD0_SIZE_MASK) {
+ case TLB_WORD0_SIZE_1KB:
+ tlb_size = 1 << 10;
+ break;
+ case TLB_WORD0_SIZE_4KB:
+ tlb_size = 4 << 10;
+ break;
+ case TLB_WORD0_SIZE_16KB:
+ tlb_size = 16 << 10;
+ break;
+ case TLB_WORD0_SIZE_64KB:
+ tlb_size = 64 << 10;
+ break;
+ case TLB_WORD0_SIZE_256KB:
+ tlb_size = 256 << 10;
+ break;
+ case TLB_WORD0_SIZE_1MB:
+ tlb_size = 1 << 20;
+ break;
+ case TLB_WORD0_SIZE_16MB:
+ tlb_size = 16 << 20;
+ break;
+ case TLB_WORD0_SIZE_256MB:
+ tlb_size = 256 << 20;
+ break;
+ }
+
+ /*
+ * Now check the end-address if it's in the range
+ */
+ if ((tlb_vaddr + tlb_size - 1) <= (vaddr + size - 1)) {
+ /*
+ * Found a TLB in the range.
+ * Change cache attribute in tlb2 word.
+ */
+ tlb_word2_value =
+ TLB_WORD2_U0_DISABLE | TLB_WORD2_U1_DISABLE |
+ TLB_WORD2_U2_DISABLE | TLB_WORD2_U3_DISABLE |
+ TLB_WORD2_W_DISABLE | tlb_word2_i_value |
+ TLB_WORD2_M_DISABLE | TLB_WORD2_G_DISABLE |
+ TLB_WORD2_E_DISABLE | TLB_WORD2_UX_ENABLE |
+ TLB_WORD2_UW_ENABLE | TLB_WORD2_UR_ENABLE |
+ TLB_WORD2_SX_ENABLE | TLB_WORD2_SW_ENABLE |
+ TLB_WORD2_SR_ENABLE;
+
+ /*
+ * Now either flush or invalidate the dcache
+ */
+ if (tlb_word2_i_value)
+ flush_dcache();
+ else
+ invalidate_dcache();
+
+ mttlb3(i, tlb_word2_value);
+ asm("iccci 0,0");
+ }
+ }
+ }
+
+ /* Execute an ISYNC instruction so that the new TLB entry takes effect */
+ asm("isync");
+}
+
static int add_tlb_entry(unsigned long phys_addr,
unsigned long virt_addr,
unsigned long tlb_word0_size_value,
diff --git a/cpu/ppc4xx/usb.c b/cpu/ppc4xx/usb.c
index 272ed8c15e..cb8d5c7d30 100644
--- a/cpu/ppc4xx/usb.c
+++ b/cpu/ppc4xx/usb.c
@@ -25,25 +25,41 @@
#if defined(CONFIG_USB_OHCI_NEW) && defined(CFG_USB_OHCI_CPU_INIT)
+#ifdef CONFIG_4xx_DCACHE
+#include <asm/mmu.h>
+DECLARE_GLOBAL_DATA_PTR;
+#endif
+
#include "usbdev.h"
int usb_cpu_init(void)
{
+#ifdef CONFIG_4xx_DCACHE
+ /* disable cache */
+ change_tlb(gd->bd->bi_memstart, gd->bd->bi_memsize, TLB_WORD2_I_ENABLE);
+#endif
#if defined(CONFIG_440EP) || defined(CONFIG_440EPX)
usb_dev_init();
#endif
-
return 0;
}
int usb_cpu_stop(void)
{
+#ifdef CONFIG_4xx_DCACHE
+ /* enable cache */
+ change_tlb(gd->bd->bi_memstart, gd->bd->bi_memsize, 0);
+#endif
return 0;
}
int usb_cpu_init_fail(void)
{
+#ifdef CONFIG_4xx_DCACHE
+ /* enable cache */
+ change_tlb(gd->bd->bi_memstart, gd->bd->bi_memsize, 0);
+#endif
return 0;
}
diff --git a/cpu/ppc4xx/usbdev.c b/cpu/ppc4xx/usbdev.c
index 5924a6cb84..d71ba7710a 100644
--- a/cpu/ppc4xx/usbdev.c
+++ b/cpu/ppc4xx/usbdev.c
@@ -7,7 +7,7 @@
#include <usb.h>
#include "usbdev.h"
-#include "vecnum.h"
+#include <asm/ppc4xx-intvec.h>
#define USB_DT_DEVICE 0x01
#define USB_DT_CONFIG 0x02
diff --git a/cpu/ppc4xx/vecnum.h b/cpu/ppc4xx/vecnum.h
deleted file mode 100644
index bddf9e5daa..0000000000
--- a/cpu/ppc4xx/vecnum.h
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
-* Copyright (C) 2002 Scott McNutt <smcnutt@artesyncp.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
-*/
-
-/*
- * Interrupt vector number definitions to ease the
- * 405 -- 440 porting pain ;-)
- *
- * NOTE: They're not all here yet ... update as needed.
- *
- */
-
-#ifndef _VECNUMS_H_
-#define _VECNUMS_H_
-
-#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
-
-/* UIC 0 */
-#define VECNUM_U0 0 /* UART 0 */
-#define VECNUM_U1 1 /* UART 1 */
-#define VECNUM_IIC0 2 /* IIC */
-#define VECNUM_KRD 3 /* Kasumi Ready for data */
-#define VECNUM_KDA 4 /* Kasumi Data Available */
-#define VECNUM_PCRW 5 /* PCI command register write */
-#define VECNUM_PPM 6 /* PCI power management */
-#define VECNUM_IIC1 7 /* IIC */
-#define VECNUM_SPI 8 /* SPI */
-#define VECNUM_EPCISER 9 /* External PCI SERR */
-#define VECNUM_MTE 10 /* MAL TXEOB */
-#define VECNUM_MRE 11 /* MAL RXEOB */
-#define VECNUM_D0 12 /* DMA channel 0 */
-#define VECNUM_D1 13 /* DMA channel 1 */
-#define VECNUM_D2 14 /* DMA channel 2 */
-#define VECNUM_D3 15 /* DMA channel 3 */
-#define VECNUM_UD0 16 /* UDMA irq 0 */
-#define VECNUM_UD1 17 /* UDMA irq 1 */
-#define VECNUM_UD2 18 /* UDMA irq 2 */
-#define VECNUM_UD3 19 /* UDMA irq 3 */
-#define VECNUM_HSB2D 20 /* USB2.0 Device */
-#define VECNUM_USBDEV 20 /* USB 1.1/USB 2.0 Device */
-#define VECNUM_OHCI1 21 /* USB2.0 Host OHCI irq 1 */
-#define VECNUM_OHCI2 22 /* USB2.0 Host OHCI irq 2 */
-#define VECNUM_EIP94 23 /* Security EIP94 */
-#define VECNUM_ETH0 24 /* Emac 0 */
-#define VECNUM_ETH1 25 /* Emac 1 */
-#define VECNUM_EHCI 26 /* USB2.0 Host EHCI */
-#define VECNUM_EIR4 27 /* External interrupt 4 */
-#define VECNUM_UIC2NC 28 /* UIC2 non-critical interrupt */
-#define VECNUM_UIC2C 29 /* UIC2 critical interrupt */
-#define VECNUM_UIC1NC 30 /* UIC1 non-critical interrupt */
-#define VECNUM_UIC1C 31 /* UIC1 critical interrupt */
-
-/* UIC 1 */
-#define VECNUM_MS (32 + 0) /* MAL SERR */
-#define VECNUM_MTDE (32 + 1) /* MAL TXDE */
-#define VECNUM_MRDE (32 + 2) /* MAL RXDE */
-#define VECNUM_U2 (32 + 3) /* UART 2 */
-#define VECNUM_U3 (32 + 4) /* UART 3 */
-#define VECNUM_EBCO (32 + 5) /* EBCO interrupt status */
-#define VECNUM_NDFC (32 + 6) /* NDFC */
-#define VECNUM_KSLE (32 + 7) /* KASUMI slave error */
-#define VECNUM_CT5 (32 + 8) /* GPT compare timer 5 */
-#define VECNUM_CT6 (32 + 9) /* GPT compare timer 6 */
-#define VECNUM_PLB34I0 (32 + 10) /* PLB3X4X MIRQ0 */
-#define VECNUM_PLB34I1 (32 + 11) /* PLB3X4X MIRQ1 */
-#define VECNUM_PLB34I2 (32 + 12) /* PLB3X4X MIRQ2 */
-#define VECNUM_PLB34I3 (32 + 13) /* PLB3X4X MIRQ3 */
-#define VECNUM_PLB34I4 (32 + 14) /* PLB3X4X MIRQ4 */
-#define VECNUM_PLB34I5 (32 + 15) /* PLB3X4X MIRQ5 */
-#define VECNUM_CT0 (32 + 16) /* GPT compare timer 0 */
-#define VECNUM_CT1 (32 + 17) /* GPT compare timer 1 */
-#define VECNUM_EIR7 (32 + 18) /* External interrupt 7 */
-#define VECNUM_EIR8 (32 + 19) /* External interrupt 8 */
-#define VECNUM_EIR9 (32 + 20) /* External interrupt 9 */
-#define VECNUM_CT2 (32 + 21) /* GPT compare timer 2 */
-#define VECNUM_CT3 (32 + 22) /* GPT compare timer 3 */
-#define VECNUM_CT4 (32 + 23) /* GPT compare timer 4 */
-#define VECNUM_SRE (32 + 24) /* Serial ROM error */
-#define VECNUM_GPTDC (32 + 25) /* GPT decrementer pulse */
-#define VECNUM_RSVD0 (32 + 26) /* Reserved */
-#define VECNUM_EPCIPER (32 + 27) /* External PCI PERR */
-#define VECNUM_EIR0 (32 + 28) /* External interrupt 0 */
-#define VECNUM_EWU0 (32 + 29) /* Ethernet 0 wakeup */
-#define VECNUM_EIR1 (32 + 30) /* External interrupt 1 */
-#define VECNUM_EWU1 (32 + 31) /* Ethernet 1 wakeup */
-
-#define VECNUM_TXDE VECNUM_MTDE
-#define VECNUM_RXDE VECNUM_MRDE
-
-/* UIC 2 */
-#define VECNUM_EIR5 (62 + 0) /* External interrupt 5 */
-#define VECNUM_EIR6 (62 + 1) /* External interrupt 6 */
-#define VECNUM_OPB (62 + 2) /* OPB to PLB bridge int stat */
-#define VECNUM_EIR2 (62 + 3) /* External interrupt 2 */
-#define VECNUM_EIR3 (62 + 4) /* External interrupt 3 */
-#define VECNUM_DDR2 (62 + 5) /* DDR2 sdram */
-#define VECNUM_MCTX0 (62 + 6) /* MAl intp coalescence TX0 */
-#define VECNUM_MCTX1 (62 + 7) /* MAl intp coalescence TX1 */
-#define VECNUM_MCTR0 (62 + 8) /* MAl intp coalescence TR0 */
-#define VECNUM_MCTR1 (62 + 9) /* MAl intp coalescence TR1 */
-
-#elif defined(CONFIG_440SPE)
-
-/* UIC 0 */
-#define VECNUM_U0 0 /* UART0 */
-#define VECNUM_U1 1 /* UART1 */
-#define VECNUM_IIC0 2 /* IIC0 */
-#define VECNUM_IIC1 3 /* IIC1 */
-#define VECNUM_PIM 4 /* PCI inbound message */
-#define VECNUM_PCRW 5 /* PCI command reg write */
-#define VECNUM_PPM 6 /* PCI power management */
-#define VECNUM_MSI0 7 /* PCI MSI level 0 */
-#define VECNUM_MSI1 8 /* PCI MSI level 0 */
-#define VECNUM_MSI2 9 /* PCI MSI level 0 */
-#define VECNUM_D0 12 /* DMA channel 0 */
-#define VECNUM_D1 13 /* DMA channel 1 */
-#define VECNUM_D2 14 /* DMA channel 2 */
-#define VECNUM_D3 15 /* DMA channel 3 */
-#define VECNUM_UIC1NC 30 /* UIC1 non-critical interrupt */
-#define VECNUM_UIC1C 31 /* UIC1 critical interrupt */
-
-/* UIC 1 */
-#define VECNUM_MS (32 + 1 ) /* MAL SERR */
-#define VECNUM_TXDE (32 + 2 ) /* MAL TXDE */
-#define VECNUM_RXDE (32 + 3 ) /* MAL RXDE */
-#define VECNUM_MTE (32 + 6 ) /* MAL Tx EOB */
-#define VECNUM_MRE (32 + 7 ) /* MAL Rx EOB */
-#define VECNUM_CT0 (32 + 12 ) /* GPT compare timer 0 */
-#define VECNUM_CT1 (32 + 13 ) /* GPT compare timer 1 */
-#define VECNUM_CT2 (32 + 14 ) /* GPT compare timer 2 */
-#define VECNUM_CT3 (32 + 15 ) /* GPT compare timer 3 */
-#define VECNUM_CT4 (32 + 16 ) /* GPT compare timer 4 */
-#define VECNUM_ETH0 (32 + 28) /* Ethernet interrupt status */
-#define VECNUM_EWU0 (32 + 29) /* Emac wakeup */
-
-/* UIC 2 */
-#define VECNUM_EIR5 (62 + 24) /* External interrupt 5 */
-#define VECNUM_EIR4 (62 + 25) /* External interrupt 4 */
-#define VECNUM_EIR3 (62 + 26) /* External interrupt 3 */
-#define VECNUM_EIR2 (62 + 27) /* External interrupt 2 */
-#define VECNUM_EIR1 (62 + 28) /* External interrupt 1 */
-#define VECNUM_EIR0 (62 + 29) /* External interrupt 0 */
-
-#elif defined(CONFIG_440SP)
-
-/* UIC 0 */
-#define VECNUM_U0 0 /* UART0 */
-#define VECNUM_U1 1 /* UART1 */
-#define VECNUM_IIC0 2 /* IIC0 */
-#define VECNUM_IIC1 3 /* IIC1 */
-#define VECNUM_PIM 4 /* PCI inbound message */
-#define VECNUM_PCRW 5 /* PCI command reg write */
-#define VECNUM_PPM 6 /* PCI power management */
-#define VECNUM_UIC1NC 30 /* UIC1 non-critical interrupt */
-#define VECNUM_UIC1C 31 /* UIC1 critical interrupt */
-
-/* UIC 1 */
-#define VECNUM_EIR0 (32 + 0) /* External interrupt 0 */
-#define VECNUM_MS (32 + 1) /* MAL SERR */
-#define VECNUM_TXDE (32 + 2) /* MAL TXDE */
-#define VECNUM_RXDE (32 + 3) /* MAL RXDE */
-#define VECNUM_MTE (32 + 6) /* MAL Tx EOB */
-#define VECNUM_MRE (32 + 7) /* MAL Rx EOB */
-#define VECNUM_CT0 (32 + 12) /* GPT compare timer 0 */
-#define VECNUM_CT1 (32 + 13) /* GPT compare timer 1 */
-#define VECNUM_CT2 (32 + 14) /* GPT compare timer 2 */
-#define VECNUM_CT3 (32 + 15) /* GPT compare timer 3 */
-#define VECNUM_CT4 (32 + 16) /* GPT compare timer 4 */
-#define VECNUM_ETH0 (32 + 28) /* Ethernet interrupt status */
-#define VECNUM_EWU0 (32 + 29) /* Emac wakeup */
-
-#elif defined(CONFIG_440)
-
-/* UIC 0 */
-#define VECNUM_U0 0 /* UART0 */
-#define VECNUM_U1 1 /* UART1 */
-#define VECNUM_IIC0 2 /* IIC0 */
-#define VECNUM_IIC1 3 /* IIC1 */
-#define VECNUM_PIM 4 /* PCI inbound message */
-#define VECNUM_PCRW 5 /* PCI command reg write */
-#define VECNUM_PPM 6 /* PCI power management */
-#define VECNUM_MSI0 7 /* PCI MSI level 0 */
-#define VECNUM_MSI1 8 /* PCI MSI level 0 */
-#define VECNUM_MSI2 9 /* PCI MSI level 0 */
-#define VECNUM_MTE 10 /* MAL TXEOB */
-#define VECNUM_MRE 11 /* MAL RXEOB */
-#define VECNUM_D0 12 /* DMA channel 0 */
-#define VECNUM_D1 13 /* DMA channel 1 */
-#define VECNUM_D2 14 /* DMA channel 2 */
-#define VECNUM_D3 15 /* DMA channel 3 */
-#define VECNUM_CT0 18 /* GPT compare timer 0 */
-#define VECNUM_CT1 19 /* GPT compare timer 1 */
-#define VECNUM_CT2 20 /* GPT compare timer 2 */
-#define VECNUM_CT3 21 /* GPT compare timer 3 */
-#define VECNUM_CT4 22 /* GPT compare timer 4 */
-#define VECNUM_EIR0 23 /* External interrupt 0 */
-#define VECNUM_EIR1 24 /* External interrupt 1 */
-#define VECNUM_EIR2 25 /* External interrupt 2 */
-#define VECNUM_EIR3 26 /* External interrupt 3 */
-#define VECNUM_EIR4 27 /* External interrupt 4 */
-#define VECNUM_EIR5 28 /* External interrupt 5 */
-#define VECNUM_EIR6 29 /* External interrupt 6 */
-#define VECNUM_UIC1NC 30 /* UIC1 non-critical interrupt */
-#define VECNUM_UIC1C 31 /* UIC1 critical interrupt */
-
-/* UIC 1 */
-#define VECNUM_MS (32 + 0 ) /* MAL SERR */
-#define VECNUM_TXDE (32 + 1 ) /* MAL TXDE */
-#define VECNUM_RXDE (32 + 2 ) /* MAL RXDE */
-#define VECNUM_USBDEV (32 + 23) /* USB 1.1/USB 2.0 Device */
-#define VECNUM_ETH0 (32 + 28) /* Ethernet 0 interrupt status */
-#define VECNUM_EWU0 (32 + 29) /* Ethernet 0 wakeup */
-
-#else /* !defined(CONFIG_440) */
-
-#if defined(CONFIG_405EZ)
-#define VECNUM_D0 0 /* DMA channel 0 */
-#define VECNUM_D1 1 /* DMA channel 1 */
-#define VECNUM_D2 2 /* DMA channel 2 */
-#define VECNUM_D3 3 /* DMA channel 3 */
-#define VECNUM_1588 4 /* IEEE 1588 network synchronization */
-#define VECNUM_U0 5 /* UART0 */
-#define VECNUM_U1 6 /* UART1 */
-#define VECNUM_CAN0 7 /* CAN 0 */
-#define VECNUM_CAN1 8 /* CAN 1 */
-#define VECNUM_SPI 9 /* SPI */
-#define VECNUM_IIC0 10 /* I2C */
-#define VECNUM_CHT0 11 /* Chameleon timer high pri interrupt */
-#define VECNUM_CHT1 12 /* Chameleon timer high pri interrupt */
-#define VECNUM_USBH1 13 /* USB Host 1 */
-#define VECNUM_USBH2 14 /* USB Host 2 */
-#define VECNUM_USBDEV 15 /* USB Device */
-#define VECNUM_ETH0 16 /* 10/100 Ethernet interrupt status */
-#define VECNUM_EWU0 17 /* Ethernet wakeup sequence detected */
-
-#define VECNUM_MADMAL 18 /* Logical OR of following MadMAL int */
-#define VECNUM_MS 18 /* MAL_SERR_INT */
-#define VECNUM_TXDE 18 /* MAL_TXDE_INT */
-#define VECNUM_RXDE 18 /* MAL_RXDE_INT */
-
-#define VECNUM_MTE 19 /* MAL TXEOB */
-#define VECNUM_MTE1 20 /* MAL TXEOB1 */
-#define VECNUM_MRE 21 /* MAL RXEOB */
-#define VECNUM_NAND 22 /* NAND Flash controller */
-#define VECNUM_ADC 23 /* ADC */
-#define VECNUM_DAC 24 /* DAC */
-#define VECNUM_OPB2PLB 25 /* OPB to PLB bridge interrupt */
-#define VECNUM_RESERVED0 26 /* Reserved */
-#define VECNUM_EIR0 27 /* External interrupt 0 */
-#define VECNUM_EIR1 28 /* External interrupt 1 */
-#define VECNUM_EIR2 29 /* External interrupt 2 */
-#define VECNUM_EIR3 30 /* External interrupt 3 */
-#define VECNUM_EIR4 31 /* External interrupt 4 */
-
-#else /* !CONFIG_405EZ */
-
-#define VECNUM_U0 0 /* UART0 */
-#define VECNUM_U1 1 /* UART1 */
-#define VECNUM_D0 5 /* DMA channel 0 */
-#define VECNUM_D1 6 /* DMA channel 1 */
-#define VECNUM_D2 7 /* DMA channel 2 */
-#define VECNUM_D3 8 /* DMA channel 3 */
-#define VECNUM_EWU0 9 /* Ethernet wakeup */
-#define VECNUM_MS 10 /* MAL SERR */
-#define VECNUM_MTE 11 /* MAL TXEOB */
-#define VECNUM_MRE 12 /* MAL RXEOB */
-#define VECNUM_TXDE 13 /* MAL TXDE */
-#define VECNUM_RXDE 14 /* MAL RXDE */
-#define VECNUM_ETH0 15 /* Ethernet interrupt status */
-#define VECNUM_EIR0 25 /* External interrupt 0 */
-#define VECNUM_EIR1 26 /* External interrupt 1 */
-#define VECNUM_EIR2 27 /* External interrupt 2 */
-#define VECNUM_EIR3 28 /* External interrupt 3 */
-#define VECNUM_EIR4 29 /* External interrupt 4 */
-#define VECNUM_EIR5 30 /* External interrupt 5 */
-#define VECNUM_EIR6 31 /* External interrupt 6 */
-#endif /* defined(CONFIG_405EZ) */
-
-#endif /* defined(CONFIG_440) */
-
-#endif /* _VECNUMS_H_ */
diff --git a/cpu/pxa/start.S b/cpu/pxa/start.S
index b922485ed3..31f408dfa7 100644
--- a/cpu/pxa/start.S
+++ b/cpu/pxa/start.S
@@ -57,7 +57,7 @@ _fiq: .word fiq
* Startup Code (reset vector)
*
* do important init only if we don't start from RAM!
- * - relocate armboot to ram
+ * - relocate armboot to RAM
* - setup stack
* - jump to second stage
*/
@@ -90,7 +90,7 @@ IRQ_STACK_START:
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
-#endif
+#endif /* CONFIG_USE_IRQ */
/****************************************************************************/
@@ -100,18 +100,18 @@ FIQ_STACK_START:
/****************************************************************************/
reset:
- mrs r0,cpsr /* set the cpu to SVC32 mode */
+ mrs r0,cpsr /* set the CPU to SVC32 mode */
bic r0,r0,#0x1f /* (superviser mode, M=10011) */
orr r0,r0,#0x13
msr cpsr,r0
/*
* we do sys-critical inits only at reboot,
- * not when booting from ram!
+ * not when booting from RAM!
*/
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit /* we do sys-critical inits */
-#endif
+#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate: /* relocate U-Boot to RAM */
@@ -130,7 +130,7 @@ copy_loop:
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
-#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
+#endif /* !CONFIG_SKIP_RELOCATE_UBOOT */
/* Set up the stack */
stack_setup:
@@ -139,7 +139,7 @@ stack_setup:
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
-#endif
+#endif /* CONFIG_USE_IRQ */
sub sp, r0, #12 /* leave 3 words for abort-stack */
clear_bss:
@@ -172,11 +172,11 @@ _start_armboot: .word start_armboot
#undef OSCR
#undef OWER
#undef OIER
-#endif
+#endif /* CONFIG_PXA250 || CONFIG_CPU_MONAHANS */
#ifdef CONFIG_PXA250
#undef RCSR
#undef CCCR
-#endif
+#endif /* CONFIG_PXA250 */
/* Interrupt-Controller base address */
IC_BASE: .word 0x40d00000
@@ -197,18 +197,18 @@ OSTIMER_BASE: .word 0x40a00000
#ifdef CONFIG_CPU_MONAHANS
# ifndef CFG_MONAHANS_RUN_MODE_OSC_RATIO
# error "You have to define CFG_MONAHANS_RUN_MODE_OSC_RATIO!!"
-# endif
+# endif /* !CFG_MONAHANS_RUN_MODE_OSC_RATIO */
# ifndef CFG_MONAHANS_TURBO_RUN_MODE_RATIO
# define CFG_MONAHANS_TURBO_RUN_MODE_RATIO 0x1
-# endif
-#else /* ! CONFIG_CPU_MONAHANS */
+# endif /* !CFG_MONAHANS_TURBO_RUN_MODE_RATIO */
+#else /* !CONFIG_CPU_MONAHANS */
#ifdef CFG_CPUSPEED
CC_BASE: .word 0x41300000
#define CCCR 0x00
cpuspeed: .word CFG_CPUSPEED
-#else
+#else /* !CFG_CPUSPEED */
#error "You have to define CFG_CPUSPEED!!"
-#endif
+#endif /* CFG_CPUSPEED */
#endif /* CONFIG_CPU_MONAHANS */
/* takes care the CP15 update has taken place */
@@ -225,7 +225,7 @@ cpu_init_crit:
ldr r0, IC_BASE
mov r1, #0x00
str r1, [r0, #ICMR]
-#else
+#else /* CONFIG_CPU_MONAHANS */
/* Step 1 - Enable CP6 permission */
mrc p15, 0, r1, c15, c1, 0 @ read CPAR
orr r1, r1, #0x40
@@ -244,14 +244,14 @@ cpu_init_crit:
ldr r1, =CKENB
ldr r2, =(CKENB_6_IRQ)
str r2, [r1]
-#endif
+#endif /* !CONFIG_CPU_MONAHANS */
/* set clock speed */
#ifdef CONFIG_CPU_MONAHANS
ldr r0, =ACCR
ldr r1, =(((CFG_MONAHANS_TURBO_RUN_MODE_RATIO<<8) & ACCR_XN_MASK) | (CFG_MONAHANS_RUN_MODE_OSC_RATIO & ACCR_XL_MASK))
str r1, [r0]
-#else /* ! CONFIG_CPU_MONAHANS */
+#else /* !CONFIG_CPU_MONAHANS */
#ifdef CFG_CPUSPEED
ldr r0, CC_BASE
ldr r1, cpuspeed
@@ -451,7 +451,7 @@ fiq:
bl do_fiq /* effiction fiq_save_user_regs */
irq_restore_user_regs
-#else
+#else /* !CONFIG_USE_IRQ */
.align 5
irq:
@@ -465,7 +465,7 @@ fiq:
bad_save_user_regs
bl do_fiq
-#endif
+#endif /* CONFIG_USE_IRQ */
/****************************************************************************/
/* */
diff --git a/cpu/pxa/usb.c b/cpu/pxa/usb.c
index 72b7dfadfe..aa6f4b7b9d 100644
--- a/cpu/pxa/usb.c
+++ b/cpu/pxa/usb.c
@@ -89,6 +89,22 @@ int usb_cpu_stop(void)
int usb_cpu_init_fail(void)
{
+ UHCHR |= UHCHR_FHR;
+ udelay(11);
+ UHCHR &= ~UHCHR_FHR;
+
+ UHCCOMS |= 1;
+ udelay(10);
+
+#if defined(CONFIG_CPU_MONAHANS)
+ UHCHR |= UHCHR_SSEP0;
+#endif
+#if defined(CONFIG_PXA27X)
+ UHCHR |= UHCHR_SSEP2;
+#endif
+ UHCHR |= UHCHR_SSEP1;
+ UHCHR |= UHCHR_SSE;
+
return 0;
}