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