1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2019
4  * Author(s): Giulio Benetti <giulio.benetti@benettiengineering.com>
5  */
6 
7 #include <common.h>
8 #include <clk.h>
9 #include <dm.h>
10 #include <dm/device_compat.h>
11 #include <init.h>
12 #include <log.h>
13 #include <ram.h>
14 #include <asm/io.h>
15 #include <linux/bitops.h>
16 #include <linux/delay.h>
17 #include <linux/err.h>
18 
19 /* SDRAM Command Code */
20 #define SD_CC_ARD		0x0     /* Master Bus (AXI) command - Read */
21 #define SD_CC_AWR		0x1     /* Master Bus (AXI) command - Write */
22 #define SD_CC_IRD		0x8     /* IP command - Read */
23 #define SD_CC_IWR		0x9     /* IP command - Write */
24 #define SD_CC_IMS		0xA     /* IP command - Set Mode Register */
25 #define SD_CC_IACT		0xB     /* IP command - ACTIVE */
26 #define SD_CC_IAF		0xC     /* IP command - Auto Refresh */
27 #define SD_CC_ISF		0xD     /* IP Command - Self Refresh */
28 #define SD_CC_IPRE		0xE     /* IP command - Precharge */
29 #define SD_CC_IPREA		0xF     /* IP command - Precharge ALL */
30 
31 #define SEMC_MCR_MDIS		BIT(1)
32 #define SEMC_MCR_DQSMD		BIT(2)
33 
34 #define SEMC_INTR_IPCMDERR	BIT(1)
35 #define SEMC_INTR_IPCMDDONE	BIT(0)
36 
37 #define SEMC_IPCMD_KEY		0xA55A0000
38 
39 struct imxrt_semc_regs {
40 	/* 0x0 */
41 	u32 mcr;
42 	u32 iocr;
43 	u32 bmcr0;
44 	u32 bmcr1;
45 	u32 br[9];
46 
47 	/* 0x34 */
48 	u32 res1;
49 	u32 inten;
50 	u32 intr;
51 	/* 0x40 */
52 	u32 sdramcr0;
53 	u32 sdramcr1;
54 	u32 sdramcr2;
55 	u32 sdramcr3;
56 	/* 0x50 */
57 	u32 nandcr0;
58 	u32 nandcr1;
59 	u32 nandcr2;
60 	u32 nandcr3;
61 	/* 0x60 */
62 	u32 norcr0;
63 	u32 norcr1;
64 	u32 norcr2;
65 	u32 norcr3;
66 	/* 0x70 */
67 	u32 sramcr0;
68 	u32 sramcr1;
69 	u32 sramcr2;
70 	u32 sramcr3;
71 	/* 0x80 */
72 	u32 dbicr0;
73 	u32 dbicr1;
74 	u32 res2[2];
75 	/* 0x90 */
76 	u32 ipcr0;
77 	u32 ipcr1;
78 	u32 ipcr2;
79 	u32 ipcmd;
80 	/* 0xA0 */
81 	u32 iptxdat;
82 	u32 res3[3];
83 	/* 0xB0 */
84 	u32 iprxdat;
85 	u32 res4[3];
86 	/* 0xC0 */
87 	u32 sts[16];
88 };
89 
90 #if !defined(TARGET_IMXRT1170_EVK)
91 #define SEMC_IOCR_MUX_A8_SHIFT		0
92 #define SEMC_IOCR_MUX_CSX0_SHIFT	3
93 #define SEMC_IOCR_MUX_CSX1_SHIFT	6
94 #define SEMC_IOCR_MUX_CSX2_SHIFT	9
95 #define SEMC_IOCR_MUX_CSX3_SHIFT	12
96 #define SEMC_IOCR_MUX_RDY_SHIFT		15
97 #else
98 #define SEMC_IOCR_MUX_A8_SHIFT		0
99 #define SEMC_IOCR_MUX_CSX0_SHIFT	4
100 #define SEMC_IOCR_MUX_CSX1_SHIFT	8
101 #define SEMC_IOCR_MUX_CSX2_SHIFT	12
102 #define SEMC_IOCR_MUX_CSX3_SHIFT	16
103 #define SEMC_IOCR_MUX_RDY_SHIFT		20
104 #endif
105 
106 struct imxrt_sdram_mux {
107 	u8 a8;
108 	u8 csx0;
109 	u8 csx1;
110 	u8 csx2;
111 	u8 csx3;
112 	u8 rdy;
113 };
114 
115 #define SEMC_SDRAMCR0_PS_SHIFT		0
116 #define SEMC_SDRAMCR0_BL_SHIFT		4
117 #define SEMC_SDRAMCR0_COL_SHIFT		8
118 #define SEMC_SDRAMCR0_CL_SHIFT		10
119 
120 struct imxrt_sdram_control {
121 	u8 memory_width;
122 	u8 burst_len;
123 	u8 no_columns;
124 	u8 cas_latency;
125 };
126 
127 #define SEMC_SDRAMCR1_PRE2ACT_SHIFT	0
128 #define SEMC_SDRAMCR1_ACT2RW_SHIFT	4
129 #define SEMC_SDRAMCR1_RFRC_SHIFT	8
130 #define SEMC_SDRAMCR1_WRC_SHIFT		13
131 #define SEMC_SDRAMCR1_CKEOFF_SHIFT	16
132 #define SEMC_SDRAMCR1_ACT2PRE_SHIFT	20
133 
134 #define SEMC_SDRAMCR2_SRRC_SHIFT	0
135 #define SEMC_SDRAMCR2_REF2REF_SHIFT	8
136 #define SEMC_SDRAMCR2_ACT2ACT_SHIFT	16
137 #define SEMC_SDRAMCR2_ITO_SHIFT		24
138 
139 #define SEMC_SDRAMCR3_REN		BIT(0)
140 #define SEMC_SDRAMCR3_REBL_SHIFT	1
141 #define SEMC_SDRAMCR3_PRESCALE_SHIFT	8
142 #define SEMC_SDRAMCR3_RT_SHIFT		16
143 #define SEMC_SDRAMCR3_UT_SHIFT		24
144 
145 struct imxrt_sdram_timing {
146 	u8 pre2act;
147 	u8 act2rw;
148 	u8 rfrc;
149 	u8 wrc;
150 	u8 ckeoff;
151 	u8 act2pre;
152 
153 	u8 srrc;
154 	u8 ref2ref;
155 	u8 act2act;
156 	u8 ito;
157 
158 	u8 rebl;
159 	u8 prescale;
160 	u8 rt;
161 	u8 ut;
162 };
163 
164 enum imxrt_semc_bank {
165 	SDRAM_BANK1,
166 	SDRAM_BANK2,
167 	SDRAM_BANK3,
168 	SDRAM_BANK4,
169 	MAX_SDRAM_BANK,
170 };
171 
172 #define SEMC_BR_VLD_MASK		1
173 #define SEMC_BR_MS_SHIFT		1
174 
175 struct bank_params {
176 	enum imxrt_semc_bank target_bank;
177 	u32 base_address;
178 	u32 memory_size;
179 };
180 
181 struct imxrt_sdram_params {
182 	struct imxrt_semc_regs *base;
183 
184 	struct imxrt_sdram_mux *sdram_mux;
185 	struct imxrt_sdram_control *sdram_control;
186 	struct imxrt_sdram_timing *sdram_timing;
187 
188 	struct bank_params bank_params[MAX_SDRAM_BANK];
189 	u8 no_sdram_banks;
190 };
191 
imxrt_sdram_wait_ipcmd_done(struct imxrt_semc_regs * regs)192 static int imxrt_sdram_wait_ipcmd_done(struct imxrt_semc_regs *regs)
193 {
194 	do {
195 		readl(&regs->intr);
196 
197 		if (regs->intr & SEMC_INTR_IPCMDDONE)
198 			return 0;
199 		if (regs->intr & SEMC_INTR_IPCMDERR)
200 			return -EIO;
201 
202 		mdelay(50);
203 	} while (1);
204 }
205 
imxrt_sdram_ipcmd(struct imxrt_semc_regs * regs,u32 mem_addr,u32 ipcmd,u32 wd,u32 * rd)206 static int imxrt_sdram_ipcmd(struct imxrt_semc_regs *regs, u32 mem_addr,
207 			     u32 ipcmd, u32 wd, u32 *rd)
208 {
209 	int ret;
210 
211 	if (ipcmd == SD_CC_IWR || ipcmd == SD_CC_IMS)
212 		writel(wd, &regs->iptxdat);
213 
214 	/* set slave address for every command as specified on RM */
215 	writel(mem_addr, &regs->ipcr0);
216 
217 	/* execute command */
218 	writel(SEMC_IPCMD_KEY | ipcmd, &regs->ipcmd);
219 
220 	ret = imxrt_sdram_wait_ipcmd_done(regs);
221 	if (ret < 0)
222 		return ret;
223 
224 	if (ipcmd == SD_CC_IRD) {
225 		if (!rd)
226 			return -EINVAL;
227 
228 		*rd = readl(&regs->iprxdat);
229 	}
230 
231 	return 0;
232 }
233 
imxrt_sdram_init(struct udevice * dev)234 int imxrt_sdram_init(struct udevice *dev)
235 {
236 	struct imxrt_sdram_params *params = dev_get_plat(dev);
237 	struct imxrt_sdram_mux *mux = params->sdram_mux;
238 	struct imxrt_sdram_control *ctrl = params->sdram_control;
239 	struct imxrt_sdram_timing *time = params->sdram_timing;
240 	struct imxrt_semc_regs *regs = params->base;
241 	struct bank_params *bank_params;
242 	u32 rd;
243 	int i;
244 
245 	/* enable the SEMC controller */
246 	clrbits_le32(&regs->mcr, SEMC_MCR_MDIS);
247 	/* set DQS mode from DQS pad */
248 	setbits_le32(&regs->mcr, SEMC_MCR_DQSMD);
249 
250 	for (i = 0, bank_params = params->bank_params;
251 		i < params->no_sdram_banks; bank_params++,
252 		i++)
253 		writel((bank_params->base_address & 0xfffff000)
254 		       | bank_params->memory_size << SEMC_BR_MS_SHIFT
255 		       | SEMC_BR_VLD_MASK,
256 		       &regs->br[bank_params->target_bank]);
257 
258 	writel(mux->a8 << SEMC_IOCR_MUX_A8_SHIFT
259 		| mux->csx0 << SEMC_IOCR_MUX_CSX0_SHIFT
260 		| mux->csx1 << SEMC_IOCR_MUX_CSX1_SHIFT
261 		| mux->csx2 << SEMC_IOCR_MUX_CSX2_SHIFT
262 		| mux->csx3 << SEMC_IOCR_MUX_CSX3_SHIFT
263 		| mux->rdy << SEMC_IOCR_MUX_RDY_SHIFT,
264 		&regs->iocr);
265 
266 	writel(ctrl->memory_width << SEMC_SDRAMCR0_PS_SHIFT
267 		| ctrl->burst_len << SEMC_SDRAMCR0_BL_SHIFT
268 		| ctrl->no_columns << SEMC_SDRAMCR0_COL_SHIFT
269 		| ctrl->cas_latency << SEMC_SDRAMCR0_CL_SHIFT,
270 		&regs->sdramcr0);
271 
272 	writel(time->pre2act << SEMC_SDRAMCR1_PRE2ACT_SHIFT
273 		| time->act2rw << SEMC_SDRAMCR1_ACT2RW_SHIFT
274 		| time->rfrc << SEMC_SDRAMCR1_RFRC_SHIFT
275 		| time->wrc << SEMC_SDRAMCR1_WRC_SHIFT
276 		| time->ckeoff << SEMC_SDRAMCR1_CKEOFF_SHIFT
277 		| time->act2pre << SEMC_SDRAMCR1_ACT2PRE_SHIFT,
278 		&regs->sdramcr1);
279 
280 	writel(time->srrc << SEMC_SDRAMCR2_SRRC_SHIFT
281 		| time->ref2ref << SEMC_SDRAMCR2_REF2REF_SHIFT
282 		| time->act2act << SEMC_SDRAMCR2_ACT2ACT_SHIFT
283 		| time->ito << SEMC_SDRAMCR2_ITO_SHIFT,
284 		&regs->sdramcr2);
285 
286 	writel(time->rebl << SEMC_SDRAMCR3_REBL_SHIFT
287 		| time->prescale << SEMC_SDRAMCR3_PRESCALE_SHIFT
288 		| time->rt << SEMC_SDRAMCR3_RT_SHIFT
289 		| time->ut << SEMC_SDRAMCR3_UT_SHIFT
290 		| SEMC_SDRAMCR3_REN,
291 		&regs->sdramcr3);
292 
293 	writel(2, &regs->ipcr1);
294 
295 	for (i = 0, bank_params = params->bank_params;
296 		i < params->no_sdram_banks; bank_params++,
297 		i++) {
298 		mdelay(250);
299 		imxrt_sdram_ipcmd(regs, bank_params->base_address, SD_CC_IPREA,
300 				  0, &rd);
301 		imxrt_sdram_ipcmd(regs, bank_params->base_address, SD_CC_IAF,
302 				  0, &rd);
303 		imxrt_sdram_ipcmd(regs, bank_params->base_address, SD_CC_IAF,
304 				  0, &rd);
305 		imxrt_sdram_ipcmd(regs, bank_params->base_address, SD_CC_IMS,
306 				  ctrl->burst_len | (ctrl->cas_latency << 4),
307 				  &rd);
308 		mdelay(250);
309 	}
310 
311 	return 0;
312 }
313 
imxrt_semc_of_to_plat(struct udevice * dev)314 static int imxrt_semc_of_to_plat(struct udevice *dev)
315 {
316 	struct imxrt_sdram_params *params = dev_get_plat(dev);
317 	ofnode bank_node;
318 	u8 bank = 0;
319 
320 	params->sdram_mux =
321 		(struct imxrt_sdram_mux *)
322 		 dev_read_u8_array_ptr(dev,
323 				       "fsl,sdram-mux",
324 				       sizeof(struct imxrt_sdram_mux));
325 	if (!params->sdram_mux) {
326 		pr_err("fsl,sdram-mux not found");
327 		return -EINVAL;
328 	}
329 
330 	params->sdram_control =
331 		(struct imxrt_sdram_control *)
332 		 dev_read_u8_array_ptr(dev,
333 				       "fsl,sdram-control",
334 				       sizeof(struct imxrt_sdram_control));
335 	if (!params->sdram_control) {
336 		pr_err("fsl,sdram-control not found");
337 		return -EINVAL;
338 	}
339 
340 	params->sdram_timing =
341 		(struct imxrt_sdram_timing *)
342 		 dev_read_u8_array_ptr(dev,
343 				       "fsl,sdram-timing",
344 				       sizeof(struct imxrt_sdram_timing));
345 	if (!params->sdram_timing) {
346 		pr_err("fsl,sdram-timing not found");
347 		return -EINVAL;
348 	}
349 
350 	dev_for_each_subnode(bank_node, dev) {
351 		struct bank_params *bank_params;
352 		char *bank_name;
353 		int ret;
354 
355 		/* extract the bank index from DT */
356 		bank_name = (char *)ofnode_get_name(bank_node);
357 		strsep(&bank_name, "@");
358 		if (!bank_name) {
359 			pr_err("missing sdram bank index");
360 			return -EINVAL;
361 		}
362 
363 		bank_params = &params->bank_params[bank];
364 		strict_strtoul(bank_name, 10,
365 			       (unsigned long *)&bank_params->target_bank);
366 		if (bank_params->target_bank >= MAX_SDRAM_BANK) {
367 			pr_err("Found bank %d , but only bank 0,1,2,3 are supported",
368 			       bank_params->target_bank);
369 			return -EINVAL;
370 		}
371 
372 		ret = ofnode_read_u32(bank_node,
373 				      "fsl,memory-size",
374 				      &bank_params->memory_size);
375 		if (ret < 0) {
376 			pr_err("fsl,memory-size not found");
377 			return -EINVAL;
378 		}
379 
380 		ret = ofnode_read_u32(bank_node,
381 				      "fsl,base-address",
382 				      &bank_params->base_address);
383 		if (ret < 0) {
384 			pr_err("fsl,base-address not found");
385 			return -EINVAL;
386 		}
387 
388 		debug("Found bank %s %u\n", bank_name,
389 		      bank_params->target_bank);
390 		bank++;
391 	}
392 
393 	params->no_sdram_banks = bank;
394 	debug("%s, no of banks = %d\n", __func__, params->no_sdram_banks);
395 
396 	return 0;
397 }
398 
imxrt_semc_probe(struct udevice * dev)399 static int imxrt_semc_probe(struct udevice *dev)
400 {
401 	struct imxrt_sdram_params *params = dev_get_plat(dev);
402 	int ret;
403 	fdt_addr_t addr;
404 
405 	addr = dev_read_addr(dev);
406 	if (addr == FDT_ADDR_T_NONE)
407 		return -EINVAL;
408 
409 	params->base = (struct imxrt_semc_regs *)addr;
410 
411 #ifdef CONFIG_CLK
412 	struct clk clk;
413 
414 	ret = clk_get_by_index(dev, 0, &clk);
415 	if (ret < 0)
416 		return ret;
417 
418 	ret = clk_enable(&clk);
419 
420 	if (ret) {
421 		dev_err(dev, "failed to enable clock\n");
422 		return ret;
423 	}
424 #endif
425 	ret = imxrt_sdram_init(dev);
426 	if (ret)
427 		return ret;
428 
429 	return 0;
430 }
431 
imxrt_semc_get_info(struct udevice * dev,struct ram_info * info)432 static int imxrt_semc_get_info(struct udevice *dev, struct ram_info *info)
433 {
434 	return 0;
435 }
436 
437 static struct ram_ops imxrt_semc_ops = {
438 	.get_info = imxrt_semc_get_info,
439 };
440 
441 static const struct udevice_id imxrt_semc_ids[] = {
442 	{ .compatible = "fsl,imxrt-semc", .data = 0 },
443 	{ }
444 };
445 
446 U_BOOT_DRIVER(imxrt_semc) = {
447 	.name = "imxrt_semc",
448 	.id = UCLASS_RAM,
449 	.of_match = imxrt_semc_ids,
450 	.ops = &imxrt_semc_ops,
451 	.of_to_plat = imxrt_semc_of_to_plat,
452 	.probe = imxrt_semc_probe,
453 	.plat_auto	= sizeof(struct imxrt_sdram_params),
454 };
455