dm: core: Require users of devres to include the header
[oweals/u-boot.git] / drivers / ram / rockchip / sdram_common.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * (C) Copyright 2018 Rockchip Electronics Co., Ltd.
4  */
5
6 #include <common.h>
7 #include <debug_uart.h>
8 #include <ram.h>
9 #include <asm/io.h>
10 #include <asm/arch-rockchip/sdram.h>
11 #include <asm/arch-rockchip/sdram_common.h>
12
13 #ifdef CONFIG_RAM_ROCKCHIP_DEBUG
14 void sdram_print_dram_type(unsigned char dramtype)
15 {
16         switch (dramtype) {
17         case DDR3:
18                 printascii("DDR3");
19                 break;
20         case DDR4:
21                 printascii("DDR4");
22                 break;
23         case LPDDR2:
24                 printascii("LPDDR2");
25                 break;
26         case LPDDR3:
27                 printascii("LPDDR3");
28                 break;
29         case LPDDR4:
30                 printascii("LPDDR4");
31                 break;
32         default:
33                 printascii("Unknown Device");
34                 break;
35         }
36 }
37
38 void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
39                           struct sdram_base_params *base)
40 {
41         u64 cap;
42         u32 bg;
43
44         bg = (cap_info->dbw == 0) ? 2 : 1;
45
46         sdram_print_dram_type(base->dramtype);
47
48         printascii(", ");
49         printdec(base->ddr_freq);
50         printascii("MHz\n");
51
52         printascii("BW=");
53         printdec(8 << cap_info->bw);
54         printascii(" Col=");
55         printdec(cap_info->col);
56         printascii(" Bk=");
57         printdec(0x1 << cap_info->bk);
58         if (base->dramtype == DDR4) {
59                 printascii(" BG=");
60                 printdec(1 << bg);
61         }
62         printascii(" CS0 Row=");
63         printdec(cap_info->cs0_row);
64         if (cap_info->cs0_high16bit_row !=
65                 cap_info->cs0_row) {
66                 printascii("/");
67                 printdec(cap_info->cs0_high16bit_row);
68         }
69         if (cap_info->rank > 1) {
70                 printascii(" CS1 Row=");
71                 printdec(cap_info->cs1_row);
72                 if (cap_info->cs1_high16bit_row !=
73                         cap_info->cs1_row) {
74                         printascii("/");
75                         printdec(cap_info->cs1_high16bit_row);
76                 }
77         }
78         printascii(" CS=");
79         printdec(cap_info->rank);
80         printascii(" Die BW=");
81         printdec(8 << cap_info->dbw);
82
83         cap = sdram_get_cs_cap(cap_info, 3, base->dramtype);
84         if (cap_info->row_3_4)
85                 cap = cap * 3 / 4;
86
87         printascii(" Size=");
88         printdec(cap >> 20);
89         printascii("MB\n");
90 }
91
92 void sdram_print_stride(unsigned int stride)
93 {
94         switch (stride) {
95         case 0xc:
96                 printf("128B stride\n");
97                 break;
98         case 5:
99         case 9:
100         case 0xd:
101         case 0x11:
102         case 0x19:
103                 printf("256B stride\n");
104                 break;
105         case 0xa:
106         case 0xe:
107         case 0x12:
108                 printf("512B stride\n");
109                 break;
110         case 0xf:
111                 printf("4K stride\n");
112                 break;
113         case 0x1f:
114                 printf("32MB + 256B stride\n");
115                 break;
116         default:
117                 printf("no stride\n");
118         }
119 }
120 #endif
121
122 /*
123  * cs: 0:cs0
124  *         1:cs1
125  *     else cs0+cs1
126  * note: it didn't consider about row_3_4
127  */
128 u64 sdram_get_cs_cap(struct sdram_cap_info *cap_info, u32 cs, u32 dram_type)
129 {
130         u32 bg;
131         u64 cap[2];
132
133         if (dram_type == DDR4)
134                 /* DDR4 8bit dram BG = 2(4bank groups),
135                  * 16bit dram BG = 1 (2 bank groups)
136                  */
137                 bg = (cap_info->dbw == 0) ? 2 : 1;
138         else
139                 bg = 0;
140         cap[0] = 1llu << (cap_info->bw + cap_info->col +
141                 bg + cap_info->bk + cap_info->cs0_row);
142
143         if (cap_info->rank == 2)
144                 cap[1] = 1llu << (cap_info->bw + cap_info->col +
145                         bg + cap_info->bk + cap_info->cs1_row);
146         else
147                 cap[1] = 0;
148
149         if (cs == 0)
150                 return cap[0];
151         else if (cs == 1)
152                 return cap[1];
153         else
154                 return (cap[0] + cap[1]);
155 }
156
157 /* n: Unit bytes */
158 void sdram_copy_to_reg(u32 *dest, const u32 *src, u32 n)
159 {
160         int i;
161
162         for (i = 0; i < n / sizeof(u32); i++) {
163                 writel(*src, dest);
164                 src++;
165                 dest++;
166         }
167 }
168
169 void sdram_org_config(struct sdram_cap_info *cap_info,
170                       struct sdram_base_params *base,
171                       u32 *p_os_reg2, u32 *p_os_reg3, u32 channel)
172 {
173         *p_os_reg2 |= SYS_REG_ENC_DDRTYPE(base->dramtype);
174         *p_os_reg2 |= SYS_REG_ENC_NUM_CH(base->num_channels);
175
176         *p_os_reg2 |= SYS_REG_ENC_ROW_3_4(cap_info->row_3_4, channel);
177         *p_os_reg2 |= SYS_REG_ENC_CHINFO(channel);
178         *p_os_reg2 |= SYS_REG_ENC_RANK(cap_info->rank, channel);
179         *p_os_reg2 |= SYS_REG_ENC_COL(cap_info->col, channel);
180         *p_os_reg2 |= SYS_REG_ENC_BK(cap_info->bk, channel);
181         *p_os_reg2 |= SYS_REG_ENC_BW(cap_info->bw, channel);
182         *p_os_reg2 |= SYS_REG_ENC_DBW(cap_info->dbw, channel);
183
184         SYS_REG_ENC_CS0_ROW(cap_info->cs0_row, *p_os_reg2, *p_os_reg3, channel);
185         if (cap_info->cs1_row)
186                 SYS_REG_ENC_CS1_ROW(cap_info->cs1_row, *p_os_reg2,
187                                     *p_os_reg3, channel);
188         *p_os_reg3 |= SYS_REG_ENC_CS1_COL(cap_info->col, channel);
189         *p_os_reg3 |= SYS_REG_ENC_VERSION(DDR_SYS_REG_VERSION);
190 }
191
192 int sdram_detect_bw(struct sdram_cap_info *cap_info)
193 {
194         return 0;
195 }
196
197 int sdram_detect_cs(struct sdram_cap_info *cap_info)
198 {
199         return 0;
200 }
201
202 int sdram_detect_col(struct sdram_cap_info *cap_info,
203                      u32 coltmp)
204 {
205         void __iomem *test_addr;
206         u32 col;
207         u32 bw = cap_info->bw;
208
209         for (col = coltmp; col >= 9; col -= 1) {
210                 writel(0, CONFIG_SYS_SDRAM_BASE);
211                 test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
212                                 (1ul << (col + bw - 1ul)));
213                 writel(PATTERN, test_addr);
214                 if ((readl(test_addr) == PATTERN) &&
215                     (readl(CONFIG_SYS_SDRAM_BASE) == 0))
216                         break;
217         }
218         if (col == 8) {
219                 printascii("col error\n");
220                 return -1;
221         }
222
223         cap_info->col = col;
224
225         return 0;
226 }
227
228 int sdram_detect_bank(struct sdram_cap_info *cap_info,
229                       u32 coltmp, u32 bktmp)
230 {
231         void __iomem *test_addr;
232         u32 bk;
233         u32 bw = cap_info->bw;
234
235         test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
236                         (1ul << (coltmp + bktmp + bw - 1ul)));
237         writel(0, CONFIG_SYS_SDRAM_BASE);
238         writel(PATTERN, test_addr);
239         if ((readl(test_addr) == PATTERN) &&
240             (readl(CONFIG_SYS_SDRAM_BASE) == 0))
241                 bk = 3;
242         else
243                 bk = 2;
244
245         cap_info->bk = bk;
246
247         return 0;
248 }
249
250 /* detect bg for ddr4 */
251 int sdram_detect_bg(struct sdram_cap_info *cap_info,
252                     u32 coltmp)
253 {
254         void __iomem *test_addr;
255         u32 dbw;
256         u32 bw = cap_info->bw;
257
258         test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
259                         (1ul << (coltmp + bw + 1ul)));
260         writel(0, CONFIG_SYS_SDRAM_BASE);
261         writel(PATTERN, test_addr);
262         if ((readl(test_addr) == PATTERN) &&
263             (readl(CONFIG_SYS_SDRAM_BASE) == 0))
264                 dbw = 0;
265         else
266                 dbw = 1;
267
268         cap_info->dbw = dbw;
269
270         return 0;
271 }
272
273 /* detect dbw for ddr3,lpddr2,lpddr3,lpddr4 */
274 int sdram_detect_dbw(struct sdram_cap_info *cap_info, u32 dram_type)
275 {
276         u32 row, col, bk, bw, cs_cap, cs;
277         u32 die_bw_0 = 0, die_bw_1 = 0;
278
279         if (dram_type == DDR3 || dram_type == LPDDR4) {
280                 cap_info->dbw = 1;
281         } else if (dram_type == LPDDR3 || dram_type == LPDDR2) {
282                 row = cap_info->cs0_row;
283                 col = cap_info->col;
284                 bk = cap_info->bk;
285                 cs = cap_info->rank;
286                 bw = cap_info->bw;
287                 cs_cap = (1 << (row + col + bk + bw - 20));
288                 if (bw == 2) {
289                         if (cs_cap <= 0x2000000) /* 256Mb */
290                                 die_bw_0 = (col < 9) ? 2 : 1;
291                         else if (cs_cap <= 0x10000000) /* 2Gb */
292                                 die_bw_0 = (col < 10) ? 2 : 1;
293                         else if (cs_cap <= 0x40000000) /* 8Gb */
294                                 die_bw_0 = (col < 11) ? 2 : 1;
295                         else
296                                 die_bw_0 = (col < 12) ? 2 : 1;
297                         if (cs > 1) {
298                                 row = cap_info->cs1_row;
299                                 cs_cap = (1 << (row + col + bk + bw - 20));
300                                 if (cs_cap <= 0x2000000) /* 256Mb */
301                                         die_bw_0 = (col < 9) ? 2 : 1;
302                                 else if (cs_cap <= 0x10000000) /* 2Gb */
303                                         die_bw_0 = (col < 10) ? 2 : 1;
304                                 else if (cs_cap <= 0x40000000) /* 8Gb */
305                                         die_bw_0 = (col < 11) ? 2 : 1;
306                                 else
307                                         die_bw_0 = (col < 12) ? 2 : 1;
308                         }
309                 } else {
310                         die_bw_1 = 1;
311                         die_bw_0 = 1;
312                 }
313                 cap_info->dbw = (die_bw_0 > die_bw_1) ? die_bw_0 : die_bw_1;
314         }
315
316         return 0;
317 }
318
319 int sdram_detect_row(struct sdram_cap_info *cap_info,
320                      u32 coltmp, u32 bktmp, u32 rowtmp)
321 {
322         u32 row;
323         u32 bw = cap_info->bw;
324         void __iomem *test_addr;
325
326         for (row = rowtmp; row > 12; row--) {
327                 writel(0, CONFIG_SYS_SDRAM_BASE);
328                 test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
329                                 (1ul << (row + bktmp + coltmp + bw - 1ul)));
330                 writel(PATTERN, test_addr);
331                 if ((readl(test_addr) == PATTERN) &&
332                     (readl(CONFIG_SYS_SDRAM_BASE) == 0))
333                         break;
334         }
335         if (row == 12) {
336                 printascii("row error");
337                 return -1;
338         }
339
340         cap_info->cs0_row = row;
341
342         return 0;
343 }
344
345 int sdram_detect_row_3_4(struct sdram_cap_info *cap_info,
346                          u32 coltmp, u32 bktmp)
347 {
348         u32 row_3_4;
349         u32 bw = cap_info->bw;
350         u32 row = cap_info->cs0_row;
351         void __iomem *test_addr, *test_addr1;
352
353         test_addr = CONFIG_SYS_SDRAM_BASE;
354         test_addr1 = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
355                         (0x3ul << (row + bktmp + coltmp + bw - 1ul - 1ul)));
356
357         writel(0, test_addr);
358         writel(PATTERN, test_addr1);
359         if ((readl(test_addr) == 0) && (readl(test_addr1) == PATTERN))
360                 row_3_4 = 0;
361         else
362                 row_3_4 = 1;
363
364         cap_info->row_3_4 = row_3_4;
365
366         return 0;
367 }
368
369 int sdram_detect_high_row(struct sdram_cap_info *cap_info)
370 {
371         cap_info->cs0_high16bit_row = cap_info->cs0_row;
372         cap_info->cs1_high16bit_row = cap_info->cs1_row;
373
374         return 0;
375 }
376
377 int sdram_detect_cs1_row(struct sdram_cap_info *cap_info, u32 dram_type)
378 {
379         void __iomem *test_addr;
380         u32 row = 0, bktmp, coltmp, bw;
381         ulong cs0_cap;
382         u32 byte_mask;
383
384         if (cap_info->rank == 2) {
385                 cs0_cap = sdram_get_cs_cap(cap_info, 0, dram_type);
386
387                 if (dram_type == DDR4) {
388                         if (cap_info->dbw == 0)
389                                 bktmp = cap_info->bk + 2;
390                         else
391                                 bktmp = cap_info->bk + 1;
392                 } else {
393                         bktmp = cap_info->bk;
394                 }
395                 bw = cap_info->bw;
396                 coltmp = cap_info->col;
397
398                 /*
399                  * because px30 support axi split,min bandwidth
400                  * is 8bit. if cs0 is 32bit, cs1 may 32bit or 16bit
401                  * so we check low 16bit data when detect cs1 row.
402                  * if cs0 is 16bit/8bit, we check low 8bit data.
403                  */
404                 if (bw == 2)
405                         byte_mask = 0xFFFF;
406                 else
407                         byte_mask = 0xFF;
408
409                 /* detect cs1 row */
410                 for (row = cap_info->cs0_row; row > 12; row--) {
411                         test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
412                                     cs0_cap +
413                                     (1ul << (row + bktmp + coltmp + bw - 1ul)));
414                         writel(0, CONFIG_SYS_SDRAM_BASE + cs0_cap);
415                         writel(PATTERN, test_addr);
416
417                         if (((readl(test_addr) & byte_mask) ==
418                              (PATTERN & byte_mask)) &&
419                             ((readl(CONFIG_SYS_SDRAM_BASE + cs0_cap) &
420                               byte_mask) == 0)) {
421                                 break;
422                         }
423                 }
424         }
425
426         cap_info->cs1_row = row;
427
428         return 0;
429 }