• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Texas Instruments' J721E DDRSS driver
4  *
5  * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
6  */
7 
8 #include <common.h>
9 #include <clk.h>
10 #include <dm.h>
11 #include <ram.h>
12 #include <asm/io.h>
13 #include <power-domain.h>
14 #include <wait_bit.h>
15 
16 #include "lpddr4_obj_if.h"
17 #include "lpddr4_if.h"
18 #include "lpddr4_structs_if.h"
19 #include "lpddr4_ctl_regs.h"
20 
21 #define SRAM_MAX 512
22 
23 #define CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS	0x80
24 #define CTRLMMR_DDR4_FSP_CLKCHNG_ACK_OFFS	0xc0
25 
26 struct j721e_ddrss_desc {
27 	struct udevice *dev;
28 	void __iomem *ddrss_ss_cfg;
29 	void __iomem *ddrss_ctrl_mmr;
30 	struct power_domain ddrcfg_pwrdmn;
31 	struct power_domain ddrdata_pwrdmn;
32 	struct clk ddr_clk;
33 	struct clk osc_clk;
34 	u32 ddr_freq1;
35 	u32 ddr_freq2;
36 	u32 ddr_fhs_cnt;
37 };
38 
39 static LPDDR4_OBJ *driverdt;
40 static lpddr4_config config;
41 static lpddr4_privatedata pd;
42 
43 static struct j721e_ddrss_desc *ddrss;
44 
45 #define TH_MACRO_EXP(fld, str) (fld##str)
46 
47 #define TH_FLD_MASK(fld)  TH_MACRO_EXP(fld, _MASK)
48 #define TH_FLD_SHIFT(fld) TH_MACRO_EXP(fld, _SHIFT)
49 #define TH_FLD_WIDTH(fld) TH_MACRO_EXP(fld, _WIDTH)
50 #define TH_FLD_WOCLR(fld) TH_MACRO_EXP(fld, _WOCLR)
51 #define TH_FLD_WOSET(fld) TH_MACRO_EXP(fld, _WOSET)
52 
53 #define str(s) #s
54 #define xstr(s) str(s)
55 
56 #define  CTL_SHIFT 11
57 #define  PHY_SHIFT 11
58 #define  PI_SHIFT 10
59 
60 #define TH_OFFSET_FROM_REG(REG, SHIFT, offset) do {\
61 	char *i, *pstr= xstr(REG); offset = 0;\
62 	for (i = &pstr[SHIFT]; *i != '\0'; ++i) {\
63 		offset = offset * 10 + (*i - '0'); }\
64 	} while (0)
65 
j721e_lpddr4_ack_freq_upd_req(void)66 static void j721e_lpddr4_ack_freq_upd_req(void)
67 {
68 	unsigned int req_type, counter;
69 
70 	debug("--->>> LPDDR4 Initialization is in progress ... <<<---\n");
71 
72 	for (counter = 0; counter < ddrss->ddr_fhs_cnt; counter++) {
73 		if (wait_for_bit_le32(ddrss->ddrss_ctrl_mmr +
74 				      CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS, 0x80,
75 				      true, 10000, false)) {
76 			printf("Timeout during frequency handshake\n");
77 			hang();
78 		}
79 
80 		req_type = readl(ddrss->ddrss_ctrl_mmr +
81 				 CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS) & 0x03;
82 
83 		debug("%s: received freq change req: req type = %d, req no. = %d \n",
84 		      __func__, req_type, counter);
85 
86 		if (req_type == 1)
87 			clk_set_rate(&ddrss->ddr_clk, ddrss->ddr_freq1);
88 		else if (req_type == 2)
89 			clk_set_rate(&ddrss->ddr_clk, ddrss->ddr_freq2);
90 		else if (req_type == 0)
91 			/* Put DDR pll in bypass mode */
92 			clk_set_rate(&ddrss->ddr_clk,
93 				     clk_get_rate(&ddrss->osc_clk));
94 		else
95 			printf("%s: Invalid freq request type\n", __func__);
96 
97 		writel(0x1, ddrss->ddrss_ctrl_mmr +
98 		       CTRLMMR_DDR4_FSP_CLKCHNG_ACK_OFFS);
99 		if (wait_for_bit_le32(ddrss->ddrss_ctrl_mmr +
100 				      CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS, 0x80,
101 				      false, 10, false)) {
102 			printf("Timeout during frequency handshake\n");
103 			hang();
104 		}
105 		writel(0x0, ddrss->ddrss_ctrl_mmr +
106 		       CTRLMMR_DDR4_FSP_CLKCHNG_ACK_OFFS);
107 	}
108 }
109 
j721e_lpddr4_info_handler(const lpddr4_privatedata * pd,lpddr4_infotype infotype)110 static void j721e_lpddr4_info_handler(const lpddr4_privatedata * pd,
111 				      lpddr4_infotype infotype)
112 {
113 	if (infotype == LPDDR4_DRV_SOC_PLL_UPDATE) {
114 		j721e_lpddr4_ack_freq_upd_req();
115 	}
116 }
117 
j721e_ddrss_power_on(struct j721e_ddrss_desc * ddrss)118 static int j721e_ddrss_power_on(struct j721e_ddrss_desc *ddrss)
119 {
120 	int ret;
121 
122 	debug("%s(ddrss=%p)\n", __func__, ddrss);
123 
124 	ret = power_domain_on(&ddrss->ddrcfg_pwrdmn);
125 	if (ret) {
126 		dev_err(ddrss->dev, "power_domain_on() failed: %d\n", ret);
127 		return ret;
128 	}
129 
130 	ret = power_domain_on(&ddrss->ddrdata_pwrdmn);
131 	if (ret) {
132 		dev_err(ddrss->dev, "power_domain_on() failed: %d\n", ret);
133 		return ret;
134 	}
135 
136 	return 0;
137 }
138 
j721e_ddrss_ofdata_to_priv(struct udevice * dev)139 static int j721e_ddrss_ofdata_to_priv(struct udevice *dev)
140 {
141 	struct j721e_ddrss_desc *ddrss = dev_get_priv(dev);
142 	phys_addr_t reg;
143 	int ret;
144 
145 	debug("%s(dev=%p)\n", __func__, dev);
146 
147 	reg = dev_read_addr_name(dev, "cfg");
148 	if (reg == FDT_ADDR_T_NONE) {
149 		dev_err(dev, "No reg property for DDRSS wrapper logic\n");
150 		return -EINVAL;
151 	}
152 	ddrss->ddrss_ss_cfg = (void *)reg;
153 
154 	reg = dev_read_addr_name(dev, "ctrl_mmr_lp4");
155 	if (reg == FDT_ADDR_T_NONE) {
156 		dev_err(dev, "No reg property for CTRL MMR\n");
157 		return -EINVAL;
158 	}
159 	ddrss->ddrss_ctrl_mmr = (void *)reg;
160 
161 	ret = power_domain_get_by_index(dev, &ddrss->ddrcfg_pwrdmn, 0);
162 	if (ret) {
163 		dev_err(dev, "power_domain_get() failed: %d\n", ret);
164 		return ret;
165 	}
166 
167 	ret = power_domain_get_by_index(dev, &ddrss->ddrdata_pwrdmn, 1);
168 	if (ret) {
169 		dev_err(dev, "power_domain_get() failed: %d\n", ret);
170 		return ret;
171 	}
172 
173 	ret = clk_get_by_index(dev, 0, &ddrss->ddr_clk);
174 	if (ret)
175 		dev_err(dev, "clk get failed%d\n", ret);
176 
177 	ret = clk_get_by_index(dev, 1, &ddrss->osc_clk);
178 	if (ret)
179 		dev_err(dev, "clk get failed for osc clk %d\n", ret);
180 
181 	ret = dev_read_u32(dev, "ti,ddr-freq1", &ddrss->ddr_freq1);
182 	if (ret)
183 		dev_err(dev, "ddr freq1 not populated %d\n", ret);
184 
185 	ret = dev_read_u32(dev, "ti,ddr-freq2", &ddrss->ddr_freq2);
186 	if (ret)
187 		dev_err(dev, "ddr freq2 not populated %d\n", ret);
188 
189 	ret = dev_read_u32(dev, "ti,ddr-fhs-cnt", &ddrss->ddr_fhs_cnt);
190 	if (ret)
191 		dev_err(dev, "ddr fhs cnt not populated %d\n", ret);
192 
193 	/* Put DDR pll in bypass mode */
194 	ret = clk_set_rate(&ddrss->ddr_clk, clk_get_rate(&ddrss->osc_clk));
195 	if (ret)
196 		dev_err(dev, "ddr clk bypass failed\n");
197 
198 	return ret;
199 }
200 
j721e_lpddr4_probe(void)201 void j721e_lpddr4_probe(void)
202 {
203 	uint32_t status = 0U;
204 	uint16_t configsize = 0U;
205 
206 	status = driverdt->probe(&config, &configsize);
207 
208 	if ((status != 0) || (configsize != sizeof(lpddr4_privatedata))
209 	    || (configsize > SRAM_MAX)) {
210 		printf("LPDDR4_Probe: FAIL\n");
211 		hang();
212 	} else {
213 		debug("LPDDR4_Probe: PASS\n");
214 	}
215 }
216 
j721e_lpddr4_init(void)217 void j721e_lpddr4_init(void)
218 {
219 	uint32_t status = 0U;
220 
221 	if ((sizeof(pd) != sizeof(lpddr4_privatedata))
222 	    || (sizeof(pd) > SRAM_MAX)) {
223 		printf("LPDDR4_Init: FAIL\n");
224 		hang();
225 	}
226 
227 	config.ctlbase = (struct lpddr4_ctlregs_s *)ddrss->ddrss_ss_cfg;
228 	config.infohandler = (lpddr4_infocallback) j721e_lpddr4_info_handler;
229 
230 	status = driverdt->init(&pd, &config);
231 
232 	if ((status > 0U) ||
233 	    (pd.ctlbase != (struct lpddr4_ctlregs_s *)config.ctlbase) ||
234 	    (pd.ctlinterrupthandler != config.ctlinterrupthandler) ||
235 	    (pd.phyindepinterrupthandler != config.phyindepinterrupthandler)) {
236 		printf("LPDDR4_Init: FAIL\n");
237 		hang();
238 	} else {
239 		debug("LPDDR4_Init: PASS\n");
240 	}
241 }
242 
populate_data_array_from_dt(lpddr4_reginitdata * reginit_data)243 void populate_data_array_from_dt(lpddr4_reginitdata * reginit_data)
244 {
245 	int ret, i;
246 
247 	ret = dev_read_u32_array(ddrss->dev, "ti,ctl-data",
248 				 (u32 *) reginit_data->denalictlreg,
249 				 LPDDR4_CTL_REG_COUNT);
250 	if (ret)
251 		printf("Error reading ctrl data\n");
252 
253 	for (i = 0; i < LPDDR4_CTL_REG_COUNT; i++)
254 		reginit_data->updatectlreg[i] = true;
255 
256 	ret = dev_read_u32_array(ddrss->dev, "ti,pi-data",
257 				 (u32 *) reginit_data->denaliphyindepreg,
258 				 LPDDR4_PHY_INDEP_REG_COUNT);
259 	if (ret)
260 		printf("Error reading PI data\n");
261 
262 	for (i = 0; i < LPDDR4_PHY_INDEP_REG_COUNT; i++)
263 		reginit_data->updatephyindepreg[i] = true;
264 
265 	ret = dev_read_u32_array(ddrss->dev, "ti,phy-data",
266 				 (u32 *) reginit_data->denaliphyreg,
267 				 LPDDR4_PHY_REG_COUNT);
268 	if (ret)
269 		printf("Error reading PHY data\n");
270 
271 	for (i = 0; i < LPDDR4_PHY_REG_COUNT; i++)
272 		reginit_data->updatephyreg[i] = true;
273 }
274 
j721e_lpddr4_hardware_reg_init(void)275 void j721e_lpddr4_hardware_reg_init(void)
276 {
277 	uint32_t status = 0U;
278 	lpddr4_reginitdata reginitdata;
279 
280 	populate_data_array_from_dt(&reginitdata);
281 
282 	status = driverdt->writectlconfig(&pd, &reginitdata);
283 	if (!status) {
284 		status = driverdt->writephyindepconfig(&pd, &reginitdata);
285 	}
286 	if (!status) {
287 		status = driverdt->writephyconfig(&pd, &reginitdata);
288 	}
289 	if (status) {
290 		printf(" ERROR: LPDDR4_HardwareRegInit failed!!\n");
291 		hang();
292 	}
293 
294 	return;
295 }
296 
j721e_lpddr4_start(void)297 void j721e_lpddr4_start(void)
298 {
299 	uint32_t status = 0U;
300 	uint32_t regval = 0U;
301 	uint32_t offset = 0U;
302 
303 	TH_OFFSET_FROM_REG(LPDDR4__START__REG, CTL_SHIFT, offset);
304 
305 	status = driverdt->readreg(&pd, LPDDR4_CTL_REGS, offset, &regval);
306 	if ((status > 0U) || ((regval & TH_FLD_MASK(LPDDR4__START__FLD)) != 0U)) {
307 		printf("LPDDR4_StartTest: FAIL\n");
308 		hang();
309 	}
310 
311 	status = driverdt->start(&pd);
312 	if (status > 0U) {
313 		printf("LPDDR4_StartTest: FAIL\n");
314 		hang();
315 	}
316 
317 	status = driverdt->readreg(&pd, LPDDR4_CTL_REGS, offset, &regval);
318 	if ((status > 0U) || ((regval & TH_FLD_MASK(LPDDR4__START__FLD)) != 1U)) {
319 		printf("LPDDR4_Start: FAIL\n");
320 		hang();
321 	} else {
322 		debug("LPDDR4_Start: PASS\n");
323 	}
324 }
325 
j721e_ddrss_probe(struct udevice * dev)326 static int j721e_ddrss_probe(struct udevice *dev)
327 {
328 	int ret;
329 	ddrss = dev_get_priv(dev);
330 
331 	debug("%s(dev=%p)\n", __func__, dev);
332 
333 	ret = j721e_ddrss_ofdata_to_priv(dev);
334 	if (ret)
335 		return ret;
336 
337 	ddrss->dev = dev;
338 	ret = j721e_ddrss_power_on(ddrss);
339 	if (ret)
340 		return ret;
341 
342 	driverdt = lpddr4_getinstance();
343 	j721e_lpddr4_probe();
344 	j721e_lpddr4_init();
345 	j721e_lpddr4_hardware_reg_init();
346 	j721e_lpddr4_start();
347 
348 	return ret;
349 }
350 
j721e_ddrss_get_info(struct udevice * dev,struct ram_info * info)351 static int j721e_ddrss_get_info(struct udevice *dev, struct ram_info *info)
352 {
353 	return 0;
354 }
355 
356 static struct ram_ops j721e_ddrss_ops = {
357 	.get_info = j721e_ddrss_get_info,
358 };
359 
360 static const struct udevice_id j721e_ddrss_ids[] = {
361 	{.compatible = "ti,j721e-ddrss"},
362 	{}
363 };
364 
365 U_BOOT_DRIVER(j721e_ddrss) = {
366 	.name = "j721e_ddrss",
367 	.id = UCLASS_RAM,
368 	.of_match = j721e_ddrss_ids,
369 	.ops = &j721e_ddrss_ops,
370 	.probe = j721e_ddrss_probe,
371 	.priv_auto_alloc_size = sizeof(struct j721e_ddrss_desc),
372 };
373