nbhw16: Add support for new board descriptor format

This commit is contained in:
Stefan Eichenberger 2017-02-27 18:26:31 +01:00
parent caf606af00
commit 3cf092bd86
7 changed files with 351 additions and 260 deletions

View File

@ -112,6 +112,7 @@ static const BD_Info bd_info[] = {
{ BD_Hmac_Sha1_4 , BD_Type_HMAC , "hmac-sha1" },
{ BD_Ui_Adapter_Type , BD_Type_UInt16 , "ui_adapter_type" },
{ PD_Dev_Tree , BD_Type_String , "pd_dev_tree" },
/* Guard entry, must be last in array (don't remove) */
{ BD_End , BD_Type_End , 0 },

View File

@ -160,6 +160,15 @@ typedef enum _BD_Tags
BD_Ui_Adapter_Type = 4096, /**< "UInt16" -> IV OG2 UI adapterboard type (0 = not present) */
BD_Pd_Module0 = 4100,
BD_Pd_Module1 = 4101,
BD_Pd_Module2 = 4102,
BD_Pd_Module3 = 4103,
BD_Pd_Module4 = 4104,
BD_Pd_Module5 = 4105,
BD_Pd_Sim = 4122,
PD_Dev_Tree = 4125, /**< "String" -> Devicetree file name */
/* project specific tags */
BD_BootPart = 32768, /**< "UInt8" */

View File

@ -0,0 +1,272 @@
/******************************************************************************
* (c) COPYRIGHT 2010 by NetModule AG, Switzerland. All rights reserved.
*
* The program(s) may only be used and/or copied with the written permission
* from NetModule AG or in accordance with the terms and conditions stipulated
* in the agreement contract under which the program(s) have been supplied.
*
* PACKAGE : NetBox HW08
*
* ABSTRACT:
* Implements functions for settings
*
* HISTORY:
* Date Author Description
* 20100421 SMA created
* 20100903 rs reading carrier board descriptor from EEPROM at 54.
* code cleanup (tabs/indentation)
* 20110211 rs partition table handling
*
*****************************************************************************/
#include <common.h>
#include <i2c.h>
#include <malloc.h>
#include "bdparser.h" /* tlv parser */
#define MAX_PARTITION_ENTRIES 4
static const BD_Context *bdctx_list; /* The board descriptor context */
static size_t bdctx_count = 0;
void bd_register_context_list(const BD_Context *list, size_t count) {
bdctx_list = list;
bdctx_count = count;
}
int bd_get_context(BD_Context *bdctx, uint32_t i2caddress, uint32_t offset)
{
bd_bool_t rc;
uint8_t bdHeader[8];
void* pBdData = NULL;
/* Read header bytes from beginning of EEPROM */
if (i2c_read( i2caddress, offset, 2, bdHeader, BD_HEADER_LENGTH )) {
debug("%s() Can't read BD header from EEPROM\n", __func__);
goto exit1;
}
/* Check whether this is a valid board descriptor (or empty EEPROM) */
rc = BD_CheckHeader( bdctx, bdHeader );
if (!rc) {
debug("%s() No valid board descriptor found\n", __func__);
goto exit1;
}
/* Allocate memory for descriptor data and .. */
pBdData = malloc( bdctx->size );
if ( pBdData == NULL ) {
debug("%s() Can't allocate %d bytes\n", __func__, bdctx->size);
goto exit1;
}
/* .. read data from EEPROM */
if (i2c_read(i2caddress, offset+BD_HEADER_LENGTH, 2, pBdData, bdctx->size)) {
debug("%s() Can't read data from EEPROM\n", __func__);
goto exit1;
}
/*
* Import data into board descriptor context
*/
rc = BD_ImportData( bdctx, pBdData );
if (!rc) {
debug("%s() Invalid board descriptor data\n", __func__);
goto exit1;
}
return 0;
exit1:
if (pBdData != NULL)
{
free(pBdData);
pBdData = NULL;
}
return -1;
}
static bd_bool_t _get_string(bd_uint16_t tag, bd_uint_t index, char* pResult, bd_size_t bufLen ) {
int i;
for (i = 0; i < bdctx_count; i++) {
if (BD_GetString(&bdctx_list[i], tag, index, pResult, bufLen)) {
return BD_TRUE;
}
}
return BD_FALSE;
}
static bd_bool_t _get_mac( bd_uint16_t tag, bd_uint_t index, bd_uint8_t pResult[6] ) {
int i;
for (i = 0; i < bdctx_count; i++) {
if (BD_GetMAC(&bdctx_list[i], tag, index, pResult)) {
return BD_TRUE;
}
}
return BD_FALSE;
}
static bd_bool_t _get_uint8( bd_uint16_t tag, bd_uint_t index, bd_uint8_t* pResult ) {
int i;
for (i = 0; i < bdctx_count; i++) {
if (BD_GetUInt8(&bdctx_list[i], tag, index, pResult)) {
return BD_TRUE;
}
}
return BD_FALSE;
}
static bd_bool_t _get_uint32( bd_uint16_t tag, bd_uint_t index, bd_uint32_t* pResult ) {
int i;
for (i = 0; i < bdctx_count; i++) {
if (BD_GetUInt32(&bdctx_list[i], tag, index, pResult)) {
return BD_TRUE;
}
}
return BD_FALSE;
}
static bd_bool_t _get_partition64( bd_uint16_t tag, bd_uint_t index, BD_PartitionEntry64 *pResult) {
int i;
for (i = 0; i < bdctx_count; i++) {
if (BD_GetPartition64(&bdctx_list[i], tag, index, pResult)) {
return BD_TRUE;
}
}
return BD_FALSE;
}
int bd_get_prodname(char *prodname, size_t len)
{
if ( !_get_string( BD_Prod_Name, 0, prodname, len) ) {
debug("%s() Product name not found\n", __func__);
return -1;
}
return 0;
}
void bd_get_hw_version(int* ver, int* rev)
{
static uint8_t hwver;
static uint8_t hwrev;
if ( !_get_uint8( BD_Hw_Ver, 0, &hwver) )
debug("%s() no Hw Version found\n", __func__);
if ( !_get_uint8( BD_Hw_Rel, 0, &hwrev) )
debug("%s() no Hw Release found\n", __func__);
*ver = hwver;
*rev = hwrev;
}
int bd_get_mac(int index, uint8_t *macaddr, size_t len)
{
if (len != 6) {
debug("macaddr size must be 6 (is %d)", len);
return -1;
}
/* MAC address */
if ( !_get_mac( BD_Eth_Mac, index, macaddr) ) {
debug("%s() MAC addresss %d not found\n", __func__, index);
return -1;
}
return 0;
}
u32 bd_get_fpgainfo(void)
{
uint32_t fpgainfo = 0xFFFFFFFF;
if ( !_get_uint32( BD_Fpga_Info, 0, &fpgainfo) )
debug("%s() no Fpga Info found\n", __func__);
return fpgainfo;
}
int bd_get_pd_module(int slot, char *config, size_t len)
{
if ( !_get_string(BD_Pd_Module0 + slot, 0, config, len) ) {
debug("%s() could not read module configuration on slot %d\n",
__func__, slot);
return -1;
}
return 0;
}
int bd_get_sim_config(char* simconfig, size_t len)
{
if (!_get_string(BD_Pd_Sim, 0, simconfig, len)) {
debug("%s() No valid SIM Config found\n", __func__);
return -1;
}
return 0;
}
int bd_get_devicetree(char* devicetreename, size_t len)
{
if (!_get_string(PD_Dev_Tree, 0, devicetreename, len)) {
debug("%s() No valid Devicetree name found\n", __func__);
return -1;
}
return 0;
}
static u8 try_partition_read(void)
{
BD_PartitionEntry64 partition;
int i;
int rc;
int partition_count = 0;
int boot_partition = 0;
for (i = 0; i < MAX_PARTITION_ENTRIES; i++)
{
rc = _get_partition64(BD_Partition64, i, &partition);
if (rc) {
partition_count++;
if (((partition.flags & BD_Partition_Flags_Active) != 0) &&
(i > 0)) {
boot_partition = i;
}
}
}
if (partition_count < 1)
{
printf("ERROR: Too few partitions defined, taking default 0\n");
}
return boot_partition;
}
int bd_get_boot_partition(void)
{
u8 boot_part;
/* If we have a new Bootpartition entry take this as boot part */
if ( _get_uint8( BD_BootPart, 0, &boot_part) ) {
if (boot_part >= 0 && boot_part <= 1) {
return boot_part;
}
}
/* If we not have a Bootpartition entry, perhaps we have a partition table */
return try_partition_read();
}

View File

@ -11,7 +11,11 @@
int bd_read(int bus_addr, int dev_addr);
u8 bd_get_boot_partition(void);
int bd_get_mac_address(uint index, u8 *mac_address, u32 len);
int bd_get_mac(uint index, u8 *mac_address, u32 len);
int bd_get_hw_version(int* pVer, int* pRev);
int bd_get_devicetree(char* devicetreename, size_t len);
int bd_get_context(BD_Context *bdctx, uint32_t i2caddress, uint32_t offset);
void bd_register_context_list(const BD_Context *list, size_t count);
u8 bd_get_boot_partition(void);
#endif /* __BOARD_DESCRIPTOR_H */

View File

@ -10,4 +10,4 @@ ifeq ($(CONFIG_SKIP_LOWLEVEL_INIT),)
obj-y := mux.o
endif
obj-y += board.o bdparser.o board_descriptor.o
obj-y += board.o ../common/bdparser.o ../common/board_descriptor.o

View File

@ -34,7 +34,8 @@
#include <environment.h>
#include <watchdog.h>
#include <environment.h>
#include "board_descriptor.h"
#include "../common/bdparser.h"
#include "../common/board_descriptor.h"
#include "board.h"
DECLARE_GLOBAL_DATA_PTR;
@ -67,12 +68,38 @@ DECLARE_GLOBAL_DATA_PTR;
static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
#endif
#define BD_EEPROM_ADDR (0x50) /* CPU BD EEPROM (8kByte) is at 50 (A0) */
#define BD_ADDRESS (0x0000) /* Board descriptor at beginning of EEPROM */
#define PD_ADDRESS (0x0200) /* Product descriptor */
#define PARTITION_ADDRESS (0x0600) /* Partition Table */
static BD_Context bdctx[3]; /* The descriptor context */
static int _bd_init(void)
{
if (bd_get_context(&bdctx[0], BD_EEPROM_ADDR, BD_ADDRESS) != 0) {
printf("%s() no valid bd found\n", __func__);
return -1;
}
if (bd_get_context(&bdctx[1], BD_EEPROM_ADDR, PD_ADDRESS) != 0) {
printf("%s() no valid pd found (legacy support)\n", __func__);
}
if (bd_get_context(&bdctx[2], BD_EEPROM_ADDR, PARTITION_ADDRESS) != 0) {
printf("%s() no valid partition table found\n", __func__);
}
bd_register_context_list(bdctx, ARRAY_SIZE(bdctx));
return 0;
}
/*
* Read header information from EEPROM into global structure.
*/
static inline int __maybe_unused read_eeprom(void)
{
return bd_read(-1, CONFIG_SYS_I2C_EEPROM_ADDR);
return _bd_init();
}
struct serial_device *default_serial_console(void)
@ -438,11 +465,40 @@ static void enable_wlan_clock(void)
enable_pwm();
}
#if !defined(CONFIG_SPL_BUILD)
static void set_devicetree_name(void)
{
char devicetreename[64];
/* add hardware versions to environment */
if (bd_get_devicetree(devicetreename, sizeof(devicetreename)) != 0) {
printf("Devicetree name not found, use legacy name\n");
strcpy(devicetreename, "am335x-nbhw16-prod2.dtb");
}
setenv("fdt_image", devicetreename);
}
static void get_hw_version(void)
{
int hw_ver, hw_rev;
char hw_versions[16];
char new_env[256];
/* add hardware versions to environment */
bd_get_hw_version(&hw_ver, &hw_rev);
printf("HW16: V%d.%d\n", hw_ver, hw_rev);
snprintf(hw_versions, sizeof(hw_versions), "CP=%d.%d", hw_ver, hw_rev);
snprintf(new_env, sizeof(new_env), "setenv bootargs $bootargs %s", hw_versions);
setenv("add_version_bootargs", new_env);
}
#endif
#ifdef CONFIG_BOARD_LATE_INIT
int board_late_init(void)
{
#if !defined(CONFIG_SPL_BUILD)
int hw_ver, hw_rev;
int boot_partition;
if (read_eeprom() < 0)
@ -457,18 +513,11 @@ int board_late_init(void)
/* mmcblk0p1 => root0, mmcblk0p2 => root1 so +1 */
setenv_ulong("root_part", boot_partition + 1);
/* add hardware versions to environment */
if (bd_get_hw_version(&hw_ver, &hw_rev)==0) {
char hw_versions[128];
char new_env[256];
printf("HW16: V%d.%d\n", hw_ver, hw_rev);
snprintf(hw_versions, sizeof(hw_versions), "CP=%d.%d", hw_ver, hw_rev);
snprintf(new_env, sizeof(new_env), "setenv bootargs $bootargs %s", hw_versions);
setenv("add_version_bootargs", new_env);
}
check_reset_button();
get_hw_version();
set_devicetree_name();
#endif
#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
@ -560,7 +609,6 @@ int board_eth_init(bd_t *bis)
{
int rv, n = 0;
uint8_t mac_addr0[6] = {02,00,00,00,00,01};
uint8_t mac_addr1[6] = {02,00,00,00,00,02};
__maybe_unused struct ti_am_eeprom *header;
#if !defined(CONFIG_SPL_BUILD)
@ -568,12 +616,9 @@ int board_eth_init(bd_t *bis)
cpsw_data.mdio_div = 0x3E;
bd_get_mac_address(0, mac_addr0, sizeof(mac_addr0));
bd_get_mac(0, mac_addr0, sizeof(mac_addr0));
set_mac_address(0, mac_addr0);
bd_get_mac_address(1, mac_addr1, sizeof(mac_addr1));
set_mac_address(1, mac_addr1);
writel(RMII_MODE_ENABLE | RMII_CHIPCKL_ENABLE, &cdev->miisel);
cpsw_slaves[0].phy_if = PHY_INTERFACE_MODE_RMII;
cpsw_slaves[1].phy_if = PHY_INTERFACE_MODE_RMII;

View File

@ -1,240 +0,0 @@
/*
* 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 <asm/io.h>
#include "board_descriptor.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 BD_Context *bd_board_info = 0;
static BD_Context *bd_system_config = 0;
static int 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);
}
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;
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;
}
static void read_sysinfo(void)
{
int err;
err = boardinfo_read(&bd_board_info, SYSINFO_ADDRESS);
if (err ) {
printf("Could not read sysinf boarddescriptor\n");
return;
}
return;
}
static void read_sysconfig(void)
{
int err;
err = boardinfo_read(&bd_system_config, SYSCONFIG_ADDRESS);
if (err ) {
printf("Could not read sysconfig boarddescriptor\n");
return;
}
}
int bd_read (int bus_addr, int dev_addr)
{
if (i2c_eeprom_init(bus_addr, dev_addr)) {
return -1;
}
read_sysinfo();
read_sysconfig();
return 0;
}
static u8 try_partition_read(void)
{
BD_PartitionEntry64 partition;
int i;
int rc;
int partition_count = 0;
int boot_partition = 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;
}
}
}
if (partition_count < 1)
{
printf("ERROR: Too few partitions defined, taking default 0\n");
}
return boot_partition;
}
u8 bd_get_boot_partition(void)
{
u8 boot_part;
if ((bd_system_config == 0)) {
puts("System config not valid, can not get boot partition\n");
return 0;
}
/* 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) {
return boot_part;
}
}
/* If we not have a Bootpartition entry, perhaps we have a partition table */
return try_partition_read();
}
int bd_get_mac_address(uint index, u8 *mac, u32 len)
{
if (bd_board_info == 0) {
puts("Board info not valid, can not get mac address\n");
return -1;
}
if (len != 6) {
return -1;
}
if (BD_GetMAC( bd_board_info, BD_Eth_Mac, index, mac))
return 0;
else
return -1;
}
int bd_get_hw_version(int* pVer, int* pRev)
{
u8 bdCpHwVer = 0;
u8 bdCpHwRev = 0;
if (bd_board_info == 0) {
puts("Board info not valid, can not get hw version\n");
return -1;
}
/* Hardware version/revision */
if ( !BD_GetUInt8( bd_board_info, BD_Hw_Ver, 0, &bdCpHwVer) ) {
printf("no Hw version found\n");
return -1;
}
/* Hardware version/revision */
if ( !BD_GetUInt8( bd_board_info, BD_Hw_Rel, 0, &bdCpHwRev) ) {
printf("no Hw release found\n");
return -1;
}
*pVer = bdCpHwVer;
*pRev = bdCpHwRev;
return 0;
}