2 * Copyright (C) 2016 Socionext Inc.
4 * based on commit a7a36122aa072fe1bb06e02b73b3634b7a6c555a of Diag
6 * SPDX-License-Identifier: GPL-2.0+
10 #include <linux/bitops.h>
11 #include <linux/err.h>
13 #include <linux/sizes.h>
14 #include <asm/processor.h>
17 #include "ddruqphy-regs.h"
18 #include "umc64-regs.h"
33 enum dram_board { /* board type */
34 DRAM_BOARD_LD20_REF, /* LD20 reference */
35 DRAM_BOARD_LD20_GLOBAL, /* LD20 TV */
36 DRAM_BOARD_LD20_C1, /* LD20 TV C1 */
37 DRAM_BOARD_LD21_REF, /* LD21 reference */
38 DRAM_BOARD_LD21_GLOBAL, /* LD21 TV */
43 static const int ddrphy_adrctrl[DRAM_BOARD_NR][DRAM_CH_NR] = {
44 {268 - 262, 268 - 263, 268 - 378}, /* LD20 reference */
45 {268 - 262, 268 - 263, 268 - 378}, /* LD20 TV */
46 {268 - 262, 268 - 263, 268 - 378}, /* LD20 TV C1 */
47 {268 - 212, 268 - 268, /* No CH2 */}, /* LD21 reference */
48 {268 - 212, 268 - 268, /* No CH2 */}, /* LD21 TV */
51 static const int ddrphy_dlltrimclk[DRAM_BOARD_NR][DRAM_CH_NR] = {
52 {268, 268, 268}, /* LD20 reference */
53 {268, 268, 268}, /* LD20 TV */
54 {189, 189, 189}, /* LD20 TV C1 */
55 {268, 268 + 252, /* No CH2 */}, /* LD21 reference */
56 {268, 268 + 202, /* No CH2 */}, /* LD21 TV */
59 static const int ddrphy_dllrecalib[DRAM_BOARD_NR][DRAM_CH_NR] = {
60 {268 - 378, 268 - 263, 268 - 378}, /* LD20 reference */
61 {268 - 378, 268 - 263, 268 - 378}, /* LD20 TV */
62 {268 - 378, 268 - 263, 268 - 378}, /* LD20 TV C1 */
63 {268 - 212, 268 - 536, /* No CH2 */}, /* LD21 reference */
64 {268 - 212, 268 - 536, /* No CH2 */}, /* LD21 TV */
67 static const u32 ddrphy_phy_pad_ctrl[DRAM_BOARD_NR][DRAM_CH_NR] = {
68 {0x50B840B1, 0x50B840B1, 0x50B840B1}, /* LD20 reference */
69 {0x50BB40B1, 0x50BB40B1, 0x50BB40B1}, /* LD20 TV */
70 {0x50BB40B1, 0x50BB40B1, 0x50BB40B1}, /* LD20 TV C1 */
71 {0x50BB40B4, 0x50B840B1, /* No CH2 */}, /* LD21 reference */
72 {0x50BB40B4, 0x50B840B1, /* No CH2 */}, /* LD21 TV */
75 static const u32 ddrphy_scl_gate_timing[DRAM_CH_NR] = {
76 0x00000140, 0x00000180, 0x00000140
79 static const int ddrphy_op_dq_shift_val[DRAM_BOARD_NR][DRAM_CH_NR][32] = {
80 { /* LD20 reference */
82 2, 1, 0, 1, 2, 1, 1, 1,
83 2, 1, 1, 2, 1, 1, 1, 1,
84 1, 2, 1, 1, 1, 2, 1, 1,
85 2, 2, 0, 1, 1, 2, 2, 1,
88 1, 1, 0, 1, 2, 2, 1, 1,
89 1, 1, 1, 1, 1, 1, 1, 1,
90 1, 1, 0, 0, 1, 1, 0, 0,
91 0, 1, 1, 1, 2, 1, 2, 1,
94 2, 2, 0, 2, 1, 1, 2, 1,
95 1, 1, 0, 1, 1, -1, 1, 1,
96 2, 2, 2, 2, 1, 1, 1, 1,
97 1, 1, 1, 0, 2, 2, 1, 2,
102 2, 1, 0, 1, 2, 1, 1, 1,
103 2, 1, 1, 2, 1, 1, 1, 1,
104 1, 2, 1, 1, 1, 2, 1, 1,
105 2, 2, 0, 1, 1, 2, 2, 1,
108 1, 1, 0, 1, 2, 2, 1, 1,
109 1, 1, 1, 1, 1, 1, 1, 1,
110 1, 1, 0, 0, 1, 1, 0, 0,
111 0, 1, 1, 1, 2, 1, 2, 1,
114 2, 2, 0, 2, 1, 1, 2, 1,
115 1, 1, 0, 1, 1, -1, 1, 1,
116 2, 2, 2, 2, 1, 1, 1, 1,
117 1, 1, 1, 0, 2, 2, 1, 2,
122 2, 1, 0, 1, 2, 1, 1, 1,
123 2, 1, 1, 2, 1, 1, 1, 1,
124 1, 2, 1, 1, 1, 2, 1, 1,
125 2, 2, 0, 1, 1, 2, 2, 1,
128 1, 1, 0, 1, 2, 2, 1, 1,
129 1, 1, 1, 1, 1, 1, 1, 1,
130 1, 1, 0, 0, 1, 1, 0, 0,
131 0, 1, 1, 1, 2, 1, 2, 1,
134 2, 2, 0, 2, 1, 1, 2, 1,
135 1, 1, 0, 1, 1, -1, 1, 1,
136 2, 2, 2, 2, 1, 1, 1, 1,
137 1, 1, 1, 0, 2, 2, 1, 2,
140 { /* LD21 reference */
142 1, 1, 0, 1, 1, 1, 1, 1,
143 1, 0, 0, 0, 1, 1, 0, 2,
144 1, 1, 0, 0, 1, 1, 1, 1,
145 1, 0, 0, 0, 1, 0, 0, 1,
147 { 1, 0, 2, 1, 1, 1, 1, 0,
148 1, 0, 0, 1, 0, 1, 0, 0,
149 1, 0, 1, 0, 1, 1, 1, 0,
150 1, 1, 1, 1, 0, 1, 0, 0,
156 1, 1, 0, 1, 1, 1, 1, 1,
157 1, 0, 0, 0, 1, 1, 0, 2,
158 1, 1, 0, 0, 1, 1, 1, 1,
159 1, 0, 0, 0, 1, 0, 0, 1,
161 { 1, 0, 2, 1, 1, 1, 1, 0,
162 1, 0, 0, 1, 0, 1, 0, 0,
163 1, 0, 1, 0, 1, 1, 1, 0,
164 1, 1, 1, 1, 0, 1, 0, 0,
170 static int ddrphy_ip_dq_shift_val[DRAM_BOARD_NR][DRAM_CH_NR][32] = {
171 { /* LD20 reference */
173 3, 3, 3, 2, 3, 2, 0, 2,
174 2, 3, 3, 1, 2, 2, 2, 2,
175 2, 2, 2, 2, 0, 1, 1, 1,
176 2, 2, 2, 2, 3, 0, 2, 2,
179 2, 2, 1, 1, -1, 1, 1, 1,
180 2, 0, 2, 2, 2, 1, 0, 2,
181 2, 1, 2, 1, 0, 1, 1, 1,
182 2, 2, 2, 2, 2, 2, 2, 2,
185 2, 2, 3, 2, 1, 2, 2, 2,
186 2, 3, 4, 2, 3, 4, 3, 3,
187 2, 2, 1, 2, 1, 1, 1, 1,
188 2, 2, 2, 2, 1, 2, 2, 1,
193 3, 3, 3, 2, 3, 2, 0, 2,
194 2, 3, 3, 1, 2, 2, 2, 2,
195 2, 2, 2, 2, 0, 1, 1, 1,
196 2, 2, 2, 2, 3, 0, 2, 2,
199 2, 2, 1, 1, -1, 1, 1, 1,
200 2, 0, 2, 2, 2, 1, 0, 2,
201 2, 1, 2, 1, 0, 1, 1, 1,
202 2, 2, 2, 2, 2, 2, 2, 2,
205 2, 2, 3, 2, 1, 2, 2, 2,
206 2, 3, 4, 2, 3, 4, 3, 3,
207 2, 2, 1, 2, 1, 1, 1, 1,
208 2, 2, 2, 2, 1, 2, 2, 1,
213 3, 3, 3, 2, 3, 2, 0, 2,
214 2, 3, 3, 1, 2, 2, 2, 2,
215 2, 2, 2, 2, 0, 1, 1, 1,
216 2, 2, 2, 2, 3, 0, 2, 2,
219 2, 2, 1, 1, -1, 1, 1, 1,
220 2, 0, 2, 2, 2, 1, 0, 2,
221 2, 1, 2, 1, 0, 1, 1, 1,
222 2, 2, 2, 2, 2, 2, 2, 2,
225 2, 2, 3, 2, 1, 2, 2, 2,
226 2, 3, 4, 2, 3, 4, 3, 3,
227 2, 2, 1, 2, 1, 1, 1, 1,
228 2, 2, 2, 2, 1, 2, 2, 1,
231 { /* LD21 reference */
233 2, 2, 2, 2, 1, 2, 2, 2,
234 2, 3, 3, 2, 2, 2, 2, 2,
235 2, 1, 2, 2, 1, 1, 1, 1,
236 2, 2, 2, 3, 1, 2, 2, 2,
239 3, 4, 4, 1, 0, 1, 1, 1,
240 1, 2, 1, 2, 2, 3, 3, 2,
241 1, 0, 2, 1, 1, 0, 1, 0,
242 0, 1, 0, 0, 1, 1, 0, 1,
248 2, 2, 2, 2, 1, 2, 2, 2,
249 2, 3, 3, 2, 2, 2, 2, 2,
250 2, 1, 2, 2, 1, 1, 1, 1,
251 2, 2, 2, 3, 1, 2, 2, 2,
254 3, 4, 4, 1, 0, 1, 1, 1,
255 1, 2, 1, 2, 2, 3, 3, 2,
256 1, 0, 2, 1, 1, 0, 1, 0,
257 0, 1, 0, 0, 1, 1, 0, 1,
264 static void ddrphy_select_lane(void __iomem *phy_base, unsigned int lane,
267 WARN_ON(lane >= (1 << PHY_LANE_SEL_LANE_WIDTH));
268 WARN_ON(bit >= (1 << PHY_LANE_SEL_BIT_WIDTH));
270 writel((bit << PHY_LANE_SEL_BIT_SHIFT) |
271 (lane << PHY_LANE_SEL_LANE_SHIFT),
272 phy_base + PHY_LANE_SEL);
275 static void ddrphy_init(void __iomem *phy_base, enum dram_board board, int ch)
277 writel(0x0C001001, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
278 while (!(readl(phy_base + PHY_UNIQUIFY_TSMC_IO_1) & BIT(1)))
280 writel(0x0C001000, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
282 writel(0x00000000, phy_base + PHY_DLL_INCR_TRIM_3);
283 writel(0x00000000, phy_base + PHY_DLL_INCR_TRIM_1);
284 ddrphy_select_lane(phy_base, 0, 0);
285 writel(0x00000005, phy_base + PHY_DLL_TRIM_1);
286 writel(0x0000000a, phy_base + PHY_DLL_TRIM_3);
287 ddrphy_select_lane(phy_base, 6, 0);
288 writel(0x00000005, phy_base + PHY_DLL_TRIM_1);
289 writel(0x0000000a, phy_base + PHY_DLL_TRIM_3);
290 ddrphy_select_lane(phy_base, 12, 0);
291 writel(0x00000005, phy_base + PHY_DLL_TRIM_1);
292 writel(0x0000000a, phy_base + PHY_DLL_TRIM_3);
293 ddrphy_select_lane(phy_base, 18, 0);
294 writel(0x00000005, phy_base + PHY_DLL_TRIM_1);
295 writel(0x0000000a, phy_base + PHY_DLL_TRIM_3);
296 writel(0x00000001, phy_base + PHY_SCL_WINDOW_TRIM);
297 writel(0x00000000, phy_base + PHY_UNQ_ANALOG_DLL_1);
298 writel(ddrphy_phy_pad_ctrl[board][ch], phy_base + PHY_PAD_CTRL);
299 writel(0x00000070, phy_base + PHY_VREF_TRAINING);
300 writel(0x01000075, phy_base + PHY_SCL_CONFIG_1);
301 writel(0x00000501, phy_base + PHY_SCL_CONFIG_2);
302 writel(0x00000000, phy_base + PHY_SCL_CONFIG_3);
303 writel(0x000261c0, phy_base + PHY_DYNAMIC_WRITE_BIT_LVL);
304 writel(0x00000000, phy_base + PHY_SCL_CONFIG_4);
305 writel(ddrphy_scl_gate_timing[ch], phy_base + PHY_SCL_GATE_TIMING);
306 writel(0x02a000a0, phy_base + PHY_WRLVL_DYN_ODT);
307 writel(0x00840004, phy_base + PHY_WRLVL_ON_OFF);
308 writel(0x0000020d, phy_base + PHY_DLL_ADRCTRL);
309 ddrphy_select_lane(phy_base, 0, 0);
310 writel(0x0000008d, phy_base + PHY_DLL_TRIM_CLK);
311 writel(0xa800100d, phy_base + PHY_DLL_RECALIB);
312 writel(0x00005076, phy_base + PHY_SCL_LATENCY);
315 static int ddrphy_to_dly_step(void __iomem *phy_base, unsigned int freq,
320 mdl = (readl(phy_base + PHY_DLL_ADRCTRL) & PHY_DLL_ADRCTRL_MDL_MASK) >>
321 PHY_DLL_ADRCTRL_MDL_SHIFT;
323 return DIV_ROUND_CLOSEST((long)freq * delay * mdl, 2 * 1000000L);
326 static void ddrphy_set_delay(void __iomem *phy_base, unsigned int reg,
327 u32 mask, u32 incr, int dly_step)
331 tmp = readl(phy_base + reg);
333 tmp |= min_t(u32, abs(dly_step), mask);
340 writel(tmp, phy_base + reg);
343 static void ddrphy_set_dll_recalib(void __iomem *phy_base, int dly_step)
345 ddrphy_set_delay(phy_base, PHY_DLL_RECALIB,
346 PHY_DLL_RECALIB_TRIM_MASK, PHY_DLL_RECALIB_INCR,
350 static void ddrphy_set_dll_adrctrl(void __iomem *phy_base, int dly_step)
352 ddrphy_set_delay(phy_base, PHY_DLL_ADRCTRL,
353 PHY_DLL_ADRCTRL_TRIM_MASK, PHY_DLL_ADRCTRL_INCR,
357 static void ddrphy_set_dll_trim_clk(void __iomem *phy_base, int dly_step)
359 ddrphy_select_lane(phy_base, 0, 0);
361 ddrphy_set_delay(phy_base, PHY_DLL_TRIM_CLK,
362 PHY_DLL_TRIM_CLK_MASK, PHY_DLL_TRIM_CLK_INCR,
366 static void ddrphy_init_tail(void __iomem *phy_base, enum dram_board board,
367 unsigned int freq, int ch)
371 step = ddrphy_to_dly_step(phy_base, freq, ddrphy_adrctrl[board][ch]);
372 ddrphy_set_dll_adrctrl(phy_base, step);
374 step = ddrphy_to_dly_step(phy_base, freq, ddrphy_dlltrimclk[board][ch]);
375 ddrphy_set_dll_trim_clk(phy_base, step);
377 step = ddrphy_to_dly_step(phy_base, freq, ddrphy_dllrecalib[board][ch]);
378 ddrphy_set_dll_recalib(phy_base, step);
381 static void ddrphy_shift_one_dq(void __iomem *phy_base, unsigned int reg,
382 u32 mask, u32 incr, int shift_val)
387 tmp = readl(phy_base + reg);
395 tmp &= ~(incr | mask);
396 tmp |= min_t(u32, abs(val), mask);
400 writel(tmp, phy_base + reg);
403 static void ddrphy_shift_dq(void __iomem *phy_base, unsigned int reg,
404 u32 mask, u32 incr, u32 override,
405 const int *shift_val_array)
410 tmp = readl(phy_base + reg);
412 writel(tmp, phy_base + reg);
414 for (dx = 0; dx < 4; dx++) {
415 for (bit = 0; bit < 8; bit++) {
416 ddrphy_select_lane(phy_base,
417 (PHY_BITLVL_DLY_WIDTH + 1) * dx,
420 ddrphy_shift_one_dq(phy_base, reg, mask, incr,
421 shift_val_array[dx * 8 + bit]);
425 ddrphy_select_lane(phy_base, 0, 0);
428 static int ddrphy_training(void __iomem *phy_base, enum dram_board board,
431 writel(0x0000000f, phy_base + PHY_WRLVL_AUTOINC_TRIM);
432 writel(0x00010000, phy_base + PHY_DLL_TRIM_2);
433 writel(0x50000000, phy_base + PHY_SCL_START);
435 while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE)
438 writel(0x00000000, phy_base + PHY_DISABLE_GATING_FOR_SCL);
439 writel(0xff00ff00, phy_base + PHY_SCL_DATA_0);
440 writel(0xff00ff00, phy_base + PHY_SCL_DATA_1);
441 writel(0xFBF8FFFF, phy_base + PHY_SCL_START_ADDR);
442 writel(0x11000000, phy_base + PHY_SCL_START);
444 while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE)
447 writel(0xFBF0FFFF, phy_base + PHY_SCL_START_ADDR);
448 writel(0x30500000, phy_base + PHY_SCL_START);
450 while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE)
453 writel(0x00000001, phy_base + PHY_DISABLE_GATING_FOR_SCL);
454 writel(0x00000010, phy_base + PHY_SCL_MAIN_CLK_DELTA);
455 writel(0x789b3de0, phy_base + PHY_SCL_DATA_0);
456 writel(0xf10e4a56, phy_base + PHY_SCL_DATA_1);
457 writel(0x11000000, phy_base + PHY_SCL_START);
459 while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE)
462 writel(0x34000000, phy_base + PHY_SCL_START);
464 while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE)
467 writel(0x00000003, phy_base + PHY_DISABLE_GATING_FOR_SCL);
469 writel(0x000261c0, phy_base + PHY_DYNAMIC_WRITE_BIT_LVL);
470 writel(0x00003270, phy_base + PHY_DYNAMIC_BIT_LVL);
471 writel(0x011BD0C4, phy_base + PHY_DSCL_CNT);
473 /* shift ip_dq trim */
474 ddrphy_shift_dq(phy_base,
475 PHY_IP_DQ_DQS_BITWISE_TRIM,
476 PHY_IP_DQ_DQS_BITWISE_TRIM_MASK,
477 PHY_IP_DQ_DQS_BITWISE_TRIM_INC,
478 PHY_IP_DQ_DQS_BITWISE_TRIM_OVERRIDE,
479 ddrphy_ip_dq_shift_val[board][ch]);
481 /* shift op_dq trim */
482 ddrphy_shift_dq(phy_base,
483 PHY_OP_DQ_DM_DQS_BITWISE_TRIM,
484 PHY_OP_DQ_DM_DQS_BITWISE_TRIM_MASK,
485 PHY_OP_DQ_DM_DQS_BITWISE_TRIM_INC,
486 PHY_OP_DQ_DM_DQS_BITWISE_TRIM_OVERRIDE,
487 ddrphy_op_dq_shift_val[board][ch]);
493 static const u32 umc_initctla[DRAM_FREQ_NR] = {0x71016D11};
494 static const u32 umc_initctlb[DRAM_FREQ_NR] = {0x07E390AC};
495 static const u32 umc_initctlc[DRAM_FREQ_NR] = {0x00FF00FF};
496 static const u32 umc_drmmr0[DRAM_FREQ_NR] = {0x00000114};
497 static const u32 umc_drmmr2[DRAM_FREQ_NR] = {0x000002a0};
499 static const u32 umc_memconf0a[DRAM_FREQ_NR][DRAM_SZ_NR] = {
501 {0x00000601, 0x00000801}, /* 1866 MHz */
504 static const u32 umc_memconf0b[DRAM_FREQ_NR][DRAM_SZ_NR] = {
506 {0x00000120, 0x00000130}, /* 1866 MHz */
509 static const u32 umc_memconfch[DRAM_FREQ_NR][DRAM_SZ_NR] = {
511 {0x00033603, 0x00033803}, /* 1866 MHz */
514 static const u32 umc_cmdctla[DRAM_FREQ_NR] = {0x060D0D20};
515 static const u32 umc_cmdctlb[DRAM_FREQ_NR] = {0x2D211C08};
516 static const u32 umc_cmdctlc[DRAM_FREQ_NR] = {0x00150C04};
517 static const u32 umc_cmdctle[DRAM_FREQ_NR][DRAM_SZ_NR] = {
519 {0x0049071D, 0x0078071D}, /* 1866 MHz */
522 static const u32 umc_rdatactl[DRAM_FREQ_NR] = {0x00000610};
523 static const u32 umc_wdatactl[DRAM_FREQ_NR] = {0x00000204};
524 static const u32 umc_odtctl[DRAM_FREQ_NR] = {0x02000002};
525 static const u32 umc_dataset[DRAM_FREQ_NR] = {0x04000000};
527 static const u32 umc_flowctla[DRAM_FREQ_NR] = {0x0081E01E};
528 static const u32 umc_directbusctrla[DRAM_CH_NR] = {
529 0x00000000, 0x00000001, 0x00000001
532 static void umc_poll_phy_init_complete(void __iomem *dc_base)
534 /* Wait for PHY Init Complete */
535 while (!(readl(dc_base + UMC_DFISTCTLC) & BIT(0)))
539 static int umc_dc_init(void __iomem *dc_base, unsigned int freq,
540 unsigned long size, int ch)
542 enum dram_freq freq_e;
543 enum dram_size size_e;
547 freq_e = DRAM_FREQ_1866M;
550 pr_err("unsupported DRAM frequency %ud MHz\n", freq);
558 size_e = DRAM_SZ_256M;
561 size_e = DRAM_SZ_512M;
564 pr_err("unsupported DRAM size 0x%08lx (per 16bit) for ch%d\n",
569 writel(0x00000001, dc_base + UMC_DFICSOVRRD);
570 writel(0x00000000, dc_base + UMC_DFITURNOFF);
572 writel(umc_initctla[freq_e], dc_base + UMC_INITCTLA);
573 writel(umc_initctlb[freq_e], dc_base + UMC_INITCTLB);
574 writel(umc_initctlc[freq_e], dc_base + UMC_INITCTLC);
576 writel(umc_drmmr0[freq_e], dc_base + UMC_DRMMR0);
577 writel(0x00000004, dc_base + UMC_DRMMR1);
578 writel(umc_drmmr2[freq_e], dc_base + UMC_DRMMR2);
579 writel(0x00000000, dc_base + UMC_DRMMR3);
581 writel(umc_memconf0a[freq_e][size_e], dc_base + UMC_MEMCONF0A);
582 writel(umc_memconf0b[freq_e][size_e], dc_base + UMC_MEMCONF0B);
583 writel(umc_memconfch[freq_e][size_e], dc_base + UMC_MEMCONFCH);
584 writel(0x00000008, dc_base + UMC_MEMMAPSET);
586 writel(umc_cmdctla[freq_e], dc_base + UMC_CMDCTLA);
587 writel(umc_cmdctlb[freq_e], dc_base + UMC_CMDCTLB);
588 writel(umc_cmdctlc[freq_e], dc_base + UMC_CMDCTLC);
589 writel(umc_cmdctle[freq_e][size_e], dc_base + UMC_CMDCTLE);
591 writel(umc_rdatactl[freq_e], dc_base + UMC_RDATACTL_D0);
592 writel(umc_rdatactl[freq_e], dc_base + UMC_RDATACTL_D1);
594 writel(umc_wdatactl[freq_e], dc_base + UMC_WDATACTL_D0);
595 writel(umc_wdatactl[freq_e], dc_base + UMC_WDATACTL_D1);
596 writel(umc_odtctl[freq_e], dc_base + UMC_ODTCTL_D0);
597 writel(umc_odtctl[freq_e], dc_base + UMC_ODTCTL_D1);
598 writel(umc_dataset[freq_e], dc_base + UMC_DATASET);
600 writel(0x00400020, dc_base + UMC_DCCGCTL);
601 writel(0x00000003, dc_base + UMC_ACSSETA);
602 writel(0x00000103, dc_base + UMC_FLOWCTLG);
603 writel(0x00010200, dc_base + UMC_ACSSETB);
605 writel(umc_flowctla[freq_e], dc_base + UMC_FLOWCTLA);
606 writel(0x00004444, dc_base + UMC_FLOWCTLC);
607 writel(0x00000000, dc_base + UMC_DFICUPDCTLA);
609 writel(0x00202000, dc_base + UMC_FLOWCTLB);
610 writel(0x00000000, dc_base + UMC_BSICMAPSET);
611 writel(0x00000000, dc_base + UMC_ERRMASKA);
612 writel(0x00000000, dc_base + UMC_ERRMASKB);
614 writel(umc_directbusctrla[ch], dc_base + UMC_DIRECTBUSCTRLA);
616 writel(0x00000001, dc_base + UMC_INITSET);
617 /* Wait for PHY Init Complete */
618 while (readl(dc_base + UMC_INITSTAT) & BIT(0))
621 writel(0x2A0A0A00, dc_base + UMC_SPCSETB);
622 writel(0x00000000, dc_base + UMC_DFICSOVRRD);
627 static int umc_ch_init(void __iomem *umc_ch_base, void __iomem *phy_ch_base,
628 enum dram_board board, unsigned int freq,
629 unsigned long size, int ch)
631 void __iomem *dc_base = umc_ch_base + 0x00011000;
632 void __iomem *phy_base = phy_ch_base;
635 /* PHY Update Mode (ON) */
636 writel(0x8000003f, dc_base + UMC_DFIPUPDCTLA);
638 /* deassert PHY reset signals */
639 writel(UMC_DIOCTLA_CTL_NRST | UMC_DIOCTLA_CFG_NRST,
640 dc_base + UMC_DIOCTLA);
642 ddrphy_init(phy_base, board, ch);
644 umc_poll_phy_init_complete(dc_base);
646 ddrphy_init_tail(phy_base, board, freq, ch);
648 ret = umc_dc_init(dc_base, freq, size, ch);
652 ret = ddrphy_training(phy_base, board, ch);
659 static void um_init(void __iomem *um_base)
661 writel(0x000000ff, um_base + UMC_MBUS0);
662 writel(0x000000ff, um_base + UMC_MBUS1);
663 writel(0x000000ff, um_base + UMC_MBUS2);
664 writel(0x00000001, um_base + UMC_MBUS3);
665 writel(0x00000001, um_base + UMC_MBUS4);
666 writel(0x00000001, um_base + UMC_MBUS5);
667 writel(0x00000001, um_base + UMC_MBUS6);
668 writel(0x00000001, um_base + UMC_MBUS7);
669 writel(0x00000001, um_base + UMC_MBUS8);
670 writel(0x00000001, um_base + UMC_MBUS9);
671 writel(0x00000001, um_base + UMC_MBUS10);
674 int uniphier_ld20_umc_init(const struct uniphier_board_data *bd)
676 void __iomem *um_base = (void __iomem *)0x5b600000;
677 void __iomem *umc_ch_base = (void __iomem *)0x5b800000;
678 void __iomem *phy_ch_base = (void __iomem *)0x6e200000;
679 enum dram_board board;
682 switch (UNIPHIER_BD_BOARD_GET_TYPE(bd->flags)) {
683 case UNIPHIER_BD_BOARD_LD20_REF:
684 board = DRAM_BOARD_LD20_REF;
686 case UNIPHIER_BD_BOARD_LD20_GLOBAL:
687 board = DRAM_BOARD_LD20_GLOBAL;
689 case UNIPHIER_BD_BOARD_LD20_C1:
690 board = DRAM_BOARD_LD20_C1;
692 case UNIPHIER_BD_BOARD_LD21_REF:
693 board = DRAM_BOARD_LD21_REF;
695 case UNIPHIER_BD_BOARD_LD21_GLOBAL:
696 board = DRAM_BOARD_LD21_GLOBAL;
699 pr_err("unsupported board type %d\n",
700 UNIPHIER_BD_BOARD_GET_TYPE(bd->flags));
704 for (ch = 0; ch < bd->dram_nr_ch; ch++) {
705 unsigned long size = bd->dram_ch[ch].size;
706 unsigned int width = bd->dram_ch[ch].width;
708 ret = umc_ch_init(umc_ch_base, phy_ch_base, board,
709 bd->dram_freq, size / (width / 16), ch);
711 pr_err("failed to initialize UMC ch%d\n", ch);
715 umc_ch_base += 0x00200000;
716 phy_ch_base += 0x00004000;