/*
 * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
 *		http://www.samsung.com
 *
 * Common Codes for S5P64X0 machines
 *
 * 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/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/dma-mapping.h>
#include <linux/gpio.h>
#include <linux/irq.h>

#include <asm/irq.h>
#include <asm/proc-fns.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>

#include <mach/map.h>
#include <mach/hardware.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>

#include <plat/cpu.h>
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/pm.h>
#include <plat/sdhci.h>
#include <plat/adc-core.h>
#include <plat/fb-core.h>
#include <plat/gpio-cfg.h>
#include <plat/regs-irqtype.h>
#include <plat/regs-serial.h>
#include <plat/watchdog-reset.h>

#include "common.h"

static const char name_s5p6440[] = "S5P6440";
static const char name_s5p6450[] = "S5P6450";

static struct cpu_table cpu_ids[] __initdata = {
	{
		.idcode		= S5P6440_CPU_ID,
		.idmask		= S5P64XX_CPU_MASK,
		.map_io		= s5p6440_map_io,
		.init_clocks	= s5p6440_init_clocks,
		.init_uarts	= s5p6440_init_uarts,
		.init		= s5p64x0_init,
		.name		= name_s5p6440,
	}, {
		.idcode		= S5P6450_CPU_ID,
		.idmask		= S5P64XX_CPU_MASK,
		.map_io		= s5p6450_map_io,
		.init_clocks	= s5p6450_init_clocks,
		.init_uarts	= s5p6450_init_uarts,
		.init		= s5p64x0_init,
		.name		= name_s5p6450,
	},
};

/* Initial IO mappings */

static struct map_desc s5p64x0_iodesc[] __initdata = {
	{
		.virtual	= (unsigned long)S5P_VA_CHIPID,
		.pfn		= __phys_to_pfn(S5P64X0_PA_CHIPID),
		.length		= SZ_4K,
		.type		= MT_DEVICE,
	}, {
		.virtual	= (unsigned long)S3C_VA_SYS,
		.pfn		= __phys_to_pfn(S5P64X0_PA_SYSCON),
		.length		= SZ_64K,
		.type		= MT_DEVICE,
	}, {
		.virtual	= (unsigned long)S3C_VA_TIMER,
		.pfn		= __phys_to_pfn(S5P64X0_PA_TIMER),
		.length		= SZ_16K,
		.type		= MT_DEVICE,
	}, {
		.virtual	= (unsigned long)S3C_VA_WATCHDOG,
		.pfn		= __phys_to_pfn(S5P64X0_PA_WDT),
		.length		= SZ_4K,
		.type		= MT_DEVICE,
	}, {
		.virtual	= (unsigned long)S5P_VA_SROMC,
		.pfn		= __phys_to_pfn(S5P64X0_PA_SROMC),
		.length		= SZ_4K,
		.type		= MT_DEVICE,
	}, {
		.virtual	= (unsigned long)S5P_VA_GPIO,
		.pfn		= __phys_to_pfn(S5P64X0_PA_GPIO),
		.length		= SZ_4K,
		.type		= MT_DEVICE,
	}, {
		.virtual	= (unsigned long)VA_VIC0,
		.pfn		= __phys_to_pfn(S5P64X0_PA_VIC0),
		.length		= SZ_16K,
		.type		= MT_DEVICE,
	}, {
		.virtual	= (unsigned long)VA_VIC1,
		.pfn		= __phys_to_pfn(S5P64X0_PA_VIC1),
		.length		= SZ_16K,
		.type		= MT_DEVICE,
	},
};

static struct map_desc s5p6440_iodesc[] __initdata = {
	{
		.virtual	= (unsigned long)S3C_VA_UART,
		.pfn		= __phys_to_pfn(S5P6440_PA_UART(0)),
		.length		= SZ_4K,
		.type		= MT_DEVICE,
	},
};

static struct map_desc s5p6450_iodesc[] __initdata = {
	{
		.virtual	= (unsigned long)S3C_VA_UART,
		.pfn		= __phys_to_pfn(S5P6450_PA_UART(0)),
		.length		= SZ_512K,
		.type		= MT_DEVICE,
	}, {
		.virtual	= (unsigned long)S3C_VA_UART + SZ_512K,
		.pfn		= __phys_to_pfn(S5P6450_PA_UART(5)),
		.length		= SZ_4K,
		.type		= MT_DEVICE,
	},
};

static void s5p64x0_idle(void)
{
	unsigned long val;

	val = __raw_readl(S5P64X0_PWR_CFG);
	val &= ~(0x3 << 5);
	val |= (0x1 << 5);
	__raw_writel(val, S5P64X0_PWR_CFG);

	cpu_do_idle();
}

/*
 * s5p64x0_map_io
 *
 * register the standard CPU IO areas
 */

void __init s5p64x0_init_io(struct map_desc *mach_desc, int size)
{
	/* initialize the io descriptors we need for initialization */
	iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));
	if (mach_desc)
		iotable_init(mach_desc, size);

	/* detect cpu id and rev. */
	s5p_init_cpu(S5P64X0_SYS_ID);

	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
}

void __init s5p6440_map_io(void)
{
	/* initialize any device information early */
	s3c_adc_setname("s3c64xx-adc");
	s3c_fb_setname("s5p64x0-fb");

	s5p64x0_default_sdhci0();
	s5p64x0_default_sdhci1();
	s5p6440_default_sdhci2();

	iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc));
	init_consistent_dma_size(SZ_8M);
}

void __init s5p6450_map_io(void)
{
	/* initialize any device information early */
	s3c_adc_setname("s3c64xx-adc");
	s3c_fb_setname("s5p64x0-fb");

	s5p64x0_default_sdhci0();
	s5p64x0_default_sdhci1();
	s5p6450_default_sdhci2();

	iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6450_iodesc));
	init_consistent_dma_size(SZ_8M);
}

/*
 * s5p64x0_init_clocks
 *
 * register and setup the CPU clocks
 */

void __init s5p6440_init_clocks(int xtal)
{
	printk(KERN_DEBUG "%s: initializing clocks\n", __func__);

	s3c24xx_register_baseclocks(xtal);
	s5p_register_clocks(xtal);
	s5p6440_register_clocks();
	s5p6440_setup_clocks();
}

void __init s5p6450_init_clocks(int xtal)
{
	printk(KERN_DEBUG "%s: initializing clocks\n", __func__);

	s3c24xx_register_baseclocks(xtal);
	s5p_register_clocks(xtal);
	s5p6450_register_clocks();
	s5p6450_setup_clocks();
}

/*
 * s5p64x0_init_irq
 *
 * register the CPU interrupts
 */

void __init s5p6440_init_irq(void)
{
	/* S5P6440 supports 2 VIC */
	u32 vic[2];

	/*
	 * VIC0 is missing IRQ_VIC0[3, 4, 8, 10, (12-22)]
	 * VIC1 is missing IRQ VIC1[1, 3, 4, 10, 11, 12, 14, 15, 22]
	 */
	vic[0] = 0xff800ae7;
	vic[1] = 0xffbf23e5;

	s5p_init_irq(vic, ARRAY_SIZE(vic));
}

void __init s5p6450_init_irq(void)
{
	/* S5P6450 supports only 2 VIC */
	u32 vic[2];

	/*
	 * VIC0 is missing IRQ_VIC0[(13-15), (21-22)]
	 * VIC1 is missing IRQ VIC1[12, 14, 23]
	 */
	vic[0] = 0xff9f1fff;
	vic[1] = 0xff7fafff;

	s5p_init_irq(vic, ARRAY_SIZE(vic));
}

struct bus_type s5p64x0_subsys = {
	.name		= "s5p64x0-core",
	.dev_name	= "s5p64x0-core",
};

static struct device s5p64x0_dev = {
	.bus	= &s5p64x0_subsys,
};

static int __init s5p64x0_core_init(void)
{
	return subsys_system_register(&s5p64x0_subsys, NULL);
}
core_initcall(s5p64x0_core_init);

int __init s5p64x0_init(void)
{
	printk(KERN_INFO "S5P64X0(S5P6440/S5P6450): Initializing architecture\n");

	/* set idle function */
	arm_pm_idle = s5p64x0_idle;

	return device_register(&s5p64x0_dev);
}

/* uart registration process */
void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
	int uart;

	for (uart = 0; uart < no; uart++) {
		s5p_uart_resources[uart].resources->start = S5P6440_PA_UART(uart);
		s5p_uart_resources[uart].resources->end = S5P6440_PA_UART(uart) + S5P_SZ_UART;
	}

	s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
}

void __init s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
	s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
}

#define eint_offset(irq)	((irq) - IRQ_EINT(0))

static int s5p64x0_irq_eint_set_type(struct irq_data *data, unsigned int type)
{
	int offs = eint_offset(data->irq);
	int shift;
	u32 ctrl, mask;
	u32 newvalue = 0;

	if (offs > 15)
		return -EINVAL;

	switch (type) {
	case IRQ_TYPE_NONE:
		printk(KERN_WARNING "No edge setting!\n");
		break;
	case IRQ_TYPE_EDGE_RISING:
		newvalue = S3C2410_EXTINT_RISEEDGE;
		break;
	case IRQ_TYPE_EDGE_FALLING:
		newvalue = S3C2410_EXTINT_FALLEDGE;
		break;
	case IRQ_TYPE_EDGE_BOTH:
		newvalue = S3C2410_EXTINT_BOTHEDGE;
		break;
	case IRQ_TYPE_LEVEL_LOW:
		newvalue = S3C2410_EXTINT_LOWLEV;
		break;
	case IRQ_TYPE_LEVEL_HIGH:
		newvalue = S3C2410_EXTINT_HILEV;
		break;
	default:
		printk(KERN_ERR "No such irq type %d", type);
		return -EINVAL;
	}

	shift = (offs / 2) * 4;
	mask = 0x7 << shift;

	ctrl = __raw_readl(S5P64X0_EINT0CON0) & ~mask;
	ctrl |= newvalue << shift;
	__raw_writel(ctrl, S5P64X0_EINT0CON0);

	/* Configure the GPIO pin for 6450 or 6440 based on CPU ID */
	if (soc_is_s5p6450())
		s3c_gpio_cfgpin(S5P6450_GPN(offs), S3C_GPIO_SFN(2));
	else
		s3c_gpio_cfgpin(S5P6440_GPN(offs), S3C_GPIO_SFN(2));

	return 0;
}

/*
 * s5p64x0_irq_demux_eint
 *
 * This function demuxes the IRQ from the group0 external interrupts,
 * from IRQ_EINT(0) to IRQ_EINT(15). It is designed to be inlined into
 * the specific handlers s5p64x0_irq_demux_eintX_Y.
 */
static inline void s5p64x0_irq_demux_eint(unsigned int start, unsigned int end)
{
	u32 status = __raw_readl(S5P64X0_EINT0PEND);
	u32 mask = __raw_readl(S5P64X0_EINT0MASK);
	unsigned int irq;

	status &= ~mask;
	status >>= start;
	status &= (1 << (end - start + 1)) - 1;

	for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
		if (status & 1)
			generic_handle_irq(irq);
		status >>= 1;
	}
}

static void s5p64x0_irq_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
{
	s5p64x0_irq_demux_eint(0, 3);
}

static void s5p64x0_irq_demux_eint4_11(unsigned int irq, struct irq_desc *desc)
{
	s5p64x0_irq_demux_eint(4, 11);
}

static void s5p64x0_irq_demux_eint12_15(unsigned int irq,
					struct irq_desc *desc)
{
	s5p64x0_irq_demux_eint(12, 15);
}

static int s5p64x0_alloc_gc(void)
{
	struct irq_chip_generic *gc;
	struct irq_chip_type *ct;

	gc = irq_alloc_generic_chip("s5p64x0-eint", 1, S5P_IRQ_EINT_BASE,
				    S5P_VA_GPIO, handle_level_irq);
	if (!gc) {
		printk(KERN_ERR "%s: irq_alloc_generic_chip for group 0"
			"external interrupts failed\n", __func__);
		return -EINVAL;
	}

	ct = gc->chip_types;
	ct->chip.irq_ack = irq_gc_ack_set_bit;
	ct->chip.irq_mask = irq_gc_mask_set_bit;
	ct->chip.irq_unmask = irq_gc_mask_clr_bit;
	ct->chip.irq_set_type = s5p64x0_irq_eint_set_type;
	ct->chip.irq_set_wake = s3c_irqext_wake;
	ct->regs.ack = EINT0PEND_OFFSET;
	ct->regs.mask = EINT0MASK_OFFSET;
	irq_setup_generic_chip(gc, IRQ_MSK(16), IRQ_GC_INIT_MASK_CACHE,
			       IRQ_NOREQUEST | IRQ_NOPROBE, 0);
	return 0;
}

static int __init s5p64x0_init_irq_eint(void)
{
	int ret = s5p64x0_alloc_gc();
	irq_set_chained_handler(IRQ_EINT0_3, s5p64x0_irq_demux_eint0_3);
	irq_set_chained_handler(IRQ_EINT4_11, s5p64x0_irq_demux_eint4_11);
	irq_set_chained_handler(IRQ_EINT12_15, s5p64x0_irq_demux_eint12_15);

	return ret;
}
arch_initcall(s5p64x0_init_irq_eint);

void s5p64x0_restart(char mode, const char *cmd)
{
	if (mode != 's')
		arch_wdt_reset();

	soft_restart(0);
}
