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