57e4e7ddc3455149b0920e181c416e21095b87b6
[kernel/u-boot.git] / arch / x86 / cpu / sc520 / sc520_sdram.c
1 /*
2  * (C) Copyright 2010,2011
3  * Graeme Russ, <graeme.russ@gmail.com>
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 #include <common.h>
25 #include <asm/io.h>
26 #include <asm/processor-flags.h>
27 #include <asm/arch/sc520.h>
28
29 DECLARE_GLOBAL_DATA_PTR;
30
31 struct sc520_sdram_info {
32         u8 banks;
33         u8 columns;
34         u8 rows;
35         u8 size;
36 };
37
38 static void sc520_sizemem(void);
39 static void sc520_set_dram_timing(void);
40 static void sc520_set_dram_refresh_rate(void);
41 static void sc520_enable_dram_refresh(void);
42 static void sc520_enable_sdram(void);
43 #if CONFIG_SYS_SDRAM_ECC_ENABLE
44 static void sc520_enable_ecc(void)
45 #endif
46
47 int dram_init_f(void)
48 {
49         sc520_sizemem();
50         sc520_set_dram_timing();
51         sc520_set_dram_refresh_rate();
52         sc520_enable_dram_refresh();
53         sc520_enable_sdram();
54 #if CONFIG_SYS_SDRAM_ECC_ENABLE
55         sc520_enable_ecc();
56 #endif
57
58         return 0;
59 }
60
61 static inline void sc520_dummy_write(void)
62 {
63         writew(0x0000, CACHELINESZ);
64 }
65 static inline void sc520_issue_sdram_op_mode_select(u8 command)
66 {
67         writeb(command, &sc520_mmcr->drcctl);
68         sc520_dummy_write();
69 }
70
71 static inline int check_long(u32 test_long)
72 {
73         u8 i;
74         u8 tmp_byte = (u8)(test_long & 0x000000ff);
75
76         for (i = 1; i < 4; i++) {
77                 if ((u8)((test_long >> (i * 8)) & 0x000000ff) != tmp_byte)
78                                 return -1;
79         }
80
81         return 0;
82 }
83
84 static inline int write_and_test(u32 data, u32 address)
85 {
86         writel(data, address);
87         if (readl(address) == data)
88                 return 0; /* Good */
89         else
90                 return -1; /* Bad */
91 }
92
93 static void sc520_enable_sdram(void)
94 {
95         u32 par_config;
96
97         /* Enable Writes, Caching and Code Execution to SDRAM */
98         par_config = readl(&sc520_mmcr->par[3]);
99         par_config &= ~(SC520_PAR_EXEC_DIS |
100                         SC520_PAR_CACHE_DIS |
101                         SC520_PAR_WRITE_DIS);
102         writel(par_config, &sc520_mmcr->par[3]);
103
104         par_config = readl(&sc520_mmcr->par[4]);
105         par_config &= ~(SC520_PAR_EXEC_DIS |
106                         SC520_PAR_CACHE_DIS |
107                         SC520_PAR_WRITE_DIS);
108         writel(par_config, &sc520_mmcr->par[4]);
109 }
110
111 static void sc520_set_dram_timing(void)
112 {
113         u8 drctmctl = 0x00;
114
115 #if defined CONFIG_SYS_SDRAM_DRCTMCTL
116         /* just have your hardware designer _GIVE_ you what you need here! */
117         drctmctl = CONFIG_SYS_SDRAM_DRCTMCTL;
118 #else
119         switch (CONFIG_SYS_SDRAM_RAS_CAS_DELAY) {
120         case 2:
121                 break;
122         case 3:
123                 drctmctl |= 0x01;
124                 break;
125         case 4:
126         default:
127                 drctmctl |= 0x02;
128                 break;
129         }
130
131         switch (CONFIG_SYS_SDRAM_PRECHARGE_DELAY) {
132         case 2:
133                 break;
134         case 3:
135                 drctmctl |= 0x04;
136                 break;
137         case 4:
138         default:
139                 drctmctl |= 0x08;
140                 break;
141
142         case 6:
143                 drctmctl |= 0x0c;
144                 break;
145         }
146
147         switch (CONFIG_SYS_SDRAM_CAS_LATENCY) {
148         case 2:
149                 break;
150         case 3:
151         default:
152                 drctmctl |= 0x10;
153                 break;
154         }
155 #endif
156         writeb(drctmctl, &sc520_mmcr->drctmctl);
157
158         /* Issue load mode register command */
159         sc520_issue_sdram_op_mode_select(0x03);
160 }
161
162 static void sc520_set_dram_refresh_rate(void)
163 {
164         u8 drctl;
165
166         drctl = readb(&sc520_mmcr->drcctl);
167         drctl &= 0xcf;
168
169         switch (CONFIG_SYS_SDRAM_REFRESH_RATE) {
170         case 78:
171                 break;
172         case 156:
173         default:
174                 drctl |= 0x10;
175                 break;
176         case 312:
177                 drctl |= 0x20;
178                 break;
179         case 624:
180                 drctl |= 0x30;
181                 break;
182         }
183
184         writeb(drctl, &sc520_mmcr->drcctl);
185 }
186
187 static void sc520_enable_dram_refresh(void)
188 {
189         u8 drctl;
190
191         drctl = readb(&sc520_mmcr->drcctl);
192         drctl &= 0x30; /* keep refresh rate */
193         drctl |= 0x08; /* enable refresh, normal mode */
194
195         writeb(drctl, &sc520_mmcr->drcctl);
196 }
197
198 static void sc520_get_bank_info(int bank, struct sc520_sdram_info *bank_info)
199 {
200         u32 col_data;
201         u32 row_data;
202
203         u32 drcbendadr;
204         u16 drccfg;
205
206         u8 banks = 0x00;
207         u8 columns = 0x00;
208         u8 rows = 0x00;
209
210         bank_info->banks = 0x00;
211         bank_info->columns = 0x00;
212         bank_info->rows = 0x00;
213         bank_info->size = 0x00;
214
215         if ((bank < 0) || (bank > 3)) {
216                 printf("Bad Bank ID\n");
217                 return;
218         }
219
220         /* Save configuration */
221         drcbendadr = readl(&sc520_mmcr->drcbendadr);
222         drccfg = readw(&sc520_mmcr->drccfg);
223
224         /* Setup SDRAM Bank to largest possible size */
225         writew(0x000b << (bank * 4), &sc520_mmcr->drccfg);
226
227         /* Set ending address for this bank */
228         writel(0x000000ff << (bank * 8), &sc520_mmcr->drcbendadr);
229
230         /* write col 11 wrap adr */
231         if (write_and_test(COL11_DATA, COL11_ADR) != 0)
232                 goto restore_and_exit;
233
234         /* write col 10 wrap adr */
235         if (write_and_test(COL10_DATA, COL10_ADR) != 0)
236                 goto restore_and_exit;
237
238         /* write col 9 wrap adr */
239         if (write_and_test(COL09_DATA, COL09_ADR) != 0)
240                 goto restore_and_exit;
241
242         /* write col 8 wrap adr */
243         if (write_and_test(COL08_DATA, COL08_ADR) != 0)
244                 goto restore_and_exit;
245
246         col_data = readl(COL11_ADR);
247
248         /* All four bytes in the read long must be the same */
249         if (check_long(col_data) < 0)
250                 goto restore_and_exit;
251
252         if ((col_data >= COL08_DATA) && (col_data <= COL11_DATA))
253                 columns = (u8)(col_data & 0x000000ff);
254         else
255                 goto restore_and_exit;
256
257         /* write row 14 wrap adr */
258         if (write_and_test(ROW14_DATA, ROW14_ADR) != 0)
259                 goto restore_and_exit;
260
261         /* write row 13 wrap adr */
262         if (write_and_test(ROW13_DATA, ROW13_ADR) != 0)
263                 goto restore_and_exit;
264
265         /* write row 12 wrap adr */
266         if (write_and_test(ROW12_DATA, ROW12_ADR) != 0)
267                 goto restore_and_exit;
268
269         /* write row 11 wrap adr */
270         if (write_and_test(ROW11_DATA, ROW11_ADR) != 0)
271                 goto restore_and_exit;
272
273         if (write_and_test(ROW10_DATA, ROW10_ADR) != 0)
274                 goto restore_and_exit;
275
276         /*
277          * read data @ row 12 wrap adr to determine number of banks,
278          * and read data @ row 14 wrap adr to determine number of rows.
279          * if data @ row 12 wrap adr is not AA, 11 or 12 we have bad RAM.
280          * if data @ row 12 wrap == AA, we only have 2 banks, NOT 4
281          * if data @ row 12 wrap == 11 or 12, we have 4 banks,
282          */
283         row_data = readl(ROW12_ADR);
284
285         /* All four bytes in the read long must be the same */
286         if (check_long(row_data) != 0)
287                 goto restore_and_exit;
288
289         switch (row_data) {
290         case ROW10_DATA:
291                 banks = 2;
292                 break;
293
294         case ROW11_DATA:
295         case ROW12_DATA:
296                 banks = 4;
297                 break;
298
299         default:
300                 goto restore_and_exit;
301         }
302
303         row_data = readl(ROW14_ADR);
304
305         /* All four bytes in the read long must be the same */
306         if (check_long(row_data) != 0)
307                 goto restore_and_exit;
308
309         switch (row_data) {
310         case ROW11_DATA:
311         case ROW12_DATA:
312         case ROW13_DATA:
313         case ROW14_DATA:
314                 rows = (u8)(row_data & 0x000000ff);
315                 break;
316
317         default:
318                 goto restore_and_exit;
319         }
320
321         bank_info->banks = banks;
322         bank_info->columns = columns;
323         bank_info->rows = rows;
324
325         if ((bank_info->banks != 0) &&
326             (bank_info->columns != 0) &&
327             (bank_info->rows != 0)) {
328                 bank_info->size = bank_info->rows;
329                 bank_info->size >>= (11 - bank_info->columns);
330                 bank_info->size++;
331         }
332
333 restore_and_exit:
334         /* Restore configuration */
335         writel(drcbendadr, &sc520_mmcr->drcbendadr);
336         writew(drccfg, &sc520_mmcr->drccfg);
337 }
338
339 static void sc520_setup_sizemem(void)
340 {
341         u8 i;
342
343         /* Disable write buffer */
344         writeb(0x00, &sc520_mmcr->dbctl);
345
346         /* Disable ECC */
347         writeb(0x00, &sc520_mmcr->eccctl);
348
349         /* Set slowest SDRAM timing */
350         writeb(0x1e, &sc520_mmcr->drctmctl);
351
352         /* Issue a NOP to all SDRAM banks */
353         sc520_issue_sdram_op_mode_select(0x01);
354
355         /* Delay for 100 microseconds */
356         udelay(100);
357
358         /* Issue 'All Banks Precharge' command */
359         sc520_issue_sdram_op_mode_select(0x02);
360
361         /* Issue 2 'Auto Refresh Enable' command */
362         sc520_issue_sdram_op_mode_select(0x04);
363         sc520_dummy_write();
364
365         /* Issue 'Load Mode Register' command */
366         sc520_issue_sdram_op_mode_select(0x03);
367
368         /* Issue 8 more 'Auto Refresh Enable' commands */
369         sc520_issue_sdram_op_mode_select(0x04);
370         for (i = 0; i < 7; i++)
371                 sc520_dummy_write();
372
373         /* Set control register to 'Normal Mode' */
374         writeb(0x00, &sc520_mmcr->drcctl);
375 }
376
377 static void sc520_sizemem(void)
378 {
379         struct sc520_sdram_info sdram_info[4];
380         u8 bank_config = 0x00;
381         u8 end_addr = 0x00;
382         u16 drccfg = 0x0000;
383         u32 drcbendadr = 0x00000000;
384         u8 i;
385
386         /* Use PARs to disable caching of maximum allowable 256MB SDRAM */
387         writel(SC520_SDRAM1_PAR | SC520_PAR_CACHE_DIS, &sc520_mmcr->par[3]);
388         writel(SC520_SDRAM2_PAR | SC520_PAR_CACHE_DIS, &sc520_mmcr->par[4]);
389
390         sc520_setup_sizemem();
391
392         gd->ram_size = 0;
393
394         /* Size each SDRAM bank */
395         for (i = 0; i <= 3; i++) {
396                 sc520_get_bank_info(i, &sdram_info[i]);
397
398                 if (sdram_info[i].banks != 0) {
399                         /* Update Configuration register */
400                         bank_config = sdram_info[i].columns - 8;
401
402                         if (sdram_info[i].banks == 4)
403                                 bank_config |= 0x08;
404
405                         drccfg |= bank_config << (i * 4);
406
407                         /* Update End Address register */
408                         end_addr += sdram_info[i].size;
409                         drcbendadr |= (end_addr | 0x80) << (i * 8);
410
411                         gd->ram_size += sdram_info[i].size << 22;
412                 }
413
414                 /* Issue 'All Banks Precharge' command */
415                 sc520_issue_sdram_op_mode_select(0x02);
416
417                 /* Set control register to 'Normal Mode' */
418                 writeb(0x00, &sc520_mmcr->drcctl);
419         }
420
421         writel(drcbendadr, &sc520_mmcr->drcbendadr);
422         writew(drccfg, &sc520_mmcr->drccfg);
423
424         /* Clear PARs preventing caching of SDRAM */
425         writel(0x00000000, &sc520_mmcr->par[3]);
426         writel(0x00000000, &sc520_mmcr->par[4]);
427 }
428
429 #if CONFIG_SYS_SDRAM_ECC_ENABLE
430 static void sc520_enable_ecc(void)
431
432         /* A nominal memory test: just a byte at each address line */
433         movl    %eax, %ecx
434         shrl    $0x1, %ecx
435         movl    $0x1, %edi
436 memtest0:
437         movb    $0xa5, (%edi)
438         cmpb    $0xa5, (%edi)
439         jne     out
440         shrl    $0x1, %ecx
441         andl    %ecx, %ecx
442         jz      set_ecc
443         shll    $0x1, %edi
444         jmp     memtest0
445
446 set_ecc:
447         /* clear all ram with a memset */
448         movl    %eax, %ecx
449         xorl    %esi, %esi
450         xorl    %edi, %edi
451         xorl    %eax, %eax
452         shrl    $0x2, %ecx
453         cld
454         rep     stosl
455
456         /* enable read, write buffers */
457         movb    $0x11, %al
458         movl    $DBCTL, %edi
459         movb    %al, (%edi)
460
461         /* enable NMI mapping for ECC */
462         movl    $ECCINT, %edi
463         movb    $0x10, %al
464         movb    %al, (%edi)
465
466         /* Turn on ECC */
467         movl    $ECCCTL, %edi
468         movb    $0x05, %al
469         movb    %al,(%edi)
470
471 out:
472         jmp     init_ecc_ret
473 }
474 #endif
475
476 int dram_init(void)
477 {
478         ulong dram_ctrl;
479         ulong dram_present = 0x00000000;
480
481         /*
482          * We read-back the configuration of the dram
483          * controller that the assembly code wrote
484          */
485         dram_ctrl = readl(&sc520_mmcr->drcbendadr);
486
487         gd->bd->bi_dram[0].start = 0;
488         if (dram_ctrl & 0x80) {
489                 /* bank 0 enabled */
490                 gd->bd->bi_dram[1].start = (dram_ctrl & 0x7f) << 22;
491                 dram_present = gd->bd->bi_dram[1].start;
492                 gd->bd->bi_dram[0].size = gd->bd->bi_dram[1].start;
493         } else {
494                 gd->bd->bi_dram[0].size = 0;
495                 gd->bd->bi_dram[1].start = gd->bd->bi_dram[0].start;
496         }
497
498         if (dram_ctrl & 0x8000) {
499                 /* bank 1 enabled */
500                 gd->bd->bi_dram[2].start = (dram_ctrl & 0x7f00) << 14;
501                 dram_present = gd->bd->bi_dram[2].start;
502                 gd->bd->bi_dram[1].size = gd->bd->bi_dram[2].start -
503                                 gd->bd->bi_dram[1].start;
504         } else {
505                 gd->bd->bi_dram[1].size = 0;
506                 gd->bd->bi_dram[2].start = gd->bd->bi_dram[1].start;
507         }
508
509         if (dram_ctrl & 0x800000) {
510                 /* bank 2 enabled */
511                 gd->bd->bi_dram[3].start = (dram_ctrl & 0x7f0000) << 6;
512                 dram_present = gd->bd->bi_dram[3].start;
513                 gd->bd->bi_dram[2].size = gd->bd->bi_dram[3].start -
514                                 gd->bd->bi_dram[2].start;
515         } else {
516                 gd->bd->bi_dram[2].size = 0;
517                 gd->bd->bi_dram[3].start = gd->bd->bi_dram[2].start;
518         }
519
520         if (dram_ctrl & 0x80000000) {
521                 /* bank 3 enabled */
522                 dram_present  = (dram_ctrl & 0x7f000000) >> 2;
523                 gd->bd->bi_dram[3].size = dram_present -
524                                 gd->bd->bi_dram[3].start;
525         } else {
526                 gd->bd->bi_dram[3].size = 0;
527         }
528
529         gd->ram_size = dram_present;
530
531         return 0;
532 }