summaryrefslogtreecommitdiff
path: root/cpu/mpc85xx
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/mpc85xx')
-rw-r--r--cpu/mpc85xx/cpu.c50
-rw-r--r--cpu/mpc85xx/cpu_init.c1
-rw-r--r--cpu/mpc85xx/pci.c185
-rw-r--r--cpu/mpc85xx/spd_sdram.c134
4 files changed, 264 insertions, 106 deletions
diff --git a/cpu/mpc85xx/cpu.c b/cpu/mpc85xx/cpu.c
index f7fe22e..0507c47 100644
--- a/cpu/mpc85xx/cpu.c
+++ b/cpu/mpc85xx/cpu.c
@@ -30,7 +30,10 @@
#include <command.h>
#include <asm/cache.h>
-/* ------------------------------------------------------------------------- */
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+
int checkcpu (void)
{
@@ -227,3 +230,48 @@ int dma_xfer(void *dest, uint count, void *src) {
return dma_check();
}
#endif
+
+
+#ifdef CONFIG_OF_FLAT_TREE
+void
+ft_cpu_setup(void *blob, bd_t *bd)
+{
+ u32 *p;
+ ulong clock;
+ int len;
+
+ 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 "/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);
+
+#if defined(CONFIG_MPC85XX_TSEC1)
+ p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/mac-address", &len);
+ memcpy(p, bd->bi_enetaddr, 6);
+#endif
+
+#if defined(CONFIG_HAS_ETH1)
+ p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/mac-address", &len);
+ memcpy(p, bd->bi_enet1addr, 6);
+#endif
+
+#if defined(CONFIG_HAS_ETH2)
+ p = ft_get_prop(blob, "/" OF_SOC "/ethernet@26000/mac-address", &len);
+ memcpy(p, bd->bi_enet2addr, 6);
+#endif
+
+#if defined(CONFIG_HAS_ETH3)
+ p = ft_get_prop(blob, "/" OF_SOC "/ethernet@27000/mac-address", &len);
+ memcpy(p, bd->bi_enet3addr, 6);
+#endif
+
+}
+#endif
diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c
index c12b47b..9f4d36c 100644
--- a/cpu/mpc85xx/cpu_init.c
+++ b/cpu/mpc85xx/cpu_init.c
@@ -32,6 +32,7 @@
DECLARE_GLOBAL_DATA_PTR;
+
#ifdef CONFIG_CPM2
static void config_8560_ioports (volatile immap_t * immr)
{
diff --git a/cpu/mpc85xx/pci.c b/cpu/mpc85xx/pci.c
index a94493e..cfb7dcd 100644
--- a/cpu/mpc85xx/pci.c
+++ b/cpu/mpc85xx/pci.c
@@ -32,66 +32,93 @@
#if defined(CONFIG_PCI)
+static struct pci_controller *pci_hose;
+
void
-pci_mpc85xx_init(struct pci_controller *hose)
+pci_mpc85xx_init(struct pci_controller *board_hose)
{
+ u16 reg16;
+ u32 dev;
+
volatile immap_t *immap = (immap_t *)CFG_CCSRBAR;
volatile ccsr_pcix_t *pcix = &immap->im_pcix;
+ volatile ccsr_pcix_t *pcix2 = &immap->im_pcix2;
+ volatile ccsr_gur_t *gur = &immap->im_gur;
+ struct pci_controller * hose;
- u16 reg16;
+ pci_hose = board_hose;
+
+ hose = &pci_hose[0];
hose->first_busno = 0;
hose->last_busno = 0xff;
- pci_set_region(hose->regions + 0,
- CFG_PCI1_MEM_BASE,
- CFG_PCI1_MEM_PHYS,
- CFG_PCI1_MEM_SIZE,
- PCI_REGION_MEM);
-
- pci_set_region(hose->regions + 1,
- CFG_PCI1_IO_BASE,
- CFG_PCI1_IO_PHYS,
- CFG_PCI1_IO_SIZE,
- PCI_REGION_IO);
-
- hose->region_count = 2;
-
pci_setup_indirect(hose,
(CFG_IMMR+0x8000),
(CFG_IMMR+0x8004));
+ /*
+ * Hose scan.
+ */
+ dev = PCI_BDF(hose->first_busno, 0, 0);
+ pci_hose_read_config_word (hose, dev, PCI_COMMAND, &reg16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
+
+ if (!(gur->pordevsr & PORDEVSR_PCI)) {
+ /* PCI-X init */
+ if (CONFIG_SYS_CLK_FREQ < 66000000)
+ printf("PCI-X will only work at 66 MHz\n");
+
+ reg16 = PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ
+ | PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E;
+ pci_hose_write_config_word(hose, dev, PCIX_COMMAND, reg16);
+ }
+
pcix->potar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
pcix->potear1 = 0x00000000;
- pcix->powbar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
+ pcix->powbar1 = (CFG_PCI1_MEM_PHYS >> 12) & 0x000fffff;
pcix->powbear1 = 0x00000000;
- pcix->powar1 = 0x8004401c; /* 512M MEM space */
+ pcix->powar1 = (POWAR_EN | POWAR_MEM_READ |
+ POWAR_MEM_WRITE | POWAR_MEM_512M);
- pcix->potar2 = 0x00000000;
+ pcix->potar2 = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff;
pcix->potear2 = 0x00000000;
- pcix->powbar2 = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff;
+ pcix->powbar2 = (CFG_PCI1_IO_PHYS >> 12) & 0x000fffff;
pcix->powbear2 = 0x00000000;
- pcix->powar2 = 0x80088017; /* 16M IO space */
+ pcix->powar2 = (POWAR_EN | POWAR_IO_READ |
+ POWAR_IO_WRITE | POWAR_IO_1M);
pcix->pitar1 = 0x00000000;
pcix->piwbar1 = 0x00000000;
- pcix->piwar1 = 0xa0f5501e; /* Enable, Prefetch, Local Mem,
- * Snoop R/W, 2G */
+ pcix->piwar1 = (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL |
+ PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G);
- /*
- * Hose scan.
- */
- pci_register_hose(hose);
+ pcix->powar3 = 0;
+ pcix->powar4 = 0;
+ pcix->piwar2 = 0;
+ pcix->piwar3 = 0;
- pci_read_config_word (PCI_BDF(0,0,0), PCI_COMMAND, &reg16);
- reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
- pci_write_config_word(PCI_BDF(0,0,0), PCI_COMMAND, reg16);
+ pci_set_region(hose->regions + 0,
+ CFG_PCI1_MEM_BASE,
+ CFG_PCI1_MEM_PHYS,
+ CFG_PCI1_MEM_SIZE,
+ PCI_REGION_MEM);
- /*
- * Clear non-reserved bits in status register.
- */
- pci_write_config_word(PCI_BDF(0,0,0), PCI_STATUS, 0xffff);
- pci_write_config_byte(PCI_BDF(0,0,0), PCI_LATENCY_TIMER,0x80);
+ pci_set_region(hose->regions + 1,
+ CFG_PCI1_IO_BASE,
+ CFG_PCI1_IO_PHYS,
+ CFG_PCI1_IO_SIZE,
+ PCI_REGION_IO);
+
+ hose->region_count = 2;
+
+ pci_register_hose(hose);
#if defined(CONFIG_MPC8555CDS) || defined(CONFIG_MPC8541CDS)
/*
@@ -117,6 +144,94 @@ pci_mpc85xx_init(struct pci_controller *hose)
#endif
hose->last_busno = pci_hose_scan(hose);
+
+#ifdef CONFIG_MPC85XX_PCI2
+ hose = &pci_hose[1];
+
+ hose->first_busno = pci_hose[0].last_busno + 1;
+ hose->last_busno = 0xff;
+
+ pci_setup_indirect(hose,
+ (CFG_IMMR+0x9000),
+ (CFG_IMMR+0x9004));
+
+ dev = PCI_BDF(hose->first_busno, 0, 0);
+ pci_hose_read_config_word (hose, dev, PCI_COMMAND, &reg16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
+
+ pcix2->potar1 = (CFG_PCI2_MEM_BASE >> 12) & 0x000fffff;
+ pcix2->potear1 = 0x00000000;
+ pcix2->powbar1 = (CFG_PCI2_MEM_PHYS >> 12) & 0x000fffff;
+ pcix2->powbear1 = 0x00000000;
+ pcix2->powar1 = (POWAR_EN | POWAR_MEM_READ |
+ POWAR_MEM_WRITE | POWAR_MEM_512M);
+
+ pcix2->potar2 = (CFG_PCI2_IO_BASE >> 12) & 0x000fffff;
+ pcix2->potear2 = 0x00000000;
+ pcix2->powbar2 = (CFG_PCI2_IO_PHYS >> 12) & 0x000fffff;
+ pcix2->powbear2 = 0x00000000;
+ pcix2->powar2 = (POWAR_EN | POWAR_IO_READ |
+ POWAR_IO_WRITE | POWAR_IO_1M);
+
+ pcix2->pitar1 = 0x00000000;
+ pcix2->piwbar1 = 0x00000000;
+ pcix2->piwar1 = (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL |
+ PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G);
+
+ pcix2->powar3 = 0;
+ pcix2->powar4 = 0;
+ pcix2->piwar2 = 0;
+ pcix2->piwar3 = 0;
+
+ pci_set_region(hose->regions + 0,
+ CFG_PCI2_MEM_BASE,
+ CFG_PCI2_MEM_PHYS,
+ CFG_PCI2_MEM_SIZE,
+ PCI_REGION_MEM);
+
+ pci_set_region(hose->regions + 1,
+ CFG_PCI2_IO_BASE,
+ CFG_PCI2_IO_PHYS,
+ CFG_PCI2_IO_SIZE,
+ PCI_REGION_IO);
+
+ hose->region_count = 2;
+
+ /*
+ * Hose scan.
+ */
+ pci_register_hose(hose);
+
+ hose->last_busno = pci_hose_scan(hose);
+#endif
}
+#ifdef CONFIG_OF_FLAT_TREE
+void
+ft_pci_setup(void *blob, bd_t *bd)
+{
+ u32 *p;
+ int len;
+
+ p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8000/bus-range", &len);
+ if (p != NULL) {
+ p[0] = pci_hose[0].first_busno;
+ p[1] = pci_hose[0].last_busno;
+ }
+
+#ifdef CONFIG_MPC85XX_PCI2
+ p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@9000/bus-range", &len);
+ if (p != NULL) {
+ p[0] = pci_hose[1].first_busno;
+ p[1] = pci_hose[1].last_busno;
+ }
+#endif
+}
+#endif /* CONFIG_OF_FLAT_TREE */
#endif /* CONFIG_PCI */
diff --git a/cpu/mpc85xx/spd_sdram.c b/cpu/mpc85xx/spd_sdram.c
index af99282..7507801 100644
--- a/cpu/mpc85xx/spd_sdram.c
+++ b/cpu/mpc85xx/spd_sdram.c
@@ -131,8 +131,8 @@ convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val)
800,
900,
250,
- 330, /* FIXME: Is 333 better/valid? */
- 660, /* FIXME: Is 667 better/valid? */
+ 330,
+ 660,
750,
0, /* undefined */
0 /* undefined */
@@ -146,6 +146,28 @@ convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val)
}
+/*
+ * Determine Refresh Rate. Ignore self refresh bit on DDR I.
+ * Table from SPD Spec, Byte 12, converted to picoseconds and
+ * filled in with "default" normal values.
+ */
+unsigned int determine_refresh_rate(unsigned int spd_refresh)
+{
+ unsigned int refresh_time_ns[8] = {
+ 15625000, /* 0 Normal 1.00x */
+ 3900000, /* 1 Reduced .25x */
+ 7800000, /* 2 Extended .50x */
+ 31300000, /* 3 Extended 2.00x */
+ 62500000, /* 4 Extended 4.00x */
+ 125000000, /* 5 Extended 8.00x */
+ 15625000, /* 6 Normal 1.00x filler */
+ 15625000, /* 7 Normal 1.00x filler */
+ };
+
+ return picos_to_clk(refresh_time_ns[spd_refresh & 0x7]);
+}
+
+
long int
spd_sdram(void)
{
@@ -157,6 +179,10 @@ spd_sdram(void)
unsigned int rank_density;
unsigned int odt_rd_cfg, odt_wr_cfg;
unsigned int odt_cfg, mode_odt_enable;
+ unsigned int refresh_clk;
+#ifdef MPC85xx_DDR_SDRAM_CLK_CNTL
+ unsigned char clk_adjust;
+#endif
unsigned int dqs_cfg;
unsigned char twr_clk, twtr_clk, twr_auto_clk;
unsigned int tCKmin_ps, tCKmax_ps;
@@ -740,38 +766,21 @@ spd_sdram(void)
ddr->sdram_mode_2 = 0;
debug("DDR: sdram_mode_2 = 0x%08x\n", ddr->sdram_mode_2);
-
/*
- * Determine Refresh Rate. Ignore self refresh bit on DDR I.
- * Table from SPD Spec, Byte 12, converted to picoseconds and
- * filled in with "default" normal values.
+ * Determine Refresh Rate.
*/
- {
- unsigned int refresh_clk;
- unsigned int refresh_time_ns[8] = {
- 15625000, /* 0 Normal 1.00x */
- 3900000, /* 1 Reduced .25x */
- 7800000, /* 2 Extended .50x */
- 31300000, /* 3 Extended 2.00x */
- 62500000, /* 4 Extended 4.00x */
- 125000000, /* 5 Extended 8.00x */
- 15625000, /* 6 Normal 1.00x filler */
- 15625000, /* 7 Normal 1.00x filler */
- };
-
- refresh_clk = picos_to_clk(refresh_time_ns[spd.refresh & 0x7]);
-
- /*
- * Set BSTOPRE to 0x100 for page mode
- * If auto-charge is used, set BSTOPRE = 0
- */
- ddr->sdram_interval =
- (0
- | (refresh_clk & 0x3fff) << 16
- | 0x100
- );
- debug("DDR: sdram_interval = 0x%08x\n", ddr->sdram_interval);
- }
+ refresh_clk = determine_refresh_rate(spd.refresh & 0x7);
+
+ /*
+ * Set BSTOPRE to 0x100 for page mode
+ * If auto-charge is used, set BSTOPRE = 0
+ */
+ ddr->sdram_interval =
+ (0
+ | (refresh_clk & 0x3fff) << 16
+ | 0x100
+ );
+ debug("DDR: sdram_interval = 0x%08x\n", ddr->sdram_interval);
/*
* Is this an ECC DDR chip?
@@ -835,28 +844,23 @@ spd_sdram(void)
#ifdef MPC85xx_DDR_SDRAM_CLK_CNTL
- {
- unsigned char clk_adjust;
-
- /*
- * Setup the clock control.
- * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1
- * SDRAM_CLK_CNTL[5-7] = Clock Adjust
- * 0110 3/4 cycle late
- * 0111 7/8 cycle late
- */
- if (spd.mem_type == SPD_MEMTYPE_DDR) {
- clk_adjust = 0x6;
- } else {
- clk_adjust = 0x7;
- }
+ /*
+ * Setup the clock control.
+ * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1
+ * SDRAM_CLK_CNTL[5-7] = Clock Adjust
+ * 0110 3/4 cycle late
+ * 0111 7/8 cycle late
+ */
+ if (spd.mem_type == SPD_MEMTYPE_DDR)
+ clk_adjust = 0x6;
+ else
+ clk_adjust = 0x7;
- ddr->sdram_clk_cntl = (0
+ ddr->sdram_clk_cntl = (0
| 0x80000000
| (clk_adjust << 23)
);
- debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl);
- }
+ debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl);
#endif
/*
@@ -1081,26 +1085,16 @@ ddr_enable_ecc(unsigned int dram_size)
}
}
- /* 8K */
- dma_xfer((uint *)0x2000, 0x2000, (uint *)0);
- /* 16K */
- dma_xfer((uint *)0x4000, 0x4000, (uint *)0);
- /* 32K */
- dma_xfer((uint *)0x8000, 0x8000, (uint *)0);
- /* 64K */
- dma_xfer((uint *)0x10000, 0x10000, (uint *)0);
- /* 128k */
- dma_xfer((uint *)0x20000, 0x20000, (uint *)0);
- /* 256k */
- dma_xfer((uint *)0x40000, 0x40000, (uint *)0);
- /* 512k */
- dma_xfer((uint *)0x80000, 0x80000, (uint *)0);
- /* 1M */
- dma_xfer((uint *)0x100000, 0x100000, (uint *)0);
- /* 2M */
- dma_xfer((uint *)0x200000, 0x200000, (uint *)0);
- /* 4M */
- dma_xfer((uint *)0x400000, 0x400000, (uint *)0);
+ dma_xfer((uint *)0x002000, 0x002000, (uint *)0); /* 8K */
+ dma_xfer((uint *)0x004000, 0x004000, (uint *)0); /* 16K */
+ dma_xfer((uint *)0x008000, 0x008000, (uint *)0); /* 32K */
+ dma_xfer((uint *)0x010000, 0x010000, (uint *)0); /* 64K */
+ dma_xfer((uint *)0x020000, 0x020000, (uint *)0); /* 128k */
+ dma_xfer((uint *)0x040000, 0x040000, (uint *)0); /* 256k */
+ dma_xfer((uint *)0x080000, 0x080000, (uint *)0); /* 512k */
+ dma_xfer((uint *)0x100000, 0x100000, (uint *)0); /* 1M */
+ dma_xfer((uint *)0x200000, 0x200000, (uint *)0); /* 2M */
+ dma_xfer((uint *)0x400000, 0x400000, (uint *)0); /* 4M */
for (i = 1; i < dram_size / 0x800000; i++) {
dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0);