linux/arch/mips/lasat/lasat_board.c
<<
>>
Prefs
   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