]> git.sur5r.net Git - u-boot/blob - arch/arm/mach-uniphier/dram/umc-ld20.c
Merge branch 'master' of http://git.denx.de/u-boot-sunxi
[u-boot] / arch / arm / mach-uniphier / dram / umc-ld20.c
1 /*
2  * Copyright (C) 2016 Socionext Inc.
3  *
4  * based on commit 9073035a9860f892f8d1345dfb0ea862b5021145 of Diag
5  *
6  * SPDX-License-Identifier:     GPL-2.0+
7  */
8
9 #include <common.h>
10 #include <linux/bitops.h>
11 #include <linux/err.h>
12 #include <linux/io.h>
13 #include <linux/sizes.h>
14 #include <asm/processor.h>
15
16 #include "../init.h"
17 #include "ddrphy-ld20-regs.h"
18 #include "umc64-regs.h"
19
20 #define DRAM_CH_NR      3
21
22 enum dram_freq {
23         DRAM_FREQ_1866M,
24         DRAM_FREQ_NR,
25 };
26
27 enum dram_size {
28         DRAM_SZ_256M,
29         DRAM_SZ_512M,
30         DRAM_SZ_NR,
31 };
32
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 */
38         DRAM_BOARD_NR,
39 };
40
41 /* PHY */
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 */
47 };
48
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 */
54 };
55
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 */
61 };
62
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 */
68 };
69
70 static const u32 ddrphy_scl_gate_timing[DRAM_CH_NR] = {
71         0x00000140, 0x00000180, 0x00000140
72 };
73
74 static const int ddrphy_op_dq_shift_val[DRAM_BOARD_NR][DRAM_CH_NR][32] = {
75         { /* LD20 reference */
76                 {
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,
81                 },
82                 {
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,
87                 },
88                 {
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,
93                 },
94         },
95         { /* LD20 TV */
96                 {
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,
101                 },
102                 {
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,
107                 },
108                 {
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,
113                 },
114         },
115         { /* LD21 reference */
116                 {
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,
121                 },
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,
126                 },
127                 /* No CH2 */
128         },
129         { /* LD21 TV */
130                 {
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,
135                 },
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,
140                 },
141                 /* No CH2 */
142         },
143 };
144
145 static int ddrphy_ip_dq_shift_val[DRAM_BOARD_NR][DRAM_CH_NR][32] = {
146         { /* LD20 reference */
147                 {
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,
152                 },
153                 {
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,
158                 },
159                 {
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,
164                 },
165         },
166         { /* LD20 TV */
167                 {
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,
172                 },
173                 {
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,
178                 },
179                 {
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,
184                 },
185         },
186         { /* LD21 reference */
187                 {
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,
192                 },
193                 {
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,
198                 },
199                 /* No CH2 */
200         },
201         { /* LD21 TV */
202                 {
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,
207                 },
208                 {
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,
213                 },
214                 /* No CH2 */
215         },
216 };
217
218 /* DDR PHY */
219 static void ddrphy_select_lane(void __iomem *phy_base, unsigned int lane,
220                                unsigned int bit)
221 {
222         WARN_ON(lane >= (1 << PHY_LANE_SEL_LANE_WIDTH));
223         WARN_ON(bit >= (1 << PHY_LANE_SEL_BIT_WIDTH));
224
225         writel((bit << PHY_LANE_SEL_BIT_SHIFT) |
226                (lane << PHY_LANE_SEL_LANE_SHIFT),
227                phy_base + PHY_LANE_SEL);
228 }
229
230 static void ddrphy_init(void __iomem *phy_base, enum dram_board board, int ch)
231 {
232         writel(0x0C001001, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
233         while (!(readl(phy_base + PHY_UNIQUIFY_TSMC_IO_1) & BIT(1)))
234                 cpu_relax();
235         writel(0x0C001000, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
236
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);
268 }
269
270 static int ddrphy_to_dly_step(void __iomem *phy_base, unsigned int freq,
271                               int delay)
272 {
273         int mdl;
274
275         mdl = (readl(phy_base + PHY_DLL_ADRCTRL) & PHY_DLL_ADRCTRL_MDL_MASK) >>
276                                                 PHY_DLL_ADRCTRL_MDL_SHIFT;
277
278         return DIV_ROUND_CLOSEST((long)freq * delay * mdl, 2 * 1000000L);
279 }
280
281 static void ddrphy_set_delay(void __iomem *phy_base, unsigned int reg,
282                              u32 mask, u32 incr, int dly_step)
283 {
284         u32 tmp;
285
286         tmp = readl(phy_base + reg);
287         tmp &= ~mask;
288         tmp |= min_t(u32, abs(dly_step), mask);
289
290         if (dly_step >= 0)
291                 tmp |= incr;
292         else
293                 tmp &= ~incr;
294
295         writel(tmp, phy_base + reg);
296 }
297
298 static void ddrphy_set_dll_recalib(void __iomem *phy_base, int dly_step)
299 {
300         ddrphy_set_delay(phy_base, PHY_DLL_RECALIB,
301                          PHY_DLL_RECALIB_TRIM_MASK, PHY_DLL_RECALIB_INCR,
302                          dly_step);
303 }
304
305 static void ddrphy_set_dll_adrctrl(void __iomem *phy_base, int dly_step)
306 {
307         ddrphy_set_delay(phy_base, PHY_DLL_ADRCTRL,
308                          PHY_DLL_ADRCTRL_TRIM_MASK, PHY_DLL_ADRCTRL_INCR,
309                          dly_step);
310 }
311
312 static void ddrphy_set_dll_trim_clk(void __iomem *phy_base, int dly_step)
313 {
314         ddrphy_select_lane(phy_base, 0, 0);
315
316         ddrphy_set_delay(phy_base, PHY_DLL_TRIM_CLK,
317                          PHY_DLL_TRIM_CLK_MASK, PHY_DLL_TRIM_CLK_INCR,
318                          dly_step);
319 }
320
321 static void ddrphy_init_tail(void __iomem *phy_base, enum dram_board board,
322                              unsigned int freq, int ch)
323 {
324         int step;
325
326         step = ddrphy_to_dly_step(phy_base, freq, ddrphy_adrctrl[board][ch]);
327         ddrphy_set_dll_adrctrl(phy_base, step);
328
329         step = ddrphy_to_dly_step(phy_base, freq, ddrphy_dlltrimclk[board][ch]);
330         ddrphy_set_dll_trim_clk(phy_base, step);
331
332         step = ddrphy_to_dly_step(phy_base, freq, ddrphy_dllrecalib[board][ch]);
333         ddrphy_set_dll_recalib(phy_base, step);
334 }
335
336 static void ddrphy_shift_one_dq(void __iomem *phy_base, unsigned int reg,
337                                 u32 mask, u32 incr, int shift_val)
338 {
339         u32 tmp;
340         int val;
341
342         tmp = readl(phy_base + reg);
343
344         val = tmp & mask;
345         if (!(tmp & incr))
346                 val = -val;
347
348         val += shift_val;
349
350         tmp &= ~(incr | mask);
351         tmp |= min_t(u32, abs(val), mask);
352         if (val >= 0)
353                 tmp |= incr;
354
355         writel(tmp, phy_base + reg);
356 }
357
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)
361 {
362         u32 tmp;
363         int dx, bit;
364
365         tmp = readl(phy_base + reg);
366         tmp |= override;
367         writel(tmp, phy_base + reg);
368
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,
373                                            bit);
374
375                         ddrphy_shift_one_dq(phy_base, reg, mask, incr,
376                                             shift_val_array[dx * 8 + bit]);
377                 }
378         }
379
380         ddrphy_select_lane(phy_base, 0, 0);
381 }
382
383 static int ddrphy_training(void __iomem *phy_base, enum dram_board board,
384                            int ch)
385 {
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);
389
390         while (readl(phy_base + PHY_SCL_START) & BIT(28))
391                 cpu_relax();
392
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);
398
399         while (readl(phy_base + PHY_SCL_START) & BIT(28))
400                 cpu_relax();
401
402         writel(0xFBF0FFFF, phy_base + PHY_SCL_START_ADDR);
403         writel(0x30500000, phy_base + PHY_SCL_START);
404
405         while (readl(phy_base + PHY_SCL_START) & BIT(28))
406                 cpu_relax();
407
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);
413
414         while (readl(phy_base + PHY_SCL_START) & BIT(28))
415                 cpu_relax();
416
417         writel(0x34000000, phy_base + PHY_SCL_START);
418
419         while (readl(phy_base + PHY_SCL_START) & BIT(28))
420                 cpu_relax();
421
422         writel(0x00000003, phy_base + PHY_DISABLE_GATING_FOR_SCL);
423
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);
427
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]);
435
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]);
443
444         return 0;
445 }
446
447 /* UMC */
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};
453
454 static u32 umc_memconf0a[DRAM_FREQ_NR][DRAM_SZ_NR] = {
455         /*  256MB       512MB */
456         {0x00000601, 0x00000801},       /* 1866 MHz */
457 };
458
459 static u32 umc_memconf0b[DRAM_FREQ_NR][DRAM_SZ_NR] = {
460         /*  256MB       512MB */
461         {0x00000120, 0x00000130},       /* 1866 MHz */
462 };
463
464 static u32 umc_memconfch[DRAM_FREQ_NR][DRAM_SZ_NR] = {
465         /*  256MB       512MB */
466         {0x00033603, 0x00033803},       /* 1866 MHz */
467 };
468
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] = {
473         /*  256MB       512MB */
474         {0x0049071D, 0x0078071D},       /* 1866 MHz */
475 };
476
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};
484
485 static u32 umc_flowctla[DRAM_FREQ_NR] = {0x0081E01E};
486 static u32 umc_directbusctrla[DRAM_CH_NR] = {
487         0x00000000, 0x00000001, 0x00000001
488 };
489
490 static void umc_poll_phy_init_complete(void __iomem *dc_base)
491 {
492         /* Wait for PHY Init Complete */
493         while (!(readl(dc_base + UMC_DFISTCTLC) & BIT(0)))
494                 cpu_relax();
495 }
496
497 static int umc_dc_init(void __iomem *dc_base, unsigned int freq,
498                        unsigned long size, int ch)
499 {
500         enum dram_freq freq_e;
501         enum dram_size size_e;
502
503         switch (freq) {
504         case 1866:
505                 freq_e = DRAM_FREQ_1866M;
506                 break;
507         default:
508                 pr_err("unsupported DRAM frequency %ud MHz\n", freq);
509                 return -EINVAL;
510         }
511
512         switch (size) {
513         case 0:
514                 return 0;
515         case SZ_256M:
516                 size_e = DRAM_SZ_256M;
517                 break;
518         case SZ_512M:
519                 size_e = DRAM_SZ_512M;
520                 break;
521         default:
522                 pr_err("unsupported DRAM size 0x%08lx (per 16bit) for ch%d\n",
523                        size, ch);
524                 return -EINVAL;
525         }
526
527         writel(0x00000001, dc_base + UMC_DFICSOVRRD);
528         writel(0x00000000, dc_base + UMC_DFITURNOFF);
529
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);
533
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);
538
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);
543
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);
548
549         writel(umc_rdatactl_d0[freq_e], dc_base + UMC_RDATACTL_D0);
550         writel(umc_rdatactl_d1[freq_e], dc_base + UMC_RDATACTL_D1);
551
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);
557
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);
562
563         writel(umc_flowctla[freq_e], dc_base + UMC_FLOWCTLA);
564         writel(0x00004444, dc_base + UMC_FLOWCTLC);
565         writel(0x00000000, dc_base + UMC_DFICUPDCTLA);
566
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);
571
572         writel(umc_directbusctrla[ch], dc_base + UMC_DIRECTBUSCTRLA);
573
574         writel(0x00000001, dc_base + UMC_INITSET);
575         /* Wait for PHY Init Complete */
576         while (readl(dc_base + UMC_INITSTAT) & BIT(0))
577                 cpu_relax();
578
579         writel(0x2A0A0A00, dc_base + UMC_SPCSETB);
580         writel(0x00000000, dc_base + UMC_DFICSOVRRD);
581
582         return 0;
583 }
584
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)
588 {
589         void __iomem *dc_base = umc_ch_base + 0x00011000;
590         void __iomem *phy_base = phy_ch_base;
591         int ret;
592
593         /* PHY Update Mode (ON) */
594         writel(0x8000003f, dc_base + UMC_DFIPUPDCTLA);
595
596         /* deassert PHY reset signals */
597         writel(UMC_DIOCTLA_CTL_NRST | UMC_DIOCTLA_CFG_NRST,
598                dc_base + UMC_DIOCTLA);
599
600         ddrphy_init(phy_base, board, ch);
601
602         umc_poll_phy_init_complete(dc_base);
603
604         ddrphy_init_tail(phy_base, board, freq, ch);
605
606         ret = umc_dc_init(dc_base, freq, size, ch);
607         if (ret)
608                 return ret;
609
610         ret = ddrphy_training(phy_base, board, ch);
611         if (ret)
612                 return ret;
613
614         return 0;
615 }
616
617 static void um_init(void __iomem *um_base)
618 {
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);
630 }
631
632 int uniphier_ld20_umc_init(const struct uniphier_board_data *bd)
633 {
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;
638         int ch, ret;
639
640         switch (UNIPHIER_BD_BOARD_GET_TYPE(bd->flags)) {
641         case UNIPHIER_BD_BOARD_LD20_REF:
642                 board = DRAM_BOARD_LD20_REF;
643                 break;
644         case UNIPHIER_BD_BOARD_LD20_GLOBAL:
645                 board = DRAM_BOARD_LD20_GLOBAL;
646                 break;
647         case UNIPHIER_BD_BOARD_LD21_REF:
648                 board = DRAM_BOARD_LD21_REF;
649                 break;
650         case UNIPHIER_BD_BOARD_LD21_GLOBAL:
651                 board = DRAM_BOARD_LD21_GLOBAL;
652                 break;
653         default:
654                 pr_err("unsupported board type %d\n",
655                        UNIPHIER_BD_BOARD_GET_TYPE(bd->flags));
656                 return -EINVAL;
657         }
658
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;
662
663                 ret = umc_ch_init(umc_ch_base, phy_ch_base, board,
664                                   bd->dram_freq, size / (width / 16), ch);
665                 if (ret) {
666                         pr_err("failed to initialize UMC ch%d\n", ch);
667                         return ret;
668                 }
669
670                 umc_ch_base += 0x00200000;
671                 phy_ch_base += 0x00004000;
672         }
673
674         um_init(um_base);
675
676         return 0;
677 }