Fix caslat calculation
Signed-off-by: John Traill <john.traill@freescale.com>
This commit is contained in:
parent
709d3073e7
commit
91a414c7d1
@ -44,7 +44,7 @@ extern int dma_xfer(void *dest, uint count, void *src);
|
|||||||
/*
|
/*
|
||||||
* Only one of the following three should be 1; others should be 0
|
* Only one of the following three should be 1; others should be 0
|
||||||
* By default the cache line interleaving is selected if
|
* 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_PAGE_INTERLEAVING 0
|
||||||
#define CFG_BANK_INTERLEAVING 0
|
#define CFG_BANK_INTERLEAVING 0
|
||||||
@ -137,8 +137,8 @@ convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val)
|
|||||||
800,
|
800,
|
||||||
900,
|
900,
|
||||||
250,
|
250,
|
||||||
330, /* FIXME: Is 333 better/valid? */
|
330,
|
||||||
660, /* FIXME: Is 667 better/valid? */
|
660,
|
||||||
750,
|
750,
|
||||||
0, /* undefined */
|
0, /* undefined */
|
||||||
0 /* undefined */
|
0 /* undefined */
|
||||||
@ -167,7 +167,7 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num,
|
|||||||
unsigned int dqs_cfg;
|
unsigned int dqs_cfg;
|
||||||
unsigned char twr_clk, twtr_clk, twr_auto_clk;
|
unsigned char twr_clk, twtr_clk, twr_auto_clk;
|
||||||
unsigned int tCKmin_ps, tCKmax_ps;
|
unsigned int tCKmin_ps, tCKmax_ps;
|
||||||
unsigned int max_data_rate, effective_data_rate;
|
unsigned int max_data_rate;
|
||||||
unsigned int busfreq;
|
unsigned int busfreq;
|
||||||
unsigned sdram_cfg_1;
|
unsigned sdram_cfg_1;
|
||||||
unsigned int memsize;
|
unsigned int memsize;
|
||||||
@ -187,6 +187,7 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num,
|
|||||||
unsigned char d_init;
|
unsigned char d_init;
|
||||||
unsigned int law_size;
|
unsigned int law_size;
|
||||||
volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm;
|
volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm;
|
||||||
|
unsigned int tCycle_ps, modfreq;
|
||||||
|
|
||||||
if (ddr_num == 1)
|
if (ddr_num == 1)
|
||||||
ddr = &immap->im_ddr1;
|
ddr = &immap->im_ddr1;
|
||||||
@ -288,7 +289,7 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_DDR_INTERLEAVE
|
#ifdef CONFIG_DDR_INTERLEAVE
|
||||||
#ifdef CONFIG_MPC8641HPCN
|
|
||||||
if (dimm_num != 1) {
|
if (dimm_num != 1) {
|
||||||
printf("For interleaving memory on HPCN, need to use DIMM 1 for DDR Controller %d !\n", ddr_num);
|
printf("For interleaving memory on HPCN, need to use DIMM 1 for DDR Controller %d !\n", ddr_num);
|
||||||
return 0;
|
return 0;
|
||||||
@ -340,8 +341,6 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num,
|
|||||||
rank_density /= 2;
|
rank_density /= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_MPC8641HPCN */
|
|
||||||
|
|
||||||
#else /* CONFIG_DDR_INTERLEAVE */
|
#else /* CONFIG_DDR_INTERLEAVE */
|
||||||
|
|
||||||
if (dimm_num == 1) {
|
if (dimm_num == 1) {
|
||||||
@ -468,81 +467,42 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num,
|
|||||||
*/
|
*/
|
||||||
busfreq = get_bus_freq(0) / 1000000; /* MHz */
|
busfreq = get_bus_freq(0) / 1000000; /* MHz */
|
||||||
|
|
||||||
effective_data_rate = max_data_rate;
|
if ((spd.mem_type == SPD_MEMTYPE_DDR2) && (busfreq < 266)) {
|
||||||
if (busfreq < 90) {
|
printf("DDR: platform frequency too low for correct DDR2 controller operation\n");
|
||||||
/* DDR rate out-of-range */
|
|
||||||
puts("DDR: platform frequency is not fit for DDR rate\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
|
} else if (busfreq < 90) {
|
||||||
} else if (90 <= busfreq && busfreq < 230 && max_data_rate >= 230) {
|
printf("DDR: platform frequency too low for correct DDR1 operation\n");
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
return 0;
|
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.
|
* Convert caslat clocks to DDR controller value.
|
||||||
@ -554,7 +514,6 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num,
|
|||||||
caslat_ctrl = (2 * caslat - 1) & 0x0f;
|
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",
|
debug("DDR: caslat SPD bit is %d, controller field is 0x%x\n",
|
||||||
caslat, caslat_ctrl);
|
caslat, caslat_ctrl);
|
||||||
|
|
||||||
@ -676,7 +635,7 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num,
|
|||||||
&& (odt_wr_cfg || odt_rd_cfg)
|
&& (odt_wr_cfg || odt_rd_cfg)
|
||||||
&& (caslat < 4)) {
|
&& (caslat < 4)) {
|
||||||
add_lat = 4 - caslat;
|
add_lat = 4 - caslat;
|
||||||
if (add_lat > trcd_clk) {
|
if (add_lat >= trcd_clk) {
|
||||||
add_lat = trcd_clk - 1;
|
add_lat = trcd_clk - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -717,22 +676,6 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num,
|
|||||||
four_act = picos_to_clk(37500); /* By the book. 1k pages? */
|
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
|
ddr->timing_cfg_2 = (0
|
||||||
| ((add_lat & 0x7) << 28) /* ADD_LAT */
|
| ((add_lat & 0x7) << 28) /* ADD_LAT */
|
||||||
| ((cpo & 0x1f) << 23) /* CPO */
|
| ((cpo & 0x1f) << 23) /* CPO */
|
||||||
|
Loading…
Reference in New Issue
Block a user