/*
 * (C) Copyright 2013
 * Gumstix Inc. <www.gumstix.com>
 * Maintainer: Ash Charles  <ash@gumstix.com>
 *
 * SPDX-License-Identifier:     GPL-2.0+
 */
#include <common.h>
#include <netdev.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/mmc_host_def.h>
#include <twl6030.h>
#include <asm/emif.h>
#include <asm/arch/clock.h>
#include <asm/arch/gpio.h>
#include <asm/gpio.h>

#include "duovero_mux_data.h"

#define WIFI_EN	43

#if defined(CONFIG_CMD_NET)
#define SMSC_NRESET	45
static void setup_net_chip(void);
#endif

#ifdef CONFIG_USB_EHCI
#include <usb.h>
#include <asm/arch/ehci.h>
#include <asm/ehci-omap.h>
#endif

DECLARE_GLOBAL_DATA_PTR;

const struct omap_sysinfo sysinfo = {
	"Board: duovero\n"
};

struct omap4_scrm_regs *const scrm = (struct omap4_scrm_regs *)0x4a30a000;

/**
 * @brief board_init
 *
 * @return 0
 */
int board_init(void)
{
	gpmc_init();

	gd->bd->bi_arch_number = MACH_TYPE_OMAP4_DUOVERO;
	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;

	return 0;
}

/**
 * @brief misc_init_r - Configure board specific configurations
 * such as power configurations, ethernet initialization as phase2 of
 * boot sequence
 *
 * @return 0
 */
int misc_init_r(void)
{
	int ret = 0;
	u8 val;

	/* wifi setup: first enable 32Khz clock from 6030 pmic */
	val = 0xe1;
	ret = i2c_write(TWL6030_CHIP_PM, 0xbe, 1, &val, 1);
	if (ret)
		printf("Failed to enable 32Khz clock to wifi module\n");

	/* then setup WIFI_EN as an output pin and send reset pulse */
	if (!gpio_request(WIFI_EN, "")) {
		gpio_direction_output(WIFI_EN, 0);
		gpio_set_value(WIFI_EN, 1);
		udelay(1);
		gpio_set_value(WIFI_EN, 0);
		udelay(1);
		gpio_set_value(WIFI_EN, 1);
	}

#if defined(CONFIG_CMD_NET)
	setup_net_chip();
#endif
	return 0;
}

void set_muxconf_regs(void)
{
	do_set_mux((*ctrl)->control_padconf_core_base,
		   core_padconf_array_essential,
		   sizeof(core_padconf_array_essential) /
		   sizeof(struct pad_conf_entry));

	do_set_mux((*ctrl)->control_padconf_wkup_base,
		   wkup_padconf_array_essential,
		   sizeof(wkup_padconf_array_essential) /
		   sizeof(struct pad_conf_entry));

	do_set_mux((*ctrl)->control_padconf_core_base,
		   core_padconf_array_non_essential,
		   sizeof(core_padconf_array_non_essential) /
		   sizeof(struct pad_conf_entry));

	do_set_mux((*ctrl)->control_padconf_wkup_base,
		   wkup_padconf_array_non_essential,
		   sizeof(wkup_padconf_array_non_essential) /
		   sizeof(struct pad_conf_entry));
}

#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_GENERIC_MMC)
int board_mmc_init(bd_t *bis)
{
	return omap_mmc_init(0, 0, 0, -1, -1);
}

void board_mmc_power_init(void)
{
	twl6030_power_mmc_init(0);
}
#endif

#if defined(CONFIG_CMD_NET)

#define GPMC_SIZE_16M	0xF
#define GPMC_BASEADDR_MASK	0x3F
#define GPMC_CS_ENABLE		0x1

static void enable_gpmc_net_config(const u32 *gpmc_config, struct gpmc_cs *cs,
		u32 base, u32 size)
{
	writel(0, &cs->config7);
	sdelay(1000);
	/* Delay for settling */
	writel(gpmc_config[0], &cs->config1);
	writel(gpmc_config[1], &cs->config2);
	writel(gpmc_config[2], &cs->config3);
	writel(gpmc_config[3], &cs->config4);
	writel(gpmc_config[4], &cs->config5);
	writel(gpmc_config[5], &cs->config6);

	/*
	 * Enable the config.  size is the CS size and goes in
	 * bits 11:8.  We set bit 6 to enable this CS and the base
	 * address goes into bits 5:0.
	 */
	writel((size << 8) | (GPMC_CS_ENABLE << 6) |
				 ((base >> 24) & GPMC_BASEADDR_MASK),
				 &cs->config7);

	sdelay(2000);
}

/* GPMC CS configuration for an SMSC LAN9221 ethernet controller */
#define NET_LAN9221_GPMC_CONFIG1    0x2a001203
#define NET_LAN9221_GPMC_CONFIG2    0x000a0a02
#define NET_LAN9221_GPMC_CONFIG3    0x00020200
#define NET_LAN9221_GPMC_CONFIG4    0x0a030a03
#define NET_LAN9221_GPMC_CONFIG5    0x000a0a0a
#define NET_LAN9221_GPMC_CONFIG6    0x8a070707
#define NET_LAN9221_GPMC_CONFIG7    0x00000f6c

/* GPMC definitions for LAN9221 chips on expansion boards */
static const u32 gpmc_lan_config[] = {
	NET_LAN9221_GPMC_CONFIG1,
	NET_LAN9221_GPMC_CONFIG2,
	NET_LAN9221_GPMC_CONFIG3,
	NET_LAN9221_GPMC_CONFIG4,
	NET_LAN9221_GPMC_CONFIG5,
	NET_LAN9221_GPMC_CONFIG6,
	/*CONFIG7- computed as params */
};

/*
 * Routine: setup_net_chip
 * Description: Setting up the configuration GPMC registers specific to the
 *	      Ethernet hardware.
 */
static void setup_net_chip(void)
{
	enable_gpmc_net_config(gpmc_lan_config, &gpmc_cfg->cs[5], 0x2C000000,
			      GPMC_SIZE_16M);

	/* Make GPIO SMSC_NRESET as output pin and send reset pulse */
	if (!gpio_request(SMSC_NRESET, "")) {
		gpio_direction_output(SMSC_NRESET, 0);
		gpio_set_value(SMSC_NRESET, 1);
		udelay(1);
		gpio_set_value(SMSC_NRESET, 0);
		udelay(1);
		gpio_set_value(SMSC_NRESET, 1);
	}
}
#endif

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

#ifdef CONFIG_USB_EHCI

static struct omap_usbhs_board_data usbhs_bdata = {
	.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
	.port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
	.port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
};

int ehci_hcd_init(int index, enum usb_init_type init,
		struct ehci_hccr **hccr, struct ehci_hcor **hcor)
{
	int ret;
	unsigned int utmi_clk;
	u32 auxclk, altclksrc;

	/* Now we can enable our port clocks */
	utmi_clk = readl((void *)CM_L3INIT_HSUSBHOST_CLKCTRL);
	utmi_clk |= HSUSBHOST_CLKCTRL_CLKSEL_UTMI_P1_MASK;
	setbits_le32((void *)CM_L3INIT_HSUSBHOST_CLKCTRL, utmi_clk);

	auxclk = readl(&scrm->auxclk3);
	/* Select sys_clk */
	auxclk &= ~AUXCLK_SRCSELECT_MASK;
	auxclk |=  AUXCLK_SRCSELECT_SYS_CLK << AUXCLK_SRCSELECT_SHIFT;
	/* Set the divisor to 2 */
	auxclk &= ~AUXCLK_CLKDIV_MASK;
	auxclk |= AUXCLK_CLKDIV_2 << AUXCLK_CLKDIV_SHIFT;
	/* Request auxilary clock #3 */
	auxclk |= AUXCLK_ENABLE_MASK;
	writel(auxclk, &scrm->auxclk3);

	altclksrc = readl(&scrm->altclksrc);

	/* Activate alternate system clock supplier */
	altclksrc &= ~ALTCLKSRC_MODE_MASK;
	altclksrc |= ALTCLKSRC_MODE_ACTIVE;

	/* enable clocks */
	altclksrc |= ALTCLKSRC_ENABLE_INT_MASK | ALTCLKSRC_ENABLE_EXT_MASK;

	writel(altclksrc, &scrm->altclksrc);

	ret = omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor);
	if (ret < 0)
		return ret;

	return 0;
}

int ehci_hcd_stop(int index)
{
	return omap_ehci_hcd_stop();
}
#endif

/*
 * get_board_rev() - get board revision
 */
u32 get_board_rev(void)
{
	return 0x20;
}
