/*
 * (C) Copyright 2010 Quantenna Communications Inc.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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 "ruby.h"
#include "malloc.h"
#include "ddr.h"
#include <shared_defs_common.h>
#include "ruby_board_cfg.h"
#include "ruby_board_db.h"
#include "board_cfg.h"
#include "pcie.h"
#include "ruby_spi_api.h"
#include "spi_api.h"

extern int board_hw_config_read(void);
extern int mdc_clk_divisor;

#ifndef TOPAZ_EP_MINI_UBOOT
void qtn_mini_hw_init(int board_id);
int board_cfg_init(int *p_board_id);
void board_pmu_init(void);

/* use spare register for saving gd pointer - used for EXPORT_FUNC() */
static void board_global_data_init(void)
{
	DECLARE_GLOBAL_DATA_PTR;
	gd->cpu_clk = RUBY_FIXED_CPU_CLK;
	gd->bus_clk = RUBY_FIXED_DEV_CLK;
	gd->baudrate = RUBY_SERIAL_BAUD;
	gd->bd->bi_memsize = RUBY_MIN_DRAM_SIZE;
	gd->bd->bi_boot_params = 0x0;
	writel((int)gd,0xe00000bc);
}

int board_init(void)
{
	dcache_enable();
	board_pmu_init();
	board_global_data_init();
	board_serial_init();
	board_check_build();
	board_intr_init();
	board_timer_init();
	board_spi_flash_init();
	return 0;
}

static void dump_muc_stack(const struct ruby_crumbs *crumbs)
{
	uint32_t sp_muc;
	const uint32_t *sp_virt;
	const uint32_t * const sp_virt_end = (void*)CONFIG_ARC_MUC_STACK_INIT_UBOOT;

	printf("\tMuC stack candidates:\n");
	printf("\t\tdram text: 0x%08lx - 0x%08lx\n",
			crumbs->muc_dram.start,
			crumbs->muc_dram.end);
	printf("\t\tsram text: 0x%08lx - 0x%08lx\n",
			crumbs->muc_sram.start,
			crumbs->muc_sram.end);

	sp_muc = crumbs->muc.sp;
	if (!sp_muc) {
		/*
		 * if the MuC isn't recording prolog crumbs,
		 * use the lowest part of the MuC stack
		 */
		sp_muc = virt_to_bus((void*)CONFIG_ARC_STACK_BEGIN);
	}
	sp_virt = (void*)bus_to_virt(sp_muc);
	if (sp_virt == RUBY_BAD_VIRT_ADDR) {
		printf("%s: could not get sp_virt, sp_muc = 0x%08x\n", __FUNCTION__, sp_muc);
		return;
	}
	if (sp_muc % 4 != 0 || ((uint32_t)sp_virt) % 4 != 0) {
		printf("%s: misaligned stack pointer muc 0x%08x\n", __FUNCTION__, sp_muc);
		return;
	}

	while (sp_virt <= sp_virt_end) {
		/*
		 * read muc stack contents at *sp, compare value with muc text sections
		 */
		uint32_t val = *sp_virt;
		int in_sram = val >= crumbs->muc_sram.start && val <= crumbs->muc_sram.end;
		int in_dram = val >= crumbs->muc_dram.start && val <= crumbs->muc_dram.end;
		if (val && (in_sram || in_dram)) {
			printf("\t\tsp 0x%08x\tfn 0x%08x\n", sp_muc, val);
		}
		sp_muc += 4;
		sp_virt++;
	}
}

static void dump_core_crumbs(const char* core, const struct ruby_crumbs_percore *core_crumbs)
{
	printf("\t%s:\tblink 0x%lx status32 0x%lx sp 0x%lx\n",
			core,
			core_crumbs->blink,
			core_crumbs->status32,
			core_crumbs->sp);
}

static void dump_ruby_crumbs(const struct ruby_crumbs *crumbs)
{
	dump_core_crumbs("lhost", &crumbs->lhost);
	dump_core_crumbs("DSP", &crumbs->dsp);
	dump_core_crumbs("MuC", &crumbs->muc);
}

static void init_ruby_crumbs(void)
{
	struct ruby_crumbs *crumbs = (struct ruby_crumbs*)RUBY_CRUMBS_ADDR_UBOOT;
	char *crumb_env;
	int show_crumbs = 0;
	int magic_valid =  crumbs->magic == RUBY_CRUMBS_MAGIC;

	crumb_env = getenv("dump_crumbs");
	if (crumb_env != NULL) {
		show_crumbs = simple_strtoul(crumb_env, NULL, 10);
	}

	if (show_crumbs) {
		printf("Info: last core activity: \n");
		if (magic_valid) {
			dump_ruby_crumbs(crumbs);
			dump_muc_stack(crumbs);
		} else {
			printf("***Crumbs magic token is incorrect, values are probably invalid\n");
			dump_ruby_crumbs(crumbs);
		}
		printf("\n");
	}

	/* clear the crumbs structure */
	memset(crumbs, 0, sizeof(*crumbs));
}

int board_late_init(void)
{
	DECLARE_GLOBAL_DATA_PTR;
	u32 ddr_size = DEFAULT_DDR_SIZE;
	int board_id;
	char *p;

	init_ruby_crumbs();

	if (board_cfg_init(&board_id) != 0) {
		printf("error: board configuration not found\n");
		return -1;
	}

	p = getenv("mdc_clk_div");
	if (p != NULL)
		mdc_clk_divisor = 3 & simple_strtoul(p, NULL, 10);

	gd->bd->bi_board_id = board_id;
	ddr_size = board_config(board_id,BOARD_CFG_DDR_SIZE);
	gd->bd->bi_memsize = ddr_size;

	if (read_new_aux_reg(SCRATCH_DATA0)) {
		printf("Warm boot\n");
	} else  {
		printf("Cold boot\n");
		qtn_mini_hw_init(board_id);
	}

	board_setup_bda((void *) CONFIG_ARC_CONF_BASE, board_id);

	qtn_parse_early_flash_config(0);

	/* Here we check the env to see if user want to Enable SPI Flash Protect
	 * Mode
	 */
	if ((p = getenv(SPI_PROTECT_MODE)) != NULL) {
		if (strcmp (p, SPI_PROTECT_MODE_ENABLE) == 0){
			spi_protect_mode_on();
		} else {
			spi_protect_mode_off();
		}
	}
#ifdef CONFIG_CMD_HNVRAM
        RUN("hnvram load");
#endif
	return 0;
}

int protect_env_get(void)
{
	char *p;

	if ((p = getenv(SPI_PROTECT_MODE)) != NULL) {
		if (strcmp (p, SPI_PROTECT_MODE_ENABLE) == 0){
			return 0;
		}
	}
	return -1;
}

#endif /* TOPAZ_EP_MINI_UBOOT */

void board_pmu_init(void)
{
#define TOPAZ_PMU_CONFIG_1	0xe00000f0
#define TOPAZ_PMU_CONFIG_2	0xe00000f4
	u32 rdata;

	rdata = 0xc00002f0;
	REG_WRITE(TOPAZ_PMU_CONFIG_1,rdata);

	rdata = 0xb7000027;
	REG_WRITE(TOPAZ_PMU_CONFIG_2,rdata);
}

/*
 * Figure out our board type from
 * env and configure properly
 */
int board_cfg_init(int *p_board_id)
{
	int board_id = DEFAULT_BOARD_ID;
#ifndef RUBY_MINI
	int uart1 = 0;
#endif
	int retval = 0;
	char *s;

	s = getenv("hw_config_id");
	if (s == NULL)
		printf("\"hw_config_id\" not set, using default value of %d\n", board_id);
	else
		board_id = simple_strtoul(s, NULL, 10);

	if (board_id == QTN_RUBY_AUTOCONFIG_ID)
		board_parse_custom_cfg();

	if (board_id == QTN_RUBY_UNIVERSAL_BOARD_ID) {
		retval = board_hw_config_read();
		if (retval < 0)
			return -1;
	}

	if (board_config(board_id, BOARD_CFG_ID) != board_id)
		return -1;

	s = (char *) board_config(board_id, BOARD_CFG_NAME);
	if (s != NULL)
		printf("hw_config_id %u: '%s'\n", board_id, s);

	*p_board_id = board_id;

#ifndef RUBY_MINI
	/* Setup UART1 */
	s = getenv("uart1");
	if (s)
		uart1 = simple_strtoul(s, NULL, 1);

	/* Check for u-boot env. or board configuration */
	if (uart1 || (board_config(board_id, BOARD_CFG_UART1) == UART1_IN_USE)) {
		printf("UART1 enabled: GPIO_PIN1 (input) Rx, GPIO_PIN9 (output) Tx\n");
		gpio_config(GPIO_PIN(1), RUBY_GPIO_ALT_INPUT);
		gpio_config(GPIO_PIN(9), RUBY_GPIO_ALT_OUTPUT);
	}
#endif

	return 0;
}

/*
 * Quantenna minimal hardware initailization, which depends on board config.
 * Include DDR and PCIe.
 */
void qtn_mini_hw_init(int board_id)
{
	u32 ddr_speed = DEFAULT_DDR_SPEED;
	u32 ddr_size = DEFAULT_DDR_SIZE;
	u32 ddr_type = DEFAULT_DDR_CFG;
	int pcie_flags;

	printf("Reset status: 0x%08x\n",
			arc_read_uncached_32(RUBY_SYS_CTL_RESET_CAUSE));
	pcie_flags = board_config(board_id, BOARD_CFG_PCIE);
	if (pcie_flags & PCIE_IN_USE) {
		uint32_t time;
		pcie_ep_early_init(pcie_flags);
		time = read_new_aux_reg(ARC_REG_TIMER1_CNT);
		time /= (RUBY_FIXED_CPU_CLK / 1000);
		printf("PCIe early init, done@%dms\n", time);
	}
#ifndef TOPAZ_EP_MINI_UBOOT
	board_info_init();
	spi_flash_info();
#endif

	ddr_type = board_config(board_id, BOARD_CFG_DDR_TYPE);
	ddr_speed = board_config(board_id, BOARD_CFG_DDR_SPEED);
	ddr_size = board_config(board_id,BOARD_CFG_DDR_SIZE);
	ddr_init(ddr_type, ddr_speed, ddr_size);

	if (pcie_flags & PCIE_IN_USE) {
		board_pcie_init(ddr_size, pcie_flags);
	}
}
