/*
 * Copyright (C) 2008-2013 Eric Jarrige <eric.jarrige@armadeus.org>
 *
 * based on the files by
 * Sascha Hauer, Pengutronix
 *
 * SPDX-License-Identifier:    GPL-2.0+
 */

#include <common.h>
#include <environment.h>
#include <jffs2/jffs2.h>
#include <nand.h>
#include <netdev.h>
#include <asm/io.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/gpio.h>
#include <asm/gpio.h>
#include <linux/errno.h>
#include "apf27.h"
#include "crc.h"
#include "fpga.h"

DECLARE_GLOBAL_DATA_PTR;

/*
 * Fuse bank 1 row 8 is "reserved for future use" and therefore available for
 * customer use. The APF27 board uses this fuse to store the board revision:
 * 0: initial board revision
 * 1: first revision - Presence of the second RAM chip on the board is blown in
 *     fuse bank 1 row 9  bit 0 - No hardware change
 * N: to be defined
 */
static u32 get_board_rev(void)
{
	struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;

	return readl(&iim->bank[1].fuse_regs[8]);
}

/*
 * Fuse bank 1 row 9 is "reserved for future use" and therefore available for
 * customer use. The APF27 board revision 1 uses the bit 0 to permanently store
 * the presence of the second RAM chip
 * 0: AFP27 with 1 RAM of 64 MiB
 * 1: AFP27 with 2 RAM chips of 64 MiB each (128MB)
 */
static int get_num_ram_bank(void)
{
	struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
	int nr_dram_banks = 1;

	if ((get_board_rev() > 0) && (CONFIG_NR_DRAM_BANKS > 1))
		nr_dram_banks += readl(&iim->bank[1].fuse_regs[9]) & 0x01;
	else
		nr_dram_banks = CONFIG_NR_DRAM_POPULATED;

	return nr_dram_banks;
}

static void apf27_port_init(int port, u32 gpio_dr, u32 ocr1, u32 ocr2,
			    u32 iconfa1, u32 iconfa2, u32 iconfb1, u32 iconfb2,
			    u32 icr1, u32 icr2, u32 imr, u32 gpio_dir, u32 gpr,
			    u32 puen, u32 gius)
{
	struct gpio_port_regs *regs = (struct gpio_port_regs *)IMX_GPIO_BASE;

	writel(gpio_dr,   &regs->port[port].gpio_dr);
	writel(ocr1,      &regs->port[port].ocr1);
	writel(ocr2,      &regs->port[port].ocr2);
	writel(iconfa1,   &regs->port[port].iconfa1);
	writel(iconfa2,   &regs->port[port].iconfa2);
	writel(iconfb1,   &regs->port[port].iconfb1);
	writel(iconfb2,   &regs->port[port].iconfb2);
	writel(icr1,      &regs->port[port].icr1);
	writel(icr2,      &regs->port[port].icr2);
	writel(imr,       &regs->port[port].imr);
	writel(gpio_dir,  &regs->port[port].gpio_dir);
	writel(gpr,       &regs->port[port].gpr);
	writel(puen,      &regs->port[port].puen);
	writel(gius,      &regs->port[port].gius);
}

#define APF27_PORT_INIT(n) apf27_port_init(PORT##n, ACFG_DR_##n##_VAL,	  \
	ACFG_OCR1_##n##_VAL, ACFG_OCR2_##n##_VAL, ACFG_ICFA1_##n##_VAL,	  \
	ACFG_ICFA2_##n##_VAL, ACFG_ICFB1_##n##_VAL, ACFG_ICFB2_##n##_VAL, \
	ACFG_ICR1_##n##_VAL, ACFG_ICR2_##n##_VAL, ACFG_IMR_##n##_VAL,	  \
	ACFG_DDIR_##n##_VAL, ACFG_GPR_##n##_VAL, ACFG_PUEN_##n##_VAL,	  \
	ACFG_GIUS_##n##_VAL)

static void apf27_iomux_init(void)
{
	APF27_PORT_INIT(A);
	APF27_PORT_INIT(B);
	APF27_PORT_INIT(C);
	APF27_PORT_INIT(D);
	APF27_PORT_INIT(E);
	APF27_PORT_INIT(F);
}

static int apf27_devices_init(void)
{
	int i;
	unsigned int mode[] = {
		PC5_PF_I2C2_DATA,
		PC6_PF_I2C2_CLK,
		PD17_PF_I2C_DATA,
		PD18_PF_I2C_CLK,
	};

	for (i = 0; i < ARRAY_SIZE(mode); i++)
		imx_gpio_mode(mode[i]);

#ifdef CONFIG_MXC_UART
	mx27_uart1_init_pins();
#endif

#ifdef CONFIG_FEC_MXC
	mx27_fec_init_pins();
#endif

#ifdef CONFIG_MMC_MXC
	mx27_sd2_init_pins();
	imx_gpio_mode((GPIO_PORTF | GPIO_OUT | GPIO_PUEN | GPIO_GPIO | 16));
	gpio_request(PC_PWRON, "pc_pwron");
	gpio_set_value(PC_PWRON, 1);
#endif
	return 0;
}

static void apf27_setup_csx(void)
{
	struct weim_regs *weim = (struct weim_regs *)IMX_WEIM_BASE;

	writel(ACFG_CS0U_VAL, &weim->cs0u);
	writel(ACFG_CS0L_VAL, &weim->cs0l);
	writel(ACFG_CS0A_VAL, &weim->cs0a);

	writel(ACFG_CS1U_VAL, &weim->cs1u);
	writel(ACFG_CS1L_VAL, &weim->cs1l);
	writel(ACFG_CS1A_VAL, &weim->cs1a);

	writel(ACFG_CS2U_VAL, &weim->cs2u);
	writel(ACFG_CS2L_VAL, &weim->cs2l);
	writel(ACFG_CS2A_VAL, &weim->cs2a);

	writel(ACFG_CS3U_VAL, &weim->cs3u);
	writel(ACFG_CS3L_VAL, &weim->cs3l);
	writel(ACFG_CS3A_VAL, &weim->cs3a);

	writel(ACFG_CS4U_VAL, &weim->cs4u);
	writel(ACFG_CS4L_VAL, &weim->cs4l);
	writel(ACFG_CS4A_VAL, &weim->cs4a);

	writel(ACFG_CS5U_VAL, &weim->cs5u);
	writel(ACFG_CS5L_VAL, &weim->cs5l);
	writel(ACFG_CS5A_VAL, &weim->cs5a);

	writel(ACFG_EIM_VAL, &weim->eim);
}

static void apf27_setup_port(void)
{
	struct system_control_regs *system =
		(struct system_control_regs *)IMX_SYSTEM_CTL_BASE;

	writel(ACFG_FMCR_VAL, &system->fmcr);
}

int board_init(void)
{
	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;

	apf27_setup_csx();
	apf27_setup_port();
	apf27_iomux_init();
	apf27_devices_init();
#if defined(CONFIG_FPGA)
	APF27_init_fpga();
#endif


	return 0;
}

int dram_init(void)
{
	gd->ram_size = get_ram_size((void *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
	if (get_num_ram_bank() > 1)
		gd->ram_size += get_ram_size((void *)PHYS_SDRAM_2,
					     PHYS_SDRAM_2_SIZE);

	return 0;
}

void dram_init_banksize(void)
{
	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
	gd->bd->bi_dram[0].size  = get_ram_size((void *)PHYS_SDRAM_1,
						PHYS_SDRAM_1_SIZE);
	gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
	if (get_num_ram_bank() > 1)
		gd->bd->bi_dram[1].size = get_ram_size((void *)PHYS_SDRAM_2,
					     PHYS_SDRAM_2_SIZE);
	else
		gd->bd->bi_dram[1].size = 0;
}

ulong board_get_usable_ram_top(ulong total_size)
{
	ulong ramtop;

	if (get_num_ram_bank() > 1)
		ramtop = PHYS_SDRAM_2 + get_ram_size((void *)PHYS_SDRAM_2,
						     PHYS_SDRAM_2_SIZE);
	else
		ramtop = PHYS_SDRAM_1 + get_ram_size((void *)PHYS_SDRAM_1,
						     PHYS_SDRAM_1_SIZE);

	return ramtop;
}

int checkboard(void)
{
	printf("Board: Armadeus APF27 revision %d\n", get_board_rev());
	return 0;
}

#ifdef CONFIG_SPL_BUILD
inline void hang(void)
{
	for (;;)
		;
}

void board_init_f(ulong bootflag)
{
	/*
	 * copy ourselves from where we are running to where we were
	 * linked at. Use ulong pointers as all addresses involved
	 * are 4-byte-aligned.
	 */
	ulong *start_ptr, *end_ptr, *link_ptr, *run_ptr, *dst;
	asm volatile ("ldr %0, =_start" : "=r"(start_ptr));
	asm volatile ("ldr %0, =_end" : "=r"(end_ptr));
	asm volatile ("ldr %0, =board_init_f" : "=r"(link_ptr));
	asm volatile ("adr %0, board_init_f" : "=r"(run_ptr));
	for (dst = start_ptr; dst < end_ptr; dst++)
		*dst = *(dst+(run_ptr-link_ptr));

	/*
	 * branch to nand_boot's link-time address.
	 */
	asm volatile("ldr pc, =nand_boot");
}
#endif /* CONFIG_SPL_BUILD */
