/*
 * (c) 2011 Graf-Syteco, Matthias Weisser
 * <weisserm@arcor.de>
 *
 * Based on tx25.c:
 * (C) Copyright 2009 DENX Software Engineering
 * Author: John Rigby <jrigby@gmail.com>
 *
 * Based on imx27lite.c:
 *   Copyright (C) 2008,2009 Eric Jarrige <jorasse@users.sourceforge.net>
 *   Copyright (C) 2009 Ilya Yanok <yanok@emcraft.com>
 * And:
 *   RedBoot tx25_misc.c Copyright (C) 2009 Red Hat
 *
 * 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 <common.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/iomux-mx25.h>

DECLARE_GLOBAL_DATA_PTR;

int board_init()
{
	static const iomux_v3_cfg_t sdhc1_pads[] = {
		NEW_PAD_CTRL(MX25_PAD_SD1_CMD__SD1_CMD, NO_PAD_CTRL),
		NEW_PAD_CTRL(MX25_PAD_SD1_CLK__SD1_CLK, NO_PAD_CTRL),
		NEW_PAD_CTRL(MX25_PAD_SD1_DATA0__SD1_DATA0, NO_PAD_CTRL),
		NEW_PAD_CTRL(MX25_PAD_SD1_DATA1__SD1_DATA1, NO_PAD_CTRL),
		NEW_PAD_CTRL(MX25_PAD_SD1_DATA2__SD1_DATA2, NO_PAD_CTRL),
		NEW_PAD_CTRL(MX25_PAD_SD1_DATA3__SD1_DATA3, NO_PAD_CTRL),
	};

	static const iomux_v3_cfg_t dig_out_pads[] = {
		MX25_PAD_CSI_D8__GPIO_1_7, /* Ouput 1 Ctrl */
		MX25_PAD_CSI_D7__GPIO_1_6, /* Ouput 2 Ctrl */
		NEW_PAD_CTRL(MX25_PAD_CSI_D6__GPIO_1_31, 0), /* Ouput 1 Stat */
		NEW_PAD_CTRL(MX25_PAD_CSI_D5__GPIO_1_30, 0), /* Ouput 2 Stat */
	};

	static const iomux_v3_cfg_t led_pads[] = {
		MX25_PAD_CSI_D9__GPIO_4_21,
		MX25_PAD_CSI_D4__GPIO_1_29,
	};

	static const iomux_v3_cfg_t can_pads[] = {
		NEW_PAD_CTRL(MX25_PAD_GPIO_A__CAN1_TX, NO_PAD_CTRL),
		NEW_PAD_CTRL(MX25_PAD_GPIO_B__CAN1_RX, NO_PAD_CTRL),
		NEW_PAD_CTRL(MX25_PAD_GPIO_C__CAN2_TX, NO_PAD_CTRL),
		NEW_PAD_CTRL(MX25_PAD_GPIO_D__CAN2_RX, NO_PAD_CTRL),
	};

	static const iomux_v3_cfg_t i2c3_pads[] = {
		MX25_PAD_CSPI1_SS1__I2C3_DAT,
		MX25_PAD_GPIO_E__I2C3_CLK,
	};

	icache_enable();

	/* Setup of core voltage selection pin to run at 1.4V */
	imx_iomux_v3_setup_pad(MX25_PAD_EXT_ARMCLK__GPIO_3_15); /* VCORE */
	gpio_direction_output(IMX_GPIO_NR(3, 15), 1);

	/* Setup of SD card pins*/
	imx_iomux_v3_setup_multiple_pads(sdhc1_pads, ARRAY_SIZE(sdhc1_pads));

	/* Setup of digital output for USB power and OC */
	imx_iomux_v3_setup_pad(MX25_PAD_CSI_D3__GPIO_1_28); /* USB Power */
	gpio_direction_output(IMX_GPIO_NR(1, 28), 1);

	imx_iomux_v3_setup_pad(MX25_PAD_CSI_D2__GPIO_1_27); /* USB OC */
	gpio_direction_input(IMX_GPIO_NR(1, 18));

	/* Setup of digital output control pins */
	imx_iomux_v3_setup_multiple_pads(dig_out_pads,
						ARRAY_SIZE(dig_out_pads));

	/* Switch both output drivers off */
	gpio_direction_output(IMX_GPIO_NR(1, 7), 0);
	gpio_direction_output(IMX_GPIO_NR(1, 6), 0);

	/* Setup of key input pin */
	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX25_PAD_KPP_ROW0__GPIO_2_29, 0));
	gpio_direction_input(IMX_GPIO_NR(2, 29));

	/* Setup of status LED outputs */
	imx_iomux_v3_setup_multiple_pads(led_pads, ARRAY_SIZE(led_pads));

	/* Switch both LEDs off */
	gpio_direction_output(IMX_GPIO_NR(4, 21), 0);
	gpio_direction_output(IMX_GPIO_NR(1, 29), 0);

	/* Setup of CAN1 and CAN2 signals */
	imx_iomux_v3_setup_multiple_pads(can_pads, ARRAY_SIZE(can_pads));

	/* Setup of I2C3 signals */
	imx_iomux_v3_setup_multiple_pads(i2c3_pads, ARRAY_SIZE(i2c3_pads));

	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;

	return 0;
}

int board_late_init(void)
{
	const char *e;

#ifdef CONFIG_FEC_MXC
/*
 * FIXME: need to revisit this
 * The original code enabled PUE and 100-k pull-down without PKE, so the right
 * value here is likely:
 *	0 for no pull
 * or:
 *	PAD_CTL_PUS_100K_DOWN for 100-k pull-down
 */
#define FEC_OUT_PAD_CTRL	0

	static const iomux_v3_cfg_t fec_pads[] = {
		MX25_PAD_FEC_TX_CLK__FEC_TX_CLK,
		MX25_PAD_FEC_RX_DV__FEC_RX_DV,
		MX25_PAD_FEC_RDATA0__FEC_RDATA0,
		NEW_PAD_CTRL(MX25_PAD_FEC_TDATA0__FEC_TDATA0, FEC_OUT_PAD_CTRL),
		NEW_PAD_CTRL(MX25_PAD_FEC_TX_EN__FEC_TX_EN, FEC_OUT_PAD_CTRL),
		NEW_PAD_CTRL(MX25_PAD_FEC_MDC__FEC_MDC, FEC_OUT_PAD_CTRL),
		MX25_PAD_FEC_MDIO__FEC_MDIO,
		MX25_PAD_FEC_RDATA1__FEC_RDATA1,
		NEW_PAD_CTRL(MX25_PAD_FEC_TDATA1__FEC_TDATA1, FEC_OUT_PAD_CTRL),

		MX25_PAD_UPLL_BYPCLK__GPIO_3_16, /* LAN-RESET */
		MX25_PAD_UART2_CTS__FEC_RX_ER, /* FEC_RX_ERR */
	};

	imx_iomux_v3_setup_multiple_pads(fec_pads, ARRAY_SIZE(fec_pads));

	/* assert PHY reset (low) */
	gpio_direction_output(IMX_GPIO_NR(3, 16), 0);

	udelay(5000);

	/* deassert PHY reset */
	gpio_set_value(IMX_GPIO_NR(3, 16), 1);

	udelay(5000);
#endif

	e = getenv("gs_base_board");
	if (e != NULL) {
		if (strcmp(e, "G283") == 0) {
			int key = gpio_get_value(IMX_GPIO_NR(2, 29));

			if (key) {
				/* Switch on both LEDs to inidcate boot mode */
				gpio_set_value(IMX_GPIO_NR(1, 29), 0);
				gpio_set_value(IMX_GPIO_NR(4, 21), 0);

				setenv("preboot", "run gs_slow_boot");
			} else
				setenv("preboot", "run gs_fast_boot");
		}
	}

	return 0;
}

int dram_init(void)
{
	/* dram_init must store complete ramsize in gd->ram_size */
	gd->ram_size = get_ram_size((void *)PHYS_SDRAM,
				PHYS_SDRAM_SIZE);
	return 0;
}
