/*
 * Copyright (C) 2011
 * Stefano Babic, DENX Software Engineering, sbabic@denx.de.
 *
 * Copyright (C) 2009 TechNexion Ltd.
 *
 * 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.
 */

#include <common.h>
#include <netdev.h>
#include <malloc.h>
#include <fpga.h>
#include <video_fb.h>
#include <asm/io.h>
#include <asm/arch/mem.h>
#include <asm/arch/mux.h>
#include <asm/arch/sys_proto.h>
#include <asm/omap_gpio.h>
#include <asm/arch/mmc_host_def.h>
#include <asm/arch/dss.h>
#include <asm/arch/clocks.h>
#include <i2c.h>
#include <spartan3.h>
#include <asm/gpio.h>
#ifdef CONFIG_USB_EHCI
#include <usb.h>
#include <asm/ehci-omap.h>
#endif
#include "mt_ventoux.h"

DECLARE_GLOBAL_DATA_PTR;

#define BUZZER		140
#define SPEAKER		141
#define USB1_PWR	127
#define USB2_PWR	149

#ifndef CONFIG_FPGA
#error "The Teejet mt_ventoux must have CONFIG_FPGA enabled"
#endif

#define FPGA_RESET	62
#define FPGA_PROG	116
#define FPGA_CCLK	117
#define FPGA_DIN	118
#define FPGA_INIT	119
#define FPGA_DONE	154

#define LCD_PWR		138
#define LCD_PON_PIN	139

#if defined(CONFIG_VIDEO) && !defined(CONFIG_SPL_BUILD)
static struct {
	u32 xres;
	u32 yres;
} panel_resolution[] = {
	{ 480, 272 },
	{ 800, 480 }
};

static struct panel_config lcd_cfg[] = {
	{
	.timing_h       = PANEL_TIMING_H(4, 8, 41),
	.timing_v       = PANEL_TIMING_V(2, 4, 10),
	.pol_freq       = 0x00000000, /* Pol Freq */
	.divisor        = 0x0001000d, /* 33Mhz Pixel Clock */
	.panel_type     = 0x01, /* TFT */
	.data_lines     = 0x03, /* 24 Bit RGB */
	.load_mode      = 0x02, /* Frame Mode */
	.panel_color	= 0,
	},
	{
	.timing_h       = PANEL_TIMING_H(20, 192, 4),
	.timing_v       = PANEL_TIMING_V(2, 20, 10),
	.pol_freq       = 0x00004000, /* Pol Freq */
	.divisor        = 0x0001000E, /* 36Mhz Pixel Clock */
	.panel_type     = 0x01, /* TFT */
	.data_lines     = 0x03, /* 24 Bit RGB */
	.load_mode      = 0x02, /* Frame Mode */
	.panel_color	= 0,
	}
};
#endif

/* Timing definitions for FPGA */
static const u32 gpmc_fpga[] = {
	FPGA_GPMC_CONFIG1,
	FPGA_GPMC_CONFIG2,
	FPGA_GPMC_CONFIG3,
	FPGA_GPMC_CONFIG4,
	FPGA_GPMC_CONFIG5,
	FPGA_GPMC_CONFIG6,
};

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

int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
{
	return omap_ehci_hcd_init(&usbhs_bdata, hccr, hcor);
}

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


static inline void fpga_reset(int nassert)
{
	gpio_set_value(FPGA_RESET, !nassert);
}

int fpga_pgm_fn(int nassert, int nflush, int cookie)
{
	debug("%s:%d: FPGA PROGRAM ", __func__, __LINE__);

	gpio_set_value(FPGA_PROG, !nassert);

	return nassert;
}

int fpga_init_fn(int cookie)
{
	return !gpio_get_value(FPGA_INIT);
}

int fpga_done_fn(int cookie)
{
	return gpio_get_value(FPGA_DONE);
}

int fpga_pre_config_fn(int cookie)
{
	debug("%s:%d: FPGA pre-configuration\n", __func__, __LINE__);

	/* Setting GPIOs for programming Mode */
	gpio_request(FPGA_RESET, "FPGA_RESET");
	gpio_direction_output(FPGA_RESET, 1);
	gpio_request(FPGA_PROG, "FPGA_PROG");
	gpio_direction_output(FPGA_PROG, 1);
	gpio_request(FPGA_CCLK, "FPGA_CCLK");
	gpio_direction_output(FPGA_CCLK, 1);
	gpio_request(FPGA_DIN, "FPGA_DIN");
	gpio_direction_output(FPGA_DIN, 0);
	gpio_request(FPGA_INIT, "FPGA_INIT");
	gpio_direction_input(FPGA_INIT);
	gpio_request(FPGA_DONE, "FPGA_DONE");
	gpio_direction_input(FPGA_DONE);

	/* Be sure that signal are deasserted */
	gpio_set_value(FPGA_RESET, 1);
	gpio_set_value(FPGA_PROG, 1);

	return 0;
}

int fpga_post_config_fn(int cookie)
{
	debug("%s:%d: FPGA post-configuration\n", __func__, __LINE__);

	fpga_reset(TRUE);
	udelay(100);
	fpga_reset(FALSE);

	return 0;
}

/* Write program to the FPGA */
int fpga_wr_fn(int nassert_write, int flush, int cookie)
{
	gpio_set_value(FPGA_DIN, nassert_write);

	return nassert_write;
}

int fpga_clk_fn(int assert_clk, int flush, int cookie)
{
	gpio_set_value(FPGA_CCLK, assert_clk);

	return assert_clk;
}

Xilinx_Spartan3_Slave_Serial_fns mt_ventoux_fpga_fns = {
	fpga_pre_config_fn,
	fpga_pgm_fn,
	fpga_clk_fn,
	fpga_init_fn,
	fpga_done_fn,
	fpga_wr_fn,
	fpga_post_config_fn,
};

Xilinx_desc fpga = XILINX_XC6SLX4_DESC(slave_serial,
			(void *)&mt_ventoux_fpga_fns, 0);

/* Initialize the FPGA */
static void mt_ventoux_init_fpga(void)
{
	fpga_pre_config_fn(0);

	/* Setting CS1 for FPGA access */
	enable_gpmc_cs_config(gpmc_fpga, &gpmc_cfg->cs[1],
		FPGA_BASE_ADDR, GPMC_SIZE_128M);

	fpga_init();
	fpga_add(fpga_xilinx, &fpga);
}

/*
 * Routine: board_init
 * Description: Early hardware init.
 */
int board_init(void)
{
	gpmc_init(); /* in SRAM or SDRAM, finish GPMC */

	/* boot param addr */
	gd->bd->bi_boot_params = (OMAP34XX_SDRC_CS0 + 0x100);

	mt_ventoux_init_fpga();

	/* GPIO_140: speaker #mute */
	MUX_VAL(CP(MCBSP3_DX),		(IEN | PTU | EN | M4))
	/* GPIO_141: Buzz Hi */
	MUX_VAL(CP(MCBSP3_DR),		(IEN  | PTU | EN | M4))

	/* Turning off the buzzer */
	gpio_request(BUZZER, "BUZZER_MUTE");
	gpio_request(SPEAKER, "SPEAKER");
	gpio_direction_output(BUZZER, 0);
	gpio_direction_output(SPEAKER, 0);

	/* Activate USB power */
	gpio_request(USB1_PWR, "USB1_PWR");
	gpio_request(USB2_PWR, "USB2_PWR");
	gpio_direction_output(USB1_PWR, 1);
	gpio_direction_output(USB2_PWR, 1);

	return 0;
}

int misc_init_r(void)
{
	char *eth_addr;

	dieid_num_r();

	eth_addr = getenv("ethaddr");
	if (eth_addr)
		return 0;

#ifndef CONFIG_SPL_BUILD
	TAM3517_READ_MAC_FROM_EEPROM;
#endif
	return 0;
}

/*
 * Routine: set_muxconf_regs
 * Description: Setting up the configuration Mux registers specific to the
 *		hardware. Many pins need to be moved from protect to primary
 *		mode.
 */
void set_muxconf_regs(void)
{
	MUX_MT_VENTOUX();
}

/*
 * Initializes on-chip ethernet controllers.
 * to override, implement board_eth_init()
 */
int board_eth_init(bd_t *bis)
{
	davinci_emac_initialize();
	return 0;
}

#if defined(CONFIG_OMAP_HSMMC) && \
	!defined(CONFIG_SPL_BUILD)
int board_mmc_init(bd_t *bis)
{
	return omap_mmc_init(0, 0, 0);
}
#endif

#if defined(CONFIG_VIDEO) && !defined(CONFIG_SPL_BUILD)
int board_video_init(void)
{
	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
	struct panel_config *panel = &lcd_cfg[0];
	char *s;
	u32 index = 0;

	void *fb;

	fb = (void *)0x88000000;

	s = getenv("panel");
	if (s) {
		index = simple_strtoul(s, NULL, 10);
		if (index < ARRAY_SIZE(lcd_cfg))
			panel = &lcd_cfg[index];
		else
			return 0;
	}

	panel->frame_buffer = fb;
	printf("Panel: %dx%d\n", panel_resolution[index].xres,
		panel_resolution[index].yres);
	panel->lcd_size = (panel_resolution[index].yres - 1) << 16 |
		(panel_resolution[index].xres - 1);

	gpio_request(LCD_PWR, "LCD Power");
	gpio_request(LCD_PON_PIN, "LCD Pon");
	gpio_direction_output(LCD_PWR, 0);
	gpio_direction_output(LCD_PON_PIN, 1);


	setbits_le32(&prcm_base->fclken_dss, FCK_DSS_ON);
	setbits_le32(&prcm_base->iclken_dss, ICK_DSS_ON);

	omap3_dss_panel_config(panel);
	omap3_dss_enable();

	return 0;
}
#endif
