u-boot/board/ti/common/board_detect_netbird.c

302 lines
6.5 KiB
C

/*
* Library to support early TI EVM EEPROM handling
*
* Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
* Lokesh Vutla
* Steve Kipisz
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/omap_common.h>
#include <i2c.h>
#include <malloc.h>
#include "board_detect.h"
#include "bdparser.h"
#define SYSINFO_ADDRESS 0x0000 /* Board descriptor at beginning of EEPROM */
#define SYSCONFIG_ADDRESS 0x0600 /* Board descriptor at beginning of EEPROM */
#define MAX_PARTITION_ENTRIES 4
static struct ti_common_eeprom bd_mirror;
static BD_Context *bd_board_info = 0;
static BD_Context *bd_system_config = 0;
static u8 boot_partition = 0;
/**
* ti_i2c_eeprom_init - Initialize an i2c bus and probe for a device
* @i2c_bus: i2c bus number to initialize
* @dev_addr: Device address to probe for
*
* Return: 0 on success or corresponding error on failure.
*/
static int __maybe_unused ti_i2c_eeprom_init(int i2c_bus, int dev_addr)
{
int rc;
if (i2c_bus >= 0) {
rc = i2c_set_bus_num(i2c_bus);
if (rc)
return rc;
}
return i2c_probe(dev_addr);
}
/**
* ti_i2c_eeprom_read - Read data from an EEPROM
* @dev_addr: The device address of the EEPROM
* @offset: Offset to start reading in the EEPROM
* @ep: Pointer to a buffer to read into
* @epsize: Size of buffer
*
* Return: 0 on success or corresponding result of i2c_read
*/
static int __maybe_unused ti_i2c_eeprom_read(int dev_addr, int offset,
uchar *ep, int epsize)
{
return i2c_read(dev_addr, offset, 2, ep, epsize);
}
static int i2c_eeprom_read(int offset, void *data, size_t len)
{
return i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR,
offset,
CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
data,
len);
}
static int boardinfo_read(BD_Context **context, size_t start_addr)
{
char bd_header_buffer[8];
void *bd_data = NULL;
// TODO read from real eeprom
if(*context)
return 0;
*context = calloc(sizeof(BD_Context), 1);
if(!*context)
{
printf("Couldn't allocate memory for board information\n");
goto failed;
}
if (i2c_eeprom_read(start_addr, bd_header_buffer, sizeof(bd_header_buffer))) {
printf("%s() Can't read BD header from EEPROM\n", __FUNCTION__);
goto failed;
}
if (!BD_CheckHeader(*context, bd_header_buffer))
{
printf("Invalid board information header\n");
goto failed;
}
bd_data = malloc((*context)->size);
if (bd_data == NULL)
{
printf("Can not allocate memory for board info");
goto failed;
}
if (i2c_eeprom_read(start_addr + sizeof(bd_header_buffer), bd_data, (*context)->size))
{
printf("Can not read board information data");
goto failed;
}
if (!BD_ImportData(*context, bd_data))
{
printf("Invalid board information!\n");
goto failed;
}
return 0;
failed:
if (bd_data != NULL)
{
free(bd_data);
bd_data = NULL;
}
if (*context != NULL)
{
free(*context);
*context = NULL;
}
return -1;
}
void read_sysinfo(void)
{
u8 bdHwVer = 0;
u8 bdHwRev = 0;
int err;
int i;
int j;
err = boardinfo_read(&bd_board_info, SYSINFO_ADDRESS);
if (err ) {
printf("Could not read sysinf boarddescriptor\n");
goto do_fake_bd;
}
/* Hardware version/revision */
if ( !BD_GetUInt8( bd_board_info, BD_Hw_Ver, 0, &bdHwVer) ) {
printf("%s() no Hw Version found\n", __FUNCTION__);
}
/* Hardware version/revision */
if ( !BD_GetUInt8( bd_board_info, BD_Hw_Rel, 0, &bdHwRev) ) {
printf("%s() no Hw Release found\n", __FUNCTION__);
}
snprintf(bd_mirror.version, sizeof(bd_mirror.version), "%d,%d", bdHwVer, bdHwRev);
/* MAC address */
memset(bd_mirror.mac_addr, 0x00, TI_EEPROM_HDR_NO_OF_MAC_ADDR * TI_EEPROM_HDR_ETH_ALEN);
for (i=0; i<TI_EEPROM_HDR_NO_OF_MAC_ADDR; i++) {
u8 mac[6];
BD_GetMAC( bd_board_info, BD_Eth_Mac, i, mac);
/* Convert nm MAC to TI MAC */
for (j=0; j<6; j++){
bd_mirror.mac_addr[i][j] = mac[j];
}
}
return;
do_fake_bd:
printf("%s() do fake boarddescriptor\n", __FUNCTION__);
/* Fill in dummy mac addresses to get u-boot working without valid BD */
memset(bd_mirror.mac_addr, 0x00, TI_EEPROM_HDR_NO_OF_MAC_ADDR * TI_EEPROM_HDR_ETH_ALEN);
bd_mirror.mac_addr[0][5] = 1;
bd_mirror.mac_addr[1][5] = 2;
}
void try_partition_read(void)
{
BD_PartitionEntry64 partition;
int i;
int rc;
int partition_count = 0;
for (i = 0; i < MAX_PARTITION_ENTRIES; i++)
{
rc = BD_GetPartition64( bd_system_config, BD_Partition64, i, &partition );
if (rc) {
partition_count++;
if (((partition.flags & BD_Partition_Flags_Active) != 0) &&
(i > 0)) {
boot_partition = i - 1; /* The first one is a dummy partition for u-boot */
}
}
}
if (partition_count < 1)
{
printf("ERROR: Too few partitions defined\n");
}
printf("Found %d partitions\n", partition_count);
}
void read_sysconfig(void)
{
int err;
u8 boot_part;
err = boardinfo_read(&bd_system_config, SYSCONFIG_ADDRESS);
if (err ) {
printf("Could not read sysconfig boarddescriptor\n");
}
/* If we have a new Bootpartition entry take this as boot part */
if ( BD_GetUInt8( bd_system_config, BD_BootPart, 0, &boot_part) ) {
if (boot_part >= 0 && boot_part <= 1) {
boot_partition = boot_part;
return;
}
}
/* If we not have a Bootpartition entry, perhaps we have a partition table */
try_partition_read();
}
int __maybe_unused ti_i2c_eeprom_am_get(int bus_addr, int dev_addr)
{
if (bd_mirror.header == TI_EEPROM_HEADER_MAGIC)
return 0;
read_sysinfo();
read_sysconfig();
bd_mirror.header = TI_EEPROM_HEADER_MAGIC;
return 0;
}
bool __maybe_unused board_ti_is(char *name_tag)
{
if (bd_mirror.header == TI_DEAD_EEPROM_MAGIC)
return false;
return !strncmp(bd_mirror.name, name_tag, TI_EEPROM_HDR_NAME_LEN);
}
char * __maybe_unused board_ti_get_rev(void)
{
if (bd_mirror.header == TI_DEAD_EEPROM_MAGIC)
return NULL;
return bd_mirror.version;
}
char * __maybe_unused board_ti_get_config(void)
{
if (bd_mirror.header == TI_DEAD_EEPROM_MAGIC)
return NULL;
return bd_mirror.config;
}
char * __maybe_unused board_ti_get_name(void)
{
if (bd_mirror.header == TI_DEAD_EEPROM_MAGIC)
return NULL;
return bd_mirror.name;
}
void __maybe_unused set_board_info_env(char *name)
{
return;
}
void __maybe_unused
board_ti_get_eth_mac_addr(int index,
u8 mac_addr[TI_EEPROM_HDR_ETH_ALEN])
{
if (bd_mirror.header == TI_DEAD_EEPROM_MAGIC)
goto fail;
if (index < 0 || index >= TI_EEPROM_HDR_NO_OF_MAC_ADDR)
goto fail;
memcpy(mac_addr, bd_mirror.mac_addr[index], TI_EEPROM_HDR_ETH_ALEN);
return;
fail:
memset(mac_addr, 0, TI_EEPROM_HDR_ETH_ALEN);
}
u8 get_boot_partition(void)
{
return boot_partition;
}