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