Add support for TQM8541/8555 boards, TQM85xx support reworked:
[oweals/u-boot.git] / 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 immap_t *immap = (immap_t *) CFG_IMMR;
61         volatile ccsr_ddr_t *ddr = &immap->im_ddr;
62         unsigned long cfg_ddr_timing1;
63         unsigned long cfg_ddr_mode;
64
65         /*
66          * Disable memory controller.
67          */
68         ddr->cs0_config = 0;
69         ddr->sdram_cfg = 0;
70
71         switch (casl) {
72         case 20:
73                 cfg_ddr_timing1 = 0x47405331 | (3 << 16);
74                 cfg_ddr_mode = 0x40020002 | (2 << 4);
75                 break;
76
77         case 25:
78                 cfg_ddr_timing1 = 0x47405331 | (4 << 16);
79                 cfg_ddr_mode = 0x40020002 | (6 << 4);
80                 break;
81
82         case 30:
83         default:
84                 cfg_ddr_timing1 = 0x47405331 | (5 << 16);
85                 cfg_ddr_mode = 0x40020002 | (3 << 4);
86                 break;
87         }
88
89         ddr->cs0_bnds = (ddr_cs_conf[0].size - 1) >> 24;
90         ddr->cs0_config = ddr_cs_conf[0].reg;
91         ddr->timing_cfg_1 = cfg_ddr_timing1;
92         ddr->timing_cfg_2 = 0x00000800;         /* P9-45,may need tuning */
93         ddr->sdram_mode = cfg_ddr_mode;
94         ddr->sdram_interval = 0x05160100;       /* autocharge,no open page */
95         ddr->err_disable = 0x0000000D;
96
97         asm ("sync;isync;msync");
98         udelay(1000);
99
100         ddr->sdram_cfg = 0xc2000000;            /* unbuffered,no DYN_PWR */
101         asm ("sync; isync; msync");
102         udelay(1000);
103
104         for (i=0; i<N_DDR_CS_CONF; i++) {
105                 ddr->cs0_config = ddr_cs_conf[i].reg;
106
107                 if (get_ram_size(0, ddr_cs_conf[i].size) == ddr_cs_conf[i].size) {
108                         /*
109                          * OK, size detected -> all done
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 immap_t *immap = (immap_t *) CFG_IMMR;
154                 volatile ccsr_gur_t *gur= &immap->im_gur;
155                 int i,x;
156
157                 x = 10;
158
159                 /*
160                  * Work around to stabilize DDR DLL
161                  */
162                 gur->ddrdllcr = 0x81000000;
163                 asm("sync;isync;msync");
164                 udelay (200);
165                 while (gur->ddrdllcr != 0x81000100) {
166                         gur->devdisr = gur->devdisr | 0x00010000;
167                         asm("sync;isync;msync");
168                         for (i=0; i<x; i++)
169                                 ;
170                         gur->devdisr = gur->devdisr & 0xfff7ffff;
171                         asm("sync;isync;msync");
172                         x++;
173                 }
174         }
175 #endif
176
177         casl = cas_latency();
178         dram_size = sdram_setup(casl);
179         if ((dram_size == 0) && (casl != CONFIG_DDR_DEFAULT_CL)) {
180                 /*
181                  * Try again with default CAS latency
182                  */
183                 puts("Problem with CAS lantency");
184                 board_add_ram_info(1);
185                 puts(", using default CL!\n");
186                 casl = CONFIG_DDR_DEFAULT_CL;
187                 dram_size = sdram_setup(casl);
188                 puts("       ");
189         }
190
191         return dram_size;
192 }
193
194 #if defined(CFG_DRAM_TEST)
195 int testdram (void)
196 {
197         uint *pstart = (uint *) CFG_MEMTEST_START;
198         uint *pend = (uint *) CFG_MEMTEST_END;
199         uint *p;
200
201         printf ("SDRAM test phase 1:\n");
202         for (p = pstart; p < pend; p++)
203                 *p = 0xaaaaaaaa;
204
205         for (p = pstart; p < pend; p++) {
206                 if (*p != 0xaaaaaaaa) {
207                         printf ("SDRAM test fails at: %08x\n", (uint) p);
208                         return 1;
209                 }
210         }
211
212         printf ("SDRAM test phase 2:\n");
213         for (p = pstart; p < pend; p++)
214                 *p = 0x55555555;
215
216         for (p = pstart; p < pend; p++) {
217                 if (*p != 0x55555555) {
218                         printf ("SDRAM test fails at: %08x\n", (uint) p);
219                         return 1;
220                 }
221         }
222
223         printf ("SDRAM test passed.\n");
224         return 0;
225 }
226 #endif