2 * Copyright (C) 2016-2017 Socionext Inc.
4 * based on commit 5ffd75ecd4929f22361ef65a35f0331d2fbc0f35 of Diag
6 * SPDX-License-Identifier: GPL-2.0+
10 #include <linux/bitops.h>
11 #include <linux/compat.h>
12 #include <linux/errno.h>
14 #include <linux/sizes.h>
15 #include <asm/processor.h>
18 #include "ddruqphy-regs.h"
19 #include "umc64-regs.h"
34 enum dram_board { /* board type */
35 DRAM_BOARD_LD20_REF, /* LD20 reference */
36 DRAM_BOARD_LD20_GLOBAL, /* LD20 TV */
37 DRAM_BOARD_LD20_C1, /* LD20 TV C1 */
38 DRAM_BOARD_LD21_REF, /* LD21 reference */
39 DRAM_BOARD_LD21_GLOBAL, /* LD21 TV */
44 static const int ddrphy_adrctrl[DRAM_BOARD_NR][DRAM_CH_NR] = {
45 {268 - 262, 268 - 263, 268 - 378}, /* LD20 reference */
46 {268 - 262, 268 - 263, 268 - 378}, /* LD20 TV */
47 {268 - 262, 268 - 263, 268 - 378}, /* LD20 TV C1 */
48 {268 - 212, 268 - 268, /* No CH2 */}, /* LD21 reference */
49 {268 - 212, 268 - 268, /* No CH2 */}, /* LD21 TV */
52 static const int ddrphy_dlltrimclk[DRAM_BOARD_NR][DRAM_CH_NR] = {
53 {268, 268, 268}, /* LD20 reference */
54 {268, 268, 268}, /* LD20 TV */
55 {189, 189, 189}, /* LD20 TV C1 */
56 {268, 268 + 252, /* No CH2 */}, /* LD21 reference */
57 {268, 268 + 202, /* No CH2 */}, /* LD21 TV */
60 static const int ddrphy_dllrecalib[DRAM_BOARD_NR][DRAM_CH_NR] = {
61 {268 - 378, 268 - 263, 268 - 378}, /* LD20 reference */
62 {268 - 378, 268 - 263, 268 - 378}, /* LD20 TV */
63 {268 - 378, 268 - 263, 268 - 378}, /* LD20 TV C1 */
64 {268 - 212, 268 - 536, /* No CH2 */}, /* LD21 reference */
65 {268 - 212, 268 - 536, /* No CH2 */}, /* LD21 TV */
68 static const u32 ddrphy_phy_pad_ctrl[DRAM_BOARD_NR][DRAM_CH_NR] = {
69 {0x50B840B1, 0x50B840B1, 0x50B840B1}, /* LD20 reference */
70 {0x50BB40B1, 0x50BB40B1, 0x50BB40B1}, /* LD20 TV */
71 {0x50BB40B1, 0x50BB40B1, 0x50BB40B1}, /* LD20 TV C1 */
72 {0x50BB40B4, 0x50B840B1, /* No CH2 */}, /* LD21 reference */
73 {0x50BB40B4, 0x50B840B1, /* No CH2 */}, /* LD21 TV */
76 static const u32 ddrphy_scl_gate_timing[DRAM_CH_NR] = {
77 0x00000140, 0x00000180, 0x00000140
80 static const short ddrphy_op_dq_shift_val_ld20[DRAM_CH_NR][32] = {
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,
101 static const short ddrphy_op_dq_shift_val_ld21[DRAM_CH_NR][32] = {
103 1, 1, 0, 1, 1, 1, 1, 1,
104 1, 0, 0, 0, 1, 1, 0, 2,
105 1, 1, 0, 0, 1, 1, 1, 1,
106 1, 0, 0, 0, 1, 0, 0, 1,
108 { 1, 0, 2, 1, 1, 1, 1, 0,
109 1, 0, 0, 1, 0, 1, 0, 0,
110 1, 0, 1, 0, 1, 1, 1, 0,
111 1, 1, 1, 1, 0, 1, 0, 0,
116 static const short (* const ddrphy_op_dq_shift_val[DRAM_BOARD_NR])[32] = {
117 ddrphy_op_dq_shift_val_ld20, /* LD20 reference */
118 ddrphy_op_dq_shift_val_ld20, /* LD20 TV */
119 ddrphy_op_dq_shift_val_ld20, /* LD20 TV C */
120 ddrphy_op_dq_shift_val_ld21, /* LD21 reference */
121 ddrphy_op_dq_shift_val_ld21, /* LD21 TV */
124 static const short ddrphy_ip_dq_shift_val_ld20[DRAM_CH_NR][32] = {
126 3, 3, 3, 2, 3, 2, 0, 2,
127 2, 3, 3, 1, 2, 2, 2, 2,
128 2, 2, 2, 2, 0, 1, 1, 1,
129 2, 2, 2, 2, 3, 0, 2, 2,
132 2, 2, 1, 1, -1, 1, 1, 1,
133 2, 0, 2, 2, 2, 1, 0, 2,
134 2, 1, 2, 1, 0, 1, 1, 1,
135 2, 2, 2, 2, 2, 2, 2, 2,
138 2, 2, 3, 2, 1, 2, 2, 2,
139 2, 3, 4, 2, 3, 4, 3, 3,
140 2, 2, 1, 2, 1, 1, 1, 1,
141 2, 2, 2, 2, 1, 2, 2, 1,
145 static const short ddrphy_ip_dq_shift_val_ld21[DRAM_CH_NR][32] = {
147 2, 2, 2, 2, 1, 2, 2, 2,
148 2, 3, 3, 2, 2, 2, 2, 2,
149 2, 1, 2, 2, 1, 1, 1, 1,
150 2, 2, 2, 3, 1, 2, 2, 2,
153 3, 4, 4, 1, 0, 1, 1, 1,
154 1, 2, 1, 2, 2, 3, 3, 2,
155 1, 0, 2, 1, 1, 0, 1, 0,
156 0, 1, 0, 0, 1, 1, 0, 1,
161 static const short (* const ddrphy_ip_dq_shift_val[DRAM_BOARD_NR])[32] = {
162 ddrphy_ip_dq_shift_val_ld20, /* LD20 reference */
163 ddrphy_ip_dq_shift_val_ld20, /* LD20 TV */
164 ddrphy_ip_dq_shift_val_ld20, /* LD20 TV C */
165 ddrphy_ip_dq_shift_val_ld21, /* LD21 reference */
166 ddrphy_ip_dq_shift_val_ld21, /* LD21 TV */
169 static void ddrphy_select_lane(void __iomem *phy_base, unsigned int lane,
172 WARN_ON(lane >= 1 << PHY_LANE_SEL_LANE_WIDTH);
173 WARN_ON(bit >= 1 << PHY_LANE_SEL_BIT_WIDTH);
175 writel((bit << PHY_LANE_SEL_BIT_SHIFT) |
176 (lane << PHY_LANE_SEL_LANE_SHIFT),
177 phy_base + PHY_LANE_SEL);
180 #define DDRPHY_EFUSEMON (void *)0x5f900118
182 static void ddrphy_init(void __iomem *phy_base, enum dram_board board, int ch)
184 writel(0x0C001001, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
185 while (!(readl(phy_base + PHY_UNIQUIFY_TSMC_IO_1) & BIT(1)))
188 if (readl(DDRPHY_EFUSEMON) & BIT(ch))
189 writel(0x00000000, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
191 writel(0x0C001000, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
193 writel(0x00000000, phy_base + PHY_DLL_INCR_TRIM_3);
194 writel(0x00000000, phy_base + PHY_DLL_INCR_TRIM_1);
195 ddrphy_select_lane(phy_base, 0, 0);
196 writel(0x00000005, phy_base + PHY_DLL_TRIM_1);
197 writel(0x0000000a, phy_base + PHY_DLL_TRIM_3);
198 ddrphy_select_lane(phy_base, 6, 0);
199 writel(0x00000005, phy_base + PHY_DLL_TRIM_1);
200 writel(0x0000000a, phy_base + PHY_DLL_TRIM_3);
201 ddrphy_select_lane(phy_base, 12, 0);
202 writel(0x00000005, phy_base + PHY_DLL_TRIM_1);
203 writel(0x0000000a, phy_base + PHY_DLL_TRIM_3);
204 ddrphy_select_lane(phy_base, 18, 0);
205 writel(0x00000005, phy_base + PHY_DLL_TRIM_1);
206 writel(0x0000000a, phy_base + PHY_DLL_TRIM_3);
207 writel(0x00000001, phy_base + PHY_SCL_WINDOW_TRIM);
208 writel(0x00000000, phy_base + PHY_UNQ_ANALOG_DLL_1);
209 writel(ddrphy_phy_pad_ctrl[board][ch], phy_base + PHY_PAD_CTRL);
210 writel(0x00000070, phy_base + PHY_VREF_TRAINING);
211 writel(0x01000075, phy_base + PHY_SCL_CONFIG_1);
212 writel(0x00000501, phy_base + PHY_SCL_CONFIG_2);
213 writel(0x00000000, phy_base + PHY_SCL_CONFIG_3);
214 writel(0x000261c0, phy_base + PHY_DYNAMIC_WRITE_BIT_LVL);
215 writel(0x00000000, phy_base + PHY_SCL_CONFIG_4);
216 writel(ddrphy_scl_gate_timing[ch], phy_base + PHY_SCL_GATE_TIMING);
217 writel(0x02a000a0, phy_base + PHY_WRLVL_DYN_ODT);
218 writel(0x00840004, phy_base + PHY_WRLVL_ON_OFF);
219 writel(0x0000020d, phy_base + PHY_DLL_ADRCTRL);
220 ddrphy_select_lane(phy_base, 0, 0);
221 writel(0x0000008d, phy_base + PHY_DLL_TRIM_CLK);
222 writel(0xa800100d, phy_base + PHY_DLL_RECALIB);
223 writel(0x00005076, phy_base + PHY_SCL_LATENCY);
226 static int ddrphy_to_dly_step(void __iomem *phy_base, unsigned int freq,
231 mdl = (readl(phy_base + PHY_DLL_ADRCTRL) & PHY_DLL_ADRCTRL_MDL_MASK) >>
232 PHY_DLL_ADRCTRL_MDL_SHIFT;
234 return DIV_ROUND_CLOSEST((long)freq * delay * mdl, 2 * 1000000L);
237 static void ddrphy_set_delay(void __iomem *phy_base, unsigned int reg,
238 u32 mask, u32 incr, int dly_step)
242 tmp = readl(phy_base + reg);
244 tmp |= min_t(u32, abs(dly_step), mask);
251 writel(tmp, phy_base + reg);
254 static void ddrphy_set_dll_recalib(void __iomem *phy_base, int dly_step)
256 ddrphy_set_delay(phy_base, PHY_DLL_RECALIB,
257 PHY_DLL_RECALIB_TRIM_MASK, PHY_DLL_RECALIB_INCR,
261 static void ddrphy_set_dll_adrctrl(void __iomem *phy_base, int dly_step)
263 ddrphy_set_delay(phy_base, PHY_DLL_ADRCTRL,
264 PHY_DLL_ADRCTRL_TRIM_MASK, PHY_DLL_ADRCTRL_INCR,
268 static void ddrphy_set_dll_trim_clk(void __iomem *phy_base, int dly_step)
270 ddrphy_select_lane(phy_base, 0, 0);
272 ddrphy_set_delay(phy_base, PHY_DLL_TRIM_CLK,
273 PHY_DLL_TRIM_CLK_MASK, PHY_DLL_TRIM_CLK_INCR,
277 static void ddrphy_init_tail(void __iomem *phy_base, enum dram_board board,
278 unsigned int freq, int ch)
282 step = ddrphy_to_dly_step(phy_base, freq, ddrphy_adrctrl[board][ch]);
283 ddrphy_set_dll_adrctrl(phy_base, step);
285 step = ddrphy_to_dly_step(phy_base, freq, ddrphy_dlltrimclk[board][ch]);
286 ddrphy_set_dll_trim_clk(phy_base, step);
288 step = ddrphy_to_dly_step(phy_base, freq, ddrphy_dllrecalib[board][ch]);
289 ddrphy_set_dll_recalib(phy_base, step);
292 static void ddrphy_shift_one_dq(void __iomem *phy_base, unsigned int reg,
293 u32 mask, u32 incr, short shift_val)
298 tmp = readl(phy_base + reg);
306 tmp &= ~(incr | mask);
307 tmp |= min_t(u32, abs(val), mask);
311 writel(tmp, phy_base + reg);
314 static void ddrphy_shift_dq(void __iomem *phy_base, unsigned int reg,
315 u32 mask, u32 incr, u32 override,
316 const short *shift_val_array)
321 tmp = readl(phy_base + reg);
323 writel(tmp, phy_base + reg);
325 for (dx = 0; dx < 4; dx++) {
326 for (bit = 0; bit < 8; bit++) {
327 ddrphy_select_lane(phy_base,
328 (PHY_BITLVL_DLY_WIDTH + 1) * dx,
331 ddrphy_shift_one_dq(phy_base, reg, mask, incr,
332 shift_val_array[dx * 8 + bit]);
336 ddrphy_select_lane(phy_base, 0, 0);
339 static int ddrphy_training(void __iomem *phy_base, enum dram_board board,
342 writel(0x0000000f, phy_base + PHY_WRLVL_AUTOINC_TRIM);
343 writel(0x00010000, phy_base + PHY_DLL_TRIM_2);
344 writel(0x50000000, phy_base + PHY_SCL_START);
346 while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE)
349 writel(0x00000000, phy_base + PHY_DISABLE_GATING_FOR_SCL);
350 writel(0xff00ff00, phy_base + PHY_SCL_DATA_0);
351 writel(0xff00ff00, phy_base + PHY_SCL_DATA_1);
352 writel(0xFBF8FFFF, phy_base + PHY_SCL_START_ADDR);
353 writel(0x11000000, phy_base + PHY_SCL_START);
355 while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE)
358 writel(0xFBF0FFFF, phy_base + PHY_SCL_START_ADDR);
359 writel(0x30500000, phy_base + PHY_SCL_START);
361 while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE)
364 writel(0x00000001, phy_base + PHY_DISABLE_GATING_FOR_SCL);
365 writel(0x00000010, phy_base + PHY_SCL_MAIN_CLK_DELTA);
366 writel(0x789b3de0, phy_base + PHY_SCL_DATA_0);
367 writel(0xf10e4a56, phy_base + PHY_SCL_DATA_1);
368 writel(0x11000000, phy_base + PHY_SCL_START);
370 while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE)
373 writel(0x34000000, phy_base + PHY_SCL_START);
375 while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE)
378 writel(0x00000003, phy_base + PHY_DISABLE_GATING_FOR_SCL);
380 writel(0x000261c0, phy_base + PHY_DYNAMIC_WRITE_BIT_LVL);
381 writel(0x00003270, phy_base + PHY_DYNAMIC_BIT_LVL);
382 writel(0x011BD0C4, phy_base + PHY_DSCL_CNT);
384 /* shift ip_dq trim */
385 ddrphy_shift_dq(phy_base,
386 PHY_IP_DQ_DQS_BITWISE_TRIM,
387 PHY_IP_DQ_DQS_BITWISE_TRIM_MASK,
388 PHY_IP_DQ_DQS_BITWISE_TRIM_INC,
389 PHY_IP_DQ_DQS_BITWISE_TRIM_OVERRIDE,
390 ddrphy_ip_dq_shift_val[board][ch]);
392 /* shift op_dq trim */
393 ddrphy_shift_dq(phy_base,
394 PHY_OP_DQ_DM_DQS_BITWISE_TRIM,
395 PHY_OP_DQ_DM_DQS_BITWISE_TRIM_MASK,
396 PHY_OP_DQ_DM_DQS_BITWISE_TRIM_INC,
397 PHY_OP_DQ_DM_DQS_BITWISE_TRIM_OVERRIDE,
398 ddrphy_op_dq_shift_val[board][ch]);
404 static const u32 umc_initctla[DRAM_FREQ_NR] = {0x71016D11};
405 static const u32 umc_initctlb[DRAM_FREQ_NR] = {0x07E390AC};
406 static const u32 umc_initctlc[DRAM_FREQ_NR] = {0x00FF00FF};
407 static const u32 umc_drmmr0[DRAM_FREQ_NR] = {0x00000114};
408 static const u32 umc_drmmr2[DRAM_FREQ_NR] = {0x000002a0};
410 static const u32 umc_memconf0a[DRAM_FREQ_NR][DRAM_SZ_NR] = {
412 {0x00000601, 0x00000801}, /* 1866 MHz */
415 static const u32 umc_memconf0b[DRAM_FREQ_NR][DRAM_SZ_NR] = {
417 {0x00000120, 0x00000130}, /* 1866 MHz */
420 static const u32 umc_memconfch[DRAM_FREQ_NR][DRAM_SZ_NR] = {
422 {0x00033603, 0x00033803}, /* 1866 MHz */
425 static const u32 umc_cmdctla[DRAM_FREQ_NR] = {0x060D0D20};
426 static const u32 umc_cmdctlb[DRAM_FREQ_NR] = {0x2D211C08};
427 static const u32 umc_cmdctlc[DRAM_FREQ_NR] = {0x00150C04};
428 static const u32 umc_cmdctle[DRAM_FREQ_NR][DRAM_SZ_NR] = {
430 {0x0049071D, 0x0078071D}, /* 1866 MHz */
433 static const u32 umc_rdatactl[DRAM_FREQ_NR] = {0x00000610};
434 static const u32 umc_wdatactl[DRAM_FREQ_NR] = {0x00000204};
435 static const u32 umc_odtctl[DRAM_FREQ_NR] = {0x02000002};
436 static const u32 umc_dataset[DRAM_FREQ_NR] = {0x04000000};
438 static const u32 umc_flowctla[DRAM_FREQ_NR] = {0x0081E01E};
439 static const u32 umc_directbusctrla[DRAM_CH_NR] = {
440 0x00000000, 0x00000001, 0x00000001
443 static void umc_poll_phy_init_complete(void __iomem *dc_base)
445 /* Wait for PHY Init Complete */
446 while (!(readl(dc_base + UMC_DFISTCTLC) & BIT(0)))
450 static int umc_dc_init(void __iomem *dc_base, unsigned int freq,
451 unsigned long size, int ch)
453 enum dram_freq freq_e;
454 enum dram_size size_e;
458 freq_e = DRAM_FREQ_1866M;
461 pr_err("unsupported DRAM frequency %ud MHz\n", freq);
469 size_e = DRAM_SZ_256M;
472 size_e = DRAM_SZ_512M;
475 pr_err("unsupported DRAM size 0x%08lx (per 16bit) for ch%d\n",
480 writel(0x00000001, dc_base + UMC_DFICSOVRRD);
481 writel(0x00000000, dc_base + UMC_DFITURNOFF);
483 writel(umc_initctla[freq_e], dc_base + UMC_INITCTLA);
484 writel(umc_initctlb[freq_e], dc_base + UMC_INITCTLB);
485 writel(umc_initctlc[freq_e], dc_base + UMC_INITCTLC);
487 writel(umc_drmmr0[freq_e], dc_base + UMC_DRMMR0);
488 writel(0x00000004, dc_base + UMC_DRMMR1);
489 writel(umc_drmmr2[freq_e], dc_base + UMC_DRMMR2);
490 writel(0x00000000, dc_base + UMC_DRMMR3);
492 writel(umc_memconf0a[freq_e][size_e], dc_base + UMC_MEMCONF0A);
493 writel(umc_memconf0b[freq_e][size_e], dc_base + UMC_MEMCONF0B);
494 writel(umc_memconfch[freq_e][size_e], dc_base + UMC_MEMCONFCH);
495 writel(0x00000000, dc_base + UMC_MEMMAPSET);
497 writel(umc_cmdctla[freq_e], dc_base + UMC_CMDCTLA);
498 writel(umc_cmdctlb[freq_e], dc_base + UMC_CMDCTLB);
499 writel(umc_cmdctlc[freq_e], dc_base + UMC_CMDCTLC);
500 writel(umc_cmdctle[freq_e][size_e], dc_base + UMC_CMDCTLE);
502 writel(umc_rdatactl[freq_e], dc_base + UMC_RDATACTL_D0);
503 writel(umc_rdatactl[freq_e], dc_base + UMC_RDATACTL_D1);
505 writel(umc_wdatactl[freq_e], dc_base + UMC_WDATACTL_D0);
506 writel(umc_wdatactl[freq_e], dc_base + UMC_WDATACTL_D1);
507 writel(umc_odtctl[freq_e], dc_base + UMC_ODTCTL_D0);
508 writel(umc_odtctl[freq_e], dc_base + UMC_ODTCTL_D1);
509 writel(umc_dataset[freq_e], dc_base + UMC_DATASET);
511 writel(0x00400020, dc_base + UMC_DCCGCTL);
512 writel(0x00000003, dc_base + UMC_ACSSETA);
513 writel(0x00000103, dc_base + UMC_FLOWCTLG);
514 writel(0x00010200, dc_base + UMC_ACSSETB);
516 writel(umc_flowctla[freq_e], dc_base + UMC_FLOWCTLA);
517 writel(0x00004444, dc_base + UMC_FLOWCTLC);
518 writel(0x00000000, dc_base + UMC_DFICUPDCTLA);
520 writel(0x00202000, dc_base + UMC_FLOWCTLB);
521 writel(0x00000000, dc_base + UMC_BSICMAPSET);
522 writel(0x00000000, dc_base + UMC_ERRMASKA);
523 writel(0x00000000, dc_base + UMC_ERRMASKB);
525 writel(umc_directbusctrla[ch], dc_base + UMC_DIRECTBUSCTRLA);
527 writel(0x00000001, dc_base + UMC_INITSET);
528 /* Wait for PHY Init Complete */
529 while (readl(dc_base + UMC_INITSTAT) & BIT(0))
532 writel(0x2A0A0A00, dc_base + UMC_SPCSETB);
533 writel(0x00000000, dc_base + UMC_DFICSOVRRD);
538 static int umc_ch_init(void __iomem *umc_ch_base, void __iomem *phy_ch_base,
539 enum dram_board board, unsigned int freq,
540 unsigned long size, int ch)
542 void __iomem *dc_base = umc_ch_base + 0x00011000;
543 void __iomem *phy_base = phy_ch_base;
546 /* PHY Update Mode (ON) */
547 writel(0x8000003f, dc_base + UMC_DFIPUPDCTLA);
549 /* deassert PHY reset signals */
550 writel(UMC_DIOCTLA_CTL_NRST | UMC_DIOCTLA_CFG_NRST,
551 dc_base + UMC_DIOCTLA);
553 ddrphy_init(phy_base, board, ch);
555 umc_poll_phy_init_complete(dc_base);
557 ddrphy_init_tail(phy_base, board, freq, ch);
559 ret = umc_dc_init(dc_base, freq, size, ch);
563 ret = ddrphy_training(phy_base, board, ch);
570 static void um_init(void __iomem *um_base)
572 writel(0x000000ff, um_base + UMC_MBUS0);
573 writel(0x000000ff, um_base + UMC_MBUS1);
574 writel(0x000000ff, um_base + UMC_MBUS2);
575 writel(0x00000001, um_base + UMC_MBUS3);
576 writel(0x00000001, um_base + UMC_MBUS4);
577 writel(0x00000001, um_base + UMC_MBUS5);
578 writel(0x00000001, um_base + UMC_MBUS6);
579 writel(0x00000001, um_base + UMC_MBUS7);
580 writel(0x00000001, um_base + UMC_MBUS8);
581 writel(0x00000001, um_base + UMC_MBUS9);
582 writel(0x00000001, um_base + UMC_MBUS10);
585 int uniphier_ld20_umc_init(const struct uniphier_board_data *bd)
587 void __iomem *um_base = (void __iomem *)0x5b600000;
588 void __iomem *umc_ch_base = (void __iomem *)0x5b800000;
589 void __iomem *phy_ch_base = (void __iomem *)0x6e200000;
590 enum dram_board board;
593 switch (UNIPHIER_BD_BOARD_GET_TYPE(bd->flags)) {
594 case UNIPHIER_BD_BOARD_LD20_REF:
595 board = DRAM_BOARD_LD20_REF;
597 case UNIPHIER_BD_BOARD_LD20_GLOBAL:
598 board = DRAM_BOARD_LD20_GLOBAL;
600 case UNIPHIER_BD_BOARD_LD20_C1:
601 board = DRAM_BOARD_LD20_C1;
603 case UNIPHIER_BD_BOARD_LD21_REF:
604 board = DRAM_BOARD_LD21_REF;
606 case UNIPHIER_BD_BOARD_LD21_GLOBAL:
607 board = DRAM_BOARD_LD21_GLOBAL;
610 pr_err("unsupported board type %d\n",
611 UNIPHIER_BD_BOARD_GET_TYPE(bd->flags));
615 for (ch = 0; ch < DRAM_CH_NR; ch++) {
616 unsigned long size = bd->dram_ch[ch].size;
617 unsigned int width = bd->dram_ch[ch].width;
620 ret = umc_ch_init(umc_ch_base, phy_ch_base, board,
621 bd->dram_freq, size / (width / 16),
624 pr_err("failed to initialize UMC ch%d\n", ch);
629 umc_ch_base += 0x00200000;
630 phy_ch_base += 0x00004000;