blob: f10d310a46d4078d688f13ec28f67099c91f7f70 [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 Harvey256dba02021-03-02 14:00:21 -0800121static int power_init_board(void)
122{
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
128 if ((!strncmp(model, "GW71", 4)) ||
129 (!strncmp(model, "GW72", 4)) ||
Tim Harvey08ac93c2023-06-09 09:54:51 -0700130 (!strncmp(model, "GW73", 4)) ||
131 (!strncmp(model, "GW7905", 6))) {
Tim Harveyd5419272021-07-27 15:19:38 -0700132 ret = uclass_get_device_by_seq(UCLASS_I2C, 0, &bus);
Tim Harvey256dba02021-03-02 14:00:21 -0800133 if (ret) {
134 printf("PMIC : failed I2C1 probe: %d\n", ret);
135 return ret;
136 }
137 ret = dm_i2c_probe(bus, 0x69, 0, &dev);
138 if (ret) {
139 printf("PMIC : failed probe: %d\n", ret);
140 return ret;
141 }
Tim Harvey08ac93c2023-06-09 09:54:51 -0700142#ifdef CONFIG_IMX8MM
143 puts("PMIC : MP5416 (IMX8MM)\n");
Tim Harvey256dba02021-03-02 14:00:21 -0800144
145 /* set VDD_ARM SW3 to 0.92V for 1.6GHz */
146 dm_i2c_reg_write(dev, MP5416_VSET_SW3,
147 BIT(7) | MP5416_VSET_SW3_SVAL(920000));
Tim Harvey08ac93c2023-06-09 09:54:51 -0700148#elif CONFIG_IMX8MP
149 puts("PMIC : MP5416 (IMX8MP)\n");
150
151 /* set VDD_ARM SW3 to 0.95V for 1.6GHz */
152 dm_i2c_reg_write(dev, MP5416_VSET_SW3,
153 BIT(7) | MP5416_VSET_SW3_SVAL(950000));
154 /* set VDD_SOC SW1 to 0.95V for 1.6GHz */
155 dm_i2c_reg_write(dev, MP5416_VSET_SW1,
156 BIT(7) | MP5416_VSET_SW1_SVAL(950000));
157#endif
Tim Harvey256dba02021-03-02 14:00:21 -0800158 }
159
Tim Harvey0f5717f2022-04-13 11:31:09 -0700160 else if (!strncmp(model, "GW74", 4)) {
Tim Harveyffe9e3c2023-08-15 15:01:15 -0700161 ret = uclass_get_device_by_seq(UCLASS_I2C, 2, &bus);
Tim Harvey0f5717f2022-04-13 11:31:09 -0700162 if (ret) {
Tim Harveyffe9e3c2023-08-15 15:01:15 -0700163 printf("PMIC : failed I2C3 probe: %d\n", ret);
Tim Harvey0f5717f2022-04-13 11:31:09 -0700164 return ret;
165 }
166 ret = dm_i2c_probe(bus, 0x25, 0, &dev);
167 if (ret) {
168 printf("PMIC : failed probe: %d\n", ret);
169 return ret;
170 }
171 puts("PMIC : PCA9450\n");
172
173 /* BUCKxOUT_DVS0/1 control BUCK123 output */
174 dm_i2c_reg_write(dev, PCA9450_BUCK123_DVS, 0x29);
175
176 /* Buck 1 DVS control through PMIC_STBY_REQ */
177 dm_i2c_reg_write(dev, PCA9450_BUCK1CTRL, 0x59);
178
Tim Harvey4897fc22022-09-08 14:41:09 -0700179 /* Set DVS1 to 0.85v for suspend */
180 dm_i2c_reg_write(dev, PCA9450_BUCK1OUT_DVS1, 0x14);
Tim Harvey0f5717f2022-04-13 11:31:09 -0700181
Tim Harvey4897fc22022-09-08 14:41:09 -0700182 /* increase VDD_SOC to 0.95V before first DRAM access */
183 dm_i2c_reg_write(dev, PCA9450_BUCK1OUT_DVS0, 0x1C);
Tim Harvey0f5717f2022-04-13 11:31:09 -0700184
Tim Harvey4897fc22022-09-08 14:41:09 -0700185 /* Kernel uses OD/OD freq for SOC */
186 /* To avoid timing risk from SOC to ARM, increase VDD_ARM to OD voltage 0.95v */
187 dm_i2c_reg_write(dev, PCA9450_BUCK2OUT_DVS0, 0x1C);
Tim Harvey0f5717f2022-04-13 11:31:09 -0700188 }
189
Tim Harvey6603b5e2021-07-27 15:19:41 -0700190 else if ((!strncmp(model, "GW7901", 6)) ||
Tim Harvey83ffc472022-08-11 11:57:04 -0700191 (!strncmp(model, "GW7902", 6)) ||
Tim Harveyb4531572022-09-14 09:02:19 -0700192 (!strncmp(model, "GW7903", 6)) ||
193 (!strncmp(model, "GW7904", 6))) {
Tim Harvey83ffc472022-08-11 11:57:04 -0700194 if (!strncmp(model, "GW7902", 6))
Tim Harvey6603b5e2021-07-27 15:19:41 -0700195 ret = uclass_get_device_by_seq(UCLASS_I2C, 0, &bus);
Tim Harvey83ffc472022-08-11 11:57:04 -0700196 else
197 ret = uclass_get_device_by_seq(UCLASS_I2C, 1, &bus);
Tim Harvey1b7fbf62021-06-30 16:50:02 -0700198 if (ret) {
199 printf("PMIC : failed I2C2 probe: %d\n", ret);
200 return ret;
201 }
202 ret = dm_i2c_probe(bus, 0x4b, 0, &dev);
203 if (ret) {
204 printf("PMIC : failed probe: %d\n", ret);
205 return ret;
206 }
207 puts("PMIC : BD71847\n");
208
209 /* unlock the PMIC regs */
210 dm_i2c_reg_write(dev, BD718XX_REGLOCK, 0x1);
211
212 /* set switchers to forced PWM mode */
213 dm_i2c_clrsetbits(dev, BD718XX_BUCK1_CTRL, 0, 0x8);
214 dm_i2c_clrsetbits(dev, BD718XX_BUCK2_CTRL, 0, 0x8);
215 dm_i2c_clrsetbits(dev, BD718XX_1ST_NODVS_BUCK_CTRL, 0, 0x8);
216 dm_i2c_clrsetbits(dev, BD718XX_2ND_NODVS_BUCK_CTRL, 0, 0x8);
217 dm_i2c_clrsetbits(dev, BD718XX_3RD_NODVS_BUCK_CTRL, 0, 0x8);
218 dm_i2c_clrsetbits(dev, BD718XX_4TH_NODVS_BUCK_CTRL, 0, 0x8);
219
220 /* increase VDD_0P95 (VDD_GPU/VPU/DRAM) to 0.975v for 1.5Ghz DDR */
221 dm_i2c_reg_write(dev, BD718XX_1ST_NODVS_BUCK_VOLT, 0x83);
222
223 /* increase VDD_SOC to 0.85v before first DRAM access */
224 dm_i2c_reg_write(dev, BD718XX_BUCK1_VOLT_RUN, 0x0f);
225
226 /* increase VDD_ARM to 0.92v for 800 and 1600Mhz */
227 dm_i2c_reg_write(dev, BD718XX_BUCK2_VOLT_RUN, 0x16);
228
229 /* Lock the PMIC regs */
230 dm_i2c_reg_write(dev, BD718XX_REGLOCK, 0x11);
231 }
232
Tim Harvey256dba02021-03-02 14:00:21 -0800233 return 0;
234}
235
236void board_init_f(ulong dummy)
237{
Tim Harvey2ccf28d2022-11-11 08:03:07 -0800238 struct udevice *bus, *dev;
239 int i, ret;
Tim Harvey256dba02021-03-02 14:00:21 -0800240 int dram_sz;
241
242 arch_cpu_init();
243
244 init_uart_clk(1);
245
Tim Harvey256dba02021-03-02 14:00:21 -0800246 timer_init();
247
Tim Harvey256dba02021-03-02 14:00:21 -0800248 /* Clear the BSS. */
249 memset(__bss_start, 0, __bss_end - __bss_start);
250
251 ret = spl_early_init();
252 if (ret) {
253 debug("spl_early_init() failed: %d\n", ret);
254 hang();
255 }
256
Tim Harvey91db7932022-04-29 12:36:25 -0700257 preloader_console_init();
258
Tim Harvey256dba02021-03-02 14:00:21 -0800259 enable_tzc380();
260
261 /* need to hold PCIe switch in reset otherwise it can lock i2c bus EEPROM is on */
262 gpio_request(PCIE_RSTN, "perst#");
263 gpio_direction_output(PCIE_RSTN, 0);
264
Tim Harveyd4daeaa2022-04-13 08:56:40 -0700265 /*
266 * probe GSC device
267 *
268 * On a board with a missing/depleted backup battery for GSC, the
269 * board may be ready to probe the GSC before its firmware is
Tim Harvey2ccf28d2022-11-11 08:03:07 -0800270 * running. Wait here for 50ms for the GSC firmware to let go of
271 * the SCL/SDA lines to avoid the i2c driver spamming
272 * 'Arbitration lost' I2C errors
Tim Harveyd4daeaa2022-04-13 08:56:40 -0700273 */
Tim Harvey2ccf28d2022-11-11 08:03:07 -0800274 if (!uclass_get_device_by_seq(UCLASS_I2C, 0, &bus)) {
275 if (!pinctrl_select_state(bus, "gpio")) {
276 struct mxc_i2c_bus *i2c_bus = dev_get_priv(bus);
277 struct gpio_desc *scl_gpio = &i2c_bus->scl_gpio;
278 struct gpio_desc *sda_gpio = &i2c_bus->sda_gpio;
279
280 dm_gpio_set_dir_flags(scl_gpio, GPIOD_IS_IN);
281 dm_gpio_set_dir_flags(sda_gpio, GPIOD_IS_IN);
282 for (i = 0; i < 5; i++) {
283 if (dm_gpio_get_value(scl_gpio) &&
284 dm_gpio_get_value(sda_gpio))
285 break;
286 mdelay(10);
287 }
288 pinctrl_select_state(bus, "default");
289 }
290 }
291 /* Wait indefiniately until the GSC probes */
Tim Harveyd4daeaa2022-04-13 08:56:40 -0700292 while (1) {
293 if (!uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(gsc), &dev))
294 break;
295 mdelay(1);
296 }
Tim Harvey1fec1822022-08-11 12:04:01 -0700297 dram_sz = venice_eeprom_init(0);
Tim Harvey256dba02021-03-02 14:00:21 -0800298
299 /* PMIC */
300 power_init_board();
301
302 /* DDR initialization */
303 spl_dram_init(dram_sz);
304
305 board_init_r(NULL, 0);
306}
307
308/* determine prioritized order of boot devices to load U-Boot from */
309void board_boot_order(u32 *spl_boot_list)
310{
Tim Harvey0f5717f2022-04-13 11:31:09 -0700311 int i = 0;
312
Tim Harvey256dba02021-03-02 14:00:21 -0800313 /*
314 * If the SPL was loaded via serial loader, we try to get
315 * U-Boot proper via USB SDP.
316 */
Tim Harvey0f5717f2022-04-13 11:31:09 -0700317 if (spl_boot_device() == BOOT_DEVICE_BOARD) {
318#ifdef CONFIG_IMX8MM
319 spl_boot_list[i++] = BOOT_DEVICE_BOARD;
320#else
321 spl_boot_list[i++] = BOOT_DEVICE_BOOTROM;
322#endif
323 }
Tim Harvey256dba02021-03-02 14:00:21 -0800324
325 /* we have only eMMC in default venice dt */
Tim Harvey0f5717f2022-04-13 11:31:09 -0700326 spl_boot_list[i++] = BOOT_DEVICE_MMC1;
Tim Harvey256dba02021-03-02 14:00:21 -0800327}
328
329/* return boot device based on where the SPL was loaded from */
330int spl_board_boot_device(enum boot_device boot_dev_spl)
331{
332 switch (boot_dev_spl) {
333 case USB_BOOT:
334 return BOOT_DEVICE_BOARD;
335 /* SDHC2 */
336 case SD2_BOOT:
337 case MMC2_BOOT:
338 return BOOT_DEVICE_MMC1;
339 /* SDHC3 */
340 case SD3_BOOT:
341 case MMC3_BOOT:
342 return BOOT_DEVICE_MMC2;
343 default:
344 return BOOT_DEVICE_NONE;
345 }
346}
Tim Harvey724d10a2022-03-08 10:45:39 -0800347
Marek Vasutf9a921e2023-10-16 18:16:12 +0200348unsigned long board_spl_mmc_get_uboot_raw_sector(struct mmc *mmc, unsigned long raw_sect)
Tim Harveya42793c2023-05-02 17:05:53 -0700349{
350 if (!IS_SD(mmc)) {
351 switch (EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config)) {
352 case 1:
353 case 2:
354 if (IS_ENABLED(CONFIG_IMX8MN) || IS_ENABLED(CONFIG_IMX8MP))
355 raw_sect -= 32 * 2;
356 break;
357 }
358 }
359
360 return raw_sect;
361}
362
Tim Harvey724d10a2022-03-08 10:45:39 -0800363const char *spl_board_loader_name(u32 boot_device)
364{
365 switch (boot_device) {
366 /* SDHC2 */
367 case BOOT_DEVICE_MMC1:
368 return "eMMC";
369 /* SDHC3 */
370 case BOOT_DEVICE_MMC2:
371 return "SD card";
372 default:
373 return NULL;
374 }
375}
Tim Harvey7ba1e9d2023-06-23 09:44:59 -0700376
377void spl_board_init(void)
378{
379 arch_misc_init();
380}