sh: Add support for R7780RP and R7780MP boards.

This adds support for the Renesas SH7780 development boards,
R7780RP and R7780MP.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile
index 86d6d06..3d8078f 100644
--- a/arch/sh/drivers/pci/Makefile
+++ b/arch/sh/drivers/pci/Makefile
@@ -7,6 +7,7 @@
 
 obj-$(CONFIG_CPU_SUBTYPE_ST40STB1)	+= pci-st40.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7751)	+= pci-sh7751.o 
+obj-$(CONFIG_CPU_SUBTYPE_SH7780)	+= pci-sh7780.o
 
 obj-$(CONFIG_SH_DREAMCAST)		+= ops-dreamcast.o fixups-dreamcast.o \
 					   dma-dreamcast.o
@@ -14,4 +15,5 @@
 obj-$(CONFIG_SH_BIGSUR)			+= ops-bigsur.o
 obj-$(CONFIG_SH_RTS7751R2D)		+= ops-rts7751r2d.o fixups-rts7751r2d.o
 obj-$(CONFIG_SH_SH03)			+= ops-sh03.o fixups-sh03.o
+obj-$(CONFIG_SH_R7780RP)		+= ops-r7780rp.o fixups-r7780rp.o
 obj-$(CONFIG_SH_TITAN)			+= ops-titan.o
diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c
new file mode 100644
index 0000000..b656b56
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-r7780rp.c
@@ -0,0 +1,39 @@
+/*
+ * arch/sh/drivers/pci/fixups-r7780rp.c
+ *
+ * Highlander R7780RP-1 PCI fixups
+ *
+ * Copyright (C) 2003  Lineo uSolutions, Inc.
+ * Copyright (C) 2004  Paul Mundt
+ *
+ * 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.
+ */
+#include "pci-sh7780.h"
+#include <asm/io.h>
+
+int pci_fixup_pcic(void)
+{
+	outl(0x000043ff, PCI_REG(SH7780_PCIIMR));
+	outl(0x0000380f, PCI_REG(SH7780_PCIAINTM));
+
+	outl(0xfbb00047, PCI_REG(SH7780_PCICMD));
+	outl(0x00000000, PCI_REG(SH7780_PCIIBAR));
+
+	outl(0x00011912, PCI_REG(SH7780_PCISVID));
+	outl(0x08000000, PCI_REG(SH7780_PCICSCR0));
+	outl(0x0000001b, PCI_REG(SH7780_PCICSAR0));
+	outl(0xfd000000, PCI_REG(SH7780_PCICSCR1));
+	outl(0x0000000f, PCI_REG(SH7780_PCICSAR1));
+
+	outl(0xfd000000, PCI_REG(SH7780_PCIMBR0));
+	outl(0x00fc0000, PCI_REG(SH7780_PCIMBMR0));
+
+	/* Set IOBR for windows containing area specified in pci.h */
+	outl((PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE-1)), PCI_REG(SH7780_PCIIOBR));
+	outl(((SH7780_PCI_IO_SIZE-1) & (7<<18)), PCI_REG(SH7780_PCIIOBMR));
+
+	return 0;
+}
+
diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c
new file mode 100644
index 0000000..3254c4e
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-r7780rp.c
@@ -0,0 +1,77 @@
+/*
+ * Author:  Ian DaSilva (idasilva@mvista.com)
+ *
+ * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * PCI initialization for the Renesas SH7780 Highlander R7780RP-1 board
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/module.h>
+
+#include <asm/io.h>
+#include "pci-sh7780.h"
+#include <asm/r7780rp/r7780rp.h>
+
+int __init pcibios_map_platform_irq(u8 slot, u8 pin)
+{
+        switch (slot) {
+	case 0: return IRQ_PCISLOT1;		/* PCI Interrupt #1 */
+	case 1: return IRQ_PCISLOT2;		/* PCI Interrupt #2 */
+	case 2: return IRQ_PCISLOT3;		/* PCI Interrupt #3 */
+	case 3: return IRQ_PCISLOT4;		/* PCI Interrupt E4 */
+	default:
+		printk("PCI: Bad IRQ mapping request for slot %d, func %d\n", slot, pin-1);
+		return -1;
+	}
+}
+
+static struct resource sh7780_io_resource = {
+	.name	= "SH7780_IO",
+	.start	= 0x2000,
+	.end	= 0x2000 + SH7780_PCI_IO_SIZE - 1,
+	.flags	= IORESOURCE_IO
+};
+
+static struct resource sh7780_mem_resource = {
+	.name	= "SH7780_mem",
+	.start	= SH7780_PCI_MEMORY_BASE,
+	.end	= SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1,
+	.flags	= IORESOURCE_MEM
+};
+
+extern struct pci_ops sh7780_pci_ops;
+
+struct pci_channel board_pci_channels[] = {
+	{ &sh7780_pci_ops, &sh7780_io_resource, &sh7780_mem_resource, 0, 0xff },
+	{ NULL, NULL, NULL, 0, 0 },
+};
+EXPORT_SYMBOL(board_pci_channels);
+
+static struct sh7780_pci_address_map sh7780_pci_map = {
+	.window0	= {
+		.base	= SH7780_CS2_BASE_ADDR,
+		.size	= 0x04000000,
+	},
+
+	.window1	= {
+		.base	= SH7780_CS3_BASE_ADDR,
+		.size	= 0x04000000,
+	},
+
+	.flags	= SH7780_PCIC_NO_RESET,
+};
+
+int __init pcibios_init_platform(void)
+{
+	return sh7780_pcic_init(&sh7780_pci_map);
+}
+
diff --git a/arch/sh/drivers/pci/pci-auto.c b/arch/sh/drivers/pci/pci-auto.c
index 4cef4d1..d55e466 100644
--- a/arch/sh/drivers/pci/pci-auto.c
+++ b/arch/sh/drivers/pci/pci-auto.c
@@ -45,11 +45,11 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 
-#undef	DEBUG
-#ifdef 	DEBUG
+#define	DEBUG
+#ifdef	DEBUG
 #define	DBG(x...)	printk(x)
 #else
-#define	DBG(x...)	
+#define	DBG(x...)
 #endif
 
 /*
@@ -102,7 +102,7 @@
 static u32 pciauto_lower_memspc;
 static u32 pciauto_upper_memspc;
 
-static void __init 
+static void __init
 pciauto_setup_bars(struct pci_channel *hose,
 		   int top_bus,
 		   int current_bus,
@@ -116,7 +116,6 @@
 	int found_mem64 = 0;
 
 	for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4) {
-#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
 		u32 bar_addr;
 
 		/* Read the old BAR value */
@@ -125,7 +124,6 @@
 					pci_devfn,
 					bar,
 					&bar_addr);
-#endif
 
 		/* Tickle the BAR and get the response */
 		early_write_config_dword(hose, top_bus,
@@ -140,8 +138,7 @@
 					bar,
 					&bar_response);
 
-#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
-		/* 
+		/*
 		 * Write the old BAR value back out, only update the BAR
 		 * if we implicitly want resources to be updated, which
 		 * is done by the generic code further down. -- PFM.
@@ -151,7 +148,6 @@
 					 pci_devfn,
 					 bar,
 					 bar_addr);
-#endif
 
 		/* If BAR is not implemented go to the next BAR */
 		if (!bar_response)
@@ -177,7 +173,7 @@
 			    PCI_BASE_ADDRESS_MEM_TYPE_64)
 				found_mem64 = 1;
 
-			addr_mask = PCI_BASE_ADDRESS_MEM_MASK;		
+			addr_mask = PCI_BASE_ADDRESS_MEM_MASK;
 			upper_limit = &pciauto_upper_memspc;
 			lower_limit = &pciauto_lower_memspc;
 			DBG("        Mem");
@@ -193,22 +189,22 @@
 		if ((bar_value + bar_size) > *upper_limit) {
 			if (bar_response & PCI_BASE_ADDRESS_SPACE) {
 				if (io_resource_inuse->child) {
-					io_resource_inuse = 
+					io_resource_inuse =
 						io_resource_inuse->child;
-					pciauto_lower_iospc = 
+					pciauto_lower_iospc =
 						io_resource_inuse->start;
-					pciauto_upper_iospc = 
+					pciauto_upper_iospc =
 						io_resource_inuse->end + 1;
 					goto retry;
 				}
 
 			} else {
 				if (mem_resource_inuse->child) {
-					mem_resource_inuse = 
+					mem_resource_inuse =
 						mem_resource_inuse->child;
-					pciauto_lower_memspc = 
+					pciauto_lower_memspc =
 						mem_resource_inuse->start;
-					pciauto_upper_memspc = 
+					pciauto_upper_memspc =
 						mem_resource_inuse->end + 1;
 					goto retry;
 				}
@@ -230,7 +226,7 @@
 		 * If we are a 64-bit decoder then increment to the
 		 * upper 32 bits of the bar and force it to locate
 		 * in the lower 4GB of memory.
-		 */ 
+		 */
 		if (found_mem64) {
 			bar += 4;
 			early_write_config_dword(hose, top_bus,
@@ -362,7 +358,7 @@
 {
 	u32 temp;
 
-#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
+#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D) && !defined(CONFIG_SH_R7780RP)
 	/*
 	 * [jsun] we always bump up baselines a little, so that if there
 	 * nothing behind P2P bridge, we don't wind up overlapping IO/MEM
@@ -396,7 +392,7 @@
 	 * configured by this routine to happily live behind a
 	 * P2P bridge in a system.
 	 */
-#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D)
+#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D) || defined(CONFIG_SH_R7780RP)
 	pciauto_lower_memspc += 0x00400000;
 	pciauto_lower_iospc += 0x00004000;
 #endif
@@ -433,12 +429,12 @@
 	int devfn_stop = 0xff;
 
 	sub_bus = current_bus;
-	
+
 	if (hose->first_devfn)
 		devfn_start = hose->first_devfn;
 	if (hose->last_devfn)
 		devfn_stop = hose->last_devfn;
-	
+
 	for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
 
 		if (PCI_FUNC(pci_devfn) && !found_multi)
@@ -471,7 +467,7 @@
 		if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) {
 			DBG("        Bridge: primary=%.2x, secondary=%.2x\n",
 				current_bus, sub_bus + 1);
-#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D)
+#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D) || defined(CONFIG_SH_R7780RP)
 			pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_1);
 #endif
 			pciauto_prescan_setup_bridge(hose, top_bus, current_bus,
@@ -490,10 +486,10 @@
 			DBG("PCI Autoconfig: Found CardBus bridge, device %d function %d\n", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn));
 			/* Place CardBus Socket/ExCA registers */
 			pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_0);
- 
+
 			pciauto_prescan_setup_cardbus_bridge(hose, top_bus,
 					current_bus, pci_devfn, sub_bus);
- 
+
 			DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n",
 				sub_bus + 1,
 				pciauto_lower_iospc, pciauto_lower_memspc);
diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c
index 682f3da..65093ec 100644
--- a/arch/sh/drivers/pci/pci-sh7751.c
+++ b/arch/sh/drivers/pci/pci-sh7751.c
@@ -223,7 +223,7 @@
 
 	word = inl(SH7751_BCR1);
 	/* check BCR for SDRAM in area */
-	if(((word >> area) & 1) == 0) {
+	if (((word >> area) & 1) == 0) {
 		printk("PCI: Area %d is not configured for SDRAM. BCR1=0x%x\n",
 		       area, word);
 		return 0;
@@ -232,7 +232,7 @@
 
 	word = (u16)inw(SH7751_BCR2);
 	/* check BCR2 for 32bit SDRAM interface*/
-	if(((word >> (area << 1)) & 0x3) != 0x3) {
+	if (((word >> (area << 1)) & 0x3) != 0x3) {
 		printk("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%x\n",
 		       area, word);
 		return 0;
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
new file mode 100644
index 0000000..e097213
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -0,0 +1,341 @@
+/*
+ *	Low-Level PCI Support for the SH7780
+ *
+ *  Dustin McIntire (dustin@sensoria.com)
+ *	Derived from arch/i386/kernel/pci-*.c which bore the message:
+ *	(c) 1999--2000 Martin Mares <mj@ucw.cz>
+ *
+ *  Ported to the new API by Paul Mundt <lethal@linux-sh.org>
+ *  With cleanup by Paul van Gool <pvangool@mimotech.com>
+ *
+ *  May be copied or modified under the terms of the GNU General Public
+ *  License.  See linux/COPYING for more information.
+ *
+ */
+
+#undef DEBUG
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+
+#include <asm/machvec.h>
+#include <asm/io.h>
+#include "pci-sh7780.h"
+
+static unsigned int pci_probe = PCI_PROBE_CONF1;
+extern int pci_fixup_pcic(void);
+
+/*
+ * Direct access to PCI hardware...
+ */
+
+#define CONFIG_CMD(bus, devfn, where) (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
+
+/*
+ * Functions for accessing PCI configuration space with type 1 accesses
+ */
+static int sh7780_pci_read(struct pci_bus *bus, unsigned int devfn,
+			   int where, int size, u32 *val)
+{
+	unsigned long flags;
+	u32 data;
+
+	/*
+	 * PCIPDR may only be accessed as 32 bit words,
+	 * so we must do byte alignment by hand
+	 */
+	local_irq_save(flags);
+	outl(CONFIG_CMD(bus, devfn, where), PCI_REG(SH7780_PCIPAR));
+	data = inl(PCI_REG(SH7780_PCIPDR));
+	local_irq_restore(flags);
+
+	switch (size) {
+	case 1:
+		*val = (data >> ((where & 3) << 3)) & 0xff;
+		break;
+	case 2:
+		*val = (data >> ((where & 2) << 3)) & 0xffff;
+		break;
+	case 4:
+		*val = data;
+		break;
+	default:
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * Since SH7780 only does 32bit access we'll have to do a read,
+ * mask,write operation.
+ * We'll allow an odd byte offset, though it should be illegal.
+ */
+static int sh7780_pci_write(struct pci_bus *bus, unsigned int devfn,
+			    int where, int size, u32 val)
+{
+	unsigned long flags;
+	int shift;
+	u32 data;
+
+	local_irq_save(flags);
+	outl(CONFIG_CMD(bus, devfn, where), PCI_REG(SH7780_PCIPAR));
+	data = inl(PCI_REG(SH7780_PCIPDR));
+	local_irq_restore(flags);
+
+	switch (size) {
+	case 1:
+		shift = (where & 3) << 3;
+		data &= ~(0xff << shift);
+		data |= ((val & 0xff) << shift);
+		break;
+	case 2:
+		shift = (where & 2) << 3;
+		data &= ~(0xffff << shift);
+		data |= ((val & 0xffff) << shift);
+		break;
+	case 4:
+		data = val;
+		break;
+	default:
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+	}
+
+	outl(data, PCI_REG(SH7780_PCIPDR));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+#undef CONFIG_CMD
+
+struct pci_ops sh7780_pci_ops = {
+	.read		= sh7780_pci_read,
+	.write		= sh7780_pci_write,
+};
+
+static int __init pci_check_direct(void)
+{
+	unsigned int tmp, id;
+
+	outl(0x00000001, SH7780_PCI_VCR2); /* Enable PCIC */
+
+	/* check for SH7780/SH7780R hardware */
+	id = inl(PCI_REG(SH7780_PCIVID));
+	if ((id != ((SH7780_DEVICE_ID << 16) | SH7780_VENDOR_ID)) &&
+	    (id != ((SH7781_DEVICE_ID << 16) | SH7780_VENDOR_ID))) {
+		printk(KERN_ERR "PCI: This is not an SH7780 (%x)\n", id);
+		return -ENODEV;
+	}
+
+	/*
+	 * Check if configuration works.
+	 */
+	if (pci_probe & PCI_PROBE_CONF1) {
+		tmp = inl(PCI_REG(SH7780_PCIPAR));
+		outl(0x80000000, PCI_REG(SH7780_PCIPAR));
+		if (inl(PCI_REG(SH7780_PCIPAR)) == 0x80000000) {
+			outl(tmp, PCI_REG(SH7780_PCIPAR));
+			printk(KERN_INFO "PCI: Using configuration type 1\n");
+			request_region(PCI_REG(SH7780_PCIPAR), 8, "PCI conf1");
+			return 0;
+		}
+		outl(tmp, PCI_REG(SH7780_PCIPAR));
+	}
+
+	pr_debug("PCI: pci_check_direct failed\n");
+	return -EINVAL;
+}
+
+/***************************************************************************************/
+
+/*
+ *  Handle bus scanning and fixups ....
+ */
+
+static void __init pci_fixup_ide_bases(struct pci_dev *d)
+{
+	int i;
+
+	/*
+	 * PCI IDE controllers use non-standard I/O port decoding, respect it.
+	 */
+	if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
+		return;
+	pr_debug("PCI: IDE base address fixup for %s\n", pci_name(d));
+	for(i=0; i<4; i++) {
+		struct resource *r = &d->resource[i];
+		if ((r->start & ~0x80) == 0x374) {
+			r->start |= 2;
+			r->end = r->start;
+		}
+	}
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
+
+/*
+ *  Called after each bus is probed, but before its children
+ *  are examined.
+ */
+
+void __init pcibios_fixup_bus(struct pci_bus *b)
+{
+	pci_read_bridge_bases(b);
+}
+
+/*
+ * Initialization. Try all known PCI access methods. Note that we support
+ * using both PCI BIOS and direct access: in such cases, we use I/O ports
+ * to access config space.
+ *
+ * Note that the platform specific initialization (BSC registers, and memory
+ * space mapping) will be called via the machine vectors (sh_mv.mv_pci_init()) if it
+ * exists and via the platform defined function pcibios_init_platform().
+ * See pci_bigsur.c for implementation;
+ *
+ * The BIOS version of the pci functions is not yet implemented but it is left
+ * in for completeness.  Currently an error will be genereated at compile time.
+ */
+
+static int __init sh7780_pci_init(void)
+{
+	int ret;
+
+	pr_debug("PCI: Starting intialization.\n");
+
+	/* Setup the INTC */
+	ctrl_outl(0x00200000, INTC_ICR0);	/* INTC SH-4 Mode */
+	ctrl_outl(0x00078000, INTC_INT2MSKCR);	/* enable PCIINTA - PCIINTD */
+	ctrl_outl(0x40000000, INTC_INTMSK1);	/* disable IRL4-7 Interrupt */
+	ctrl_outl(0x0000fffe, INTC_INTMSK2);	/* disable IRL4-7 Interrupt */
+	ctrl_outl(0x80000000, INTC_INTMSKCLR1);	/* enable IRL0-3 Interrupt */
+	ctrl_outl(0xfffe0000, INTC_INTMSKCLR2);	/* enable IRL0-3 Interrupt */
+
+	if ((ret = pci_check_direct()) != 0)
+		return ret;
+
+	return pcibios_init_platform();
+}
+
+core_initcall(sh7780_pci_init);
+
+int __init sh7780_pcic_init(struct sh7780_pci_address_map *map)
+{
+	u32 word;
+
+	/*
+	 * This code is unused for some boards as it is done in the
+	 * bootloader and doing it here means the MAC addresses loaded
+	 * by the bootloader get lost.
+	 */
+	if (!(map->flags & SH7780_PCIC_NO_RESET)) {
+		/* toggle PCI reset pin */
+		word = SH7780_PCICR_PREFIX | SH7780_PCICR_PRST;
+		outl(word,PCI_REG(SH7780_PCICR));
+		/* Wait for a long time... not 1 sec. but long enough */
+		mdelay(100);
+		word = SH7780_PCICR_PREFIX;
+		outl(word,PCI_REG(SH7780_PCICR));
+	}
+
+	/* set the command/status bits to:
+	 * Wait Cycle Control + Parity Enable + Bus Master +
+	 * Mem space enable
+	 */
+	outl(0x00000046, PCI_REG(SH7780_PCICMD));
+
+	/* define this host as the host bridge */
+	word = SH7780_PCI_HOST_BRIDGE << 24;
+	outl(word, PCI_REG(SH7780_PCIRID));
+
+	/* Set IO and Mem windows to local address
+	 * Make PCI and local address the same for easy 1 to 1 mapping
+	 * Window0 = map->window0.size @ non-cached area base = SDRAM
+	 * Window1 = map->window1.size @ cached area base = SDRAM
+	 */
+	word = ((map->window0.size - 1) & 0x1ff00001) | 0x01;
+	outl(0x07f00001, PCI_REG(SH7780_PCILSR0));
+	word = ((map->window1.size - 1) & 0x1ff00001) | 0x01;
+	outl(0x00000001, PCI_REG(SH7780_PCILSR1));
+	/* Set the values on window 0 PCI config registers */
+	word = P2SEGADDR(map->window0.base);
+	outl(0xa8000000, PCI_REG(SH7780_PCILAR0));
+	outl(0x08000000, PCI_REG(SH7780_PCIMBAR0));
+	/* Set the values on window 1 PCI config registers */
+	word = P2SEGADDR(map->window1.base);
+	outl(0x00000000, PCI_REG(SH7780_PCILAR1));
+	outl(0x00000000, PCI_REG(SH7780_PCIMBAR1));
+
+	/* Map IO space into PCI IO window
+	 * The IO window is 64K-PCIBIOS_MIN_IO in size
+	 * IO addresses will be translated to the
+	 * PCI IO window base address
+	 */
+	PCIDBG(3,"PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", PCIBIOS_MIN_IO,
+	    (64*1024), SH7780_PCI_IO_BASE+PCIBIOS_MIN_IO);
+
+	/* NOTE: I'm ignoring the PCI error IRQs for now..
+	 * TODO: add support for the internal error interrupts and
+	 * DMA interrupts...
+	 */
+
+#ifdef CONFIG_SH_R7780RP
+	pci_fixup_pcic();
+#endif
+
+	/* SH7780 init done, set central function init complete */
+	/* use round robin mode to stop a device starving/overruning */
+	word = SH7780_PCICR_PREFIX | SH7780_PCICR_CFIN | /* SH7780_PCICR_ARBM |*/ SH7780_PCICR_FTO;
+	outl(word, PCI_REG(SH7780_PCICR));
+
+	return 1;
+}
+
+char * __init pcibios_setup(char *str)
+{
+	if (!strcmp(str, "off")) {
+		pci_probe = 0;
+		return NULL;
+	}
+
+	return str;
+}
+
+/*
+ *	IRQ functions
+ */
+static u8 __init sh7780_no_swizzle(struct pci_dev *dev, u8 *pin)
+{
+	/* no swizzling */
+	return PCI_SLOT(dev->devfn);
+}
+
+static int sh7780_pci_lookup_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int irq = -1;
+
+	/* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */
+	irq = pcibios_map_platform_irq(slot,pin);
+	if( irq < 0 ) {
+		pr_debug("PCI: Error mapping IRQ on device %s\n", pci_name(dev));
+		return irq;
+	}
+
+	pr_debug("Setting IRQ for slot %s to %d\n", pci_name(dev), irq);
+
+	return irq;
+}
+
+void __init pcibios_fixup_irqs(void)
+{
+	pci_fixup_irqs(sh7780_no_swizzle, sh7780_pci_lookup_irq);
+}
+
diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h
new file mode 100644
index 0000000..750d5d7
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-sh7780.h
@@ -0,0 +1,168 @@
+/*
+ *	Low-Level PCI Support for SH7780 targets
+ *
+ *  Dustin McIntire (dustin@sensoria.com) (c) 2001
+ *  Paul Mundt (lethal@linux-sh.org) (c) 2003
+ *
+ *  May be copied or modified under the terms of the GNU General Public
+ *  License.  See linux/COPYING for more information.
+ *
+ */
+
+#ifndef _PCI_SH7780_H_
+#define _PCI_SH7780_H_
+
+#include <linux/pci.h>
+
+/* set debug level 4=verbose...1=terse */
+//#define DEBUG_PCI 3
+#undef DEBUG_PCI
+
+#ifdef DEBUG_PCI
+#define PCIDBG(n, x...) { if(DEBUG_PCI>=n) printk(x); }
+#else
+#define PCIDBG(n, x...)
+#endif
+
+/* startup values */
+#define PCI_PROBE_BIOS		1
+#define PCI_PROBE_CONF1		2
+#define PCI_PROBE_CONF2		4
+#define PCI_NO_SORT		0x100
+#define PCI_BIOS_SORT		0x200
+#define PCI_NO_CHECKS		0x400
+#define PCI_ASSIGN_ROMS		0x1000
+#define PCI_BIOS_IRQ_SCAN	0x2000
+
+/* Platform Specific Values */
+#define SH7780_VENDOR_ID	0x1912
+#define SH7780_DEVICE_ID	0x0002
+#define SH7781_DEVICE_ID	0x0001
+
+/* SH7780 Control Registers */
+#define	SH7780_PCI_VCR0		0xFE000000
+#define	SH7780_PCI_VCR1		0xFE000004
+#define	SH7780_PCI_VCR2		0xFE000008
+
+/* SH7780 Specific Values */
+#define SH7780_PCI_CONFIG_BASE	0xFD000000	/* Config space base addr */
+#define SH7780_PCI_CONFIG_SIZE	0x01000000	/* Config space size */
+#define SH7780_PCI_MEMORY_BASE	0xFD000000	/* Memory space base addr */
+#define SH7780_PCI_MEM_SIZE	0x01000000	/* Size of Memory window */
+#if 1
+#define SH7780_PCI_IO_BASE	0xFE400000	/* IO space base address */
+#define SH7780_PCI_IO_SIZE	0x00400000	/* Size of IO window */
+#else
+#define SH7780_PCI_IO_BASE	0xFE200000	/* IO space base address */
+#define SH7780_PCI_IO_SIZE	0x00200000	/* Size of IO window */
+#endif
+
+#define SH7780_PCIREG_BASE	0xFE040000	/* PCI regs base address */
+#define PCI_REG(n)		(SH7780_PCIREG_BASE+n)
+
+/* SH7780 PCI Config Registers */
+#define SH7780_PCIVID		0x000		/* Vendor ID */
+#define SH7780_PCIDID		0x002		/* Device ID */
+#define SH7780_PCICMD		0x004		/* Command */
+#define SH7780_PCISTATUS	0x006		/* Status */
+#define SH7780_PCIRID		0x008		/* Revision ID */
+#define SH7780_PCIPIF		0x009		/* Program Interface */
+#define SH7780_PCISUB		0x00a		/* Sub class code */
+#define SH7780_PCIBCC		0x00b		/* Base class code */
+#define SH7780_PCICLS		0x00c		/* Cache line size */
+#define SH7780_PCILTM		0x00d		/* latency timer */
+#define SH7780_PCIHDR		0x00e		/* Header type */
+#define SH7780_PCIBIST		0x00f		/* BIST */
+#define SH7780_PCIIBAR		0x010		/* IO Base address */
+#define SH7780_PCIMBAR0		0x014		/* Memory base address0 */
+#define SH7780_PCIMBAR1		0x018		/* Memory base address1 */
+#define SH7780_PCISVID		0x02c		/* Sub system vendor ID */
+#define SH7780_PCISID		0x02e		/* Sub system ID */
+#define SH7780_PCICP		0x034
+#define SH7780_PCIINTLINE	0x03c		/* Interrupt line */
+#define SH7780_PCIINTPIN	0x03d		/* Interrupt pin */
+#define SH7780_PCIMINGNT	0x03e		/* Minumum grand */
+#define SH7780_PCIMAXLAT	0x03f		/* Maxmum latency */
+#define SH7780_PCICID		0x040
+#define SH7780_PCINIP		0x041
+#define SH7780_PCIPMC		0x042
+#define SH7780_PCIPMCSR		0x044
+#define SH7780_PCIPMCSR_BSE	0x046
+#define SH7780_PCICDD		0x047
+
+/* SH7780 PCI Local Registers */
+#define SH7780_PCICR		0x100		/* PCI Control Register */
+  #define SH7780_PCICR_PREFIX	0xA5000000	/* CR prefix for write */
+  #define SH7780_PCICR_PFCS	0x00000800	/* TRDY/IRDY Enable */
+  #define SH7780_PCICR_FTO	0x00000400	/* TRDY/IRDY Enable */
+  #define SH7780_PCICR_PFE	0x00000200	/* Target Read Single */
+  #define SH7780_PCICR_TBS	0x00000100	/* Target Byte Swap */
+  #define SH7780_PCICR_ARBM	0x00000040	/* PCI Arbitration Mode */
+  #define SH7780_PCICR_IOCS	0x00000004	/* INTA output assert */
+  #define SH7780_PCICR_PRST	0x00000002	/* PCI Reset Assert */
+  #define SH7780_PCICR_CFIN	0x00000001	/* Central Fun. Init Done */
+#define SH7780_PCILSR0		0x104		/* PCI Local Space Register0 */
+#define SH7780_PCILSR1		0x108		/* PCI Local Space Register1 */
+#define SH7780_PCILAR0		0x10C	/* PCI Local Address Register1 */
+#define SH7780_PCILAR1		0x110	/* PCI Local Address Register1 */
+#define SH7780_PCIIR		0x114		/* PCI Interrupt Register */
+#define SH7780_PCIIMR		0x118	/* PCI Interrupt Mask Register */
+#define SH7780_PCIAIR		0x11C		/* Error Address Register */
+#define SH7780_PCICIR		0x120	/* Error Command/Data Register */
+#define SH7780_PCIAINT		0x130		/* Arbiter Interrupt Register */
+#define SH7780_PCIAINTM		0x134		/* Arbiter Int. Mask Register */
+#define SH7780_PCIBMIR		0x138		/* Error Bus Master Register */
+#define SH7780_PCIPAR		0x1C0		/* PIO Address Register */
+#define SH7780_PCIPINT		0x1CC	/* Power Management Int. Register */
+#define SH7780_PCIPINTM		0x1D0	/* Power Management Mask Register */
+#define SH7780_PCIMBR0		0x1E0		/* Memory Bank0 Register */
+#define SH7780_PCIMBMR0		0x1E4		/* Memory Bank0 Mask Register */
+#define SH7780_PCIMBR1		0x1E8		/* Memory Bank1  Register */
+#define SH7780_PCIMBMR1		0x1EC		/* Memory Bank1 Mask Register */
+#define SH7780_PCIMBR2		0x1F0		/* Memory Bank2 Register */
+#define SH7780_PCIMBMR2		0x1F4		/* Memory Bank2 Mask Register */
+#define SH7780_PCIIOBR		0x1F8		/* Bank Register */
+#define SH7780_PCIIOBMR		0x1FC		/* Bank Mask Register */
+#define SH7780_PCICSCR0		0x210		/* Cache Snoop1 Cnt. Register */
+#define SH7780_PCICSCR1		0x214		/* Cache Snoop2 Cnt. Register */
+#define SH7780_PCICSAR0		0x218	/* Cache Snoop1 Addr. Register */
+#define SH7780_PCICSAR1		0x21C	/* Cache Snoop2 Addr. Register */
+#define SH7780_PCIPDR		0x220		/* Port IO Data Register */
+
+/* General Memory Config Addresses */
+#define SH7780_CS0_BASE_ADDR	0x0
+#define SH7780_MEM_REGION_SIZE	0x04000000
+#define SH7780_CS1_BASE_ADDR	(SH7780_CS0_BASE_ADDR + SH7780_MEM_REGION_SIZE)
+#define SH7780_CS2_BASE_ADDR	(SH7780_CS1_BASE_ADDR + SH7780_MEM_REGION_SIZE)
+#define SH7780_CS3_BASE_ADDR	(SH7780_CS2_BASE_ADDR + SH7780_MEM_REGION_SIZE)
+#define SH7780_CS4_BASE_ADDR	(SH7780_CS3_BASE_ADDR + SH7780_MEM_REGION_SIZE)
+#define SH7780_CS5_BASE_ADDR	(SH7780_CS4_BASE_ADDR + SH7780_MEM_REGION_SIZE)
+#define SH7780_CS6_BASE_ADDR	(SH7780_CS5_BASE_ADDR + SH7780_MEM_REGION_SIZE)
+
+/* General PCI values */
+#define SH7780_PCI_HOST_BRIDGE	0x6
+
+/* Flags */
+#define SH7780_PCIC_NO_RESET	0x0001
+
+/* External functions defined per platform i.e. Big Sur, SE... (these could be routed
+ * through the machine vectors... */
+extern int pcibios_init_platform(void);
+extern int pcibios_map_platform_irq(u8 slot, u8 pin);
+
+struct sh7780_pci_address_space {
+	unsigned long base;
+	unsigned long size;
+};
+
+struct sh7780_pci_address_map {
+	struct sh7780_pci_address_space window0;
+	struct sh7780_pci_address_space window1;
+	unsigned long flags;
+};
+
+/* arch/sh/drivers/pci/pci-sh7780.c */
+extern int sh7780_pcic_init(struct sh7780_pci_address_map *map);
+
+#endif /* _PCI_SH7780_H_ */
+