11558Srgrimes// SPDX-License-Identifier: GPL-2.0+
254263Sshin/*
31558Srgrimes * Board specific initialization for J721E EVM
41558Srgrimes *
517046Sjulian * Copyright (C) 2018-2019 Texas Instruments Incorporated - https://www.ti.com/
61558Srgrimes *	Lokesh Vutla <lokeshvutla@ti.com>
71558Srgrimes *
81558Srgrimes */
9150679Stobez
101558Srgrimes#include <generic-phy.h>
111558Srgrimes#include <image.h>
121558Srgrimes#include <net.h>
13243185Shrs#include <asm/arch/hardware.h>
141558Srgrimes#include <asm/gpio.h>
151558Srgrimes#include <spl.h>
161558Srgrimes#include <dm.h>
171558Srgrimes
181558Srgrimes#include "../common/board_detect.h"
191558Srgrimes#include "../common/fdt_ops.h"
201558Srgrimes
211558Srgrimes#define board_is_j721e_som()	(board_ti_k3_is("J721EX-PM1-SOM") || \
221558Srgrimes				 board_ti_k3_is("J721EX-PM2-SOM"))
231558Srgrimes
241558Srgrimes#define board_is_j721e_sk()	(board_ti_k3_is("J721EX-EAIK") || \
2554263Sshin				 board_ti_k3_is("J721EX-SK"))
261558Srgrimes
271558Srgrimes#define board_is_j7200_som()	(board_ti_k3_is("J7200X-PM1-SOM") || \
2817591Sjulian				 board_ti_k3_is("J7200X-PM2-SOM"))
291558Srgrimes
301558Srgrimes/* Max number of MAC addresses that are parsed/processed per daughter card */
311558Srgrimes#define DAUGHTER_CARD_NO_OF_MAC_ADDR	8
321558Srgrimes
331558SrgrimesDECLARE_GLOBAL_DATA_PTR;
341558Srgrimes
351558Srgrimesint board_init(void)
361558Srgrimes{
37191080Skmacy	return 0;
381558Srgrimes}
3954263Sshin
401558Srgrimesint dram_init(void)
411558Srgrimes{
4278140Sru#ifdef CONFIG_PHYS_64BIT
431558Srgrimes	gd->ram_size = 0x100000000;
441558Srgrimes#else
451558Srgrimes	gd->ram_size = 0x80000000;
461558Srgrimes#endif
471558Srgrimes
481558Srgrimes	return 0;
49191080Skmacy}
501558Srgrimes
511558Srgrimesphys_addr_t board_get_usable_ram_top(phys_size_t total_size)
52191080Skmacy{
53191080Skmacy#ifdef CONFIG_PHYS_64BIT
541558Srgrimes	/* Limit RAM used by U-Boot to the DDR low region */
551558Srgrimes	if (gd->ram_top > 0x100000000)
561558Srgrimes		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 */
65	gd->bd->bi_dram[0].start = 0x80000000;
66	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 */
71	gd->bd->bi_dram[1].start = 0x880000000;
72	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{
82	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	}
93
94	return -1;
95}
96#endif
97
98#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};
103	char *hypermux_sel_gpio = (board_is_j721e_som()) ? "8" : "6";
104
105	if (dm_gpio_lookup_name(hypermux_sel_gpio, &desc))
106		return;
107
108	if (dm_gpio_request(&desc, hypermux_sel_gpio))
109		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,
120						       "ti,am654-ospi");
121		fdt_setprop(blob, offset, "status", "disabled",
122			    sizeof("disabled"));
123	}
124}
125#endif
126
127#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))
129void spl_perform_fixups(struct spl_image_info *spl_image)
130{
131	detect_enable_hyperflash(spl_image->fdt_addr);
132}
133#endif
134
135#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
136int ft_board_setup(void *blob, struct bd_info *bd)
137{
138	detect_enable_hyperflash(blob);
139
140	return 0;
141}
142#endif
143
144#ifdef CONFIG_TI_I2C_BOARD_DETECT
145int do_board_detect(void)
146{
147	int ret;
148
149	if (board_ti_was_eeprom_read())
150		return 0;
151
152	ret = ti_i2c_eeprom_am6_get_base(CONFIG_EEPROM_BUS_ADDRESS,
153					 CONFIG_EEPROM_CHIP_ADDRESS);
154	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	}
163
164	return ret;
165}
166
167int 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
180/*
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
303		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])
327				continue;
328
329			/* 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, " ");
345		}
346
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);
350	}
351
352	return 0;
353}
354#endif
355
356#ifdef CONFIG_BOARD_LATE_INIT
357static 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};
363static 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";
372	else if (board_is_j721e_sk())
373		name = "j721e-sk";
374	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);
382	ti_set_fdt_env(name, ti_j721e_evm_fdt_map);
383}
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
405int board_late_init(void)
406{
407	if (IS_ENABLED(CONFIG_TI_I2C_BOARD_DETECT)) {
408		setup_board_eeprom_env();
409		setup_serial();
410
411		/* Check for and probe any plugged-in daughtercards */
412		if (board_is_j721e_som() || board_is_j7200_som())
413			probe_daughtercards();
414	}
415
416	return 0;
417}
418#endif
419
420static 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
455void spl_board_init(void)
456{
457	struct udevice *dev;
458	int ret;
459
460	if ((IS_ENABLED(CONFIG_TARGET_J721E_A72_EVM) ||
461	     IS_ENABLED(CONFIG_TARGET_J7200_A72_EVM)) &&
462	    IS_ENABLED(CONFIG_TI_I2C_BOARD_DETECT)) {
463		if (!board_is_j721e_sk())
464			probe_daughtercards();
465	}
466
467	if (IS_ENABLED(CONFIG_ESM_K3)) {
468		ret = uclass_get_device_by_name(UCLASS_MISC, "esm@700000", &dev);
469		if (ret)
470			printf("MISC init for esm@700000 failed: %d\n", ret);
471
472		ret = uclass_get_device_by_name(UCLASS_MISC, "esm@40800000", &dev);
473		if (ret)
474			printf("MISC init for esm@40800000 failed: %d\n", ret);
475	}
476
477	if (IS_ENABLED(CONFIG_ESM_PMIC)) {
478		ret = uclass_get_device_by_driver(UCLASS_MISC,
479						  DM_DRIVER_GET(pmic_esm),
480						  &dev);
481		if (ret)
482			printf("ESM PMIC init failed: %d\n", ret);
483	}
484	if ((IS_ENABLED(CONFIG_TARGET_J7200_A72_EVM) || IS_ENABLED(CONFIG_TARGET_J721E_A72_EVM)) &&
485	    IS_ENABLED(CONFIG_HBMC_AM654)) {
486		struct udevice *dev;
487		int ret;
488
489		ret = detect_SW3_1_state();
490		if (ret == 1) {
491			ret = uclass_get_device_by_driver(UCLASS_MTD,
492							  DM_DRIVER_GET(hbmc_am654),
493							  &dev);
494			if (ret)
495				debug("Failed to probe hyperflash\n");
496		}
497	}
498}
499