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