2 * Sun8i a33 platform dram controller init.
4 * (C) Copyright 2007-2015 Allwinner Technology Co.
5 * Jerry Wang <wangflord@allwinnertech.com>
6 * (C) Copyright 2015 Vishnu Patekar <vishnupatekar0510@gmail.com>
7 * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
9 * SPDX-License-Identifier: GPL-2.0+
14 #include <asm/arch/clock.h>
15 #include <asm/arch/dram.h>
16 #include <asm/arch/prcm.h>
18 #define DRAM_CLK_MUL 2
19 #define DRAM_CLK_DIV 1
32 static void mctl_set_cr(struct dram_para
*para
)
34 struct sunxi_mctl_com_reg
* const mctl_com
=
35 (struct sunxi_mctl_com_reg
*)SUNXI_DRAM_COM_BASE
;
37 writel(MCTL_CR_CS1_CONTROL(para
->cs1
) | MCTL_CR_UNKNOWN
|
38 MCTL_CR_CHANNEL(1) | MCTL_CR_DRAM_TYPE(para
->dram_type
) |
39 (para
->seq
? MCTL_CR_SEQUENCE
: 0) |
40 ((para
->bus_width
== 16) ? MCTL_CR_BUSW16
: MCTL_CR_BUSW8
) |
41 MCTL_CR_PAGE_SIZE(para
->page_size
) | MCTL_CR_ROW(para
->rows
) |
42 MCTL_CR_BANK(para
->bank
) | MCTL_CR_RANK(para
->rank
),
46 static void auto_detect_dram_size(struct dram_para
*para
)
48 u8 orig_rank
= para
->rank
;
52 para
->page_size
= 512;
57 for (rows
= 11 ; rows
< 16 ; rows
++) {
58 if (mctl_mem_matches(1 << (rows
+ 9))) /* row-column */
62 /* Column (page size) detect */
64 para
->page_size
= 8192;
66 for (columns
= 9 ; columns
< 13 ; columns
++) {
67 if (mctl_mem_matches(1 << columns
))
72 para
->rank
= orig_rank
;
74 para
->page_size
= 1 << columns
;
78 static inline int ns_to_t(int nanoseconds
)
80 const unsigned int ctrl_freq
=
81 CONFIG_DRAM_CLK
* DRAM_CLK_MUL
/ DRAM_CLK_DIV
;
83 return (ctrl_freq
* nanoseconds
+ 999) / 1000;
86 static void auto_set_timing_para(struct dram_para
*para
)
88 struct sunxi_mctl_ctl_reg
* const mctl_ctl
=
89 (struct sunxi_mctl_ctl_reg
*)SUNXI_DRAM_CTL0_BASE
;
94 u8 tfaw
= ns_to_t(50);
95 u8 trrd
= max(ns_to_t(10), 4);
96 u8 trcd
= ns_to_t(15);
98 u8 txp
= max(ns_to_t(8), 3);
99 u8 twtr
= max(ns_to_t(8), 4);
100 u8 trtp
= max(ns_to_t(8), 4);
101 u8 twr
= max(ns_to_t(15), 3);
102 u8 trp
= ns_to_t(15);
103 u8 tras
= ns_to_t(38);
105 u16 trefi
= ns_to_t(7800) / 32;
106 u16 trfc
= ns_to_t(350);
108 /* Fixed timing parameters */
117 u8 tcl
= 6; /* CL 12 */
118 u8 tcwl
= 4; /* CWL 8 */
122 u32 tdinit0
= (500 * CONFIG_DRAM_CLK
) + 1; /* 500us */
123 u32 tdinit1
= (360 * CONFIG_DRAM_CLK
) / 1000 + 1; /* 360ns */
124 u32 tdinit2
= (200 * CONFIG_DRAM_CLK
) + 1; /* 200us */
125 u32 tdinit3
= (1 * CONFIG_DRAM_CLK
) + 1; /* 1us */
127 u8 twtp
= tcwl
+ 2 + twr
; /* WL + BL / 2 + tWR */
128 u8 twr2rd
= tcwl
+ 2 + twtr
; /* WL + BL / 2 + tWTR */
129 u8 trd2wr
= tcl
+ 2 + 1 - tcwl
; /* RL + BL / 2 + 2 - WL */
131 /* Set work mode register */
133 /* Set mode register */
134 if (para
->dram_type
== DRAM_TYPE_DDR3
) {
135 writel(MCTL_MR0
, &mctl_ctl
->mr0
);
136 writel(MCTL_MR1
, &mctl_ctl
->mr1
);
137 writel(MCTL_MR2
, &mctl_ctl
->mr2
);
138 writel(MCTL_MR3
, &mctl_ctl
->mr3
);
139 } else if (para
->dram_type
== DRAM_TYPE_LPDDR3
) {
140 writel(MCTL_LPDDR3_MR0
, &mctl_ctl
->mr0
);
141 writel(MCTL_LPDDR3_MR1
, &mctl_ctl
->mr1
);
142 writel(MCTL_LPDDR3_MR2
, &mctl_ctl
->mr2
);
143 writel(MCTL_LPDDR3_MR3
, &mctl_ctl
->mr3
);
145 /* timing parameters for LPDDR3 */
146 tfaw
= max(ns_to_t(50), 4);
147 trrd
= max(ns_to_t(10), 2);
148 trcd
= max(ns_to_t(24), 2);
150 txp
= max(ns_to_t(8), 2);
151 twtr
= max(ns_to_t(8), 2);
152 trtp
= max(ns_to_t(8), 2);
153 trp
= max(ns_to_t(27), 2);
155 trefi
= ns_to_t(3900) / 32;
160 tcwl
= 3; /* CWL 8 */
162 tdinit0
= (200 * CONFIG_DRAM_CLK
) + 1; /* 200us */
163 tdinit1
= (100 * CONFIG_DRAM_CLK
) / 1000 + 1; /* 100ns */
164 tdinit2
= (11 * CONFIG_DRAM_CLK
) + 1; /* 200us */
165 tdinit3
= (1 * CONFIG_DRAM_CLK
) + 1; /* 1us */
166 twtp
= tcwl
+ 4 + twr
+ 1; /* CWL + BL/2 + tWR */
167 twr2rd
= tcwl
+ 4 + 1 + twtr
; /* WL + BL / 2 + tWTR */
168 trd2wr
= tcl
+ 4 + 5 - tcwl
+ 1; /* RL + BL / 2 + 2 - WL */
170 /* Set dram timing */
171 reg_val
= (twtp
<< 24) | (tfaw
<< 16) | (trasmax
<< 8) | (tras
<< 0);
172 writel(reg_val
, &mctl_ctl
->dramtmg0
);
173 reg_val
= (txp
<< 16) | (trtp
<< 8) | (trc
<< 0);
174 writel(reg_val
, &mctl_ctl
->dramtmg1
);
175 reg_val
= (tcwl
<< 24) | (tcl
<< 16) | (trd2wr
<< 8) | (twr2rd
<< 0);
176 writel(reg_val
, &mctl_ctl
->dramtmg2
);
177 reg_val
= (tmrw
<< 16) | (tmrd
<< 12) | (tmod
<< 0);
178 writel(reg_val
, &mctl_ctl
->dramtmg3
);
179 reg_val
= (trcd
<< 24) | (tccd
<< 16) | (trrd
<< 8) | (trp
<< 0);
180 writel(reg_val
, &mctl_ctl
->dramtmg4
);
181 reg_val
= (tcksrx
<< 24) | (tcksre
<< 16) | (tckesr
<< 8) | (tcke
<< 0);
182 writel(reg_val
, &mctl_ctl
->dramtmg5
);
183 /* Set two rank timing and exit self-refresh timing */
184 reg_val
= readl(&mctl_ctl
->dramtmg8
);
185 reg_val
&= ~(0xff << 8);
186 reg_val
&= ~(0xff << 0);
187 reg_val
|= (0x33 << 8);
188 reg_val
|= (0x8 << 0);
189 writel(reg_val
, &mctl_ctl
->dramtmg8
);
190 /* Set phy interface time */
191 reg_val
= (0x2 << 24) | (t_rdata_en
<< 16) | (0x1 << 8)
193 /* PHY interface write latency and read latency configure */
194 writel(reg_val
, &mctl_ctl
->pitmg0
);
195 /* Set phy time PTR0-2 use default */
196 writel(((tdinit0
<< 0) | (tdinit1
<< 20)), &mctl_ctl
->ptr3
);
197 writel(((tdinit2
<< 0) | (tdinit3
<< 20)), &mctl_ctl
->ptr4
);
198 /* Set refresh timing */
199 reg_val
= (trefi
<< 16) | (trfc
<< 0);
200 writel(reg_val
, &mctl_ctl
->rfshtmg
);
203 static void mctl_set_pir(u32 val
)
205 struct sunxi_mctl_ctl_reg
* const mctl_ctl
=
206 (struct sunxi_mctl_ctl_reg
*)SUNXI_DRAM_CTL0_BASE
;
208 writel(val
, &mctl_ctl
->pir
);
209 mctl_await_completion(&mctl_ctl
->pgsr0
, 0x1, 0x1);
212 static void mctl_data_train_cfg(struct dram_para
*para
)
214 struct sunxi_mctl_ctl_reg
* const mctl_ctl
=
215 (struct sunxi_mctl_ctl_reg
*)SUNXI_DRAM_CTL0_BASE
;
218 clrsetbits_le32(&mctl_ctl
->dtcr
, 0x3 << 24, 0x3 << 24);
220 clrsetbits_le32(&mctl_ctl
->dtcr
, 0x3 << 24, 0x1 << 24);
223 static int mctl_train_dram(struct dram_para
*para
)
225 struct sunxi_mctl_ctl_reg
* const mctl_ctl
=
226 (struct sunxi_mctl_ctl_reg
*)SUNXI_DRAM_CTL0_BASE
;
228 mctl_data_train_cfg(para
);
231 return ((readl(&mctl_ctl
->pgsr0
) >> 20) & 0xff) ? -EIO
: 0;
234 static void set_master_priority(void)
236 writel(0x00a0000d, MCTL_MASTER_CFG0(0));
237 writel(0x00500064, MCTL_MASTER_CFG1(0));
238 writel(0x07000009, MCTL_MASTER_CFG0(1));
239 writel(0x00000600, MCTL_MASTER_CFG1(1));
240 writel(0x01000009, MCTL_MASTER_CFG0(3));
241 writel(0x00000064, MCTL_MASTER_CFG1(3));
242 writel(0x08000009, MCTL_MASTER_CFG0(4));
243 writel(0x00000640, MCTL_MASTER_CFG1(4));
244 writel(0x20000308, MCTL_MASTER_CFG0(8));
245 writel(0x00001000, MCTL_MASTER_CFG1(8));
246 writel(0x02800009, MCTL_MASTER_CFG0(9));
247 writel(0x00000100, MCTL_MASTER_CFG1(9));
248 writel(0x01800009, MCTL_MASTER_CFG0(5));
249 writel(0x00000100, MCTL_MASTER_CFG1(5));
250 writel(0x01800009, MCTL_MASTER_CFG0(7));
251 writel(0x00000100, MCTL_MASTER_CFG1(7));
252 writel(0x00640009, MCTL_MASTER_CFG0(6));
253 writel(0x00000032, MCTL_MASTER_CFG1(6));
254 writel(0x0100000d, MCTL_MASTER_CFG0(2));
255 writel(0x00500080, MCTL_MASTER_CFG1(2));
258 static int mctl_channel_init(struct dram_para
*para
)
260 struct sunxi_mctl_ctl_reg
* const mctl_ctl
=
261 (struct sunxi_mctl_ctl_reg
*)SUNXI_DRAM_CTL0_BASE
;
262 struct sunxi_mctl_com_reg
* const mctl_com
=
263 (struct sunxi_mctl_com_reg
*)SUNXI_DRAM_COM_BASE
;
264 u32 low_data_lines_status
; /* Training status of datalines 0 - 7 */
265 u32 high_data_lines_status
; /* Training status of datalines 8 - 15 */
268 auto_set_timing_para(para
);
270 /* Set dram master access priority */
271 writel(0x000101a0, &mctl_com
->bwcr
);
272 /* set cpu high priority */
273 writel(0x1, &mctl_com
->mapr
);
274 set_master_priority();
277 /* Disable dram VTC */
278 clrbits_le32(&mctl_ctl
->pgcr0
, 0x3f << 0 | 0x1 << 30);
279 clrsetbits_le32(&mctl_ctl
->pgcr1
, 0x1 << 24, 0x1 << 26);
281 writel(0x94be6fa3, MCTL_PROTECT
);
283 clrsetbits_le32(MX_UPD2
, 0xfff << 16, 0x50 << 16);
284 writel(0x0, MCTL_PROTECT
);
289 if (IS_ENABLED(CONFIG_DRAM_ODT_EN
))
294 for (i
= 0 ; i
< 11 ; i
++) {
295 clrsetbits_le32(DATX0IOCR(i
), (0x3 << 24) | (0x3 << 16),
297 clrsetbits_le32(DATX1IOCR(i
), (0x3 << 24) | (0x3 << 16),
299 clrsetbits_le32(DATX2IOCR(i
), (0x3 << 24) | (0x3 << 16),
301 clrsetbits_le32(DATX3IOCR(i
), (0x3 << 24) | (0x3 << 16),
305 for (i
= 0; i
< 31; i
++)
306 clrsetbits_le32(CAIOCR(i
), 0x3 << 26 | 0x3 << 16, 0x2 << 26);
308 /* set PLL configuration */
309 if (CONFIG_DRAM_CLK
>= 480)
310 setbits_le32(&mctl_ctl
->pllgcr
, 0x1 << 19);
312 setbits_le32(&mctl_ctl
->pllgcr
, 0x3 << 19);
314 /* Auto detect dram config, set 2 rank and 16bit bus-width */
317 para
->bus_width
= 16;
320 /* Open DQS gating */
321 clrbits_le32(&mctl_ctl
->pgcr2
, (0x3 << 6));
322 clrbits_le32(&mctl_ctl
->dqsgmr
, (0x1 << 8) | (0x7));
324 if (para
->dram_type
== DRAM_TYPE_LPDDR3
)
325 clrsetbits_le32(&mctl_ctl
->dxccr
, (0x1 << 27) | (0x3<<6) ,
327 if (readl(&mctl_com
->cr
) & 0x1)
328 writel(0x00000303, &mctl_ctl
->odtmap
);
330 writel(0x00000201, &mctl_ctl
->odtmap
);
332 mctl_data_train_cfg(para
);
334 clrsetbits_le32(ZQnPR(0), 0x000000ff, CONFIG_DRAM_ZQ
& 0xff);
335 clrsetbits_le32(ZQnPR(1), 0x000000ff, (CONFIG_DRAM_ZQ
>> 8) & 0xff);
338 if (para
->dram_type
== DRAM_TYPE_DDR3
)
339 mctl_set_pir(0x0201f3 | 0x1<<10);
341 mctl_set_pir(0x020173 | 0x1<<10);
343 /* DQS gate training */
344 if (mctl_train_dram(para
) != 0) {
345 low_data_lines_status
= (readl(DXnGSR0(0)) >> 24) & 0x03;
346 high_data_lines_status
= (readl(DXnGSR0(1)) >> 24) & 0x03;
348 if (low_data_lines_status
== 0x3)
351 /* DRAM has only one rank */
355 if (low_data_lines_status
== high_data_lines_status
)
356 goto done
; /* 16 bit bus, 1 rank */
358 if (!(low_data_lines_status
& high_data_lines_status
)) {
359 /* Retry 16 bit bus-width with CS1 set */
362 if (mctl_train_dram(para
) == 0)
366 /* Try 8 bit bus-width */
367 writel(0x0, DXnGCR0(1)); /* Disable high DQ */
371 if (mctl_train_dram(para
) != 0)
375 /* Check the dramc status */
376 mctl_await_completion(&mctl_ctl
->statr
, 0x1, 0x1);
378 /* Close DQS gating */
379 setbits_le32(&mctl_ctl
->pgcr2
, 0x3 << 6);
381 /* set PGCR3,CKE polarity */
382 writel(0x00aa0060, &mctl_ctl
->pgcr3
);
383 /* Enable master access */
384 writel(0xffffffff, &mctl_com
->maer
);
389 static void mctl_sys_init(struct dram_para
*para
)
391 struct sunxi_ccm_reg
* const ccm
=
392 (struct sunxi_ccm_reg
*)SUNXI_CCM_BASE
;
393 struct sunxi_mctl_ctl_reg
* const mctl_ctl
=
394 (struct sunxi_mctl_ctl_reg
*)SUNXI_DRAM_CTL0_BASE
;
396 clrbits_le32(&ccm
->mbus_clk_cfg
, MBUS_CLK_GATE
);
397 clrbits_le32(&ccm
->mbus_reset
, CCM_MBUS_RESET_RESET
);
398 clrbits_le32(&ccm
->ahb_gate0
, 1 << AHB_GATE_OFFSET_MCTL
);
399 clrbits_le32(&ccm
->ahb_reset0_cfg
, 1 << AHB_RESET_OFFSET_MCTL
);
400 clrbits_le32(&ccm
->pll5_cfg
, CCM_PLL5_CTRL_EN
);
402 clrbits_le32(&ccm
->dram_clk_cfg
, 0x01<<31);
404 clock_set_pll5(CONFIG_DRAM_CLK
* 1000000 * DRAM_CLK_MUL
);
406 clrsetbits_le32(&ccm
->dram_clk_cfg
, CCM_DRAMCLK_CFG_DIV_MASK
,
407 CCM_DRAMCLK_CFG_DIV(DRAM_CLK_DIV
) |
408 CCM_DRAMCLK_CFG_RST
| CCM_DRAMCLK_CFG_UPD
);
409 mctl_await_completion(&ccm
->dram_clk_cfg
, CCM_DRAMCLK_CFG_UPD
, 0);
411 setbits_le32(&ccm
->ahb_reset0_cfg
, 1 << AHB_RESET_OFFSET_MCTL
);
412 setbits_le32(&ccm
->ahb_gate0
, 1 << AHB_GATE_OFFSET_MCTL
);
413 setbits_le32(&ccm
->mbus_reset
, CCM_MBUS_RESET_RESET
);
414 setbits_le32(&ccm
->mbus_clk_cfg
, MBUS_CLK_GATE
);
417 para
->bus_width
= 16;
420 /* Set dram master access priority */
421 writel(0x0000e00f, &mctl_ctl
->clken
); /* normal */
426 unsigned long sunxi_dram_init(void)
428 struct sunxi_mctl_com_reg
* const mctl_com
=
429 (struct sunxi_mctl_com_reg
*)SUNXI_DRAM_COM_BASE
;
430 struct sunxi_mctl_ctl_reg
* const mctl_ctl
=
431 (struct sunxi_mctl_ctl_reg
*)SUNXI_DRAM_CTL0_BASE
;
433 struct dram_para para
= {
442 #if defined(CONFIG_MACH_SUN8I_A83T)
443 #if (CONFIG_DRAM_TYPE == 3) || (CONFIG_DRAM_TYPE == 7)
444 para
.dram_type
= CONFIG_DRAM_TYPE
;
446 #error Unsupported DRAM type, Please set DRAM type (3:DDR3, 7:LPDDR3)
449 setbits_le32(SUNXI_PRCM_BASE
+ 0x1e0, 0x1 << 8);
451 writel(0, (SUNXI_PRCM_BASE
+ 0x1e8));
454 mctl_sys_init(¶
);
456 if (mctl_channel_init(¶
) != 0)
459 auto_detect_dram_size(¶
);
461 /* Enable master software clk */
462 writel(readl(&mctl_com
->swonr
) | 0x3ffff, &mctl_com
->swonr
);
464 /* Set DRAM ODT MAP */
466 writel(0x00000303, &mctl_ctl
->odtmap
);
468 writel(0x00000201, &mctl_ctl
->odtmap
);
470 return para
.page_size
* (para
.bus_width
/ 8) *
471 (1 << (para
.bank
+ para
.rank
+ para
.rows
));