18bd522ceSDave Liu /* 28bd522ceSDave Liu * Copyright (C) 2007 Freescale Semiconductor, Inc. 38bd522ceSDave Liu * 48bd522ceSDave Liu * Authors: Nick.Spence@freescale.com 58bd522ceSDave Liu * Wilson.Lo@freescale.com 68bd522ceSDave Liu * scottwood@freescale.com 78bd522ceSDave Liu * 88bd522ceSDave Liu * See file CREDITS for list of people who contributed to this 98bd522ceSDave Liu * project. 108bd522ceSDave Liu * 118bd522ceSDave Liu * This program is free software; you can redistribute it and/or 128bd522ceSDave Liu * modify it under the terms of the GNU General Public License as 138bd522ceSDave Liu * published by the Free Software Foundation; either version 2 of 148bd522ceSDave Liu * the License, or (at your option) any later version. 158bd522ceSDave Liu * 168bd522ceSDave Liu * This program is distributed in the hope that it will be useful, 178bd522ceSDave Liu * but WITHOUT ANY WARRANTY; without even the implied warranty of 188bd522ceSDave Liu * MERCHANTABILITY or FITNESS for A PARTICULAR PURPOSE. See the 198bd522ceSDave Liu * GNU General Public License for more details. 208bd522ceSDave Liu * 218bd522ceSDave Liu * You should have received a copy of the GNU General Public License 228bd522ceSDave Liu * along with this program; if not, write to the Free Software 238bd522ceSDave Liu * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 248bd522ceSDave Liu * MA 02111-1307 USA 258bd522ceSDave Liu */ 268bd522ceSDave Liu 278bd522ceSDave Liu #include <common.h> 288bd522ceSDave Liu #include <mpc83xx.h> 298bd522ceSDave Liu #include <spd_sdram.h> 308bd522ceSDave Liu 318bd522ceSDave Liu #include <asm/bitops.h> 328bd522ceSDave Liu #include <asm/io.h> 338bd522ceSDave Liu 348bd522ceSDave Liu #include <asm/processor.h> 358bd522ceSDave Liu 368bd522ceSDave Liu DECLARE_GLOBAL_DATA_PTR; 378bd522ceSDave Liu 388bd522ceSDave Liu static void resume_from_sleep(void) 398bd522ceSDave Liu { 408bd522ceSDave Liu u32 magic = *(u32 *)0; 418bd522ceSDave Liu 428bd522ceSDave Liu typedef void (*func_t)(void); 438bd522ceSDave Liu func_t resume = *(func_t *)4; 448bd522ceSDave Liu 458bd522ceSDave Liu if (magic == 0xf5153ae5) 468bd522ceSDave Liu resume(); 478bd522ceSDave Liu 488bd522ceSDave Liu gd->flags &= ~GD_FLG_SILENT; 498bd522ceSDave Liu puts("\nResume from sleep failed: bad magic word\n"); 508bd522ceSDave Liu } 518bd522ceSDave Liu 528bd522ceSDave Liu /* Fixed sdram init -- doesn't use serial presence detect. 538bd522ceSDave Liu * 548bd522ceSDave Liu * This is useful for faster booting in configs where the RAM is unlikely 558bd522ceSDave Liu * to be changed, or for things like NAND booting where space is tight. 568bd522ceSDave Liu */ 578bd522ceSDave Liu static long fixed_sdram(void) 588bd522ceSDave Liu { 59*6d0f6bcfSJean-Christophe PLAGNIOL-VILLARD volatile immap_t *im = (volatile immap_t *)CONFIG_SYS_IMMR; 60*6d0f6bcfSJean-Christophe PLAGNIOL-VILLARD u32 msize = CONFIG_SYS_DDR_SIZE * 1024 * 1024; 618bd522ceSDave Liu u32 msize_log2 = __ilog2(msize); 628bd522ceSDave Liu 63*6d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->sysconf.ddrlaw[0].bar = CONFIG_SYS_DDR_SDRAM_BASE & 0xfffff000; 648bd522ceSDave Liu im->sysconf.ddrlaw[0].ar = LBLAWAR_EN | (msize_log2 - 1); 65*6d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->sysconf.ddrcdr = CONFIG_SYS_DDRCDR_VALUE; 668bd522ceSDave Liu 678bd522ceSDave Liu /* 688bd522ceSDave Liu * Erratum DDR3 requires a 50ms delay after clearing DDRCDR[DDR_cfg], 698bd522ceSDave Liu * or the DDR2 controller may fail to initialize correctly. 708bd522ceSDave Liu */ 718bd522ceSDave Liu udelay(50000); 728bd522ceSDave Liu 738bd522ceSDave Liu im->ddr.csbnds[0].csbnds = (msize - 1) >> 24; 74*6d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.cs_config[0] = CONFIG_SYS_DDR_CS0_CONFIG; 758bd522ceSDave Liu 768bd522ceSDave Liu /* Currently we use only one CS, so disable the other bank. */ 778bd522ceSDave Liu im->ddr.cs_config[1] = 0; 788bd522ceSDave Liu 79*6d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.sdram_clk_cntl = CONFIG_SYS_DDR_SDRAM_CLK_CNTL; 80*6d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3; 81*6d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1; 82*6d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2; 83*6d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0; 848bd522ceSDave Liu 858bd522ceSDave Liu if (im->pmc.pmccr1 & PMCCR1_POWER_OFF) 86*6d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG | SDRAM_CFG_BI; 878bd522ceSDave Liu else 88*6d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG; 898bd522ceSDave Liu 90*6d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.sdram_cfg2 = CONFIG_SYS_DDR_SDRAM_CFG2; 91*6d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.sdram_mode = CONFIG_SYS_DDR_MODE; 92*6d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.sdram_mode2 = CONFIG_SYS_DDR_MODE2; 938bd522ceSDave Liu 94*6d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.sdram_interval = CONFIG_SYS_DDR_INTERVAL; 958bd522ceSDave Liu sync(); 968bd522ceSDave Liu 978bd522ceSDave Liu /* enable DDR controller */ 988bd522ceSDave Liu im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN; 998bd522ceSDave Liu sync(); 1008bd522ceSDave Liu 1018bd522ceSDave Liu return msize; 1028bd522ceSDave Liu } 1038bd522ceSDave Liu 1049973e3c6SBecky Bruce phys_size_t initdram(int board_type) 1058bd522ceSDave Liu { 106*6d0f6bcfSJean-Christophe PLAGNIOL-VILLARD volatile immap_t *im = (volatile immap_t *)CONFIG_SYS_IMMR; 1078bd522ceSDave Liu u32 msize; 1088bd522ceSDave Liu 1098bd522ceSDave Liu if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32)im) 1108bd522ceSDave Liu return -1; 1118bd522ceSDave Liu 1128bd522ceSDave Liu /* DDR SDRAM */ 1138bd522ceSDave Liu msize = fixed_sdram(); 1148bd522ceSDave Liu 1158bd522ceSDave Liu if (im->pmc.pmccr1 & PMCCR1_POWER_OFF) 1168bd522ceSDave Liu resume_from_sleep(); 1178bd522ceSDave Liu 1188bd522ceSDave Liu /* return total bus SDRAM size(bytes) -- DDR */ 1198bd522ceSDave Liu return msize; 1208bd522ceSDave Liu } 121