/*
 * (C) Copyright 2011 HALE electronic <helmut.raiger@hale.at>
 * (C) Copyright 2009 Magnus Lilja <lilja.magnus@gmail.com>
 * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
 *
 * 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 <common.h>
#include <netdev.h>
#include <command.h>
#include <pmic.h>
#include <asm/arch/clock.h>
#include <asm/arch/sys_proto.h>
#include <asm/io.h>

DECLARE_GLOBAL_DATA_PTR;

#define BOARD_STRING	"Board: HALE TT-01"

/* Clock configuration */
#define CCM_CCMR_SETUP		0x074B0BF5

static void board_setup_clocks(void)
{
	struct clock_control_regs *ccm = (struct clock_control_regs *) CCM_BASE;
	volatile int wait = 0x10000;

	writel(CCM_CCMR_SETUP, &ccm->ccmr);
	while (wait--)
		;

	writel(CCM_CCMR_SETUP | CCMR_MPE, &ccm->ccmr);
	writel((CCM_CCMR_SETUP | CCMR_MPE) & ~CCMR_MDS, &ccm->ccmr);

	/* Set up clock to 532MHz */
	writel(PDR0_CSI_PODF(0x1ff) | PDR0_PER_PODF(7) |
			PDR0_HSP_PODF(3) | PDR0_NFC_PODF(5) |
			PDR0_IPG_PODF(1) | PDR0_MAX_PODF(3) |
			PDR0_MCU_PODF(0), &ccm->pdr0);
	writel(PLL_PD(0) | PLL_MFD(51) | PLL_MFI(10) | PLL_MFN(12),
			&ccm->mpctl);
	writel(PLL_PD(1) | PLL_MFD(4) | PLL_MFI(12) | PLL_MFN(1),
			&ccm->spctl);
}

/* DRAM configuration */

#define ESDMISC_MDDR_SETUP	0x00000004
#define ESDMISC_MDDR_RESET_DL	0x0000000c
/*
 * decoding magic 0x6ac73a = 0b 0110 1010   1100 0111   0011 1010 below:
 *   tXP = 11, tWTR = 0, tRP = 10, tMRD = 10
 *   tWR = 1, tRAS = 100, tRRD = 01, tCAS = 11
 *   tRCD = 011, tRC = 010
 *  note: all but tWTR (1), tRC (111) are reset defaults,
 *     the same values work in the jtag configuration
 *
 *  Bluetechnix setup has 0x75e73a (for 128MB) =
 *			0b 0111 0101   1110 0111   0011 1010
 *   tXP = 11, tWTR = 1, tRP = 01, tMRD = 01
 *   tWR = 1, tRAS = 110, tRRD = 01, tCAS = 11
 *   tRCD = 011, tRC = 010
 */
#define ESDCFG0_MDDR_SETUP	0x006ac73a
#define ESDCTL_ROW_COL		(ESDCTL_SDE | ESDCTL_ROW(2) | ESDCTL_COL(2))
#define ESDCTL_SETTINGS		(ESDCTL_ROW_COL | ESDCTL_SREFR(3) | \
				 ESDCTL_DSIZ(2) | ESDCTL_BL(1))
#define ESDCTL_PRECHARGE	(ESDCTL_ROW_COL | ESDCTL_CMD_PRECHARGE)
#define ESDCTL_AUTOREFRESH	(ESDCTL_ROW_COL | ESDCTL_CMD_AUTOREFRESH)
#define ESDCTL_LOADMODEREG	(ESDCTL_ROW_COL | ESDCTL_CMD_LOADMODEREG)
#define ESDCTL_RW		ESDCTL_SETTINGS

static void board_setup_sdram(void)
{
	u32 *pad;
	struct esdc_regs *esdc = (struct esdc_regs *)ESDCTL_BASE_ADDR;

	/*
	 * setup pad control for the controller pins
	 * no loopback, no pull, no keeper, no open drain,
	 * standard input, standard drive, slow slew rate
	 */
	for (pad = (u32 *) IOMUXC_SW_PAD_CTL_SDCKE1_SDCLK_SDCLK_B;
			pad <= (u32 *) IOMUXC_SW_PAD_CTL_VPG0_VPG1_A0; pad++)
		*pad = 0;

	/* set up MX31 DDR Memory Controller */
	writel(ESDMISC_MDDR_SETUP, &esdc->misc);
	writel(ESDCFG0_MDDR_SETUP, &esdc->cfg0);

	/* perform DDR init sequence for CSD0 */
	writel(ESDCTL_PRECHARGE, &esdc->ctl0);
	writel(0x12344321, CSD0_BASE+0x0f00);
	writel(ESDCTL_AUTOREFRESH, &esdc->ctl0);
	writel(0x12344321, CSD0_BASE);
	writel(0x12344321, CSD0_BASE);
	writel(ESDCTL_LOADMODEREG, &esdc->ctl0);
	writeb(0xda, CSD0_BASE+0x33);
	writeb(0xff, CSD0_BASE+0x1000000);
	writel(ESDCTL_RW, &esdc->ctl0);
	writel(0xDEADBEEF, CSD0_BASE);
	writel(ESDMISC_MDDR_RESET_DL, &esdc->misc);
}

static void tt01_spi3_hw_init(void)
{
	/* CSPI3 */
	mx31_gpio_mux(IOMUX_MODE(MUX_CTL_CSPI3_MISO, MUX_CTL_FUNC));
	mx31_gpio_mux(IOMUX_MODE(MUX_CTL_CSPI3_MOSI, MUX_CTL_FUNC));
	mx31_gpio_mux(IOMUX_MODE(MUX_CTL_CSPI3_SCLK, MUX_CTL_FUNC));
	/* CSPI3, SS0 = Atlas */
	mx31_gpio_mux(IOMUX_MODE(MUX_CTL_CSPI2_SS0, MUX_CTL_ALT1));

	/* start CSPI3 clock (3 = always on except if PLL off) */
	setbits_le32(CCM_CGR0, 3 << 16);
}

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

int board_early_init_f(void)
{
	/* CS4: FPGA incl. network controller */
	struct mxc_weimcs cs4 = {
		/*    sp wp bcd bcs psz pme sync dol cnc wsc ew wws edc */
		CSCR_U(0, 0,  0,  0,  0,  0,   0,  0,  3, 28, 1,  7,  6),
		/*   oea oen ebwa ebwn csa ebc dsz csn psr cre wrap csen */
		CSCR_L(4,  4,   4,  10,  4,  0,  5,  4,  0,  0,   0,   1),
		/*  ebra ebrn rwa rwn mum lah lbn lba dww dct wwu age cnc2 fce*/
		CSCR_A(4,   4,  4,  4,  0,  1,  4,  3,  0,  0,  0,  0,  1,   0)
	};

	/* this seems essential, won't start without, but why? */
	writel(IPU_CONF_DI_EN, (u32 *) IPU_CONF);

	board_setup_clocks();
	board_setup_sdram();
	mxc_setup_weimcs(4, &cs4);

	/* Setup UART2 and SPI3 pins */
	mx31_uart2_hw_init();
	tt01_spi3_hw_init();

	return 0;
}

int board_init(void)
{
	/* address of boot parameters */
	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
	return 0;
}

int board_late_init(void)
{
	pmic_init();

#ifdef CONFIG_HW_WATCHDOG
	mxc_hw_watchdog_enable();
#endif

	return 0;
}

int checkboard(void)
{
	puts(BOARD_STRING "\n");
	return 0;
}

int board_eth_init(bd_t *bis)
{
	int rc = 0;
#ifdef CONFIG_SMC911X
	rc = smc911x_initialize(0, CONFIG_SMC911X_BASE);
#endif
	return rc;
}
