1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2019 Kontron Electronics GmbH
4 */
5
6#include <asm/arch/imx-regs.h>
7#include <asm/arch/sys_proto.h>
8#include <asm/global_data.h>
9#include <asm/io.h>
10#include <asm/mach-imx/boot_mode.h>
11#include <efi.h>
12#include <efi_loader.h>
13#include <env_internal.h>
14#include <fdt_support.h>
15#include <linux/errno.h>
16#include <linux/kernel.h>
17#include <net.h>
18
19DECLARE_GLOBAL_DATA_PTR;
20
21#if IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)
22struct efi_fw_image fw_images[] = {
23	{
24		.image_type_id = KONTRON_SL_MX8MM_FIT_IMAGE_GUID,
25		.fw_name = u"KONTROL-SL-MX8MM-UBOOT",
26		.image_index = 1,
27	},
28};
29
30struct efi_capsule_update_info update_info = {
31	.dfu_string = "sf 0:0=flash-bin raw 0x400 0x1f0000",
32	.num_images = ARRAY_SIZE(fw_images),
33	.images = fw_images,
34};
35
36#endif /* EFI_HAVE_CAPSULE_SUPPORT */
37
38int board_phys_sdram_size(phys_size_t *size)
39{
40	u32 ddr_size = readl(MCU_BOOTROM_BASE_ADDR);
41
42	if (ddr_size == 4) {
43		*size = 0x100000000;
44	} else if (ddr_size == 3) {
45		*size = 0xc0000000;
46	} else if (ddr_size == 2) {
47		*size = 0x80000000;
48	} else if (ddr_size == 1) {
49		*size = 0x40000000;
50	} else {
51		printf("Unknown DDR type!!!\n");
52		*size = 0x40000000;
53	}
54
55	return 0;
56}
57
58/*
59 * If the SoM is mounted on a baseboard with a USB ethernet controller,
60 * there might be an additional MAC address programmed to the MAC OTP fuses.
61 * Although the i.MX8MM has only one MAC, the MAC0, MAC1 and MAC2 registers
62 * in the OTP fuses can still be used to store two separate addresses.
63 * Try to read the secondary address from MAC1 and MAC2 and adjust the
64 * devicetree so Linux can pick up the MAC address.
65 */
66int fdt_set_usb_eth_addr(void *blob)
67{
68	u32 value = readl(OCOTP_BASE_ADDR + 0x660);
69	unsigned char mac[6];
70	int node, ret;
71
72	mac[0] = value >> 24;
73	mac[1] = value >> 16;
74	mac[2] = value >> 8;
75	mac[3] = value;
76
77	value = readl(OCOTP_BASE_ADDR + 0x650);
78	mac[4] = value >> 24;
79	mac[5] = value >> 16;
80
81	node = fdt_path_offset(blob, fdt_get_alias(blob, "ethernet1"));
82	if (node < 0) {
83		/*
84		 * There is no node for the USB ethernet in the devicetree. Just skip.
85		 */
86		return 0;
87	}
88
89	if (is_zero_ethaddr(mac)) {
90		printf("\nNo MAC address for USB ethernet set in OTP fuses!\n");
91		return 0;
92	}
93
94	if (!is_valid_ethaddr(mac)) {
95		printf("\nInvalid MAC address for USB ethernet set in OTP fuses!\n");
96		return -EINVAL;
97	}
98
99	ret = fdt_setprop(blob, node, "local-mac-address", &mac, 6);
100	if (ret)
101		ret = fdt_setprop(blob, node, "mac-address", &mac, 6);
102
103	if (ret)
104		printf("\nMissing mac-address or local-mac-address property in dt, skip setting MAC address for USB ethernet\n");
105
106	return 0;
107}
108
109int ft_board_setup(void *blob, struct bd_info *bd)
110{
111	int ret = fdt_set_usb_eth_addr(blob);
112
113	if (ret)
114		return ret;
115
116	return fdt_fixup_memory(blob, PHYS_SDRAM, gd->ram_size);
117}
118
119int board_init(void)
120{
121	return 0;
122}
123
124int board_late_init(void)
125{
126	if (!fdt_node_check_compatible(gd->fdt_blob, 0, "kontron,imx8mm-n802x-som") ||
127	    !fdt_node_check_compatible(gd->fdt_blob, 0, "kontron,imx8mm-osm-s")) {
128		env_set("som_type", "osm-s");
129		env_set("touch_rst_gpio", "111");
130	} else {
131		env_set("som_type", "sl");
132		env_set("touch_rst_gpio", "87");
133	}
134
135	return 0;
136}
137
138enum env_location env_get_location(enum env_operation op, int prio)
139{
140	enum boot_device boot_dev = get_boot_device();
141
142	if (prio)
143		return ENVL_UNKNOWN;
144
145	/*
146	 * Make sure that the environment is loaded from
147	 * the MMC if we are running from SD card or eMMC.
148	 */
149	if (CONFIG_IS_ENABLED(ENV_IS_IN_MMC) &&
150	    (boot_dev == SD1_BOOT || boot_dev == SD2_BOOT))
151		return ENVL_MMC;
152
153	if (CONFIG_IS_ENABLED(ENV_IS_IN_SPI_FLASH))
154		return ENVL_SPI_FLASH;
155
156	return ENVL_NOWHERE;
157}
158
159#if defined(CONFIG_ENV_IS_IN_MMC)
160int board_mmc_get_env_dev(int devno)
161{
162	return devno;
163}
164#endif
165