1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Copyright (C) 2024 Toradex */
3
4 #include <hang.h>
5 #include <init.h>
6 #include <log.h>
7 #include <spl.h>
8 #include <asm/arch/clock.h>
9 #include <asm/arch/ddr.h>
10 #include <asm/arch/sys_proto.h>
11 #include <asm/global_data.h>
12 #include <asm/mach-imx/boot_mode.h>
13 #include <dm/device.h>
14 #include <power/pmic.h>
15 #include <power/pca9450.h>
16
17 #include "lpddr4_timing.h"
18
19 DECLARE_GLOBAL_DATA_PTR;
20
spl_board_boot_device(enum boot_device boot_dev_spl)21 int spl_board_boot_device(enum boot_device boot_dev_spl)
22 {
23 return BOOT_DEVICE_BOOTROM;
24 }
25
spl_dram_init(void)26 void spl_dram_init(void)
27 {
28 /*
29 * Try configuring for dual rank memory falling back to single rank
30 */
31 if (!ddr_init(&dram_timing)) {
32 puts("DDR configured as dual rank\n");
33 return;
34 }
35
36 lpddr4_single_rank_training_patch();
37 if (!ddr_init(&dram_timing)) {
38 puts("DDR configured as single rank\n");
39 return;
40 }
41 puts("DDR configuration failed\n");
42 }
43
spl_board_init(void)44 void spl_board_init(void)
45 {
46 arch_misc_init();
47
48 /*
49 * Set GIC clock to 500Mhz for OD VDD_SOC. Kernel driver does
50 * not allow to change it. Should set the clock after PMIC
51 * setting done. Default is 400Mhz (system_pll1_800m with div = 2)
52 * set by ROM for ND VDD_SOC
53 */
54 clock_enable(CCGR_GIC, 0);
55 clock_set_target_val(GIC_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(5));
56 clock_enable(CCGR_GIC, 1);
57
58 puts("Normal Boot\n");
59 }
60
power_init_board(void)61 int power_init_board(void)
62 {
63 struct udevice *dev;
64 int ret;
65
66 ret = pmic_get("pmic@25", &dev);
67 if (ret == -ENODEV) {
68 puts("No pmic@25\n");
69 return 0;
70 }
71 if (ret < 0)
72 return ret;
73
74 /* BUCKxOUT_DVS0/1 control BUCK123 output */
75 pmic_reg_write(dev, PCA9450_BUCK123_DVS, 0x29);
76
77 /*
78 * Increase VDD_SOC to typical value 0.95V before first
79 * DRAM access, set DVS1 to 0.85V for suspend.
80 * Enable DVS control through PMIC_STBY_REQ and
81 * set B1_ENMODE=1 (ON by PMIC_ON_REQ=H)
82 */
83 if (IS_ENABLED(CONFIG_IMX8M_VDD_SOC_850MV))
84 /* set DVS0 to 0.85v for special case */
85 pmic_reg_write(dev, PCA9450_BUCK1OUT_DVS0, 0x14);
86 else
87 pmic_reg_write(dev, PCA9450_BUCK1OUT_DVS0, 0x1c);
88
89 pmic_reg_write(dev, PCA9450_BUCK1OUT_DVS1, 0x14);
90 pmic_reg_write(dev, PCA9450_BUCK1CTRL, 0x59);
91
92 /*
93 * Kernel uses OD/OD freq for SOC.
94 * To avoid timing risk from SOC to ARM,increase VDD_ARM to OD
95 * voltage 0.95V.
96 */
97 pmic_reg_write(dev, PCA9450_BUCK2OUT_DVS0, 0x1c);
98
99 /* set LDO4 and CONFIG2 to enable the I2C level translator */
100 pmic_reg_write(dev, PCA9450_LDO4CTRL, 0x59);
101 pmic_reg_write(dev, PCA9450_CONFIG2, 0x1);
102
103 return 0;
104 }
105
106 /* Do not use BSS area in this phase */
board_init_f(ulong dummy)107 void board_init_f(ulong dummy)
108 {
109 int ret;
110
111 arch_cpu_init();
112
113 init_uart_clk(3);
114
115 ret = spl_early_init();
116 if (ret) {
117 debug("spl_init() failed: %d\n", ret);
118 hang();
119 }
120
121 preloader_console_init();
122
123 enable_tzc380();
124
125 /* PMIC initialization */
126 power_init_board();
127
128 /* DDR initialization */
129 spl_dram_init();
130 }
131