blob: c7be54002899aeb4768dcaf669396201c09af8b6 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -04002/*
Hao Zhang8e697a02014-07-09 23:44:46 +03003 * Keystone : Board initialization
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -04004 *
Hao Zhang8e697a02014-07-09 23:44:46 +03005 * (C) Copyright 2014
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -04006 * Texas Instruments Incorporated, <www.ti.com>
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -04007 */
8
9#include <common.h>
Vitaly Andrianov1ee31512016-03-11 08:23:04 -050010#include "board.h"
Simon Glass0af6e2d2019-08-01 09:46:52 -060011#include <env.h>
Simon Glassf11478f2019-12-28 10:45:07 -070012#include <hang.h>
Simon Glass2dc9c342020-05-10 11:40:01 -060013#include <image.h>
Simon Glass8e16b1e2019-12-28 10:45:05 -070014#include <init.h>
Hao Zhang95948202014-10-22 16:32:31 +030015#include <spl.h>
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -040016#include <exports.h>
17#include <fdt_support.h>
Khoronzhuk, Ivan50df5cc2014-07-09 19:48:40 +030018#include <asm/arch/ddr3.h>
Khoronzhuk, Ivan238de852014-09-29 22:17:24 +030019#include <asm/arch/psc_defs.h>
Lokesh Vutlada18b182015-10-08 11:31:47 +053020#include <asm/arch/clock.h>
Khoronzhuk, Ivan8062b052014-06-07 05:10:49 +030021#include <asm/ti-common/ti-aemif.h>
Khoronzhuk, Ivanf2c13ba2014-09-29 22:17:22 +030022#include <asm/ti-common/keystone_net.h>
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -040023
24DECLARE_GLOBAL_DATA_PTR;
25
Lokesh Vutla56c8f0a2016-04-13 09:50:59 +053026#if defined(CONFIG_TI_AEMIF)
Khoronzhuk, Ivan8062b052014-06-07 05:10:49 +030027static struct aemif_config aemif_configs[] = {
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -040028 { /* CS0 */
Khoronzhuk, Ivan8062b052014-06-07 05:10:49 +030029 .mode = AEMIF_MODE_NAND,
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -040030 .wr_setup = 0xf,
31 .wr_strobe = 0x3f,
32 .wr_hold = 7,
33 .rd_setup = 0xf,
34 .rd_strobe = 0x3f,
35 .rd_hold = 7,
36 .turn_around = 3,
Khoronzhuk, Ivan8062b052014-06-07 05:10:49 +030037 .width = AEMIF_WIDTH_8,
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -040038 },
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -040039};
Lokesh Vutla56c8f0a2016-04-13 09:50:59 +053040#endif
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -040041
42int dram_init(void)
43{
Vitaly Andrianova9554d62015-02-11 14:07:58 -050044 u32 ddr3_size;
45
46 ddr3_size = ddr3_init();
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -040047
48 gd->ram_size = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE,
49 CONFIG_MAX_RAM_BANK_SIZE);
Lokesh Vutla56c8f0a2016-04-13 09:50:59 +053050#if defined(CONFIG_TI_AEMIF)
Cooper Jr., Franklin6e549452017-06-16 17:25:25 -050051 if (!board_is_k2g_ice())
52 aemif_init(ARRAY_SIZE(aemif_configs), aemif_configs);
Lokesh Vutla56c8f0a2016-04-13 09:50:59 +053053#endif
54
Cooper Jr., Franklin6e549452017-06-16 17:25:25 -050055 if (!board_is_k2g_ice()) {
56 if (ddr3_size)
57 ddr3_init_ecc(KS2_DDR3A_EMIF_CTRL_BASE, ddr3_size);
58 else
59 ddr3_init_ecc(KS2_DDR3A_EMIF_CTRL_BASE,
60 gd->ram_size >> 30);
61 }
Lokesh Vutlab4b5aac2016-08-27 17:19:15 +053062
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -040063 return 0;
64}
65
Keerthy3d966e12018-11-27 17:52:41 +053066struct image_header *spl_get_load_buffer(ssize_t offset, size_t size)
67{
68 return (struct image_header *)(CONFIG_SYS_TEXT_BASE);
69}
70
Hao Zhang8e697a02014-07-09 23:44:46 +030071int board_init(void)
72{
Nishanth Menon842649d2015-07-22 18:05:43 -050073 gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
Hao Zhang8e697a02014-07-09 23:44:46 +030074 return 0;
75}
Karicheri, Muralidharan657f6b52014-04-01 15:01:13 -040076
Hao Zhang95948202014-10-22 16:32:31 +030077#ifdef CONFIG_SPL_BUILD
78void spl_board_init(void)
79{
80 spl_init_keystone_plls();
81 preloader_console_init();
82}
83
84u32 spl_boot_device(void)
85{
86#if defined(CONFIG_SPL_SPI_LOAD)
87 return BOOT_DEVICE_SPI;
88#else
89 puts("Unknown boot device\n");
90 hang();
91#endif
92}
93#endif
94
Robert P. J. Day3c757002016-05-19 15:23:12 -040095#ifdef CONFIG_OF_BOARD_SETUP
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +090096int ft_board_setup(void *blob, struct bd_info *bd)
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -040097{
Hao Zhang8e697a02014-07-09 23:44:46 +030098 int lpae;
99 char *env;
100 char *endp;
101 int nbanks;
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -0400102 u64 size[2];
Hao Zhang8e697a02014-07-09 23:44:46 +0300103 u64 start[2];
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -0400104 u32 ddr3a_size;
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -0400105
Simon Glass64b723f2017-08-03 12:22:12 -0600106 env = env_get("mem_lpae");
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -0400107 lpae = env && simple_strtol(env, NULL, 0);
108
109 ddr3a_size = 0;
110 if (lpae) {
Vitaly Andrianov539de5f2016-03-04 10:36:43 -0600111 ddr3a_size = ddr3_get_size();
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -0400112 if ((ddr3a_size != 8) && (ddr3a_size != 4))
113 ddr3a_size = 0;
114 }
115
116 nbanks = 1;
117 start[0] = bd->bi_dram[0].start;
118 size[0] = bd->bi_dram[0].size;
119
120 /* adjust memory start address for LPAE */
121 if (lpae) {
Hao Zhang8e697a02014-07-09 23:44:46 +0300122 start[0] -= CONFIG_SYS_SDRAM_BASE;
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -0400123 start[0] += CONFIG_SYS_LPAE_SDRAM_BASE;
124 }
125
126 if ((size[0] == 0x80000000) && (ddr3a_size != 0)) {
127 size[1] = ((u64)ddr3a_size - 2) << 30;
128 start[1] = 0x880000000;
129 nbanks++;
130 }
131
132 /* reserve memory at start of bank */
Simon Glass64b723f2017-08-03 12:22:12 -0600133 env = env_get("mem_reserve_head");
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -0400134 if (env) {
135 start[0] += ustrtoul(env, &endp, 0);
136 size[0] -= ustrtoul(env, &endp, 0);
137 }
138
Simon Glass64b723f2017-08-03 12:22:12 -0600139 env = env_get("mem_reserve");
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -0400140 if (env)
141 size[0] -= ustrtoul(env, &endp, 0);
142
143 fdt_fixup_memory_banks(blob, start, size, nbanks);
144
Nicholas Faustinifdc8c5c2018-10-03 12:58:49 +0200145 return 0;
146}
147
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +0900148void ft_board_setup_ex(void *blob, struct bd_info *bd)
Nicholas Faustinifdc8c5c2018-10-03 12:58:49 +0200149{
150 int lpae;
151 u64 size;
152 char *env;
153 u64 *reserve_start;
154 int unitrd_fixup = 0;
155
156 env = env_get("mem_lpae");
157 lpae = env && simple_strtol(env, NULL, 0);
158 env = env_get("uinitrd_fixup");
159 unitrd_fixup = env && simple_strtol(env, NULL, 0);
160
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -0400161 /* Fix up the initrd */
Murali Karicheri1b845322014-07-09 23:44:45 +0300162 if (lpae && unitrd_fixup) {
Nicholas Faustinifdc8c5c2018-10-03 12:58:49 +0200163 int nodeoffset;
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -0400164 int err;
Nicholas Faustinifdc8c5c2018-10-03 12:58:49 +0200165 u64 *prop1, *prop2;
Hao Zhang8e697a02014-07-09 23:44:46 +0300166 u64 initrd_start, initrd_end;
Murali Karicheri1b845322014-07-09 23:44:45 +0300167
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -0400168 nodeoffset = fdt_path_offset(blob, "/chosen");
169 if (nodeoffset >= 0) {
Nicholas Faustinifdc8c5c2018-10-03 12:58:49 +0200170 prop1 = (u64 *)fdt_getprop(blob, nodeoffset,
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -0400171 "linux,initrd-start", NULL);
Nicholas Faustinifdc8c5c2018-10-03 12:58:49 +0200172 prop2 = (u64 *)fdt_getprop(blob, nodeoffset,
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -0400173 "linux,initrd-end", NULL);
174 if (prop1 && prop2) {
Nicholas Faustinifdc8c5c2018-10-03 12:58:49 +0200175 initrd_start = __be64_to_cpu(*prop1);
Hao Zhang8e697a02014-07-09 23:44:46 +0300176 initrd_start -= CONFIG_SYS_SDRAM_BASE;
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -0400177 initrd_start += CONFIG_SYS_LPAE_SDRAM_BASE;
178 initrd_start = __cpu_to_be64(initrd_start);
Nicholas Faustinifdc8c5c2018-10-03 12:58:49 +0200179 initrd_end = __be64_to_cpu(*prop2);
Hao Zhang8e697a02014-07-09 23:44:46 +0300180 initrd_end -= CONFIG_SYS_SDRAM_BASE;
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -0400181 initrd_end += CONFIG_SYS_LPAE_SDRAM_BASE;
182 initrd_end = __cpu_to_be64(initrd_end);
183
184 err = fdt_delprop(blob, nodeoffset,
185 "linux,initrd-start");
186 if (err < 0)
187 puts("error deleting initrd-start\n");
188
189 err = fdt_delprop(blob, nodeoffset,
190 "linux,initrd-end");
191 if (err < 0)
192 puts("error deleting initrd-end\n");
193
194 err = fdt_setprop(blob, nodeoffset,
195 "linux,initrd-start",
196 &initrd_start,
197 sizeof(initrd_start));
198 if (err < 0)
199 puts("error adding initrd-start\n");
200
201 err = fdt_setprop(blob, nodeoffset,
202 "linux,initrd-end",
203 &initrd_end,
204 sizeof(initrd_end));
205 if (err < 0)
206 puts("error adding linux,initrd-end\n");
207 }
208 }
209 }
Simon Glass2aec3cc2014-10-23 18:58:47 -0600210
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -0400211 if (lpae) {
212 /*
213 * the initrd and other reserved memory areas are
214 * embedded in in the DTB itslef. fix up these addresses
215 * to 36 bit format
216 */
217 reserve_start = (u64 *)((char *)blob +
218 fdt_off_mem_rsvmap(blob));
219 while (1) {
220 *reserve_start = __cpu_to_be64(*reserve_start);
221 size = __cpu_to_be64(*(reserve_start + 1));
222 if (size) {
Hao Zhang8e697a02014-07-09 23:44:46 +0300223 *reserve_start -= CONFIG_SYS_SDRAM_BASE;
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -0400224 *reserve_start +=
225 CONFIG_SYS_LPAE_SDRAM_BASE;
226 *reserve_start =
227 __cpu_to_be64(*reserve_start);
228 } else {
229 break;
230 }
231 reserve_start += 2;
232 }
233 }
Vitaly Andrianov19173012014-10-22 17:47:58 +0300234
235 ddr3_check_ecc_int(KS2_DDR3A_EMIF_CTRL_BASE);
Vitaly Andrianov7bcf4d62014-04-04 13:16:53 -0400236}
Robert P. J. Day3c757002016-05-19 15:23:12 -0400237#endif /* CONFIG_OF_BOARD_SETUP */
Cooper Jr., Franklin74f22ca2017-06-16 17:25:15 -0500238
239#if defined(CONFIG_DTB_RESELECT)
240int __weak embedded_dtb_select(void)
241{
242 return 0;
243}
244#endif