1 // SPDX-License-Identifier: GPL-2.0+ OR MIT
2 /*
3  * Copyright 2021 NXP
4  */
5 #include <common.h>
6 #include <asm/io.h>
7 #include <asm/arch/clock.h>
8 #include <asm/arch/ddr.h>
9 #include <asm/arch/imx-regs.h>
10 
11 #define DENALI_CTL_00		(DDR_CTL_BASE_ADDR)
12 #define CTL_START		0x1
13 
14 #define DENALI_CTL_03		(DDR_CTL_BASE_ADDR + 4 * 3)
15 #define DENALI_CTL_197		(DDR_CTL_BASE_ADDR + 4 * 197)
16 #define DENALI_CTL_250		(DDR_CTL_BASE_ADDR + 4 * 250)
17 #define DENALI_CTL_251		(DDR_CTL_BASE_ADDR + 4 * 251)
18 #define DENALI_CTL_266		(DDR_CTL_BASE_ADDR + 4 * 266)
19 #define DFI_INIT_COMPLETE	0x2
20 
21 #define DENALI_CTL_614		(DDR_CTL_BASE_ADDR + 4 * 614)
22 #define DENALI_CTL_615		(DDR_CTL_BASE_ADDR + 4 * 615)
23 
24 #define DENALI_PI_00		(DDR_PI_BASE_ADDR)
25 #define PI_START		0x1
26 
27 #define DENALI_PI_04		(DDR_PI_BASE_ADDR + 4 * 4)
28 #define DENALI_PI_11		(DDR_PI_BASE_ADDR + 4 * 11)
29 #define DENALI_PI_12		(DDR_PI_BASE_ADDR + 4 * 12)
30 #define DENALI_CTL_23		(DDR_CTL_BASE_ADDR + 4 * 23)
31 #define DENALI_CTL_25		(DDR_CTL_BASE_ADDR + 4 * 25)
32 
33 #define DENALI_PHY_1624		(DDR_PHY_BASE_ADDR + 4 * 1624)
34 #define DENALI_PHY_1537		(DDR_PHY_BASE_ADDR + 4 * 1537)
35 #define PHY_FREQ_SEL_MULTICAST_EN(X)	((X) << 8)
36 #define PHY_FREQ_SEL_INDEX(X)		((X) << 16)
37 
38 #define DENALI_PHY_1547		(DDR_PHY_BASE_ADDR + 4 * 1547)
39 #define DENALI_PHY_1555		(DDR_PHY_BASE_ADDR + 4 * 1555)
40 #define DENALI_PHY_1564		(DDR_PHY_BASE_ADDR + 4 * 1564)
41 #define DENALI_PHY_1565		(DDR_PHY_BASE_ADDR + 4 * 1565)
42 
ddr_calibration(unsigned int fsp_table[3])43 int ddr_calibration(unsigned int fsp_table[3])
44 {
45 	u32 reg_val;
46 	u32 int_status_init, phy_freq_req, phy_freq_type;
47 	u32 lock_0, lock_1, lock_2;
48 	u32 freq_chg_pt, freq_chg_cnt;
49 
50 	reg_val = readl(DENALI_CTL_250);
51 	if (((reg_val >> 16) & 0x3) == 1)
52 		freq_chg_cnt = 2;
53 	else
54 		freq_chg_cnt = 3;
55 
56 	reg_val = readl(DENALI_PI_12);
57 	if (reg_val == 0x3) {
58 		freq_chg_pt = 1;
59 	} else if (reg_val == 0x7) {
60 		freq_chg_pt = 2;
61 	} else {
62 		printf("frequency map(0x%x) is wrong, please check!\r\n", reg_val);
63 		return -1;
64 	}
65 
66 	debug("%s\n", __func__);
67 
68 	/* Assert PI_START parameter and then assert START parameter in Controller. */
69 	reg_val = readl(DENALI_PI_00) | PI_START;
70 	writel(reg_val, DENALI_PI_00);
71 
72 	reg_val = readl(DENALI_CTL_00) | CTL_START;
73 	writel(reg_val, DENALI_CTL_00);
74 
75 	/* Poll for init_done_bit in Controller interrupt status register (INT_STATUS_INIT) */
76 	do {
77 		if (!freq_chg_cnt) {
78 			int_status_init = (readl(DENALI_CTL_266) >> 8) & 0xff;
79 			/* DDR subsystem is ready for traffic. */
80 			if (int_status_init & DFI_INIT_COMPLETE) {
81 				printf("complete\n");
82 				break;
83 			}
84 		}
85 
86 		/*
87 		 * During leveling, PHY will request for freq change and SoC clock
88 		 * logic should provide requested frequency, Polling SIM LPDDR_CTRL2
89 		 * Bit phy_freq_chg_req until be 1'b1
90 		 */
91 		reg_val = readl(AVD_SIM_LPDDR_CTRL2);
92 		phy_freq_req = (reg_val >> 7) & 0x1;
93 
94 		if (phy_freq_req) {
95 			phy_freq_type = reg_val & 0x1F;
96 			if (!phy_freq_type) {
97 				printf("Poll for freq_chg_req on SIM register and change to F0 frequency.\n");
98 				set_ddr_clk(fsp_table[phy_freq_type] >> 1);
99 
100 				/* Write 1'b1 at LPDDR_CTRL2 bit phy_freq_cfg_ack */
101 				reg_val = readl(AVD_SIM_LPDDR_CTRL2);
102 				writel(reg_val | (0x1 << 6), AVD_SIM_LPDDR_CTRL2);
103 			} else if (phy_freq_type == 0x01) {
104 				printf("Poll for freq_chg_req on SIM register and change to F1 frequency.\n");
105 				set_ddr_clk(fsp_table[phy_freq_type] >> 1);
106 
107 				/* Write 1'b1 at LPDDR_CTRL2 bit phy_freq_cfg_ack */
108 				reg_val = readl(AVD_SIM_LPDDR_CTRL2);
109 				writel(reg_val | (0x1 << 6), AVD_SIM_LPDDR_CTRL2);
110 				if (freq_chg_pt == 1)
111 					freq_chg_cnt--;
112 			} else if (phy_freq_type == 0x02) {
113 				printf("Poll for freq_chg_req on SIM register and change to F2 frequency.\n");
114 				set_ddr_clk(fsp_table[phy_freq_type] >> 1);
115 
116 				/* Write 1'b1 at LPDDR_CTRL2 bit phy_freq_cfg_ack */
117 				reg_val = readl(AVD_SIM_LPDDR_CTRL2);
118 				writel(reg_val | (0x1 << 6), AVD_SIM_LPDDR_CTRL2);
119 				if (freq_chg_pt == 2)
120 					freq_chg_cnt--;
121 			}
122 			reg_val = readl(AVD_SIM_LPDDR_CTRL2);
123 		}
124 	} while (1);
125 
126 	/* Check PLL lock status */
127 	lock_0 = readl(DENALI_PHY_1564) & 0xffff;
128 	lock_1 = (readl(DENALI_PHY_1564) >> 16) & 0xffff;
129 	lock_2 = readl(DENALI_PHY_1565) & 0xffff;
130 
131 	if ((lock_0 & 0x3) != 0x3 || (lock_1 & 0x3) != 0x3 || (lock_2 & 0x3) != 0x3) {
132 		printf("De-Skew PLL failed to lock\n");
133 		printf("lock_0=0x%x, lock_1=0x%x, lock_2=0x%x\n", lock_0, lock_1, lock_2);
134 		return -1;
135 	}
136 
137 	printf("De-Skew PLL is locked and ready\n");
138 	return 0;
139 }
140 
ddr_init(struct dram_timing_info2 * dram_timing)141 int ddr_init(struct dram_timing_info2 *dram_timing)
142 {
143 	int i;
144 
145 	debug("%s\n", __func__);
146 
147 	set_ddr_clk(dram_timing->fsp_table[0] >> 1); /* Set to boot freq */
148 
149 	/* Initialize CTL registers */
150 	for (i = 0; i < dram_timing->ctl_cfg_num; i++)
151 		writel(dram_timing->ctl_cfg[i].val, (ulong)dram_timing->ctl_cfg[i].reg);
152 
153 	/* Initialize PI registers */
154 	for (i = 0; i < dram_timing->pi_cfg_num; i++)
155 		writel(dram_timing->pi_cfg[i].val, (ulong)dram_timing->pi_cfg[i].reg);
156 
157 	/* Write PHY regiters for all 3 frequency points (48Mhz/384Mhz/528Mhz): f1_index=0 */
158 	writel(PHY_FREQ_SEL_MULTICAST_EN(1) | PHY_FREQ_SEL_INDEX(0), DENALI_PHY_1537);
159 	for (i = 0; i < dram_timing->phy_f1_cfg_num; i++)
160 		writel(dram_timing->phy_f1_cfg[i].val, (ulong)dram_timing->phy_f1_cfg[i].reg);
161 
162 	/* Write PHY regiters for freqency point 2 (528Mhz): f2_index=1 */
163 	writel(PHY_FREQ_SEL_MULTICAST_EN(0) | PHY_FREQ_SEL_INDEX(1), DENALI_PHY_1537);
164 	for (i = 0; i < dram_timing->phy_f2_cfg_num; i++)
165 		writel(dram_timing->phy_f2_cfg[i].val, (ulong)dram_timing->phy_f2_cfg[i].reg);
166 
167 	/* Re-enable MULTICAST mode */
168 	writel(PHY_FREQ_SEL_MULTICAST_EN(1) | PHY_FREQ_SEL_INDEX(0), DENALI_PHY_1537);
169 
170 	return ddr_calibration(dram_timing->fsp_table);
171 }
172 
enable_bypass_mode(void)173 void enable_bypass_mode(void)
174 {
175 	u32 reg_val;
176 
177 	/* PI_INIT_LVL_EN=0x0 (DENALI_PI_04) */
178 	reg_val = readl(DENALI_PI_04) & ~0x1;
179 	writel(reg_val, DENALI_PI_04);
180 
181 	/* PI_FREQ_MAP=0x1 (DENALI_PI_12) */
182 	writel(0x1, DENALI_PI_12);
183 
184 	/* PI_INIT_WORK_FREQ=0x0 (DENALI_PI_11) */
185 	reg_val = readl(DENALI_PI_11) & ~(0x1f << 8);
186 	writel(reg_val, DENALI_PI_11);
187 
188 	/* DFIBUS_FREQ_INIT=0x0 (DENALI_CTL_23) */
189 	reg_val = readl(DENALI_CTL_23) & ~(0x3 << 24);
190 	writel(reg_val, DENALI_CTL_23);
191 
192 	/* PHY_LP4_BOOT_DISABLE=0x0 (DENALI_PHY_1547) */
193 	reg_val = readl(DENALI_PHY_1547) & ~(0x1 << 8);
194 	writel(reg_val, DENALI_PHY_1547);
195 
196 	/* PHY_PLL_BYPASS=0x1 (DENALI_PHY_1624) */
197 	reg_val = readl(DENALI_PHY_1624) | 0x1;
198 	writel(reg_val, DENALI_PHY_1624);
199 
200 	/* PHY_LP4_BOOT_PLL_BYPASS to 0x1 (DENALI_PHY_1555) */
201 	reg_val = readl(DENALI_PHY_1555) | 0x1;
202 	writel(reg_val, DENALI_PHY_1555);
203 
204 	/* FREQ_CHANGE_TYPE_F0 = 0x0/FREQ_CHANGE_TYPE_F1 = 0x1/FREQ_CHANGE_TYPE_F2 = 0x2 */
205 	reg_val = 0x020100;
206 	writel(reg_val, DENALI_CTL_25);
207 }
208