Newer
Older
if (!(is_lpddr2_sdram_present(base, cs, lpddr2_dev_details)))
return NULL;
display_sdram_details(emif_num(base), cs, lpddr2_dev_details);
return lpddr2_dev_details;
}
#endif /* CONFIG_SYS_AUTOMATIC_SDRAM_DETECTION */
static void do_sdram_init(u32 base)
{
const struct emif_regs *regs;
u32 in_sdram, emif_nr;
debug(">>do_sdram_init() %x\n", base);
in_sdram = running_from_sdram();
emif_nr = (base == EMIF1_BASE) ? 1 : 2;
#ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
emif_get_reg_dump(emif_nr, ®s);
if (!regs) {
debug("EMIF: reg dump not provided\n");
return;
}
#else
/*
* The user has not provided the register values. We need to
* calculate it based on the timings and the DDR frequency
*/
struct emif_device_details dev_details;
struct emif_regs calculated_regs;
/*
* Get device details:
* - Discovered if CONFIG_SYS_AUTOMATIC_SDRAM_DETECTION is set
* - Obtained from user otherwise
*/
struct lpddr2_device_details cs0_dev_details, cs1_dev_details;
dev_details.cs0_device_details = emif_get_device_details(emif_nr, CS0,
dev_details.cs1_device_details = emif_get_device_details(emif_nr, CS1,
&cs1_dev_details);
emif_reset_phy(base);
/* Return if no devices on this EMIF */
if (!dev_details.cs0_device_details &&
!dev_details.cs1_device_details) {
return;
}
/*
* Get device timings:
* - Default timings specified by JESD209-2 if
* CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS is set
* - Obtained from user otherwise
*/
emif_get_device_timings(emif_nr, &dev_details.cs0_device_timings,
&dev_details.cs1_device_timings);
/* Calculate the register values */
emif_calculate_regs(&dev_details, omap_ddr_clk(), &calculated_regs);
regs = &calculated_regs;
#endif /* CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS */
/*
* Initializing the LPDDR2 device can not happen from SDRAM.
* Changing the timing registers in EMIF can happen(going from one
* OPP to another)
*/
if (!(in_sdram || warm_reset())) {
if (emif_sdram_type() == EMIF_SDRAM_TYPE_LPDDR2)
lpddr2_init(base, regs);
else
ddr3_init(base, regs);
}
if (warm_reset() && (emif_sdram_type() == EMIF_SDRAM_TYPE_DDR3)) {
set_lpmode_selfrefresh(base);
emif_reset_phy(base);
ddr3_leveling(base, regs);
}
/* Write to the shadow registers */
emif_update_timings(base, regs);
debug("<<do_sdram_init() %x\n", base);
}
void emif_post_init_config(u32 base)
{
struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
u32 omap_rev = omap_revision();
if (omap_rev == OMAP4430_ES2_0)
emif_reset_phy(base);
/* Put EMIF back in smart idle on ES1.0 */
if (omap_rev == OMAP4430_ES1_0)
writel(0x80000000, &emif->emif_pwr_mgmt_ctrl);
}
void dmm_init(u32 base)
{
const struct dmm_lisa_map_regs *lisa_map_regs;
#ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
#else
u32 emif1_size, emif2_size, mapped_size, section_map = 0;
u32 section_cnt, sys_addr;
struct dmm_lisa_map_regs lis_map_regs_calculated = {0};
mapped_size = 0;
section_cnt = 3;
sys_addr = CONFIG_SYS_SDRAM_BASE;
emif1_size = get_emif_mem_size(EMIF1_BASE);
emif2_size = get_emif_mem_size(EMIF2_BASE);
debug("emif1_size 0x%x emif2_size 0x%x\n", emif1_size, emif2_size);
if (!emif1_size && !emif2_size)
return;
/* symmetric interleaved section */
if (emif1_size && emif2_size) {
mapped_size = min(emif1_size, emif2_size);
section_map = DMM_LISA_MAP_INTERLEAVED_BASE_VAL;
section_map |= 0 << EMIF_SDRC_ADDR_SHIFT;
/* only MSB */
section_map |= (sys_addr >> 24) <<
EMIF_SYS_ADDR_SHIFT;
section_map |= get_dmm_section_size_map(mapped_size * 2)
<< EMIF_SYS_SIZE_SHIFT;
lis_map_regs_calculated.dmm_lisa_map_3 = section_map;
emif1_size -= mapped_size;
emif2_size -= mapped_size;
sys_addr += (mapped_size * 2);
section_cnt--;
}
/*
* Single EMIF section(we can have a maximum of 1 single EMIF
* section- either EMIF1 or EMIF2 or none, but not both)
*/
if (emif1_size) {
section_map = DMM_LISA_MAP_EMIF1_ONLY_BASE_VAL;
section_map |= get_dmm_section_size_map(emif1_size)
<< EMIF_SYS_SIZE_SHIFT;
/* only MSB */
section_map |= (mapped_size >> 24) <<
EMIF_SDRC_ADDR_SHIFT;
section_map |= (sys_addr >> 24) << EMIF_SYS_ADDR_SHIFT;
section_cnt--;
}
if (emif2_size) {
section_map = DMM_LISA_MAP_EMIF2_ONLY_BASE_VAL;
section_map |= get_dmm_section_size_map(emif2_size) <<
EMIF_SYS_SIZE_SHIFT;
section_map |= mapped_size >> 24 << EMIF_SDRC_ADDR_SHIFT;
section_map |= sys_addr >> 24 << EMIF_SYS_ADDR_SHIFT;
section_cnt--;
}
if (section_cnt == 2) {
/* Only 1 section - either symmetric or single EMIF */
lis_map_regs_calculated.dmm_lisa_map_3 = section_map;
lis_map_regs_calculated.dmm_lisa_map_2 = 0;
lis_map_regs_calculated.dmm_lisa_map_1 = 0;
} else {
/* 2 sections - 1 symmetric, 1 single EMIF */
lis_map_regs_calculated.dmm_lisa_map_2 = section_map;
lis_map_regs_calculated.dmm_lisa_map_1 = 0;
}
/* TRAP for invalid TILER mappings in section 0 */
lis_map_regs_calculated.dmm_lisa_map_0 = DMM_LISA_MAP_0_INVAL_ADDR_TRAP;
lisa_map_regs = &lis_map_regs_calculated;
#endif
struct dmm_lisa_map_regs *hw_lisa_map_regs =
(struct dmm_lisa_map_regs *)base;
writel(0, &hw_lisa_map_regs->dmm_lisa_map_3);
writel(0, &hw_lisa_map_regs->dmm_lisa_map_2);
writel(0, &hw_lisa_map_regs->dmm_lisa_map_1);
writel(0, &hw_lisa_map_regs->dmm_lisa_map_0);
writel(lisa_map_regs->dmm_lisa_map_3,
&hw_lisa_map_regs->dmm_lisa_map_3);
writel(lisa_map_regs->dmm_lisa_map_2,
&hw_lisa_map_regs->dmm_lisa_map_2);
writel(lisa_map_regs->dmm_lisa_map_1,
&hw_lisa_map_regs->dmm_lisa_map_1);
writel(lisa_map_regs->dmm_lisa_map_0,
&hw_lisa_map_regs->dmm_lisa_map_0);
if (lisa_map_regs->is_ma_present) {
(struct dmm_lisa_map_regs *)MA_BASE;
writel(lisa_map_regs->dmm_lisa_map_3,
&hw_lisa_map_regs->dmm_lisa_map_3);
writel(lisa_map_regs->dmm_lisa_map_2,
&hw_lisa_map_regs->dmm_lisa_map_2);
writel(lisa_map_regs->dmm_lisa_map_1,
&hw_lisa_map_regs->dmm_lisa_map_1);
writel(lisa_map_regs->dmm_lisa_map_0,
&hw_lisa_map_regs->dmm_lisa_map_0);
}
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
/*
* EMIF should be configured only when
* memory is mapped on it. Using emif1_enabled
* and emif2_enabled variables for this.
*/
emif1_enabled = 0;
emif2_enabled = 0;
for (i = 0; i < 4; i++) {
section = __raw_readl(DMM_BASE + i*4);
valid = (section & EMIF_SDRC_MAP_MASK) >>
(EMIF_SDRC_MAP_SHIFT);
if (valid == 3) {
emif1_enabled = 1;
emif2_enabled = 1;
break;
} else if (valid == 1) {
emif1_enabled = 1;
} else if (valid == 2) {
emif2_enabled = 1;
}
}
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
}
/*
* SDRAM initialization:
* SDRAM initialization has two parts:
* 1. Configuring the SDRAM device
* 2. Update the AC timings related parameters in the EMIF module
* (1) should be done only once and should not be done while we are
* running from SDRAM.
* (2) can and should be done more than once if OPP changes.
* Particularly, this may be needed when we boot without SPL and
* and using Configuration Header(CH). ROM code supports only at 50% OPP
* at boot (low power boot). So u-boot has to switch to OPP100 and update
* the frequency. So,
* Doing (1) and (2) makes sense - first time initialization
* Doing (2) and not (1) makes sense - OPP change (when using CH)
* Doing (1) and not (2) doen't make sense
* See do_sdram_init() for the details
*/
void sdram_init(void)
{
u32 in_sdram, size_prog, size_detect;
u32 sdram_type = emif_sdram_type();
if (omap_hw_init_context() == OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL)
return;
in_sdram = running_from_sdram();
debug("in_sdram = %d\n", in_sdram);
if (!in_sdram) {
if ((sdram_type == EMIF_SDRAM_TYPE_LPDDR2) && !warm_reset())
bypass_dpll((*prcm)->cm_clkmode_dpll_core);
else if (sdram_type == EMIF_SDRAM_TYPE_DDR3)
writel(CM_DLL_CTRL_NO_OVERRIDE, (*prcm)->cm_dll_ctrl);
dmm_init(DMM_BASE);
if (emif1_enabled)
do_sdram_init(EMIF1_BASE);
if (emif2_enabled)
do_sdram_init(EMIF2_BASE);
if (!(in_sdram || warm_reset())) {
if (emif1_enabled)
emif_post_init_config(EMIF1_BASE);
if (emif2_enabled)
emif_post_init_config(EMIF2_BASE);
}
/* for the shadow registers to take effect */
if (sdram_type == EMIF_SDRAM_TYPE_LPDDR2)
/* Do some testing after the init */
if (!in_sdram) {
size_prog = log_2_n_round_down(size_prog);
size_prog = (1 << size_prog);
size_detect = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE,
size_prog);
/* Compare with the size programmed */
if (size_detect != size_prog) {
printf("SDRAM: identified size not same as expected"
" size identified: %x expected: %x\n",
size_detect,
size_prog);
} else
debug("get_ram_size() successful");
}
debug("<<sdram_init()\n");
}