/*
 * (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 <mxc_gpio.h>
#include <asm/io.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/imx25-pinmux.h>

DECLARE_GLOBAL_DATA_PTR;

int board_init()
{
	struct iomuxc_mux_ctl *muxctl;
	struct iomuxc_pad_ctl *padctl;
	struct iomuxc_pad_input_select *inputselect;
	u32 gpio_mux_mode0_sion = MX25_PIN_MUX_MODE(0) | MX25_PIN_MUX_SION;
	u32 gpio_mux_mode1 = MX25_PIN_MUX_MODE(1);
	u32 gpio_mux_mode5 = MX25_PIN_MUX_MODE(5);
	u32 gpio_mux_mode6 = MX25_PIN_MUX_MODE(6);
	u32 input_select1 = MX25_PAD_INPUT_SELECT_DAISY(1);
	u32 input_select2 = MX25_PAD_INPUT_SELECT_DAISY(2);

	icache_enable();

	muxctl = (struct iomuxc_mux_ctl *)IMX_IOPADMUX_BASE;
	padctl = (struct iomuxc_pad_ctl *)IMX_IOPADCTL_BASE;
	inputselect = (struct iomuxc_pad_input_select *)IMX_IOPADINPUTSEL_BASE;

	/* Setup of core volatage selection pin to run at 1.4V */
	writel(gpio_mux_mode5, &muxctl->pad_ext_armclk); /* VCORE GPIO3[15] */
	mxc_gpio_direction(MXC_GPIO_PORT_TO_NUM(3, 15), MXC_GPIO_DIRECTION_OUT);
	mxc_gpio_set(MXC_GPIO_PORT_TO_NUM(3, 15), 1);

	/* Setup of input daisy chains for SD card pins*/
	writel(gpio_mux_mode0_sion, &muxctl->pad_sd1_cmd);
	writel(gpio_mux_mode0_sion, &muxctl->pad_sd1_clk);
	writel(gpio_mux_mode0_sion, &muxctl->pad_sd1_data0);
	writel(gpio_mux_mode0_sion, &muxctl->pad_sd1_data1);
	writel(gpio_mux_mode0_sion, &muxctl->pad_sd1_data2);
	writel(gpio_mux_mode0_sion, &muxctl->pad_sd1_data3);

	/* Setup of digital output for USB power and OC */
	writel(gpio_mux_mode5, &muxctl->pad_csi_d3); /* USB Power GPIO1[28] */
	mxc_gpio_direction(MXC_GPIO_PORT_TO_NUM(1, 28), MXC_GPIO_DIRECTION_OUT);
	mxc_gpio_set(MXC_GPIO_PORT_TO_NUM(1, 28), 1);

	writel(gpio_mux_mode5, &muxctl->pad_csi_d2); /* USB OC GPIO1[27] */
	mxc_gpio_direction(MXC_GPIO_PORT_TO_NUM(1, 18), MXC_GPIO_DIRECTION_IN);

	/* Setup of digital output control pins */
	writel(gpio_mux_mode5, &muxctl->pad_csi_d8); /* Ouput 1 Ctrl GPIO1[7] */
	writel(gpio_mux_mode5, &muxctl->pad_csi_d7); /* Ouput 2 Ctrl GPIO1[6] */
	writel(gpio_mux_mode5, &muxctl->pad_csi_d6); /* Ouput 1 Stat GPIO1[31]*/
	writel(gpio_mux_mode5, &muxctl->pad_csi_d5); /* Ouput 2 Stat GPIO1[30]*/

	writel(0, &padctl->pad_csi_d6); /* Ouput 1 Stat pull up off */
	writel(0, &padctl->pad_csi_d5); /* Ouput 2 Stat pull up off */

	/* Switch both output drivers off */
	mxc_gpio_set(MXC_GPIO_PORT_TO_NUM(1, 7), 0);
	mxc_gpio_direction(MXC_GPIO_PORT_TO_NUM(1, 7), MXC_GPIO_DIRECTION_OUT);
	mxc_gpio_set(MXC_GPIO_PORT_TO_NUM(1, 6), 0);
	mxc_gpio_direction(MXC_GPIO_PORT_TO_NUM(1, 6), MXC_GPIO_DIRECTION_OUT);

	/* Setup of key input pin GPIO2[29]*/
	writel(gpio_mux_mode5 | MX25_PIN_MUX_SION, &muxctl->pad_kpp_row0);
	writel(0, &padctl->pad_kpp_row0); /* Key pull up off */
	mxc_gpio_direction(MXC_GPIO_PORT_TO_NUM(2, 29), MXC_GPIO_DIRECTION_IN);

	/* Setup of status LED outputs */
	writel(gpio_mux_mode5, &muxctl->pad_csi_d9);	/* GPIO4[21] */
	writel(gpio_mux_mode5, &muxctl->pad_csi_d4);	/* GPIO1[29] */

	/* Switch both LEDs off */
	mxc_gpio_set(MXC_GPIO_PORT_TO_NUM(4, 21), 0);
	mxc_gpio_direction(MXC_GPIO_PORT_TO_NUM(4, 21), MXC_GPIO_DIRECTION_OUT);
	mxc_gpio_set(MXC_GPIO_PORT_TO_NUM(1, 29), 0);
	mxc_gpio_direction(MXC_GPIO_PORT_TO_NUM(1, 29), MXC_GPIO_DIRECTION_OUT);

	/* Setup of CAN1 and CAN2 signals */
	writel(gpio_mux_mode6, &muxctl->pad_gpio_a);	/* CAN1 TX */
	writel(gpio_mux_mode6, &muxctl->pad_gpio_b);	/* CAN1 RX */
	writel(gpio_mux_mode6, &muxctl->pad_gpio_c);	/* CAN2 TX */
	writel(gpio_mux_mode6, &muxctl->pad_gpio_d);	/* CAN2 RX */

	/* Setup of input daisy chains for CAN signals*/
	writel(input_select1, &inputselect->can1_ipp_ind_canrx); /* CAN1 RX */
	writel(input_select1, &inputselect->can2_ipp_ind_canrx); /* CAN2 RX */

	/* Setup of I2C3 signals */
	writel(gpio_mux_mode1, &muxctl->pad_cspi1_ss1);	/* I2C3 SDA */
	writel(gpio_mux_mode1, &muxctl->pad_gpio_e);	/* I2C3 SCL */

	/* Setup of input daisy chains for I2C3 signals*/
	writel(input_select1, &inputselect->i2c3_ipp_sda_in);	/* I2C3 SDA */
	writel(input_select2, &inputselect->i2c3_ipp_scl_in);	/* I2C3 SCL */

	/* board id for linux */
	gd->bd->bi_arch_number = MACH_TYPE_ZMX25;
	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;

	return 0;
}

int board_late_init(void)
{
	const char *e;

#ifdef CONFIG_FEC_MXC
	struct iomuxc_mux_ctl *muxctl;
	struct iomuxc_pad_ctl *padctl;
	u32 gpio_mux_mode2 = MX25_PIN_MUX_MODE(2);
	u32 gpio_mux_mode5 = MX25_PIN_MUX_MODE(5);

	/*
	 * fec pin init is generic
	 */
	mx25_fec_init_pins();

	/*
	 * Set up LAN-RESET and FEC_RX_ERR
	 *
	 * LAN-RESET:  GPIO3[16] is ALT 5 mode of pin U20
	 * FEC_RX_ERR: FEC_RX_ERR is ALT 2 mode of pin R2
	 */
	muxctl = (struct iomuxc_mux_ctl *)IMX_IOPADMUX_BASE;
	padctl = (struct iomuxc_pad_ctl *)IMX_IOPADCTL_BASE;

	writel(gpio_mux_mode5, &muxctl->pad_upll_bypclk);
	writel(gpio_mux_mode2, &muxctl->pad_uart2_cts);

	/* assert PHY reset (low) */
	mxc_gpio_set(MXC_GPIO_PORT_TO_NUM(3, 16), 0);
	mxc_gpio_direction(MXC_GPIO_PORT_TO_NUM(3, 16), MXC_GPIO_DIRECTION_OUT);

	udelay(5000);

	/* deassert PHY reset */
	mxc_gpio_set(MXC_GPIO_PORT_TO_NUM(3, 16), 1);

	udelay(5000);
#endif

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

			if (key) {
				/* Switch on both LEDs to inidcate boot mode */
				mxc_gpio_set(MXC_GPIO_PORT_TO_NUM(1, 29), 0);
				mxc_gpio_set(MXC_GPIO_PORT_TO_NUM(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;
}

void dram_init_banksize(void)
{
	gd->bd->bi_dram[0].start = PHYS_SDRAM;
	gd->bd->bi_dram[0].size = gd->ram_size;
}
