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