]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/mbx8xx/mbx8xx.c
nand: remove CONFIG_SYS_NAND_PAGE_SIZE
[karo-tx-uboot.git] / board / mbx8xx / mbx8xx.c
1 /*
2  * (C) Copyright 2000
3  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
4  * Marius Groeger <mgroeger@sysgo.de>
5  *
6  * Board specific routines for the MBX
7  *
8  * - initialisation
9  * - interface to VPD data (mac address, clock speeds)
10  * - memory controller
11  * - serial io initialisation
12  * - ethernet io initialisation
13  *
14  * -----------------------------------------------------------------
15  * SPDX-License-Identifier:     GPL-2.0+
16  */
17
18 #include <common.h>
19 #include <commproc.h>
20 #include <mpc8xx.h>
21 #include <net.h>
22 #include "dimm.h"
23 #include "vpd.h"
24 #include "csr.h"
25
26 /* ------------------------------------------------------------------------- */
27
28 static const uint sdram_table_40[] = {
29         /* DRAM - single read. (offset 0 in upm RAM)
30          */
31         0xCFAFC004, 0x0FAFC404, 0x0CAF0C04, 0x30AF0C00,
32         0xF1BF4805, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
33
34         /* DRAM - burst read. (offset 8 in upm RAM)
35          */
36         0xCFAFC004, 0x0FAFC404, 0x0CAF0C04, 0x03AF0C08,
37         0x0CAF0C04, 0x03AF0C08, 0x0CAF0C04, 0x03AF0C08,
38         0x0CAF0C04, 0x30AF0C00, 0xF3BF4805, 0xFFFFC005,
39         0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
40
41         /* DRAM - single write. (offset 18 in upm RAM)
42          */
43         0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x33FF4804,
44         0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
45
46         /* DRAM - burst write. (offset 20 in upm RAM)
47          */
48         0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x03FF0C0C,
49         0x0CFF0C00, 0x03FF0C0C, 0x0CFF0C00, 0x03FF0C0C,
50         0x0CFF0C00, 0x33FF4804, 0xFFFFC005, 0xFFFFC005,
51         0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
52
53         /* refresh  (offset 30 in upm RAM)
54          */
55         0xFCFFC004, 0xC0FFC004, 0x01FFC004, 0x0FFFC004,
56         0x3FFFC004, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
57         0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
58
59         /* exception. (offset 3c in upm RAM)
60          */
61         0xFFFFC007, 0xFFFFC007, 0xFFFFC007, 0xFFFFC007,
62 };
63
64 static const uint sdram_table_50[] = {
65         /* DRAM - single read. (offset 0 in upm RAM)
66          */
67         0xCFAFC004, 0x0FAFC404, 0x0CAF8C04, 0x10AF0C04,
68         0xF0AF0C00, 0xF3BF4805, 0xFFFFC005, 0xFFFFC005,
69
70         /* DRAM - burst read. (offset 8 in upm RAM)
71          */
72         0xCFAFC004, 0X0FAFC404, 0X0CAF8C04, 0X00AF0C04,
73   /*    0X07AF0C08, 0X0CAF0C04, 0X01AF0C04, 0X0FAF0C04, */
74         0X07AF0C08, 0X0CAF0C04, 0X01AF0C04, 0X0FAF0C08,
75         0X0CAF0C04, 0X01AF0C04, 0X0FAF0C08, 0X0CAF0C04,
76   /*    0X10AF0C04, 0XF0AFC000, 0XF3FF4805, 0XFFFFC005, */
77         0X10AF0C04, 0XF0AFC000, 0XF3BF4805, 0XFFFFC005,
78
79         /* DRAM - single write. (offset 18 in upm RAM)
80          */
81         0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x13FF4804,
82         0xFFFFC004, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
83
84         /* DRAM - burst write. (offset 20 in upm RAM)
85          */
86         0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x03FF0C0C,
87         0x0CFF0C00, 0x03FF0C0C, 0x0CFF0C00, 0x03FF0C0C,
88         0x0CFF0C00, 0x13FF4804, 0xFFFFC004, 0xFFFFC005,
89         0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
90
91         /* refresh  (offset 30 in upm RAM)
92          */
93         0xFCFFC004, 0xC0FFC004, 0x01FFC004, 0x0FFFC004,
94         0x1FFFC004, 0xFFFFC004, 0xFFFFC005, 0xFFFFC005,
95         0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
96
97         /* exception. (offset 3c in upm RAM)
98          */
99         0xFFFFC007, 0xFFFFC007, 0xFFFFC007, 0xFFFFC007,
100 };
101
102 /* ------------------------------------------------------------------------- */
103
104 #ifdef CONFIG_SYS_USE_OSCCLK
105 static unsigned int get_reffreq(void);
106 #endif
107 static unsigned int board_get_cpufreq(void);
108
109 void mbx_init (void)
110 {
111         volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
112         volatile memctl8xx_t *memctl = &immr->im_memctl;
113         ulong speed, plprcr, sccr;
114         ulong br0_32 = memctl->memc_br0 & 0x400;
115
116         /* real-time clock status and control register */
117         immr->im_sitk.sitk_rtcsck = KAPWR_KEY;
118         immr->im_sit.sit_rtcsc = 0x00C3;
119
120         /* SIEL and SIMASK Registers (see MBX PRG 2-3) */
121         immr->im_siu_conf.sc_simask = 0x00000000;
122         immr->im_siu_conf.sc_siel = 0xAAAA0000;
123         immr->im_siu_conf.sc_tesr = 0xFFFFFFFF;
124
125         /*
126          * Prepare access to i2c bus. The MBX offers 3 devices on the i2c bus:
127          * 1. Vital Product Data (contains clock speeds, MAC address etc, see vpd.h)
128          * 2. RAM  Specs (see dimm.h)
129          * 2. DIMM Specs (see dimm.h)
130          */
131         vpd_init ();
132
133         /* system clock and reset control register */
134         immr->im_clkrstk.cark_sccrk = KAPWR_KEY;
135         sccr = immr->im_clkrst.car_sccr;
136         sccr &= SCCR_MASK;
137         sccr |= CONFIG_SYS_SCCR;
138         immr->im_clkrst.car_sccr = sccr;
139
140         speed = board_get_cpufreq ();
141
142 #if ((CONFIG_SYS_PLPRCR & PLPRCR_MF_MSK) != 0)
143         plprcr = CONFIG_SYS_PLPRCR;
144 #else
145         plprcr = immr->im_clkrst.car_plprcr;
146         plprcr &= PLPRCR_MF_MSK;        /* isolate MF field */
147         plprcr |= CONFIG_SYS_PLPRCR;            /* reset control bits   */
148 #endif
149
150 #ifdef CONFIG_SYS_USE_OSCCLK                    /* See doc/README.MBX ! */
151         plprcr |= ((speed + get_reffreq() / 2) / refclock - 1) << 20;
152 #endif
153
154         immr->im_clkrstk.cark_plprcrk = KAPWR_KEY;
155         immr->im_clkrst.car_plprcr = plprcr;
156
157         /*
158          * preliminary setup of memory controller:
159          * - map Flash, otherwise configuration/status
160          *    registers won't be accessible when read
161          *    by board_init_f.
162          * - map NVRAM and configuation/status registers.
163          * - map pci registers.
164          * - DON'T map ram yet, this is done in initdram().
165          */
166         switch (speed / 1000000) {
167         case 40:
168                 memctl->memc_br0 = 0xFE000000 | br0_32 | 1;
169                 memctl->memc_or0 = 0xFF800930;
170                 memctl->memc_or4 = CONFIG_SYS_NVRAM_OR | 0x920;
171                 memctl->memc_br4 = CONFIG_SYS_NVRAM_BASE | 0x401;
172                 break;
173         case 50:
174                 memctl->memc_br0 = 0xFE000000 | br0_32 | 1;
175                 memctl->memc_or0 = 0xFF800940;
176                 memctl->memc_or4 = CONFIG_SYS_NVRAM_OR | 0x930;
177                 memctl->memc_br4 = CONFIG_SYS_NVRAM_BASE | 0x401;
178                 break;
179         default:
180                 hang ();
181                 break;
182         }
183 #ifdef CONFIG_USE_PCI
184         memctl->memc_or5 = CONFIG_SYS_PCIMEM_OR;
185         memctl->memc_br5 = CONFIG_SYS_PCIMEM_BASE | 0x001;
186         memctl->memc_or6 = CONFIG_SYS_PCIBRIDGE_OR;
187         memctl->memc_br6 = CONFIG_SYS_PCIBRIDGE_BASE | 0x001;
188 #endif
189         /*
190          * FIXME: I do not understand why I have to call this to
191          * initialise the control register here before booting from
192          * the PCMCIA card but if I do not the Linux kernel falls
193          * over in a big heap. If you can answer this question I
194          * would like to know about it.
195          */
196         board_ether_init();
197 }
198
199 void board_serial_init (void)
200 {
201         MBX_CSR1 &= ~(CSR1_COM1EN | CSR1_XCVRDIS);
202 }
203
204 void board_ether_init (void)
205 {
206         MBX_CSR1 &= ~(CSR1_EAEN | CSR1_ELEN);
207         MBX_CSR1 |= CSR1_ETEN | CSR1_TPEN | CSR1_FDDIS;
208 }
209
210 static unsigned int board_get_cpufreq (void)
211 {
212 #ifndef CONFIG_8xx_GCLK_FREQ
213         vpd_packet_t *packet;
214         ulong *p;
215
216         packet = vpd_find_packet (VPD_PID_ICS);
217         p = (ulong *)packet->data;
218         return *p;
219 #else
220         return((unsigned int)CONFIG_8xx_GCLK_FREQ );
221 #endif /* CONFIG_8xx_GCLK_FREQ */
222 }
223
224 #ifdef CONFIG_SYS_USE_OSCCLK
225 static unsigned int get_reffreq (void)
226 {
227         vpd_packet_t *packet;
228         ulong *p;
229
230         packet = vpd_find_packet (VPD_PID_RCS);
231         p = (ulong *)packet->data;
232         return *p;
233 }
234 #endif
235
236 static void board_get_enetaddr(uchar *addr)
237 {
238         int i;
239         vpd_packet_t *packet;
240
241         packet = vpd_find_packet (VPD_PID_EA);
242         for (i = 0; i < 6; i++)
243                 addr[i] = packet->data[i];
244 }
245
246 int misc_init_r(void)
247 {
248         uchar enetaddr[6];
249
250         if (!eth_getenv_enetaddr("ethaddr", enetaddr)) {
251                 board_get_enetaddr(enetaddr);
252                 eth_setenv_enetaddr("ethaddr", enetaddr);
253         }
254
255         return 0;
256 }
257
258 /*
259  * Check Board Identity:
260  */
261
262 int checkboard (void)
263 {
264         vpd_packet_t *packet;
265         int i;
266         const char *const fmt =
267                 "\n      *** Warning: Low Battery Status - %s Battery ***";
268
269         puts ("Board: ");
270
271         packet = vpd_find_packet (VPD_PID_PID);
272         for (i = 0; i < packet->size; i++) {
273                 serial_putc (packet->data[i]);
274         }
275         packet = vpd_find_packet (VPD_PID_MT);
276         for (i = 0; i < packet->size; i++) {
277                 serial_putc (packet->data[i]);
278         }
279         serial_putc ('(');
280         packet = vpd_find_packet (VPD_PID_FAN);
281         for (i = 0; i < packet->size; i++) {
282                 serial_putc (packet->data[i]);
283         }
284         serial_putc (')');
285
286         if (!(MBX_CSR2 & SR2_BATGD))
287                 printf (fmt, "On-Board");
288         if (!(MBX_CSR2 & SR2_NVBATGD))
289                 printf (fmt, "NVRAM");
290
291         serial_putc ('\n');
292
293         return (0);
294 }
295
296 /* ------------------------------------------------------------------------- */
297
298 static ulong get_ramsize (dimm_t * dimm)
299 {
300         ulong size = 0;
301
302         if (dimm->fmt == 1 || dimm->fmt == 2 || dimm->fmt == 3
303                 || dimm->fmt == 4) {
304                 size = (1 << (dimm->n_row + dimm->n_col)) * dimm->n_banks *
305                         ((dimm->data_w_hi << 8 | dimm->data_w_lo) / 8);
306         }
307
308         return size;
309 }
310
311 phys_size_t initdram (int board_type)
312 {
313         volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
314         volatile memctl8xx_t *memctl = &immap->im_memctl;
315         unsigned long ram_sz = 0;
316         unsigned long dimm_sz = 0;
317         dimm_t vpd_dimm, vpd_dram;
318         unsigned int speed = board_get_cpufreq () / 1000000;
319
320         if (vpd_read (0xa2, (uchar *) & vpd_dimm, sizeof (vpd_dimm), 0) > 0) {
321                 dimm_sz = get_ramsize (&vpd_dimm);
322         }
323         if (vpd_read (0xa6, (uchar *) & vpd_dram, sizeof (vpd_dram), 0) > 0) {
324                 ram_sz = get_ramsize (&vpd_dram);
325         }
326
327         /*
328          * Only initialize memory controller when running from FLASH.
329          * When running from RAM, don't touch it.
330          */
331         if ((ulong) initdram & 0xff000000) {
332                 ulong dimm_bank;
333                 ulong br0_32 = memctl->memc_br0 & 0x400;
334
335                 switch (speed) {
336                 case 40:
337                         upmconfig (UPMA, (uint *) sdram_table_40,
338                                            sizeof (sdram_table_40) / sizeof (uint));
339                         memctl->memc_mptpr = 0x0200;
340                         memctl->memc_mamr = dimm_sz ? 0x06801000 : 0x13801000;
341                         memctl->memc_or7 = 0xff800930;
342                         memctl->memc_br7 = 0xfc000000 | (br0_32 ^ br0_32) | 1;
343                         break;
344                 case 50:
345                         upmconfig (UPMA, (uint *) sdram_table_50,
346                                            sizeof (sdram_table_50) / sizeof (uint));
347                         memctl->memc_mptpr = 0x0200;
348                         memctl->memc_mamr = dimm_sz ? 0x08801000 : 0x1880100;
349                         memctl->memc_or7 = 0xff800940;
350                         memctl->memc_br7 = 0xfc000000 | (br0_32 ^ br0_32) | 1;
351                         break;
352                 default:
353                         hang ();
354                         break;
355                 }
356
357                 /* now map ram and dimm, largest one first */
358                 dimm_bank = dimm_sz / 2;
359                 if (!dimm_sz) {
360                         memctl->memc_or1 = ~(ram_sz - 1) | 0x400;
361                         memctl->memc_br1 = CONFIG_SYS_SDRAM_BASE | 0x81;
362                         memctl->memc_br2 = 0;
363                         memctl->memc_br3 = 0;
364                 } else if (ram_sz > dimm_bank) {
365                         memctl->memc_or1 = ~(ram_sz - 1) | 0x400;
366                         memctl->memc_br1 = CONFIG_SYS_SDRAM_BASE | 0x81;
367                         memctl->memc_or2 = ~(dimm_bank - 1) | 0x400;
368                         memctl->memc_br2 = (CONFIG_SYS_SDRAM_BASE + ram_sz) | 0x81;
369                         memctl->memc_or3 = ~(dimm_bank - 1) | 0x400;
370                         memctl->memc_br3 = (CONFIG_SYS_SDRAM_BASE + ram_sz + dimm_bank) \
371                                                                      | 0x81;
372                 } else {
373                         memctl->memc_or2 = ~(dimm_bank - 1) | 0x400;
374                         memctl->memc_br2 = CONFIG_SYS_SDRAM_BASE | 0x81;
375                         memctl->memc_or3 = ~(dimm_bank - 1) | 0x400;
376                         memctl->memc_br3 = (CONFIG_SYS_SDRAM_BASE + dimm_bank) | 0x81;
377                         memctl->memc_or1 = ~(ram_sz - 1) | 0x400;
378                         memctl->memc_br1 = (CONFIG_SYS_SDRAM_BASE + dimm_sz) | 0x81;
379                 }
380         }
381
382         return ram_sz + dimm_sz;
383 }