/*
* Only one of the following three should be 1; others should be 0
* By default the cache line interleaving is selected if
- * the CONFIG_DDR_INTERLEAVE flag is defined in MPC8641HPCN.h
+ * the CONFIG_DDR_INTERLEAVE flag is defined
*/
#define CFG_PAGE_INTERLEAVING 0
#define CFG_BANK_INTERLEAVING 0
#define CFG_SUPER_BANK_INTERLEAVING 0
/*
- * Convert picoseconds into clock cycles (rounding up if needed).
+ * Convert picoseconds into DRAM clock cycles (rounding up if needed).
*/
-int
-picos_to_clk(int picos)
+static unsigned int
+picos_to_clk(unsigned int picos)
{
- int clks;
-
- clks = picos / (2000000000 / (get_bus_freq(0) / 1000));
- if (picos % (2000000000 / (get_bus_freq(0) / 1000)) != 0) {
+ /* use unsigned long long to avoid rounding errors */
+ const unsigned long long ULL_2e12 = 2000000000000ULL;
+ unsigned long long clks;
+ unsigned long long clks_temp;
+
+ if (! picos)
+ return 0;
+
+ clks = get_bus_freq(0) * (unsigned long long) picos;
+ clks_temp = clks;
+ clks = clks / ULL_2e12;
+ if (clks_temp % ULL_2e12) {
clks++;
}
- return clks;
+ if (clks > 0xFFFFFFFFULL) {
+ clks = 0xFFFFFFFFULL;
+ }
+
+ return (unsigned int) clks;
}
800,
900,
250,
- 330, /* FIXME: Is 333 better/valid? */
- 660, /* FIXME: Is 667 better/valid? */
+ 330,
+ 660,
750,
0, /* undefined */
0 /* undefined */
}
+/*
+ * 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_init(unsigned char i2c_address, unsigned int ddr_num,
unsigned int dimm_num, unsigned int start_addr)
unsigned int rank_density;
unsigned int odt_rd_cfg, odt_wr_cfg;
unsigned int odt_cfg, mode_odt_enable;
+ unsigned int refresh_clk;
+#ifdef MPC86xx_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;
- unsigned int max_data_rate, effective_data_rate;
+ unsigned int max_data_rate;
unsigned int busfreq;
- unsigned sdram_cfg_1;
unsigned int memsize;
unsigned char caslat, caslat_ctrl;
unsigned int trfc, trfc_clk, trfc_low, trfc_high;
unsigned char cpo;
unsigned char burst_len;
unsigned int mode_caslat;
- unsigned char sdram_type;
unsigned char d_init;
- unsigned int law_size;
- volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm;
+ unsigned int tCycle_ps, modfreq;
if (ddr_num == 1)
ddr = &immap->im_ddr1;
/*
* Read SPD information.
*/
-
debug("Performing SPD read at I2C address 0x%02lx\n",i2c_address);
memset((void *)&spd, 0, sizeof(spd));
CFG_READ_SPD(i2c_address, 0, 1, (uchar *) &spd, sizeof(spd));
}
/*
- * Adjust DDR II IO voltage biasing. It just makes it work.
+ * Adjust DDR II IO voltage biasing. Rev1 only
*/
- if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+ if (((get_svr() & 0xf0) == 0x10) && (spd.mem_type == SPD_MEMTYPE_DDR2)) {
gur->ddrioovcr = (0
| 0x80000000 /* Enable */
| 0x10000000 /* VSEL to 1.8V */
}
#ifdef CONFIG_DDR_INTERLEAVE
-#ifdef CONFIG_MPC8641HPCN
+
if (dimm_num != 1) {
printf("For interleaving memory on HPCN, need to use DIMM 1 for DDR Controller %d !\n", ddr_num);
return 0;
rank_density /= 2;
}
}
-#endif /* CONFIG_MPC8641HPCN */
-
#else /* CONFIG_DDR_INTERLEAVE */
if (dimm_num == 1) {
* are slower than the DDR module.
*/
busfreq = get_bus_freq(0) / 1000000; /* MHz */
+ tCycle_ps = convert_bcd_tenths_to_cycle_time_ps(spd.clk_cycle3);
+ modfreq = 2 * 1000 * 1000 / tCycle_ps;
- effective_data_rate = max_data_rate;
- if (busfreq < 90) {
- /* DDR rate out-of-range */
- puts("DDR: platform frequency is not fit for DDR rate\n");
+ if ((spd.mem_type == SPD_MEMTYPE_DDR2) && (busfreq < 266)) {
+ printf("DDR: platform frequency too low for correct DDR2 controller operation\n");
return 0;
-
- } else if (90 <= busfreq && busfreq < 230 && max_data_rate >= 230) {
- /*
- * busfreq 90~230 range, treated as DDR 200.
- */
- effective_data_rate = 200;
- if (spd.clk_cycle3 == 0xa0) /* 10 ns */
- caslat -= 2;
- else if (spd.clk_cycle2 == 0xa0)
- caslat--;
-
- } else if (230 <= busfreq && busfreq < 280 && max_data_rate >= 280) {
- /*
- * busfreq 230~280 range, treated as DDR 266.
- */
- effective_data_rate = 266;
- if (spd.clk_cycle3 == 0x75) /* 7.5 ns */
- caslat -= 2;
- else if (spd.clk_cycle2 == 0x75)
- caslat--;
-
- } else if (280 <= busfreq && busfreq < 350 && max_data_rate >= 350) {
- /*
- * busfreq 280~350 range, treated as DDR 333.
- */
- effective_data_rate = 333;
- if (spd.clk_cycle3 == 0x60) /* 6.0 ns */
- caslat -= 2;
- else if (spd.clk_cycle2 == 0x60)
- caslat--;
-
- } else if (350 <= busfreq && busfreq < 460 && max_data_rate >= 460) {
- /*
- * busfreq 350~460 range, treated as DDR 400.
- */
- effective_data_rate = 400;
- if (spd.clk_cycle3 == 0x50) /* 5.0 ns */
- caslat -= 2;
- else if (spd.clk_cycle2 == 0x50)
- caslat--;
-
- } else if (460 <= busfreq && busfreq < 560 && max_data_rate >= 560) {
- /*
- * busfreq 460~560 range, treated as DDR 533.
- */
- effective_data_rate = 533;
- if (spd.clk_cycle3 == 0x3D) /* 3.75 ns */
- caslat -= 2;
- else if (spd.clk_cycle2 == 0x3D)
- caslat--;
-
- } else if (560 <= busfreq && busfreq < 700 && max_data_rate >= 700) {
- /*
- * busfreq 560~700 range, treated as DDR 667.
- */
- effective_data_rate = 667;
- if (spd.clk_cycle3 == 0x30) /* 3.0 ns */
- caslat -= 2;
- else if (spd.clk_cycle2 == 0x30)
- caslat--;
-
- } else if (700 <= busfreq) {
- /*
- * DDR rate out-of-range
- */
- printf("DDR: Bus freq %d MHz is not fit for DDR rate %d MHz\n",
- busfreq, max_data_rate);
+ } else if (busfreq < 90) {
+ printf("DDR: platform frequency too low for correct DDR1 operation\n");
return 0;
}
+ if ((busfreq <= modfreq) && (spd.cas_lat & (1 << (caslat - 2)))) {
+ caslat -= 2;
+ } else {
+ tCycle_ps = convert_bcd_tenths_to_cycle_time_ps(spd.clk_cycle2);
+ modfreq = 2 * 1000 * 1000 / tCycle_ps;
+ if ((busfreq <= modfreq) && (spd.cas_lat & (1 << (caslat - 1))))
+ caslat -= 1;
+ else if (busfreq > max_data_rate) {
+ printf("DDR: Bus freq %d MHz is not fit for DDR rate %d MHz\n",
+ busfreq, max_data_rate);
+ return 0;
+ }
+ }
+
+ /*
+ * Empirically set ~MCAS-to-preamble override for DDR 2.
+ * Your milage will vary.
+ */
+ cpo = 0;
+ if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+ if (busfreq <= 333) {
+ cpo = 0x7;
+ } else if (busfreq <= 400) {
+ cpo = 0x9;
+ } else {
+ cpo = 0xa;
+ }
+ }
/*
* Convert caslat clocks to DDR controller value.
caslat_ctrl = (2 * caslat - 1) & 0x0f;
}
- debug("DDR: effective data rate is %d MHz\n", effective_data_rate);
debug("DDR: caslat SPD bit is %d, controller field is 0x%x\n",
caslat, caslat_ctrl);
&& (odt_wr_cfg || odt_rd_cfg)
&& (caslat < 4)) {
add_lat = 4 - caslat;
- if (add_lat > trcd_clk) {
+ if (add_lat >= trcd_clk) {
add_lat = trcd_clk - 1;
}
}
four_act = picos_to_clk(37500); /* By the book. 1k pages? */
}
- /*
- * Empirically set ~MCAS-to-preamble override for DDR 2.
- * Your milage will vary.
- */
- cpo = 0;
- if (spd.mem_type == SPD_MEMTYPE_DDR2) {
- if (effective_data_rate == 266 || effective_data_rate == 333) {
- cpo = 0x7; /* READ_LAT + 5/4 */
- } else if (effective_data_rate == 400) {
- cpo = 0x9; /* READ_LAT + 7/4 */
- } else {
- /* Pure speculation */
- cpo = 0xb;
- }
- }
-
ddr->timing_cfg_2 = (0
| ((add_lat & 0x7) << 28) /* ADD_LAT */
| ((cpo & 0x1f) << 23) /* CPO */
twr_auto_clk = (spd.twr * 250 + tCKmax_ps - 1) / tCKmax_ps;
}
-
/*
* Mode Reg in bits 16 ~ 31,
* Extended Mode Reg 1 in bits 0 ~ 15.
debug("DDR: sdram_mode = 0x%08x\n", ddr->sdram_mode_1);
-
/*
* Clear EMRS2 and EMRS3.
*/
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 = determine_refresh_rate(spd.refresh & 0x7);
- 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);
- /*
- * 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?
debug("DDR: err_sbe = 0x%08x\n", ddr->err_sbe);
#endif
- asm("sync;isync");
+ asm volatile("sync;isync");
udelay(500);
/*
#ifdef MPC86xx_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
-
/*
* Figure out memory size in Megabytes.
*/
* Read both dimm slots and decide whether
* or not to enable this controller.
*/
- memset((void *)&spd1,0,sizeof(spd1));
- memset((void *)&spd2,0,sizeof(spd2));
+ memset((void *)&spd1, 0, sizeof(spd1));
+ memset((void *)&spd2, 0, sizeof(spd2));
if (ddr_num == 1) {
CFG_READ_SPD(SPD_EEPROM_ADDRESS1,
0, 1, (uchar *) &spd1, sizeof(spd1));
+#if defined(SPD_EEPROM_ADDRESS2)
CFG_READ_SPD(SPD_EEPROM_ADDRESS2,
0, 1, (uchar *) &spd2, sizeof(spd2));
+#endif
} else {
+#if defined(SPD_EEPROM_ADDRESS3)
CFG_READ_SPD(SPD_EEPROM_ADDRESS3,
0, 1, (uchar *) &spd1, sizeof(spd1));
+#endif
+#if defined(SPD_EEPROM_ADDRESS4)
CFG_READ_SPD(SPD_EEPROM_ADDRESS4,
0, 1, (uchar *) &spd2, sizeof(spd2));
+#endif
}
/*
* If the user wanted ECC (enabled via sdram_cfg[2])
*/
if (config == 0x02) {
+ ddr->err_disable = 0x00000000;
+ asm volatile("sync;isync;");
+ ddr->err_sbe = 0x00ff0000;
+ ddr->err_int_en = 0x0000000d;
sdram_cfg_1 |= 0x20000000; /* ECC_EN */
}
#endif
/*
- * REV1 uses 1T timing.
- * REV2 may use 1T or 2T as configured by the user.
+ * Set 1T or 2T timing based on 1 or 2 modules
*/
{
- uint pvr = get_pvr();
-
- if (pvr != PVR_85xx_REV1) {
-#if defined(CONFIG_DDR_2T_TIMING)
+ if (!(no_dimm1 || no_dimm2)) {
/*
+ * 2T timing,because both DIMMS are present.
* Enable 2T timing by setting sdram_cfg[16].
*/
sdram_cfg_1 |= 0x8000; /* 2T_EN */
-#endif
}
}
{
int memsize_ddr1_dimm1 = 0;
int memsize_ddr1_dimm2 = 0;
+ int memsize_ddr1 = 0;
+ unsigned int law_size_ddr1;
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm;
+#ifdef CONFIG_DDR_INTERLEAVE
+ volatile ccsr_ddr_t *ddr1 = &immap->im_ddr1;
+#endif
+
+#if (CONFIG_NUM_DDR_CONTROLLERS > 1)
int memsize_ddr2_dimm1 = 0;
int memsize_ddr2_dimm2 = 0;
- int memsize_total = 0;
- int memsize_ddr1 = 0;
int memsize_ddr2 = 0;
+ unsigned int law_size_ddr2;
+#endif
+
unsigned int ddr1_enabled = 0;
unsigned int ddr2_enabled = 0;
- unsigned int law_size_ddr1;
- unsigned int law_size_ddr2;
- volatile immap_t *immap = (immap_t *)CFG_IMMR;
- volatile ccsr_ddr_t *ddr1 = &immap->im_ddr1;
- volatile ccsr_ddr_t *ddr2 = &immap->im_ddr2;
- volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm;
+ int memsize_total = 0;
#ifdef CONFIG_DDR_INTERLEAVE
unsigned int law_size_interleaved;
+ volatile ccsr_ddr_t *ddr2 = &immap->im_ddr2;
memsize_ddr1_dimm1 = spd_init(SPD_EEPROM_ADDRESS1,
1, 1,
(unsigned int)memsize_total * 1024*1024);
memsize_total += memsize_ddr1_dimm1;
+#if defined(SPD_EEPROM_ADDRESS2)
memsize_ddr1_dimm2 = spd_init(SPD_EEPROM_ADDRESS2,
1, 2,
(unsigned int)memsize_total * 1024*1024);
+#endif
memsize_total += memsize_ddr1_dimm2;
/*
debug("\nDDR: LAWBAR8=0x%08x\n", mcm->lawbar8);
debug("DDR: LAWAR8=0x%08x\n", mcm->lawar8);
}
+
+ debug("\nMemory size of DDR2 = 0x%08lx\n", memsize_ddr2);
+
#endif /* CONFIG_NUM_DDR_CONTROLLERS > 1 */
- debug("\nMemory sizes are DDR1 = 0x%08lx, DDR2 = 0x%08lx\n",
- memsize_ddr1, memsize_ddr2);
+ debug("\nMemory size of DDR1 = 0x%08lx\n", memsize_ddr1);
/*
* If neither DDR controller is enabled return 0.
*/
if (!ddr1_enabled && !ddr2_enabled)
return 0;
- else {
- printf("Non-interleaved");
- return memsize_total * 1024 * 1024;
- }
+
+ printf("Non-interleaved");
+ return memsize_total * 1024 * 1024;
#endif /* CONFIG_DDR_INTERLEAVE */
}
}
}
- /* 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);
*/
debug("DMA DDR: err_disable = 0x%08x\n", ddr1->err_disable);
ddr1->err_disable = 0x00000000;
- asm("sync;isync;msync");
+ asm volatile("sync;isync");
debug("DMA DDR: err_disable = 0x%08x\n", ddr1->err_disable);
}