157b915a7b7ec9ca53130fbd058c1333df9c53df
[oweals/u-boot.git] / arch / arm / mach-uniphier / dram / umc-ld20.c
1 /*
2  * Copyright (C) 2016-2017 Socionext Inc.
3  *
4  * based on commit e732175d0b0dbc2a3855cb8ac791c538666b6fd4 of Diag
5  *
6  * SPDX-License-Identifier:     GPL-2.0+
7  */
8
9 #include <common.h>
10 #include <linux/bitops.h>
11 #include <linux/compat.h>
12 #include <linux/errno.h>
13 #include <linux/io.h>
14 #include <linux/sizes.h>
15 #include <asm/processor.h>
16
17 #include "../init.h"
18 #include "ddruqphy-regs.h"
19 #include "umc64-regs.h"
20
21 #define DRAM_CH_NR      3
22
23 enum dram_freq {
24         DRAM_FREQ_1866M,
25         DRAM_FREQ_NR,
26 };
27
28 enum dram_size {
29         DRAM_SZ_256M,
30         DRAM_SZ_512M,
31         DRAM_SZ_NR,
32 };
33
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 */
40         DRAM_BOARD_NR,
41 };
42
43 /* PHY */
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 */
50 };
51
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 */
58 };
59
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 */
66 };
67
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 */
74 };
75
76 static const u32 ddrphy_scl_gate_timing[DRAM_CH_NR] = {
77         0x00000140, 0x00000180, 0x00000140
78 };
79
80 static const short ddrphy_op_dq_shift_val_ld20[DRAM_CH_NR][32] = {
81         {
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,
86         },
87         {
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,
92         },
93         {
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,
98         },
99 };
100
101 static const short ddrphy_op_dq_shift_val_ld21[DRAM_CH_NR][32] = {
102         {
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,
107         },
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,
112         },
113         /* No CH2 */
114 };
115
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 */
122 };
123
124 static const short ddrphy_ip_dq_shift_val_ld20[DRAM_CH_NR][32] = {
125         {
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,
130         },
131         {
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,
136         },
137         {
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,
142         },
143 };
144
145 static const short ddrphy_ip_dq_shift_val_ld21[DRAM_CH_NR][32] = {
146         {
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,
151         },
152         {
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,
157         },
158         /* No CH2 */
159 };
160
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 */
167 };
168
169 static void ddrphy_select_lane(void __iomem *phy_base, unsigned int lane,
170                                unsigned int bit)
171 {
172         WARN_ON(lane >= 1 << PHY_LANE_SEL_LANE_WIDTH);
173         WARN_ON(bit >= 1 << PHY_LANE_SEL_BIT_WIDTH);
174
175         writel((bit << PHY_LANE_SEL_BIT_SHIFT) |
176                (lane << PHY_LANE_SEL_LANE_SHIFT),
177                phy_base + PHY_LANE_SEL);
178 }
179
180 static void ddrphy_init(void __iomem *phy_base, enum dram_board board, int ch)
181 {
182         writel(0x0C001001, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
183         while (!(readl(phy_base + PHY_UNIQUIFY_TSMC_IO_1) & BIT(1)))
184                 cpu_relax();
185         writel(0x0C001000, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
186
187         writel(0x00000000, phy_base + PHY_DLL_INCR_TRIM_3);
188         writel(0x00000000, phy_base + PHY_DLL_INCR_TRIM_1);
189         ddrphy_select_lane(phy_base, 0, 0);
190         writel(0x00000005, phy_base + PHY_DLL_TRIM_1);
191         writel(0x0000000a, phy_base + PHY_DLL_TRIM_3);
192         ddrphy_select_lane(phy_base, 6, 0);
193         writel(0x00000005, phy_base + PHY_DLL_TRIM_1);
194         writel(0x0000000a, phy_base + PHY_DLL_TRIM_3);
195         ddrphy_select_lane(phy_base, 12, 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, 18, 0);
199         writel(0x00000005, phy_base + PHY_DLL_TRIM_1);
200         writel(0x0000000a, phy_base + PHY_DLL_TRIM_3);
201         writel(0x00000001, phy_base + PHY_SCL_WINDOW_TRIM);
202         writel(0x00000000, phy_base + PHY_UNQ_ANALOG_DLL_1);
203         writel(ddrphy_phy_pad_ctrl[board][ch], phy_base + PHY_PAD_CTRL);
204         writel(0x00000070, phy_base + PHY_VREF_TRAINING);
205         writel(0x01000075, phy_base + PHY_SCL_CONFIG_1);
206         writel(0x00000501, phy_base + PHY_SCL_CONFIG_2);
207         writel(0x00000000, phy_base + PHY_SCL_CONFIG_3);
208         writel(0x000261c0, phy_base + PHY_DYNAMIC_WRITE_BIT_LVL);
209         writel(0x00000000, phy_base + PHY_SCL_CONFIG_4);
210         writel(ddrphy_scl_gate_timing[ch], phy_base + PHY_SCL_GATE_TIMING);
211         writel(0x02a000a0, phy_base + PHY_WRLVL_DYN_ODT);
212         writel(0x00840004, phy_base + PHY_WRLVL_ON_OFF);
213         writel(0x0000020d, phy_base + PHY_DLL_ADRCTRL);
214         ddrphy_select_lane(phy_base, 0, 0);
215         writel(0x0000008d, phy_base + PHY_DLL_TRIM_CLK);
216         writel(0xa800100d, phy_base + PHY_DLL_RECALIB);
217         writel(0x00005076, phy_base + PHY_SCL_LATENCY);
218 }
219
220 static int ddrphy_to_dly_step(void __iomem *phy_base, unsigned int freq,
221                               int delay)
222 {
223         int mdl;
224
225         mdl = (readl(phy_base + PHY_DLL_ADRCTRL) & PHY_DLL_ADRCTRL_MDL_MASK) >>
226                                                 PHY_DLL_ADRCTRL_MDL_SHIFT;
227
228         return DIV_ROUND_CLOSEST((long)freq * delay * mdl, 2 * 1000000L);
229 }
230
231 static void ddrphy_set_delay(void __iomem *phy_base, unsigned int reg,
232                              u32 mask, u32 incr, int dly_step)
233 {
234         u32 tmp;
235
236         tmp = readl(phy_base + reg);
237         tmp &= ~mask;
238         tmp |= min_t(u32, abs(dly_step), mask);
239
240         if (dly_step >= 0)
241                 tmp |= incr;
242         else
243                 tmp &= ~incr;
244
245         writel(tmp, phy_base + reg);
246 }
247
248 static void ddrphy_set_dll_recalib(void __iomem *phy_base, int dly_step)
249 {
250         ddrphy_set_delay(phy_base, PHY_DLL_RECALIB,
251                          PHY_DLL_RECALIB_TRIM_MASK, PHY_DLL_RECALIB_INCR,
252                          dly_step);
253 }
254
255 static void ddrphy_set_dll_adrctrl(void __iomem *phy_base, int dly_step)
256 {
257         ddrphy_set_delay(phy_base, PHY_DLL_ADRCTRL,
258                          PHY_DLL_ADRCTRL_TRIM_MASK, PHY_DLL_ADRCTRL_INCR,
259                          dly_step);
260 }
261
262 static void ddrphy_set_dll_trim_clk(void __iomem *phy_base, int dly_step)
263 {
264         ddrphy_select_lane(phy_base, 0, 0);
265
266         ddrphy_set_delay(phy_base, PHY_DLL_TRIM_CLK,
267                          PHY_DLL_TRIM_CLK_MASK, PHY_DLL_TRIM_CLK_INCR,
268                          dly_step);
269 }
270
271 static void ddrphy_init_tail(void __iomem *phy_base, enum dram_board board,
272                              unsigned int freq, int ch)
273 {
274         int step;
275
276         step = ddrphy_to_dly_step(phy_base, freq, ddrphy_adrctrl[board][ch]);
277         ddrphy_set_dll_adrctrl(phy_base, step);
278
279         step = ddrphy_to_dly_step(phy_base, freq, ddrphy_dlltrimclk[board][ch]);
280         ddrphy_set_dll_trim_clk(phy_base, step);
281
282         step = ddrphy_to_dly_step(phy_base, freq, ddrphy_dllrecalib[board][ch]);
283         ddrphy_set_dll_recalib(phy_base, step);
284 }
285
286 static void ddrphy_shift_one_dq(void __iomem *phy_base, unsigned int reg,
287                                 u32 mask, u32 incr, short shift_val)
288 {
289         u32 tmp;
290         int val;
291
292         tmp = readl(phy_base + reg);
293
294         val = tmp & mask;
295         if (!(tmp & incr))
296                 val = -val;
297
298         val += shift_val;
299
300         tmp &= ~(incr | mask);
301         tmp |= min_t(u32, abs(val), mask);
302         if (val >= 0)
303                 tmp |= incr;
304
305         writel(tmp, phy_base + reg);
306 }
307
308 static void ddrphy_shift_dq(void __iomem *phy_base, unsigned int reg,
309                             u32 mask, u32 incr, u32 override,
310                             const short *shift_val_array)
311 {
312         u32 tmp;
313         int dx, bit;
314
315         tmp = readl(phy_base + reg);
316         tmp |= override;
317         writel(tmp, phy_base + reg);
318
319         for (dx = 0; dx < 4; dx++) {
320                 for (bit = 0; bit < 8; bit++) {
321                         ddrphy_select_lane(phy_base,
322                                            (PHY_BITLVL_DLY_WIDTH + 1) * dx,
323                                            bit);
324
325                         ddrphy_shift_one_dq(phy_base, reg, mask, incr,
326                                             shift_val_array[dx * 8 + bit]);
327                 }
328         }
329
330         ddrphy_select_lane(phy_base, 0, 0);
331 }
332
333 static int ddrphy_training(void __iomem *phy_base, enum dram_board board,
334                            int ch)
335 {
336         writel(0x0000000f, phy_base + PHY_WRLVL_AUTOINC_TRIM);
337         writel(0x00010000, phy_base + PHY_DLL_TRIM_2);
338         writel(0x50000000, phy_base + PHY_SCL_START);
339
340         while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE)
341                 cpu_relax();
342
343         writel(0x00000000, phy_base + PHY_DISABLE_GATING_FOR_SCL);
344         writel(0xff00ff00, phy_base + PHY_SCL_DATA_0);
345         writel(0xff00ff00, phy_base + PHY_SCL_DATA_1);
346         writel(0xFBF8FFFF, phy_base + PHY_SCL_START_ADDR);
347         writel(0x11000000, phy_base + PHY_SCL_START);
348
349         while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE)
350                 cpu_relax();
351
352         writel(0xFBF0FFFF, phy_base + PHY_SCL_START_ADDR);
353         writel(0x30500000, phy_base + PHY_SCL_START);
354
355         while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE)
356                 cpu_relax();
357
358         writel(0x00000001, phy_base + PHY_DISABLE_GATING_FOR_SCL);
359         writel(0x00000010, phy_base + PHY_SCL_MAIN_CLK_DELTA);
360         writel(0x789b3de0, phy_base + PHY_SCL_DATA_0);
361         writel(0xf10e4a56, phy_base + PHY_SCL_DATA_1);
362         writel(0x11000000, phy_base + PHY_SCL_START);
363
364         while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE)
365                 cpu_relax();
366
367         writel(0x34000000, phy_base + PHY_SCL_START);
368
369         while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE)
370                 cpu_relax();
371
372         writel(0x00000003, phy_base + PHY_DISABLE_GATING_FOR_SCL);
373
374         writel(0x000261c0, phy_base + PHY_DYNAMIC_WRITE_BIT_LVL);
375         writel(0x00003270, phy_base + PHY_DYNAMIC_BIT_LVL);
376         writel(0x011BD0C4, phy_base + PHY_DSCL_CNT);
377
378         /* shift ip_dq trim */
379         ddrphy_shift_dq(phy_base,
380                         PHY_IP_DQ_DQS_BITWISE_TRIM,
381                         PHY_IP_DQ_DQS_BITWISE_TRIM_MASK,
382                         PHY_IP_DQ_DQS_BITWISE_TRIM_INC,
383                         PHY_IP_DQ_DQS_BITWISE_TRIM_OVERRIDE,
384                         ddrphy_ip_dq_shift_val[board][ch]);
385
386         /* shift op_dq trim */
387         ddrphy_shift_dq(phy_base,
388                         PHY_OP_DQ_DM_DQS_BITWISE_TRIM,
389                         PHY_OP_DQ_DM_DQS_BITWISE_TRIM_MASK,
390                         PHY_OP_DQ_DM_DQS_BITWISE_TRIM_INC,
391                         PHY_OP_DQ_DM_DQS_BITWISE_TRIM_OVERRIDE,
392                         ddrphy_op_dq_shift_val[board][ch]);
393
394         return 0;
395 }
396
397 /* UMC */
398 static const u32 umc_initctla[DRAM_FREQ_NR] = {0x71016D11};
399 static const u32 umc_initctlb[DRAM_FREQ_NR] = {0x07E390AC};
400 static const u32 umc_initctlc[DRAM_FREQ_NR] = {0x00FF00FF};
401 static const u32 umc_drmmr0[DRAM_FREQ_NR] = {0x00000114};
402 static const u32 umc_drmmr2[DRAM_FREQ_NR] = {0x000002a0};
403
404 static const u32 umc_memconf0a[DRAM_FREQ_NR][DRAM_SZ_NR] = {
405         /*  256MB       512MB */
406         {0x00000601, 0x00000801},       /* 1866 MHz */
407 };
408
409 static const u32 umc_memconf0b[DRAM_FREQ_NR][DRAM_SZ_NR] = {
410         /*  256MB       512MB */
411         {0x00000120, 0x00000130},       /* 1866 MHz */
412 };
413
414 static const u32 umc_memconfch[DRAM_FREQ_NR][DRAM_SZ_NR] = {
415         /*  256MB       512MB */
416         {0x00033603, 0x00033803},       /* 1866 MHz */
417 };
418
419 static const u32 umc_cmdctla[DRAM_FREQ_NR] = {0x060D0D20};
420 static const u32 umc_cmdctlb[DRAM_FREQ_NR] = {0x2D211C08};
421 static const u32 umc_cmdctlc[DRAM_FREQ_NR] = {0x00150C04};
422 static const u32 umc_cmdctle[DRAM_FREQ_NR][DRAM_SZ_NR] = {
423         /*  256MB       512MB */
424         {0x0049071D, 0x0078071D},       /* 1866 MHz */
425 };
426
427 static const u32 umc_rdatactl[DRAM_FREQ_NR] = {0x00000610};
428 static const u32 umc_wdatactl[DRAM_FREQ_NR] = {0x00000204};
429 static const u32 umc_odtctl[DRAM_FREQ_NR] = {0x02000002};
430 static const u32 umc_dataset[DRAM_FREQ_NR] = {0x04000000};
431
432 static const u32 umc_flowctla[DRAM_FREQ_NR] = {0x0081E01E};
433 static const u32 umc_directbusctrla[DRAM_CH_NR] = {
434         0x00000000, 0x00000001, 0x00000001
435 };
436
437 static void umc_poll_phy_init_complete(void __iomem *dc_base)
438 {
439         /* Wait for PHY Init Complete */
440         while (!(readl(dc_base + UMC_DFISTCTLC) & BIT(0)))
441                 cpu_relax();
442 }
443
444 static int umc_dc_init(void __iomem *dc_base, unsigned int freq,
445                        unsigned long size, int ch)
446 {
447         enum dram_freq freq_e;
448         enum dram_size size_e;
449
450         switch (freq) {
451         case 1866:
452                 freq_e = DRAM_FREQ_1866M;
453                 break;
454         default:
455                 pr_err("unsupported DRAM frequency %ud MHz\n", freq);
456                 return -EINVAL;
457         }
458
459         switch (size) {
460         case 0:
461                 return 0;
462         case SZ_256M:
463                 size_e = DRAM_SZ_256M;
464                 break;
465         case SZ_512M:
466                 size_e = DRAM_SZ_512M;
467                 break;
468         default:
469                 pr_err("unsupported DRAM size 0x%08lx (per 16bit) for ch%d\n",
470                        size, ch);
471                 return -EINVAL;
472         }
473
474         writel(0x00000001, dc_base + UMC_DFICSOVRRD);
475         writel(0x00000000, dc_base + UMC_DFITURNOFF);
476
477         writel(umc_initctla[freq_e], dc_base + UMC_INITCTLA);
478         writel(umc_initctlb[freq_e], dc_base + UMC_INITCTLB);
479         writel(umc_initctlc[freq_e], dc_base + UMC_INITCTLC);
480
481         writel(umc_drmmr0[freq_e], dc_base + UMC_DRMMR0);
482         writel(0x00000004, dc_base + UMC_DRMMR1);
483         writel(umc_drmmr2[freq_e], dc_base + UMC_DRMMR2);
484         writel(0x00000000, dc_base + UMC_DRMMR3);
485
486         writel(umc_memconf0a[freq_e][size_e], dc_base + UMC_MEMCONF0A);
487         writel(umc_memconf0b[freq_e][size_e], dc_base + UMC_MEMCONF0B);
488         writel(umc_memconfch[freq_e][size_e], dc_base + UMC_MEMCONFCH);
489         writel(0x00000000, dc_base + UMC_MEMMAPSET);
490
491         writel(umc_cmdctla[freq_e], dc_base + UMC_CMDCTLA);
492         writel(umc_cmdctlb[freq_e], dc_base + UMC_CMDCTLB);
493         writel(umc_cmdctlc[freq_e], dc_base + UMC_CMDCTLC);
494         writel(umc_cmdctle[freq_e][size_e], dc_base + UMC_CMDCTLE);
495
496         writel(umc_rdatactl[freq_e], dc_base + UMC_RDATACTL_D0);
497         writel(umc_rdatactl[freq_e], dc_base + UMC_RDATACTL_D1);
498
499         writel(umc_wdatactl[freq_e], dc_base + UMC_WDATACTL_D0);
500         writel(umc_wdatactl[freq_e], dc_base + UMC_WDATACTL_D1);
501         writel(umc_odtctl[freq_e], dc_base + UMC_ODTCTL_D0);
502         writel(umc_odtctl[freq_e], dc_base + UMC_ODTCTL_D1);
503         writel(umc_dataset[freq_e], dc_base + UMC_DATASET);
504
505         writel(0x00400020, dc_base + UMC_DCCGCTL);
506         writel(0x00000003, dc_base + UMC_ACSSETA);
507         writel(0x00000103, dc_base + UMC_FLOWCTLG);
508         writel(0x00010200, dc_base + UMC_ACSSETB);
509
510         writel(umc_flowctla[freq_e], dc_base + UMC_FLOWCTLA);
511         writel(0x00004444, dc_base + UMC_FLOWCTLC);
512         writel(0x00000000, dc_base + UMC_DFICUPDCTLA);
513
514         writel(0x00202000, dc_base + UMC_FLOWCTLB);
515         writel(0x00000000, dc_base + UMC_BSICMAPSET);
516         writel(0x00000000, dc_base + UMC_ERRMASKA);
517         writel(0x00000000, dc_base + UMC_ERRMASKB);
518
519         writel(umc_directbusctrla[ch], dc_base + UMC_DIRECTBUSCTRLA);
520
521         writel(0x00000001, dc_base + UMC_INITSET);
522         /* Wait for PHY Init Complete */
523         while (readl(dc_base + UMC_INITSTAT) & BIT(0))
524                 cpu_relax();
525
526         writel(0x2A0A0A00, dc_base + UMC_SPCSETB);
527         writel(0x00000000, dc_base + UMC_DFICSOVRRD);
528
529         return 0;
530 }
531
532 static int umc_ch_init(void __iomem *umc_ch_base, void __iomem *phy_ch_base,
533                        enum dram_board board, unsigned int freq,
534                        unsigned long size, int ch)
535 {
536         void __iomem *dc_base = umc_ch_base + 0x00011000;
537         void __iomem *phy_base = phy_ch_base;
538         int ret;
539
540         /* PHY Update Mode (ON) */
541         writel(0x8000003f, dc_base + UMC_DFIPUPDCTLA);
542
543         /* deassert PHY reset signals */
544         writel(UMC_DIOCTLA_CTL_NRST | UMC_DIOCTLA_CFG_NRST,
545                dc_base + UMC_DIOCTLA);
546
547         ddrphy_init(phy_base, board, ch);
548
549         umc_poll_phy_init_complete(dc_base);
550
551         ddrphy_init_tail(phy_base, board, freq, ch);
552
553         ret = umc_dc_init(dc_base, freq, size, ch);
554         if (ret)
555                 return ret;
556
557         ret = ddrphy_training(phy_base, board, ch);
558         if (ret)
559                 return ret;
560
561         return 0;
562 }
563
564 static void um_init(void __iomem *um_base)
565 {
566         writel(0x000000ff, um_base + UMC_MBUS0);
567         writel(0x000000ff, um_base + UMC_MBUS1);
568         writel(0x000000ff, um_base + UMC_MBUS2);
569         writel(0x00000001, um_base + UMC_MBUS3);
570         writel(0x00000001, um_base + UMC_MBUS4);
571         writel(0x00000001, um_base + UMC_MBUS5);
572         writel(0x00000001, um_base + UMC_MBUS6);
573         writel(0x00000001, um_base + UMC_MBUS7);
574         writel(0x00000001, um_base + UMC_MBUS8);
575         writel(0x00000001, um_base + UMC_MBUS9);
576         writel(0x00000001, um_base + UMC_MBUS10);
577 }
578
579 int uniphier_ld20_umc_init(const struct uniphier_board_data *bd)
580 {
581         void __iomem *um_base = (void __iomem *)0x5b600000;
582         void __iomem *umc_ch_base = (void __iomem *)0x5b800000;
583         void __iomem *phy_ch_base = (void __iomem *)0x6e200000;
584         enum dram_board board;
585         int ch, ret;
586
587         switch (UNIPHIER_BD_BOARD_GET_TYPE(bd->flags)) {
588         case UNIPHIER_BD_BOARD_LD20_REF:
589                 board = DRAM_BOARD_LD20_REF;
590                 break;
591         case UNIPHIER_BD_BOARD_LD20_GLOBAL:
592                 board = DRAM_BOARD_LD20_GLOBAL;
593                 break;
594         case UNIPHIER_BD_BOARD_LD20_C1:
595                 board = DRAM_BOARD_LD20_C1;
596                 break;
597         case UNIPHIER_BD_BOARD_LD21_REF:
598                 board = DRAM_BOARD_LD21_REF;
599                 break;
600         case UNIPHIER_BD_BOARD_LD21_GLOBAL:
601                 board = DRAM_BOARD_LD21_GLOBAL;
602                 break;
603         default:
604                 pr_err("unsupported board type %d\n",
605                        UNIPHIER_BD_BOARD_GET_TYPE(bd->flags));
606                 return -EINVAL;
607         }
608
609         for (ch = 0; ch < bd->dram_nr_ch; ch++) {
610                 unsigned long size = bd->dram_ch[ch].size;
611                 unsigned int width = bd->dram_ch[ch].width;
612
613                 ret = umc_ch_init(umc_ch_base, phy_ch_base, board,
614                                   bd->dram_freq, size / (width / 16), ch);
615                 if (ret) {
616                         pr_err("failed to initialize UMC ch%d\n", ch);
617                         return ret;
618                 }
619
620                 umc_ch_base += 0x00200000;
621                 phy_ch_base += 0x00004000;
622         }
623
624         um_init(um_base);
625
626         return 0;
627 }