/*
 * 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/irq.h>
#include <linux/pci.h>
#include <linux/serial_8250.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 pcit_cmos_rsrc[] = {
        {
                .start = 0x70,
                .end   = 0x71,
                .flags = IORESOURCE_IO
        },
        {
                .start = 8,
                .end   = 8,
                .flags = IORESOURCE_IRQ
        }
};

static struct platform_device pcit_cmos_device = {
        .name           = "rtc_cmos",
        .num_resources  = ARRAY_SIZE(pcit_cmos_rsrc),
        .resource       = pcit_cmos_rsrc
};

static struct platform_device pcit_pcspeaker_pdev = {
	.name		= "pcspkr",
	.id		= -1,
};

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(struct irq_data *d)
{
	u32 mask = 1 << (d->irq - SNI_PCIT_INT_START + 24);

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

void disable_pcit_irq(struct irq_data *d)
{
	u32 mask = 1 << (d->irq - SNI_PCIT_INT_START + 24);

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

static struct irq_chip pcit_irq_type = {
	.name = "PCIT",
	.irq_mask = disable_pcit_irq,
	.irq_unmask = enable_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++)
		irq_set_chip_and_handler(i, &pcit_irq_type, handle_level_irq);
	*(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++)
		irq_set_chip_and_handler(i, &pcit_irq_type, handle_level_irq);
	*(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 __init sni_pcit_init(void)
{
	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);
	        platform_device_register(&pcit_cmos_device);
		platform_device_register(&pcit_pcspeaker_pdev);
	        break;

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

device_initcall(snirm_pcit_setup_devinit);
