/*
- * Copyright 2004 Freescale Semiconductor.
+ * Copyright 2004, 2007 Freescale Semiconductor.
* (C) Copyright 2003 Motorola Inc.
* Xianghua Xiao (X.Xiao@motorola.com)
*
#include <i2c.h>
#include <spd.h>
#include <asm/mmu.h>
+#include <asm/fsl_law.h>
#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
{
int clks;
- clks = picos / (2000000000 / (get_bus_freq(0) / 1000));
- if (picos % (2000000000 / (get_bus_freq(0) / 1000)) != 0) {
+ clks = picos / (2000000000 / (get_ddr_freq(0) / 1000));
+ if (picos % (2000000000 / (get_ddr_freq(0) / 1000)) != 0) {
clks++;
}
long int
spd_sdram(void)
{
- volatile immap_t *immap = (immap_t *)CFG_IMMR;
- volatile ccsr_ddr_t *ddr = &immap->im_ddr;
- volatile ccsr_gur_t *gur = &immap->im_gur;
+ volatile ccsr_ddr_t *ddr = (void *)(CFG_MPC85xx_DDR_ADDR);
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 MPC85xx_DDR_SDRAM_CLK_CNTL
unsigned int max_data_rate, effective_data_rate;
unsigned int busfreq;
unsigned sdram_cfg;
- unsigned int memsize;
+ unsigned int memsize = 0;
unsigned char caslat, caslat_ctrl;
unsigned int trfc, trfc_clk, trfc_low, trfc_high;
unsigned int trcd_clk;
unsigned int mode_caslat;
unsigned char sdram_type;
unsigned char d_init;
+ unsigned int bnds;
+
+ /*
+ * Skip configuration if already configured.
+ * memsize is determined from last configured chip select.
+ */
+ if (ddr->cs0_config & 0x80000000) {
+ debug(" cs0 already configured, bnds=%x\n",ddr->cs0_bnds);
+ bnds = 0xfff & ddr->cs0_bnds;
+ if (bnds < 0xff) { /* do not add if at top of 4G */
+ memsize = (bnds + 1) << 4;
+ }
+ }
+ if (ddr->cs1_config & 0x80000000) {
+ debug(" cs1 already configured, bnds=%x\n",ddr->cs1_bnds);
+ bnds = 0xfff & ddr->cs1_bnds;
+ if (bnds < 0xff) { /* do not add if at top of 4G */
+ memsize = (bnds + 1) << 4; /* assume ordered bnds */
+ }
+ }
+ if (ddr->cs2_config & 0x80000000) {
+ debug(" cs2 already configured, bnds=%x\n",ddr->cs2_bnds);
+ bnds = 0xfff & ddr->cs2_bnds;
+ if (bnds < 0xff) { /* do not add if at top of 4G */
+ memsize = (bnds + 1) << 4;
+ }
+ }
+ if (ddr->cs3_config & 0x80000000) {
+ debug(" cs3 already configured, bnds=%x\n",ddr->cs3_bnds);
+ bnds = 0xfff & ddr->cs3_bnds;
+ if (bnds < 0xff) { /* do not add if at top of 4G */
+ memsize = (bnds + 1) << 4;
+ }
+ }
+
+ if (memsize) {
+ printf(" Reusing current %dMB configuration\n",memsize);
+ memsize = setup_laws_and_tlbs(memsize);
+ return memsize << 20;
+ }
/*
* Read SPD information.
return 0;
}
+#ifdef CONFIG_MPC8548
/*
* Adjust DDR II IO voltage biasing.
* Only 8548 rev 1 needs the fix
*/
- if ((SVR_VER(get_svr()) == SVR_8548_E) &&
+ if ((SVR_SOC_VER(get_svr()) == SVR_8548_E) &&
(SVR_MJREV(get_svr()) == 1) &&
(spd.mem_type == SPD_MEMTYPE_DDR2)) {
+ volatile ccsr_gur_t *gur = (void *)(CFG_MPC85xx_GUTS_ADDR);
gur->ddrioovcr = (0x80000000 /* Enable */
| 0x10000000);/* VSEL to 1.8V */
}
+#endif
/*
* Determine the size of each Rank in bytes.
#endif
}
+ ba_bits = 0;
+ if (spd.nbanks == 0x8)
+ ba_bits = 1;
+
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) );
debug("\n");
* Adjust the CAS Latency to allow for bus speeds that
* are slower than the DDR module.
*/
- busfreq = get_bus_freq(0) / 1000000; /* MHz */
+ busfreq = get_ddr_freq(0) / 1000000; /* MHz */
effective_data_rate = max_data_rate;
if (busfreq < 90) {
/*
* Sneak in some Extended Refresh Recovery.
*/
- ddr->ext_refrec = (trfc_high << 16);
- debug("DDR: ext_refrec = 0x%08x\n", ddr->ext_refrec);
+ ddr->timing_cfg_3 = (trfc_high << 16);
+ debug("DDR: timing_cfg_3 = 0x%08x\n", ddr->timing_cfg_3);
ddr->timing_cfg_1 =
(0
*/
cpo = 0;
if (spd.mem_type == SPD_MEMTYPE_DDR2) {
- if (effective_data_rate == 266 || effective_data_rate == 333) {
+ if (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;
+ cpo = 0x9; /* READ_LAT + 7/4 */
}
}
if (spd.mem_type == SPD_MEMTYPE_DDR)
clk_adjust = 0x6;
else
+#ifdef CONFIG_MPC8568
+ /* Empirally setting clk_adjust */
+ clk_adjust = 0x6;
+#else
clk_adjust = 0x7;
+#endif
ddr->sdram_clk_cntl = (0
| 0x80000000
static unsigned int
setup_laws_and_tlbs(unsigned int memsize)
{
- volatile immap_t *immap = (immap_t *)CFG_IMMR;
- volatile ccsr_local_ecm_t *ecm = &immap->im_local_ecm;
unsigned int tlb_size;
unsigned int law_size;
unsigned int ram_tlb_index;
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));
- 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: MAS3=0x%08x\n",
- TLB1_MAS3(E500_TLB_RPN(ram_tlb_address),
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 1));
+ set_tlb(1, ram_tlb_address, ram_tlb_address,
+ MAS3_SX|MAS3_SW|MAS3_SR, 0,
+ 0, ram_tlb_index, tlb_size, 1);
ram_tlb_address += (0x1000 << ((tlb_size - 1) * 2));
ram_tlb_index++;
/*
* Set up LAWBAR for all of DDR.
*/
- ecm->lawbar1 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff);
- ecm->lawar1 = (LAWAR_EN
- | LAWAR_TRGT_IF_DDR
- | (LAWAR_SIZE & law_size));
- debug("DDR: LAWBAR1=0x%08x\n", ecm->lawbar1);
- debug("DDR: LARAR1=0x%08x\n", ecm->lawar1);
+
+#ifdef CONFIG_FSL_LAW
+ set_next_law(CFG_DDR_SDRAM_BASE, law_size, LAW_TRGT_IF_DDR);
+#endif
/*
* Confirm that the requested amount of memory was mapped.
{
uint *p = 0;
uint i = 0;
- volatile immap_t *immap = (immap_t *)CFG_IMMR;
- volatile ccsr_ddr_t *ddr= &immap->im_ddr;
+ volatile ccsr_ddr_t *ddr= (void *)(CFG_MPC85xx_DDR_ADDR);
dma_init();