10fa934d2SPrabhakar Kushwaha /* 20fa934d2SPrabhakar Kushwaha * Copyright 2011 Freescale Semiconductor, Inc. 30fa934d2SPrabhakar Kushwaha * 41a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 50fa934d2SPrabhakar Kushwaha */ 60fa934d2SPrabhakar Kushwaha #include <common.h> 70fa934d2SPrabhakar Kushwaha #include <mpc85xx.h> 80fa934d2SPrabhakar Kushwaha #include <asm/io.h> 90fa934d2SPrabhakar Kushwaha #include <ns16550.h> 100fa934d2SPrabhakar Kushwaha #include <nand.h> 110fa934d2SPrabhakar Kushwaha #include <asm/mmu.h> 120fa934d2SPrabhakar Kushwaha #include <asm/immap_85xx.h> 13*5614e71bSYork Sun #include <fsl_ddr_sdram.h> 140fa934d2SPrabhakar Kushwaha #include <asm/fsl_law.h> 150fa934d2SPrabhakar Kushwaha #include <asm/global_data.h> 160fa934d2SPrabhakar Kushwaha 170fa934d2SPrabhakar Kushwaha DECLARE_GLOBAL_DATA_PTR; 180fa934d2SPrabhakar Kushwaha 190fa934d2SPrabhakar Kushwaha 200fa934d2SPrabhakar Kushwaha void sdram_init(void) 210fa934d2SPrabhakar Kushwaha { 22*5614e71bSYork Sun ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_FSL_DDR_ADDR; 230fa934d2SPrabhakar Kushwaha ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; 240fa934d2SPrabhakar Kushwaha u32 ddr_ratio; 250fa934d2SPrabhakar Kushwaha unsigned long ddr_freq_mhz; 260fa934d2SPrabhakar Kushwaha 270fa934d2SPrabhakar Kushwaha ddr_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_DDR_RATIO; 280fa934d2SPrabhakar Kushwaha ddr_ratio = ddr_ratio >> MPC85xx_PORPLLSR_DDR_RATIO_SHIFT; 29e1a2a340SShengzhou Liu ddr_freq_mhz = (CONFIG_SYS_CLK_FREQ * ddr_ratio) / 1000000; 300fa934d2SPrabhakar Kushwaha 310fa934d2SPrabhakar Kushwaha /* mask off E bit */ 320fa934d2SPrabhakar Kushwaha u32 svr = SVR_SOC_VER(mfspr(SPRN_SVR)); 330fa934d2SPrabhakar Kushwaha 340fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_CONTROL | SDRAM_CFG_32_BE, &ddr->sdram_cfg); 350fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_CS0_BNDS, &ddr->cs0_bnds); 360fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_CS0_CONFIG, &ddr->cs0_config); 370fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_CONTROL_2, &ddr->sdram_cfg_2); 380fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_DATA_INIT, &ddr->sdram_data_init); 390fa934d2SPrabhakar Kushwaha 400fa934d2SPrabhakar Kushwaha if (ddr_freq_mhz < 700) { 410fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_TIMING_3_667, &ddr->timing_cfg_3); 420fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_TIMING_0_667, &ddr->timing_cfg_0); 430fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_TIMING_1_667, &ddr->timing_cfg_1); 440fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_TIMING_2_667, &ddr->timing_cfg_2); 450fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_MODE_1_667, &ddr->sdram_mode); 460fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_MODE_2_667, &ddr->sdram_mode_2); 470fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_INTERVAL_667, &ddr->sdram_interval); 480fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_CLK_CTRL_667, &ddr->sdram_clk_cntl); 490fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_WRLVL_CONTROL_667, &ddr->ddr_wrlvl_cntl); 500fa934d2SPrabhakar Kushwaha } else { 510fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_TIMING_3_800, &ddr->timing_cfg_3); 520fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_TIMING_0_800, &ddr->timing_cfg_0); 530fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_TIMING_1_800, &ddr->timing_cfg_1); 540fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_TIMING_2_800, &ddr->timing_cfg_2); 550fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_MODE_1_800, &ddr->sdram_mode); 560fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_MODE_2_800, &ddr->sdram_mode_2); 570fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_INTERVAL_800, &ddr->sdram_interval); 580fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_CLK_CTRL_800, &ddr->sdram_clk_cntl); 590fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_WRLVL_CONTROL_800, &ddr->ddr_wrlvl_cntl); 600fa934d2SPrabhakar Kushwaha } 610fa934d2SPrabhakar Kushwaha 620fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_TIMING_4, &ddr->timing_cfg_4); 630fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_TIMING_5, &ddr->timing_cfg_5); 640fa934d2SPrabhakar Kushwaha __raw_writel(CONFIG_SYS_DDR_ZQ_CONTROL, &ddr->ddr_zq_cntl); 650fa934d2SPrabhakar Kushwaha 660fa934d2SPrabhakar Kushwaha /* P1014 and it's derivatives support max 16bit DDR width */ 670fa934d2SPrabhakar Kushwaha if (svr == SVR_P1014) { 680fa934d2SPrabhakar Kushwaha __raw_writel(ddr->sdram_cfg & ~SDRAM_CFG_DBW_MASK, &ddr->sdram_cfg); 690fa934d2SPrabhakar Kushwaha __raw_writel(ddr->sdram_cfg | SDRAM_CFG_16_BE, &ddr->sdram_cfg); 700fa934d2SPrabhakar Kushwaha /* For CS0_BNDS we divide the start and end address by 2, so we can just 710fa934d2SPrabhakar Kushwaha * shift the entire register to achieve the desired result and the mask 720fa934d2SPrabhakar Kushwaha * the value so we don't write reserved fields */ 730fa934d2SPrabhakar Kushwaha __raw_writel((CONFIG_SYS_DDR_CS0_BNDS >> 1) & 0x0fff0fff, &ddr->cs0_bnds); 740fa934d2SPrabhakar Kushwaha } 750fa934d2SPrabhakar Kushwaha 760fa934d2SPrabhakar Kushwaha asm volatile("sync;isync"); 770fa934d2SPrabhakar Kushwaha udelay(500); 780fa934d2SPrabhakar Kushwaha 790fa934d2SPrabhakar Kushwaha /* Let the controller go */ 800fa934d2SPrabhakar Kushwaha out_be32(&ddr->sdram_cfg, in_be32(&ddr->sdram_cfg) | SDRAM_CFG_MEM_EN); 810fa934d2SPrabhakar Kushwaha 820fa934d2SPrabhakar Kushwaha set_next_law(CONFIG_SYS_NAND_DDR_LAW, LAW_SIZE_1G, LAW_TRGT_IF_DDR_1); 830fa934d2SPrabhakar Kushwaha } 840fa934d2SPrabhakar Kushwaha 850fa934d2SPrabhakar Kushwaha void board_init_f(ulong bootflag) 860fa934d2SPrabhakar Kushwaha { 870fa934d2SPrabhakar Kushwaha u32 plat_ratio; 880fa934d2SPrabhakar Kushwaha ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; 890fa934d2SPrabhakar Kushwaha 900fa934d2SPrabhakar Kushwaha /* initialize selected port with appropriate baud rate */ 910fa934d2SPrabhakar Kushwaha plat_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_PLAT_RATIO; 920fa934d2SPrabhakar Kushwaha plat_ratio >>= 1; 930fa934d2SPrabhakar Kushwaha gd->bus_clk = CONFIG_SYS_CLK_FREQ * plat_ratio; 940fa934d2SPrabhakar Kushwaha 950fa934d2SPrabhakar Kushwaha NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1, 960fa934d2SPrabhakar Kushwaha gd->bus_clk / 16 / CONFIG_BAUDRATE); 970fa934d2SPrabhakar Kushwaha 980fa934d2SPrabhakar Kushwaha puts("\nNAND boot... "); 990fa934d2SPrabhakar Kushwaha 1000fa934d2SPrabhakar Kushwaha /* Initialize the DDR3 */ 1010fa934d2SPrabhakar Kushwaha sdram_init(); 1020fa934d2SPrabhakar Kushwaha 1030fa934d2SPrabhakar Kushwaha /* copy code to RAM and jump to it - this should not return */ 1040fa934d2SPrabhakar Kushwaha /* NOTE - code has to be copied out of NAND buffer before 1050fa934d2SPrabhakar Kushwaha * other blocks can be read. 1060fa934d2SPrabhakar Kushwaha */ 1070fa934d2SPrabhakar Kushwaha 1080fa934d2SPrabhakar Kushwaha relocate_code(CONFIG_SPL_RELOC_STACK, 0, CONFIG_SPL_RELOC_TEXT_BASE); 1090fa934d2SPrabhakar Kushwaha } 1100fa934d2SPrabhakar Kushwaha 1110fa934d2SPrabhakar Kushwaha void board_init_r(gd_t *gd, ulong dest_addr) 1120fa934d2SPrabhakar Kushwaha { 1130fa934d2SPrabhakar Kushwaha nand_boot(); 1140fa934d2SPrabhakar Kushwaha } 1150fa934d2SPrabhakar Kushwaha 1160fa934d2SPrabhakar Kushwaha void putc(char c) 1170fa934d2SPrabhakar Kushwaha { 1180fa934d2SPrabhakar Kushwaha if (c == '\n') 1190fa934d2SPrabhakar Kushwaha NS16550_putc((NS16550_t)CONFIG_SYS_NS16550_COM1, '\r'); 1200fa934d2SPrabhakar Kushwaha 1210fa934d2SPrabhakar Kushwaha NS16550_putc((NS16550_t)CONFIG_SYS_NS16550_COM1, c); 1220fa934d2SPrabhakar Kushwaha } 1230fa934d2SPrabhakar Kushwaha 1240fa934d2SPrabhakar Kushwaha void puts(const char *str) 1250fa934d2SPrabhakar Kushwaha { 1260fa934d2SPrabhakar Kushwaha while (*str) 1270fa934d2SPrabhakar Kushwaha putc(*str++); 1280fa934d2SPrabhakar Kushwaha } 129