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