/*
 * PCI Tower specific code
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
 */

#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/serial_8250.h>

#include <asm/mc146818-time.h>
#include <asm/sni.h>
#include <asm/time.h>
#include <asm/irq_cpu.h>


#define PORT(_base,_irq)				\
	{						\
		.iobase		= _base,		\
		.irq		= _irq,			\
		.uartclk	= 1843200,		\
		.iotype		= UPIO_PORT,		\
		.flags		= UPF_BOOT_AUTOCONF,	\
	}

static struct plat_serial8250_port pcit_data[] = {
	PORT(0x3f8, 0),
	PORT(0x2f8, 3),
	{ },
};

static struct platform_device pcit_serial8250_device = {
	.name			= "serial8250",
	.id			= PLAT8250_DEV_PLATFORM,
	.dev			= {
		.platform_data	= pcit_data,
	},
};

static struct plat_serial8250_port pcit_cplus_data[] = {
	PORT(0x3f8, 0),
	PORT(0x2f8, 3),
	PORT(0x3e8, 4),
	PORT(0x2e8, 3),
	{ },
};

static struct platform_device pcit_cplus_serial8250_device = {
	.name			= "serial8250",
	.id			= PLAT8250_DEV_PLATFORM,
	.dev			= {
		.platform_data	= pcit_cplus_data,
	},
};

static struct resource sni_io_resource = {
	.start	= 0x00000000UL,
	.end	= 0x03bfffffUL,
	.name	= "PCIT IO",
	.flags	= IORESOURCE_IO,
};

static struct resource pcit_io_resources[] = {
	{
		.start	= 0x00,
		.end	= 0x1f,
		.name	= "dma1",
		.flags	= IORESOURCE_BUSY
	}, {
		.start	=  0x40,
		.end	= 0x5f,
		.name	= "timer",
		.flags	= IORESOURCE_BUSY
	}, {
		.start	=  0x60,
		.end	= 0x6f,
		.name	= "keyboard",
		.flags	= IORESOURCE_BUSY
	}, {
		.start	=  0x80,
		.end	= 0x8f,
		.name	= "dma page reg",
		.flags	= IORESOURCE_BUSY
	}, {
		.start	=  0xc0,
		.end	= 0xdf,
		.name	= "dma2",
		.flags	= IORESOURCE_BUSY
	}, {
		.start	=  0xcf8,
		.end	= 0xcfb,
		.name	= "PCI config addr",
		.flags	= IORESOURCE_BUSY
	}, {
		.start	=  0xcfc,
		.end	= 0xcff,
		.name	= "PCI config data",
		.flags	= IORESOURCE_BUSY
	}
};

static struct resource sni_mem_resource = {
	.start	= 0x18000000UL,
	.end	= 0x1fbfffffUL,
	.name	= "PCIT PCI MEM",
	.flags	= IORESOURCE_MEM
};

static void __init sni_pcit_resource_init(void)
{
	int i;

	/* request I/O space for devices used on all i[345]86 PCs */
	for (i = 0; i < ARRAY_SIZE(pcit_io_resources); i++)
		request_resource(&sni_io_resource, pcit_io_resources + i);
}


extern struct pci_ops sni_pcit_ops;

static struct pci_controller sni_pcit_controller = {
	.pci_ops	= &sni_pcit_ops,
	.mem_resource	= &sni_mem_resource,
	.mem_offset	= 0x00000000UL,
	.io_resource	= &sni_io_resource,
	.io_offset	= 0x00000000UL,
	.io_map_base    = SNI_PORT_BASE
};

static void enable_pcit_irq(unsigned int irq)
{
	u32 mask = 1 << (irq - SNI_PCIT_INT_START + 24);

	*(volatile u32 *)SNI_PCIT_INT_REG |= mask;
}

void disable_pcit_irq(unsigned int irq)
{
	u32 mask = 1 << (irq - SNI_PCIT_INT_START + 24);

	*(volatile u32 *)SNI_PCIT_INT_REG &= ~mask;
}

void end_pcit_irq(unsigned int irq)
{
	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
		enable_pcit_irq(irq);
}

static struct irq_chip pcit_irq_type = {
	.typename = "PCIT",
	.ack = disable_pcit_irq,
	.mask = disable_pcit_irq,
	.mask_ack = disable_pcit_irq,
	.unmask = enable_pcit_irq,
	.end = end_pcit_irq,
};

static void pcit_hwint1(void)
{
	u32 pending = *(volatile u32 *)SNI_PCIT_INT_REG;
	int irq;

	clear_c0_status(IE_IRQ1);
	irq = ffs((pending >> 16) & 0x7f);

	if (likely(irq > 0))
		do_IRQ (irq + SNI_PCIT_INT_START - 1);
	set_c0_status (IE_IRQ1);
}

static void pcit_hwint0(void)
{
	u32 pending = *(volatile u32 *)SNI_PCIT_INT_REG;
	int irq;

	clear_c0_status(IE_IRQ0);
	irq = ffs((pending >> 16) & 0x3f);

	if (likely(irq > 0))
		do_IRQ (irq + SNI_PCIT_INT_START - 1);
	set_c0_status (IE_IRQ0);
}

static void sni_pcit_hwint(void)
{
	u32 pending = read_c0_cause() & read_c0_status();

	if (pending & C_IRQ1)
		pcit_hwint1();
	else if (pending & C_IRQ2)
		do_IRQ (MIPS_CPU_IRQ_BASE + 4);
	else if (pending & C_IRQ3)
		do_IRQ (MIPS_CPU_IRQ_BASE + 5);
	else if (pending & C_IRQ5)
		do_IRQ (MIPS_CPU_IRQ_BASE + 7);
}

static void sni_pcit_hwint_cplus(void)
{
	u32 pending = read_c0_cause() & read_c0_status();

	if (pending & C_IRQ0)
		pcit_hwint0();
	else if (pending & C_IRQ1)
		do_IRQ (MIPS_CPU_IRQ_BASE + 3);
	else if (pending & C_IRQ2)
		do_IRQ (MIPS_CPU_IRQ_BASE + 4);
	else if (pending & C_IRQ3)
		do_IRQ (MIPS_CPU_IRQ_BASE + 5);
	else if (pending & C_IRQ5)
		do_IRQ (MIPS_CPU_IRQ_BASE + 7);
}

void __init sni_pcit_irq_init(void)
{
	int i;

	mips_cpu_irq_init();
	for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
		set_irq_chip(i, &pcit_irq_type);
	*(volatile u32 *)SNI_PCIT_INT_REG = 0;
	sni_hwint = sni_pcit_hwint;
	change_c0_status(ST0_IM, IE_IRQ1);
	setup_irq (SNI_PCIT_INT_START + 6, &sni_isa_irq);
}

void __init sni_pcit_cplus_irq_init(void)
{
	int i;

	mips_cpu_irq_init();
	for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
		set_irq_chip(i, &pcit_irq_type);
	*(volatile u32 *)SNI_PCIT_INT_REG = 0x40000000;
	sni_hwint = sni_pcit_hwint_cplus;
	change_c0_status(ST0_IM, IE_IRQ0);
	setup_irq (MIPS_CPU_IRQ_BASE + 3, &sni_isa_irq);
}

void sni_pcit_init(void)
{
	rtc_mips_get_time = mc146818_get_cmos_time;
	rtc_mips_set_time = mc146818_set_rtc_mmss;
	board_time_init = sni_cpu_time_init;
	ioport_resource.end = sni_io_resource.end;
#ifdef CONFIG_PCI
	PCIBIOS_MIN_IO = 0x9000;
	register_pci_controller(&sni_pcit_controller);
#endif
	sni_pcit_resource_init();
}

static int __init snirm_pcit_setup_devinit(void)
{
	switch (sni_brd_type) {
	case SNI_BRD_PCI_TOWER:
	        platform_device_register(&pcit_serial8250_device);
	        break;

	case SNI_BRD_PCI_TOWER_CPLUS:
	        platform_device_register(&pcit_cplus_serial8250_device);
	        break;
	}
	return 0;
}

device_initcall(snirm_pcit_setup_devinit);
