blob: 9dc3ed6dfffaaf64b31d6b7101a3afa32b4fbeea [file] [log] [blame]
Lokesh Vutlaf8185032019-06-13 10:29:49 +05301// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Board specific initialization for J721E EVM
4 *
Nishanth Menona94a4072023-11-01 15:56:03 -05005 * Copyright (C) 2018-2019 Texas Instruments Incorporated - https://www.ti.com/
Lokesh Vutlaf8185032019-06-13 10:29:49 +05306 * Lokesh Vutla <lokeshvutla@ti.com>
7 *
8 */
9
Aswath Govindraju6cfabdd2021-07-21 21:28:39 +053010#include <generic-phy.h>
Simon Glass4d72caa2020-05-10 11:40:01 -060011#include <image.h>
Simon Glass90526e92020-05-10 11:39:56 -060012#include <net.h>
Andreas Dannenberg643eb6e2020-01-07 13:15:54 +053013#include <asm/arch/hardware.h>
14#include <asm/gpio.h>
Lokesh Vutlaf8185032019-06-13 10:29:49 +053015#include <spl.h>
Tero Kristofa281f62020-02-14 11:18:19 +020016#include <dm.h>
Lokesh Vutlaf8185032019-06-13 10:29:49 +053017
Andreas Dannenberg643eb6e2020-01-07 13:15:54 +053018#include "../common/board_detect.h"
Nishanth Menonc6d06582024-02-12 13:47:22 -060019#include "../common/fdt_ops.h"
Andreas Dannenberg643eb6e2020-01-07 13:15:54 +053020
21#define board_is_j721e_som() (board_ti_k3_is("J721EX-PM1-SOM") || \
22 board_ti_k3_is("J721EX-PM2-SOM"))
23
Sinthu Rajadfb24292022-02-09 15:06:50 +053024#define board_is_j721e_sk() (board_ti_k3_is("J721EX-EAIK") || \
25 board_ti_k3_is("J721EX-SK"))
26
Aswath Govindraju6cfabdd2021-07-21 21:28:39 +053027#define board_is_j7200_som() (board_ti_k3_is("J7200X-PM1-SOM") || \
28 board_ti_k3_is("J7200X-PM2-SOM"))
Lokesh Vutla2cf09d72020-08-05 22:44:25 +053029
Andreas Dannenberg643eb6e2020-01-07 13:15:54 +053030/* Max number of MAC addresses that are parsed/processed per daughter card */
31#define DAUGHTER_CARD_NO_OF_MAC_ADDR 8
32
Lokesh Vutlaf8185032019-06-13 10:29:49 +053033DECLARE_GLOBAL_DATA_PTR;
34
35int board_init(void)
36{
37 return 0;
38}
39
40int dram_init(void)
41{
42#ifdef CONFIG_PHYS_64BIT
43 gd->ram_size = 0x100000000;
44#else
45 gd->ram_size = 0x80000000;
46#endif
47
48 return 0;
49}
50
Heinrich Schuchardtd768dd82023-08-12 20:16:58 +020051phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
Lokesh Vutlaf8185032019-06-13 10:29:49 +053052{
53#ifdef CONFIG_PHYS_64BIT
54 /* Limit RAM used by U-Boot to the DDR low region */
55 if (gd->ram_top > 0x100000000)
56 return 0x100000000;
57#endif
58
59 return gd->ram_top;
60}
61
62int dram_init_banksize(void)
63{
64 /* Bank 0 declares the memory available in the DDR low region */
Andrew Davisa2132892023-11-30 08:49:11 -060065 gd->bd->bi_dram[0].start = 0x80000000;
Lokesh Vutlaf8185032019-06-13 10:29:49 +053066 gd->bd->bi_dram[0].size = 0x80000000;
67 gd->ram_size = 0x80000000;
68
69#ifdef CONFIG_PHYS_64BIT
70 /* Bank 1 declares the memory available in the DDR high region */
Andrew Davisa2132892023-11-30 08:49:11 -060071 gd->bd->bi_dram[1].start = 0x880000000;
Lokesh Vutlaf8185032019-06-13 10:29:49 +053072 gd->bd->bi_dram[1].size = 0x80000000;
73 gd->ram_size = 0x100000000;
74#endif
75
76 return 0;
77}
78
79#ifdef CONFIG_SPL_LOAD_FIT
80int board_fit_config_name_match(const char *name)
81{
Sinthu Rajad8004912022-02-09 15:06:52 +053082 bool eeprom_read = board_ti_was_eeprom_read();
83
84 if (!eeprom_read || board_is_j721e_som()) {
85 if (!strcmp(name, "k3-j721e-common-proc-board") ||
86 !strcmp(name, "k3-j721e-r5-common-proc-board"))
87 return 0;
88 } else if (board_is_j721e_sk()) {
89 if (!strcmp(name, "k3-j721e-sk") ||
90 !strcmp(name, "k3-j721e-r5-sk"))
91 return 0;
92 }
Lokesh Vutlaf8185032019-06-13 10:29:49 +053093
94 return -1;
95}
96#endif
Suman Annad146af52019-06-13 10:29:50 +053097
Vignesh Raghavendrad2bc9872020-08-07 00:26:57 +053098#if CONFIG_IS_ENABLED(DM_GPIO) && CONFIG_IS_ENABLED(OF_LIBFDT)
99/* Returns 1, if onboard mux is set to hyperflash */
100static void __maybe_unused detect_enable_hyperflash(void *blob)
101{
102 struct gpio_desc desc = {0};
Vaishnav Achath66a33f42022-05-09 11:50:16 +0530103 char *hypermux_sel_gpio = (board_is_j721e_som()) ? "8" : "6";
Vignesh Raghavendrad2bc9872020-08-07 00:26:57 +0530104
Vaishnav Achath66a33f42022-05-09 11:50:16 +0530105 if (dm_gpio_lookup_name(hypermux_sel_gpio, &desc))
Vignesh Raghavendrad2bc9872020-08-07 00:26:57 +0530106 return;
107
Vaishnav Achath66a33f42022-05-09 11:50:16 +0530108 if (dm_gpio_request(&desc, hypermux_sel_gpio))
Vignesh Raghavendrad2bc9872020-08-07 00:26:57 +0530109 return;
110
111 if (dm_gpio_set_dir_flags(&desc, GPIOD_IS_IN))
112 return;
113
114 if (dm_gpio_get_value(&desc)) {
115 int offset;
116
117 do_fixup_by_compat(blob, "ti,am654-hbmc", "status",
118 "okay", sizeof("okay"), 0);
119 offset = fdt_node_offset_by_compatible(blob, -1,
Vignesh Raghavendra5a8a7a92020-09-17 16:48:16 +0530120 "ti,am654-ospi");
Vignesh Raghavendrad2bc9872020-08-07 00:26:57 +0530121 fdt_setprop(blob, offset, "status", "disabled",
122 sizeof("disabled"));
123 }
124}
125#endif
126
Vaishnav Achath66a33f42022-05-09 11:50:16 +0530127#if defined(CONFIG_SPL_BUILD) && (defined(CONFIG_TARGET_J7200_A72_EVM) || defined(CONFIG_TARGET_J7200_R5_EVM) || \
128 defined(CONFIG_TARGET_J721E_A72_EVM) || defined(CONFIG_TARGET_J721E_R5_EVM))
Vignesh Raghavendrae85382f2020-08-13 14:56:16 +0530129void spl_perform_fixups(struct spl_image_info *spl_image)
130{
131 detect_enable_hyperflash(spl_image->fdt_addr);
132}
133#endif
134
Suman Annad146af52019-06-13 10:29:50 +0530135#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
Masahiro Yamadab75d8dc2020-06-26 15:13:33 +0900136int ft_board_setup(void *blob, struct bd_info *bd)
Suman Annad146af52019-06-13 10:29:50 +0530137{
Vignesh Raghavendrad2bc9872020-08-07 00:26:57 +0530138 detect_enable_hyperflash(blob);
139
Andrew Davis30e96a22023-04-06 11:38:10 -0500140 return 0;
Suman Annad146af52019-06-13 10:29:50 +0530141}
142#endif
Andreas Dannenberg643eb6e2020-01-07 13:15:54 +0530143
Lokesh Vutlab29a7cd2020-08-05 22:44:14 +0530144#ifdef CONFIG_TI_I2C_BOARD_DETECT
Andreas Dannenberg643eb6e2020-01-07 13:15:54 +0530145int do_board_detect(void)
146{
147 int ret;
148
Sinthu Rajad8004912022-02-09 15:06:52 +0530149 if (board_ti_was_eeprom_read())
150 return 0;
151
Andreas Dannenberg643eb6e2020-01-07 13:15:54 +0530152 ret = ti_i2c_eeprom_am6_get_base(CONFIG_EEPROM_BUS_ADDRESS,
153 CONFIG_EEPROM_CHIP_ADDRESS);
Sinthu Rajaa46c5282022-02-09 15:06:49 +0530154 if (ret) {
155 printf("EEPROM not available at 0x%02x, trying to read at 0x%02x\n",
156 CONFIG_EEPROM_CHIP_ADDRESS, CONFIG_EEPROM_CHIP_ADDRESS + 1);
157 ret = ti_i2c_eeprom_am6_get_base(CONFIG_EEPROM_BUS_ADDRESS,
158 CONFIG_EEPROM_CHIP_ADDRESS + 1);
159 if (ret)
160 pr_err("Reading on-board EEPROM at 0x%02x failed %d\n",
161 CONFIG_EEPROM_CHIP_ADDRESS + 1, ret);
162 }
Andreas Dannenberg643eb6e2020-01-07 13:15:54 +0530163
164 return ret;
165}
166
Lokesh Vutlac7068ab2020-01-07 13:15:55 +0530167int checkboard(void)
168{
169 struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
170
171 if (do_board_detect())
172 /* EEPROM not populated */
173 printf("Board: %s rev %s\n", "J721EX-PM1-SOM", "E2");
174 else
175 printf("Board: %s rev %s\n", ep->name, ep->version);
176
177 return 0;
178}
179
Andreas Dannenberg643eb6e2020-01-07 13:15:54 +0530180/*
181 * Declaration of daughtercards to probe. Note that when adding more
182 * cards they should be grouped by the 'i2c_addr' field to allow for a
183 * more efficient probing process.
184 */
185static const struct {
186 u8 i2c_addr; /* I2C address of card EEPROM */
187 char *card_name; /* EEPROM-programmed card name */
188 char *dtbo_name; /* Device tree overlay to apply */
189 u8 eth_offset; /* ethXaddr MAC address index offset */
190} ext_cards[] = {
191 {
192 0x51,
193 "J7X-BASE-CPB",
194 "", /* No dtbo for this board */
195 0,
196 },
197 {
198 0x52,
199 "J7X-INFOTAN-EXP",
200 "", /* No dtbo for this board */
201 0,
202 },
203 {
204 0x52,
205 "J7X-GESI-EXP",
206 "", /* No dtbo for this board */
207 5, /* Start populating from eth5addr */
208 },
209 {
210 0x54,
211 "J7X-VSC8514-ETH",
212 "", /* No dtbo for this board */
213 1, /* Start populating from eth1addr */
214 },
215};
216
217static bool daughter_card_detect_flags[ARRAY_SIZE(ext_cards)];
218
219const char *board_fit_get_additionnal_images(int index, const char *type)
220{
221 int i, j;
222
223 if (strcmp(type, FIT_FDT_PROP))
224 return NULL;
225
226 j = 0;
227 for (i = 0; i < ARRAY_SIZE(ext_cards); i++) {
228 if (daughter_card_detect_flags[i]) {
229 if (j == index) {
230 /*
231 * Return dtbo name only if populated,
232 * otherwise stop parsing here.
233 */
234 if (strlen(ext_cards[i].dtbo_name))
235 return ext_cards[i].dtbo_name;
236 else
237 return NULL;
238 };
239
240 j++;
241 }
242 }
243
244 return NULL;
245}
246
247static int probe_daughtercards(void)
248{
249 char mac_addr[DAUGHTER_CARD_NO_OF_MAC_ADDR][TI_EEPROM_HDR_ETH_ALEN];
250 bool eeprom_read_success;
251 struct ti_am6_eeprom ep;
252 u8 previous_i2c_addr;
253 u8 mac_addr_cnt;
254 int i;
255 int ret;
256
257 /* Mark previous I2C address variable as not populated */
258 previous_i2c_addr = 0xff;
259
260 /* No EEPROM data was read yet */
261 eeprom_read_success = false;
262
263 /* Iterate through list of daughtercards */
264 for (i = 0; i < ARRAY_SIZE(ext_cards); i++) {
265 /* Obtain card-specific I2C address */
266 u8 i2c_addr = ext_cards[i].i2c_addr;
267
268 /* Read card EEPROM if not already read previously */
269 if (i2c_addr != previous_i2c_addr) {
270 /* Store I2C address so we can avoid reading twice */
271 previous_i2c_addr = i2c_addr;
272
273 /* Get and parse the daughter card EEPROM record */
274 ret = ti_i2c_eeprom_am6_get(CONFIG_EEPROM_BUS_ADDRESS,
275 i2c_addr,
276 &ep,
277 (char **)mac_addr,
278 DAUGHTER_CARD_NO_OF_MAC_ADDR,
279 &mac_addr_cnt);
280 if (ret) {
281 debug("%s: No daughtercard EEPROM at 0x%02x found %d\n",
282 __func__, i2c_addr, ret);
283 eeprom_read_success = false;
284 /* Skip to the next daughtercard to probe */
285 continue;
286 }
287
288 /* EEPROM read successful, okay to further process. */
289 eeprom_read_success = true;
290 }
291
292 /* Only continue processing if EEPROM data was read */
293 if (!eeprom_read_success)
294 continue;
295
296 /* Only process the parsed data if we found a match */
297 if (strncmp(ep.name, ext_cards[i].card_name, sizeof(ep.name)))
298 continue;
299
300 printf("Detected: %s rev %s\n", ep.name, ep.version);
301 daughter_card_detect_flags[i] = true;
302
Nishanth Menon21a704a2023-11-04 02:21:41 -0500303 if (!IS_ENABLED(CONFIG_SPL_BUILD)) {
304 int j;
305 /*
306 * Populate any MAC addresses from daughtercard into the U-Boot
307 * environment, starting with a card-specific offset so we can
308 * have multiple ext_cards contribute to the MAC pool in a well-
309 * defined manner.
310 */
311 for (j = 0; j < mac_addr_cnt; j++) {
312 if (!is_valid_ethaddr((u8 *)mac_addr[j]))
313 continue;
314
315 eth_env_set_enetaddr_by_index("eth",
316 ext_cards[i].eth_offset + j,
317 (uchar *)mac_addr[j]);
318 }
319 }
320 }
321
322 if (!IS_ENABLED(CONFIG_SPL_BUILD)) {
323 char name_overlays[1024] = { 0 };
324
325 for (i = 0; i < ARRAY_SIZE(ext_cards); i++) {
326 if (!daughter_card_detect_flags[i])
Andreas Dannenberg643eb6e2020-01-07 13:15:54 +0530327 continue;
328
Nishanth Menon21a704a2023-11-04 02:21:41 -0500329 /* Skip if no overlays are to be added */
330 if (!strlen(ext_cards[i].dtbo_name))
331 continue;
332
333 /*
334 * Make sure we are not running out of buffer space by checking
335 * if we can fit the new overlay, a trailing space to be used
336 * as a separator, plus the terminating zero.
337 */
338 if (strlen(name_overlays) + strlen(ext_cards[i].dtbo_name) + 2 >
339 sizeof(name_overlays))
340 return -ENOMEM;
341
342 /* Append to our list of overlays */
343 strcat(name_overlays, ext_cards[i].dtbo_name);
344 strcat(name_overlays, " ");
Andreas Dannenberg643eb6e2020-01-07 13:15:54 +0530345 }
Nishanth Menon21a704a2023-11-04 02:21:41 -0500346
347 /* Apply device tree overlay(s) to the U-Boot environment, if any */
348 if (strlen(name_overlays))
349 return env_set("name_overlays", name_overlays);
Andreas Dannenberg643eb6e2020-01-07 13:15:54 +0530350 }
Andreas Dannenberg643eb6e2020-01-07 13:15:54 +0530351
352 return 0;
353}
Lokesh Vutlab29a7cd2020-08-05 22:44:14 +0530354#endif
Andreas Dannenberg643eb6e2020-01-07 13:15:54 +0530355
Sinthu Rajad948fc42022-02-09 15:06:48 +0530356#ifdef CONFIG_BOARD_LATE_INIT
Nishanth Menonc6d06582024-02-12 13:47:22 -0600357static struct ti_fdt_map ti_j721e_evm_fdt_map[] = {
358 {"j721e", "k3-j721e-common-proc-board.dtb"},
359 {"j721e-sk", "k3-j721e-sk.dtb"},
360 {"j7200", "k3-j7200-common-proc-board.dtb"},
361 { /* Sentinel. */ }
362};
Sinthu Rajad948fc42022-02-09 15:06:48 +0530363static void setup_board_eeprom_env(void)
364{
365 char *name = "j721e";
366
367 if (do_board_detect())
368 goto invalid_eeprom;
369
370 if (board_is_j721e_som())
371 name = "j721e";
Sinthu Rajadfb24292022-02-09 15:06:50 +0530372 else if (board_is_j721e_sk())
373 name = "j721e-sk";
Sinthu Rajad948fc42022-02-09 15:06:48 +0530374 else if (board_is_j7200_som())
375 name = "j7200";
376 else
377 printf("Unidentified board claims %s in eeprom header\n",
378 board_ti_get_name());
379
380invalid_eeprom:
381 set_board_info_env_am6(name);
Nishanth Menonc6d06582024-02-12 13:47:22 -0600382 ti_set_fdt_env(name, ti_j721e_evm_fdt_map);
Sinthu Rajad948fc42022-02-09 15:06:48 +0530383}
384
385static void setup_serial(void)
386{
387 struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
388 unsigned long board_serial;
389 char *endp;
390 char serial_string[17] = { 0 };
391
392 if (env_get("serial#"))
393 return;
394
395 board_serial = hextoul(ep->serial, &endp);
396 if (*endp != '\0') {
397 pr_err("Error: Can't set serial# to %s\n", ep->serial);
398 return;
399 }
400
401 snprintf(serial_string, sizeof(serial_string), "%016lx", board_serial);
402 env_set("serial#", serial_string);
403}
404
Andreas Dannenberg643eb6e2020-01-07 13:15:54 +0530405int board_late_init(void)
406{
Lokesh Vutlab29a7cd2020-08-05 22:44:14 +0530407 if (IS_ENABLED(CONFIG_TI_I2C_BOARD_DETECT)) {
408 setup_board_eeprom_env();
409 setup_serial();
Andreas Dannenberg643eb6e2020-01-07 13:15:54 +0530410
Lokesh Vutlab29a7cd2020-08-05 22:44:14 +0530411 /* Check for and probe any plugged-in daughtercards */
Sinthu Rajaee59fa42022-02-09 15:06:51 +0530412 if (board_is_j721e_som() || board_is_j7200_som())
413 probe_daughtercards();
Lokesh Vutlab29a7cd2020-08-05 22:44:14 +0530414 }
Andreas Dannenberg643eb6e2020-01-07 13:15:54 +0530415
416 return 0;
417}
Sinthu Rajad948fc42022-02-09 15:06:48 +0530418#endif
Andreas Dannenberg643eb6e2020-01-07 13:15:54 +0530419
Vaishnav Achath66a33f42022-05-09 11:50:16 +0530420static int __maybe_unused detect_SW3_1_state(void)
421{
422 if (IS_ENABLED(CONFIG_TARGET_J7200_A72_EVM) || IS_ENABLED(CONFIG_TARGET_J721E_A72_EVM)) {
423 struct gpio_desc desc = {0};
424 int ret;
425 char *hypermux_sel_gpio = (board_is_j721e_som()) ? "8" : "6";
426
427 ret = dm_gpio_lookup_name(hypermux_sel_gpio, &desc);
428 if (ret) {
429 printf("error getting GPIO lookup name: %d\n", ret);
430 return ret;
431 }
432
433 ret = dm_gpio_request(&desc, hypermux_sel_gpio);
434 if (ret) {
435 printf("error requesting GPIO: %d\n", ret);
436 goto err_free_gpio;
437 }
438
439 ret = dm_gpio_set_dir_flags(&desc, GPIOD_IS_IN);
440 if (ret) {
441 printf("error setting direction flag of GPIO: %d\n", ret);
442 goto err_free_gpio;
443 }
444
445 ret = dm_gpio_get_value(&desc);
446 if (ret < 0)
447 printf("error getting value of GPIO: %d\n", ret);
448
449err_free_gpio:
450 dm_gpio_free(desc.dev, &desc);
451 return ret;
452 }
453}
454
Andreas Dannenberg643eb6e2020-01-07 13:15:54 +0530455void spl_board_init(void)
456{
Tero Kristofa281f62020-02-14 11:18:19 +0200457 struct udevice *dev;
458 int ret;
Tero Kristofa281f62020-02-14 11:18:19 +0200459
Lokesh Vutlacf1d6862020-08-05 22:44:24 +0530460 if ((IS_ENABLED(CONFIG_TARGET_J721E_A72_EVM) ||
461 IS_ENABLED(CONFIG_TARGET_J7200_A72_EVM)) &&
Sinthu Rajaee59fa42022-02-09 15:06:51 +0530462 IS_ENABLED(CONFIG_TI_I2C_BOARD_DETECT)) {
463 if (!board_is_j721e_sk())
464 probe_daughtercards();
465 }
Tero Kristofa281f62020-02-14 11:18:19 +0200466
Nishanth Menond672e152023-11-04 02:21:40 -0500467 if (IS_ENABLED(CONFIG_ESM_K3)) {
Tero Kristofa281f62020-02-14 11:18:19 +0200468 ret = uclass_get_device_by_driver(UCLASS_MISC,
Simon Glass65e25be2020-12-28 20:34:56 -0700469 DM_DRIVER_GET(k3_esm), &dev);
Tero Kristofa281f62020-02-14 11:18:19 +0200470 if (ret)
471 printf("ESM init failed: %d\n", ret);
472 }
Tero Kristofa281f62020-02-14 11:18:19 +0200473
Nishanth Menond672e152023-11-04 02:21:40 -0500474 if (IS_ENABLED(CONFIG_ESM_PMIC)) {
Tero Kristofa281f62020-02-14 11:18:19 +0200475 ret = uclass_get_device_by_driver(UCLASS_MISC,
Simon Glass65e25be2020-12-28 20:34:56 -0700476 DM_DRIVER_GET(pmic_esm),
Tero Kristofa281f62020-02-14 11:18:19 +0200477 &dev);
478 if (ret)
479 printf("ESM PMIC init failed: %d\n", ret);
480 }
Vaishnav Achath66a33f42022-05-09 11:50:16 +0530481 if ((IS_ENABLED(CONFIG_TARGET_J7200_A72_EVM) || IS_ENABLED(CONFIG_TARGET_J721E_A72_EVM)) &&
482 IS_ENABLED(CONFIG_HBMC_AM654)) {
483 struct udevice *dev;
484 int ret;
485
486 ret = detect_SW3_1_state();
487 if (ret == 1) {
488 ret = uclass_get_device_by_driver(UCLASS_MTD,
489 DM_DRIVER_GET(hbmc_am654),
490 &dev);
491 if (ret)
492 debug("Failed to probe hyperflash\n");
493 }
494 }
Andreas Dannenberg643eb6e2020-01-07 13:15:54 +0530495}