TQM85xx: Bugfix in the SDRAM initialisation
[oweals/u-boot.git] / board / tqc / tqm85xx / sdram.c
1 /*
2  * (C) Copyright 2005
3  * Stefan Roese, DENX Software Engineering, sr@denx.de.
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/processor.h>
26 #include <asm/immap_85xx.h>
27 #include <asm/processor.h>
28 #include <asm/mmu.h>
29
30 struct sdram_conf_s {
31         unsigned long size;
32         unsigned long reg;
33 };
34
35 typedef struct sdram_conf_s sdram_conf_t;
36
37 sdram_conf_t ddr_cs_conf[] = {
38         {(512 << 20), 0x80000202},      /* 512MB, 14x10(4)      */
39         {(256 << 20), 0x80000102},      /* 256MB, 13x10(4)      */
40         {(128 << 20), 0x80000101},      /* 128MB, 13x9(4)       */
41         {( 64 << 20), 0x80000001},      /*  64MB, 12x9(4)       */
42 };
43
44 #define N_DDR_CS_CONF (sizeof(ddr_cs_conf) / sizeof(ddr_cs_conf[0]))
45
46 int cas_latency (void);
47
48 /*
49  * Autodetect onboard DDR SDRAM on 85xx platforms
50  *
51  * NOTE: Some of the hardcoded values are hardware dependant,
52  *       so this should be extended for other future boards
53  *       using this routine!
54  */
55 long int sdram_setup (int casl)
56 {
57         int i;
58         volatile ccsr_ddr_t *ddr = (void *)(CFG_MPC85xx_DDR_ADDR);
59         unsigned long cfg_ddr_timing1;
60         unsigned long cfg_ddr_mode;
61
62         /*
63          * Disable memory controller.
64          */
65         ddr->cs0_config = 0;
66         ddr->sdram_cfg = 0;
67
68         switch (casl) {
69         case 20:
70                 cfg_ddr_timing1 = 0x47405331 | (3 << 16);
71                 cfg_ddr_mode = 0x40020002 | (2 << 4);
72                 break;
73
74         case 25:
75                 cfg_ddr_timing1 = 0x47405331 | (4 << 16);
76                 cfg_ddr_mode = 0x40020002 | (6 << 4);
77                 break;
78
79         case 30:
80         default:
81                 cfg_ddr_timing1 = 0x47405331 | (5 << 16);
82                 cfg_ddr_mode = 0x40020002 | (3 << 4);
83                 break;
84         }
85
86         ddr->cs0_bnds = (ddr_cs_conf[0].size - 1) >> 24;
87         ddr->cs0_config = ddr_cs_conf[0].reg;
88         ddr->timing_cfg_1 = cfg_ddr_timing1;
89         ddr->timing_cfg_2 = 0x00000800;         /* P9-45,may need tuning */
90         ddr->sdram_mode = cfg_ddr_mode;
91         ddr->sdram_interval = 0x05160100;       /* autocharge,no open page */
92         ddr->err_disable = 0x0000000D;
93
94         asm ("sync; isync; msync");
95         udelay (1000);
96
97         ddr->sdram_cfg = 0xc2000000;            /* unbuffered,no DYN_PWR */
98         asm ("sync; isync; msync");
99         udelay (1000);
100
101         for (i = 0; i < N_DDR_CS_CONF; i++) {
102                 ddr->cs0_config = ddr_cs_conf[i].reg;
103
104                 if (get_ram_size (0, ddr_cs_conf[i].size) ==
105                     ddr_cs_conf[i].size) {
106                         /*
107                          * size detected -> set Chip Select Bounds Register
108                          */
109                         ddr->cs0_bnds = (ddr_cs_conf[i].size - 1) >> 24;
110
111                         return ddr_cs_conf[i].size;
112                 }
113         }
114
115         return 0;               /* nothing found !              */
116 }
117
118 void board_add_ram_info (int use_default)
119 {
120         int casl;
121
122         if (use_default)
123                 casl = CONFIG_DDR_DEFAULT_CL;
124         else
125                 casl = cas_latency ();
126
127         puts (" (CL=");
128         switch (casl) {
129         case 20:
130                 puts ("2)");
131                 break;
132
133         case 25:
134                 puts ("2.5)");
135                 break;
136
137         case 30:
138                 puts ("3)");
139                 break;
140         }
141 }
142
143 long int initdram (int board_type)
144 {
145         long dram_size = 0;
146         int casl;
147
148 #if defined(CONFIG_DDR_DLL)
149         /*
150          * This DLL-Override only used on TQM8540 and TQM8560
151          */
152         {
153                 volatile ccsr_gur_t *gur = (void *)(CFG_MPC85xx_GUTS_ADDR);
154                 int i, x;
155
156                 x = 10;
157
158                 /*
159                  * Work around to stabilize DDR DLL
160                  */
161                 gur->ddrdllcr = 0x81000000;
162                 asm ("sync; isync; msync");
163                 udelay (200);
164                 while (gur->ddrdllcr != 0x81000100) {
165                         gur->devdisr = gur->devdisr | 0x00010000;
166                         asm ("sync; isync; msync");
167                         for (i = 0; i < x; i++)
168                                 ;
169                         gur->devdisr = gur->devdisr & 0xfff7ffff;
170                         asm ("sync; isync; msync");
171                         x++;
172                 }
173         }
174 #endif
175
176         casl = cas_latency ();
177         dram_size = sdram_setup (casl);
178         if ((dram_size == 0) && (casl != CONFIG_DDR_DEFAULT_CL)) {
179                 /*
180                  * Try again with default CAS latency
181                  */
182                 puts ("Problem with CAS lantency");
183                 board_add_ram_info (1);
184                 puts (", using default CL!\n");
185                 casl = CONFIG_DDR_DEFAULT_CL;
186                 dram_size = sdram_setup (casl);
187                 puts ("       ");
188         }
189
190         return dram_size;
191 }
192
193 #if defined(CFG_DRAM_TEST)
194 int testdram (void)
195 {
196         uint *pstart = (uint *) CFG_MEMTEST_START;
197         uint *pend = (uint *) CFG_MEMTEST_END;
198         uint *p;
199
200         printf ("SDRAM test phase 1:\n");
201         for (p = pstart; p < pend; p++)
202                 *p = 0xaaaaaaaa;
203
204         for (p = pstart; p < pend; p++) {
205                 if (*p != 0xaaaaaaaa) {
206                         printf ("SDRAM test fails at: %08x\n", (uint) p);
207                         return 1;
208                 }
209         }
210
211         printf ("SDRAM test phase 2:\n");
212         for (p = pstart; p < pend; p++)
213                 *p = 0x55555555;
214
215         for (p = pstart; p < pend; p++) {
216                 if (*p != 0x55555555) {
217                         printf ("SDRAM test fails at: %08x\n", (uint) p);
218                         return 1;
219                 }
220         }
221
222         printf ("SDRAM test passed.\n");
223         return 0;
224 }
225 #endif