/*
 * (C) Copyright 2010 Quantenna Communications Inc.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that 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
 */

#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <qtn/shared_defs.h>
#include <asm/board/board_config.h>
#include <common/ruby_board_db.h>
#include <common/ruby_partitions.h>

static int			global_board_id = -1;
static int			global_spi_protect_mode = 0;
static int			g_slow_ethernet = 0;
static const board_cfg_t	g_board_cfg_table[] = QTN_BOARD_DB;

#define MEM_SIZE_128MB (128 * 1024 * 1024)

static int __init
setup_slow_ethernet(char *buf)
{
	g_slow_ethernet = (buf != NULL);
	return 0;
}
early_param("slow_ethernet", setup_slow_ethernet);

static void __init
update_ddr_size(void)
{
	/* update DDR size */
	extern unsigned long end_mem;
	int ddr_size = 0;
	if (get_board_config(BOARD_CFG_DDR_SIZE, &ddr_size) < 0) {
		printk_init("UNKNOWN DDR SIZE !!!\n");
	} else {
#if !TOPAZ_MMAP_UNIFIED
		if (ddr_size > MEM_SIZE_128MB)
			ddr_size = MEM_SIZE_128MB;
#endif
		end_mem = RUBY_DRAM_BEGIN + ddr_size;
	}
}

void __init
qtn_set_hw_config_id(int id)
{
	global_board_id = id;
	update_ddr_size();
}

int qtn_get_hw_config_id(void)
{
	return global_board_id;
}
EXPORT_SYMBOL(qtn_get_hw_config_id);

void __init
qtn_set_spi_protect_config(u32 mode)
{
        global_spi_protect_mode = mode;
}

int qtn_get_spi_protect_config(void)
{
        return global_spi_protect_mode;
}
EXPORT_SYMBOL(qtn_get_spi_protect_config);

static ruby_bda_t *get_bda(void) {
	return (ruby_bda_t *)(CONFIG_ARC_CONF_BASE);
}

static int
lookup_config( const board_cfg_t *p_board_config_entry, int board_config_param, int *p_board_config_value )
{
	int	retval = 0;

	switch (board_config_param)
	{
	  case BOARD_CFG_WIFI_HW:
		*p_board_config_value = p_board_config_entry->bc_wifi_hw;
		break;

	  case BOARD_CFG_EMAC0:
		*p_board_config_value = p_board_config_entry->bc_emac0;
		break;

	  case BOARD_CFG_EMAC1:
		*p_board_config_value = p_board_config_entry->bc_emac1;
		break;

	  case BOARD_CFG_PHY1_ADDR:
		*p_board_config_value = p_board_config_entry->bc_phy1_addr;
		break;

	  case BOARD_CFG_PHY0_ADDR:
		*p_board_config_value = p_board_config_entry->bc_phy0_addr;
		break;

	  case BOARD_CFG_UART1:
		*p_board_config_value = p_board_config_entry->bc_uart1;
		break;

	  case BOARD_CFG_PCIE:
		*p_board_config_value = p_board_config_entry->bc_pcie;
		break;

	  case BOARD_CFG_RGMII_TIMING:
		*p_board_config_value = p_board_config_entry->bc_rgmii_timing;
		break;

	  case BOARD_CFG_DDR_SIZE:
		*p_board_config_value = p_board_config_entry->bc_ddr_size;
		break;

	  case BOARD_CFG_FLASH_SIZE:
		{
			ruby_bda_t *bda = get_bda();
			if (global_board_id == QTN_RUBY_AUTOCONFIG_ID || global_board_id == QTN_RUBY_UNIVERSAL_BOARD_ID) {
				*p_board_config_value = bda->bda_flashsz;
			} else {
				*p_board_config_value = 0;
			}
		}
		break;
	  default:
		retval = -1;
	}

	return( retval );
}

int
get_board_config( int board_config_param, int *p_board_config_value )
{
	int	iter;
	int	retval = -1;
	int	found_entry = 0;

	static int	get_board_config_error_is_reported = 0;

	if (p_board_config_value == NULL) {
		return( -1 );
	}

	if (global_board_id == QTN_RUBY_AUTOCONFIG_ID || global_board_id == QTN_RUBY_UNIVERSAL_BOARD_ID) {
		ruby_bda_t *bda = get_bda();

		/* need to fixup address VA on LHOST as it may be different to one on uboot */
		bda->bda_boardcfg.bc_name = bda->bda_boardname;

		return lookup_config(&bda->bda_boardcfg,
			board_config_param, p_board_config_value );
	}
	//printk("get_board_config:board ID %d param %d\n",global_board_id,board_config_param);
	for (iter = 0; iter < sizeof( g_board_cfg_table ) / sizeof( g_board_cfg_table[ 0 ] ) && (found_entry == 0); iter++) {
		if (global_board_id == g_board_cfg_table[ iter ].bc_board_id) {
			found_entry = 1;
			retval = lookup_config( &g_board_cfg_table[ iter ], board_config_param, p_board_config_value );
		}
	}
	/*
	 * Default to the first entry in the table if not found.
	 * Likely will not work for customer boards, but Q bringup baords might be OK.
	 */
	if (found_entry == 0) {
		retval = lookup_config( &g_board_cfg_table[ 0 ], board_config_param, p_board_config_value );
		if (get_board_config_error_is_reported == 0) {
			printk(KERN_ERR "get board config: HW config ID %d not recognized, defaulting to %d\n",
					 global_board_id, g_board_cfg_table[ 0 ].bc_board_id);
			get_board_config_error_is_reported = 1;
		}
	}

	return( retval );
}
EXPORT_SYMBOL(get_board_config);

int
board_slow_ethernet(void)
{
	int emac0_cfg = 0, emac1_cfg = 0;

	if (g_slow_ethernet) {
			return 1;
	}

#ifdef DETECT_SLOW_ETHERNET
	get_board_config(BOARD_CFG_EMAC0, &emac0_cfg);
	get_board_config(BOARD_CFG_EMAC1, &emac1_cfg);
#endif

	return ( (emac0_cfg | emac1_cfg) & EMAC_SLOW_PHY);
}
EXPORT_SYMBOL(board_slow_ethernet);

int
board_napi_budget(void)
{
	return 128;
}
EXPORT_SYMBOL(board_napi_budget);

int
get_all_board_params( char *p )
{
	int iter;
	char *temp=p;
	board_cfg_t *board = NULL;

	if (global_board_id == QTN_RUBY_AUTOCONFIG_ID || global_board_id == QTN_RUBY_UNIVERSAL_BOARD_ID) {
		ruby_bda_t *bda = (ruby_bda_t *)(CONFIG_ARC_CONF_BASE);
		board = &bda->bda_boardcfg;
	} else {
		for (iter = 0; iter < sizeof( g_board_cfg_table ) / sizeof( g_board_cfg_table[ 0 ] ); iter++) {
			if (global_board_id == g_board_cfg_table[ iter ].bc_board_id) {
				board = (board_cfg_t *)&g_board_cfg_table[ iter ];
				break;
			}
		}
	}

	if (board) {
		temp += sprintf( temp, "board_id\t%d\n", board->bc_board_id);
			temp += sprintf( temp, "name\t%s\n", board->bc_name);
			temp += sprintf( temp, "ddr_type\t%d\n", board->bc_ddr_type);
			temp += sprintf( temp, "ddr_speed\t%d\n", board->bc_ddr_speed);
			temp += sprintf( temp, "ddr_size\t%d\n", board->bc_ddr_size);
			temp += sprintf( temp, "emac0\t%d\n", board->bc_emac0);
			temp += sprintf( temp, "emac1\t%d\n", board->bc_emac1);
			temp += sprintf( temp, "phy0_addr\t%d\n", board->bc_phy0_addr);
			temp += sprintf( temp, "phy1_addr\t%d\n", board->bc_phy1_addr);
			temp += sprintf( temp, "spi1\t%d\n", board->bc_spi1);
			temp += sprintf( temp, "wifi_hw\t%d\n", board->bc_wifi_hw);
			temp += sprintf( temp, "uart1\t%d\n", board->bc_uart1);
			temp += sprintf( temp, "bd_pcie\t%d\n", board->bc_pcie);
			temp += sprintf( temp, "rgmii_timing\t%d\n", board->bc_rgmii_timing);
		}
	return (temp-p);
}
EXPORT_SYMBOL(get_all_board_params);

void __init
parse_board_config(char *cmdline)
{
	/* parse command line */
	int cmdline_len = strlen(cmdline);
	const char *var = "hw_config_id=";
	int var_len = strlen(var);
	while (cmdline_len > var_len) {
		if (!strncmp(cmdline, var, var_len)) {
			sscanf(cmdline + var_len, "%d", &global_board_id);
			printk_init("Board id: %d\n", global_board_id);
			break;
		}
		++cmdline;
		--cmdline_len;
	}

	/* we should already know board id */
	if (global_board_id < 0) {
		printk_init("UNKNOWN BOARD ID !!!\n");
	}

	/* update DDR size */
	update_ddr_size();
}
