arm: socfpga: Enable all FPGA config support for Arria 10
[platform/kernel/u-boot.git] / arch / arm / mach-uniphier / dram / umc-ld20.c
1 /*
2  * Copyright (C) 2016-2017 Socionext Inc.
3  *
4  * based on commit 5ffd75ecd4929f22361ef65a35f0331d2fbc0f35 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 #define DDRPHY_EFUSEMON         (void *)0x5f900118
181
182 static void ddrphy_init(void __iomem *phy_base, enum dram_board board, int ch)
183 {
184         writel(0x0C001001, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
185         while (!(readl(phy_base + PHY_UNIQUIFY_TSMC_IO_1) & BIT(1)))
186                 cpu_relax();
187
188         if (readl(DDRPHY_EFUSEMON) & BIT(ch))
189                 writel(0x00000000, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
190         else
191                 writel(0x0C001000, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
192
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);
224 }
225
226 static int ddrphy_to_dly_step(void __iomem *phy_base, unsigned int freq,
227                               int delay)
228 {
229         int mdl;
230
231         mdl = (readl(phy_base + PHY_DLL_ADRCTRL) & PHY_DLL_ADRCTRL_MDL_MASK) >>
232                                                 PHY_DLL_ADRCTRL_MDL_SHIFT;
233
234         return DIV_ROUND_CLOSEST((long)freq * delay * mdl, 2 * 1000000L);
235 }
236
237 static void ddrphy_set_delay(void __iomem *phy_base, unsigned int reg,
238                              u32 mask, u32 incr, int dly_step)
239 {
240         u32 tmp;
241
242         tmp = readl(phy_base + reg);
243         tmp &= ~mask;
244         tmp |= min_t(u32, abs(dly_step), mask);
245
246         if (dly_step >= 0)
247                 tmp |= incr;
248         else
249                 tmp &= ~incr;
250
251         writel(tmp, phy_base + reg);
252 }
253
254 static void ddrphy_set_dll_recalib(void __iomem *phy_base, int dly_step)
255 {
256         ddrphy_set_delay(phy_base, PHY_DLL_RECALIB,
257                          PHY_DLL_RECALIB_TRIM_MASK, PHY_DLL_RECALIB_INCR,
258                          dly_step);
259 }
260
261 static void ddrphy_set_dll_adrctrl(void __iomem *phy_base, int dly_step)
262 {
263         ddrphy_set_delay(phy_base, PHY_DLL_ADRCTRL,
264                          PHY_DLL_ADRCTRL_TRIM_MASK, PHY_DLL_ADRCTRL_INCR,
265                          dly_step);
266 }
267
268 static void ddrphy_set_dll_trim_clk(void __iomem *phy_base, int dly_step)
269 {
270         ddrphy_select_lane(phy_base, 0, 0);
271
272         ddrphy_set_delay(phy_base, PHY_DLL_TRIM_CLK,
273                          PHY_DLL_TRIM_CLK_MASK, PHY_DLL_TRIM_CLK_INCR,
274                          dly_step);
275 }
276
277 static void ddrphy_init_tail(void __iomem *phy_base, enum dram_board board,
278                              unsigned int freq, int ch)
279 {
280         int step;
281
282         step = ddrphy_to_dly_step(phy_base, freq, ddrphy_adrctrl[board][ch]);
283         ddrphy_set_dll_adrctrl(phy_base, step);
284
285         step = ddrphy_to_dly_step(phy_base, freq, ddrphy_dlltrimclk[board][ch]);
286         ddrphy_set_dll_trim_clk(phy_base, step);
287
288         step = ddrphy_to_dly_step(phy_base, freq, ddrphy_dllrecalib[board][ch]);
289         ddrphy_set_dll_recalib(phy_base, step);
290 }
291
292 static void ddrphy_shift_one_dq(void __iomem *phy_base, unsigned int reg,
293                                 u32 mask, u32 incr, short shift_val)
294 {
295         u32 tmp;
296         int val;
297
298         tmp = readl(phy_base + reg);
299
300         val = tmp & mask;
301         if (!(tmp & incr))
302                 val = -val;
303
304         val += shift_val;
305
306         tmp &= ~(incr | mask);
307         tmp |= min_t(u32, abs(val), mask);
308         if (val >= 0)
309                 tmp |= incr;
310
311         writel(tmp, phy_base + reg);
312 }
313
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)
317 {
318         u32 tmp;
319         int dx, bit;
320
321         tmp = readl(phy_base + reg);
322         tmp |= override;
323         writel(tmp, phy_base + reg);
324
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,
329                                            bit);
330
331                         ddrphy_shift_one_dq(phy_base, reg, mask, incr,
332                                             shift_val_array[dx * 8 + bit]);
333                 }
334         }
335
336         ddrphy_select_lane(phy_base, 0, 0);
337 }
338
339 static int ddrphy_training(void __iomem *phy_base, enum dram_board board,
340                            int ch)
341 {
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);
345
346         while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE)
347                 cpu_relax();
348
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);
354
355         while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE)
356                 cpu_relax();
357
358         writel(0xFBF0FFFF, phy_base + PHY_SCL_START_ADDR);
359         writel(0x30500000, phy_base + PHY_SCL_START);
360
361         while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE)
362                 cpu_relax();
363
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);
369
370         while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE)
371                 cpu_relax();
372
373         writel(0x34000000, phy_base + PHY_SCL_START);
374
375         while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE)
376                 cpu_relax();
377
378         writel(0x00000003, phy_base + PHY_DISABLE_GATING_FOR_SCL);
379
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);
383
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]);
391
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]);
399
400         return 0;
401 }
402
403 /* UMC */
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};
409
410 static const u32 umc_memconf0a[DRAM_FREQ_NR][DRAM_SZ_NR] = {
411         /*  256MB       512MB */
412         {0x00000601, 0x00000801},       /* 1866 MHz */
413 };
414
415 static const u32 umc_memconf0b[DRAM_FREQ_NR][DRAM_SZ_NR] = {
416         /*  256MB       512MB */
417         {0x00000120, 0x00000130},       /* 1866 MHz */
418 };
419
420 static const u32 umc_memconfch[DRAM_FREQ_NR][DRAM_SZ_NR] = {
421         /*  256MB       512MB */
422         {0x00033603, 0x00033803},       /* 1866 MHz */
423 };
424
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] = {
429         /*  256MB       512MB */
430         {0x0049071D, 0x0078071D},       /* 1866 MHz */
431 };
432
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};
437
438 static const u32 umc_flowctla[DRAM_FREQ_NR] = {0x0081E01E};
439 static const u32 umc_directbusctrla[DRAM_CH_NR] = {
440         0x00000000, 0x00000001, 0x00000001
441 };
442
443 static void umc_poll_phy_init_complete(void __iomem *dc_base)
444 {
445         /* Wait for PHY Init Complete */
446         while (!(readl(dc_base + UMC_DFISTCTLC) & BIT(0)))
447                 cpu_relax();
448 }
449
450 static int umc_dc_init(void __iomem *dc_base, unsigned int freq,
451                        unsigned long size, int ch)
452 {
453         enum dram_freq freq_e;
454         enum dram_size size_e;
455
456         switch (freq) {
457         case 1866:
458                 freq_e = DRAM_FREQ_1866M;
459                 break;
460         default:
461                 pr_err("unsupported DRAM frequency %ud MHz\n", freq);
462                 return -EINVAL;
463         }
464
465         switch (size) {
466         case 0:
467                 return 0;
468         case SZ_256M:
469                 size_e = DRAM_SZ_256M;
470                 break;
471         case SZ_512M:
472                 size_e = DRAM_SZ_512M;
473                 break;
474         default:
475                 pr_err("unsupported DRAM size 0x%08lx (per 16bit) for ch%d\n",
476                        size, ch);
477                 return -EINVAL;
478         }
479
480         writel(0x00000001, dc_base + UMC_DFICSOVRRD);
481         writel(0x00000000, dc_base + UMC_DFITURNOFF);
482
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);
486
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);
491
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);
496
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);
501
502         writel(umc_rdatactl[freq_e], dc_base + UMC_RDATACTL_D0);
503         writel(umc_rdatactl[freq_e], dc_base + UMC_RDATACTL_D1);
504
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);
510
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);
515
516         writel(umc_flowctla[freq_e], dc_base + UMC_FLOWCTLA);
517         writel(0x00004444, dc_base + UMC_FLOWCTLC);
518         writel(0x00000000, dc_base + UMC_DFICUPDCTLA);
519
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);
524
525         writel(umc_directbusctrla[ch], dc_base + UMC_DIRECTBUSCTRLA);
526
527         writel(0x00000001, dc_base + UMC_INITSET);
528         /* Wait for PHY Init Complete */
529         while (readl(dc_base + UMC_INITSTAT) & BIT(0))
530                 cpu_relax();
531
532         writel(0x2A0A0A00, dc_base + UMC_SPCSETB);
533         writel(0x00000000, dc_base + UMC_DFICSOVRRD);
534
535         return 0;
536 }
537
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)
541 {
542         void __iomem *dc_base = umc_ch_base + 0x00011000;
543         void __iomem *phy_base = phy_ch_base;
544         int ret;
545
546         /* PHY Update Mode (ON) */
547         writel(0x8000003f, dc_base + UMC_DFIPUPDCTLA);
548
549         /* deassert PHY reset signals */
550         writel(UMC_DIOCTLA_CTL_NRST | UMC_DIOCTLA_CFG_NRST,
551                dc_base + UMC_DIOCTLA);
552
553         ddrphy_init(phy_base, board, ch);
554
555         umc_poll_phy_init_complete(dc_base);
556
557         ddrphy_init_tail(phy_base, board, freq, ch);
558
559         ret = umc_dc_init(dc_base, freq, size, ch);
560         if (ret)
561                 return ret;
562
563         ret = ddrphy_training(phy_base, board, ch);
564         if (ret)
565                 return ret;
566
567         return 0;
568 }
569
570 static void um_init(void __iomem *um_base)
571 {
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);
583 }
584
585 int uniphier_ld20_umc_init(const struct uniphier_board_data *bd)
586 {
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;
591         int ch, ret;
592
593         switch (UNIPHIER_BD_BOARD_GET_TYPE(bd->flags)) {
594         case UNIPHIER_BD_BOARD_LD20_REF:
595                 board = DRAM_BOARD_LD20_REF;
596                 break;
597         case UNIPHIER_BD_BOARD_LD20_GLOBAL:
598                 board = DRAM_BOARD_LD20_GLOBAL;
599                 break;
600         case UNIPHIER_BD_BOARD_LD20_C1:
601                 board = DRAM_BOARD_LD20_C1;
602                 break;
603         case UNIPHIER_BD_BOARD_LD21_REF:
604                 board = DRAM_BOARD_LD21_REF;
605                 break;
606         case UNIPHIER_BD_BOARD_LD21_GLOBAL:
607                 board = DRAM_BOARD_LD21_GLOBAL;
608                 break;
609         default:
610                 pr_err("unsupported board type %d\n",
611                        UNIPHIER_BD_BOARD_GET_TYPE(bd->flags));
612                 return -EINVAL;
613         }
614
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;
618
619                 if (size) {
620                         ret = umc_ch_init(umc_ch_base, phy_ch_base, board,
621                                           bd->dram_freq, size / (width / 16),
622                                           ch);
623                         if (ret) {
624                                 pr_err("failed to initialize UMC ch%d\n", ch);
625                                 return ret;
626                         }
627                 }
628
629                 umc_ch_base += 0x00200000;
630                 phy_ch_base += 0x00004000;
631         }
632
633         um_init(um_base);
634
635         return 0;
636 }