/*
 * linux/arch/arm/mach-omap2/board-apollon.c
 *
 * Copyright (C) 2005,2006 Samsung Electronics
 * Author: Kyungmin Park <kyungmin.park@samsung.com>
 *
 * Modified from mach-omap/omap2/board-h4.c
 *
 * Code for apollon OMAP2 board. Should work on many OMAP2 systems where
 * the bootloader passes the board-specific data to the kernel.
 * Do not put any board specific code to this file; create a new machine
 * type if you need custom low-level initializations.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/onenand.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/delay.h>

#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>

#include <asm/arch/gpio.h>
#include <asm/arch/mux.h>
#include <asm/arch/usb.h>
#include <asm/arch/board.h>
#include <asm/arch/common.h>
#include "prcm-regs.h"

/* LED & Switch macros */
#define LED0_GPIO13		13
#define LED1_GPIO14		14
#define LED2_GPIO15		15
#define SW_ENTER_GPIO16		16
#define SW_UP_GPIO17		17
#define SW_DOWN_GPIO58		58

static struct mtd_partition apollon_partitions[] = {
	{
		.name		= "X-Loader + U-Boot",
		.offset		= 0,
		.size		= SZ_128K,
		.mask_flags	= MTD_WRITEABLE,
	},
	{
		.name		= "params",
		.offset		= MTDPART_OFS_APPEND,
		.size		= SZ_128K,
	},
	{
		.name		= "kernel",
		.offset		= MTDPART_OFS_APPEND,
		.size		= SZ_2M,
	},
	{
		.name		= "rootfs",
		.offset		= MTDPART_OFS_APPEND,
		.size		= SZ_16M,
	},
	{
		.name		= "filesystem00",
		.offset		= MTDPART_OFS_APPEND,
		.size		= SZ_32M,
	},
	{
		.name		= "filesystem01",
		.offset		= MTDPART_OFS_APPEND,
		.size		= MTDPART_SIZ_FULL,
	},
};

static struct flash_platform_data apollon_flash_data = {
	.parts		= apollon_partitions,
	.nr_parts	= ARRAY_SIZE(apollon_partitions),
};

static struct resource apollon_flash_resource = {
	.start		= APOLLON_CS0_BASE,
	.end		= APOLLON_CS0_BASE + SZ_128K,
	.flags		= IORESOURCE_MEM,
};

static struct platform_device apollon_onenand_device = {
	.name		= "onenand",
	.id		= -1,
	.dev		= {
		.platform_data	= &apollon_flash_data,
	},
	.num_resources	= ARRAY_SIZE(&apollon_flash_resource),
	.resource	= &apollon_flash_resource,
};

static struct resource apollon_smc91x_resources[] = {
	[0] = {
		.start	= APOLLON_ETHR_START,		/* Physical */
		.end	= APOLLON_ETHR_START + 0xf,
		.flags  = IORESOURCE_MEM,
	},
	[1] = {
		.start	= OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
		.end	= OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
		.flags	= IORESOURCE_IRQ,
	},
};

static struct platform_device apollon_smc91x_device = {
	.name		= "smc91x",
	.id		= -1,
	.num_resources	= ARRAY_SIZE(apollon_smc91x_resources),
	.resource	= apollon_smc91x_resources,
};

static struct platform_device apollon_lcd_device = {
	.name		= "apollon_lcd",
	.id		= -1,
};

static struct platform_device *apollon_devices[] __initdata = {
	&apollon_onenand_device,
	&apollon_smc91x_device,
	&apollon_lcd_device,
};

static inline void __init apollon_init_smc91x(void)
{
	/* Make sure CS1 timings are correct */
	GPMC_CONFIG1_1 = 0x00011203;
	GPMC_CONFIG2_1 = 0x001f1f01;
	GPMC_CONFIG3_1 = 0x00080803;
	GPMC_CONFIG4_1 = 0x1c091c09;
	GPMC_CONFIG5_1 = 0x041f1f1f;
	GPMC_CONFIG6_1 = 0x000004c4;
	GPMC_CONFIG7_1 = 0x00000f40 | (APOLLON_CS1_BASE >> 24);
	udelay(100);

	omap_cfg_reg(W4__24XX_GPIO74);
	if (omap_request_gpio(APOLLON_ETHR_GPIO_IRQ) < 0) {
		printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
			APOLLON_ETHR_GPIO_IRQ);
		return;
	}
	omap_set_gpio_direction(APOLLON_ETHR_GPIO_IRQ, 1);
}

static void __init omap_apollon_init_irq(void)
{
	omap2_init_common_hw();
	omap_init_irq();
	omap_gpio_init();
	apollon_init_smc91x();
}

static struct omap_uart_config apollon_uart_config __initdata = {
	.enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2),
};

static struct omap_mmc_config apollon_mmc_config __initdata = {
	.mmc [0] = {
		.enabled 	= 1,
		.wire4		= 1,
		.wp_pin		= -1,
		.power_pin	= -1,
		.switch_pin	= -1,
	},
};

static struct omap_lcd_config apollon_lcd_config __initdata = {
	.ctrl_name	= "internal",
};

static struct omap_board_config_kernel apollon_config[] = {
	{ OMAP_TAG_UART,	&apollon_uart_config },
	{ OMAP_TAG_MMC,		&apollon_mmc_config },
	{ OMAP_TAG_LCD,		&apollon_lcd_config },
};

static void __init apollon_led_init(void)
{
	/* LED0 - AA10 */
	omap_cfg_reg(AA10_242X_GPIO13);
	omap_request_gpio(LED0_GPIO13);
	omap_set_gpio_direction(LED0_GPIO13, 0);
	omap_set_gpio_dataout(LED0_GPIO13, 0);
	/* LED1  - AA6 */
	omap_cfg_reg(AA6_242X_GPIO14);
	omap_request_gpio(LED1_GPIO14);
	omap_set_gpio_direction(LED1_GPIO14, 0);
	omap_set_gpio_dataout(LED1_GPIO14, 0);
	/* LED2  - AA4 */
	omap_cfg_reg(AA4_242X_GPIO15);
	omap_request_gpio(LED2_GPIO15);
	omap_set_gpio_direction(LED2_GPIO15, 0);
	omap_set_gpio_dataout(LED2_GPIO15, 0);
}

static irqreturn_t apollon_sw_interrupt(int irq, void *ignored)
{
	static unsigned int led0, led1, led2;

	if (irq == OMAP_GPIO_IRQ(SW_ENTER_GPIO16))
		omap_set_gpio_dataout(LED0_GPIO13, led0 ^= 1);
	else if (irq == OMAP_GPIO_IRQ(SW_UP_GPIO17))
		omap_set_gpio_dataout(LED1_GPIO14, led1 ^= 1);
	else if (irq == OMAP_GPIO_IRQ(SW_DOWN_GPIO58))
		omap_set_gpio_dataout(LED2_GPIO15, led2 ^= 1);

	return IRQ_HANDLED;
}

static void __init apollon_sw_init(void)
{
	/* Enter SW - Y11 */
	omap_cfg_reg(Y11_242X_GPIO16);
	omap_request_gpio(SW_ENTER_GPIO16);
	omap_set_gpio_direction(SW_ENTER_GPIO16, 1);
	/* Up SW - AA12 */
	omap_cfg_reg(AA12_242X_GPIO17);
	omap_request_gpio(SW_UP_GPIO17);
	omap_set_gpio_direction(SW_UP_GPIO17, 1);
	/* Down SW - AA8 */
	omap_cfg_reg(AA8_242X_GPIO58);
	omap_request_gpio(SW_DOWN_GPIO58);
	omap_set_gpio_direction(SW_DOWN_GPIO58, 1);

	set_irq_type(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), IRQT_RISING);
	if (request_irq(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), &apollon_sw_interrupt,
				IRQF_SHARED, "enter sw",
				&apollon_sw_interrupt))
		return;
	set_irq_type(OMAP_GPIO_IRQ(SW_UP_GPIO17), IRQT_RISING);
	if (request_irq(OMAP_GPIO_IRQ(SW_UP_GPIO17), &apollon_sw_interrupt,
				IRQF_SHARED, "up sw",
				&apollon_sw_interrupt))
		return;
	set_irq_type(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), IRQT_RISING);
	if (request_irq(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), &apollon_sw_interrupt,
				IRQF_SHARED, "down sw",
				&apollon_sw_interrupt))
		return;
}

static void __init omap_apollon_init(void)
{
	apollon_led_init();
	apollon_sw_init();

	/* REVISIT: where's the correct place */
	omap_cfg_reg(W19_24XX_SYS_NIRQ);

	/* Use Interal loop-back in MMC/SDIO Module Input Clock selection */
	CONTROL_DEVCONF |= (1 << 24);

	/*
 	 * Make sure the serial ports are muxed on at this point.
	 * You have to mux them off in device drivers later on
	 * if not needed.
	 */
	platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices));
	omap_board_config = apollon_config;
	omap_board_config_size = ARRAY_SIZE(apollon_config);
	omap_serial_init();
}

static void __init omap_apollon_map_io(void)
{
	omap2_map_common_io();
}

MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
	/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
	.phys_io	= 0x48000000,
	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
	.boot_params	= 0x80000100,
	.map_io		= omap_apollon_map_io,
	.init_irq	= omap_apollon_init_irq,
	.init_machine	= omap_apollon_init,
	.timer		= &omap_timer,
MACHINE_END
