mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-25 10:19:47 +00:00
![Thomas Gleixner](/assets/img/avatar_default.png)
Based on 1 normalized pattern(s): this program is free software you can distribute it and or modify it under the terms of the gnu general public license version 2 as published by the free software foundation this program is distributed in the hope it will be useful but without any warranty without even the implied warranty of merchantability or fitness for a particular purpose see the gnu general public license for more details you should have received a copy of the gnu general public license along with this program if not write to the free software foundation inc 59 temple place suite 330 boston ma 02111 1307 usa extracted by the scancode license scanner the SPDX license identifier GPL-2.0-only has been chosen to replace the boilerplate/reference in 32 file(s). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Allison Randal <allison@lohutok.net> Reviewed-by: Richard Fontana <rfontana@redhat.com> Reviewed-by: Steve Winslow <swinslow@gmail.com> Reviewed-by: Alexios Zavras <alexios.zavras@intel.com> Cc: linux-spdx@vger.kernel.org Link: https://lkml.kernel.org/r/20190528170026.531157061@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
268 lines
6.4 KiB
C
268 lines
6.4 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Thomas Horsten <thh@lasat.com>
|
|
* Copyright (C) 2000 LASAT Networks A/S.
|
|
*
|
|
* Routines specific to the LASAT boards
|
|
*/
|
|
#include <linux/types.h>
|
|
#include <linux/crc32.h>
|
|
#include <asm/lasat/lasat.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/string.h>
|
|
#include <linux/ctype.h>
|
|
#include <linux/mutex.h>
|
|
#include <asm/addrspace.h>
|
|
#include "at93c.h"
|
|
/* New model description table */
|
|
#include "lasat_models.h"
|
|
|
|
static DEFINE_MUTEX(lasat_eeprom_mutex);
|
|
|
|
#define EEPROM_CRC(data, len) (~crc32(~0, data, len))
|
|
|
|
struct lasat_info lasat_board_info;
|
|
|
|
int EEPROMRead(unsigned int pos, unsigned char *data, int len)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < len; i++)
|
|
*data++ = at93c_read(pos++);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int EEPROMWrite(unsigned int pos, unsigned char *data, int len)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < len; i++)
|
|
at93c_write(pos++, *data++);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void init_flash_sizes(void)
|
|
{
|
|
unsigned long *lb = lasat_board_info.li_flashpart_base;
|
|
unsigned long *ls = lasat_board_info.li_flashpart_size;
|
|
int i;
|
|
|
|
ls[LASAT_MTD_BOOTLOADER] = 0x40000;
|
|
ls[LASAT_MTD_SERVICE] = 0xC0000;
|
|
ls[LASAT_MTD_NORMAL] = 0x100000;
|
|
|
|
if (!IS_LASAT_200()) {
|
|
lasat_board_info.li_flash_base = 0x1e000000;
|
|
|
|
lb[LASAT_MTD_BOOTLOADER] = 0x1e400000;
|
|
|
|
if (lasat_board_info.li_flash_size > 0x200000) {
|
|
ls[LASAT_MTD_CONFIG] = 0x100000;
|
|
ls[LASAT_MTD_FS] = 0x500000;
|
|
}
|
|
} else {
|
|
lasat_board_info.li_flash_base = 0x10000000;
|
|
|
|
if (lasat_board_info.li_flash_size < 0x1000000) {
|
|
lb[LASAT_MTD_BOOTLOADER] = 0x10000000;
|
|
ls[LASAT_MTD_CONFIG] = 0x100000;
|
|
if (lasat_board_info.li_flash_size >= 0x400000)
|
|
ls[LASAT_MTD_FS] =
|
|
lasat_board_info.li_flash_size - 0x300000;
|
|
}
|
|
}
|
|
|
|
for (i = 1; i < LASAT_MTD_LAST; i++)
|
|
lb[i] = lb[i-1] + ls[i-1];
|
|
}
|
|
|
|
int lasat_init_board_info(void)
|
|
{
|
|
int c;
|
|
unsigned long crc;
|
|
unsigned long cfg0, cfg1;
|
|
const struct product_info *ppi;
|
|
int i_n_base_models = N_BASE_MODELS;
|
|
const char * const * i_txt_base_models = txt_base_models;
|
|
int i_n_prids = N_PRIDS;
|
|
|
|
memset(&lasat_board_info, 0, sizeof(lasat_board_info));
|
|
|
|
/* First read the EEPROM info */
|
|
EEPROMRead(0, (unsigned char *)&lasat_board_info.li_eeprom_info,
|
|
sizeof(struct lasat_eeprom_struct));
|
|
|
|
/* Check the CRC */
|
|
crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info),
|
|
sizeof(struct lasat_eeprom_struct) - 4);
|
|
|
|
if (crc != lasat_board_info.li_eeprom_info.crc32) {
|
|
printk(KERN_WARNING "WARNING...\nWARNING...\nEEPROM CRC does "
|
|
"not match calculated, attempting to soldier on...\n");
|
|
}
|
|
|
|
if (lasat_board_info.li_eeprom_info.version != LASAT_EEPROM_VERSION) {
|
|
printk(KERN_WARNING "WARNING...\nWARNING...\nEEPROM version "
|
|
"%d, wanted version %d, attempting to soldier on...\n",
|
|
(unsigned int)lasat_board_info.li_eeprom_info.version,
|
|
LASAT_EEPROM_VERSION);
|
|
}
|
|
|
|
cfg0 = lasat_board_info.li_eeprom_info.cfg[0];
|
|
cfg1 = lasat_board_info.li_eeprom_info.cfg[1];
|
|
|
|
if (LASAT_W0_DSCTYPE(cfg0) != 1) {
|
|
printk(KERN_WARNING "WARNING...\nWARNING...\n"
|
|
"Invalid configuration read from EEPROM, attempting to "
|
|
"soldier on...");
|
|
}
|
|
/* We have a valid configuration */
|
|
|
|
switch (LASAT_W0_SDRAMBANKSZ(cfg0)) {
|
|
case 0:
|
|
lasat_board_info.li_memsize = 0x0800000;
|
|
break;
|
|
case 1:
|
|
lasat_board_info.li_memsize = 0x1000000;
|
|
break;
|
|
case 2:
|
|
lasat_board_info.li_memsize = 0x2000000;
|
|
break;
|
|
case 3:
|
|
lasat_board_info.li_memsize = 0x4000000;
|
|
break;
|
|
case 4:
|
|
lasat_board_info.li_memsize = 0x8000000;
|
|
break;
|
|
default:
|
|
lasat_board_info.li_memsize = 0;
|
|
}
|
|
|
|
switch (LASAT_W0_SDRAMBANKS(cfg0)) {
|
|
case 0:
|
|
break;
|
|
case 1:
|
|
lasat_board_info.li_memsize *= 2;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
switch (LASAT_W0_BUSSPEED(cfg0)) {
|
|
case 0x0:
|
|
lasat_board_info.li_bus_hz = 60000000;
|
|
break;
|
|
case 0x1:
|
|
lasat_board_info.li_bus_hz = 66000000;
|
|
break;
|
|
case 0x2:
|
|
lasat_board_info.li_bus_hz = 66666667;
|
|
break;
|
|
case 0x3:
|
|
lasat_board_info.li_bus_hz = 80000000;
|
|
break;
|
|
case 0x4:
|
|
lasat_board_info.li_bus_hz = 83333333;
|
|
break;
|
|
case 0x5:
|
|
lasat_board_info.li_bus_hz = 100000000;
|
|
break;
|
|
}
|
|
|
|
switch (LASAT_W0_CPUCLK(cfg0)) {
|
|
case 0x0:
|
|
lasat_board_info.li_cpu_hz =
|
|
lasat_board_info.li_bus_hz;
|
|
break;
|
|
case 0x1:
|
|
lasat_board_info.li_cpu_hz =
|
|
lasat_board_info.li_bus_hz +
|
|
(lasat_board_info.li_bus_hz >> 1);
|
|
break;
|
|
case 0x2:
|
|
lasat_board_info.li_cpu_hz =
|
|
lasat_board_info.li_bus_hz +
|
|
lasat_board_info.li_bus_hz;
|
|
break;
|
|
case 0x3:
|
|
lasat_board_info.li_cpu_hz =
|
|
lasat_board_info.li_bus_hz +
|
|
lasat_board_info.li_bus_hz +
|
|
(lasat_board_info.li_bus_hz >> 1);
|
|
break;
|
|
case 0x4:
|
|
lasat_board_info.li_cpu_hz =
|
|
lasat_board_info.li_bus_hz +
|
|
lasat_board_info.li_bus_hz +
|
|
lasat_board_info.li_bus_hz;
|
|
break;
|
|
}
|
|
|
|
/* Flash size */
|
|
switch (LASAT_W1_FLASHSIZE(cfg1)) {
|
|
case 0:
|
|
lasat_board_info.li_flash_size = 0x200000;
|
|
break;
|
|
case 1:
|
|
lasat_board_info.li_flash_size = 0x400000;
|
|
break;
|
|
case 2:
|
|
lasat_board_info.li_flash_size = 0x800000;
|
|
break;
|
|
case 3:
|
|
lasat_board_info.li_flash_size = 0x1000000;
|
|
break;
|
|
case 4:
|
|
lasat_board_info.li_flash_size = 0x2000000;
|
|
break;
|
|
}
|
|
|
|
init_flash_sizes();
|
|
|
|
lasat_board_info.li_bmid = LASAT_W0_BMID(cfg0);
|
|
lasat_board_info.li_prid = lasat_board_info.li_eeprom_info.prid;
|
|
if (lasat_board_info.li_prid == 0xffff || lasat_board_info.li_prid == 0)
|
|
lasat_board_info.li_prid = lasat_board_info.li_bmid;
|
|
|
|
/* Base model stuff */
|
|
if (lasat_board_info.li_bmid > i_n_base_models)
|
|
lasat_board_info.li_bmid = i_n_base_models;
|
|
strcpy(lasat_board_info.li_bmstr,
|
|
i_txt_base_models[lasat_board_info.li_bmid]);
|
|
|
|
/* Product ID dependent values */
|
|
c = lasat_board_info.li_prid;
|
|
if (c >= i_n_prids) {
|
|
strcpy(lasat_board_info.li_namestr, "Unknown Model");
|
|
strcpy(lasat_board_info.li_typestr, "Unknown Type");
|
|
} else {
|
|
ppi = &vendor_info_table[0].vi_product_info[c];
|
|
strcpy(lasat_board_info.li_namestr, ppi->pi_name);
|
|
if (ppi->pi_type)
|
|
strcpy(lasat_board_info.li_typestr, ppi->pi_type);
|
|
else
|
|
sprintf(lasat_board_info.li_typestr, "%d", 10 * c);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void lasat_write_eeprom_info(void)
|
|
{
|
|
unsigned long crc;
|
|
|
|
mutex_lock(&lasat_eeprom_mutex);
|
|
|
|
/* Generate the CRC */
|
|
crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info),
|
|
sizeof(struct lasat_eeprom_struct) - 4);
|
|
lasat_board_info.li_eeprom_info.crc32 = crc;
|
|
|
|
/* Write the EEPROM info */
|
|
EEPROMWrite(0, (unsigned char *)&lasat_board_info.li_eeprom_info,
|
|
sizeof(struct lasat_eeprom_struct));
|
|
|
|
mutex_unlock(&lasat_eeprom_mutex);
|
|
}
|