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