1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2022 Marek Vasut <marex@denx.de>
4  */
5 
6 #include <asm-generic/gpio.h>
7 #include <asm-generic/sections.h>
8 #include <asm/arch/clock.h>
9 #include <asm/arch/ddr.h>
10 #include <asm/arch/sys_proto.h>
11 #include <asm/io.h>
12 #include <asm/mach-imx/boot_mode.h>
13 #include <asm/mach-imx/iomux-v3.h>
14 #include <dm/uclass.h>
15 #include <env.h>
16 #include <hang.h>
17 #include <i2c_eeprom.h>
18 #include <image.h>
19 #include <init.h>
20 #include <net.h>
21 #include <spl.h>
22 
23 #include <dm/uclass.h>
24 #include <dm/device.h>
25 #include <dm/uclass-internal.h>
26 #include <dm/device-internal.h>
27 
28 DECLARE_GLOBAL_DATA_PTR;
29 
30 #define WDOG_PAD_CTRL	(PAD_CTL_DSE6 | PAD_CTL_ODE | PAD_CTL_PUE | PAD_CTL_PE)
31 
32 #define DDRC_ECCCFG0_ECC_MODE_MASK	0x7
33 
dmo_get_memcfg(void)34 u8 dmo_get_memcfg(void)
35 {
36 	struct gpio_desc gpio[4];
37 	u8 memcfg = 0;
38 	ofnode node;
39 	int i, ret;
40 
41 	node = ofnode_path("/config");
42 	if (!ofnode_valid(node)) {
43 		printf("%s: no /config node?\n", __func__);
44 		return BIT(2) | BIT(0);
45 	}
46 
47 	ret = gpio_request_list_by_name_nodev(node,
48 					      "dmo,ram-coding-gpios",
49 					      gpio, ARRAY_SIZE(gpio),
50 					      GPIOD_IS_IN);
51 	if (ret < 0)
52 		return BIT(2) | BIT(0);
53 
54 	for (i = 0; i < ret; i++)
55 		memcfg |= !!dm_gpio_get_value(&(gpio[i])) << i;
56 
57 	gpio_free_list_nodev(gpio, ret);
58 
59 	return memcfg;
60 }
61 
board_phys_sdram_size(phys_size_t * size)62 int board_phys_sdram_size(phys_size_t *size)
63 {
64 	u8 memcfg = dmo_get_memcfg();
65 	u8 ecc = 0;
66 
67 	*size = 4ULL >> ((memcfg >> 1) & 0x3);
68 
69 	if (IS_ENABLED(CONFIG_IMX8M_DRAM_INLINE_ECC)) {
70 		/* 896 MiB, i.e. 1 GiB without 12.5% reserved for in-band ECC */
71 		ecc = readl(DDRC_ECCCFG0(0)) & DDRC_ECCCFG0_ECC_MODE_MASK;
72 	}
73 
74 	*size *= SZ_1G - (ecc ? (SZ_1G / 8) : 0);
75 
76 	return 0;
77 }
78 
79 #ifdef CONFIG_XPL_BUILD
data_modul_imx_edm_sbc_early_init_f(const iomux_v3_cfg_t wdog_pad)80 static void data_modul_imx_edm_sbc_early_init_f(const iomux_v3_cfg_t wdog_pad)
81 {
82 	struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR;
83 
84 	imx_iomux_v3_setup_pad(wdog_pad | MUX_PAD_CTRL(WDOG_PAD_CTRL));
85 
86 	set_wdog_reset(wdog);
87 }
88 
data_modul_imx_edm_sbc_board_power_init(void)89 __weak int data_modul_imx_edm_sbc_board_power_init(void)
90 {
91 	return 0;
92 }
93 
spl_dram_init(struct dram_timing_info * dram_timing_info[8])94 static void spl_dram_init(struct dram_timing_info *dram_timing_info[8])
95 {
96 	u8 memcfg = dmo_get_memcfg();
97 	int i;
98 
99 	printf("DDR:   %d GiB x%d [0x%x]\n",
100 	       /* 0..4 GiB, 1..2 GiB, 0..1 GiB */
101 	       4 >> ((memcfg >> 1) & 0x3),
102 	       /* 0..x32, 1..x16 */
103 	       32 >> (memcfg & BIT(0)),
104 	       memcfg);
105 
106 	if (!dram_timing_info[memcfg]) {
107 		printf("Unsupported DRAM strapping, trying lowest supported. MEMCFG=0x%x\n",
108 		       memcfg);
109 		for (i = 7; i >= 0; i--)
110 			if (dram_timing_info[i])	/* Configuration found */
111 				break;
112 	}
113 
114 	ddr_init(dram_timing_info[memcfg]);
115 
116 	if (IS_ENABLED(CONFIG_IMX8M_DRAM_INLINE_ECC)) {
117 		printf("DDR:   Inline ECC %sabled\n",
118 		       (readl(DDRC_ECCCFG0(0)) & DDRC_ECCCFG0_ECC_MODE_MASK) ?
119 		       "en" : "dis");
120 	}
121 }
122 
dmo_board_init_f(const iomux_v3_cfg_t wdog_pad,struct dram_timing_info * dram_timing_info[8])123 void dmo_board_init_f(const iomux_v3_cfg_t wdog_pad,
124 		      struct dram_timing_info *dram_timing_info[8])
125 {
126 	struct udevice *dev;
127 	int ret;
128 
129 	icache_enable();
130 
131 	arch_cpu_init();
132 
133 	init_uart_clk(2);
134 
135 	data_modul_imx_edm_sbc_early_init_f(wdog_pad);
136 
137 	/* Clear the BSS. */
138 	memset(__bss_start, 0, __bss_end - __bss_start);
139 
140 	ret = spl_early_init();
141 	if (ret) {
142 		debug("spl_early_init() failed: %d\n", ret);
143 		hang();
144 	}
145 
146 	preloader_console_init();
147 
148 	ret = uclass_get_device_by_name(UCLASS_CLK,
149 					"clock-controller@30380000",
150 					&dev);
151 	if (ret < 0) {
152 		printf("Failed to find clock node. Check device tree\n");
153 		hang();
154 	}
155 
156 	enable_tzc380();
157 
158 	data_modul_imx_edm_sbc_board_power_init();
159 
160 	/* DDR initialization */
161 	spl_dram_init(dram_timing_info);
162 
163 	board_init_r(NULL, 0);
164 }
165 #else
dmo_setup_boot_device(void)166 void dmo_setup_boot_device(void)
167 {
168 	int boot_device = get_boot_device();
169 	char *devnum;
170 
171 	devnum = env_get("devnum");
172 	if (devnum)	/* devnum is already set */
173 		return;
174 
175 	if (boot_device == MMC3_BOOT)	/* eMMC */
176 		env_set_ulong("devnum", 0);
177 	else
178 		env_set_ulong("devnum", 1);
179 }
180 
dmo_setup_mac_address(void)181 void dmo_setup_mac_address(void)
182 {
183 	unsigned char enetaddr[6];
184 	struct udevice *dev;
185 	int off, ret;
186 
187 	ret = eth_env_get_enetaddr("ethaddr", enetaddr);
188 	if (ret)	/* ethaddr is already set */
189 		return;
190 
191 	off = fdt_path_offset(gd->fdt_blob, "eeprom0");
192 	if (off < 0) {
193 		printf("%s: No eeprom0 path offset\n", __func__);
194 		return;
195 	}
196 
197 	ret = uclass_get_device_by_of_offset(UCLASS_I2C_EEPROM, off, &dev);
198 	if (ret) {
199 		printf("Cannot find EEPROM!\n");
200 		return;
201 	}
202 
203 	ret = i2c_eeprom_read(dev, 0xb0, enetaddr, 0x6);
204 	if (ret) {
205 		printf("Error reading configuration EEPROM!\n");
206 		return;
207 	}
208 
209 	if (is_valid_ethaddr(enetaddr))
210 		eth_env_set_enetaddr("ethaddr", enetaddr);
211 }
212 #endif
213