summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-06-23 19:27:00 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-06-23 19:27:00 -0700
commitcc93d69c98f2acf35b0fba2930a592c598054419 (patch)
treef3628fece1a9551a908cc2ddad9804e8539d206c
parent125190efd98a565b4ec64868ba273da25616443c (diff)
[PATCH] sh: PCI updates
From: Paul Mundt <lethal@Linux-SH.ORG> This updates the pci-auto code, as well as adding ops and fixups for the RTS7751R2D board. Signed-off-by: Paul Mundt <lethal@linux-sh.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/sh/drivers/pci/Makefile1
-rw-r--r--arch/sh/drivers/pci/fixups-rts7751r2d.c32
-rw-r--r--arch/sh/drivers/pci/ops-rts7751r2d.c74
-rw-r--r--arch/sh/drivers/pci/ops-snapgear.c2
-rw-r--r--arch/sh/drivers/pci/pci-auto.c221
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.c37
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.h7
-rw-r--r--arch/sh/drivers/pci/pci.c2
8 files changed, 260 insertions, 116 deletions
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile
index 20e928162d1b..4923bbf5e8a9 100644
--- a/arch/sh/drivers/pci/Makefile
+++ b/arch/sh/drivers/pci/Makefile
@@ -12,4 +12,5 @@ obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \
dma-dreamcast.o
obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o
obj-$(CONFIG_SH_BIGSUR) += ops-bigsur.o
+obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o
diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c
new file mode 100644
index 000000000000..7b5dbe157867
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c
@@ -0,0 +1,32 @@
+/*
+ * arch/sh/drivers/pci/fixups-rts7751r2d.c
+ *
+ * RTS7751R2D 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-sh7751.h"
+#include <asm/io.h>
+
+#define PCIMCR_MRSET_OFF 0xBFFFFFFF
+#define PCIMCR_RFSH_OFF 0xFFFFFFFB
+
+int pci_fixup_pcic(void)
+{
+ unsigned long mcr;
+
+ outl(0xfb900047, SH7751_PCICONF1);
+ outl(0xab000001, SH7751_PCICONF4);
+
+ mcr = inl(SH7751_MCR);
+ mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
+ outl(mcr, SH7751_PCIMCR);
+
+ return 0;
+}
+
diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c
new file mode 100644
index 000000000000..2bceb43c9a33
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-rts7751r2d.c
@@ -0,0 +1,74 @@
+/*
+ * linux/arch/sh/kernel/pci-rts7751r2d.c
+ *
+ * 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 SH7751R RTS7751R2D 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-sh7751.h"
+#include <asm/rts7751r2d/rts7751r2d.h>
+
+int __init pcibios_map_platform_irq(u8 slot, u8 pin)
+{
+ switch (slot) {
+ case 0: return IRQ_PCISLOT1; /* PCI Extend slot #1 */
+ case 1: return IRQ_PCISLOT2; /* PCI Extend slot #2 */
+ case 2: return IRQ_PCMCIA; /* PCI Cardbus Bridge */
+ case 3: return IRQ_PCIETH; /* Realtek Ethernet controller */
+ default:
+ printk("PCI: Bad IRQ mapping request for slot %d\n", slot);
+ return -1;
+ }
+}
+
+static struct resource sh7751_io_resource = {
+ .name = "SH7751_IO",
+ .start = 0x4000,
+ .end = 0x4000 + SH7751_PCI_IO_SIZE - 1,
+ .flags = IORESOURCE_IO
+};
+
+static struct resource sh7751_mem_resource = {
+ .name = "SH7751_mem",
+ .start = SH7751_PCI_MEMORY_BASE,
+ .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
+ .flags = IORESOURCE_MEM
+};
+
+extern struct pci_ops sh7751_pci_ops;
+
+struct pci_channel board_pci_channels[] = {
+ { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
+ { NULL, NULL, NULL, 0, 0 },
+};
+EXPORT_SYMBOL(board_pci_channels);
+
+static struct sh7751_pci_address_map sh7751_pci_map = {
+ .window0 = {
+ .base = SH7751_CS3_BASE_ADDR,
+ .size = 0x03f00000,
+ },
+
+ .flags = SH7751_PCIC_NO_RESET,
+};
+
+int __init pcibios_init_platform(void)
+{
+ return sh7751_pcic_init(&sh7751_pci_map);
+}
+
diff --git a/arch/sh/drivers/pci/ops-snapgear.c b/arch/sh/drivers/pci/ops-snapgear.c
index b44fe7f5356c..6fdb9765c99a 100644
--- a/arch/sh/drivers/pci/ops-snapgear.c
+++ b/arch/sh/drivers/pci/ops-snapgear.c
@@ -61,6 +61,8 @@ static struct sh7751_pci_address_map sh7751_pci_map = {
.base = SH7751_CS2_BASE_ADDR,
.size = SNAPGEAR_LSR1_SIZE,
},
+
+ .flags = SH7751_PCIC_NO_RESET,
};
/*
diff --git a/arch/sh/drivers/pci/pci-auto.c b/arch/sh/drivers/pci/pci-auto.c
index 65fb8832f3d7..2ad70d499114 100644
--- a/arch/sh/drivers/pci/pci-auto.c
+++ b/arch/sh/drivers/pci/pci-auto.c
@@ -45,7 +45,7 @@
#include <linux/types.h>
#include <linux/pci.h>
-#define DEBUG
+#undef DEBUG
#ifdef DEBUG
#define DBG(x...) printk(x)
#else
@@ -106,7 +106,8 @@ static void __init
pciauto_setup_bars(struct pci_channel *hose,
int top_bus,
int current_bus,
- int pci_devfn)
+ int pci_devfn,
+ int bar_limit)
{
u32 bar_response, bar_size, bar_value;
u32 bar, addr_mask, bar_nr = 0;
@@ -114,7 +115,8 @@ pciauto_setup_bars(struct pci_channel *hose,
u32 * lower_limit;
int found_mem64 = 0;
- for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar+=4) {
+ 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 */
@@ -123,6 +125,7 @@ pciauto_setup_bars(struct pci_channel *hose,
pci_devfn,
bar,
&bar_addr);
+#endif
/* Tickle the BAR and get the response */
early_write_config_dword(hose, top_bus,
@@ -137,6 +140,7 @@ pciauto_setup_bars(struct pci_channel *hose,
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
@@ -147,6 +151,7 @@ pciauto_setup_bars(struct pci_channel *hose,
pci_devfn,
bar,
bar_addr);
+#endif
/* If BAR is not implemented go to the next BAR */
if (!bar_response)
@@ -287,6 +292,11 @@ pciauto_postscan_setup_bridge(struct pci_channel *hose,
{
u32 temp;
+ /*
+ * [jsun] we always bump up baselines a little, so that if there
+ * nothing behind P2P bridge, we don't wind up overlapping IO/MEM
+ * spaces.
+ */
pciauto_lower_memspc += 1;
pciauto_lower_iospc += 1;
@@ -318,93 +328,99 @@ pciauto_postscan_setup_bridge(struct pci_channel *hose,
static void __init
pciauto_prescan_setup_cardbus_bridge(struct pci_channel *hose,
- int top_bus,
- int current_bus,
- int pci_devfn,
- int sub_bus)
+ int top_bus,
+ int current_bus,
+ int pci_devfn,
+ int sub_bus)
{
- /* Configure bus number registers */
- early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
- PCI_PRIMARY_BUS, current_bus);
- early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
- PCI_SECONDARY_BUS, sub_bus + 1);
- early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
- PCI_SUBORDINATE_BUS, 0xff);
-
- /* Align memory and I/O to 4KB and 4 byte boundaries. */
- pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1))
- & ~(0x1000 - 1);
- pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1))
- & ~(0x4 - 1);
-
- early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
- PCI_CB_MEMORY_BASE_0, pciauto_lower_memspc);
- early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
- PCI_CB_IO_BASE_0, pciauto_lower_iospc);
+ /* Configure bus number registers */
+ early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
+ PCI_PRIMARY_BUS, current_bus);
+ early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
+ PCI_SECONDARY_BUS, sub_bus + 1);
+ early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
+ PCI_SUBORDINATE_BUS, 0xff);
+
+ /* Align memory and I/O to 4KB and 4 byte boundaries. */
+ pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1))
+ & ~(0x1000 - 1);
+ pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1))
+ & ~(0x4 - 1);
+
+ early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
+ PCI_CB_MEMORY_BASE_0, pciauto_lower_memspc);
+ early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
+ PCI_CB_IO_BASE_0, pciauto_lower_iospc);
}
static void __init
pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose,
- int top_bus,
- int current_bus,
- int pci_devfn,
- int sub_bus)
+ int top_bus,
+ int current_bus,
+ int pci_devfn,
+ int sub_bus)
{
- u32 temp;
-
- /*
- * [jsun] we always bump up baselines a little, so that if there
- * nothing behind P2P bridge, we don't wind up overlapping IO/MEM
- * spaces.
- */
- pciauto_lower_memspc += 1;
- pciauto_lower_iospc += 1;
-
- /*
- * Configure subordinate bus number. The PCI subsystem
- * bus scan will renumber buses (reserving three additional
- * for this PCI<->CardBus bridge for the case where a CardBus
- * adapter contains a P2P or CB2CB bridge.
- */
-
- early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
- PCI_SUBORDINATE_BUS, sub_bus);
-
- /*
- * Reserve an additional 4MB for mem space and 16KB for
- * I/O space. This should cover any additional space
- * requirement of unusual CardBus devices with
- * additional bridges that can consume more address space.
- *
- * Although pcmcia-cs currently will reprogram bridge
- * windows, the goal is to add an option to leave them
- * alone and use the bridge window ranges as the regions
- * that are searched for free resources upon hot-insertion
- * of a device. This will allow a PCI<->CardBus bridge
- * configured by this routine to happily live behind a
- * P2P bridge in a system.
- */
-
- /* Align memory and I/O to 4KB and 4 byte boundaries. */
- pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1))
- & ~(0x1000 - 1);
- pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1))
- & ~(0x4 - 1);
- /* Set up memory and I/O filter limits, assume 32-bit I/O space */
- early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
- PCI_CB_MEMORY_LIMIT_0, pciauto_lower_memspc - 1);
- early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
- PCI_CB_IO_LIMIT_0, pciauto_lower_iospc - 1);
-
- /* Enable memory and I/O accesses, enable bus master */
- early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
- PCI_COMMAND, &temp);
- early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
- PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY
- | PCI_COMMAND_MASTER);
+ u32 temp;
+
+#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
+ /*
+ * [jsun] we always bump up baselines a little, so that if there
+ * nothing behind P2P bridge, we don't wind up overlapping IO/MEM
+ * spaces.
+ */
+ pciauto_lower_memspc += 1;
+ pciauto_lower_iospc += 1;
+#endif
+
+ /*
+ * Configure subordinate bus number. The PCI subsystem
+ * bus scan will renumber buses (reserving three additional
+ * for this PCI<->CardBus bridge for the case where a CardBus
+ * adapter contains a P2P or CB2CB bridge.
+ */
+
+ early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
+ PCI_SUBORDINATE_BUS, sub_bus);
+
+ /*
+ * Reserve an additional 4MB for mem space and 16KB for
+ * I/O space. This should cover any additional space
+ * requirement of unusual CardBus devices with
+ * additional bridges that can consume more address space.
+ *
+ * Although pcmcia-cs currently will reprogram bridge
+ * windows, the goal is to add an option to leave them
+ * alone and use the bridge window ranges as the regions
+ * that are searched for free resources upon hot-insertion
+ * of a device. This will allow a PCI<->CardBus bridge
+ * configured by this routine to happily live behind a
+ * P2P bridge in a system.
+ */
+#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D)
+ pciauto_lower_memspc += 0x00400000;
+ pciauto_lower_iospc += 0x00004000;
+#endif
+
+ /* Align memory and I/O to 4KB and 4 byte boundaries. */
+ pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1))
+ & ~(0x1000 - 1);
+ pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1))
+ & ~(0x4 - 1);
+ /* Set up memory and I/O filter limits, assume 32-bit I/O space */
+ early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
+ PCI_CB_MEMORY_LIMIT_0, pciauto_lower_memspc - 1);
+ early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
+ PCI_CB_IO_LIMIT_0, pciauto_lower_iospc - 1);
+
+ /* Enable memory and I/O accesses, enable bus master */
+ early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
+ PCI_COMMAND, &temp);
+ early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
+ PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER);
}
-#define PCIAUTO_IDE_MODE_MASK 0x05
+#define PCIAUTO_IDE_MODE_MASK 0x05
static int __init
pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus)
@@ -455,6 +471,9 @@ pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus)
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)
+ pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_1);
+#endif
pciauto_prescan_setup_bridge(hose, top_bus, current_bus,
pci_devfn, sub_bus);
DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n",
@@ -463,26 +482,26 @@ pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus)
sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1);
DBG("Back to bus %.2x\n", current_bus);
pciauto_postscan_setup_bridge(hose, top_bus, current_bus,
- pci_devfn, sub_bus);
+ pci_devfn, sub_bus);
continue;
- } else if ((pci_class >> 16) == PCI_CLASS_BRIDGE_CARDBUS) {
- DBG(" CARDBUS Bridge: primary=%.2x, secondary=%.2x\n",
- current_bus, sub_bus + 1);
- 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);
+ } else if ((pci_class >> 16) == PCI_CLASS_BRIDGE_CARDBUS) {
+ DBG(" CARDBUS Bridge: primary=%.2x, secondary=%.2x\n",
+ current_bus, sub_bus + 1);
+ 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);
+ 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);
- sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1);
- DBG("Back to bus %.2x, sub_bus is %x\n", current_bus, sub_bus);
- pciauto_postscan_setup_cardbus_bridge(hose, top_bus,
- current_bus, pci_devfn, sub_bus);
- continue;
+ DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n",
+ sub_bus + 1,
+ pciauto_lower_iospc, pciauto_lower_memspc);
+ sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1);
+ DBG("Back to bus %.2x, sub_bus is %x\n", current_bus, sub_bus);
+ pciauto_postscan_setup_cardbus_bridge(hose, top_bus,
+ current_bus, pci_devfn, sub_bus);
+ continue;
} else if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) {
unsigned char prg_iface;
@@ -495,7 +514,7 @@ pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus)
}
}
- /*
+ /*
* Found a peripheral, enable some standard
* settings
*/
@@ -509,7 +528,7 @@ pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus)
PCI_LATENCY_TIMER, 0x80);
/* Allocate PCI I/O and/or memory space */
- pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn);
+ pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_5);
}
return sub_bus;
}
diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c
index e53823e65dcc..b2bb72972bdb 100644
--- a/arch/sh/drivers/pci/pci-sh7751.c
+++ b/arch/sh/drivers/pci/pci-sh7751.c
@@ -31,6 +31,7 @@
#include "pci-sh7751.h"
static unsigned int pci_probe = PCI_PROBE_CONF1;
+extern int pci_fixup_pcic(void);
/*
* Direct access to PCI hardware...
@@ -74,7 +75,8 @@ static int sh7751_pci_read(struct pci_bus *bus, unsigned int devfn,
}
/*
- * Since SH7751 only does 32bit access we'll have to do a read,mask,write operation.
+ * Since SH7751 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 sh7751_pci_write(struct pci_bus *bus, unsigned int devfn,
@@ -156,6 +158,7 @@ static int __init pci_check_direct(void)
* Handle bus scanning and fixups ....
*/
+#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
static void __init pci_fixup_ide_bases(struct pci_dev *d)
{
int i;
@@ -174,11 +177,13 @@ static void __init pci_fixup_ide_bases(struct pci_dev *d)
}
}
}
-
+#endif
/* Add future fixups here... */
struct pci_fixup pcibios_fixups[] = {
+#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
{ PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases },
+#endif
{ 0 }
};
@@ -261,19 +266,19 @@ int __init sh7751_pcic_init(struct sh7751_pci_address_map *map)
outl(word, PCI_REG(SH7751_PCICLKR));
/*
- * XXX: This code is unused for the SnapGear boards as it is done in
- * the bootloader and doing it here means the MAC addresses loaded by
- * the bootloader get lost.
+ * 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.
*/
-#ifndef CONFIG_SH_SECUREEDGE5410
- /* toggle PCI reset pin */
- word = SH7751_PCICR_PREFIX | SH7751_PCICR_PRST;
- outl(word,PCI_REG(SH7751_PCICR));
- /* Wait for a long time... not 1 sec. but long enough */
- mdelay(100);
- word = SH7751_PCICR_PREFIX;
- outl(word,PCI_REG(SH7751_PCICR));
-#endif
+ if (!(map->flags & SH7751_PCIC_NO_RESET)) {
+ /* toggle PCI reset pin */
+ word = SH7751_PCICR_PREFIX | SH7751_PCICR_PRST;
+ outl(word,PCI_REG(SH7751_PCICR));
+ /* Wait for a long time... not 1 sec. but long enough */
+ mdelay(100);
+ word = SH7751_PCICR_PREFIX;
+ outl(word,PCI_REG(SH7751_PCICR));
+ }
/* set the command/status bits to:
* Wait Cycle Control + Parity Enable + Bus Master +
@@ -364,6 +369,10 @@ int __init sh7751_pcic_init(struct sh7751_pci_address_map *map)
* DMA interrupts...
*/
+#ifdef CONFIG_SH_RTS7751R2D
+ pci_fixup_pcic();
+#endif
+
/* SH7751 init done, set central function init complete */
/* use round robin mode to stop a device starving/overruning */
word = SH7751_PCICR_PREFIX | SH7751_PCICR_CFIN | SH7751_PCICR_ARBM;
diff --git a/arch/sh/drivers/pci/pci-sh7751.h b/arch/sh/drivers/pci/pci-sh7751.h
index b8b1d421aec7..1fee5cae10d1 100644
--- a/arch/sh/drivers/pci/pci-sh7751.h
+++ b/arch/sh/drivers/pci/pci-sh7751.h
@@ -234,6 +234,7 @@
#define SH7751_PCIWCR2 0x1EC /* Wait Control 2 Register */
#define SH7751_PCIWCR3 0x1F0 /* Wait Control 3 Register */
#define SH7751_PCIMCR 0x1F4 /* Memory Control Register */
+#define SH7751_PCIBCR3 0x1f8 /* Memory BCR3 Register */
#define SH7751_PCIPCTR 0x200 /* Port Control Register */
#define SH7751_PCIPCTR_P2EN 0x000400000 /* Port 2 Enable */
#define SH7751_PCIPCTR_P1EN 0x000200000 /* Port 1 Enable */
@@ -256,6 +257,8 @@
/* Memory Control Registers */
#define SH7751_BCR1 0xFF800000 /* Memory BCR1 Register */
#define SH7751_BCR2 0xFF800004 /* Memory BCR2 Register */
+#define SH7751_BCR3 0xFF800050 /* Memory BCR3 Register */
+#define SH7751_BCR4 0xFE0A00F0 /* Memory BCR4 Register */
#define SH7751_WCR1 0xFF800008 /* Wait Control 1 Register */
#define SH7751_WCR2 0xFF80000C /* Wait Control 2 Register */
#define SH7751_WCR3 0xFF800010 /* Wait Control 3 Register */
@@ -274,6 +277,9 @@
/* General PCI values */
#define SH7751_PCI_HOST_BRIDGE 0x6
+/* Flags */
+#define SH7751_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);
@@ -287,6 +293,7 @@ struct sh7751_pci_address_space {
struct sh7751_pci_address_map {
struct sh7751_pci_address_space window0;
struct sh7751_pci_address_space window1;
+ unsigned long flags;
};
/* arch/sh/drivers/pci/pci-sh7751.c */
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index fce69a2ecd15..4bf35336d824 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -25,7 +25,7 @@ static int __init pcibios_init(void)
#ifdef CONFIG_PCI_AUTO
/* assign resources */
- busno=0;
+ busno = 0;
for (p = board_pci_channels; p->pci_ops != NULL; p++) {
busno = pciauto_assign_resources(busno, p) + 1;
}