Merge branch 'mpc86xx'
[platform/kernel/u-boot.git] / board / nc650 / nc650.c
1 /*
2  * (C) Copyright 2006 Detlev Zundel, dzu@denx.de
3  * (C) Copyright 2001
4  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5  *
6  * See file CREDITS for list of people who contributed to this
7  * project.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  */
24
25 #include <common.h>
26 #include <config.h>
27 #include <mpc8xx.h>
28
29 /*
30  *  Memory Controller Using
31  *
32  *  CS0 - Flash memory            (0x40000000)
33  *  CS3 - SDRAM                   (0x00000000}
34  */
35
36 /* ------------------------------------------------------------------------- */
37
38 #define _not_used_      0xffffffff
39
40 const uint sdram_table[] = {
41         /* single read. (offset 0 in upm RAM) */
42         0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00,
43         0x1ff77c47,
44
45         /* MRS initialization (offset 5) */
46
47         0x1ff77c34, 0xefeabc34, 0x1fb57c35,
48
49         /* burst read. (offset 8 in upm RAM) */
50         0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
51         0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47,
52         _not_used_, _not_used_, _not_used_, _not_used_,
53         _not_used_, _not_used_, _not_used_, _not_used_,
54
55         /* single write. (offset 18 in upm RAM) */
56         0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47,
57         _not_used_, _not_used_, _not_used_, _not_used_,
58
59         /* burst write. (offset 20 in upm RAM) */
60         0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00,
61         0xf0affc00, 0xe1bbbc04, 0x1ff77c47, _not_used_,
62         _not_used_, _not_used_, _not_used_, _not_used_,
63         _not_used_, _not_used_, _not_used_, _not_used_,
64
65         /* refresh. (offset 30 in upm RAM) */
66         0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
67         0xfffffc84, 0xfffffc07, _not_used_, _not_used_,
68         _not_used_, _not_used_, _not_used_, _not_used_,
69
70         /* exception. (offset 3c in upm RAM) */
71         0x7ffffc07, _not_used_, _not_used_, _not_used_
72 };
73
74 const uint nand_flash_table[] = {
75         /* single read. (offset 0 in upm RAM) */
76         0x0ff3fc04, 0x0ff3fc04, 0x0ff3fc04, 0x0ffffc04,
77         0xfffffc00, 0xfffffc05, 0xfffffc05, 0xfffffc05,
78
79         /* burst read. (offset 8 in upm RAM) */
80         0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
81         0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
82         0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
83         0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
84
85         /* single write. (offset 18 in upm RAM) */
86         0x00fffc04, 0x00fffc04, 0x00fffc04, 0x0ffffc04,
87         0x0ffffc84, 0x0ffffc84, 0xfffffc00, 0xfffffc05,
88
89         /* burst write. (offset 20 in upm RAM) */
90         0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
91         0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
92         0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
93         0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
94
95         /* refresh. (offset 30 in upm RAM) */
96         0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
97         0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
98         0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
99
100         /* exception. (offset 3c in upm RAM) */
101         0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05
102 };
103
104 /* ------------------------------------------------------------------------- */
105
106 /*
107  * Check Board Identity:
108  */
109
110 int checkboard (void)
111 {
112 #if !defined(CONFIG_CP850)
113         puts ("Board: NC650");
114 #else
115         puts ("Board: CP850");
116 #endif
117 #if defined(CONFIG_IDS852_REV1)
118         puts (" with IDS852 rev 1 module\n");
119 #elif defined(CONFIG_IDS852_REV2)
120         puts (" with IDS852 rev 2 module\n");
121 #endif
122         return 0;
123 }
124
125 /* ------------------------------------------------------------------------- */
126
127 static long int dram_size (long int, long int *, long int);
128
129 /* ------------------------------------------------------------------------- */
130
131 long int initdram (int board_type)
132 {
133         volatile immap_t *immap = (immap_t *) CFG_IMMR;
134         volatile memctl8xx_t *memctl = &immap->im_memctl;
135         long int size8, size9;
136         long int size_b0 = 0;
137         unsigned long reg;
138
139         upmconfig (UPMA, (uint *) sdram_table,
140                            sizeof (sdram_table) / sizeof (uint));
141
142         /*
143          * Preliminary prescaler for refresh (depends on number of
144          * banks): This value is selected for four cycles every 62.4 us
145          * with two SDRAM banks or four cycles every 31.2 us with one
146          * bank. It will be adjusted after memory sizing.
147          */
148         memctl->memc_mptpr = CFG_MPTPR_2BK_8K;
149
150         memctl->memc_mar = 0x00000088;
151
152         /*
153          * Map controller bank 1 to the SDRAM bank at
154          * preliminary address - these have to be modified after the
155          * SDRAM size has been determined.
156          */
157         memctl->memc_or3 = CFG_OR3_PRELIM;
158         memctl->memc_br3 = CFG_BR3_PRELIM;
159
160         memctl->memc_mamr = CFG_MAMR_8COL & (~(MAMR_PTAE));     /* no refresh yet */
161
162         udelay (200);
163
164         /* perform SDRAM initializsation sequence */
165
166         memctl->memc_mcr = 0x80006105;  /* SDRAM bank 0 */
167         udelay (200);
168         memctl->memc_mcr = 0x80006230;  /* SDRAM bank 0 - execute twice */
169         udelay (200);
170
171         memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */
172
173         udelay (1000);
174
175         /*
176          * Check Bank 0 Memory Size for re-configuration
177          *
178          * try 8 column mode
179          */
180         size8 = dram_size (CFG_MAMR_8COL, (ulong *) SDRAM_BASE3_PRELIM,
181                                            SDRAM_MAX_SIZE);
182
183         udelay (1000);
184
185         /*
186          * try 9 column mode
187          */
188         size9 = dram_size (CFG_MAMR_9COL, (ulong *) SDRAM_BASE3_PRELIM,
189                                           SDRAM_MAX_SIZE);
190
191         udelay (1000);
192
193         if (size8 < size9) {
194                 size_b0 = size9;
195         } else {
196                 size_b0 = size8;
197                 memctl->memc_mamr = CFG_MAMR_8COL;
198                 udelay (500);
199         }
200
201         /*
202          * Adjust refresh rate depending on SDRAM type, both banks.
203          * For types > 128 MBit leave it at the current (fast) rate
204          */
205         if ((size_b0 < 0x02000000)) {
206                 /* reduce to 15.6 us (62.4 us / quad) */
207                 memctl->memc_mptpr = CFG_MPTPR_2BK_4K;
208                 udelay (1000);
209         }
210
211         /*
212          * Final mapping
213          */
214
215         memctl->memc_or3 = ((-size_b0) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
216         memctl->memc_br3 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
217
218         /* adjust refresh rate depending on SDRAM type, one bank */
219         reg = memctl->memc_mptpr;
220         reg >>= 1;                                      /* reduce to CFG_MPTPR_1BK_8K / _4K */
221         memctl->memc_mptpr = reg;
222
223         udelay (10000);
224
225         /* Configure UPMB for NAND flash access */
226         upmconfig (UPMB, (uint *) nand_flash_table,
227                            sizeof (nand_flash_table) / sizeof (uint));
228
229         memctl->memc_mbmr = CFG_MBMR_NAND;
230
231         return (size_b0);
232 }
233
234 /* ------------------------------------------------------------------------- */
235
236 /*
237  * Check memory range for valid RAM. A simple memory test determines
238  * the actually available RAM size between addresses `base' and
239  * `base + maxsize'. Some (not all) hardware errors are detected:
240  * - short between address lines
241  * - short between data lines
242  */
243
244 static long int dram_size (long int mamr_value, long int *base, long int maxsize)
245 {
246         volatile immap_t *immap = (immap_t *) CFG_IMMR;
247         volatile memctl8xx_t *memctl = &immap->im_memctl;
248
249         memctl->memc_mamr = mamr_value;
250
251         return (get_ram_size(base, maxsize));
252 }
253
254
255 #if defined(CONFIG_CP850)
256
257 #define DPRAM_VARNAME           "KP850DIP"
258 #define PARAM_ADDR              0x7C0
259 #define NAME_ADDR               0x7F8
260 #define BOARD_NAME              "KP01"
261 #define DEFAULT_LB              "241111"
262
263 int misc_init_r(void)
264 {
265         int             iCompatMode = 0;
266         char            *pParam = NULL;
267         char            *envlb;
268
269         /*
270            First byte in CPLD read address space signals compatibility mode
271            0 - cp850
272            1 - kp852
273         */
274         pParam = (char*)(CFG_CPLD_BASE);
275         if( *pParam != 0)
276                 iCompatMode = 1;
277
278         if ( iCompatMode != 0) {
279                 /*
280                    In KP852 compatibility mode we have to write to
281                    DPRAM as early as possible the binary coded
282                    line config and board name.
283                    The line config is derived from the environment
284                    variable DPRAM_VARNAME by converting from ASCII
285                    to binary per character.
286                 */
287                 if ( (envlb = getenv ( DPRAM_VARNAME )) == 0) {
288                         setenv( DPRAM_VARNAME, DEFAULT_LB);
289                         envlb = DEFAULT_LB;
290                 }
291
292                 /* Status string */
293                 printf("Mode:  KP852(LB=%s)\n", envlb);
294
295                 /* copy appl init */
296                 pParam = (char*)(DPRAM_BASE_ADDR + PARAM_ADDR);
297                 while (*envlb) {
298                         *(pParam++) = *(envlb++) - '0';
299                 }
300                 *pParam = '\0';
301
302                 /* copy board id */
303                 pParam = (char*)(DPRAM_BASE_ADDR + NAME_ADDR);
304                 strcpy( pParam, BOARD_NAME);
305         } else {
306                 puts("Mode:  CP850\n");
307         }
308
309         return 0;
310 }
311 #endif