aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-01-28 16:52:50 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-01-28 16:52:50 -0500
commite189f3495c4e30fc84fc9241096edf3932e23439 (patch)
tree5916c89ace81537a02ae01869386ba6caafdab9c /arch/sh/drivers
parentf4798748dee00c807a63f5518f08b3df161e0f6d (diff)
parent6582d7b7376aa587d74b08c74457dc28abc1a9fa (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (197 commits) sh: add spi header and r2d platform data V3 sh: update r7780rp interrupt code sh: remove consistent alloc stuff from the machine vector sh: use declared coherent memory for dreamcast pci ethernet adapter sh: declared coherent memory support V2 sh: Add support for SDK7780 board. sh: constify function pointer tables sh: Kill off -traditional for linker script. cdrom: Add support for Sega Dreamcast GD-ROM. sh: Kill off hs7751rvoip reference from arch/sh/Kconfig. sh: Drop r7780rp_defconfig, use r7780mp_defconfig as kbuild default. sh: Kill off dead HS771RVoIP board support. sh: r7785rp: Fix up DECLARE_INTC_DESC() arg mismatch. sh: r7785rp: Hook up the rest of the HL7785 FPGA IRQ vectors. sh: r2d - enable sm501 usb host function sh: remove voyagergx sh: r2d - add lcd planel timings to sm501 platform data sh: Add OHCI and UDC platform devices for SH7720. sh: intc - remove default interrupt priority tables sh: Correct pte size mismatch for X2 TLB. ...
Diffstat (limited to 'arch/sh/drivers')
-rw-r--r--arch/sh/drivers/dma/Kconfig2
-rw-r--r--arch/sh/drivers/dma/dma-sh.c2
-rw-r--r--arch/sh/drivers/pci/Makefile7
-rw-r--r--arch/sh/drivers/pci/dma-dreamcast.c70
-rw-r--r--arch/sh/drivers/pci/fixups-dreamcast.c10
-rw-r--r--arch/sh/drivers/pci/fixups-sdk7780.c59
-rw-r--r--arch/sh/drivers/pci/ops-cayman.c94
-rw-r--r--arch/sh/drivers/pci/ops-r7780rp.c16
-rw-r--r--arch/sh/drivers/pci/ops-sdk7780.c73
-rw-r--r--arch/sh/drivers/pci/ops-sh5.c93
-rw-r--r--arch/sh/drivers/pci/pci-auto.c2
-rw-r--r--arch/sh/drivers/pci/pci-sh4.h4
-rw-r--r--arch/sh/drivers/pci/pci-sh5.c228
-rw-r--r--arch/sh/drivers/pci/pci-sh5.h113
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c1
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.h1
-rw-r--r--arch/sh/drivers/pci/pci.c2
17 files changed, 686 insertions, 91 deletions
diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig
index 4e711a0c3dae..01936368b8b0 100644
--- a/arch/sh/drivers/dma/Kconfig
+++ b/arch/sh/drivers/dma/Kconfig
@@ -12,7 +12,7 @@ config SH_DMA
12config NR_ONCHIP_DMA_CHANNELS 12config NR_ONCHIP_DMA_CHANNELS
13 int 13 int
14 depends on SH_DMA 14 depends on SH_DMA
15 default "6" if CPU_SUBTYPE_SH7720 15 default "6" if CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721
16 default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R 16 default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R
17 default "12" if CPU_SUBTYPE_SH7780 17 default "12" if CPU_SUBTYPE_SH7780
18 default "4" 18 default "4"
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c
index 958bac1c585a..5c3359756a92 100644
--- a/arch/sh/drivers/dma/dma-sh.c
+++ b/arch/sh/drivers/dma/dma-sh.c
@@ -25,6 +25,7 @@ static int dmte_irq_map[] = {
25 DMTE2_IRQ, 25 DMTE2_IRQ,
26 DMTE3_IRQ, 26 DMTE3_IRQ,
27#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ 27#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
28 defined(CONFIG_CPU_SUBTYPE_SH7721) || \
28 defined(CONFIG_CPU_SUBTYPE_SH7751R) || \ 29 defined(CONFIG_CPU_SUBTYPE_SH7751R) || \
29 defined(CONFIG_CPU_SUBTYPE_SH7760) || \ 30 defined(CONFIG_CPU_SUBTYPE_SH7760) || \
30 defined(CONFIG_CPU_SUBTYPE_SH7709) || \ 31 defined(CONFIG_CPU_SUBTYPE_SH7709) || \
@@ -203,6 +204,7 @@ static int sh_dmac_get_dma_residue(struct dma_channel *chan)
203} 204}
204 205
205#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ 206#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
207 defined(CONFIG_CPU_SUBTYPE_SH7721) || \
206 defined(CONFIG_CPU_SUBTYPE_SH7780) 208 defined(CONFIG_CPU_SUBTYPE_SH7780)
207#define dmaor_read_reg() ctrl_inw(DMAOR) 209#define dmaor_read_reg() ctrl_inw(DMAOR)
208#define dmaor_write_reg(data) ctrl_outw(data, DMAOR) 210#define dmaor_write_reg(data) ctrl_outw(data, DMAOR)
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile
index fba6b5ba0b3a..0718805774e8 100644
--- a/arch/sh/drivers/pci/Makefile
+++ b/arch/sh/drivers/pci/Makefile
@@ -7,16 +7,19 @@ obj-$(CONFIG_PCI_AUTO) += pci-auto.o
7 7
8obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o 8obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o
9obj-$(CONFIG_CPU_SUBTYPE_SH7751R) += pci-sh7751.o ops-sh4.o 9obj-$(CONFIG_CPU_SUBTYPE_SH7751R) += pci-sh7751.o ops-sh4.o
10obj-$(CONFIG_CPU_SUBTYPE_SH7763) += pci-sh7780.o ops-sh4.o
10obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o 11obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o
11obj-$(CONFIG_CPU_SUBTYPE_SH7785) += pci-sh7780.o ops-sh4.o 12obj-$(CONFIG_CPU_SUBTYPE_SH7785) += pci-sh7780.o ops-sh4.o
13obj-$(CONFIG_CPU_SH5) += pci-sh5.o ops-sh5.o
12 14
13obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \ 15obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o
14 dma-dreamcast.o
15obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o 16obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o
16obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o 17obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o
17obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o 18obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o
18obj-$(CONFIG_SH_HIGHLANDER) += ops-r7780rp.o fixups-r7780rp.o 19obj-$(CONFIG_SH_HIGHLANDER) += ops-r7780rp.o fixups-r7780rp.o
20obj-$(CONFIG_SH_SDK7780) += ops-sdk7780.o fixups-sdk7780.o
19obj-$(CONFIG_SH_TITAN) += ops-titan.o 21obj-$(CONFIG_SH_TITAN) += ops-titan.o
20obj-$(CONFIG_SH_LANDISK) += ops-landisk.o 22obj-$(CONFIG_SH_LANDISK) += ops-landisk.o
21obj-$(CONFIG_SH_LBOX_RE2) += ops-lboxre2.o fixups-lboxre2.o 23obj-$(CONFIG_SH_LBOX_RE2) += ops-lboxre2.o fixups-lboxre2.o
22obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += ops-se7780.o fixups-se7780.o 24obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += ops-se7780.o fixups-se7780.o
25obj-$(CONFIG_SH_CAYMAN) += ops-cayman.o
diff --git a/arch/sh/drivers/pci/dma-dreamcast.c b/arch/sh/drivers/pci/dma-dreamcast.c
deleted file mode 100644
index 888a34050599..000000000000
--- a/arch/sh/drivers/pci/dma-dreamcast.c
+++ /dev/null
@@ -1,70 +0,0 @@
1/*
2 * arch/sh/drivers/pci/dma-dreamcast.c
3 *
4 * PCI DMA support for the Sega Dreamcast
5 *
6 * Copyright (C) 2001, 2002 M. R. Brown
7 * Copyright (C) 2002, 2003 Paul Mundt
8 *
9 * This file originally bore the message (with enclosed-$):
10 * Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp
11 * Dreamcast PCI: Supports SEGA Broadband Adaptor only.
12 *
13 * This file is subject to the terms and conditions of the GNU General Public
14 * License. See the file "COPYING" in the main directory of this archive
15 * for more details.
16 */
17
18#include <linux/sched.h>
19#include <linux/kernel.h>
20#include <linux/param.h>
21#include <linux/interrupt.h>
22#include <linux/init.h>
23#include <linux/irq.h>
24#include <linux/pci.h>
25#include <linux/dma-mapping.h>
26#include <linux/device.h>
27
28#include <asm/io.h>
29#include <asm/irq.h>
30#include <asm/mach/pci.h>
31
32static int gapspci_dma_used = 0;
33
34void *dreamcast_consistent_alloc(struct device *dev, size_t size,
35 dma_addr_t *dma_handle, gfp_t flag)
36{
37 unsigned long buf;
38
39 if (dev && dev->bus != &pci_bus_type)
40 return NULL;
41
42 if (gapspci_dma_used + size > GAPSPCI_DMA_SIZE)
43 return ERR_PTR(-EINVAL);
44
45 buf = GAPSPCI_DMA_BASE + gapspci_dma_used;
46
47 gapspci_dma_used = PAGE_ALIGN(gapspci_dma_used+size);
48
49 *dma_handle = (dma_addr_t)buf;
50
51 buf = P2SEGADDR(buf);
52
53 /* Flush the dcache before we hand off the buffer */
54 __flush_purge_region((void *)buf, size);
55
56 return (void *)buf;
57}
58
59int dreamcast_consistent_free(struct device *dev, size_t size,
60 void *vaddr, dma_addr_t dma_handle)
61{
62 if (dev && dev->bus != &pci_bus_type)
63 return -EINVAL;
64
65 /* XXX */
66 gapspci_dma_used = 0;
67
68 return 0;
69}
70
diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c
index 6f53f8200dc3..c44699301eeb 100644
--- a/arch/sh/drivers/pci/fixups-dreamcast.c
+++ b/arch/sh/drivers/pci/fixups-dreamcast.c
@@ -22,6 +22,7 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/irq.h> 23#include <linux/irq.h>
24#include <linux/pci.h> 24#include <linux/pci.h>
25#include <linux/dma-mapping.h>
25 26
26#include <asm/io.h> 27#include <asm/io.h>
27#include <asm/irq.h> 28#include <asm/irq.h>
@@ -40,6 +41,15 @@ static void __init gapspci_fixup_resources(struct pci_dev *dev)
40 */ 41 */
41 dev->resource[1].start = p->io_resource->start + 0x100; 42 dev->resource[1].start = p->io_resource->start + 0x100;
42 dev->resource[1].end = dev->resource[1].start + 0x200 - 1; 43 dev->resource[1].end = dev->resource[1].start + 0x200 - 1;
44 /*
45 * Redirect dma memory allocations to special memory window.
46 */
47 BUG_ON(!dma_declare_coherent_memory(&dev->dev,
48 GAPSPCI_DMA_BASE,
49 GAPSPCI_DMA_BASE,
50 GAPSPCI_DMA_SIZE,
51 DMA_MEMORY_MAP |
52 DMA_MEMORY_EXCLUSIVE));
43 break; 53 break;
44 default: 54 default:
45 printk("PCI: Failed resource fixup\n"); 55 printk("PCI: Failed resource fixup\n");
diff --git a/arch/sh/drivers/pci/fixups-sdk7780.c b/arch/sh/drivers/pci/fixups-sdk7780.c
new file mode 100644
index 000000000000..2f8863099dd1
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-sdk7780.c
@@ -0,0 +1,59 @@
1/*
2 * arch/sh/drivers/pci/fixups-sdk7780.c
3 *
4 * PCI fixups for the SDK7780SE03
5 *
6 * Copyright (C) 2003 Lineo uSolutions, Inc.
7 * Copyright (C) 2004 - 2006 Paul Mundt
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#include <linux/pci.h>
14#include "pci-sh4.h"
15#include <asm/io.h>
16
17int pci_fixup_pcic(void)
18{
19 ctrl_outl(0x00000001, SH7780_PCI_VCR2);
20
21 /* Enable all interrupts, so we know what to fix */
22 pci_write_reg(0x0000C3FF, SH7780_PCIIMR);
23 pci_write_reg(0x0000380F, SH7780_PCIAINTM);
24
25 /* Set up standard PCI config registers */
26 pci_write_reg(0xFB00, SH7780_PCISTATUS);
27 pci_write_reg(0x0047, SH7780_PCICMD);
28 pci_write_reg(0x00, SH7780_PCIPIF);
29 pci_write_reg(0x00, SH7780_PCISUB);
30 pci_write_reg(0x06, SH7780_PCIBCC);
31 pci_write_reg(0x1912, SH7780_PCISVID);
32 pci_write_reg(0x0001, SH7780_PCISID);
33
34 pci_write_reg(0x08000000, SH7780_PCIMBAR0); /* PCI */
35 pci_write_reg(0x08000000, SH7780_PCILAR0); /* SHwy */
36 pci_write_reg(0x07F00001, SH7780_PCILSR); /* size 128M w/ MBAR */
37
38 pci_write_reg(0x00000000, SH7780_PCIMBAR1);
39 pci_write_reg(0x00000000, SH7780_PCILAR1);
40 pci_write_reg(0x00000000, SH7780_PCILSR1);
41
42 pci_write_reg(0xAB000801, SH7780_PCIIBAR);
43
44 /*
45 * Set the MBR so PCI address is one-to-one with window,
46 * meaning all calls go straight through... use ifdef to
47 * catch erroneous assumption.
48 */
49 pci_write_reg(0xFD000000 , SH7780_PCIMBR0);
50 pci_write_reg(0x00FC0000 , SH7780_PCIMBMR0); /* 16M */
51
52 /* Set IOBR for window containing area specified in pci.h */
53 pci_write_reg(PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE-1), SH7780_PCIIOBR);
54 pci_write_reg((SH7780_PCI_IO_SIZE-1) & (7 << 18), SH7780_PCIIOBMR);
55
56 pci_write_reg(0xA5000C01, SH7780_PCICR);
57
58 return 0;
59}
diff --git a/arch/sh/drivers/pci/ops-cayman.c b/arch/sh/drivers/pci/ops-cayman.c
new file mode 100644
index 000000000000..980275ffa30b
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-cayman.c
@@ -0,0 +1,94 @@
1#include <linux/kernel.h>
2#include <linux/init.h>
3#include <linux/pci.h>
4#include <linux/types.h>
5#include <asm/cpu/irq.h>
6#include "pci-sh5.h"
7
8static inline u8 bridge_swizzle(u8 pin, u8 slot)
9{
10 return (((pin - 1) + slot) % 4) + 1;
11}
12
13int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin)
14{
15 int result = -1;
16
17 /* The complication here is that the PCI IRQ lines from the Cayman's 2
18 5V slots get into the CPU via a different path from the IRQ lines
19 from the 3 3.3V slots. Thus, we have to detect whether the card's
20 interrupts go via the 5V or 3.3V path, i.e. the 'bridge swizzling'
21 at the point where we cross from 5V to 3.3V is not the normal case.
22
23 The added complication is that we don't know that the 5V slots are
24 always bus 2, because a card containing a PCI-PCI bridge may be
25 plugged into a 3.3V slot, and this changes the bus numbering.
26
27 Also, the Cayman has an intermediate PCI bus that goes a custom
28 expansion board header (and to the secondary bridge). This bus has
29 never been used in practice.
30
31 The 1ary onboard PCI-PCI bridge is device 3 on bus 0
32 The 2ary onboard PCI-PCI bridge is device 0 on the 2ary bus of
33 the 1ary bridge.
34 */
35
36 struct slot_pin {
37 int slot;
38 int pin;
39 } path[4];
40 int i=0;
41
42 while (dev->bus->number > 0) {
43
44 slot = path[i].slot = PCI_SLOT(dev->devfn);
45 pin = path[i].pin = bridge_swizzle(pin, slot);
46 dev = dev->bus->self;
47 i++;
48 if (i > 3) panic("PCI path to root bus too long!\n");
49 }
50
51 slot = PCI_SLOT(dev->devfn);
52 /* This is the slot on bus 0 through which the device is eventually
53 reachable. */
54
55 /* Now work back up. */
56 if ((slot < 3) || (i == 0)) {
57 /* Bus 0 (incl. PCI-PCI bridge itself) : perform the final
58 swizzle now. */
59 result = IRQ_INTA + bridge_swizzle(pin, slot) - 1;
60 } else {
61 i--;
62 slot = path[i].slot;
63 pin = path[i].pin;
64 if (slot > 0) {
65 panic("PCI expansion bus device found - not handled!\n");
66 } else {
67 if (i > 0) {
68 /* 5V slots */
69 i--;
70 slot = path[i].slot;
71 pin = path[i].pin;
72 /* 'pin' was swizzled earlier wrt slot, don't do it again. */
73 result = IRQ_P2INTA + (pin - 1);
74 } else {
75 /* IRQ for 2ary PCI-PCI bridge : unused */
76 result = -1;
77 }
78 }
79 }
80
81 return result;
82}
83
84struct pci_channel board_pci_channels[] = {
85 { &sh5_pci_ops, NULL, NULL, 0, 0xff },
86 { NULL, NULL, NULL, 0, 0 },
87};
88EXPORT_SYMBOL(board_pci_channels);
89
90int __init pcibios_init_platform(void)
91{
92 return sh5pci_init(__pa(memory_start),
93 __pa(memory_end) - __pa(memory_start));
94}
diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c
index 48fe4032ebea..5fdadaeed6fc 100644
--- a/arch/sh/drivers/pci/ops-r7780rp.c
+++ b/arch/sh/drivers/pci/ops-r7780rp.c
@@ -17,25 +17,13 @@
17#include <asm/io.h> 17#include <asm/io.h>
18#include "pci-sh4.h" 18#include "pci-sh4.h"
19 19
20static char r7780rp_irq_tab[] __initdata = { 20static char irq_tab[] __initdata = {
21 0, 1, 2, 3,
22};
23
24static char r7780mp_irq_tab[] __initdata = {
25 65, 66, 67, 68, 21 65, 66, 67, 68,
26}; 22};
27 23
28int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) 24int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
29{ 25{
30 if (mach_is_r7780rp()) 26 return irq_tab[slot];
31 return r7780rp_irq_tab[slot];
32 if (mach_is_r7780mp() || mach_is_r7785rp())
33 return r7780mp_irq_tab[slot];
34
35 printk(KERN_ERR "PCI: Bad IRQ mapping "
36 "request for slot %d, func %d\n", slot, pin-1);
37
38 return -1;
39} 27}
40 28
41static struct resource sh7780_io_resource = { 29static struct resource sh7780_io_resource = {
diff --git a/arch/sh/drivers/pci/ops-sdk7780.c b/arch/sh/drivers/pci/ops-sdk7780.c
new file mode 100644
index 000000000000..66a9b4047f26
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-sdk7780.c
@@ -0,0 +1,73 @@
1/*
2 * linux/arch/sh/drivers/pci/ops-sdk7780.c
3 *
4 * Copyright (C) 2006 Nobuhiro Iwamatsu
5 *
6 * PCI initialization for the SDK7780SE03
7 *
8 * May be copied or modified under the terms of the GNU General Public
9 * License. See linux/COPYING for more information.
10 */
11#include <linux/kernel.h>
12#include <linux/types.h>
13#include <linux/init.h>
14#include <linux/delay.h>
15#include <linux/pci.h>
16#include <asm/sdk7780.h>
17#include <asm/io.h>
18#include "pci-sh4.h"
19
20/* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */
21static char sdk7780_irq_tab[4][16] __initdata = {
22 /* INTA */
23 { 65, 68, 67, 68, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
24 /* INTB */
25 { 66, 65, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26 /* INTC */
27 { 67, 66, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
28 /* INTD */
29 { 68, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
30};
31
32int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
33{
34 return sdk7780_irq_tab[pin-1][slot];
35}
36
37static struct resource sdk7780_io_resource = {
38 .name = "SH7780_IO",
39 .start = SH7780_PCI_IO_BASE,
40 .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1,
41 .flags = IORESOURCE_IO
42};
43
44static struct resource sdk7780_mem_resource = {
45 .name = "SH7780_mem",
46 .start = SH7780_PCI_MEMORY_BASE,
47 .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1,
48 .flags = IORESOURCE_MEM
49};
50
51struct pci_channel board_pci_channels[] = {
52 { &sh4_pci_ops, &sdk7780_io_resource, &sdk7780_mem_resource, 0, 0xff },
53 { NULL, NULL, NULL, 0, 0 },
54};
55EXPORT_SYMBOL(board_pci_channels);
56
57static struct sh4_pci_address_map sdk7780_pci_map = {
58 .window0 = {
59 .base = SH7780_CS2_BASE_ADDR,
60 .size = 0x04000000,
61 },
62 .window1 = {
63 .base = SH7780_CS3_BASE_ADDR,
64 .size = 0x04000000,
65 },
66 .flags = SH4_PCIC_NO_RESET,
67};
68
69int __init pcibios_init_platform(void)
70{
71 printk(KERN_INFO "SH7780 PCI: Finished initializing PCI controller\n");
72 return sh7780_pcic_init(&sdk7780_pci_map);
73}
diff --git a/arch/sh/drivers/pci/ops-sh5.c b/arch/sh/drivers/pci/ops-sh5.c
new file mode 100644
index 000000000000..729e38a6fe07
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-sh5.c
@@ -0,0 +1,93 @@
1/*
2 * Support functions for the SH5 PCI hardware.
3 *
4 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
5 * Copyright (C) 2003, 2004 Paul Mundt
6 * Copyright (C) 2004 Richard Curnow
7 *
8 * May be copied or modified under the terms of the GNU General Public
9 * License. See linux/COPYING for more information.
10 */
11#include <linux/kernel.h>
12#include <linux/rwsem.h>
13#include <linux/smp.h>
14#include <linux/interrupt.h>
15#include <linux/init.h>
16#include <linux/errno.h>
17#include <linux/pci.h>
18#include <linux/delay.h>
19#include <linux/types.h>
20#include <linux/irq.h>
21#include <asm/pci.h>
22#include <asm/io.h>
23#include "pci-sh5.h"
24
25static void __init pci_fixup_ide_bases(struct pci_dev *d)
26{
27 int i;
28
29 /*
30 * PCI IDE controllers use non-standard I/O port decoding, respect it.
31 */
32 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
33 return;
34 printk("PCI: IDE base address fixup for %s\n", pci_name(d));
35 for(i=0; i<4; i++) {
36 struct resource *r = &d->resource[i];
37 if ((r->start & ~0x80) == 0x374) {
38 r->start |= 2;
39 r->end = r->start;
40 }
41 }
42}
43DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
44
45char * __devinit pcibios_setup(char *str)
46{
47 return str;
48}
49
50static int sh5pci_read(struct pci_bus *bus, unsigned int devfn, int where,
51 int size, u32 *val)
52{
53 SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
54
55 switch (size) {
56 case 1:
57 *val = (u8)SH5PCI_READ_BYTE(PDR + (where & 3));
58 break;
59 case 2:
60 *val = (u16)SH5PCI_READ_SHORT(PDR + (where & 2));
61 break;
62 case 4:
63 *val = SH5PCI_READ(PDR);
64 break;
65 }
66
67 return PCIBIOS_SUCCESSFUL;
68}
69
70static int sh5pci_write(struct pci_bus *bus, unsigned int devfn, int where,
71 int size, u32 val)
72{
73 SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
74
75 switch (size) {
76 case 1:
77 SH5PCI_WRITE_BYTE(PDR + (where & 3), (u8)val);
78 break;
79 case 2:
80 SH5PCI_WRITE_SHORT(PDR + (where & 2), (u16)val);
81 break;
82 case 4:
83 SH5PCI_WRITE(PDR, val);
84 break;
85 }
86
87 return PCIBIOS_SUCCESSFUL;
88}
89
90struct pci_ops sh5_pci_ops = {
91 .read = sh5pci_read,
92 .write = sh5pci_write,
93};
diff --git a/arch/sh/drivers/pci/pci-auto.c b/arch/sh/drivers/pci/pci-auto.c
index 224e007736fb..ea404704ace8 100644
--- a/arch/sh/drivers/pci/pci-auto.c
+++ b/arch/sh/drivers/pci/pci-auto.c
@@ -516,10 +516,8 @@ pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus)
516 PCI_COMMAND, cmdstat | PCI_COMMAND_IO | 516 PCI_COMMAND, cmdstat | PCI_COMMAND_IO |
517 PCI_COMMAND_MEMORY | 517 PCI_COMMAND_MEMORY |
518 PCI_COMMAND_MASTER); 518 PCI_COMMAND_MASTER);
519#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
520 early_write_config_byte(hose, top_bus, current_bus, pci_devfn, 519 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
521 PCI_LATENCY_TIMER, 0x80); 520 PCI_LATENCY_TIMER, 0x80);
522#endif
523 521
524 /* Allocate PCI I/O and/or memory space */ 522 /* Allocate PCI I/O and/or memory space */
525 pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_5); 523 pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_5);
diff --git a/arch/sh/drivers/pci/pci-sh4.h b/arch/sh/drivers/pci/pci-sh4.h
index 1901c33cde6a..4925c79ea959 100644
--- a/arch/sh/drivers/pci/pci-sh4.h
+++ b/arch/sh/drivers/pci/pci-sh4.h
@@ -1,7 +1,9 @@
1#ifndef __PCI_SH4_H 1#ifndef __PCI_SH4_H
2#define __PCI_SH4_H 2#define __PCI_SH4_H
3 3
4#if defined(CONFIG_CPU_SUBTYPE_SH7780) || defined(CONFIG_CPU_SUBTYPE_SH7785) 4#if defined(CONFIG_CPU_SUBTYPE_SH7780) || \
5 defined(CONFIG_CPU_SUBTYPE_SH7785) || \
6 defined(CONFIG_CPU_SUBTYPE_SH7763)
5#include "pci-sh7780.h" 7#include "pci-sh7780.h"
6#else 8#else
7#include "pci-sh7751.h" 9#include "pci-sh7751.h"
diff --git a/arch/sh/drivers/pci/pci-sh5.c b/arch/sh/drivers/pci/pci-sh5.c
new file mode 100644
index 000000000000..a00a4df8c02d
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-sh5.c
@@ -0,0 +1,228 @@
1/*
2 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
3 * Copyright (C) 2003, 2004 Paul Mundt
4 * Copyright (C) 2004 Richard Curnow
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Support functions for the SH5 PCI hardware.
10 */
11
12#include <linux/kernel.h>
13#include <linux/rwsem.h>
14#include <linux/smp.h>
15#include <linux/interrupt.h>
16#include <linux/init.h>
17#include <linux/errno.h>
18#include <linux/pci.h>
19#include <linux/delay.h>
20#include <linux/types.h>
21#include <linux/irq.h>
22#include <asm/cpu/irq.h>
23#include <asm/pci.h>
24#include <asm/io.h>
25#include "pci-sh5.h"
26
27unsigned long pcicr_virt;
28unsigned long PCI_IO_AREA;
29
30/* Rounds a number UP to the nearest power of two. Used for
31 * sizing the PCI window.
32 */
33static u32 __init r2p2(u32 num)
34{
35 int i = 31;
36 u32 tmp = num;
37
38 if (num == 0)
39 return 0;
40
41 do {
42 if (tmp & (1 << 31))
43 break;
44 i--;
45 tmp <<= 1;
46 } while (i >= 0);
47
48 tmp = 1 << i;
49 /* If the original number isn't a power of 2, round it up */
50 if (tmp != num)
51 tmp <<= 1;
52
53 return tmp;
54}
55
56static irqreturn_t pcish5_err_irq(int irq, void *dev_id)
57{
58 struct pt_regs *regs = get_irq_regs();
59 unsigned pci_int, pci_air, pci_cir, pci_aint;
60
61 pci_int = SH5PCI_READ(INT);
62 pci_cir = SH5PCI_READ(CIR);
63 pci_air = SH5PCI_READ(AIR);
64
65 if (pci_int) {
66 printk("PCI INTERRUPT (at %08llx)!\n", regs->pc);
67 printk("PCI INT -> 0x%x\n", pci_int & 0xffff);
68 printk("PCI AIR -> 0x%x\n", pci_air);
69 printk("PCI CIR -> 0x%x\n", pci_cir);
70 SH5PCI_WRITE(INT, ~0);
71 }
72
73 pci_aint = SH5PCI_READ(AINT);
74 if (pci_aint) {
75 printk("PCI ARB INTERRUPT!\n");
76 printk("PCI AINT -> 0x%x\n", pci_aint);
77 printk("PCI AIR -> 0x%x\n", pci_air);
78 printk("PCI CIR -> 0x%x\n", pci_cir);
79 SH5PCI_WRITE(AINT, ~0);
80 }
81
82 return IRQ_HANDLED;
83}
84
85static irqreturn_t pcish5_serr_irq(int irq, void *dev_id)
86{
87 printk("SERR IRQ\n");
88
89 return IRQ_NONE;
90}
91
92int __init sh5pci_init(unsigned long memStart, unsigned long memSize)
93{
94 u32 lsr0;
95 u32 uval;
96
97 if (request_irq(IRQ_ERR, pcish5_err_irq,
98 IRQF_DISABLED, "PCI Error",NULL) < 0) {
99 printk(KERN_ERR "PCISH5: Cannot hook PCI_PERR interrupt\n");
100 return -EINVAL;
101 }
102
103 if (request_irq(IRQ_SERR, pcish5_serr_irq,
104 IRQF_DISABLED, "PCI SERR interrupt", NULL) < 0) {
105 printk(KERN_ERR "PCISH5: Cannot hook PCI_SERR interrupt\n");
106 return -EINVAL;
107 }
108
109 pcicr_virt = onchip_remap(SH5PCI_ICR_BASE, 1024, "PCICR");
110 if (!pcicr_virt) {
111 panic("Unable to remap PCICR\n");
112 }
113
114 PCI_IO_AREA = onchip_remap(SH5PCI_IO_BASE, 0x10000, "PCIIO");
115 if (!PCI_IO_AREA) {
116 panic("Unable to remap PCIIO\n");
117 }
118
119 /* Clear snoop registers */
120 SH5PCI_WRITE(CSCR0, 0);
121 SH5PCI_WRITE(CSCR1, 0);
122
123 /* Switch off interrupts */
124 SH5PCI_WRITE(INTM, 0);
125 SH5PCI_WRITE(AINTM, 0);
126 SH5PCI_WRITE(PINTM, 0);
127
128 /* Set bus active, take it out of reset */
129 uval = SH5PCI_READ(CR);
130
131 /* Set command Register */
132 SH5PCI_WRITE(CR, uval | CR_LOCK_MASK | CR_CFINT| CR_FTO | CR_PFE |
133 CR_PFCS | CR_BMAM);
134
135 uval=SH5PCI_READ(CR);
136
137 /* Allow it to be a master */
138 /* NB - WE DISABLE I/O ACCESS to stop overlap */
139 /* set WAIT bit to enable stepping, an attempt to improve stability */
140 SH5PCI_WRITE_SHORT(CSR_CMD,
141 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
142 PCI_COMMAND_WAIT);
143
144 /*
145 ** Set translation mapping memory in order to convert the address
146 ** used for the main bus, to the PCI internal address.
147 */
148 SH5PCI_WRITE(MBR,0x40000000);
149
150 /* Always set the max size 512M */
151 SH5PCI_WRITE(MBMR, PCISH5_MEM_SIZCONV(512*1024*1024));
152
153 /*
154 ** I/O addresses are mapped at internal PCI specific address
155 ** as is described into the configuration bridge table.
156 ** These are changed to 0, to allow cards that have legacy
157 ** io such as vga to function correctly. We set the SH5 IOBAR to
158 ** 256K, which is a bit big as we can only have 64K of address space
159 */
160
161 SH5PCI_WRITE(IOBR,0x0);
162
163 /* Set up a 256K window. Totally pointless waste of address space */
164 SH5PCI_WRITE(IOBMR,0);
165
166 /* The SH5 has a HUGE 256K I/O region, which breaks the PCI spec.
167 * Ideally, we would want to map the I/O region somewhere, but it
168 * is so big this is not that easy!
169 */
170 SH5PCI_WRITE(CSR_IBAR0,~0);
171 /* Set memory size value */
172 memSize = memory_end - memory_start;
173
174 /* Now we set up the mbars so the PCI bus can see the memory of
175 * the machine */
176 if (memSize < (1024 * 1024)) {
177 printk(KERN_ERR "PCISH5: Ridiculous memory size of 0x%lx?\n",
178 memSize);
179 return -EINVAL;
180 }
181
182 /* Set LSR 0 */
183 lsr0 = (memSize > (512 * 1024 * 1024)) ? 0x1ff00001 :
184 ((r2p2(memSize) - 0x100000) | 0x1);
185 SH5PCI_WRITE(LSR0, lsr0);
186
187 /* Set MBAR 0 */
188 SH5PCI_WRITE(CSR_MBAR0, memory_start);
189 SH5PCI_WRITE(LAR0, memory_start);
190
191 SH5PCI_WRITE(CSR_MBAR1,0);
192 SH5PCI_WRITE(LAR1,0);
193 SH5PCI_WRITE(LSR1,0);
194
195 /* Enable the PCI interrupts on the device */
196 SH5PCI_WRITE(INTM, ~0);
197 SH5PCI_WRITE(AINTM, ~0);
198 SH5PCI_WRITE(PINTM, ~0);
199
200 return 0;
201}
202
203void __devinit pcibios_fixup_bus(struct pci_bus *bus)
204{
205 struct pci_dev *dev = bus->self;
206 int i;
207
208 if (dev) {
209 for (i= 0; i < 3; i++) {
210 bus->resource[i] =
211 &dev->resource[PCI_BRIDGE_RESOURCES+i];
212 bus->resource[i]->name = bus->name;
213 }
214 bus->resource[0]->flags |= IORESOURCE_IO;
215 bus->resource[1]->flags |= IORESOURCE_MEM;
216
217 /* For now, propagate host limits to the bus;
218 * we'll adjust them later. */
219 bus->resource[0]->end = 64*1024 - 1 ;
220 bus->resource[1]->end = PCIBIOS_MIN_MEM+(256*1024*1024)-1;
221 bus->resource[0]->start = PCIBIOS_MIN_IO;
222 bus->resource[1]->start = PCIBIOS_MIN_MEM;
223
224 /* Turn off downstream PF memory address range by default */
225 bus->resource[2]->start = 1024*1024;
226 bus->resource[2]->end = bus->resource[2]->start - 1;
227 }
228}
diff --git a/arch/sh/drivers/pci/pci-sh5.h b/arch/sh/drivers/pci/pci-sh5.h
new file mode 100644
index 000000000000..7cff3fc04d30
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-sh5.h
@@ -0,0 +1,113 @@
1/*
2 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * Definitions for the SH5 PCI hardware.
8 */
9#ifndef __PCI_SH5_H
10#define __PCI_SH5_H
11
12/* Product ID */
13#define PCISH5_PID 0x350d
14
15/* vendor ID */
16#define PCISH5_VID 0x1054
17
18/* Configuration types */
19#define ST_TYPE0 0x00 /* Configuration cycle type 0 */
20#define ST_TYPE1 0x01 /* Configuration cycle type 1 */
21
22/* VCR data */
23#define PCISH5_VCR_STATUS 0x00
24#define PCISH5_VCR_VERSION 0x08
25
26/*
27** ICR register offsets and bits
28*/
29#define PCISH5_ICR_CR 0x100 /* PCI control register values */
30#define CR_PBAM (1<<12)
31#define CR_PFCS (1<<11)
32#define CR_FTO (1<<10)
33#define CR_PFE (1<<9)
34#define CR_TBS (1<<8)
35#define CR_SPUE (1<<7)
36#define CR_BMAM (1<<6)
37#define CR_HOST (1<<5)
38#define CR_CLKEN (1<<4)
39#define CR_SOCS (1<<3)
40#define CR_IOCS (1<<2)
41#define CR_RSTCTL (1<<1)
42#define CR_CFINT (1<<0)
43#define CR_LOCK_MASK 0xa5000000
44
45#define PCISH5_ICR_INT 0x114 /* Interrupt registert values */
46#define INT_MADIM (1<<2)
47
48#define PCISH5_ICR_LSR0 0X104 /* Local space register values */
49#define PCISH5_ICR_LSR1 0X108 /* Local space register values */
50#define PCISH5_ICR_LAR0 0x10c /* Local address register values */
51#define PCISH5_ICR_LAR1 0x110 /* Local address register values */
52#define PCISH5_ICR_INTM 0x118 /* Interrupt mask register values */
53#define PCISH5_ICR_AIR 0x11c /* Interrupt error address information register values */
54#define PCISH5_ICR_CIR 0x120 /* Interrupt error command information register values */
55#define PCISH5_ICR_AINT 0x130 /* Interrupt error arbiter interrupt register values */
56#define PCISH5_ICR_AINTM 0x134 /* Interrupt error arbiter interrupt mask register values */
57#define PCISH5_ICR_BMIR 0x138 /* Interrupt error info register of bus master values */
58#define PCISH5_ICR_PAR 0x1c0 /* Pio address register values */
59#define PCISH5_ICR_MBR 0x1c4 /* Memory space bank register values */
60#define PCISH5_ICR_IOBR 0x1c8 /* I/O space bank register values */
61#define PCISH5_ICR_PINT 0x1cc /* power management interrupt register values */
62#define PCISH5_ICR_PINTM 0x1d0 /* power management interrupt mask register values */
63#define PCISH5_ICR_MBMR 0x1d8 /* memory space bank mask register values */
64#define PCISH5_ICR_IOBMR 0x1dc /* I/O space bank mask register values */
65#define PCISH5_ICR_CSCR0 0x210 /* PCI cache snoop control register 0 */
66#define PCISH5_ICR_CSCR1 0x214 /* PCI cache snoop control register 1 */
67#define PCISH5_ICR_PDR 0x220 /* Pio data register values */
68
69/* These are configs space registers */
70#define PCISH5_ICR_CSR_VID 0x000 /* Vendor id */
71#define PCISH5_ICR_CSR_DID 0x002 /* Device id */
72#define PCISH5_ICR_CSR_CMD 0x004 /* Command register */
73#define PCISH5_ICR_CSR_STATUS 0x006 /* Stautus */
74#define PCISH5_ICR_CSR_IBAR0 0x010 /* I/O base address register */
75#define PCISH5_ICR_CSR_MBAR0 0x014 /* First Memory base address register */
76#define PCISH5_ICR_CSR_MBAR1 0x018 /* Second Memory base address register */
77
78/* Base address of registers */
79#define SH5PCI_ICR_BASE (PHYS_PCI_BLOCK + 0x00040000)
80#define SH5PCI_IO_BASE (PHYS_PCI_BLOCK + 0x00800000)
81/* #define SH5PCI_VCR_BASE (P2SEG_PCICB_BLOCK + P2SEG) */
82
83extern unsigned long pcicr_virt;
84/* Register selection macro */
85#define PCISH5_ICR_REG(x) ( pcicr_virt + (PCISH5_ICR_##x))
86/* #define PCISH5_VCR_REG(x) ( SH5PCI_VCR_BASE (PCISH5_VCR_##x)) */
87
88/* Write I/O functions */
89#define SH5PCI_WRITE(reg,val) ctrl_outl((u32)(val),PCISH5_ICR_REG(reg))
90#define SH5PCI_WRITE_SHORT(reg,val) ctrl_outw((u16)(val),PCISH5_ICR_REG(reg))
91#define SH5PCI_WRITE_BYTE(reg,val) ctrl_outb((u8)(val),PCISH5_ICR_REG(reg))
92
93/* Read I/O functions */
94#define SH5PCI_READ(reg) ctrl_inl(PCISH5_ICR_REG(reg))
95#define SH5PCI_READ_SHORT(reg) ctrl_inw(PCISH5_ICR_REG(reg))
96#define SH5PCI_READ_BYTE(reg) ctrl_inb(PCISH5_ICR_REG(reg))
97
98/* Set PCI config bits */
99#define SET_CONFIG_BITS(bus,devfn,where) ((((bus) << 16) | ((devfn) << 8) | ((where) & ~3)) | 0x80000000)
100
101/* Set PCI command register */
102#define CONFIG_CMD(bus, devfn, where) SET_CONFIG_BITS(bus->number,devfn,where)
103
104/* Size converters */
105#define PCISH5_MEM_SIZCONV(x) (((x / 0x40000) - 1) << 18)
106#define PCISH5_IO_SIZCONV(x) (((x / 0x40000) - 1) << 18)
107
108extern struct pci_ops sh5_pci_ops;
109
110/* arch/sh/drivers/pci/pci-sh5.c */
111int sh5pci_init(unsigned long memStart, unsigned long memSize);
112
113#endif /* __PCI_SH5_H */
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index e516087fb435..7d797f4de5e7 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -58,6 +58,7 @@ static int __init sh7780_pci_init(void)
58 id = pci_read_reg(SH7780_PCIVID); 58 id = pci_read_reg(SH7780_PCIVID);
59 if ((id & 0xffff) == SH7780_VENDOR_ID) { 59 if ((id & 0xffff) == SH7780_VENDOR_ID) {
60 switch ((id >> 16) & 0xffff) { 60 switch ((id >> 16) & 0xffff) {
61 case SH7763_DEVICE_ID:
61 case SH7780_DEVICE_ID: 62 case SH7780_DEVICE_ID:
62 case SH7781_DEVICE_ID: 63 case SH7781_DEVICE_ID:
63 case SH7785_DEVICE_ID: 64 case SH7785_DEVICE_ID:
diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h
index 1d069a859de2..97b2c98f05c4 100644
--- a/arch/sh/drivers/pci/pci-sh7780.h
+++ b/arch/sh/drivers/pci/pci-sh7780.h
@@ -16,6 +16,7 @@
16#define SH7780_VENDOR_ID 0x1912 16#define SH7780_VENDOR_ID 0x1912
17#define SH7781_DEVICE_ID 0x0001 17#define SH7781_DEVICE_ID 0x0001
18#define SH7780_DEVICE_ID 0x0002 18#define SH7780_DEVICE_ID 0x0002
19#define SH7763_DEVICE_ID 0x0004
19#define SH7785_DEVICE_ID 0x0007 20#define SH7785_DEVICE_ID 0x0007
20 21
21/* SH7780 Control Registers */ 22/* SH7780 Control Registers */
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index ccaba368ac9b..49b435c3a57a 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -71,7 +71,7 @@ subsys_initcall(pcibios_init);
71 * Called after each bus is probed, but before its children 71 * Called after each bus is probed, but before its children
72 * are examined. 72 * are examined.
73 */ 73 */
74void __devinit pcibios_fixup_bus(struct pci_bus *bus) 74void __devinit __weak pcibios_fixup_bus(struct pci_bus *bus)
75{ 75{
76 pci_read_bridge_bases(bus); 76 pci_read_bridge_bases(bus);
77} 77}