1fdd119a3fef16ae76191d8b053e5286cc992d93
[platform/kernel/u-boot.git] / arch / arm / mach-uniphier / dram / umc-ld20.c
1 /*
2  * Copyright (C) 2016 Socionext Inc.
3  *
4  * based on commit a3c28918e86ad57127cf07bf8b32950cab20c03c 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 #define CONFIG_DDR_FREQ         1866
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_LD21_REF,    /* LD21 reference */
38         DRAM_BOARD_LD21_GLOBAL, /* LD21 TV */
39         DRAM_BOARD_NR,
40 };
41
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
47
48 #define PHY_DLL_MAS_DLY_WIDTH           8
49 #define PHY_SLV_DLY_WIDTH               6
50
51 static void ddrphy_maskwritel(u32 data, u32 mask, void *addr)
52 {
53         u32 value;
54
55         value = (readl(addr) & ~mask) | (data & mask);
56         writel(value, addr);
57 }
58
59 static u32 ddrphy_maskreadl(u32 mask, void *addr)
60 {
61         return readl(addr) & mask;
62 }
63
64 /* set phy_lane_sel.phy_lane_sel */
65 static void ddrphy_set_phy_lane_sel(int val, void __iomem *phy_base)
66 {
67         ddrphy_maskwritel(val, MSK_PHY_LANE_SEL, phy_base + PHY_LANE_SEL);
68 }
69
70 /* set phy_lane_sel.bit_sel */
71 static void ddrphy_set_bit_sel(int bit, void __iomem *phy_base)
72 {
73         ddrphy_maskwritel(bit << 8, MSK_BIT_SEL, phy_base + PHY_LANE_SEL);
74 }
75
76 /* Calculating step for PUB-byte */
77 static int ddrphy_hpstep(int delay, void __iomem *phy_base)
78 {
79         int mdl, freq;
80
81         freq = CONFIG_DDR_FREQ; /* FIXME */
82         mdl = ddrphy_maskreadl(MSK_DLL_MAS_DLY, phy_base + PHY_DLL_ADRCTRL) >> 24;
83
84         return DIV_ROUND_CLOSEST(freq * delay * mdl, 2 * 1000000);
85 }
86
87 static void ddrphy_set_dll_trim_clk(int delay_ckoffset,  void __iomem *phy_base)
88 {
89         u8 ck_step;     /* ckoffset_step for clock */
90         u32 ck_step_all;
91
92         /* CK-Offset */
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);
97         } else{
98                 /* shift - direction */
99                 ck_step = min(ddrphy_hpstep(-1*delay_ckoffset, phy_base), 127);
100                 ck_step_all = ck_step;
101         }
102
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);
105 }
106
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)
110 {
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 */
113
114         /* Q-Offset */
115         if (delay_qoffset >= 0) {
116                 dlls_trim_adrctrl_ma = min(ddrphy_hpstep(delay_qoffset, phy_base), 63);
117                 incr_dly_adrctrl_ma = 0x1;
118         } else {
119                 dlls_trim_adrctrl_ma = min(ddrphy_hpstep(-1*delay_qoffset, phy_base), 63);
120                 incr_dly_adrctrl_ma = 0x0;
121         }
122
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);
128
129         /* write value for all bits other than bit[7:6] */
130         ddrphy_maskwritel(recalib_all, ~0xc0, phy_base + PHY_DLL_RECALIB);
131 }
132
133 static void ddrphy_set_dll_adrctrl(int delay_qoffset, u8 override_adrctrl,
134                                    void __iomem *phy_base)
135 {
136         u8 dlls_trim_adrctrl, incr_dly_adrctrl; /* qoffset_step for clock */
137         u32 adrctrl_all;
138
139         if (delay_qoffset >= 0) {
140                 dlls_trim_adrctrl = min(ddrphy_hpstep(delay_qoffset, phy_base), 63);
141                 incr_dly_adrctrl = 0x1;
142         } else {
143                 dlls_trim_adrctrl = min(ddrphy_hpstep(-delay_qoffset, phy_base), 63);
144                 incr_dly_adrctrl = 0x0;
145         }
146
147         adrctrl_all = (incr_dly_adrctrl << 9) |
148                         ((override_adrctrl & 0x1) << 8) |
149                         dlls_trim_adrctrl;
150
151         ddrphy_maskwritel(adrctrl_all, 0x33f, phy_base + PHY_DLL_ADRCTRL);
152 }
153
154 /* dio */
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 */
160 };
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 */
166 };
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 */
172 };
173
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 */
179 };
180
181 static u32 dio_scl_gate_timing[DRAM_CH_NR] = {0x00000140, 0x00000180, 0x00000140};
182
183 static int dio_op_dq_shift_val[DRAM_BOARD_NR][DRAM_CH_NR][32] = {
184         { /* LD20 reference */
185                 {
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,
188                 },
189                 {
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,
192                 },
193                 {
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,
196                 },
197         },
198         { /* LD20 TV */
199                 {
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,
202                 },
203                 {
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,
206                 },
207                 {
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,
210                 },
211         },
212         { /* LD21 reference */
213                 {
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,
216                 },
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,
219                 },
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,
222                 },
223         },
224         { /* LD21 TV */
225                 {
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,
228                 },
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,
231                 },
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,
234                 },
235         },
236 };
237 static int dio_ip_dq_shift_val[DRAM_BOARD_NR][DRAM_CH_NR][32] = {
238         { /* LD20 reference */
239                 {
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,
242                 },
243                 {
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,
246                 },
247                 {
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,
250                 },
251         },
252         { /* LD20 TV */
253                 {
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,
256                 },
257                 {
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,
260                 },
261                 {
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,
264                 },
265         },
266         { /* LD21 reference */
267                 {
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,
270                 },
271                 {
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,
274                 },
275                 {
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,
278                 },
279         },
280         { /* LD21 TV */
281                 {
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,
284                 },
285                 {
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,
288                 },
289                 {
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,
292                 },
293         },
294 };
295
296 /* umc */
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};
302
303 static u32 umc_memconf0a[DRAM_FREQ_NR][DRAM_SZ_NR] = {
304         /*  256MB       512MB */
305         {0x00000601, 0x00000801},       /* 1866 MHz */
306 };
307 static u32 umc_memconf0b[DRAM_FREQ_NR][DRAM_SZ_NR] = {
308         /*  256MB       512MB */
309         {0x00000120, 0x00000130},       /* 1866 MHz */
310 };
311 static u32 umc_memconfch[DRAM_FREQ_NR][DRAM_SZ_NR] = {
312         /*  256MB       512MB */
313         {0x00033603, 0x00033803},       /* 1866 MHz */
314 };
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] = {
319         /*  256MB       512MB */
320         {0x0049071D, 0x0078071D},       /* 1866 MHz */
321 };
322
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};
330
331 static u32 umc_flowctla[DRAM_FREQ_NR] = {0x0081E01E};
332 static u32 umc_directbusctrla[DRAM_CH_NR] = {
333         0x00000000, 0x00000001, 0x00000001
334 };
335
336 /* polling function for PHY Init Complete */
337 static void ddrphy_init_complete(void __iomem *dc_base)
338 {
339         /* Wait for PHY Init Complete */
340         while (!(readl(dc_base + UMC_DFISTCTLC) & BIT(0)))
341                 cpu_relax();
342 }
343
344 /* DDR PHY */
345 static void ddrphy_init(void __iomem *phy_base, void __iomem *dc_base,
346                         enum dram_freq freq, enum dram_board board, int ch)
347 {
348         writel(0x0C001001, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
349         while (!(readl(phy_base + PHY_UNIQUIFY_TSMC_IO_1) & BIT(1)))
350                 cpu_relax();
351         writel(0x0C001000, phy_base + PHY_UNIQUIFY_TSMC_IO_1);
352
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);
384
385         ddrphy_init_complete(dc_base);
386
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,
390                                phy_base);
391 }
392
393 static void ddrphy_shift_dq(u32 reg_mask, u32 reg_addr, int shift_val,
394                             void __iomem *phy_base)
395 {
396         u32 reg_val;
397         int dq_val;
398
399         reg_val = ddrphy_maskreadl(reg_mask, phy_base + reg_addr) & 0x7f;
400         dq_val = reg_val & 0x3f;
401
402         if ((reg_val & 0x40) == 0x00)
403                 dq_val = -1 * dq_val;
404
405         /* value shift*/
406         dq_val = dq_val + shift_val;
407
408         if (dq_val >= 0)
409                 reg_val = 0x40 + (dq_val & 0x3f);
410         else
411                 reg_val = ((-1 * dq_val) & 0x3f);
412
413         ddrphy_maskwritel(reg_val, reg_mask, phy_base + reg_addr);
414 }
415
416 static void ddrphy_shift(void __iomem *phy_base, enum dram_board board, int ch)
417 {
418         u32 dx, bit;
419
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);
425
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),
429                                         phy_base);
430
431                 for (bit = 0; bit < 8; bit++) {
432                         ddrphy_set_bit_sel(bit, phy_base);
433
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],
438                                         phy_base);
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],
443                                         phy_base);
444                 }
445
446         }
447         ddrphy_set_phy_lane_sel(0, phy_base);
448         ddrphy_set_bit_sel(0, phy_base);
449 }
450
451 static int ddrphy_training(void __iomem *phy_base, enum dram_board board,
452                            int ch)
453 {
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);
457
458         while (readl(phy_base + PHY_SCL_START) & BIT(28))
459                 cpu_relax();
460
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);
466
467         while (readl(phy_base + PHY_SCL_START) & BIT(28))
468                 cpu_relax();
469
470         writel(0xFBF0FFFF, phy_base + PHY_SCL_START_ADDR);
471         writel(0x30500000, phy_base + PHY_SCL_START);
472
473         while (readl(phy_base + PHY_SCL_START) & BIT(28))
474                 cpu_relax();
475
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);
481
482         while (readl(phy_base + PHY_SCL_START) & BIT(28))
483                 cpu_relax();
484
485         writel(0x34000000, phy_base + PHY_SCL_START);
486
487         while (readl(phy_base + PHY_SCL_START) & BIT(28))
488                 cpu_relax();
489
490         writel(0x00000003, phy_base + PHY_DISABLE_GATING_FOR_SCL);
491
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);
495
496         /* shift ip_dq, op_dq trim */
497         ddrphy_shift(phy_base, board, ch);
498         return 0;
499 }
500
501 static int umc_dc_init(void __iomem *dc_base, enum dram_freq freq,
502                        unsigned long size, int ch)
503 {
504         enum dram_size size_e;
505
506         switch (size) {
507         case 0:
508                 return 0;
509         case SZ_256M:
510                 size_e = DRAM_SZ_256M;
511                 break;
512         case SZ_512M:
513                 size_e = DRAM_SZ_512M;
514                 break;
515         default:
516                 pr_err("unsupported DRAM size 0x%08lx (per 16bit) for ch%d\n",
517                        size, ch);
518                 return -EINVAL;
519         }
520
521         writel(0x00000001, dc_base + UMC_DFICSOVRRD);
522         writel(0x00000000, dc_base + UMC_DFITURNOFF);
523
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);
527
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);
532
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);
537
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);
542
543         writel(umc_rdatactl_d0[freq], dc_base + UMC_RDATACTL_D0);
544         writel(umc_rdatactl_d1[freq], dc_base + UMC_RDATACTL_D1);
545
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);
551
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);
556
557         writel(umc_flowctla[freq], dc_base + UMC_FLOWCTLA);
558         writel(0x00004444, dc_base + UMC_FLOWCTLC);
559         writel(0x00000000, dc_base + UMC_DFICUPDCTLA);
560
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);
565
566         writel(umc_directbusctrla[ch], dc_base + UMC_DIRECTBUSCTRLA);
567
568         writel(0x00000001, dc_base + UMC_INITSET);
569         /* Wait for PHY Init Complete */
570         while (readl(dc_base + UMC_INITSTAT) & BIT(0))
571                 cpu_relax();
572
573         writel(0x2A0A0A00, dc_base + UMC_SPCSETB);
574         writel(0x00000000, dc_base + UMC_DFICSOVRRD);
575
576         return 0;
577 }
578
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)
582 {
583         void __iomem *dc_base = umc_ch_base + 0x00011000;
584         void __iomem *phy_base = phy_ch_base;
585         int ret;
586
587         /* PHY Update Mode (ON) */
588         writel(0x8000003f, dc_base + UMC_DFIPUPDCTLA);
589
590         /* deassert PHY reset signals */
591         writel(UMC_DIOCTLA_CTL_NRST | UMC_DIOCTLA_CFG_NRST,
592                dc_base + UMC_DIOCTLA);
593
594         ddrphy_init(phy_base, dc_base, freq, board, ch);
595
596         ret = umc_dc_init(dc_base, freq, size, ch);
597         if (ret)
598                 return ret;
599
600         ret = ddrphy_training(phy_base, board, ch);
601         if (ret)
602                 return ret;
603
604         return 0;
605 }
606
607 static void um_init(void __iomem *um_base)
608 {
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);
620 }
621
622 int uniphier_ld20_umc_init(const struct uniphier_board_data *bd)
623 {
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;
627         enum dram_freq freq;
628         enum dram_board board;
629         int ch, ret;
630
631         switch (bd->dram_freq) {
632         case 1866:
633                 freq = DRAM_FREQ_1866M;
634                 break;
635         default:
636                 pr_err("unsupported DRAM frequency %d MHz\n", bd->dram_freq);
637                 return -EINVAL;
638         }
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, freq, board,
664                                   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 }