blob: 4ece82c73039211889a92ba663683c386884d024 [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
Tom Riniabb9a042024-05-18 20:20:43 -06006#include <common.h>
Marek Vasut78943112022-12-11 21:17:14 +01007#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>
Marek Vasut78943112022-12-11 21:17:14 +010015#include <dm/uclass.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
28DECLARE_GLOBAL_DATA_PTR;
29
30#define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_ODE | PAD_CTL_PUE | PAD_CTL_PE)
31
Marek Vasutb7ad7702023-12-07 18:50:32 +010032#define DDRC_ECCCFG0_ECC_MODE_MASK 0x7
33
Marek Vasut78943112022-12-11 21:17:14 +010034u8 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 for (i = 0; i < ret; i++)
52 memcfg |= !!dm_gpio_get_value(&(gpio[i])) << i;
53
54 gpio_free_list_nodev(gpio, ret);
55
56 return memcfg;
57}
58
59int board_phys_sdram_size(phys_size_t *size)
60{
61 u8 memcfg = dmo_get_memcfg();
Marek Vasutb7ad7702023-12-07 18:50:32 +010062 u8 ecc = 0;
63
64 *size = 4ULL >> ((memcfg >> 1) & 0x3);
65
66 if (IS_ENABLED(CONFIG_IMX8M_DRAM_INLINE_ECC)) {
67 /* 896 MiB, i.e. 1 GiB without 12.5% reserved for in-band ECC */
68 ecc = readl(DDRC_ECCCFG0(0)) & DDRC_ECCCFG0_ECC_MODE_MASK;
69 }
Marek Vasut78943112022-12-11 21:17:14 +010070
Marek Vasutb7ad7702023-12-07 18:50:32 +010071 *size *= SZ_1G - (ecc ? (SZ_1G / 8) : 0);
Marek Vasut78943112022-12-11 21:17:14 +010072
73 return 0;
74}
75
76#ifdef CONFIG_SPL_BUILD
77static void data_modul_imx_edm_sbc_early_init_f(const iomux_v3_cfg_t wdog_pad)
78{
79 struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR;
80
81 imx_iomux_v3_setup_pad(wdog_pad | MUX_PAD_CTRL(WDOG_PAD_CTRL));
82
83 set_wdog_reset(wdog);
84}
85
86__weak int data_modul_imx_edm_sbc_board_power_init(void)
87{
88 return 0;
89}
90
91static void spl_dram_init(struct dram_timing_info *dram_timing_info[8])
92{
93 u8 memcfg = dmo_get_memcfg();
94 int i;
95
96 printf("DDR: %d GiB x%d [0x%x]\n",
97 /* 0..4 GiB, 1..2 GiB, 0..1 GiB */
98 4 >> ((memcfg >> 1) & 0x3),
99 /* 0..x32, 1..x16 */
100 32 >> (memcfg & BIT(0)),
101 memcfg);
102
103 if (!dram_timing_info[memcfg]) {
104 printf("Unsupported DRAM strapping, trying lowest supported. MEMCFG=0x%x\n",
105 memcfg);
106 for (i = 7; i >= 0; i--)
107 if (dram_timing_info[i]) /* Configuration found */
108 break;
109 }
110
111 ddr_init(dram_timing_info[memcfg]);
Marek Vasutb7ad7702023-12-07 18:50:32 +0100112
113 if (IS_ENABLED(CONFIG_IMX8M_DRAM_INLINE_ECC)) {
114 printf("DDR: Inline ECC %sabled\n",
115 (readl(DDRC_ECCCFG0(0)) & DDRC_ECCCFG0_ECC_MODE_MASK) ?
116 "en" : "dis");
117 }
Marek Vasut78943112022-12-11 21:17:14 +0100118}
119
120void dmo_board_init_f(const iomux_v3_cfg_t wdog_pad,
121 struct dram_timing_info *dram_timing_info[8])
122{
123 struct udevice *dev;
124 int ret;
125
126 icache_enable();
127
128 arch_cpu_init();
129
130 init_uart_clk(2);
131
132 data_modul_imx_edm_sbc_early_init_f(wdog_pad);
133
134 /* Clear the BSS. */
135 memset(__bss_start, 0, __bss_end - __bss_start);
136
137 ret = spl_early_init();
138 if (ret) {
139 debug("spl_early_init() failed: %d\n", ret);
140 hang();
141 }
142
143 preloader_console_init();
144
145 ret = uclass_get_device_by_name(UCLASS_CLK,
146 "clock-controller@30380000",
147 &dev);
148 if (ret < 0) {
149 printf("Failed to find clock node. Check device tree\n");
150 hang();
151 }
152
153 enable_tzc380();
154
155 data_modul_imx_edm_sbc_board_power_init();
156
157 /* DDR initialization */
158 spl_dram_init(dram_timing_info);
159
160 board_init_r(NULL, 0);
161}
162#else
163void dmo_setup_boot_device(void)
164{
165 int boot_device = get_boot_device();
166 char *devnum;
167
168 devnum = env_get("devnum");
169 if (devnum) /* devnum is already set */
170 return;
171
172 if (boot_device == MMC3_BOOT) /* eMMC */
173 env_set_ulong("devnum", 0);
174 else
175 env_set_ulong("devnum", 1);
176}
177
178void dmo_setup_mac_address(void)
179{
180 unsigned char enetaddr[6];
181 struct udevice *dev;
182 int off, ret;
183
184 ret = eth_env_get_enetaddr("ethaddr", enetaddr);
185 if (ret) /* ethaddr is already set */
186 return;
187
188 off = fdt_path_offset(gd->fdt_blob, "eeprom0");
189 if (off < 0) {
190 printf("%s: No eeprom0 path offset\n", __func__);
191 return;
192 }
193
194 ret = uclass_get_device_by_of_offset(UCLASS_I2C_EEPROM, off, &dev);
195 if (ret) {
196 printf("Cannot find EEPROM!\n");
197 return;
198 }
199
200 ret = i2c_eeprom_read(dev, 0xb0, enetaddr, 0x6);
201 if (ret) {
202 printf("Error reading configuration EEPROM!\n");
203 return;
204 }
205
206 if (is_valid_ethaddr(enetaddr))
207 eth_env_set_enetaddr("ethaddr", enetaddr);
208}
209#endif