import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / arch / mips / lasat / lasat_board.c
1 /*
2  * lasat_board.c
3  *
4  * Thomas Horsten <thh@lasat.com>
5  * Copyright (C) 2000 LASAT Networks A/S.
6  *
7  * ########################################################################
8  *
9  *  This program is free software; you can distribute it and/or modify it
10  *  under the terms of the GNU General Public License (Version 2) as
11  *  published by the Free Software Foundation.
12  *
13  *  This program is distributed in the hope it will be useful, but WITHOUT
14  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16  *  for more details.
17  *
18  *  You should have received a copy of the GNU General Public License along
19  *  with this program; if not, write to the Free Software Foundation, Inc.,
20  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
21  *
22  * ########################################################################
23  *
24  * Routines specific to the LASAT boards
25  */
26 #include <linux/types.h>
27 #include <linux/crc32.h>
28 #include <asm/lasat/lasat.h>
29 #include <linux/kernel.h>
30 #include <linux/string.h>
31 #include <linux/ctype.h>
32 #include <asm/bootinfo.h>
33 #include <asm/addrspace.h>
34 #include "at93c.h"
35 /* New model description table */
36 #include "lasat_models.h"
37
38 #define EEPROM_CRC(data, len) (~0 ^ crc32(~0, data, len))
39
40 struct lasat_info lasat_board_info;
41
42 void update_bcastaddr(void);
43
44 int EEPROMRead(unsigned int pos, unsigned char *data, int len)
45 {
46         int i;
47
48         for (i=0; i<len; i++)
49                 *data++ = at93c_read(pos++);
50
51         return 0;
52 }
53 int EEPROMWrite(unsigned int pos, unsigned char *data, int len)
54 {
55         int i;
56
57         for (i=0; i<len; i++)
58                 at93c_write(pos++, *data++);
59
60         return 0;
61 }
62
63 static void init_flash_sizes(void)
64 {
65         int i;
66         unsigned long *lb = lasat_board_info.li_flashpart_base;
67         unsigned long *ls = lasat_board_info.li_flashpart_size;
68
69         ls[LASAT_MTD_BOOTLOADER] = 0x40000;
70         ls[LASAT_MTD_SERVICE] = 0xC0000;
71         ls[LASAT_MTD_NORMAL] = 0x100000;
72
73         if (mips_machtype == MACH_LASAT_100) {
74                 lasat_board_info.li_flash_base = 0x1e000000;
75                 
76                 lb[LASAT_MTD_BOOTLOADER] = 0x1e400000;
77
78                 if (lasat_board_info.li_flash_size > 0x200000) {
79                         ls[LASAT_MTD_CONFIG] = 0x100000;
80                         ls[LASAT_MTD_FS] = 0x500000;
81                 }
82         } else {
83                 lasat_board_info.li_flash_base = 0x10000000;
84
85                 if (lasat_board_info.li_flash_size < 0x1000000) {
86                         lb[LASAT_MTD_BOOTLOADER] = 0x10000000;
87                         ls[LASAT_MTD_CONFIG] = 0x100000;
88                         if (lasat_board_info.li_flash_size >= 0x400000) {
89                                 ls[LASAT_MTD_FS] = lasat_board_info.li_flash_size - 0x300000;
90                         }
91                 }
92         }
93
94         for (i = 1; i < LASAT_MTD_LAST; i++)
95                 lb[i] = lb[i-1] + ls[i-1];
96 }
97
98 int lasat_init_board_info(void)
99 {
100         int c;
101         unsigned long crc;
102         unsigned long cfg0, cfg1;
103         const product_info_t   *ppi;
104         int i_n_base_models = N_BASE_MODELS;
105         const char * const * i_txt_base_models = txt_base_models;
106         int i_n_prids = N_PRIDS;
107
108         memset(&lasat_board_info, 0, sizeof(lasat_board_info));
109
110         /* First read the EEPROM info */
111         EEPROMRead(0, (unsigned char *)&lasat_board_info.li_eeprom_info, 
112                    sizeof(struct lasat_eeprom_struct));
113
114         /* Check the CRC */
115         crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info),
116                     sizeof(struct lasat_eeprom_struct) - 4);
117
118         if (crc != lasat_board_info.li_eeprom_info.crc32) {
119                 prom_printf("WARNING...\nWARNING...\nEEPROM CRC does not match calculated, attempting to soldier on...\n");
120         }
121
122         if (lasat_board_info.li_eeprom_info.version != LASAT_EEPROM_VERSION)
123         {
124                 prom_printf("WARNING...\nWARNING...\nEEPROM version %d, wanted version %d, attempting to soldier on...\n",
125                        (unsigned int)lasat_board_info.li_eeprom_info.version,
126                        LASAT_EEPROM_VERSION);
127         }
128
129         cfg0 = lasat_board_info.li_eeprom_info.cfg[0];
130         cfg1 = lasat_board_info.li_eeprom_info.cfg[1];
131
132         if ( LASAT_W0_DSCTYPE(cfg0) != 1) {
133                 prom_printf("WARNING...\nWARNING...\nInvalid configuration read from EEPROM, attempting to soldier on...");
134         }
135         /* We have a valid configuration */
136
137         switch (LASAT_W0_SDRAMBANKSZ(cfg0)) {
138         case 0:
139                 lasat_board_info.li_memsize = 0x0800000;
140                 break;
141         case 1:
142                 lasat_board_info.li_memsize = 0x1000000;
143                 break;
144         case 2:
145                 lasat_board_info.li_memsize = 0x2000000;
146                 break;
147         case 3:
148                 lasat_board_info.li_memsize = 0x4000000;
149                 break;
150         case 4:
151                 lasat_board_info.li_memsize = 0x8000000;
152                 break;
153         default:
154                 lasat_board_info.li_memsize = 0;
155         }
156
157         switch (LASAT_W0_SDRAMBANKS(cfg0)) {
158         case 0:
159                 break;
160         case 1:
161                 lasat_board_info.li_memsize *= 2;
162                 break;
163         default:
164                 break;
165         }
166
167         switch (LASAT_W0_BUSSPEED(cfg0)) {
168         case 0x0:
169                 lasat_board_info.li_bus_hz = 60000000;
170                 break;
171         case 0x1:
172                 lasat_board_info.li_bus_hz = 66000000;
173                 break;
174         case 0x2:
175                 lasat_board_info.li_bus_hz = 66666667;
176                 break;
177         case 0x3:
178                 lasat_board_info.li_bus_hz = 80000000;
179                 break;
180         case 0x4:
181                 lasat_board_info.li_bus_hz = 83333333;
182                 break;
183         case 0x5:
184                 lasat_board_info.li_bus_hz = 100000000;
185                 break;
186         }
187
188         switch (LASAT_W0_CPUCLK(cfg0)) {
189         case 0x0:
190                 lasat_board_info.li_cpu_hz =
191                         lasat_board_info.li_bus_hz;
192                 break;
193         case 0x1:
194                 lasat_board_info.li_cpu_hz =
195                         lasat_board_info.li_bus_hz +
196                         (lasat_board_info.li_bus_hz >> 1);      
197                 break;
198         case 0x2:
199                 lasat_board_info.li_cpu_hz =
200                         lasat_board_info.li_bus_hz +
201                         lasat_board_info.li_bus_hz;
202                 break;
203         case 0x3:
204                 lasat_board_info.li_cpu_hz =
205                         lasat_board_info.li_bus_hz +
206                         lasat_board_info.li_bus_hz +
207                         (lasat_board_info.li_bus_hz >> 1);
208                 break;
209         case 0x4:
210                 lasat_board_info.li_cpu_hz =
211                         lasat_board_info.li_bus_hz +
212                         lasat_board_info.li_bus_hz +
213                         lasat_board_info.li_bus_hz;
214                 break;
215         }
216
217         /* Flash size */
218         switch (LASAT_W1_FLASHSIZE(cfg1)) {
219         case 0:
220                 lasat_board_info.li_flash_size = 0x200000;
221                 break;
222         case 1:
223                 lasat_board_info.li_flash_size = 0x400000;
224                 break;
225         case 2:
226                 lasat_board_info.li_flash_size = 0x800000;
227                 break;
228         case 3:
229                 lasat_board_info.li_flash_size = 0x1000000;
230                 break;
231         case 4:
232                 lasat_board_info.li_flash_size = 0x2000000;
233                 break;
234         }
235
236         init_flash_sizes();
237
238         lasat_board_info.li_bmid = LASAT_W0_BMID(cfg0);
239         lasat_board_info.li_prid = lasat_board_info.li_eeprom_info.prid;
240         if (lasat_board_info.li_prid == 0xffff || lasat_board_info.li_prid == 0)
241                 lasat_board_info.li_prid = lasat_board_info.li_bmid;
242
243         /* Base model stuff */
244         if (lasat_board_info.li_bmid > i_n_base_models)
245                 lasat_board_info.li_bmid = i_n_base_models;
246         strcpy(lasat_board_info.li_bmstr, i_txt_base_models[lasat_board_info.li_bmid]);
247
248         /* Product ID dependent values */
249         c = lasat_board_info.li_prid;
250         if (c >= i_n_prids) {
251                 strcpy(lasat_board_info.li_namestr, "Unknown Model");
252                 strcpy(lasat_board_info.li_typestr, "Unknown Type");
253         } else {
254                 ppi = &vendor_info_table[0].vi_product_info[c];
255                 strcpy(lasat_board_info.li_namestr, ppi->pi_name);
256                 if (ppi->pi_type)
257                         strcpy(lasat_board_info.li_typestr, ppi->pi_type);
258                 else
259                         sprintf(lasat_board_info.li_typestr, "%d",10*c);
260         }
261
262 #if defined(CONFIG_INET) && defined(CONFIG_SYSCTL)
263         update_bcastaddr();
264 #endif
265
266         return 0;
267 }
268
269 void lasat_write_eeprom_info(void)
270 {
271         unsigned long crc;
272
273         /* Generate the CRC */
274         crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info),
275                     sizeof(struct lasat_eeprom_struct) - 4);
276         lasat_board_info.li_eeprom_info.crc32 = crc;
277
278         /* Write the EEPROM info */
279         EEPROMWrite(0, (unsigned char *)&lasat_board_info.li_eeprom_info, 
280                     sizeof(struct lasat_eeprom_struct));
281 }
282