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 * 81a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 98bd522ceSDave Liu */ 108bd522ceSDave Liu 118bd522ceSDave Liu #include <common.h> 128bd522ceSDave Liu #include <mpc83xx.h> 138bd522ceSDave Liu #include <spd_sdram.h> 148bd522ceSDave Liu 158bd522ceSDave Liu #include <asm/bitops.h> 168bd522ceSDave Liu #include <asm/io.h> 178bd522ceSDave Liu 188bd522ceSDave Liu #include <asm/processor.h> 198bd522ceSDave Liu 208bd522ceSDave Liu DECLARE_GLOBAL_DATA_PTR; 218bd522ceSDave Liu 228bd522ceSDave Liu static void resume_from_sleep(void) 238bd522ceSDave Liu { 248bd522ceSDave Liu u32 magic = *(u32 *)0; 258bd522ceSDave Liu 268bd522ceSDave Liu typedef void (*func_t)(void); 278bd522ceSDave Liu func_t resume = *(func_t *)4; 288bd522ceSDave Liu 298bd522ceSDave Liu if (magic == 0xf5153ae5) 308bd522ceSDave Liu resume(); 318bd522ceSDave Liu 328bd522ceSDave Liu gd->flags &= ~GD_FLG_SILENT; 338bd522ceSDave Liu puts("\nResume from sleep failed: bad magic word\n"); 348bd522ceSDave Liu } 358bd522ceSDave Liu 368bd522ceSDave Liu /* Fixed sdram init -- doesn't use serial presence detect. 378bd522ceSDave Liu * 388bd522ceSDave Liu * This is useful for faster booting in configs where the RAM is unlikely 398bd522ceSDave Liu * to be changed, or for things like NAND booting where space is tight. 408bd522ceSDave Liu */ 412e95004dSAnton Vorontsov #ifndef CONFIG_SYS_RAMBOOT 428bd522ceSDave Liu static long fixed_sdram(void) 438bd522ceSDave Liu { 446d0f6bcfSJean-Christophe PLAGNIOL-VILLARD volatile immap_t *im = (volatile immap_t *)CONFIG_SYS_IMMR; 456d0f6bcfSJean-Christophe PLAGNIOL-VILLARD u32 msize = CONFIG_SYS_DDR_SIZE * 1024 * 1024; 468bd522ceSDave Liu u32 msize_log2 = __ilog2(msize); 478bd522ceSDave Liu 486d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->sysconf.ddrlaw[0].bar = CONFIG_SYS_DDR_SDRAM_BASE & 0xfffff000; 498bd522ceSDave Liu im->sysconf.ddrlaw[0].ar = LBLAWAR_EN | (msize_log2 - 1); 506d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->sysconf.ddrcdr = CONFIG_SYS_DDRCDR_VALUE; 518bd522ceSDave Liu 528bd522ceSDave Liu /* 538bd522ceSDave Liu * Erratum DDR3 requires a 50ms delay after clearing DDRCDR[DDR_cfg], 548bd522ceSDave Liu * or the DDR2 controller may fail to initialize correctly. 558bd522ceSDave Liu */ 562e95004dSAnton Vorontsov __udelay(50000); 578bd522ceSDave Liu 588bd522ceSDave Liu im->ddr.csbnds[0].csbnds = (msize - 1) >> 24; 596d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.cs_config[0] = CONFIG_SYS_DDR_CS0_CONFIG; 608bd522ceSDave Liu 618bd522ceSDave Liu /* Currently we use only one CS, so disable the other bank. */ 628bd522ceSDave Liu im->ddr.cs_config[1] = 0; 638bd522ceSDave Liu 646d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.sdram_clk_cntl = CONFIG_SYS_DDR_SDRAM_CLK_CNTL; 656d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3; 666d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1; 676d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2; 686d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0; 698bd522ceSDave Liu 708bd522ceSDave Liu if (im->pmc.pmccr1 & PMCCR1_POWER_OFF) 716d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG | SDRAM_CFG_BI; 728bd522ceSDave Liu else 736d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG; 748bd522ceSDave Liu 756d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.sdram_cfg2 = CONFIG_SYS_DDR_SDRAM_CFG2; 766d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.sdram_mode = CONFIG_SYS_DDR_MODE; 776d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.sdram_mode2 = CONFIG_SYS_DDR_MODE2; 788bd522ceSDave Liu 796d0f6bcfSJean-Christophe PLAGNIOL-VILLARD im->ddr.sdram_interval = CONFIG_SYS_DDR_INTERVAL; 808bd522ceSDave Liu sync(); 818bd522ceSDave Liu 828bd522ceSDave Liu /* enable DDR controller */ 838bd522ceSDave Liu im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN; 848bd522ceSDave Liu sync(); 858bd522ceSDave Liu 868bd522ceSDave Liu return msize; 878bd522ceSDave Liu } 882e95004dSAnton Vorontsov #else 892e95004dSAnton Vorontsov static long fixed_sdram(void) 902e95004dSAnton Vorontsov { 912e95004dSAnton Vorontsov return CONFIG_SYS_DDR_SIZE * 1024 * 1024; 922e95004dSAnton Vorontsov } 932e95004dSAnton Vorontsov #endif /* CONFIG_SYS_RAMBOOT */ 948bd522ceSDave Liu 95*088454cdSSimon Glass int initdram(void) 968bd522ceSDave Liu { 976d0f6bcfSJean-Christophe PLAGNIOL-VILLARD volatile immap_t *im = (volatile immap_t *)CONFIG_SYS_IMMR; 988bd522ceSDave Liu u32 msize; 998bd522ceSDave Liu 1008bd522ceSDave Liu if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32)im) 101*088454cdSSimon Glass return -ENXIO; 1028bd522ceSDave Liu 1038bd522ceSDave Liu /* DDR SDRAM */ 1048bd522ceSDave Liu msize = fixed_sdram(); 1058bd522ceSDave Liu 1068bd522ceSDave Liu if (im->pmc.pmccr1 & PMCCR1_POWER_OFF) 1078bd522ceSDave Liu resume_from_sleep(); 1088bd522ceSDave Liu 109*088454cdSSimon Glass /* set total bus SDRAM size(bytes) -- DDR */ 110*088454cdSSimon Glass gd->ram_size = msize; 111*088454cdSSimon Glass 112*088454cdSSimon Glass return 0; 1138bd522ceSDave Liu } 114