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 <linux/mutex.h> 27#include <asm/addrspace.h> 28#include "at93c.h" 29/* New model description table */ 30#include "lasat_models.h" 31 32static DEFINE_MUTEX(lasat_eeprom_mutex); 33 34#define EEPROM_CRC(data, len) (~crc32(~0, data, len)) 35 36struct lasat_info lasat_board_info; 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} 47 48int EEPROMWrite(unsigned int pos, unsigned char *data, int len) 49{ 50 int i; 51 52 for (i = 0; i < len; i++) 53 at93c_write(pos++, *data++); 54 55 return 0; 56} 57 58static void init_flash_sizes(void) 59{ 60 unsigned long *lb = lasat_board_info.li_flashpart_base; 61 unsigned long *ls = lasat_board_info.li_flashpart_size; 62 int i; 63 64 ls[LASAT_MTD_BOOTLOADER] = 0x40000; 65 ls[LASAT_MTD_SERVICE] = 0xC0000; 66 ls[LASAT_MTD_NORMAL] = 0x100000; 67 68 if (!IS_LASAT_200()) { 69 lasat_board_info.li_flash_base = 0x1e000000; 70 71 lb[LASAT_MTD_BOOTLOADER] = 0x1e400000; 72 73 if (lasat_board_info.li_flash_size > 0x200000) { 74 ls[LASAT_MTD_CONFIG] = 0x100000; 75 ls[LASAT_MTD_FS] = 0x500000; 76 } 77 } else { 78 lasat_board_info.li_flash_base = 0x10000000; 79 80 if (lasat_board_info.li_flash_size < 0x1000000) { 81 lb[LASAT_MTD_BOOTLOADER] = 0x10000000; 82 ls[LASAT_MTD_CONFIG] = 0x100000; 83 if (lasat_board_info.li_flash_size >= 0x400000) 84 ls[LASAT_MTD_FS] = 85 lasat_board_info.li_flash_size - 0x300000; 86 } 87 } 88 89 for (i = 1; i < LASAT_MTD_LAST; i++) 90 lb[i] = lb[i-1] + ls[i-1]; 91} 92 93int lasat_init_board_info(void) 94{ 95 int c; 96 unsigned long crc; 97 unsigned long cfg0, cfg1; 98 const struct product_info *ppi; 99 int i_n_base_models = N_BASE_MODELS; 100 const char * const * i_txt_base_models = txt_base_models; 101 int i_n_prids = N_PRIDS; 102 103 memset(&lasat_board_info, 0, sizeof(lasat_board_info)); 104 105 /* First read the EEPROM info */ 106 EEPROMRead(0, (unsigned char *)&lasat_board_info.li_eeprom_info, 107 sizeof(struct lasat_eeprom_struct)); 108 109 /* Check the CRC */ 110 crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info), 111 sizeof(struct lasat_eeprom_struct) - 4); 112 113 if (crc != lasat_board_info.li_eeprom_info.crc32) { 114 printk(KERN_WARNING "WARNING...\nWARNING...\nEEPROM CRC does " 115 "not match calculated, attempting to soldier on...\n"); 116 } 117 118 if (lasat_board_info.li_eeprom_info.version != LASAT_EEPROM_VERSION) { 119 printk(KERN_WARNING "WARNING...\nWARNING...\nEEPROM version " 120 "%d, wanted version %d, attempting to soldier on...\n", 121 (unsigned int)lasat_board_info.li_eeprom_info.version, 122 LASAT_EEPROM_VERSION); 123 } 124 125 cfg0 = lasat_board_info.li_eeprom_info.cfg[0]; 126 cfg1 = lasat_board_info.li_eeprom_info.cfg[1]; 127 128 if (LASAT_W0_DSCTYPE(cfg0) != 1) { 129 printk(KERN_WARNING "WARNING...\nWARNING...\n" 130 "Invalid configuration read from EEPROM, attempting to " 131 "soldier on..."); 132 } 133 /* We have a valid configuration */ 134 135 switch (LASAT_W0_SDRAMBANKSZ(cfg0)) { 136 case 0: 137 lasat_board_info.li_memsize = 0x0800000; 138 break; 139 case 1: 140 lasat_board_info.li_memsize = 0x1000000; 141 break; 142 case 2: 143 lasat_board_info.li_memsize = 0x2000000; 144 break; 145 case 3: 146 lasat_board_info.li_memsize = 0x4000000; 147 break; 148 case 4: 149 lasat_board_info.li_memsize = 0x8000000; 150 break; 151 default: 152 lasat_board_info.li_memsize = 0; 153 } 154 155 switch (LASAT_W0_SDRAMBANKS(cfg0)) { 156 case 0: 157 break; 158 case 1: 159 lasat_board_info.li_memsize *= 2; 160 break; 161 default: 162 break; 163 } 164 165 switch (LASAT_W0_BUSSPEED(cfg0)) { 166 case 0x0: 167 lasat_board_info.li_bus_hz = 60000000; 168 break; 169 case 0x1: 170 lasat_board_info.li_bus_hz = 66000000; 171 break; 172 case 0x2: 173 lasat_board_info.li_bus_hz = 66666667; 174 break; 175 case 0x3: 176 lasat_board_info.li_bus_hz = 80000000; 177 break; 178 case 0x4: 179 lasat_board_info.li_bus_hz = 83333333; 180 break; 181 case 0x5: 182 lasat_board_info.li_bus_hz = 100000000; 183 break; 184 } 185 186 switch (LASAT_W0_CPUCLK(cfg0)) { 187 case 0x0: 188 lasat_board_info.li_cpu_hz = 189 lasat_board_info.li_bus_hz; 190 break; 191 case 0x1: 192 lasat_board_info.li_cpu_hz = 193 lasat_board_info.li_bus_hz + 194 (lasat_board_info.li_bus_hz >> 1); 195 break; 196 case 0x2: 197 lasat_board_info.li_cpu_hz = 198 lasat_board_info.li_bus_hz + 199 lasat_board_info.li_bus_hz; 200 break; 201 case 0x3: 202 lasat_board_info.li_cpu_hz = 203 lasat_board_info.li_bus_hz + 204 lasat_board_info.li_bus_hz + 205 (lasat_board_info.li_bus_hz >> 1); 206 break; 207 case 0x4: 208 lasat_board_info.li_cpu_hz = 209 lasat_board_info.li_bus_hz + 210 lasat_board_info.li_bus_hz + 211 lasat_board_info.li_bus_hz; 212 break; 213 } 214 215 /* Flash size */ 216 switch (LASAT_W1_FLASHSIZE(cfg1)) { 217 case 0: 218 lasat_board_info.li_flash_size = 0x200000; 219 break; 220 case 1: 221 lasat_board_info.li_flash_size = 0x400000; 222 break; 223 case 2: 224 lasat_board_info.li_flash_size = 0x800000; 225 break; 226 case 3: 227 lasat_board_info.li_flash_size = 0x1000000; 228 break; 229 case 4: 230 lasat_board_info.li_flash_size = 0x2000000; 231 break; 232 } 233 234 init_flash_sizes(); 235 236 lasat_board_info.li_bmid = LASAT_W0_BMID(cfg0); 237 lasat_board_info.li_prid = lasat_board_info.li_eeprom_info.prid; 238 if (lasat_board_info.li_prid == 0xffff || lasat_board_info.li_prid == 0) 239 lasat_board_info.li_prid = lasat_board_info.li_bmid; 240 241 /* Base model stuff */ 242 if (lasat_board_info.li_bmid > i_n_base_models) 243 lasat_board_info.li_bmid = i_n_base_models; 244 strcpy(lasat_board_info.li_bmstr, 245 i_txt_base_models[lasat_board_info.li_bmid]); 246 247 /* Product ID dependent values */ 248 c = lasat_board_info.li_prid; 249 if (c >= i_n_prids) { 250 strcpy(lasat_board_info.li_namestr, "Unknown Model"); 251 strcpy(lasat_board_info.li_typestr, "Unknown Type"); 252 } else { 253 ppi = &vendor_info_table[0].vi_product_info[c]; 254 strcpy(lasat_board_info.li_namestr, ppi->pi_name); 255 if (ppi->pi_type) 256 strcpy(lasat_board_info.li_typestr, ppi->pi_type); 257 else 258 sprintf(lasat_board_info.li_typestr, "%d", 10 * c); 259 } 260 261 return 0; 262} 263 264void lasat_write_eeprom_info(void) 265{ 266 unsigned long crc; 267 268 mutex_lock(&lasat_eeprom_mutex); 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 mutex_unlock(&lasat_eeprom_mutex); 280} 281