2 * Copyright (C) 2016 Socionext Inc.
4 * based on commit a3c28918e86ad57127cf07bf8b32950cab20c03c 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"
21 #define CONFIG_DDR_FREQ 1866
34 enum dram_board { /* board type */
35 DRAM_BOARD_LD20_REF, /* LD20 reference */
36 DRAM_BOARD_LD20_GLOBAL, /* LD20 TV */
37 DRAM_BOARD_LD21_REF, /* LD21 reference */
38 DRAM_BOARD_LD21_GLOBAL, /* LD21 TV */
42 #define MSK_PHY_LANE_SEL 0x000000FF
43 #define MSK_BIT_SEL 0x00000F00
44 #define MSK_DLL_MAS_DLY 0xFF000000
45 #define MSK_MAS_DLY 0x7F000000
46 #define MSK_DLLS_TRIM_CLK 0x000000FF
48 #define PHY_DLL_MAS_DLY_WIDTH 8
49 #define PHY_SLV_DLY_WIDTH 6
51 static void ddrphy_maskwritel(u32 data, u32 mask, void *addr)
55 value = (readl(addr) & ~mask) | (data & mask);
59 static u32 ddrphy_maskreadl(u32 mask, void *addr)
61 return readl(addr) & mask;
64 /* set phy_lane_sel.phy_lane_sel */
65 static void ddrphy_set_phy_lane_sel(int val, void __iomem *phy_base)
67 ddrphy_maskwritel(val, MSK_PHY_LANE_SEL, phy_base + PHY_LANE_SEL);
70 /* set phy_lane_sel.bit_sel */
71 static void ddrphy_set_bit_sel(int bit, void __iomem *phy_base)
73 ddrphy_maskwritel(bit << 8, MSK_BIT_SEL, phy_base + PHY_LANE_SEL);
76 /* Calculating step for PUB-byte */
77 static int ddrphy_hpstep(int delay, void __iomem *phy_base)
81 freq = CONFIG_DDR_FREQ; /* FIXME */
82 mdl = ddrphy_maskreadl(MSK_DLL_MAS_DLY, phy_base + PHY_DLL_ADRCTRL) >> 24;
84 return DIV_ROUND_CLOSEST(freq * delay * mdl, 2 * 1000000);
87 static void ddrphy_set_dll_trim_clk(int delay_ckoffset, void __iomem *phy_base)
89 u8 ck_step; /* ckoffset_step for clock */
93 if (delay_ckoffset >= 0) {
94 /* shift + direction */
95 ck_step = min(ddrphy_hpstep(delay_ckoffset, phy_base), 127);
96 ck_step_all = ((0x1<<(PHY_SLV_DLY_WIDTH + 1))|ck_step);
98 /* shift - direction */
99 ck_step = min(ddrphy_hpstep(-1*delay_ckoffset, phy_base), 127);
100 ck_step_all = ck_step;
103 ddrphy_set_phy_lane_sel(0, phy_base);
104 ddrphy_maskwritel(ck_step_all, MSK_DLLS_TRIM_CLK, phy_base + PHY_DLL_TRIM_CLK);
107 static void ddrphy_set_dll_recalib(int delay_qoffset, u32 recalib_cnt,
108 u8 disable_recalib, u8 ctr_start_val,
109 void __iomem *phy_base)
111 u8 dlls_trim_adrctrl_ma, incr_dly_adrctrl_ma; /* qoffset_step and flag for inc/dec */
112 u32 recalib_all; /* all fields of register dll_recalib */
115 if (delay_qoffset >= 0) {
116 dlls_trim_adrctrl_ma = min(ddrphy_hpstep(delay_qoffset, phy_base), 63);
117 incr_dly_adrctrl_ma = 0x1;
119 dlls_trim_adrctrl_ma = min(ddrphy_hpstep(-1*delay_qoffset, phy_base), 63);
120 incr_dly_adrctrl_ma = 0x0;
123 recalib_all = ((ctr_start_val & 0xf) << 28) |
124 (incr_dly_adrctrl_ma << 27) |
125 ((disable_recalib & 0x1) << 26) |
126 ((recalib_cnt & 0x3ffff) << 8) |
127 (dlls_trim_adrctrl_ma & 0x3f);
129 /* write value for all bits other than bit[7:6] */
130 ddrphy_maskwritel(recalib_all, ~0xc0, phy_base + PHY_DLL_RECALIB);
133 static void ddrphy_set_dll_adrctrl(int delay_qoffset, u8 override_adrctrl,
134 void __iomem *phy_base)
136 u8 dlls_trim_adrctrl, incr_dly_adrctrl; /* qoffset_step for clock */
139 if (delay_qoffset >= 0) {
140 dlls_trim_adrctrl = min(ddrphy_hpstep(delay_qoffset, phy_base), 63);
141 incr_dly_adrctrl = 0x1;
143 dlls_trim_adrctrl = min(ddrphy_hpstep(-delay_qoffset, phy_base), 63);
144 incr_dly_adrctrl = 0x0;
147 adrctrl_all = (incr_dly_adrctrl << 9) |
148 ((override_adrctrl & 0x1) << 8) |
151 ddrphy_maskwritel(adrctrl_all, 0x33f, phy_base + PHY_DLL_ADRCTRL);
155 static int dio_adrctrl_0[DRAM_BOARD_NR][DRAM_CH_NR] = {
156 {268-262, 268-263, 268-378}, /* LD20 reference */
157 {268-262, 268-263, 268-378}, /* LD20 TV */
158 {268-212, 268-268, 0}, /* LD21 reference */
159 {268-212, 268-268, 0}, /* LD21 TV */
161 static int dio_dlltrimclk_0[DRAM_BOARD_NR][DRAM_CH_NR] = {
162 {268, 268, 268}, /* LD20 reference */
163 {268, 268, 268}, /* LD20 TV */
164 {268, 268+252, 0}, /* LD21 reference */
165 {268, 268+202, 0}, /* LD21 TV */
167 static int dio_dllrecalib_0[DRAM_BOARD_NR][DRAM_CH_NR] = {
168 {268-378, 268-263, 268-378}, /* LD20 reference */
169 {268-378, 268-263, 268-378}, /* LD20 TV */
170 {268-212, 268-536, 0}, /* LD21 reference */
171 {268-212, 268-536, 0}, /* LD21 TV */
174 static u32 dio_phy_pad_ctrl[DRAM_BOARD_NR][DRAM_CH_NR] = {
175 {0x50B840B1, 0x50B840B1, 0x50B840B1}, /* LD20 reference */
176 {0x50BB40B1, 0x50BB40B1, 0x50BB40B1}, /* LD20 TV */
177 {0x50BB40B4, 0x50B840B1, 0x50BB40B1}, /* LD21 reference */
178 {0x50BB40B4, 0x50B840B1, 0x50BB40B1}, /* LD21 TV */
181 static u32 dio_scl_gate_timing[DRAM_CH_NR] = {0x00000140, 0x00000180, 0x00000140};
183 static int dio_op_dq_shift_val[DRAM_BOARD_NR][DRAM_CH_NR][32] = {
184 { /* LD20 reference */
186 2, 1, 0, 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1,
187 1, 2, 1, 1, 1, 2, 1, 1, 2, 2, 0, 1, 1, 2, 2, 1,
190 1, 1, 0, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
191 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 2, 1, 2, 1,
194 2, 2, 0, 2, 1, 1, 2, 1, 1, 1, 0, 1, 1, -1, 1, 1,
195 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 1, 2,
200 2, 1, 0, 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1,
201 1, 2, 1, 1, 1, 2, 1, 1, 2, 2, 0, 1, 1, 2, 2, 1,
204 1, 1, 0, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
205 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 2, 1, 2, 1,
208 2, 2, 0, 2, 1, 1, 2, 1, 1, 1, 0, 1, 1, -1, 1, 1,
209 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 1, 2,
212 { /* LD21 reference */
214 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 2,
215 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1,
217 { 1, 0, 2, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0,
218 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0,
220 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
221 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
226 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 2,
227 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1,
229 { 1, 0, 2, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0,
230 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0,
232 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
233 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
237 static int dio_ip_dq_shift_val[DRAM_BOARD_NR][DRAM_CH_NR][32] = {
238 { /* LD20 reference */
240 3, 3, 3, 2, 3, 2, 0, 2, 2, 3, 3, 1, 2, 2, 2, 2,
241 2, 2, 2, 2, 0, 1, 1, 1, 2, 2, 2, 2, 3, 0, 2, 2,
244 2, 2, 1, 1, -1, 1, 1, 1, 2, 0, 2, 2, 2, 1, 0, 2,
245 2, 1, 2, 1, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
248 2, 2, 3, 2, 1, 2, 2, 2, 2, 3, 4, 2, 3, 4, 3, 3,
249 2, 2, 1, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 1,
254 3, 3, 3, 2, 3, 2, 0, 2, 2, 3, 3, 1, 2, 2, 2, 2,
255 2, 2, 2, 2, 0, 1, 1, 1, 2, 2, 2, 2, 3, 0, 2, 2,
258 2, 2, 1, 1, -1, 1, 1, 1, 2, 0, 2, 2, 2, 1, 0, 2,
259 2, 1, 2, 1, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
262 2, 2, 3, 2, 1, 2, 2, 2, 2, 3, 4, 2, 3, 4, 3, 3,
263 2, 2, 1, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 1,
266 { /* LD21 reference */
268 2, 2, 2, 2, 1, 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, 2,
269 2, 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, 3, 1, 2, 2, 2,
272 3, 4, 4, 1, 0, 1, 1, 1, 1, 2, 1, 2, 2, 3, 3, 2,
273 1, 0, 2, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1,
276 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
277 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
282 2, 2, 2, 2, 1, 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, 2,
283 2, 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, 3, 1, 2, 2, 2,
286 3, 4, 4, 1, 0, 1, 1, 1, 1, 2, 1, 2, 2, 3, 3, 2,
287 1, 0, 2, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1,
290 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
291 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
297 static u32 umc_initctla[DRAM_FREQ_NR] = {0x71016D11};
298 static u32 umc_initctlb[DRAM_FREQ_NR] = {0x07E390AC};
299 static u32 umc_initctlc[DRAM_FREQ_NR] = {0x00FF00FF};
300 static u32 umc_drmmr0[DRAM_FREQ_NR] = {0x00000114};
301 static u32 umc_drmmr2[DRAM_FREQ_NR] = {0x000002a0};
303 static u32 umc_memconf0a[DRAM_FREQ_NR][DRAM_SZ_NR] = {
305 {0x00000601, 0x00000801}, /* 1866 MHz */
307 static u32 umc_memconf0b[DRAM_FREQ_NR][DRAM_SZ_NR] = {
309 {0x00000120, 0x00000130}, /* 1866 MHz */
311 static u32 umc_memconfch[DRAM_FREQ_NR][DRAM_SZ_NR] = {
313 {0x00033603, 0x00033803}, /* 1866 MHz */
315 static u32 umc_cmdctla[DRAM_FREQ_NR] = {0x060D0D20};
316 static u32 umc_cmdctlb[DRAM_FREQ_NR] = {0x2D211C08};
317 static u32 umc_cmdctlc[DRAM_FREQ_NR] = {0x00150C04};
318 static u32 umc_cmdctle[DRAM_FREQ_NR][DRAM_SZ_NR] = {
320 {0x0049071D, 0x0078071D}, /* 1866 MHz */
323 static u32 umc_rdatactl_d0[DRAM_FREQ_NR] = {0x00000610};
324 static u32 umc_rdatactl_d1[DRAM_FREQ_NR] = {0x00000610};
325 static u32 umc_wdatactl_d0[DRAM_FREQ_NR] = {0x00000204};
326 static u32 umc_wdatactl_d1[DRAM_FREQ_NR] = {0x00000204};
327 static u32 umc_odtctl_d0[DRAM_FREQ_NR] = {0x02000002};
328 static u32 umc_odtctl_d1[DRAM_FREQ_NR] = {0x02000002};
329 static u32 umc_dataset[DRAM_FREQ_NR] = {0x04000000};
331 static u32 umc_flowctla[DRAM_FREQ_NR] = {0x0081E01E};
332 static u32 umc_directbusctrla[DRAM_CH_NR] = {
333 0x00000000, 0x00000001, 0x00000001
336 /* polling function for PHY Init Complete */
337 static void ddrphy_init_complete(void __iomem *dc_base)
339 /* Wait for PHY Init Complete */
340 while (!(readl(dc_base + UMC_DFISTCTLC) & BIT(0)))
345 static void ddrphy_init(void __iomem *phy_base, void __iomem *dc_base,
346 enum dram_freq freq, enum dram_board board, int ch)
348 writel(0x0C001001, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
349 while (!(readl(phy_base + PHY_UNIQUIFY_TSMC_IO_1) & BIT(1)))
351 writel(0x0C001000, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
353 writel(0x00000000, phy_base + PHY_DLL_INCR_TRIM_3);
354 writel(0x00000000, phy_base + PHY_DLL_INCR_TRIM_1);
355 writel(0x00000000, phy_base + PHY_LANE_SEL);
356 writel(0x00000005, phy_base + PHY_DLL_TRIM_1);
357 writel(0x0000000a, phy_base + PHY_DLL_TRIM_3);
358 writel(0x00000006, phy_base + PHY_LANE_SEL);
359 writel(0x00000005, phy_base + PHY_DLL_TRIM_1);
360 writel(0x0000000a, phy_base + PHY_DLL_TRIM_3);
361 writel(0x0000000c, phy_base + PHY_LANE_SEL);
362 writel(0x00000005, phy_base + PHY_DLL_TRIM_1);
363 writel(0x0000000a, phy_base + PHY_DLL_TRIM_3);
364 writel(0x00000012, phy_base + PHY_LANE_SEL);
365 writel(0x00000005, phy_base + PHY_DLL_TRIM_1);
366 writel(0x0000000a, phy_base + PHY_DLL_TRIM_3);
367 writel(0x00000001, phy_base + PHY_SCL_WINDOW_TRIM);
368 writel(0x00000000, phy_base + PHY_UNQ_ANALOG_DLL_1);
369 writel(dio_phy_pad_ctrl[board][ch], phy_base + PHY_PAD_CTRL);
370 writel(0x00000070, phy_base + PHY_VREF_TRAINING);
371 writel(0x01000075, phy_base + PHY_SCL_CONFIG_1);
372 writel(0x00000501, phy_base + PHY_SCL_CONFIG_2);
373 writel(0x00000000, phy_base + PHY_SCL_CONFIG_3);
374 writel(0x000261c0, phy_base + PHY_DYNAMIC_WRITE_BIT_LVL);
375 writel(0x00000000, phy_base + PHY_SCL_CONFIG_4);
376 writel(dio_scl_gate_timing[ch], phy_base + PHY_SCL_GATE_TIMING);
377 writel(0x02a000a0, phy_base + PHY_WRLVL_DYN_ODT);
378 writel(0x00840004, phy_base + PHY_WRLVL_ON_OFF);
379 writel(0x0000020d, phy_base + PHY_DLL_ADRCTRL);
380 writel(0x00000000, phy_base + PHY_LANE_SEL);
381 writel(0x0000008d, phy_base + PHY_DLL_TRIM_CLK);
382 writel(0xa800100d, phy_base + PHY_DLL_RECALIB);
383 writel(0x00005076, phy_base + PHY_SCL_LATENCY);
385 ddrphy_init_complete(dc_base);
387 ddrphy_set_dll_adrctrl(dio_adrctrl_0[board][ch], 0, phy_base);
388 ddrphy_set_dll_trim_clk(dio_dlltrimclk_0[board][ch], phy_base);
389 ddrphy_set_dll_recalib(dio_dllrecalib_0[board][ch], 0x10, 0, 0xa,
393 static void ddrphy_shift_dq(u32 reg_mask, u32 reg_addr, int shift_val,
394 void __iomem *phy_base)
399 reg_val = ddrphy_maskreadl(reg_mask, phy_base + reg_addr) & 0x7f;
400 dq_val = reg_val & 0x3f;
402 if ((reg_val & 0x40) == 0x00)
403 dq_val = -1 * dq_val;
406 dq_val = dq_val + shift_val;
409 reg_val = 0x40 + (dq_val & 0x3f);
411 reg_val = ((-1 * dq_val) & 0x3f);
413 ddrphy_maskwritel(reg_val, reg_mask, phy_base + reg_addr);
416 static void ddrphy_shift(void __iomem *phy_base, enum dram_board board, int ch)
420 /* set override = 1 */
421 ddrphy_maskwritel(MSK_OVERRIDE, MSK_OVERRIDE,
422 phy_base + PHY_OP_DQ_DM_DQS_BITWISE_TRIM);
423 ddrphy_maskwritel(MSK_OVERRIDE, MSK_OVERRIDE,
424 phy_base + PHY_IP_DQ_DQS_BITWISE_TRIM);
426 for (dx = 0; dx < 4; dx++) {
427 /* set byte to PHY_LANE_SEL.phy_lane_sel= dx * (PHY_BITLVL_DLY_WIDTH+1) */
428 ddrphy_set_phy_lane_sel(dx * (PHY_BITLVL_DLY_WIDTH + 1),
431 for (bit = 0; bit < 8; bit++) {
432 ddrphy_set_bit_sel(bit, phy_base);
434 /* shift write reg value*/
435 ddrphy_shift_dq(MSK_OP_DQ_DM_DQS_BITWISE_TRIM,
436 PHY_OP_DQ_DM_DQS_BITWISE_TRIM,
437 dio_op_dq_shift_val[board][ch][dx * 8 + bit],
439 /* shift read reg value */
440 ddrphy_shift_dq(MSK_IP_DQ_DQS_BITWISE_TRIM,
441 PHY_IP_DQ_DQS_BITWISE_TRIM,
442 dio_ip_dq_shift_val[board][ch][dx * 8 + bit],
447 ddrphy_set_phy_lane_sel(0, phy_base);
448 ddrphy_set_bit_sel(0, phy_base);
451 static int ddrphy_training(void __iomem *phy_base, enum dram_board board,
454 writel(0x0000000f, phy_base + PHY_WRLVL_AUTOINC_TRIM);
455 writel(0x00010000, phy_base + PHY_DLL_TRIM_2);
456 writel(0x50000000, phy_base + PHY_SCL_START);
458 while (readl(phy_base + PHY_SCL_START) & BIT(28))
461 writel(0x00000000, phy_base + PHY_DISABLE_GATING_FOR_SCL);
462 writel(0xff00ff00, phy_base + PHY_SCL_DATA_0);
463 writel(0xff00ff00, phy_base + PHY_SCL_DATA_1);
464 writel(0xFBF8FFFF, phy_base + PHY_SCL_START_ADDR);
465 writel(0x11000000, phy_base + PHY_SCL_START);
467 while (readl(phy_base + PHY_SCL_START) & BIT(28))
470 writel(0xFBF0FFFF, phy_base + PHY_SCL_START_ADDR);
471 writel(0x30500000, phy_base + PHY_SCL_START);
473 while (readl(phy_base + PHY_SCL_START) & BIT(28))
476 writel(0x00000001, phy_base + PHY_DISABLE_GATING_FOR_SCL);
477 writel(0x00000010, phy_base + PHY_SCL_MAIN_CLK_DELTA);
478 writel(0x789b3de0, phy_base + PHY_SCL_DATA_0);
479 writel(0xf10e4a56, phy_base + PHY_SCL_DATA_1);
480 writel(0x11000000, phy_base + PHY_SCL_START);
482 while (readl(phy_base + PHY_SCL_START) & BIT(28))
485 writel(0x34000000, phy_base + PHY_SCL_START);
487 while (readl(phy_base + PHY_SCL_START) & BIT(28))
490 writel(0x00000003, phy_base + PHY_DISABLE_GATING_FOR_SCL);
492 writel(0x000261c0, phy_base + PHY_DYNAMIC_WRITE_BIT_LVL);
493 writel(0x00003270, phy_base + PHY_DYNAMIC_BIT_LVL);
494 writel(0x011BD0C4, phy_base + PHY_DSCL_CNT);
496 /* shift ip_dq, op_dq trim */
497 ddrphy_shift(phy_base, board, ch);
501 static int umc_dc_init(void __iomem *dc_base, enum dram_freq freq,
502 unsigned long size, int ch)
504 enum dram_size size_e;
510 size_e = DRAM_SZ_256M;
513 size_e = DRAM_SZ_512M;
516 pr_err("unsupported DRAM size 0x%08lx (per 16bit) for ch%d\n",
521 writel(0x00000001, dc_base + UMC_DFICSOVRRD);
522 writel(0x00000000, dc_base + UMC_DFITURNOFF);
524 writel(umc_initctla[freq], dc_base + UMC_INITCTLA);
525 writel(umc_initctlb[freq], dc_base + UMC_INITCTLB);
526 writel(umc_initctlc[freq], dc_base + UMC_INITCTLC);
528 writel(umc_drmmr0[freq], dc_base + UMC_DRMMR0);
529 writel(0x00000004, dc_base + UMC_DRMMR1);
530 writel(umc_drmmr2[freq], dc_base + UMC_DRMMR2);
531 writel(0x00000000, dc_base + UMC_DRMMR3);
533 writel(umc_memconf0a[freq][size_e], dc_base + UMC_MEMCONF0A);
534 writel(umc_memconf0b[freq][size_e], dc_base + UMC_MEMCONF0B);
535 writel(umc_memconfch[freq][size_e], dc_base + UMC_MEMCONFCH);
536 writel(0x00000008, dc_base + UMC_MEMMAPSET);
538 writel(umc_cmdctla[freq], dc_base + UMC_CMDCTLA);
539 writel(umc_cmdctlb[freq], dc_base + UMC_CMDCTLB);
540 writel(umc_cmdctlc[freq], dc_base + UMC_CMDCTLC);
541 writel(umc_cmdctle[freq][size_e], dc_base + UMC_CMDCTLE);
543 writel(umc_rdatactl_d0[freq], dc_base + UMC_RDATACTL_D0);
544 writel(umc_rdatactl_d1[freq], dc_base + UMC_RDATACTL_D1);
546 writel(umc_wdatactl_d0[freq], dc_base + UMC_WDATACTL_D0);
547 writel(umc_wdatactl_d1[freq], dc_base + UMC_WDATACTL_D1);
548 writel(umc_odtctl_d0[freq], dc_base + UMC_ODTCTL_D0);
549 writel(umc_odtctl_d1[freq], dc_base + UMC_ODTCTL_D1);
550 writel(umc_dataset[freq], dc_base + UMC_DATASET);
552 writel(0x00400020, dc_base + UMC_DCCGCTL);
553 writel(0x00000003, dc_base + UMC_ACSSETA);
554 writel(0x00000103, dc_base + UMC_FLOWCTLG);
555 writel(0x00010200, dc_base + UMC_ACSSETB);
557 writel(umc_flowctla[freq], dc_base + UMC_FLOWCTLA);
558 writel(0x00004444, dc_base + UMC_FLOWCTLC);
559 writel(0x00000000, dc_base + UMC_DFICUPDCTLA);
561 writel(0x00202000, dc_base + UMC_FLOWCTLB);
562 writel(0x00000000, dc_base + UMC_BSICMAPSET);
563 writel(0x00000000, dc_base + UMC_ERRMASKA);
564 writel(0x00000000, dc_base + UMC_ERRMASKB);
566 writel(umc_directbusctrla[ch], dc_base + UMC_DIRECTBUSCTRLA);
568 writel(0x00000001, dc_base + UMC_INITSET);
569 /* Wait for PHY Init Complete */
570 while (readl(dc_base + UMC_INITSTAT) & BIT(0))
573 writel(0x2A0A0A00, dc_base + UMC_SPCSETB);
574 writel(0x00000000, dc_base + UMC_DFICSOVRRD);
579 static int umc_ch_init(void __iomem *umc_ch_base, void __iomem *phy_ch_base,
580 enum dram_freq freq, enum dram_board board,
581 unsigned long size, int ch)
583 void __iomem *dc_base = umc_ch_base + 0x00011000;
584 void __iomem *phy_base = phy_ch_base;
587 /* PHY Update Mode (ON) */
588 writel(0x8000003f, dc_base + UMC_DFIPUPDCTLA);
590 /* deassert PHY reset signals */
591 writel(UMC_DIOCTLA_CTL_NRST | UMC_DIOCTLA_CFG_NRST,
592 dc_base + UMC_DIOCTLA);
594 ddrphy_init(phy_base, dc_base, freq, board, ch);
596 ret = umc_dc_init(dc_base, freq, size, ch);
600 ret = ddrphy_training(phy_base, board, ch);
607 static void um_init(void __iomem *um_base)
609 writel(0x000000ff, um_base + UMC_MBUS0);
610 writel(0x000000ff, um_base + UMC_MBUS1);
611 writel(0x000000ff, um_base + UMC_MBUS2);
612 writel(0x00000001, um_base + UMC_MBUS3);
613 writel(0x00000001, um_base + UMC_MBUS4);
614 writel(0x00000001, um_base + UMC_MBUS5);
615 writel(0x00000001, um_base + UMC_MBUS6);
616 writel(0x00000001, um_base + UMC_MBUS7);
617 writel(0x00000001, um_base + UMC_MBUS8);
618 writel(0x00000001, um_base + UMC_MBUS9);
619 writel(0x00000001, um_base + UMC_MBUS10);
622 int uniphier_ld20_umc_init(const struct uniphier_board_data *bd)
624 void __iomem *um_base = (void __iomem *)0x5b600000;
625 void __iomem *umc_ch_base = (void __iomem *)0x5b800000;
626 void __iomem *phy_ch_base = (void __iomem *)0x6e200000;
628 enum dram_board board;
631 switch (bd->dram_freq) {
633 freq = DRAM_FREQ_1866M;
636 pr_err("unsupported DRAM frequency %d MHz\n", bd->dram_freq);
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, freq, board,
664 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;