blob: 09a6bf97aabecf3ea3b0cd7a05911798196980c8 [file] [log] [blame]
/*
* Copyright (c) 2010 Quantenna Communications, Inc.
* All rights reserved.
*
* file purpose
* Map board_id to coard configuration definitions
*/
////////////////////////////////////////////////////////////////////////////
// Includes
////////////////////////////////////////////////////////////////////////////
#include "ruby.h"
#include "board_cfg.h"
#include "ddr.h"
#include "malloc.h"
#include <shared_defs_common.h>
/* Enable auto configured board ID based on uboot environment vars */
#define UBOOT_BOARD_AUTOCONFIG
#include "ruby_board_cfg.h"
#include "ruby_board_db.h"
#include "spi_flash.h"
#define FLASH_SIZE_INTERPRET_MB_THRESHOLD 1024
static const board_cfg_t g_board_cfg_table[] = QTN_BOARD_DB;
static board_cfg_t *custom_board = NULL;
extern uint32_t flash_size;
static char board_name[RUBY_BDA_NAMELEN];
const char * const board_cfg_field_names[] = BOARD_CFG_FIELD_NAMES;
extern board_cfg_t board_hw_config;
extern int mdc_clk_divisor;
/***************************************************************************
Function:
Purpose:
Returns:
Note: Code assumes parameter is within range
**************************************************************************/
const board_cfg_t *board_locate(int board_id)
{
int i;
if (board_id == QTN_RUBY_UNIVERSAL_BOARD_ID) {
return &board_hw_config;
}
if (board_id == QTN_RUBY_AUTOCONFIG_ID) {
return custom_board;
}
for (i = 0; i < ARRAY_SIZE(g_board_cfg_table); i++) {
if (board_id == g_board_cfg_table[i].bc_board_id){
return &g_board_cfg_table[i];
}
}
return NULL;
}
int board_config(int board_id, int parameter)
{
const int *ptr;
const board_cfg_t *board = board_locate(board_id);
if (board) {
ptr = (int *)board;
return ptr[parameter];
}
return -1;
}
static int board_parse_tag_value(const struct ruby_cfgstr_map *map, const char *token, int *val)
{
while (map && map->name) {
if (!strcmp(map->name, token)) {
*val = map->val;
return 0;
}
map++;
}
return -1;
}
#ifndef TOPAZ_EP_MINI_UBOOT
static const char *board_find_tag_name(const struct ruby_board_param *params, uint32_t index, int val)
{
while (params) {
if (params->p_index == index) {
const struct ruby_cfgstr_map *map = params->p_map;
while (map) {
if (map->val == val) {
return map->name;
}
map++;
}
return NULL;
}
params++;
}
return NULL;
}
#endif /* TOPAZ_EP_MINI_UBOOT */
int board_parse_tag(const char *bc_param, const char *valstr, int *val)
{
const struct ruby_board_param *params = g_custom_board_params;
while (params && params->p_map) {
if (strcmp(bc_param, board_cfg_field_names[params->p_index]) == 0 &&
board_parse_tag_value(params->p_map, valstr, val) == 0) {
return 0;
}
params++;
}
return -1;
}
int board_parse_custom_cfg(void)
{
const struct ruby_board_param *params = g_custom_board_params;
int *ptr;
char *token = NULL;
int val = 0;
custom_board = &g_custom_board_cfg;
ptr = (int *) custom_board;
while (params && params->p_map) {
val = 0;
token = getenv(board_cfg_field_names[params->p_index]);
if (!token) {
continue;
}
if (params->p_index == BOARD_CFG_NAME) {
uint32_t len = strlen(token);
/* Copy the boardname string as we don't know if the buffer space from getenv() will be reused */
memset(board_name, 0, RUBY_BDA_NAMELEN);
memcpy(board_name, token, min(len, RUBY_BDA_NAMELEN - 1));
} else if (!board_parse_tag_value(params->p_map, token, &val)) {
if (params->p_index == BOARD_CFG_FLASH_SIZE) {
flash_size = val;
} else if (params->p_index < BOARD_CFG_STRUCT_NUM_FIELDS) {
ptr[params->p_index] = val;
}
} else {
printf("%s: token '%s' invalid\n", __FUNCTION__, token);
}
params++;
}
return 0;
}
void board_setup_bda(void *addr, int board_id)
{
ruby_bda_t *bda = (ruby_bda_t *)addr;
const board_cfg_t *board = board_locate(board_id);
char *name = (board_id == QTN_RUBY_AUTOCONFIG_ID) ? board_name : board->bc_name;
uint32_t len = strlen(name);
bda->bda_len = sizeof(ruby_bda_t);
bda->bda_version = RUBY_BDA_VERSION;
printf("BDA at 0x%x\n", (int)addr);
memcpy(&bda->bda_boardcfg, board, sizeof(board_cfg_t));
memset(bda->bda_boardname, 0 , RUBY_BDA_NAMELEN);
memcpy(bda->bda_boardname, name, (len > (RUBY_BDA_NAMELEN-1)) ? (RUBY_BDA_NAMELEN -1) : len);
if (flash_size == 0) {
bda->bda_flashsz = spi_flash_size();
} else if (flash_size < FLASH_SIZE_INTERPRET_MB_THRESHOLD) {
/*
* Older Universal hw_config_id implementations
* specify flash size in megabytes. Assume very small
* values were intended as megabytes
*/
bda->bda_flashsz = flash_size << 20;
} else {
bda->bda_flashsz = flash_size;
}
}
#ifndef TOPAZ_EP_MINI_UBOOT
int do_list_board_options(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
const struct ruby_board_param *params = g_custom_board_params;
printf("HW config Board options:\n");
while (params && params->p_map) {
const struct ruby_cfgstr_map *map = params->p_map;
printf("%s=(", board_cfg_field_names[params->p_index]);
while(map && map->name) {
printf("%s,", map->name);
map++;
}
printf(")\n");
params++;
}
return 0;
}
int do_list_board_cfg(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
const struct ruby_board_param *params = g_custom_board_params;
const board_cfg_t *board = NULL;
int board_id = 0;
char *token = (argc == 2) ? argv[1] : getenv("hw_config_id");;
if(!token) {
printf("\"hw_config_id\" not set\n");
return -1;
}
board_id = simple_strtoul (token, NULL, 10);
if (board_id < 0) {
printf("\"Invalid board: %s\n", token);
return -1;
}
board = board_locate(board_id);
if(!board) {
printf("Board ID:%d not valid.\n", board_id);
return -1;
}
if (argc == 2) {
printf("Board config for ID:%d\n", board_id);
} else {
printf("Current board config:\n");
}
printf("\tID:\t%d\n", board->bc_board_id);
printf("\tName:\t%s\n", board->bc_name);
printf("\tDDR:\t%s %dMHz %dM\n",
board_find_tag_name(params, BOARD_CFG_DDR_TYPE, board->bc_ddr_type),
board->bc_ddr_speed, board->bc_ddr_size >> 20);
printf("\tEMAC0:\t%s\n", board_find_tag_name(params, BOARD_CFG_EMAC0, board->bc_emac0));
printf("\tEMAC1:\t%s\n", board_find_tag_name(params, BOARD_CFG_EMAC1, board->bc_emac1));
printf("\tRFPA:\t%s\n", board_find_tag_name(params, BOARD_CFG_WIFI_HW, board->bc_wifi_hw));
printf("\tRGMII:\t0x%x\n", board->bc_rgmii_timing);
printf("\tSPI1:\t%s\n", board->bc_spi1 ? "Enabled" : "Disabled");
printf("\tUART1:\t%s\n", board->bc_uart1 ? "Enabled" : "Disabled");
printf("\tPCIe:\t%s\n", board->bc_pcie ? "Enabled" : "Disabled");
return 0;
}
int do_list_board(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
int i;
printf("HW config Board Name\n");
printf("-------- ------------------------------\n");
for (i=0;i<sizeof(g_board_cfg_table)/sizeof(board_cfg_t);i++) {
printf("%8d %s\n",g_board_cfg_table[i].bc_board_id,
g_board_cfg_table[i].bc_name);
}
printf("\n");
return 0;
}
U_BOOT_CMD(boardcfg, 2, 0, do_list_board_cfg,"list current board config",NULL);
U_BOOT_CMD(boardopts, 1, 0, do_list_board_options,"list board config options",NULL);
U_BOOT_CMD(lsid, 1, 0, do_list_board,"list board IDs",NULL);
#endif /* TOPAZ_EP_MINI_UBOOT */