blob: e9cdede6214014aa64c03b834d2d3b4eff42a2cb [file] [log] [blame]
Tim Harvey256dba02021-03-02 14:00:21 -08001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2021 Gateworks Corporation
4 */
5
Tim Harvey256dba02021-03-02 14:00:21 -08006#include <cpu_func.h>
7#include <hang.h>
8#include <i2c.h>
Tim Harvey256dba02021-03-02 14:00:21 -08009#include <init.h>
Tim Harvey256dba02021-03-02 14:00:21 -080010#include <spl.h>
Tim Harvey256dba02021-03-02 14:00:21 -080011#include <asm/mach-imx/gpio.h>
Tim Harvey256dba02021-03-02 14:00:21 -080012#include <asm/arch/clock.h>
13#include <asm/arch/imx8mm_pins.h>
Tim Harvey1a50e742022-02-11 10:48:56 -080014#include <asm/arch/imx8mn_pins.h>
Tim Harvey0f5717f2022-04-13 11:31:09 -070015#include <asm/arch/imx8mp_pins.h>
Tim Harvey256dba02021-03-02 14:00:21 -080016#include <asm/arch/sys_proto.h>
17#include <asm/mach-imx/boot_mode.h>
Tim Harvey2ccf28d2022-11-11 08:03:07 -080018#include <asm/mach-imx/mxc_i2c.h>
Tim Harvey256dba02021-03-02 14:00:21 -080019#include <asm/arch/ddr.h>
20#include <asm-generic/gpio.h>
Shiji Yangbb112342023-08-03 09:47:16 +080021#include <asm/sections.h>
Tim Harvey256dba02021-03-02 14:00:21 -080022#include <dm/uclass.h>
23#include <dm/device.h>
Tim Harvey2ccf28d2022-11-11 08:03:07 -080024#include <dm/pinctrl.h>
Tim Harveyd4daeaa2022-04-13 08:56:40 -070025#include <linux/delay.h>
Tim Harvey1b7fbf62021-06-30 16:50:02 -070026#include <power/bd71837.h>
Tim Harvey256dba02021-03-02 14:00:21 -080027#include <power/mp5416.h>
Tim Harvey0f5717f2022-04-13 11:31:09 -070028#include <power/pca9450.h>
Tim Harvey256dba02021-03-02 14:00:21 -080029
Tim Harveyd4daeaa2022-04-13 08:56:40 -070030#include "eeprom.h"
Tim Harvey256dba02021-03-02 14:00:21 -080031#include "lpddr4_timing.h"
32
33#define PCIE_RSTN IMX_GPIO_NR(4, 6)
34
Tim Harvey256dba02021-03-02 14:00:21 -080035static void spl_dram_init(int size)
36{
37 struct dram_timing_info *dram_timing;
38
39 switch (size) {
Tim Harvey1a50e742022-02-11 10:48:56 -080040#ifdef CONFIG_IMX8MM
Tim Harvey5cc5e192022-02-18 15:19:33 -080041 case 512:
42 dram_timing = &dram_timing_512mb;
43 break;
44 case 1024:
Tim Harvey256dba02021-03-02 14:00:21 -080045 dram_timing = &dram_timing_1gb;
46 break;
Tim Harvey5cc5e192022-02-18 15:19:33 -080047 case 2048:
Tim Harvey6603b5e2021-07-27 15:19:41 -070048 dram_timing = &dram_timing_2gb;
49 break;
Tim Harvey5cc5e192022-02-18 15:19:33 -080050 case 4096:
Tim Harvey256dba02021-03-02 14:00:21 -080051 dram_timing = &dram_timing_4gb;
52 break;
53 default:
Tim Harvey5cc5e192022-02-18 15:19:33 -080054 printf("Unknown DDR configuration: %d MiB\n", size);
Tim Harvey256dba02021-03-02 14:00:21 -080055 dram_timing = &dram_timing_1gb;
Tim Harvey5cc5e192022-02-18 15:19:33 -080056 size = 1024;
Tim Harvey0f5717f2022-04-13 11:31:09 -070057#elif CONFIG_IMX8MN
Tim Harvey5cc5e192022-02-18 15:19:33 -080058 case 1024:
Tim Harvey1a50e742022-02-11 10:48:56 -080059 dram_timing = &dram_timing_1gb_single_die;
60 break;
Tim Harvey5cc5e192022-02-18 15:19:33 -080061 case 2048:
Tim Harveyd4daeaa2022-04-13 08:56:40 -070062 if (!strcmp(eeprom_get_model(), "GW7902-SP466-A") ||
63 !strcmp(eeprom_get_model(), "GW7902-SP466-B")) {
Tim Harvey1a50e742022-02-11 10:48:56 -080064 dram_timing = &dram_timing_2gb_dual_die;
65 } else {
66 dram_timing = &dram_timing_2gb_single_die;
67 }
68 break;
69 default:
Tim Harvey5cc5e192022-02-18 15:19:33 -080070 printf("Unknown DDR configuration: %d MiB\n", size);
Tim Harvey1a50e742022-02-11 10:48:56 -080071 dram_timing = &dram_timing_2gb_dual_die;
Tim Harvey5cc5e192022-02-18 15:19:33 -080072 size = 2048;
Tim Harvey0f5717f2022-04-13 11:31:09 -070073#elif CONFIG_IMX8MP
Tim Harvey08ac93c2023-06-09 09:54:51 -070074 case 1024:
75 dram_timing = &dram_timing_1gb_single_die;
76 break;
Tim Harvey0f5717f2022-04-13 11:31:09 -070077 case 4096:
78 dram_timing = &dram_timing_4gb_dual_die;
79 break;
80 default:
81 printf("Unknown DDR configuration: %d GiB\n", size);
82 dram_timing = &dram_timing_4gb_dual_die;
83 size = 4096;
Tim Harvey1a50e742022-02-11 10:48:56 -080084#endif
Tim Harvey256dba02021-03-02 14:00:21 -080085 }
86
Tim Harvey5cc5e192022-02-18 15:19:33 -080087 printf("DRAM : LPDDR4 ");
88 if (size > 512)
Tim Harvey03280f32023-06-09 09:54:01 -070089 printf("%d GiB", size / 1024);
Tim Harvey5cc5e192022-02-18 15:19:33 -080090 else
Tim Harvey03280f32023-06-09 09:54:01 -070091 printf("%d MiB", size);
92 printf(" %dMT/s %dMHz\n",
93 dram_timing->fsp_msg[0].drate,
94 dram_timing->fsp_msg[0].drate / 2);
Tim Harvey256dba02021-03-02 14:00:21 -080095 ddr_init(dram_timing);
Tim Harvey256dba02021-03-02 14:00:21 -080096}
97
Tim Harvey256dba02021-03-02 14:00:21 -080098/*
99 * Model specific PMIC adjustments necessary prior to DRAM init
100 *
101 * Note that we can not use pmic dm drivers here as we have a generic
102 * venice dt that does not have board-specific pmic's defined.
103 *
Tim Harvey1b7fbf62021-06-30 16:50:02 -0700104 * Instead we must use dm_i2c so we a helpers to give us
105 * clrsetbit functions we would otherwise have if we could use PMIC dm
106 * drivers.
Tim Harvey256dba02021-03-02 14:00:21 -0800107 */
Tim Harvey1b7fbf62021-06-30 16:50:02 -0700108static int dm_i2c_clrsetbits(struct udevice *dev, uint reg, uint clr, uint set)
109{
110 int ret;
111 u8 val;
112
113 ret = dm_i2c_read(dev, reg, &val, 1);
114 if (ret)
115 return ret;
116 val = (val & ~clr) | set;
117
118 return dm_i2c_write(dev, reg, &val, 1);
119}
120
Tim Harvey34f53c22024-06-19 14:12:58 -0700121static int power_init_board(struct udevice *gsc)
Tim Harvey256dba02021-03-02 14:00:21 -0800122{
Tim Harveyd4daeaa2022-04-13 08:56:40 -0700123 const char *model = eeprom_get_model();
Tim Harvey256dba02021-03-02 14:00:21 -0800124 struct udevice *bus;
125 struct udevice *dev;
126 int ret;
127
Tim Harvey34f53c22024-06-19 14:12:58 -0700128 /* Enable GSC voltage supervisor for new board models */
129 if ((!strncmp(model, "GW7100", 6) && model[10] > 'D') ||
130 (!strncmp(model, "GW7101", 6) && model[10] > 'D') ||
131 (!strncmp(model, "GW7200", 6) && model[10] > 'E') ||
132 (!strncmp(model, "GW7201", 6) && model[10] > 'E') ||
133 (!strncmp(model, "GW7300", 6) && model[10] > 'E') ||
134 (!strncmp(model, "GW7301", 6) && model[10] > 'E') ||
135 (!strncmp(model, "GW740", 5) && model[7] > 'B')) {
136 u8 ver;
137
138 if (!dm_i2c_read(gsc, 14, &ver, 1) && ver > 62) {
139 printf("GSC : enabling voltage supervisor\n");
140 dm_i2c_clrsetbits(gsc, 25, 0, BIT(1));
141 }
142 }
143
Tim Harvey256dba02021-03-02 14:00:21 -0800144 if ((!strncmp(model, "GW71", 4)) ||
145 (!strncmp(model, "GW72", 4)) ||
Tim Harvey08ac93c2023-06-09 09:54:51 -0700146 (!strncmp(model, "GW73", 4)) ||
147 (!strncmp(model, "GW7905", 6))) {
Tim Harveyd5419272021-07-27 15:19:38 -0700148 ret = uclass_get_device_by_seq(UCLASS_I2C, 0, &bus);
Tim Harvey256dba02021-03-02 14:00:21 -0800149 if (ret) {
150 printf("PMIC : failed I2C1 probe: %d\n", ret);
151 return ret;
152 }
153 ret = dm_i2c_probe(bus, 0x69, 0, &dev);
154 if (ret) {
155 printf("PMIC : failed probe: %d\n", ret);
156 return ret;
157 }
Tim Harvey08ac93c2023-06-09 09:54:51 -0700158#ifdef CONFIG_IMX8MM
159 puts("PMIC : MP5416 (IMX8MM)\n");
Tim Harvey256dba02021-03-02 14:00:21 -0800160
161 /* set VDD_ARM SW3 to 0.92V for 1.6GHz */
162 dm_i2c_reg_write(dev, MP5416_VSET_SW3,
163 BIT(7) | MP5416_VSET_SW3_SVAL(920000));
Tim Harvey08ac93c2023-06-09 09:54:51 -0700164#elif CONFIG_IMX8MP
165 puts("PMIC : MP5416 (IMX8MP)\n");
166
167 /* set VDD_ARM SW3 to 0.95V for 1.6GHz */
168 dm_i2c_reg_write(dev, MP5416_VSET_SW3,
169 BIT(7) | MP5416_VSET_SW3_SVAL(950000));
170 /* set VDD_SOC SW1 to 0.95V for 1.6GHz */
171 dm_i2c_reg_write(dev, MP5416_VSET_SW1,
172 BIT(7) | MP5416_VSET_SW1_SVAL(950000));
173#endif
Tim Harvey256dba02021-03-02 14:00:21 -0800174 }
175
Tim Harvey0f5717f2022-04-13 11:31:09 -0700176 else if (!strncmp(model, "GW74", 4)) {
Tim Harveyffe9e3c2023-08-15 15:01:15 -0700177 ret = uclass_get_device_by_seq(UCLASS_I2C, 2, &bus);
Tim Harvey0f5717f2022-04-13 11:31:09 -0700178 if (ret) {
Tim Harveyffe9e3c2023-08-15 15:01:15 -0700179 printf("PMIC : failed I2C3 probe: %d\n", ret);
Tim Harvey0f5717f2022-04-13 11:31:09 -0700180 return ret;
181 }
182 ret = dm_i2c_probe(bus, 0x25, 0, &dev);
183 if (ret) {
184 printf("PMIC : failed probe: %d\n", ret);
185 return ret;
186 }
187 puts("PMIC : PCA9450\n");
188
189 /* BUCKxOUT_DVS0/1 control BUCK123 output */
190 dm_i2c_reg_write(dev, PCA9450_BUCK123_DVS, 0x29);
191
192 /* Buck 1 DVS control through PMIC_STBY_REQ */
193 dm_i2c_reg_write(dev, PCA9450_BUCK1CTRL, 0x59);
194
Tim Harvey4897fc22022-09-08 14:41:09 -0700195 /* Set DVS1 to 0.85v for suspend */
196 dm_i2c_reg_write(dev, PCA9450_BUCK1OUT_DVS1, 0x14);
Tim Harvey0f5717f2022-04-13 11:31:09 -0700197
Tim Harvey4897fc22022-09-08 14:41:09 -0700198 /* increase VDD_SOC to 0.95V before first DRAM access */
199 dm_i2c_reg_write(dev, PCA9450_BUCK1OUT_DVS0, 0x1C);
Tim Harvey0f5717f2022-04-13 11:31:09 -0700200
Tim Harvey4897fc22022-09-08 14:41:09 -0700201 /* Kernel uses OD/OD freq for SOC */
202 /* To avoid timing risk from SOC to ARM, increase VDD_ARM to OD voltage 0.95v */
203 dm_i2c_reg_write(dev, PCA9450_BUCK2OUT_DVS0, 0x1C);
Tim Harvey0f5717f2022-04-13 11:31:09 -0700204 }
205
Tim Harvey6603b5e2021-07-27 15:19:41 -0700206 else if ((!strncmp(model, "GW7901", 6)) ||
Tim Harvey83ffc472022-08-11 11:57:04 -0700207 (!strncmp(model, "GW7902", 6)) ||
Tim Harveyb4531572022-09-14 09:02:19 -0700208 (!strncmp(model, "GW7903", 6)) ||
209 (!strncmp(model, "GW7904", 6))) {
Tim Harvey83ffc472022-08-11 11:57:04 -0700210 if (!strncmp(model, "GW7902", 6))
Tim Harvey6603b5e2021-07-27 15:19:41 -0700211 ret = uclass_get_device_by_seq(UCLASS_I2C, 0, &bus);
Tim Harvey83ffc472022-08-11 11:57:04 -0700212 else
213 ret = uclass_get_device_by_seq(UCLASS_I2C, 1, &bus);
Tim Harvey1b7fbf62021-06-30 16:50:02 -0700214 if (ret) {
215 printf("PMIC : failed I2C2 probe: %d\n", ret);
216 return ret;
217 }
218 ret = dm_i2c_probe(bus, 0x4b, 0, &dev);
219 if (ret) {
220 printf("PMIC : failed probe: %d\n", ret);
221 return ret;
222 }
223 puts("PMIC : BD71847\n");
224
225 /* unlock the PMIC regs */
226 dm_i2c_reg_write(dev, BD718XX_REGLOCK, 0x1);
227
228 /* set switchers to forced PWM mode */
229 dm_i2c_clrsetbits(dev, BD718XX_BUCK1_CTRL, 0, 0x8);
230 dm_i2c_clrsetbits(dev, BD718XX_BUCK2_CTRL, 0, 0x8);
231 dm_i2c_clrsetbits(dev, BD718XX_1ST_NODVS_BUCK_CTRL, 0, 0x8);
232 dm_i2c_clrsetbits(dev, BD718XX_2ND_NODVS_BUCK_CTRL, 0, 0x8);
233 dm_i2c_clrsetbits(dev, BD718XX_3RD_NODVS_BUCK_CTRL, 0, 0x8);
234 dm_i2c_clrsetbits(dev, BD718XX_4TH_NODVS_BUCK_CTRL, 0, 0x8);
235
236 /* increase VDD_0P95 (VDD_GPU/VPU/DRAM) to 0.975v for 1.5Ghz DDR */
237 dm_i2c_reg_write(dev, BD718XX_1ST_NODVS_BUCK_VOLT, 0x83);
238
239 /* increase VDD_SOC to 0.85v before first DRAM access */
240 dm_i2c_reg_write(dev, BD718XX_BUCK1_VOLT_RUN, 0x0f);
241
242 /* increase VDD_ARM to 0.92v for 800 and 1600Mhz */
243 dm_i2c_reg_write(dev, BD718XX_BUCK2_VOLT_RUN, 0x16);
244
245 /* Lock the PMIC regs */
246 dm_i2c_reg_write(dev, BD718XX_REGLOCK, 0x11);
247 }
248
Tim Harvey256dba02021-03-02 14:00:21 -0800249 return 0;
250}
251
252void board_init_f(ulong dummy)
253{
Tim Harvey2ccf28d2022-11-11 08:03:07 -0800254 struct udevice *bus, *dev;
255 int i, ret;
Tim Harvey256dba02021-03-02 14:00:21 -0800256 int dram_sz;
257
258 arch_cpu_init();
259
260 init_uart_clk(1);
261
Tim Harvey256dba02021-03-02 14:00:21 -0800262 timer_init();
263
Tim Harvey256dba02021-03-02 14:00:21 -0800264 /* Clear the BSS. */
265 memset(__bss_start, 0, __bss_end - __bss_start);
266
267 ret = spl_early_init();
268 if (ret) {
269 debug("spl_early_init() failed: %d\n", ret);
270 hang();
271 }
272
Tim Harvey91db7932022-04-29 12:36:25 -0700273 preloader_console_init();
274
Tim Harvey256dba02021-03-02 14:00:21 -0800275 enable_tzc380();
276
277 /* need to hold PCIe switch in reset otherwise it can lock i2c bus EEPROM is on */
278 gpio_request(PCIE_RSTN, "perst#");
279 gpio_direction_output(PCIE_RSTN, 0);
280
Tim Harveyd4daeaa2022-04-13 08:56:40 -0700281 /*
282 * probe GSC device
283 *
284 * On a board with a missing/depleted backup battery for GSC, the
285 * board may be ready to probe the GSC before its firmware is
Tim Harvey2ccf28d2022-11-11 08:03:07 -0800286 * running. Wait here for 50ms for the GSC firmware to let go of
287 * the SCL/SDA lines to avoid the i2c driver spamming
288 * 'Arbitration lost' I2C errors
Tim Harveyd4daeaa2022-04-13 08:56:40 -0700289 */
Tim Harvey2ccf28d2022-11-11 08:03:07 -0800290 if (!uclass_get_device_by_seq(UCLASS_I2C, 0, &bus)) {
291 if (!pinctrl_select_state(bus, "gpio")) {
292 struct mxc_i2c_bus *i2c_bus = dev_get_priv(bus);
293 struct gpio_desc *scl_gpio = &i2c_bus->scl_gpio;
294 struct gpio_desc *sda_gpio = &i2c_bus->sda_gpio;
295
296 dm_gpio_set_dir_flags(scl_gpio, GPIOD_IS_IN);
297 dm_gpio_set_dir_flags(sda_gpio, GPIOD_IS_IN);
298 for (i = 0; i < 5; i++) {
299 if (dm_gpio_get_value(scl_gpio) &&
300 dm_gpio_get_value(sda_gpio))
301 break;
302 mdelay(10);
303 }
304 pinctrl_select_state(bus, "default");
Tim Harvey211e58a2024-06-19 14:13:22 -0700305 mdelay(10);
Tim Harvey2ccf28d2022-11-11 08:03:07 -0800306 }
307 }
308 /* Wait indefiniately until the GSC probes */
Tim Harveyd4daeaa2022-04-13 08:56:40 -0700309 while (1) {
310 if (!uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(gsc), &dev))
311 break;
312 mdelay(1);
313 }
Tim Harvey1fec1822022-08-11 12:04:01 -0700314 dram_sz = venice_eeprom_init(0);
Tim Harvey256dba02021-03-02 14:00:21 -0800315
316 /* PMIC */
Tim Harvey34f53c22024-06-19 14:12:58 -0700317 power_init_board(dev);
Tim Harvey256dba02021-03-02 14:00:21 -0800318
319 /* DDR initialization */
320 spl_dram_init(dram_sz);
321
322 board_init_r(NULL, 0);
323}
324
325/* determine prioritized order of boot devices to load U-Boot from */
326void board_boot_order(u32 *spl_boot_list)
327{
Tim Harvey0f5717f2022-04-13 11:31:09 -0700328 int i = 0;
329
Tim Harvey256dba02021-03-02 14:00:21 -0800330 /*
331 * If the SPL was loaded via serial loader, we try to get
332 * U-Boot proper via USB SDP.
333 */
Tim Harvey0f5717f2022-04-13 11:31:09 -0700334 if (spl_boot_device() == BOOT_DEVICE_BOARD) {
335#ifdef CONFIG_IMX8MM
336 spl_boot_list[i++] = BOOT_DEVICE_BOARD;
337#else
338 spl_boot_list[i++] = BOOT_DEVICE_BOOTROM;
339#endif
340 }
Tim Harvey256dba02021-03-02 14:00:21 -0800341
342 /* we have only eMMC in default venice dt */
Tim Harvey0f5717f2022-04-13 11:31:09 -0700343 spl_boot_list[i++] = BOOT_DEVICE_MMC1;
Tim Harvey256dba02021-03-02 14:00:21 -0800344}
345
346/* return boot device based on where the SPL was loaded from */
347int spl_board_boot_device(enum boot_device boot_dev_spl)
348{
349 switch (boot_dev_spl) {
350 case USB_BOOT:
351 return BOOT_DEVICE_BOARD;
352 /* SDHC2 */
353 case SD2_BOOT:
354 case MMC2_BOOT:
355 return BOOT_DEVICE_MMC1;
356 /* SDHC3 */
357 case SD3_BOOT:
358 case MMC3_BOOT:
359 return BOOT_DEVICE_MMC2;
360 default:
361 return BOOT_DEVICE_NONE;
362 }
363}
Tim Harvey724d10a2022-03-08 10:45:39 -0800364
Marek Vasutf9a921e2023-10-16 18:16:12 +0200365unsigned long board_spl_mmc_get_uboot_raw_sector(struct mmc *mmc, unsigned long raw_sect)
Tim Harveya42793c2023-05-02 17:05:53 -0700366{
367 if (!IS_SD(mmc)) {
368 switch (EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config)) {
369 case 1:
370 case 2:
371 if (IS_ENABLED(CONFIG_IMX8MN) || IS_ENABLED(CONFIG_IMX8MP))
372 raw_sect -= 32 * 2;
373 break;
374 }
375 }
376
377 return raw_sect;
378}
379
Tim Harvey724d10a2022-03-08 10:45:39 -0800380const char *spl_board_loader_name(u32 boot_device)
381{
382 switch (boot_device) {
383 /* SDHC2 */
384 case BOOT_DEVICE_MMC1:
385 return "eMMC";
386 /* SDHC3 */
387 case BOOT_DEVICE_MMC2:
388 return "SD card";
389 default:
390 return NULL;
391 }
392}
Tim Harvey7ba1e9d2023-06-23 09:44:59 -0700393
394void spl_board_init(void)
395{
396 arch_misc_init();
397}