2 * Copyright (C) 2016 Socionext Inc.
4 * based on commit 9073035a9860f892f8d1345dfb0ea862b5021145 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 "ddrphy-ld20-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_LD21_REF, /* LD21 reference */
37 DRAM_BOARD_LD21_GLOBAL, /* LD21 TV */
42 static const int ddrphy_adrctrl[DRAM_BOARD_NR][DRAM_CH_NR] = {
43 {268 - 262, 268 - 263, 268 - 378}, /* LD20 reference */
44 {268 - 262, 268 - 263, 268 - 378}, /* LD20 TV */
45 {268 - 212, 268 - 268, /* No CH2 */}, /* LD21 reference */
46 {268 - 212, 268 - 268, /* No CH2 */}, /* LD21 TV */
49 static const int ddrphy_dlltrimclk[DRAM_BOARD_NR][DRAM_CH_NR] = {
50 {268, 268, 268}, /* LD20 reference */
51 {268, 268, 268}, /* LD20 TV */
52 {268, 268 + 252, /* No CH2 */}, /* LD21 reference */
53 {268, 268 + 202, /* No CH2 */}, /* LD21 TV */
56 static const int ddrphy_dllrecalib[DRAM_BOARD_NR][DRAM_CH_NR] = {
57 {268 - 378, 268 - 263, 268 - 378}, /* LD20 reference */
58 {268 - 378, 268 - 263, 268 - 378}, /* LD20 TV */
59 {268 - 212, 268 - 536, /* No CH2 */}, /* LD21 reference */
60 {268 - 212, 268 - 536, /* No CH2 */}, /* LD21 TV */
63 static const u32 ddrphy_phy_pad_ctrl[DRAM_BOARD_NR][DRAM_CH_NR] = {
64 {0x50B840B1, 0x50B840B1, 0x50B840B1}, /* LD20 reference */
65 {0x50BB40B1, 0x50BB40B1, 0x50BB40B1}, /* LD20 TV */
66 {0x50BB40B4, 0x50B840B1, /* No CH2 */}, /* LD21 reference */
67 {0x50BB40B4, 0x50B840B1, /* No CH2 */}, /* LD21 TV */
70 static const u32 ddrphy_scl_gate_timing[DRAM_CH_NR] = {
71 0x00000140, 0x00000180, 0x00000140
74 static const int ddrphy_op_dq_shift_val[DRAM_BOARD_NR][DRAM_CH_NR][32] = {
75 { /* LD20 reference */
77 2, 1, 0, 1, 2, 1, 1, 1,
78 2, 1, 1, 2, 1, 1, 1, 1,
79 1, 2, 1, 1, 1, 2, 1, 1,
80 2, 2, 0, 1, 1, 2, 2, 1,
83 1, 1, 0, 1, 2, 2, 1, 1,
84 1, 1, 1, 1, 1, 1, 1, 1,
85 1, 1, 0, 0, 1, 1, 0, 0,
86 0, 1, 1, 1, 2, 1, 2, 1,
89 2, 2, 0, 2, 1, 1, 2, 1,
90 1, 1, 0, 1, 1, -1, 1, 1,
91 2, 2, 2, 2, 1, 1, 1, 1,
92 1, 1, 1, 0, 2, 2, 1, 2,
97 2, 1, 0, 1, 2, 1, 1, 1,
98 2, 1, 1, 2, 1, 1, 1, 1,
99 1, 2, 1, 1, 1, 2, 1, 1,
100 2, 2, 0, 1, 1, 2, 2, 1,
103 1, 1, 0, 1, 2, 2, 1, 1,
104 1, 1, 1, 1, 1, 1, 1, 1,
105 1, 1, 0, 0, 1, 1, 0, 0,
106 0, 1, 1, 1, 2, 1, 2, 1,
109 2, 2, 0, 2, 1, 1, 2, 1,
110 1, 1, 0, 1, 1, -1, 1, 1,
111 2, 2, 2, 2, 1, 1, 1, 1,
112 1, 1, 1, 0, 2, 2, 1, 2,
115 { /* LD21 reference */
117 1, 1, 0, 1, 1, 1, 1, 1,
118 1, 0, 0, 0, 1, 1, 0, 2,
119 1, 1, 0, 0, 1, 1, 1, 1,
120 1, 0, 0, 0, 1, 0, 0, 1,
122 { 1, 0, 2, 1, 1, 1, 1, 0,
123 1, 0, 0, 1, 0, 1, 0, 0,
124 1, 0, 1, 0, 1, 1, 1, 0,
125 1, 1, 1, 1, 0, 1, 0, 0,
131 1, 1, 0, 1, 1, 1, 1, 1,
132 1, 0, 0, 0, 1, 1, 0, 2,
133 1, 1, 0, 0, 1, 1, 1, 1,
134 1, 0, 0, 0, 1, 0, 0, 1,
136 { 1, 0, 2, 1, 1, 1, 1, 0,
137 1, 0, 0, 1, 0, 1, 0, 0,
138 1, 0, 1, 0, 1, 1, 1, 0,
139 1, 1, 1, 1, 0, 1, 0, 0,
145 static int ddrphy_ip_dq_shift_val[DRAM_BOARD_NR][DRAM_CH_NR][32] = {
146 { /* LD20 reference */
148 3, 3, 3, 2, 3, 2, 0, 2,
149 2, 3, 3, 1, 2, 2, 2, 2,
150 2, 2, 2, 2, 0, 1, 1, 1,
151 2, 2, 2, 2, 3, 0, 2, 2,
154 2, 2, 1, 1, -1, 1, 1, 1,
155 2, 0, 2, 2, 2, 1, 0, 2,
156 2, 1, 2, 1, 0, 1, 1, 1,
157 2, 2, 2, 2, 2, 2, 2, 2,
160 2, 2, 3, 2, 1, 2, 2, 2,
161 2, 3, 4, 2, 3, 4, 3, 3,
162 2, 2, 1, 2, 1, 1, 1, 1,
163 2, 2, 2, 2, 1, 2, 2, 1,
168 3, 3, 3, 2, 3, 2, 0, 2,
169 2, 3, 3, 1, 2, 2, 2, 2,
170 2, 2, 2, 2, 0, 1, 1, 1,
171 2, 2, 2, 2, 3, 0, 2, 2,
174 2, 2, 1, 1, -1, 1, 1, 1,
175 2, 0, 2, 2, 2, 1, 0, 2,
176 2, 1, 2, 1, 0, 1, 1, 1,
177 2, 2, 2, 2, 2, 2, 2, 2,
180 2, 2, 3, 2, 1, 2, 2, 2,
181 2, 3, 4, 2, 3, 4, 3, 3,
182 2, 2, 1, 2, 1, 1, 1, 1,
183 2, 2, 2, 2, 1, 2, 2, 1,
186 { /* LD21 reference */
188 2, 2, 2, 2, 1, 2, 2, 2,
189 2, 3, 3, 2, 2, 2, 2, 2,
190 2, 1, 2, 2, 1, 1, 1, 1,
191 2, 2, 2, 3, 1, 2, 2, 2,
194 3, 4, 4, 1, 0, 1, 1, 1,
195 1, 2, 1, 2, 2, 3, 3, 2,
196 1, 0, 2, 1, 1, 0, 1, 0,
197 0, 1, 0, 0, 1, 1, 0, 1,
203 2, 2, 2, 2, 1, 2, 2, 2,
204 2, 3, 3, 2, 2, 2, 2, 2,
205 2, 1, 2, 2, 1, 1, 1, 1,
206 2, 2, 2, 3, 1, 2, 2, 2,
209 3, 4, 4, 1, 0, 1, 1, 1,
210 1, 2, 1, 2, 2, 3, 3, 2,
211 1, 0, 2, 1, 1, 0, 1, 0,
212 0, 1, 0, 0, 1, 1, 0, 1,
219 static void ddrphy_select_lane(void __iomem *phy_base, unsigned int lane,
222 WARN_ON(lane >= (1 << PHY_LANE_SEL_LANE_WIDTH));
223 WARN_ON(bit >= (1 << PHY_LANE_SEL_BIT_WIDTH));
225 writel((bit << PHY_LANE_SEL_BIT_SHIFT) |
226 (lane << PHY_LANE_SEL_LANE_SHIFT),
227 phy_base + PHY_LANE_SEL);
230 static void ddrphy_init(void __iomem *phy_base, enum dram_board board, int ch)
232 writel(0x0C001001, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
233 while (!(readl(phy_base + PHY_UNIQUIFY_TSMC_IO_1) & BIT(1)))
235 writel(0x0C001000, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
237 writel(0x00000000, phy_base + PHY_DLL_INCR_TRIM_3);
238 writel(0x00000000, phy_base + PHY_DLL_INCR_TRIM_1);
239 ddrphy_select_lane(phy_base, 0, 0);
240 writel(0x00000005, phy_base + PHY_DLL_TRIM_1);
241 writel(0x0000000a, phy_base + PHY_DLL_TRIM_3);
242 ddrphy_select_lane(phy_base, 6, 0);
243 writel(0x00000005, phy_base + PHY_DLL_TRIM_1);
244 writel(0x0000000a, phy_base + PHY_DLL_TRIM_3);
245 ddrphy_select_lane(phy_base, 12, 0);
246 writel(0x00000005, phy_base + PHY_DLL_TRIM_1);
247 writel(0x0000000a, phy_base + PHY_DLL_TRIM_3);
248 ddrphy_select_lane(phy_base, 18, 0);
249 writel(0x00000005, phy_base + PHY_DLL_TRIM_1);
250 writel(0x0000000a, phy_base + PHY_DLL_TRIM_3);
251 writel(0x00000001, phy_base + PHY_SCL_WINDOW_TRIM);
252 writel(0x00000000, phy_base + PHY_UNQ_ANALOG_DLL_1);
253 writel(ddrphy_phy_pad_ctrl[board][ch], phy_base + PHY_PAD_CTRL);
254 writel(0x00000070, phy_base + PHY_VREF_TRAINING);
255 writel(0x01000075, phy_base + PHY_SCL_CONFIG_1);
256 writel(0x00000501, phy_base + PHY_SCL_CONFIG_2);
257 writel(0x00000000, phy_base + PHY_SCL_CONFIG_3);
258 writel(0x000261c0, phy_base + PHY_DYNAMIC_WRITE_BIT_LVL);
259 writel(0x00000000, phy_base + PHY_SCL_CONFIG_4);
260 writel(ddrphy_scl_gate_timing[ch], phy_base + PHY_SCL_GATE_TIMING);
261 writel(0x02a000a0, phy_base + PHY_WRLVL_DYN_ODT);
262 writel(0x00840004, phy_base + PHY_WRLVL_ON_OFF);
263 writel(0x0000020d, phy_base + PHY_DLL_ADRCTRL);
264 ddrphy_select_lane(phy_base, 0, 0);
265 writel(0x0000008d, phy_base + PHY_DLL_TRIM_CLK);
266 writel(0xa800100d, phy_base + PHY_DLL_RECALIB);
267 writel(0x00005076, phy_base + PHY_SCL_LATENCY);
270 static int ddrphy_to_dly_step(void __iomem *phy_base, unsigned int freq,
275 mdl = (readl(phy_base + PHY_DLL_ADRCTRL) & PHY_DLL_ADRCTRL_MDL_MASK) >>
276 PHY_DLL_ADRCTRL_MDL_SHIFT;
278 return DIV_ROUND_CLOSEST((long)freq * delay * mdl, 2 * 1000000L);
281 static void ddrphy_set_delay(void __iomem *phy_base, unsigned int reg,
282 u32 mask, u32 incr, int dly_step)
286 tmp = readl(phy_base + reg);
288 tmp |= min_t(u32, abs(dly_step), mask);
295 writel(tmp, phy_base + reg);
298 static void ddrphy_set_dll_recalib(void __iomem *phy_base, int dly_step)
300 ddrphy_set_delay(phy_base, PHY_DLL_RECALIB,
301 PHY_DLL_RECALIB_TRIM_MASK, PHY_DLL_RECALIB_INCR,
305 static void ddrphy_set_dll_adrctrl(void __iomem *phy_base, int dly_step)
307 ddrphy_set_delay(phy_base, PHY_DLL_ADRCTRL,
308 PHY_DLL_ADRCTRL_TRIM_MASK, PHY_DLL_ADRCTRL_INCR,
312 static void ddrphy_set_dll_trim_clk(void __iomem *phy_base, int dly_step)
314 ddrphy_select_lane(phy_base, 0, 0);
316 ddrphy_set_delay(phy_base, PHY_DLL_TRIM_CLK,
317 PHY_DLL_TRIM_CLK_MASK, PHY_DLL_TRIM_CLK_INCR,
321 static void ddrphy_init_tail(void __iomem *phy_base, enum dram_board board,
322 unsigned int freq, int ch)
326 step = ddrphy_to_dly_step(phy_base, freq, ddrphy_adrctrl[board][ch]);
327 ddrphy_set_dll_adrctrl(phy_base, step);
329 step = ddrphy_to_dly_step(phy_base, freq, ddrphy_dlltrimclk[board][ch]);
330 ddrphy_set_dll_trim_clk(phy_base, step);
332 step = ddrphy_to_dly_step(phy_base, freq, ddrphy_dllrecalib[board][ch]);
333 ddrphy_set_dll_recalib(phy_base, step);
336 static void ddrphy_shift_one_dq(void __iomem *phy_base, unsigned int reg,
337 u32 mask, u32 incr, int shift_val)
342 tmp = readl(phy_base + reg);
350 tmp &= ~(incr | mask);
351 tmp |= min_t(u32, abs(val), mask);
355 writel(tmp, phy_base + reg);
358 static void ddrphy_shift_dq(void __iomem *phy_base, unsigned int reg,
359 u32 mask, u32 incr, u32 override,
360 const int *shift_val_array)
365 tmp = readl(phy_base + reg);
367 writel(tmp, phy_base + reg);
369 for (dx = 0; dx < 4; dx++) {
370 for (bit = 0; bit < 8; bit++) {
371 ddrphy_select_lane(phy_base,
372 (PHY_BITLVL_DLY_WIDTH + 1) * dx,
375 ddrphy_shift_one_dq(phy_base, reg, mask, incr,
376 shift_val_array[dx * 8 + bit]);
380 ddrphy_select_lane(phy_base, 0, 0);
383 static int ddrphy_training(void __iomem *phy_base, enum dram_board board,
386 writel(0x0000000f, phy_base + PHY_WRLVL_AUTOINC_TRIM);
387 writel(0x00010000, phy_base + PHY_DLL_TRIM_2);
388 writel(0x50000000, phy_base + PHY_SCL_START);
390 while (readl(phy_base + PHY_SCL_START) & BIT(28))
393 writel(0x00000000, phy_base + PHY_DISABLE_GATING_FOR_SCL);
394 writel(0xff00ff00, phy_base + PHY_SCL_DATA_0);
395 writel(0xff00ff00, phy_base + PHY_SCL_DATA_1);
396 writel(0xFBF8FFFF, phy_base + PHY_SCL_START_ADDR);
397 writel(0x11000000, phy_base + PHY_SCL_START);
399 while (readl(phy_base + PHY_SCL_START) & BIT(28))
402 writel(0xFBF0FFFF, phy_base + PHY_SCL_START_ADDR);
403 writel(0x30500000, phy_base + PHY_SCL_START);
405 while (readl(phy_base + PHY_SCL_START) & BIT(28))
408 writel(0x00000001, phy_base + PHY_DISABLE_GATING_FOR_SCL);
409 writel(0x00000010, phy_base + PHY_SCL_MAIN_CLK_DELTA);
410 writel(0x789b3de0, phy_base + PHY_SCL_DATA_0);
411 writel(0xf10e4a56, phy_base + PHY_SCL_DATA_1);
412 writel(0x11000000, phy_base + PHY_SCL_START);
414 while (readl(phy_base + PHY_SCL_START) & BIT(28))
417 writel(0x34000000, phy_base + PHY_SCL_START);
419 while (readl(phy_base + PHY_SCL_START) & BIT(28))
422 writel(0x00000003, phy_base + PHY_DISABLE_GATING_FOR_SCL);
424 writel(0x000261c0, phy_base + PHY_DYNAMIC_WRITE_BIT_LVL);
425 writel(0x00003270, phy_base + PHY_DYNAMIC_BIT_LVL);
426 writel(0x011BD0C4, phy_base + PHY_DSCL_CNT);
428 /* shift ip_dq trim */
429 ddrphy_shift_dq(phy_base,
430 PHY_IP_DQ_DQS_BITWISE_TRIM,
431 PHY_IP_DQ_DQS_BITWISE_TRIM_MASK,
432 PHY_IP_DQ_DQS_BITWISE_TRIM_INC,
433 PHY_IP_DQ_DQS_BITWISE_TRIM_OVERRIDE,
434 ddrphy_ip_dq_shift_val[board][ch]);
436 /* shift op_dq trim */
437 ddrphy_shift_dq(phy_base,
438 PHY_OP_DQ_DM_DQS_BITWISE_TRIM,
439 PHY_OP_DQ_DM_DQS_BITWISE_TRIM_MASK,
440 PHY_OP_DQ_DM_DQS_BITWISE_TRIM_INC,
441 PHY_OP_DQ_DM_DQS_BITWISE_TRIM_OVERRIDE,
442 ddrphy_op_dq_shift_val[board][ch]);
448 static u32 umc_initctla[DRAM_FREQ_NR] = {0x71016D11};
449 static u32 umc_initctlb[DRAM_FREQ_NR] = {0x07E390AC};
450 static u32 umc_initctlc[DRAM_FREQ_NR] = {0x00FF00FF};
451 static u32 umc_drmmr0[DRAM_FREQ_NR] = {0x00000114};
452 static u32 umc_drmmr2[DRAM_FREQ_NR] = {0x000002a0};
454 static u32 umc_memconf0a[DRAM_FREQ_NR][DRAM_SZ_NR] = {
456 {0x00000601, 0x00000801}, /* 1866 MHz */
459 static u32 umc_memconf0b[DRAM_FREQ_NR][DRAM_SZ_NR] = {
461 {0x00000120, 0x00000130}, /* 1866 MHz */
464 static u32 umc_memconfch[DRAM_FREQ_NR][DRAM_SZ_NR] = {
466 {0x00033603, 0x00033803}, /* 1866 MHz */
469 static u32 umc_cmdctla[DRAM_FREQ_NR] = {0x060D0D20};
470 static u32 umc_cmdctlb[DRAM_FREQ_NR] = {0x2D211C08};
471 static u32 umc_cmdctlc[DRAM_FREQ_NR] = {0x00150C04};
472 static u32 umc_cmdctle[DRAM_FREQ_NR][DRAM_SZ_NR] = {
474 {0x0049071D, 0x0078071D}, /* 1866 MHz */
477 static u32 umc_rdatactl_d0[DRAM_FREQ_NR] = {0x00000610};
478 static u32 umc_rdatactl_d1[DRAM_FREQ_NR] = {0x00000610};
479 static u32 umc_wdatactl_d0[DRAM_FREQ_NR] = {0x00000204};
480 static u32 umc_wdatactl_d1[DRAM_FREQ_NR] = {0x00000204};
481 static u32 umc_odtctl_d0[DRAM_FREQ_NR] = {0x02000002};
482 static u32 umc_odtctl_d1[DRAM_FREQ_NR] = {0x02000002};
483 static u32 umc_dataset[DRAM_FREQ_NR] = {0x04000000};
485 static u32 umc_flowctla[DRAM_FREQ_NR] = {0x0081E01E};
486 static u32 umc_directbusctrla[DRAM_CH_NR] = {
487 0x00000000, 0x00000001, 0x00000001
490 static void umc_poll_phy_init_complete(void __iomem *dc_base)
492 /* Wait for PHY Init Complete */
493 while (!(readl(dc_base + UMC_DFISTCTLC) & BIT(0)))
497 static int umc_dc_init(void __iomem *dc_base, unsigned int freq,
498 unsigned long size, int ch)
500 enum dram_freq freq_e;
501 enum dram_size size_e;
505 freq_e = DRAM_FREQ_1866M;
508 pr_err("unsupported DRAM frequency %ud MHz\n", freq);
516 size_e = DRAM_SZ_256M;
519 size_e = DRAM_SZ_512M;
522 pr_err("unsupported DRAM size 0x%08lx (per 16bit) for ch%d\n",
527 writel(0x00000001, dc_base + UMC_DFICSOVRRD);
528 writel(0x00000000, dc_base + UMC_DFITURNOFF);
530 writel(umc_initctla[freq_e], dc_base + UMC_INITCTLA);
531 writel(umc_initctlb[freq_e], dc_base + UMC_INITCTLB);
532 writel(umc_initctlc[freq_e], dc_base + UMC_INITCTLC);
534 writel(umc_drmmr0[freq_e], dc_base + UMC_DRMMR0);
535 writel(0x00000004, dc_base + UMC_DRMMR1);
536 writel(umc_drmmr2[freq_e], dc_base + UMC_DRMMR2);
537 writel(0x00000000, dc_base + UMC_DRMMR3);
539 writel(umc_memconf0a[freq_e][size_e], dc_base + UMC_MEMCONF0A);
540 writel(umc_memconf0b[freq_e][size_e], dc_base + UMC_MEMCONF0B);
541 writel(umc_memconfch[freq_e][size_e], dc_base + UMC_MEMCONFCH);
542 writel(0x00000008, dc_base + UMC_MEMMAPSET);
544 writel(umc_cmdctla[freq_e], dc_base + UMC_CMDCTLA);
545 writel(umc_cmdctlb[freq_e], dc_base + UMC_CMDCTLB);
546 writel(umc_cmdctlc[freq_e], dc_base + UMC_CMDCTLC);
547 writel(umc_cmdctle[freq_e][size_e], dc_base + UMC_CMDCTLE);
549 writel(umc_rdatactl_d0[freq_e], dc_base + UMC_RDATACTL_D0);
550 writel(umc_rdatactl_d1[freq_e], dc_base + UMC_RDATACTL_D1);
552 writel(umc_wdatactl_d0[freq_e], dc_base + UMC_WDATACTL_D0);
553 writel(umc_wdatactl_d1[freq_e], dc_base + UMC_WDATACTL_D1);
554 writel(umc_odtctl_d0[freq_e], dc_base + UMC_ODTCTL_D0);
555 writel(umc_odtctl_d1[freq_e], dc_base + UMC_ODTCTL_D1);
556 writel(umc_dataset[freq_e], dc_base + UMC_DATASET);
558 writel(0x00400020, dc_base + UMC_DCCGCTL);
559 writel(0x00000003, dc_base + UMC_ACSSETA);
560 writel(0x00000103, dc_base + UMC_FLOWCTLG);
561 writel(0x00010200, dc_base + UMC_ACSSETB);
563 writel(umc_flowctla[freq_e], dc_base + UMC_FLOWCTLA);
564 writel(0x00004444, dc_base + UMC_FLOWCTLC);
565 writel(0x00000000, dc_base + UMC_DFICUPDCTLA);
567 writel(0x00202000, dc_base + UMC_FLOWCTLB);
568 writel(0x00000000, dc_base + UMC_BSICMAPSET);
569 writel(0x00000000, dc_base + UMC_ERRMASKA);
570 writel(0x00000000, dc_base + UMC_ERRMASKB);
572 writel(umc_directbusctrla[ch], dc_base + UMC_DIRECTBUSCTRLA);
574 writel(0x00000001, dc_base + UMC_INITSET);
575 /* Wait for PHY Init Complete */
576 while (readl(dc_base + UMC_INITSTAT) & BIT(0))
579 writel(0x2A0A0A00, dc_base + UMC_SPCSETB);
580 writel(0x00000000, dc_base + UMC_DFICSOVRRD);
585 static int umc_ch_init(void __iomem *umc_ch_base, void __iomem *phy_ch_base,
586 enum dram_board board, unsigned int freq,
587 unsigned long size, int ch)
589 void __iomem *dc_base = umc_ch_base + 0x00011000;
590 void __iomem *phy_base = phy_ch_base;
593 /* PHY Update Mode (ON) */
594 writel(0x8000003f, dc_base + UMC_DFIPUPDCTLA);
596 /* deassert PHY reset signals */
597 writel(UMC_DIOCTLA_CTL_NRST | UMC_DIOCTLA_CFG_NRST,
598 dc_base + UMC_DIOCTLA);
600 ddrphy_init(phy_base, board, ch);
602 umc_poll_phy_init_complete(dc_base);
604 ddrphy_init_tail(phy_base, board, freq, ch);
606 ret = umc_dc_init(dc_base, freq, size, ch);
610 ret = ddrphy_training(phy_base, board, ch);
617 static void um_init(void __iomem *um_base)
619 writel(0x000000ff, um_base + UMC_MBUS0);
620 writel(0x000000ff, um_base + UMC_MBUS1);
621 writel(0x000000ff, um_base + UMC_MBUS2);
622 writel(0x00000001, um_base + UMC_MBUS3);
623 writel(0x00000001, um_base + UMC_MBUS4);
624 writel(0x00000001, um_base + UMC_MBUS5);
625 writel(0x00000001, um_base + UMC_MBUS6);
626 writel(0x00000001, um_base + UMC_MBUS7);
627 writel(0x00000001, um_base + UMC_MBUS8);
628 writel(0x00000001, um_base + UMC_MBUS9);
629 writel(0x00000001, um_base + UMC_MBUS10);
632 int uniphier_ld20_umc_init(const struct uniphier_board_data *bd)
634 void __iomem *um_base = (void __iomem *)0x5b600000;
635 void __iomem *umc_ch_base = (void __iomem *)0x5b800000;
636 void __iomem *phy_ch_base = (void __iomem *)0x6e200000;
637 enum dram_board board;
640 switch (UNIPHIER_BD_BOARD_GET_TYPE(bd->flags)) {
641 case UNIPHIER_BD_BOARD_LD20_REF:
642 board = DRAM_BOARD_LD20_REF;
644 case UNIPHIER_BD_BOARD_LD20_GLOBAL:
645 board = DRAM_BOARD_LD20_GLOBAL;
647 case UNIPHIER_BD_BOARD_LD21_REF:
648 board = DRAM_BOARD_LD21_REF;
650 case UNIPHIER_BD_BOARD_LD21_GLOBAL:
651 board = DRAM_BOARD_LD21_GLOBAL;
654 pr_err("unsupported board type %d\n",
655 UNIPHIER_BD_BOARD_GET_TYPE(bd->flags));
659 for (ch = 0; ch < bd->dram_nr_ch; ch++) {
660 unsigned long size = bd->dram_ch[ch].size;
661 unsigned int width = bd->dram_ch[ch].width;
663 ret = umc_ch_init(umc_ch_base, phy_ch_base, board,
664 bd->dram_freq, size / (width / 16), ch);
666 pr_err("failed to initialize UMC ch%d\n", ch);
670 umc_ch_base += 0x00200000;
671 phy_ch_base += 0x00004000;