1e595107eSHao Zhang /* 2e595107eSHao Zhang * Keystone : Board initialization 3e595107eSHao Zhang * 4e595107eSHao Zhang * (C) Copyright 2014 5e595107eSHao Zhang * Texas Instruments Incorporated, <www.ti.com> 6e595107eSHao Zhang * 7e595107eSHao Zhang * SPDX-License-Identifier: GPL-2.0+ 8e595107eSHao Zhang */ 9e595107eSHao Zhang 10e595107eSHao Zhang #include <common.h> 11b8dafa22SVitaly Andrianov #include "board.h" 125ec66b14SHao Zhang #include <spl.h> 13e595107eSHao Zhang #include <exports.h> 14e595107eSHao Zhang #include <fdt_support.h> 15e595107eSHao Zhang #include <asm/arch/ddr3.h> 16497e9e03SKhoronzhuk, Ivan #include <asm/arch/psc_defs.h> 178626cb80SLokesh Vutla #include <asm/arch/clock.h> 18e595107eSHao Zhang #include <asm/ti-common/ti-aemif.h> 190935cac6SKhoronzhuk, Ivan #include <asm/ti-common/keystone_net.h> 20e595107eSHao Zhang 21e595107eSHao Zhang DECLARE_GLOBAL_DATA_PTR; 22e595107eSHao Zhang 238f695232SLokesh Vutla #if defined(CONFIG_TI_AEMIF) 24e595107eSHao Zhang static struct aemif_config aemif_configs[] = { 25e595107eSHao Zhang { /* CS0 */ 26e595107eSHao Zhang .mode = AEMIF_MODE_NAND, 27e595107eSHao Zhang .wr_setup = 0xf, 28e595107eSHao Zhang .wr_strobe = 0x3f, 29e595107eSHao Zhang .wr_hold = 7, 30e595107eSHao Zhang .rd_setup = 0xf, 31e595107eSHao Zhang .rd_strobe = 0x3f, 32e595107eSHao Zhang .rd_hold = 7, 33e595107eSHao Zhang .turn_around = 3, 34e595107eSHao Zhang .width = AEMIF_WIDTH_8, 35e595107eSHao Zhang }, 36e595107eSHao Zhang }; 378f695232SLokesh Vutla #endif 38e595107eSHao Zhang 39e595107eSHao Zhang int dram_init(void) 40e595107eSHao Zhang { 4166c98a0cSVitaly Andrianov u32 ddr3_size; 4266c98a0cSVitaly Andrianov 4366c98a0cSVitaly Andrianov ddr3_size = ddr3_init(); 44e595107eSHao Zhang 45e595107eSHao Zhang gd->ram_size = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 46e595107eSHao Zhang CONFIG_MAX_RAM_BANK_SIZE); 478f695232SLokesh Vutla #if defined(CONFIG_TI_AEMIF) 48*e66a5da3SCooper Jr., Franklin if (!board_is_k2g_ice()) 49e595107eSHao Zhang aemif_init(ARRAY_SIZE(aemif_configs), aemif_configs); 508f695232SLokesh Vutla #endif 518f695232SLokesh Vutla 52*e66a5da3SCooper Jr., Franklin if (!board_is_k2g_ice()) { 53235dd6e8SVitaly Andrianov if (ddr3_size) 5466c98a0cSVitaly Andrianov ddr3_init_ecc(KS2_DDR3A_EMIF_CTRL_BASE, ddr3_size); 55e92a6b2eSLokesh Vutla else 56*e66a5da3SCooper Jr., Franklin ddr3_init_ecc(KS2_DDR3A_EMIF_CTRL_BASE, 57*e66a5da3SCooper Jr., Franklin gd->ram_size >> 30); 58*e66a5da3SCooper Jr., Franklin } 59e92a6b2eSLokesh Vutla 60e595107eSHao Zhang return 0; 61e595107eSHao Zhang } 62e595107eSHao Zhang 63e595107eSHao Zhang int board_init(void) 64e595107eSHao Zhang { 6559d4cd22SNishanth Menon gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; 66e595107eSHao Zhang 67e595107eSHao Zhang return 0; 68e595107eSHao Zhang } 69e595107eSHao Zhang 70e595107eSHao Zhang #ifdef CONFIG_DRIVER_TI_KEYSTONE_NET 710369008cSMugunthan V N #ifndef CONFIG_DM_ETH 72e595107eSHao Zhang int get_eth_env_param(char *env_name) 73e595107eSHao Zhang { 74e595107eSHao Zhang char *env; 75e595107eSHao Zhang int res = -1; 76e595107eSHao Zhang 77e595107eSHao Zhang env = getenv(env_name); 78e595107eSHao Zhang if (env) 79e595107eSHao Zhang res = simple_strtol(env, NULL, 0); 80e595107eSHao Zhang 81e595107eSHao Zhang return res; 82e595107eSHao Zhang } 83e595107eSHao Zhang 84e595107eSHao Zhang int board_eth_init(bd_t *bis) 85e595107eSHao Zhang { 86e595107eSHao Zhang int j; 87e595107eSHao Zhang int res; 88e595107eSHao Zhang int port_num; 89e595107eSHao Zhang char link_type_name[32]; 90e595107eSHao Zhang 9191266ccbSVitaly Andrianov if (cpu_is_k2g()) 9291266ccbSVitaly Andrianov writel(KS2_ETHERNET_RGMII, KS2_ETHERNET_CFG); 9391266ccbSVitaly Andrianov 94497e9e03SKhoronzhuk, Ivan /* By default, select PA PLL clock as PA clock source */ 9591266ccbSVitaly Andrianov #ifndef CONFIG_SOC_K2G 96497e9e03SKhoronzhuk, Ivan if (psc_enable_module(KS2_LPSC_PA)) 97497e9e03SKhoronzhuk, Ivan return -1; 9891266ccbSVitaly Andrianov #endif 99497e9e03SKhoronzhuk, Ivan if (psc_enable_module(KS2_LPSC_CPGMAC)) 100497e9e03SKhoronzhuk, Ivan return -1; 101497e9e03SKhoronzhuk, Ivan if (psc_enable_module(KS2_LPSC_CRYPTO)) 102497e9e03SKhoronzhuk, Ivan return -1; 103497e9e03SKhoronzhuk, Ivan 1048626cb80SLokesh Vutla if (cpu_is_k2e() || cpu_is_k2l()) 1058626cb80SLokesh Vutla pll_pa_clk_sel(); 1068626cb80SLokesh Vutla 107e595107eSHao Zhang port_num = get_num_eth_ports(); 108e595107eSHao Zhang 109e595107eSHao Zhang for (j = 0; j < port_num; j++) { 110e595107eSHao Zhang sprintf(link_type_name, "sgmii%d_link_type", j); 111e595107eSHao Zhang res = get_eth_env_param(link_type_name); 112e595107eSHao Zhang if (res >= 0) 113e595107eSHao Zhang eth_priv_cfg[j].sgmii_link_type = res; 114e595107eSHao Zhang 115e595107eSHao Zhang keystone2_emac_initialize(ð_priv_cfg[j]); 116e595107eSHao Zhang } 117e595107eSHao Zhang 118e595107eSHao Zhang return 0; 119e595107eSHao Zhang } 120e595107eSHao Zhang #endif 1210369008cSMugunthan V N #endif 122e595107eSHao Zhang 1235ec66b14SHao Zhang #ifdef CONFIG_SPL_BUILD 1245ec66b14SHao Zhang void spl_board_init(void) 1255ec66b14SHao Zhang { 1265ec66b14SHao Zhang spl_init_keystone_plls(); 1275ec66b14SHao Zhang preloader_console_init(); 1285ec66b14SHao Zhang } 1295ec66b14SHao Zhang 1305ec66b14SHao Zhang u32 spl_boot_device(void) 1315ec66b14SHao Zhang { 1325ec66b14SHao Zhang #if defined(CONFIG_SPL_SPI_LOAD) 1335ec66b14SHao Zhang return BOOT_DEVICE_SPI; 1345ec66b14SHao Zhang #else 1355ec66b14SHao Zhang puts("Unknown boot device\n"); 1365ec66b14SHao Zhang hang(); 1375ec66b14SHao Zhang #endif 1385ec66b14SHao Zhang } 1395ec66b14SHao Zhang #endif 1405ec66b14SHao Zhang 1417ffe3cd6SRobert P. J. Day #ifdef CONFIG_OF_BOARD_SETUP 142e895a4b0SSimon Glass int ft_board_setup(void *blob, bd_t *bd) 143e595107eSHao Zhang { 144e595107eSHao Zhang int lpae; 145e595107eSHao Zhang char *env; 146e595107eSHao Zhang char *endp; 147e595107eSHao Zhang int nbanks; 148e595107eSHao Zhang u64 size[2]; 149e595107eSHao Zhang u64 start[2]; 150e595107eSHao Zhang int nodeoffset; 151e595107eSHao Zhang u32 ddr3a_size; 152e595107eSHao Zhang int unitrd_fixup = 0; 153e595107eSHao Zhang 154e595107eSHao Zhang env = getenv("mem_lpae"); 155e595107eSHao Zhang lpae = env && simple_strtol(env, NULL, 0); 156e595107eSHao Zhang env = getenv("uinitrd_fixup"); 157e595107eSHao Zhang unitrd_fixup = env && simple_strtol(env, NULL, 0); 158e595107eSHao Zhang 159e595107eSHao Zhang ddr3a_size = 0; 160e595107eSHao Zhang if (lpae) { 1618efc2437SVitaly Andrianov ddr3a_size = ddr3_get_size(); 162e595107eSHao Zhang if ((ddr3a_size != 8) && (ddr3a_size != 4)) 163e595107eSHao Zhang ddr3a_size = 0; 164e595107eSHao Zhang } 165e595107eSHao Zhang 166e595107eSHao Zhang nbanks = 1; 167e595107eSHao Zhang start[0] = bd->bi_dram[0].start; 168e595107eSHao Zhang size[0] = bd->bi_dram[0].size; 169e595107eSHao Zhang 170e595107eSHao Zhang /* adjust memory start address for LPAE */ 171e595107eSHao Zhang if (lpae) { 172e595107eSHao Zhang start[0] -= CONFIG_SYS_SDRAM_BASE; 173e595107eSHao Zhang start[0] += CONFIG_SYS_LPAE_SDRAM_BASE; 174e595107eSHao Zhang } 175e595107eSHao Zhang 176e595107eSHao Zhang if ((size[0] == 0x80000000) && (ddr3a_size != 0)) { 177e595107eSHao Zhang size[1] = ((u64)ddr3a_size - 2) << 30; 178e595107eSHao Zhang start[1] = 0x880000000; 179e595107eSHao Zhang nbanks++; 180e595107eSHao Zhang } 181e595107eSHao Zhang 182e595107eSHao Zhang /* reserve memory at start of bank */ 18330491fc8SKhoronzhuk, Ivan env = getenv("mem_reserve_head"); 184e595107eSHao Zhang if (env) { 185e595107eSHao Zhang start[0] += ustrtoul(env, &endp, 0); 186e595107eSHao Zhang size[0] -= ustrtoul(env, &endp, 0); 187e595107eSHao Zhang } 188e595107eSHao Zhang 18930491fc8SKhoronzhuk, Ivan env = getenv("mem_reserve"); 190e595107eSHao Zhang if (env) 191e595107eSHao Zhang size[0] -= ustrtoul(env, &endp, 0); 192e595107eSHao Zhang 193e595107eSHao Zhang fdt_fixup_memory_banks(blob, start, size, nbanks); 194e595107eSHao Zhang 195e595107eSHao Zhang /* Fix up the initrd */ 196e595107eSHao Zhang if (lpae && unitrd_fixup) { 197e595107eSHao Zhang int err; 198e595107eSHao Zhang u32 *prop1, *prop2; 199e595107eSHao Zhang u64 initrd_start, initrd_end; 200e595107eSHao Zhang 201e595107eSHao Zhang nodeoffset = fdt_path_offset(blob, "/chosen"); 202e595107eSHao Zhang if (nodeoffset >= 0) { 203e595107eSHao Zhang prop1 = (u32 *)fdt_getprop(blob, nodeoffset, 204e595107eSHao Zhang "linux,initrd-start", NULL); 205e595107eSHao Zhang prop2 = (u32 *)fdt_getprop(blob, nodeoffset, 206e595107eSHao Zhang "linux,initrd-end", NULL); 207e595107eSHao Zhang if (prop1 && prop2) { 208e595107eSHao Zhang initrd_start = __be32_to_cpu(*prop1); 209e595107eSHao Zhang initrd_start -= CONFIG_SYS_SDRAM_BASE; 210e595107eSHao Zhang initrd_start += CONFIG_SYS_LPAE_SDRAM_BASE; 211e595107eSHao Zhang initrd_start = __cpu_to_be64(initrd_start); 212e595107eSHao Zhang initrd_end = __be32_to_cpu(*prop2); 213e595107eSHao Zhang initrd_end -= CONFIG_SYS_SDRAM_BASE; 214e595107eSHao Zhang initrd_end += CONFIG_SYS_LPAE_SDRAM_BASE; 215e595107eSHao Zhang initrd_end = __cpu_to_be64(initrd_end); 216e595107eSHao Zhang 217e595107eSHao Zhang err = fdt_delprop(blob, nodeoffset, 218e595107eSHao Zhang "linux,initrd-start"); 219e595107eSHao Zhang if (err < 0) 220e595107eSHao Zhang puts("error deleting initrd-start\n"); 221e595107eSHao Zhang 222e595107eSHao Zhang err = fdt_delprop(blob, nodeoffset, 223e595107eSHao Zhang "linux,initrd-end"); 224e595107eSHao Zhang if (err < 0) 225e595107eSHao Zhang puts("error deleting initrd-end\n"); 226e595107eSHao Zhang 227e595107eSHao Zhang err = fdt_setprop(blob, nodeoffset, 228e595107eSHao Zhang "linux,initrd-start", 229e595107eSHao Zhang &initrd_start, 230e595107eSHao Zhang sizeof(initrd_start)); 231e595107eSHao Zhang if (err < 0) 232e595107eSHao Zhang puts("error adding initrd-start\n"); 233e595107eSHao Zhang 234e595107eSHao Zhang err = fdt_setprop(blob, nodeoffset, 235e595107eSHao Zhang "linux,initrd-end", 236e595107eSHao Zhang &initrd_end, 237e595107eSHao Zhang sizeof(initrd_end)); 238e595107eSHao Zhang if (err < 0) 239e595107eSHao Zhang puts("error adding linux,initrd-end\n"); 240e595107eSHao Zhang } 241e595107eSHao Zhang } 242e595107eSHao Zhang } 243e895a4b0SSimon Glass 244e895a4b0SSimon Glass return 0; 245e595107eSHao Zhang } 246e595107eSHao Zhang 247e595107eSHao Zhang void ft_board_setup_ex(void *blob, bd_t *bd) 248e595107eSHao Zhang { 249e595107eSHao Zhang int lpae; 250e595107eSHao Zhang u64 size; 251e595107eSHao Zhang char *env; 252e595107eSHao Zhang u64 *reserve_start; 253e595107eSHao Zhang 254e595107eSHao Zhang env = getenv("mem_lpae"); 255e595107eSHao Zhang lpae = env && simple_strtol(env, NULL, 0); 256e595107eSHao Zhang 257e595107eSHao Zhang if (lpae) { 258e595107eSHao Zhang /* 259e595107eSHao Zhang * the initrd and other reserved memory areas are 260e595107eSHao Zhang * embedded in in the DTB itslef. fix up these addresses 261e595107eSHao Zhang * to 36 bit format 262e595107eSHao Zhang */ 263e595107eSHao Zhang reserve_start = (u64 *)((char *)blob + 264e595107eSHao Zhang fdt_off_mem_rsvmap(blob)); 265e595107eSHao Zhang while (1) { 266e595107eSHao Zhang *reserve_start = __cpu_to_be64(*reserve_start); 267e595107eSHao Zhang size = __cpu_to_be64(*(reserve_start + 1)); 268e595107eSHao Zhang if (size) { 269e595107eSHao Zhang *reserve_start -= CONFIG_SYS_SDRAM_BASE; 270e595107eSHao Zhang *reserve_start += 271e595107eSHao Zhang CONFIG_SYS_LPAE_SDRAM_BASE; 272e595107eSHao Zhang *reserve_start = 273e595107eSHao Zhang __cpu_to_be64(*reserve_start); 274e595107eSHao Zhang } else { 275e595107eSHao Zhang break; 276e595107eSHao Zhang } 277e595107eSHao Zhang reserve_start += 2; 278e595107eSHao Zhang } 279e595107eSHao Zhang } 28089f44bb0SVitaly Andrianov 28189f44bb0SVitaly Andrianov ddr3_check_ecc_int(KS2_DDR3A_EMIF_CTRL_BASE); 282e595107eSHao Zhang } 2837ffe3cd6SRobert P. J. Day #endif /* CONFIG_OF_BOARD_SETUP */ 2845f48da9aSCooper Jr., Franklin 2855f48da9aSCooper Jr., Franklin #if defined(CONFIG_DTB_RESELECT) 2865f48da9aSCooper Jr., Franklin int __weak embedded_dtb_select(void) 2875f48da9aSCooper Jr., Franklin { 2885f48da9aSCooper Jr., Franklin return 0; 2895f48da9aSCooper Jr., Franklin } 2905f48da9aSCooper Jr., Franklin #endif 291