/*
 * Copyright 2014 Freescale Semiconductor, Inc.
 *
 * SPDX-License-Identifier:     GPL-2.0+
 */

#include <common.h>
#include <command.h>
#include <i2c.h>
#include <netdev.h>
#include <linux/compiler.h>
#include <asm/mmu.h>
#include <asm/processor.h>
#include <asm/immap_85xx.h>
#include <asm/fsl_law.h>
#include <asm/fsl_serdes.h>
#include <asm/fsl_portals.h>
#include <asm/fsl_liodn.h>
#include <fm_eth.h>
#include "t102xrdb.h"
#ifdef CONFIG_T1024RDB
#include "cpld.h"
#elif defined(CONFIG_T1023RDB)
#include <i2c.h>
#include <mmc.h>
#endif
#include "../common/sleep.h"

DECLARE_GLOBAL_DATA_PTR;

#ifdef CONFIG_T1023RDB
enum {
	GPIO1_SD_SEL    = 0x00020000, /* GPIO1_14, 0: eMMC, 1:SD/MMC */
	GPIO1_EMMC_SEL,
	GPIO3_GET_VERSION,	       /* GPIO3_4/5, 00:RevB, 01: RevC */
	GPIO3_BRD_VER_MASK = 0x0c000000,
	GPIO3_OFFSET = 0x2000,
	I2C_GET_BANK,
	I2C_SET_BANK0,
	I2C_SET_BANK4,
};
#endif

int checkboard(void)
{
	struct cpu_type *cpu = gd->arch.cpu;
	static const char *freq[3] = {"100.00MHZ", "125.00MHz", "156.25MHZ"};
	ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	u32 srds_s1;

	srds_s1 = in_be32(&gur->rcwsr[4]) & FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
	srds_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;

	printf("Board: %sRDB, ", cpu->name);
#if defined(CONFIG_T1024RDB)
	printf("Board rev: 0x%02x CPLD ver: 0x%02x, ",
	       CPLD_READ(hw_ver), CPLD_READ(sw_ver));
#elif defined(CONFIG_T1023RDB)
	printf("Rev%c, ", t1023rdb_ctrl(GPIO3_GET_VERSION) + 'B');
#endif
	printf("boot from ");

#ifdef CONFIG_SDCARD
	puts("SD/MMC\n");
#elif CONFIG_SPIFLASH
	puts("SPI\n");
#elif defined(CONFIG_T1024RDB)
	u8 reg;

	reg = CPLD_READ(flash_csr);

	if (reg & CPLD_BOOT_SEL) {
		puts("NAND\n");
	} else {
		reg = ((reg & CPLD_LBMAP_MASK) >> CPLD_LBMAP_SHIFT);
		printf("NOR vBank%d\n", reg);
	}
#elif defined(CONFIG_T1023RDB)
#ifdef CONFIG_NAND
	puts("NAND\n");
#else
	printf("NOR vBank%d\n", t1023rdb_ctrl(I2C_GET_BANK));
#endif
#endif

	puts("SERDES Reference Clocks:\n");
	if (srds_s1 == 0x95)
		printf("SD1_CLK1=%s, SD1_CLK2=%s\n", freq[2], freq[0]);
	else
		printf("SD1_CLK1=%s, SD1_CLK2=%s\n", freq[0], freq[1]);

	return 0;
}

#ifdef CONFIG_T1024RDB
static void board_mux_lane(void)
{
	ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	u32 srds_prtcl_s1;
	u8 reg = CPLD_READ(misc_ctl_status);

	srds_prtcl_s1 = in_be32(&gur->rcwsr[4]) &
				FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
	srds_prtcl_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;

	if (srds_prtcl_s1 == 0x95) {
		/* Route Lane B to PCIE */
		CPLD_WRITE(misc_ctl_status, reg & ~CPLD_PCIE_SGMII_MUX);
	} else {
		/* Route Lane B to SGMII */
		CPLD_WRITE(misc_ctl_status, reg | CPLD_PCIE_SGMII_MUX);
	}
	CPLD_WRITE(boot_override, CPLD_OVERRIDE_MUX_EN);
}
#endif

int board_early_init_f(void)
{
#if defined(CONFIG_DEEP_SLEEP)
	if (is_warm_boot())
		fsl_dp_disable_console();
#endif

	return 0;
}

int board_early_init_r(void)
{
#ifdef CONFIG_SYS_FLASH_BASE
	const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
	int flash_esel = find_tlb_idx((void *)flashbase, 1);
	/*
	 * Remap Boot flash region to caching-inhibited
	 * so that flash can be erased properly.
	 */

	/* Flush d-cache and invalidate i-cache of any FLASH data */
	flush_dcache();
	invalidate_icache();
	if (flash_esel == -1) {
		/* very unlikely unless something is messed up */
		puts("Error: Could not find TLB for FLASH BASE\n");
		flash_esel = 2;	/* give our best effort to continue */
	} else {
		/* invalidate existing TLB entry for flash + promjet */
		disable_tlb(flash_esel);
	}

	set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
		MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
		0, flash_esel, BOOKE_PAGESZ_256M, 1);
#endif

	set_liodns();
#ifdef CONFIG_SYS_DPAA_QBMAN
	setup_portals();
#endif
#ifdef CONFIG_T1024RDB
	board_mux_lane();
#endif

	return 0;
}

unsigned long get_board_sys_clk(void)
{
	return CONFIG_SYS_CLK_FREQ;
}

unsigned long get_board_ddr_clk(void)
{
	return CONFIG_DDR_CLK_FREQ;
}

int misc_init_r(void)
{
	return 0;
}

int ft_board_setup(void *blob, bd_t *bd)
{
	phys_addr_t base;
	phys_size_t size;

	ft_cpu_setup(blob, bd);

	base = getenv_bootm_low();
	size = getenv_bootm_size();

	fdt_fixup_memory(blob, (u64)base, (u64)size);

#ifdef CONFIG_PCI
	pci_of_setup(blob, bd);
#endif

	fdt_fixup_liodn(blob);
	fdt_fixup_dr_usb(blob, bd);

#ifdef CONFIG_SYS_DPAA_FMAN
	fdt_fixup_fman_ethernet(blob);
	fdt_fixup_board_enet(blob);
#endif

#ifdef CONFIG_T1023RDB
	if (t1023rdb_ctrl(GPIO3_GET_VERSION) > 0)
		fdt_enable_nor(blob);
#endif

	return 0;
}

#ifdef CONFIG_T1023RDB
/* Enable NOR flash for RevC */
static void fdt_enable_nor(void *blob)
{
	int nodeoff = fdt_node_offset_by_compatible(blob, 0, "cfi-flash");

	if (nodeoff >= 0)
		fdt_status_okay(blob, nodeoff);
	else
		printf("WARNING unable to set status for NOR\n");
}

int board_mmc_getcd(struct mmc *mmc)
{
	ccsr_gpio_t __iomem *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
	u32 val = in_be32(&pgpio->gpdat);

	/* GPIO1_14, 0: eMMC, 1: SD/MMC */
	val &= GPIO1_SD_SEL;

	return val ? -1 : 1;
}

int board_mmc_getwp(struct mmc *mmc)
{
	ccsr_gpio_t __iomem *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
	u32 val = in_be32(&pgpio->gpdat);

	val &= GPIO1_SD_SEL;

	return val ? -1 : 0;
}

static u32 t1023rdb_ctrl(u32 ctrl_type)
{
	ccsr_gpio_t __iomem *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
	ccsr_gur_t __iomem  *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	u32 val, orig_bus = i2c_get_bus_num();
	u8 tmp;

	switch (ctrl_type) {
	case GPIO1_SD_SEL:
		val = in_be32(&pgpio->gpdat);
		val |= GPIO1_SD_SEL;
		out_be32(&pgpio->gpdat, val);
		setbits_be32(&pgpio->gpdir, GPIO1_SD_SEL);
		break;
	case GPIO1_EMMC_SEL:
		val = in_be32(&pgpio->gpdat);
		val &= ~GPIO1_SD_SEL;
		out_be32(&pgpio->gpdat, val);
		setbits_be32(&pgpio->gpdir, GPIO1_SD_SEL);
		break;
	case GPIO3_GET_VERSION:
		pgpio = (ccsr_gpio_t *)(CONFIG_SYS_MPC85xx_GPIO_ADDR
			 + GPIO3_OFFSET);
		val = in_be32(&pgpio->gpdat);
		val = ((val & GPIO3_BRD_VER_MASK) >> 26) & 0x3;
		if (val == 0x3) /* GPIO3_4/5 not used on RevB */
			val = 0;
		return val;
	case I2C_GET_BANK:
		i2c_set_bus_num(I2C_PCA6408_BUS_NUM);
		i2c_read(I2C_PCA6408_ADDR, 0, 1, &tmp, 1);
		tmp &= 0x7;
		tmp = ((tmp & 1) << 2) | (tmp & 2) | ((tmp & 4) >> 2);
		i2c_set_bus_num(orig_bus);
		return tmp;
	case I2C_SET_BANK0:
		i2c_set_bus_num(I2C_PCA6408_BUS_NUM);
		tmp = 0x0;
		i2c_write(I2C_PCA6408_ADDR, 1, 1, &tmp, 1);
		tmp = 0xf8;
		i2c_write(I2C_PCA6408_ADDR, 3, 1, &tmp, 1);
		/* asserting HRESET_REQ */
		out_be32(&gur->rstcr, 0x2);
		break;
	case I2C_SET_BANK4:
		i2c_set_bus_num(I2C_PCA6408_BUS_NUM);
		tmp = 0x1;
		i2c_write(I2C_PCA6408_ADDR, 1, 1, &tmp, 1);
		tmp = 0xf8;
		i2c_write(I2C_PCA6408_ADDR, 3, 1, &tmp, 1);
		out_be32(&gur->rstcr, 0x2);
		break;
	default:
		break;
	}
	return 0;
}

static int switch_cmd(cmd_tbl_t *cmdtp, int flag, int argc,
		    char * const argv[])
{
	if (argc < 2)
		return CMD_RET_USAGE;
	if (!strcmp(argv[1], "bank0"))
		t1023rdb_ctrl(I2C_SET_BANK0);
	else if (!strcmp(argv[1], "bank4") || !strcmp(argv[1], "altbank"))
		t1023rdb_ctrl(I2C_SET_BANK4);
	else if (!strcmp(argv[1], "sd"))
		t1023rdb_ctrl(GPIO1_SD_SEL);
	else if (!strcmp(argv[1], "emmc"))
		t1023rdb_ctrl(GPIO1_EMMC_SEL);
	else
		return CMD_RET_USAGE;
	return 0;
}

U_BOOT_CMD(
	switch, 2, 0, switch_cmd,
	"for bank0/bank4/sd/emmc switch control in runtime",
	"command (e.g. switch bank4)"
);
#endif
