blob: 32233c0e1ab9c4afc0051791ffec863a6bfddcd0 [file] [log] [blame]
Vitor Soares987c7362025-04-07 14:04:36 +01001// 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
19DECLARE_GLOBAL_DATA_PTR;
20
21int spl_board_boot_device(enum boot_device boot_dev_spl)
22{
23 return BOOT_DEVICE_BOOTROM;
24}
25
26void 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
44void 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
61int 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 */
107void 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}