blob: b0a315ba9531f1779d774008da0e017066918797 [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
Tom Riniabb9a042024-05-18 20:20:43 -06006#include <common.h>
Tim Harvey256dba02021-03-02 14:00:21 -08007#include <cpu_func.h>
8#include <hang.h>
9#include <i2c.h>
Tim Harvey256dba02021-03-02 14:00:21 -080010#include <init.h>
Tim Harvey256dba02021-03-02 14:00:21 -080011#include <spl.h>
Tim Harvey256dba02021-03-02 14:00:21 -080012#include <asm/mach-imx/gpio.h>
Tim Harvey256dba02021-03-02 14:00:21 -080013#include <asm/arch/clock.h>
14#include <asm/arch/imx8mm_pins.h>
Tim Harvey1a50e742022-02-11 10:48:56 -080015#include <asm/arch/imx8mn_pins.h>
Tim Harvey0f5717f2022-04-13 11:31:09 -070016#include <asm/arch/imx8mp_pins.h>
Tim Harvey256dba02021-03-02 14:00:21 -080017#include <asm/arch/sys_proto.h>
18#include <asm/mach-imx/boot_mode.h>
Tim Harvey2ccf28d2022-11-11 08:03:07 -080019#include <asm/mach-imx/mxc_i2c.h>
Tim Harvey256dba02021-03-02 14:00:21 -080020#include <asm/arch/ddr.h>
21#include <asm-generic/gpio.h>
Shiji Yangbb112342023-08-03 09:47:16 +080022#include <asm/sections.h>
Tim Harvey256dba02021-03-02 14:00:21 -080023#include <dm/uclass.h>
24#include <dm/device.h>
Tim Harvey2ccf28d2022-11-11 08:03:07 -080025#include <dm/pinctrl.h>
Tim Harveyd4daeaa2022-04-13 08:56:40 -070026#include <linux/delay.h>
Tim Harvey1b7fbf62021-06-30 16:50:02 -070027#include <power/bd71837.h>
Tim Harvey256dba02021-03-02 14:00:21 -080028#include <power/mp5416.h>
Tim Harvey0f5717f2022-04-13 11:31:09 -070029#include <power/pca9450.h>
Tim Harvey256dba02021-03-02 14:00:21 -080030
Tim Harveyd4daeaa2022-04-13 08:56:40 -070031#include "eeprom.h"
Tim Harvey256dba02021-03-02 14:00:21 -080032#include "lpddr4_timing.h"
33
34#define PCIE_RSTN IMX_GPIO_NR(4, 6)
35
Tim Harvey256dba02021-03-02 14:00:21 -080036static void spl_dram_init(int size)
37{
38 struct dram_timing_info *dram_timing;
39
40 switch (size) {
Tim Harvey1a50e742022-02-11 10:48:56 -080041#ifdef CONFIG_IMX8MM
Tim Harvey5cc5e192022-02-18 15:19:33 -080042 case 512:
43 dram_timing = &dram_timing_512mb;
44 break;
45 case 1024:
Tim Harvey256dba02021-03-02 14:00:21 -080046 dram_timing = &dram_timing_1gb;
47 break;
Tim Harvey5cc5e192022-02-18 15:19:33 -080048 case 2048:
Tim Harvey6603b5e2021-07-27 15:19:41 -070049 dram_timing = &dram_timing_2gb;
50 break;
Tim Harvey5cc5e192022-02-18 15:19:33 -080051 case 4096:
Tim Harvey256dba02021-03-02 14:00:21 -080052 dram_timing = &dram_timing_4gb;
53 break;
54 default:
Tim Harvey5cc5e192022-02-18 15:19:33 -080055 printf("Unknown DDR configuration: %d MiB\n", size);
Tim Harvey256dba02021-03-02 14:00:21 -080056 dram_timing = &dram_timing_1gb;
Tim Harvey5cc5e192022-02-18 15:19:33 -080057 size = 1024;
Tim Harvey0f5717f2022-04-13 11:31:09 -070058#elif CONFIG_IMX8MN
Tim Harvey5cc5e192022-02-18 15:19:33 -080059 case 1024:
Tim Harvey1a50e742022-02-11 10:48:56 -080060 dram_timing = &dram_timing_1gb_single_die;
61 break;
Tim Harvey5cc5e192022-02-18 15:19:33 -080062 case 2048:
Tim Harveyd4daeaa2022-04-13 08:56:40 -070063 if (!strcmp(eeprom_get_model(), "GW7902-SP466-A") ||
64 !strcmp(eeprom_get_model(), "GW7902-SP466-B")) {
Tim Harvey1a50e742022-02-11 10:48:56 -080065 dram_timing = &dram_timing_2gb_dual_die;
66 } else {
67 dram_timing = &dram_timing_2gb_single_die;
68 }
69 break;
70 default:
Tim Harvey5cc5e192022-02-18 15:19:33 -080071 printf("Unknown DDR configuration: %d MiB\n", size);
Tim Harvey1a50e742022-02-11 10:48:56 -080072 dram_timing = &dram_timing_2gb_dual_die;
Tim Harvey5cc5e192022-02-18 15:19:33 -080073 size = 2048;
Tim Harvey0f5717f2022-04-13 11:31:09 -070074#elif CONFIG_IMX8MP
Tim Harvey08ac93c2023-06-09 09:54:51 -070075 case 1024:
76 dram_timing = &dram_timing_1gb_single_die;
77 break;
Tim Harvey0f5717f2022-04-13 11:31:09 -070078 case 4096:
79 dram_timing = &dram_timing_4gb_dual_die;
80 break;
81 default:
82 printf("Unknown DDR configuration: %d GiB\n", size);
83 dram_timing = &dram_timing_4gb_dual_die;
84 size = 4096;
Tim Harvey1a50e742022-02-11 10:48:56 -080085#endif
Tim Harvey256dba02021-03-02 14:00:21 -080086 }
87
Tim Harvey5cc5e192022-02-18 15:19:33 -080088 printf("DRAM : LPDDR4 ");
89 if (size > 512)
Tim Harvey03280f32023-06-09 09:54:01 -070090 printf("%d GiB", size / 1024);
Tim Harvey5cc5e192022-02-18 15:19:33 -080091 else
Tim Harvey03280f32023-06-09 09:54:01 -070092 printf("%d MiB", size);
93 printf(" %dMT/s %dMHz\n",
94 dram_timing->fsp_msg[0].drate,
95 dram_timing->fsp_msg[0].drate / 2);
Tim Harvey256dba02021-03-02 14:00:21 -080096 ddr_init(dram_timing);
Tim Harvey256dba02021-03-02 14:00:21 -080097}
98
Tim Harvey256dba02021-03-02 14:00:21 -080099/*
100 * Model specific PMIC adjustments necessary prior to DRAM init
101 *
102 * Note that we can not use pmic dm drivers here as we have a generic
103 * venice dt that does not have board-specific pmic's defined.
104 *
Tim Harvey1b7fbf62021-06-30 16:50:02 -0700105 * Instead we must use dm_i2c so we a helpers to give us
106 * clrsetbit functions we would otherwise have if we could use PMIC dm
107 * drivers.
Tim Harvey256dba02021-03-02 14:00:21 -0800108 */
Tim Harvey1b7fbf62021-06-30 16:50:02 -0700109static int dm_i2c_clrsetbits(struct udevice *dev, uint reg, uint clr, uint set)
110{
111 int ret;
112 u8 val;
113
114 ret = dm_i2c_read(dev, reg, &val, 1);
115 if (ret)
116 return ret;
117 val = (val & ~clr) | set;
118
119 return dm_i2c_write(dev, reg, &val, 1);
120}
121
Tim Harvey256dba02021-03-02 14:00:21 -0800122static int power_init_board(void)
123{
Tim Harveyd4daeaa2022-04-13 08:56:40 -0700124 const char *model = eeprom_get_model();
Tim Harvey256dba02021-03-02 14:00:21 -0800125 struct udevice *bus;
126 struct udevice *dev;
127 int ret;
128
129 if ((!strncmp(model, "GW71", 4)) ||
130 (!strncmp(model, "GW72", 4)) ||
Tim Harvey08ac93c2023-06-09 09:54:51 -0700131 (!strncmp(model, "GW73", 4)) ||
132 (!strncmp(model, "GW7905", 6))) {
Tim Harveyd5419272021-07-27 15:19:38 -0700133 ret = uclass_get_device_by_seq(UCLASS_I2C, 0, &bus);
Tim Harvey256dba02021-03-02 14:00:21 -0800134 if (ret) {
135 printf("PMIC : failed I2C1 probe: %d\n", ret);
136 return ret;
137 }
138 ret = dm_i2c_probe(bus, 0x69, 0, &dev);
139 if (ret) {
140 printf("PMIC : failed probe: %d\n", ret);
141 return ret;
142 }
Tim Harvey08ac93c2023-06-09 09:54:51 -0700143#ifdef CONFIG_IMX8MM
144 puts("PMIC : MP5416 (IMX8MM)\n");
Tim Harvey256dba02021-03-02 14:00:21 -0800145
146 /* set VDD_ARM SW3 to 0.92V for 1.6GHz */
147 dm_i2c_reg_write(dev, MP5416_VSET_SW3,
148 BIT(7) | MP5416_VSET_SW3_SVAL(920000));
Tim Harvey08ac93c2023-06-09 09:54:51 -0700149#elif CONFIG_IMX8MP
150 puts("PMIC : MP5416 (IMX8MP)\n");
151
152 /* set VDD_ARM SW3 to 0.95V for 1.6GHz */
153 dm_i2c_reg_write(dev, MP5416_VSET_SW3,
154 BIT(7) | MP5416_VSET_SW3_SVAL(950000));
155 /* set VDD_SOC SW1 to 0.95V for 1.6GHz */
156 dm_i2c_reg_write(dev, MP5416_VSET_SW1,
157 BIT(7) | MP5416_VSET_SW1_SVAL(950000));
158#endif
Tim Harvey256dba02021-03-02 14:00:21 -0800159 }
160
Tim Harvey0f5717f2022-04-13 11:31:09 -0700161 else if (!strncmp(model, "GW74", 4)) {
Tim Harveyffe9e3c2023-08-15 15:01:15 -0700162 ret = uclass_get_device_by_seq(UCLASS_I2C, 2, &bus);
Tim Harvey0f5717f2022-04-13 11:31:09 -0700163 if (ret) {
Tim Harveyffe9e3c2023-08-15 15:01:15 -0700164 printf("PMIC : failed I2C3 probe: %d\n", ret);
Tim Harvey0f5717f2022-04-13 11:31:09 -0700165 return ret;
166 }
167 ret = dm_i2c_probe(bus, 0x25, 0, &dev);
168 if (ret) {
169 printf("PMIC : failed probe: %d\n", ret);
170 return ret;
171 }
172 puts("PMIC : PCA9450\n");
173
174 /* BUCKxOUT_DVS0/1 control BUCK123 output */
175 dm_i2c_reg_write(dev, PCA9450_BUCK123_DVS, 0x29);
176
177 /* Buck 1 DVS control through PMIC_STBY_REQ */
178 dm_i2c_reg_write(dev, PCA9450_BUCK1CTRL, 0x59);
179
Tim Harvey4897fc22022-09-08 14:41:09 -0700180 /* Set DVS1 to 0.85v for suspend */
181 dm_i2c_reg_write(dev, PCA9450_BUCK1OUT_DVS1, 0x14);
Tim Harvey0f5717f2022-04-13 11:31:09 -0700182
Tim Harvey4897fc22022-09-08 14:41:09 -0700183 /* increase VDD_SOC to 0.95V before first DRAM access */
184 dm_i2c_reg_write(dev, PCA9450_BUCK1OUT_DVS0, 0x1C);
Tim Harvey0f5717f2022-04-13 11:31:09 -0700185
Tim Harvey4897fc22022-09-08 14:41:09 -0700186 /* Kernel uses OD/OD freq for SOC */
187 /* To avoid timing risk from SOC to ARM, increase VDD_ARM to OD voltage 0.95v */
188 dm_i2c_reg_write(dev, PCA9450_BUCK2OUT_DVS0, 0x1C);
Tim Harvey0f5717f2022-04-13 11:31:09 -0700189 }
190
Tim Harvey6603b5e2021-07-27 15:19:41 -0700191 else if ((!strncmp(model, "GW7901", 6)) ||
Tim Harvey83ffc472022-08-11 11:57:04 -0700192 (!strncmp(model, "GW7902", 6)) ||
Tim Harveyb4531572022-09-14 09:02:19 -0700193 (!strncmp(model, "GW7903", 6)) ||
194 (!strncmp(model, "GW7904", 6))) {
Tim Harvey83ffc472022-08-11 11:57:04 -0700195 if (!strncmp(model, "GW7902", 6))
Tim Harvey6603b5e2021-07-27 15:19:41 -0700196 ret = uclass_get_device_by_seq(UCLASS_I2C, 0, &bus);
Tim Harvey83ffc472022-08-11 11:57:04 -0700197 else
198 ret = uclass_get_device_by_seq(UCLASS_I2C, 1, &bus);
Tim Harvey1b7fbf62021-06-30 16:50:02 -0700199 if (ret) {
200 printf("PMIC : failed I2C2 probe: %d\n", ret);
201 return ret;
202 }
203 ret = dm_i2c_probe(bus, 0x4b, 0, &dev);
204 if (ret) {
205 printf("PMIC : failed probe: %d\n", ret);
206 return ret;
207 }
208 puts("PMIC : BD71847\n");
209
210 /* unlock the PMIC regs */
211 dm_i2c_reg_write(dev, BD718XX_REGLOCK, 0x1);
212
213 /* set switchers to forced PWM mode */
214 dm_i2c_clrsetbits(dev, BD718XX_BUCK1_CTRL, 0, 0x8);
215 dm_i2c_clrsetbits(dev, BD718XX_BUCK2_CTRL, 0, 0x8);
216 dm_i2c_clrsetbits(dev, BD718XX_1ST_NODVS_BUCK_CTRL, 0, 0x8);
217 dm_i2c_clrsetbits(dev, BD718XX_2ND_NODVS_BUCK_CTRL, 0, 0x8);
218 dm_i2c_clrsetbits(dev, BD718XX_3RD_NODVS_BUCK_CTRL, 0, 0x8);
219 dm_i2c_clrsetbits(dev, BD718XX_4TH_NODVS_BUCK_CTRL, 0, 0x8);
220
221 /* increase VDD_0P95 (VDD_GPU/VPU/DRAM) to 0.975v for 1.5Ghz DDR */
222 dm_i2c_reg_write(dev, BD718XX_1ST_NODVS_BUCK_VOLT, 0x83);
223
224 /* increase VDD_SOC to 0.85v before first DRAM access */
225 dm_i2c_reg_write(dev, BD718XX_BUCK1_VOLT_RUN, 0x0f);
226
227 /* increase VDD_ARM to 0.92v for 800 and 1600Mhz */
228 dm_i2c_reg_write(dev, BD718XX_BUCK2_VOLT_RUN, 0x16);
229
230 /* Lock the PMIC regs */
231 dm_i2c_reg_write(dev, BD718XX_REGLOCK, 0x11);
232 }
233
Tim Harvey256dba02021-03-02 14:00:21 -0800234 return 0;
235}
236
237void board_init_f(ulong dummy)
238{
Tim Harvey2ccf28d2022-11-11 08:03:07 -0800239 struct udevice *bus, *dev;
240 int i, ret;
Tim Harvey256dba02021-03-02 14:00:21 -0800241 int dram_sz;
242
243 arch_cpu_init();
244
245 init_uart_clk(1);
246
Tim Harvey256dba02021-03-02 14:00:21 -0800247 timer_init();
248
Tim Harvey256dba02021-03-02 14:00:21 -0800249 /* Clear the BSS. */
250 memset(__bss_start, 0, __bss_end - __bss_start);
251
252 ret = spl_early_init();
253 if (ret) {
254 debug("spl_early_init() failed: %d\n", ret);
255 hang();
256 }
257
Tim Harvey91db7932022-04-29 12:36:25 -0700258 preloader_console_init();
259
Tim Harvey256dba02021-03-02 14:00:21 -0800260 enable_tzc380();
261
262 /* need to hold PCIe switch in reset otherwise it can lock i2c bus EEPROM is on */
263 gpio_request(PCIE_RSTN, "perst#");
264 gpio_direction_output(PCIE_RSTN, 0);
265
Tim Harveyd4daeaa2022-04-13 08:56:40 -0700266 /*
267 * probe GSC device
268 *
269 * On a board with a missing/depleted backup battery for GSC, the
270 * board may be ready to probe the GSC before its firmware is
Tim Harvey2ccf28d2022-11-11 08:03:07 -0800271 * running. Wait here for 50ms for the GSC firmware to let go of
272 * the SCL/SDA lines to avoid the i2c driver spamming
273 * 'Arbitration lost' I2C errors
Tim Harveyd4daeaa2022-04-13 08:56:40 -0700274 */
Tim Harvey2ccf28d2022-11-11 08:03:07 -0800275 if (!uclass_get_device_by_seq(UCLASS_I2C, 0, &bus)) {
276 if (!pinctrl_select_state(bus, "gpio")) {
277 struct mxc_i2c_bus *i2c_bus = dev_get_priv(bus);
278 struct gpio_desc *scl_gpio = &i2c_bus->scl_gpio;
279 struct gpio_desc *sda_gpio = &i2c_bus->sda_gpio;
280
281 dm_gpio_set_dir_flags(scl_gpio, GPIOD_IS_IN);
282 dm_gpio_set_dir_flags(sda_gpio, GPIOD_IS_IN);
283 for (i = 0; i < 5; i++) {
284 if (dm_gpio_get_value(scl_gpio) &&
285 dm_gpio_get_value(sda_gpio))
286 break;
287 mdelay(10);
288 }
289 pinctrl_select_state(bus, "default");
290 }
291 }
292 /* Wait indefiniately until the GSC probes */
Tim Harveyd4daeaa2022-04-13 08:56:40 -0700293 while (1) {
294 if (!uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(gsc), &dev))
295 break;
296 mdelay(1);
297 }
Tim Harvey1fec1822022-08-11 12:04:01 -0700298 dram_sz = venice_eeprom_init(0);
Tim Harvey256dba02021-03-02 14:00:21 -0800299
300 /* PMIC */
301 power_init_board();
302
303 /* DDR initialization */
304 spl_dram_init(dram_sz);
305
306 board_init_r(NULL, 0);
307}
308
309/* determine prioritized order of boot devices to load U-Boot from */
310void board_boot_order(u32 *spl_boot_list)
311{
Tim Harvey0f5717f2022-04-13 11:31:09 -0700312 int i = 0;
313
Tim Harvey256dba02021-03-02 14:00:21 -0800314 /*
315 * If the SPL was loaded via serial loader, we try to get
316 * U-Boot proper via USB SDP.
317 */
Tim Harvey0f5717f2022-04-13 11:31:09 -0700318 if (spl_boot_device() == BOOT_DEVICE_BOARD) {
319#ifdef CONFIG_IMX8MM
320 spl_boot_list[i++] = BOOT_DEVICE_BOARD;
321#else
322 spl_boot_list[i++] = BOOT_DEVICE_BOOTROM;
323#endif
324 }
Tim Harvey256dba02021-03-02 14:00:21 -0800325
326 /* we have only eMMC in default venice dt */
Tim Harvey0f5717f2022-04-13 11:31:09 -0700327 spl_boot_list[i++] = BOOT_DEVICE_MMC1;
Tim Harvey256dba02021-03-02 14:00:21 -0800328}
329
330/* return boot device based on where the SPL was loaded from */
331int spl_board_boot_device(enum boot_device boot_dev_spl)
332{
333 switch (boot_dev_spl) {
334 case USB_BOOT:
335 return BOOT_DEVICE_BOARD;
336 /* SDHC2 */
337 case SD2_BOOT:
338 case MMC2_BOOT:
339 return BOOT_DEVICE_MMC1;
340 /* SDHC3 */
341 case SD3_BOOT:
342 case MMC3_BOOT:
343 return BOOT_DEVICE_MMC2;
344 default:
345 return BOOT_DEVICE_NONE;
346 }
347}
Tim Harvey724d10a2022-03-08 10:45:39 -0800348
Marek Vasutf9a921e2023-10-16 18:16:12 +0200349unsigned long board_spl_mmc_get_uboot_raw_sector(struct mmc *mmc, unsigned long raw_sect)
Tim Harveya42793c2023-05-02 17:05:53 -0700350{
351 if (!IS_SD(mmc)) {
352 switch (EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config)) {
353 case 1:
354 case 2:
355 if (IS_ENABLED(CONFIG_IMX8MN) || IS_ENABLED(CONFIG_IMX8MP))
356 raw_sect -= 32 * 2;
357 break;
358 }
359 }
360
361 return raw_sect;
362}
363
Tim Harvey724d10a2022-03-08 10:45:39 -0800364const char *spl_board_loader_name(u32 boot_device)
365{
366 switch (boot_device) {
367 /* SDHC2 */
368 case BOOT_DEVICE_MMC1:
369 return "eMMC";
370 /* SDHC3 */
371 case BOOT_DEVICE_MMC2:
372 return "SD card";
373 default:
374 return NULL;
375 }
376}
Tim Harvey7ba1e9d2023-06-23 09:44:59 -0700377
378void spl_board_init(void)
379{
380 arch_misc_init();
381}