1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2025 NXP
4  */
5 
6 #include "lpddr4_timing.h"
7 
8 #include <init.h>
9 #include <spl.h>
10 #include <asm/arch/clock.h>
11 #include <asm/arch/ddr.h>
12 #include <asm/arch/mu.h>
13 #include <asm/arch/sys_proto.h>
14 #include <asm/arch/trdc.h>
15 #include <asm/mach-imx/boot_mode.h>
16 #include <asm/mach-imx/ele_api.h>
17 #include <asm/global_data.h>
18 #include <asm/sections.h>
19 #include <dm/device.h>
20 #include <dm/device-internal.h>
21 #include <dm/uclass.h>
22 #include <dm/uclass-internal.h>
23 #include <linux/delay.h>
24 #include <power/pca9450.h>
25 #include <power/pmic.h>
26 
27 DECLARE_GLOBAL_DATA_PTR;
28 
29 #define SRC_DDRC_SW_CTRL		(0x44461020)
30 #define SRC_DDRPHY_SINGLE_RESET_SW_CTRL	(0x44461424)
31 
32 static struct _drams {
33 	u8 mr8;
34 	struct dram_timing_info *pdram_timing;
35 	char *name;
36 } frdm_drams[2] = {
37 	{0x10, &dram_timing_1GB, "1GB DRAM" },
38 	{0x18, &dram_timing_2GB, "2GB DRAM" },
39 };
40 
spl_board_boot_device(enum boot_device boot_dev_spl)41 int spl_board_boot_device(enum boot_device boot_dev_spl)
42 {
43 	return BOOT_DEVICE_BOOTROM;
44 }
45 
spl_board_init(void)46 void spl_board_init(void)
47 {
48 	int ret;
49 
50 	ret = ele_start_rng();
51 	if (ret)
52 		printf("Fail to start RNG: %d\n", ret);
53 
54 	puts("Normal Boot\n");
55 }
56 
spl_dram_init(void)57 void spl_dram_init(void)
58 {
59 	int i;
60 	int ret;
61 
62 	for (i = 0; i < ARRAY_SIZE(frdm_drams); i++) {
63 		struct dram_timing_info *ptiming = frdm_drams[i].pdram_timing;
64 
65 		printf("DDR: %uMTS\n", ptiming->fsp_msg[0].drate);
66 		ret = ddr_init(ptiming);
67 		if (ret == 0) {
68 			if (lpddr4_mr_read(1, 8) == frdm_drams[i].mr8) {
69 				printf("found DRAM %s matched\n", frdm_drams[i].name);
70 				break;
71 			}
72 
73 			/* Power down and Power up DDR Mixer */
74 
75 			/* Clear PwrOkIn via DDRMIX register */
76 			setbits_32(SRC_DDRPHY_SINGLE_RESET_SW_CTRL, BIT(0));
77 			/* Power off the DDRMIX */
78 			setbits_32(SRC_DDRC_SW_CTRL, BIT(31));
79 
80 			udelay(50);
81 
82 			/* Power up the DDRMIX */
83 			clrbits_32(SRC_DDRC_SW_CTRL, BIT(31));
84 			setbits_32(SRC_DDRC_SW_CTRL, BIT(0));
85 			udelay(10);
86 			clrbits_32(SRC_DDRC_SW_CTRL, BIT(0));
87 			udelay(10);
88 		}
89 	}
90 }
91 
power_init_board(void)92 int power_init_board(void)
93 {
94 	struct udevice *dev;
95 	int ret;
96 	unsigned int val = 0, buck_val;
97 
98 	ret = pmic_get("pmic@25", &dev);
99 	if (ret == -ENODEV) {
100 		puts("No pca9450@25\n");
101 		return 0;
102 	}
103 	if (ret != 0)
104 		return ret;
105 
106 	/* BUCKxOUT_DVS0/1 control BUCK123 output */
107 	pmic_reg_write(dev, PCA9450_BUCK123_DVS, 0x29);
108 
109 	/* Enable DVS control through PMIC_STBY_REQ */
110 	pmic_reg_write(dev, PCA9450_BUCK1CTRL, 0x59);
111 
112 	ret = pmic_reg_read(dev, PCA9450_PWR_CTRL);
113 	if (ret < 0)
114 		return ret;
115 
116 	val = ret;
117 
118 	if (is_voltage_mode(VOLT_LOW_DRIVE)) {
119 		buck_val = 0x0c; /* 0.8V for Low drive mode */
120 		printf("PMIC: Low Drive Voltage Mode\n");
121 	} else if (is_voltage_mode(VOLT_NOMINAL_DRIVE)) {
122 		buck_val = 0x10; /* 0.85V for Nominal drive mode */
123 		printf("PMIC: Nominal Voltage Mode\n");
124 	} else {
125 		buck_val = 0x14; /* 0.9V for Over drive mode */
126 		printf("PMIC: Over Drive Voltage Mode\n");
127 	}
128 
129 	if (val & PCA9450_REG_PWRCTRL_TOFF_DEB) {
130 		pmic_reg_write(dev, PCA9450_BUCK1OUT_DVS0, buck_val);
131 		pmic_reg_write(dev, PCA9450_BUCK3OUT_DVS0, buck_val);
132 	} else {
133 		pmic_reg_write(dev, PCA9450_BUCK1OUT_DVS0, buck_val + 0x4);
134 		pmic_reg_write(dev, PCA9450_BUCK3OUT_DVS0, buck_val + 0x4);
135 	}
136 
137 	/* Set standby voltage to 0.65V */
138 	if (val & PCA9450_REG_PWRCTRL_TOFF_DEB)
139 		pmic_reg_write(dev, PCA9450_BUCK1OUT_DVS1, 0x0);
140 	else
141 		pmic_reg_write(dev, PCA9450_BUCK1OUT_DVS1, 0x4);
142 
143 	/* I2C_LT_EN*/
144 	pmic_reg_write(dev, 0xa, 0x3);
145 	return 0;
146 }
147 
board_init_f(ulong dummy)148 void board_init_f(ulong dummy)
149 {
150 	int ret;
151 
152 	/* Clear the BSS. */
153 	memset(__bss_start, 0, __bss_end - __bss_start);
154 
155 	timer_init();
156 
157 	arch_cpu_init();
158 
159 	board_early_init_f();
160 
161 	spl_early_init();
162 
163 	preloader_console_init();
164 
165 	ret = imx9_probe_mu();
166 	if (ret) {
167 		printf("Fail to init Sentinel API\n");
168 	} else {
169 		debug("SOC: 0x%x\n", gd->arch.soc_rev);
170 		debug("LC: 0x%x\n", gd->arch.lifecycle);
171 	}
172 
173 	clock_init_late();
174 
175 	power_init_board();
176 
177 	if (!is_voltage_mode(VOLT_LOW_DRIVE))
178 		set_arm_clk(get_cpu_speed_grade_hz());
179 
180 	/* Init power of mix */
181 	soc_power_init();
182 
183 	/* Setup TRDC for DDR access */
184 	trdc_init();
185 
186 	/* DDR initialization */
187 	spl_dram_init();
188 
189 	/* Put M33 into CPUWAIT for following kick */
190 	ret = m33_prepare();
191 	if (!ret)
192 		printf("M33 prepare ok\n");
193 
194 	board_init_r(NULL, 0);
195 }
196