/*
 * Copyright 2009-2012 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/cache.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 "../common/qixis.h"
#include "../common/vsc3316_3308.h"
#include "t4qds.h"
#include "t4240qds_qixis.h"

DECLARE_GLOBAL_DATA_PTR;

static int8_t vsc3316_fsm1_tx[8][2] = { {0, 0}, {1, 1}, {6, 6}, {7, 7},
				{8, 8}, {9, 9}, {14, 14}, {15, 15} };

static int8_t vsc3316_fsm2_tx[8][2] = { {2, 2}, {3, 3}, {4, 4}, {5, 5},
				{10, 10}, {11, 11}, {12, 12}, {13, 13} };

static int8_t vsc3316_fsm1_rx[8][2] = { {2, 12}, {3, 13}, {4, 5}, {5, 4},
				{10, 11}, {11, 10}, {12, 2}, {13, 3} };

static int8_t vsc3316_fsm2_rx[8][2] = { {0, 15}, {1, 14}, {6, 7}, {7, 6},
				{8, 9}, {9, 8}, {14, 1}, {15, 0} };

int checkboard(void)
{
	char buf[64];
	u8 sw;
	struct cpu_type *cpu = gd->arch.cpu;
	unsigned int i;

	printf("Board: %sQDS, ", cpu->name);
	printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, ",
	       QIXIS_READ(id), QIXIS_READ(arch));

	sw = QIXIS_READ(brdcfg[0]);
	sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;

	if (sw < 0x8)
		printf("vBank: %d\n", sw);
	else if (sw == 0x8)
		puts("Promjet\n");
	else if (sw == 0x9)
		puts("NAND\n");
	else
		printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH);

	printf("FPGA: v%d (%s), build %d",
	       (int)QIXIS_READ(scver), qixis_read_tag(buf),
	       (int)qixis_read_minor());
	/* the timestamp string contains "\n" at the end */
	printf(" on %s", qixis_read_time(buf));

	/*
	 * Display the actual SERDES reference clocks as configured by the
	 * dip switches on the board.  Note that the SWx registers could
	 * technically be set to force the reference clocks to match the
	 * values that the SERDES expects (or vice versa).  For now, however,
	 * we just display both values and hope the user notices when they
	 * don't match.
	 */
	puts("SERDES Reference Clocks: ");
	sw = QIXIS_READ(brdcfg[2]);
	for (i = 0; i < MAX_SERDES; i++) {
		static const char * const freq[] = {
			"100", "125", "156.25", "161.1328125"};
		unsigned int clock = (sw >> (6 - 2 * i)) & 3;

		printf("SERDES%u=%sMHz ", i+1, freq[clock]);
	}
	puts("\n");

	return 0;
}

int select_i2c_ch_pca9547(u8 ch)
{
	int ret;

	ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1);
	if (ret) {
		puts("PCA: failed to select proper channel\n");
		return ret;
	}

	return 0;
}

/*
 * read_voltage from sensor on I2C bus
 * We use average of 4 readings, waiting for 532us befor another reading
 */
#define NUM_READINGS	4	/* prefer to be power of 2 for efficiency */
#define WAIT_FOR_ADC	532	/* wait for 532 microseconds for ADC */

static inline int read_voltage(void)
{
	int i, ret, voltage_read = 0;
	u16 vol_mon;

	for (i = 0; i < NUM_READINGS; i++) {
		ret = i2c_read(I2C_VOL_MONITOR_ADDR,
			I2C_VOL_MONITOR_BUS_V_OFFSET, 1, (void *)&vol_mon, 2);
		if (ret) {
			printf("VID: failed to read core voltage\n");
			return ret;
		}
		if (vol_mon & I2C_VOL_MONITOR_BUS_V_OVF) {
			printf("VID: Core voltage sensor error\n");
			return -1;
		}
		debug("VID: bus voltage reads 0x%04x\n", vol_mon);
		/* LSB = 4mv */
		voltage_read += (vol_mon >> I2C_VOL_MONITOR_BUS_V_SHIFT) * 4;
		udelay(WAIT_FOR_ADC);
	}
	/* calculate the average */
	voltage_read /= NUM_READINGS;

	return voltage_read;
}

/*
 * We need to calculate how long before the voltage starts to drop or increase
 * It returns with the loop count. Each loop takes several readings (532us)
 */
static inline int wait_for_voltage_change(int vdd_last)
{
	int timeout, vdd_current;

	vdd_current = read_voltage();
	/* wait until voltage starts to drop */
	for (timeout = 0; abs(vdd_last - vdd_current) <= 4 &&
		timeout < 100; timeout++) {
		vdd_current = read_voltage();
	}
	if (timeout >= 100) {
		printf("VID: Voltage adjustment timeout\n");
		return -1;
	}
	return timeout;
}

/*
 * argument 'wait' is the time we know the voltage difference can be measured
 * this function keeps reading the voltage until it is stable
 */
static inline int wait_for_voltage_stable(int wait)
{
	int timeout, vdd_current, vdd_last;

	vdd_last = read_voltage();
	udelay(wait * NUM_READINGS * WAIT_FOR_ADC);
	/* wait until voltage is stable */
	vdd_current = read_voltage();
	for (timeout = 0; abs(vdd_last - vdd_current) >= 4 &&
		timeout < 100; timeout++) {
		vdd_last = vdd_current;
		udelay(wait * NUM_READINGS * WAIT_FOR_ADC);
		vdd_current = read_voltage();
	}
	if (timeout >= 100) {
		printf("VID: Voltage adjustment timeout\n");
		return -1;
	}

	return vdd_current;
}

static inline int set_voltage(u8 vid)
{
	int wait, vdd_last;

	vdd_last = read_voltage();
	QIXIS_WRITE(brdcfg[6], vid);
	wait = wait_for_voltage_change(vdd_last);
	if (wait < 0)
		return -1;
	debug("VID: Waited %d us\n", wait * NUM_READINGS * WAIT_FOR_ADC);
	wait = wait ? wait : 1;

	vdd_last = wait_for_voltage_stable(wait);
	if (vdd_last < 0)
		return -1;
	debug("VID: Current voltage is %d mV\n", vdd_last);

	return vdd_last;
}


static int adjust_vdd(ulong vdd_override)
{
	int re_enable = disable_interrupts();
	ccsr_gur_t __iomem *gur =
		(void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	u32 fusesr;
	u8 vid, vid_current;
	int vdd_target, vdd_current, vdd_last;
	int ret;
	unsigned long vdd_string_override;
	char *vdd_string;
	static const uint16_t vdd[32] = {
		0,	/* unused */
		9875,	/* 0.9875V */
		9750,
		9625,
		9500,
		9375,
		9250,
		9125,
		9000,
		8875,
		8750,
		8625,
		8500,
		8375,
		8250,
		8125,
		10000,	/* 1.0000V */
		10125,
		10250,
		10375,
		10500,
		10625,
		10750,
		10875,
		11000,
		0,	/* reserved */
	};
	struct vdd_drive {
		u8 vid;
		unsigned voltage;
	};

	ret = select_i2c_ch_pca9547(I2C_MUX_CH_VOL_MONITOR);
	if (ret) {
		debug("VID: I2c failed to switch channel\n");
		ret = -1;
		goto exit;
	}

	/* get the voltage ID from fuse status register */
	fusesr = in_be32(&gur->dcfg_fusesr);
	vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_VID_SHIFT) &
		FSL_CORENET_DCFG_FUSESR_VID_MASK;
	if (vid == FSL_CORENET_DCFG_FUSESR_VID_MASK) {
		vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_ALTVID_SHIFT) &
			FSL_CORENET_DCFG_FUSESR_ALTVID_MASK;
	}
	vdd_target = vdd[vid];

	/* check override variable for overriding VDD */
	vdd_string = getenv("t4240qds_vdd_mv");
	if (vdd_override == 0 && vdd_string &&
	    !strict_strtoul(vdd_string, 10, &vdd_string_override))
		vdd_override = vdd_string_override;
	if (vdd_override >= 819 && vdd_override <= 1212) {
		vdd_target = vdd_override * 10; /* convert to 1/10 mV */
		debug("VDD override is %lu\n", vdd_override);
	} else if (vdd_override != 0) {
		printf("Invalid value.\n");
	}

	if (vdd_target == 0) {
		debug("VID: VID not used\n");
		ret = 0;
		goto exit;
	} else {
		/* round up and divice by 10 to get a value in mV */
		vdd_target = DIV_ROUND_UP(vdd_target, 10);
		debug("VID: vid = %d mV\n", vdd_target);
	}

	/*
	 * Check current board VID setting
	 * Voltage regulator support output to 6.250mv step
	 * The highes voltage allowed for this board is (vid=0x40) 1.21250V
	 * the lowest is (vid=0x7f) 0.81875V
	 */
	vid_current =  QIXIS_READ(brdcfg[6]);
	vdd_current = 121250 - (vid_current - 0x40) * 625;
	debug("VID: Current vid setting is (0x%x) %d mV\n",
	      vid_current, vdd_current/100);

	/*
	 * Read voltage monitor to check real voltage.
	 * Voltage monitor LSB is 4mv.
	 */
	vdd_last = read_voltage();
	if (vdd_last < 0) {
		printf("VID: Could not read voltage sensor abort VID adjustment\n");
		ret = -1;
		goto exit;
	}
	debug("VID: Core voltage is at %d mV\n", vdd_last);
	/*
	 * Adjust voltage to at or 8mV above target.
	 * Each step of adjustment is 6.25mV.
	 * Stepping down too fast may cause over current.
	 */
	while (vdd_last > 0 && vid_current < 0x80 &&
		vdd_last > (vdd_target + 8)) {
		vid_current++;
		vdd_last = set_voltage(vid_current);
	}
	/*
	 * Check if we need to step up
	 * This happens when board voltage switch was set too low
	 */
	while (vdd_last > 0 && vid_current >= 0x40 &&
		vdd_last < vdd_target + 2) {
		vid_current--;
		vdd_last = set_voltage(vid_current);
	}
	if (vdd_last > 0)
		printf("VID: Core voltage %d mV\n", vdd_last);
	else
		ret = -1;

exit:
	if (re_enable)
		enable_interrupts();
	return ret;
}

/* Configure Crossbar switches for Front-Side SerDes Ports */
int config_frontside_crossbar_vsc3316(void)
{
	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	u32 srds_prtcl_s1, srds_prtcl_s2;
	int ret;

	ret = select_i2c_ch_pca9547(I2C_MUX_CH_VSC3316_FS);
	if (ret)
		return ret;

	srds_prtcl_s1 = in_be32(&gur->rcwsr[4]) &
			FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
	srds_prtcl_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
	switch (srds_prtcl_s1) {
	case 38:
		/* swap first lane and third lane on slot1 */
		vsc3316_fsm1_tx[0][1] = 14;
		vsc3316_fsm1_tx[6][1] = 0;
		vsc3316_fsm1_rx[1][1] = 2;
		vsc3316_fsm1_rx[6][1] = 13;
	case 40:
	case 46:
	case 48:
		/* swap first lane and third lane on slot2 */
		vsc3316_fsm1_tx[2][1] = 8;
		vsc3316_fsm1_tx[4][1] = 6;
		vsc3316_fsm1_rx[2][1] = 10;
		vsc3316_fsm1_rx[5][1] = 5;
	default:
		ret = vsc3316_config(VSC3316_FSM_TX_ADDR, vsc3316_fsm1_tx, 8);
		if (ret)
			return ret;
		ret = vsc3316_config(VSC3316_FSM_RX_ADDR, vsc3316_fsm1_rx, 8);
		if (ret)
			return ret;
		break;
	}

	srds_prtcl_s2 = in_be32(&gur->rcwsr[4]) &
				FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
	srds_prtcl_s2 >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
	switch (srds_prtcl_s2) {
	case 38:
		/* swap first lane and third lane on slot3 */
		vsc3316_fsm2_tx[2][1] = 11;
		vsc3316_fsm2_tx[5][1] = 4;
		vsc3316_fsm2_rx[2][1] = 9;
		vsc3316_fsm2_rx[4][1] = 7;
	case 40:
	case 46:
	case 48:
	case 50:
	case 52:
	case 54:
		/* swap first lane and third lane on slot4 */
		vsc3316_fsm2_tx[6][1] = 3;
		vsc3316_fsm2_tx[1][1] = 12;
		vsc3316_fsm2_rx[0][1] = 1;
		vsc3316_fsm2_rx[6][1] = 15;
	default:
		ret = vsc3316_config(VSC3316_FSM_TX_ADDR, vsc3316_fsm2_tx, 8);
		if (ret)
			return ret;
		ret = vsc3316_config(VSC3316_FSM_RX_ADDR, vsc3316_fsm2_rx, 8);
		if (ret)
			return ret;
		break;
	}

	return 0;
}

int config_backside_crossbar_mux(void)
{
	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	u32 srds_prtcl_s3, srds_prtcl_s4;
	u8 brdcfg;

	srds_prtcl_s3 = in_be32(&gur->rcwsr[4]) &
			FSL_CORENET2_RCWSR4_SRDS3_PRTCL;
	srds_prtcl_s3 >>= FSL_CORENET2_RCWSR4_SRDS3_PRTCL_SHIFT;
	switch (srds_prtcl_s3) {
	case 0:
		/* SerDes3 is not enabled */
		break;
	case 2:
	case 9:
	case 10:
		/* SD3(0:7) => SLOT5(0:7) */
		brdcfg = QIXIS_READ(brdcfg[12]);
		brdcfg &= ~BRDCFG12_SD3MX_MASK;
		brdcfg |= BRDCFG12_SD3MX_SLOT5;
		QIXIS_WRITE(brdcfg[12], brdcfg);
		break;
	case 4:
	case 6:
	case 8:
	case 12:
	case 14:
	case 16:
	case 17:
	case 19:
	case 20:
		/* SD3(4:7) => SLOT6(0:3) */
		brdcfg = QIXIS_READ(brdcfg[12]);
		brdcfg &= ~BRDCFG12_SD3MX_MASK;
		brdcfg |= BRDCFG12_SD3MX_SLOT6;
		QIXIS_WRITE(brdcfg[12], brdcfg);
		break;
	default:
		printf("WARNING: unsupported for SerDes3 Protocol %d\n",
		       srds_prtcl_s3);
		return -1;
	}

	srds_prtcl_s4 = in_be32(&gur->rcwsr[4]) &
			FSL_CORENET2_RCWSR4_SRDS4_PRTCL;
	srds_prtcl_s4 >>= FSL_CORENET2_RCWSR4_SRDS4_PRTCL_SHIFT;
	switch (srds_prtcl_s4) {
	case 0:
		/* SerDes4 is not enabled */
		break;
	case 2:
		/* 10b, SD4(0:7) => SLOT7(0:7) */
		brdcfg = QIXIS_READ(brdcfg[12]);
		brdcfg &= ~BRDCFG12_SD4MX_MASK;
		brdcfg |= BRDCFG12_SD4MX_SLOT7;
		QIXIS_WRITE(brdcfg[12], brdcfg);
		break;
	case 4:
	case 6:
	case 8:
		/* x1b, SD4(4:7) => SLOT8(0:3) */
		brdcfg = QIXIS_READ(brdcfg[12]);
		brdcfg &= ~BRDCFG12_SD4MX_MASK;
		brdcfg |= BRDCFG12_SD4MX_SLOT8;
		QIXIS_WRITE(brdcfg[12], brdcfg);
		break;
	case 10:
	case 12:
	case 14:
	case 16:
	case 18:
		/* 00b, SD4(4:5) => AURORA, SD4(6:7) => SATA */
		brdcfg = QIXIS_READ(brdcfg[12]);
		brdcfg &= ~BRDCFG12_SD4MX_MASK;
		brdcfg |= BRDCFG12_SD4MX_AURO_SATA;
		QIXIS_WRITE(brdcfg[12], brdcfg);
		break;
	default:
		printf("WARNING: unsupported for SerDes4 Protocol %d\n",
		       srds_prtcl_s4);
		return -1;
	}

	return 0;
}

int board_early_init_r(void)
{
	const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
	const u8 flash_esel = find_tlb_idx((void *)flashbase, 1);

	/*
	 * Remap Boot flash + PROMJET 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();

	/* 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);

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

	/* Disable remote I2C connection to qixis fpga */
	QIXIS_WRITE(brdcfg[5], QIXIS_READ(brdcfg[5]) & ~BRDCFG5_IRE);

	/*
	 * Adjust core voltage according to voltage ID
	 * This function changes I2C mux to channel 2.
	 */
	if (adjust_vdd(0))
		printf("Warning: Adjusting core voltage failed.\n");

	/* Configure board SERDES ports crossbar */
	config_frontside_crossbar_vsc3316();
	config_backside_crossbar_mux();
	select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);

	return 0;
}

unsigned long get_board_sys_clk(void)
{
	u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
#ifdef CONFIG_FSL_QIXIS_CLOCK_MEASUREMENT
	/* use accurate clock measurement */
	int freq = QIXIS_READ(clk_freq[0]) << 8 | QIXIS_READ(clk_freq[1]);
	int base = QIXIS_READ(clk_base[0]) << 8 | QIXIS_READ(clk_base[1]);
	u32 val;

	val =  freq * base;
	if (val) {
		debug("SYS Clock measurement is: %d\n", val);
		return val;
	} else {
		printf("Warning: SYS clock measurement is invalid, using value from brdcfg1.\n");
	}
#endif

	switch (sysclk_conf & 0x0F) {
	case QIXIS_SYSCLK_83:
		return 83333333;
	case QIXIS_SYSCLK_100:
		return 100000000;
	case QIXIS_SYSCLK_125:
		return 125000000;
	case QIXIS_SYSCLK_133:
		return 133333333;
	case QIXIS_SYSCLK_150:
		return 150000000;
	case QIXIS_SYSCLK_160:
		return 160000000;
	case QIXIS_SYSCLK_166:
		return 166666666;
	}
	return 66666666;
}

unsigned long get_board_ddr_clk(void)
{
	u8 ddrclk_conf = QIXIS_READ(brdcfg[1]);
#ifdef CONFIG_FSL_QIXIS_CLOCK_MEASUREMENT
	/* use accurate clock measurement */
	int freq = QIXIS_READ(clk_freq[2]) << 8 | QIXIS_READ(clk_freq[3]);
	int base = QIXIS_READ(clk_base[0]) << 8 | QIXIS_READ(clk_base[1]);
	u32 val;

	val =  freq * base;
	if (val) {
		debug("DDR Clock measurement is: %d\n", val);
		return val;
	} else {
		printf("Warning: DDR clock measurement is invalid, using value from brdcfg1.\n");
	}
#endif

	switch ((ddrclk_conf & 0x30) >> 4) {
	case QIXIS_DDRCLK_100:
		return 100000000;
	case QIXIS_DDRCLK_125:
		return 125000000;
	case QIXIS_DDRCLK_133:
		return 133333333;
	}
	return 66666666;
}

static const char *serdes_clock_to_string(u32 clock)
{
	switch (clock) {
	case SRDS_PLLCR0_RFCK_SEL_100:
		return "100";
	case SRDS_PLLCR0_RFCK_SEL_125:
		return "125";
	case SRDS_PLLCR0_RFCK_SEL_156_25:
		return "156.25";
	case SRDS_PLLCR0_RFCK_SEL_161_13:
		return "161.1328125";
	default:
		return "???";
	}
}

int misc_init_r(void)
{
	u8 sw;
	serdes_corenet_t *srds_regs =
		(void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
	u32 actual[MAX_SERDES];
	unsigned int i;

	sw = QIXIS_READ(brdcfg[2]);
	for (i = 0; i < MAX_SERDES; i++) {
		unsigned int clock = (sw >> (6 - 2 * i)) & 3;
		switch (clock) {
		case 0:
			actual[i] = SRDS_PLLCR0_RFCK_SEL_100;
			break;
		case 1:
			actual[i] = SRDS_PLLCR0_RFCK_SEL_125;
			break;
		case 2:
			actual[i] = SRDS_PLLCR0_RFCK_SEL_156_25;
			break;
		case 3:
			actual[i] = SRDS_PLLCR0_RFCK_SEL_161_13;
			break;
		}
	}

	for (i = 0; i < MAX_SERDES; i++) {
		u32 pllcr0 = srds_regs->bank[i].pllcr0;
		u32 expected = pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK;
		if (expected != actual[i]) {
			printf("Warning: SERDES%u expects reference clock %sMHz, but actual is %sMHz\n",
			       i + 1, serdes_clock_to_string(expected),
			       serdes_clock_to_string(actual[i]));
		}
	}

	return 0;
}

void 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
}

/*
 * This function is called by bdinfo to print detail board information.
 * As an exmaple for future board, we organize the messages into
 * several sections. If applicable, the message is in the format of
 * <name>      = <value>
 * It should aligned with normal output of bdinfo command.
 *
 * Voltage: Core, DDR and another configurable voltages
 * Clock  : Critical clocks which are not printed already
 * RCW    : RCW source if not printed already
 * Misc   : Other important information not in above catagories
 */
void board_detail(void)
{
	int i;
	u8 brdcfg[16], dutcfg[16], rst_ctl;
	int vdd, rcwsrc;
	static const char * const clk[] = {"66.67", "100", "125", "133.33"};

	for (i = 0; i < 16; i++) {
		brdcfg[i] = qixis_read(offsetof(struct qixis, brdcfg[0]) + i);
		dutcfg[i] = qixis_read(offsetof(struct qixis, dutcfg[0]) + i);
	}

	/* Voltage secion */
	if (!select_i2c_ch_pca9547(I2C_MUX_CH_VOL_MONITOR)) {
		vdd = read_voltage();
		if (vdd > 0)
			printf("Core voltage= %d mV\n", vdd);
		select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
	}

	printf("XVDD        = 1.%d V\n", ((brdcfg[8] & 0xf) - 4) * 5 + 25);

	/* clock section */
	printf("SYSCLK      = %s MHz\nDDRCLK      = %s MHz\n",
	       clk[(brdcfg[11] >> 2) & 0x3], clk[brdcfg[11] & 3]);

	/* RCW section */
	rcwsrc = (dutcfg[0] << 1) + (dutcfg[1] & 1);
	puts("RCW source  = ");
	switch (rcwsrc) {
	case 0x017:
	case 0x01f:
		puts("8-bit NOR\n");
		break;
	case 0x027:
	case 0x02F:
		puts("16-bit NOR\n");
		break;
	case 0x040:
		puts("SDHC/eMMC\n");
		break;
	case 0x044:
		puts("SPI 16-bit addressing\n");
		break;
	case 0x045:
		puts("SPI 24-bit addressing\n");
		break;
	case 0x048:
		puts("I2C normal addressing\n");
		break;
	case 0x049:
		puts("I2C extended addressing\n");
		break;
	case 0x108:
	case 0x109:
	case 0x10a:
	case 0x10b:
		puts("8-bit NAND, 2KB\n");
		break;
	default:
		if ((rcwsrc >= 0x080) && (rcwsrc <= 0x09f))
			puts("Hard-coded RCW\n");
		else if ((rcwsrc >= 0x110) && (rcwsrc <= 0x11f))
			puts("8-bit NAND, 4KB\n");
		else
			puts("unknown\n");
		break;
	}

	/* Misc section */
	rst_ctl = QIXIS_READ(rst_ctl);
	puts("HRESET_REQ  = ");
	switch (rst_ctl & 0x30) {
	case 0x00:
		puts("Ignored\n");
		break;
	case 0x10:
		puts("Assert HRESET\n");
		break;
	case 0x30:
		puts("Reset system\n");
		break;
	default:
		puts("N/A\n");
		break;
	}
}

/*
 * Reverse engineering switch settings.
 * Some bits cannot be figured out. They will be displayed as
 * underscore in binary format. mask[] has those bits.
 * Some bits are calculated differently than the actual switches
 * if booting with overriding by FPGA.
 */
void qixis_dump_switch(void)
{
	int i;
	u8 sw[9];

	/*
	 * Any bit with 1 means that bit cannot be reverse engineered.
	 * It will be displayed as _ in binary format.
	 */
	static const u8 mask[] = {0, 0, 0, 0, 0, 0x1, 0xcf, 0x3f, 0x1f};
	char buf[10];
	u8 brdcfg[16], dutcfg[16];

	for (i = 0; i < 16; i++) {
		brdcfg[i] = qixis_read(offsetof(struct qixis, brdcfg[0]) + i);
		dutcfg[i] = qixis_read(offsetof(struct qixis, dutcfg[0]) + i);
	}

	sw[0] = dutcfg[0];
	sw[1] = (dutcfg[1] << 0x07)		|
		((dutcfg[12] & 0xC0) >> 1)	|
		((dutcfg[11] & 0xE0) >> 3)	|
		((dutcfg[6] & 0x80) >> 6)	|
		((dutcfg[1] & 0x80) >> 7);
	sw[2] = ((brdcfg[1] & 0x0f) << 4)	|
		((brdcfg[1] & 0x30) >> 2)	|
		((brdcfg[1] & 0x40) >> 5)	|
		((brdcfg[1] & 0x80) >> 7);
	sw[3] = brdcfg[2];
	sw[4] = ((dutcfg[2] & 0x01) << 7)	|
		((dutcfg[2] & 0x06) << 4)	|
		((~QIXIS_READ(present)) & 0x10)	|
		((brdcfg[3] & 0x80) >> 4)	|
		((brdcfg[3] & 0x01) << 2)	|
		((brdcfg[6] == 0x62) ? 3 :
		((brdcfg[6] == 0x5a) ? 2 :
		((brdcfg[6] == 0x5e) ? 1 : 0)));
	sw[5] = ((brdcfg[0] & 0x0f) << 4)	|
		((QIXIS_READ(rst_ctl) & 0x30) >> 2) |
		((brdcfg[0] & 0x40) >> 5);
	sw[6] = (brdcfg[11] & 0x20)		|
		((brdcfg[5] & 0x02) << 3);
	sw[7] = (((~QIXIS_READ(rst_ctl)) & 0x40) << 1) |
		((brdcfg[5] & 0x10) << 2);
	sw[8] = ((brdcfg[12] & 0x08) << 4)	|
		((brdcfg[12] & 0x03) << 5);

	puts("DIP switch (reverse-engineering)\n");
	for (i = 0; i < 9; i++) {
		printf("SW%d         = 0b%s (0x%02x)\n",
		       i + 1, byte_to_binary_mask(sw[i], mask[i], buf), sw[i]);
	}
}

static int do_vdd_adjust(cmd_tbl_t *cmdtp,
			 int flag, int argc,
			 char * const argv[])
{
	ulong override;

	if (argc < 2)
		return CMD_RET_USAGE;
	if (!strict_strtoul(argv[1], 10, &override))
		adjust_vdd(override);	/* the value is checked by callee */
	else
		return CMD_RET_USAGE;

	return 0;
}

U_BOOT_CMD(
	vdd_override, 2, 0, do_vdd_adjust,
	"Override VDD",
	"- override with the voltage specified in mV, eg. 1050"
);
