/*
 * 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;

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

		cpu_do_idle();
	}
	local_irq_enable();
}

/*
 * 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 */
	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);
}
