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