aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/drivers/pci')
-rw-r--r--arch/sh/drivers/pci/Kconfig41
-rw-r--r--arch/sh/drivers/pci/Makefile16
-rw-r--r--arch/sh/drivers/pci/dma-dreamcast.c71
-rw-r--r--arch/sh/drivers/pci/fixups-dreamcast.c81
-rw-r--r--arch/sh/drivers/pci/fixups-rts7751r2d.c43
-rw-r--r--arch/sh/drivers/pci/fixups-sh03.c61
-rw-r--r--arch/sh/drivers/pci/ops-bigsur.c88
-rw-r--r--arch/sh/drivers/pci/ops-dreamcast.c169
-rw-r--r--arch/sh/drivers/pci/ops-rts7751r2d.c79
-rw-r--r--arch/sh/drivers/pci/ops-sh03.c45
-rw-r--r--arch/sh/drivers/pci/ops-snapgear.c102
-rw-r--r--arch/sh/drivers/pci/pci-auto.c555
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.c417
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.h303
-rw-r--r--arch/sh/drivers/pci/pci-st40.c509
-rw-r--r--arch/sh/drivers/pci/pci-st40.h136
-rw-r--r--arch/sh/drivers/pci/pci.c155
17 files changed, 2871 insertions, 0 deletions
diff --git a/arch/sh/drivers/pci/Kconfig b/arch/sh/drivers/pci/Kconfig
new file mode 100644
index 000000000000..6d1cbbe6745c
--- /dev/null
+++ b/arch/sh/drivers/pci/Kconfig
@@ -0,0 +1,41 @@
1config PCI
2 bool "PCI support"
3 help
4 Find out whether you have a PCI motherboard. PCI is the name of a
5 bus system, i.e. the way the CPU talks to the other stuff inside
6 your box. If you have PCI, say Y, otherwise N.
7
8 The PCI-HOWTO, available from
9 <http://www.tldp.org/docs.html#howto>, contains valuable
10 information about which PCI hardware does work under Linux and which
11 doesn't.
12
13config SH_PCIDMA_NONCOHERENT
14 bool "Cache and PCI noncoherent"
15 depends on PCI
16 default y
17 help
18 Enable this option if your platform does not have a CPU cache which
19 remains coherent with PCI DMA. It is safest to say 'Y', although you
20 will see better performance if you can say 'N', because the PCI DMA
21 code will not have to flush the CPU's caches. If you have a PCI host
22 bridge integrated with your SH CPU, refer carefully to the chip specs
23 to see if you can say 'N' here. Otherwise, leave it as 'Y'.
24
25# This is also board-specific
26config PCI_AUTO
27 bool
28 depends on PCI
29 default y
30
31config PCI_AUTO_UPDATE_RESOURCES
32 bool
33 depends on PCI_AUTO
34 default y if !SH_DREAMCAST
35 help
36 Selecting this option will cause the PCI auto code to leave your
37 BAR values alone. Otherwise they will be updated automatically. If
38 for some reason, you have a board that simply refuses to work
39 with its resources updated beyond what they are when the device
40 is powered up, set this to N. Everyone else will want this as Y.
41
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile
new file mode 100644
index 000000000000..365bc16a4a83
--- /dev/null
+++ b/arch/sh/drivers/pci/Makefile
@@ -0,0 +1,16 @@
1#
2# Makefile for the PCI specific kernel interface routines under Linux.
3#
4
5obj-y += pci.o
6obj-$(CONFIG_PCI_AUTO) += pci-auto.o
7
8obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += pci-st40.o
9obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o
10
11obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \
12 dma-dreamcast.o
13obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o
14obj-$(CONFIG_SH_BIGSUR) += ops-bigsur.o
15obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o
16obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o
diff --git a/arch/sh/drivers/pci/dma-dreamcast.c b/arch/sh/drivers/pci/dma-dreamcast.c
new file mode 100644
index 000000000000..83de7ef4e7df
--- /dev/null
+++ b/arch/sh/drivers/pci/dma-dreamcast.c
@@ -0,0 +1,71 @@
1/*
2 * arch/sh/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/config.h>
19#include <linux/sched.h>
20#include <linux/kernel.h>
21#include <linux/param.h>
22#include <linux/interrupt.h>
23#include <linux/init.h>
24#include <linux/irq.h>
25#include <linux/pci.h>
26#include <linux/dma-mapping.h>
27#include <linux/device.h>
28
29#include <asm/io.h>
30#include <asm/irq.h>
31#include <asm/mach/pci.h>
32
33static int gapspci_dma_used = 0;
34
35void *dreamcast_consistent_alloc(struct device *dev, size_t size,
36 dma_addr_t *dma_handle, int flag)
37{
38 unsigned long buf;
39
40 if (dev && dev->bus != &pci_bus_type)
41 return NULL;
42
43 if (gapspci_dma_used + size > GAPSPCI_DMA_SIZE)
44 return ERR_PTR(-EINVAL);
45
46 buf = GAPSPCI_DMA_BASE + gapspci_dma_used;
47
48 gapspci_dma_used = PAGE_ALIGN(gapspci_dma_used+size);
49
50 *dma_handle = (dma_addr_t)buf;
51
52 buf = P2SEGADDR(buf);
53
54 /* Flush the dcache before we hand off the buffer */
55 dma_cache_wback_inv((void *)buf, size);
56
57 return (void *)buf;
58}
59
60int dreamcast_consistent_free(struct device *dev, size_t size,
61 void *vaddr, dma_addr_t dma_handle)
62{
63 if (dev && dev->bus != &pci_bus_type)
64 return -EINVAL;
65
66 /* XXX */
67 gapspci_dma_used = 0;
68
69 return 0;
70}
71
diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c
new file mode 100644
index 000000000000..cf30e2fa51be
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-dreamcast.c
@@ -0,0 +1,81 @@
1/*
2 * arch/sh/pci/fixups-dreamcast.c
3 *
4 * PCI fixups 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/config.h>
19#include <linux/sched.h>
20#include <linux/kernel.h>
21#include <linux/param.h>
22#include <linux/interrupt.h>
23#include <linux/init.h>
24#include <linux/irq.h>
25#include <linux/pci.h>
26
27#include <asm/io.h>
28#include <asm/irq.h>
29#include <asm/mach/pci.h>
30
31static void __init gapspci_fixup_resources(struct pci_dev *dev)
32{
33 struct pci_channel *p = board_pci_channels;
34
35 printk(KERN_NOTICE "PCI: Fixing up device %s\n", pci_name(dev));
36
37 switch (dev->device) {
38 case PCI_DEVICE_ID_SEGA_BBA:
39 /*
40 * We also assume that dev->devfn == 0
41 */
42 dev->resource[1].start = p->io_resource->start + 0x100;
43 dev->resource[1].end = dev->resource[1].start + 0x200 - 1;
44 break;
45 default:
46 printk("PCI: Failed resource fixup\n");
47 }
48}
49
50DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources);
51
52void __init pcibios_fixup_bus(struct pci_bus *bus)
53{
54 /*
55 * We don't have any sub bus to fix up, and this is a rather
56 * stupid place to put general device fixups. Don't do it.
57 * Use the pcibios_fixups table or suffer the consequences.
58 */
59}
60
61void __init pcibios_fixup_irqs(void)
62{
63 struct pci_dev *dev = 0;
64
65 for_each_pci_dev(dev) {
66 /*
67 * The interrupt routing semantics here are quite trivial.
68 *
69 * We basically only support one interrupt, so we only bother
70 * updating a device's interrupt line with this single shared
71 * interrupt. Keeps routing quite simple, doesn't it?
72 */
73 printk(KERN_NOTICE "PCI: Fixing up IRQ routing for device %s\n",
74 pci_name(dev));
75
76 dev->irq = GAPSPCI_IRQ;
77
78 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
79 }
80}
81
diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c
new file mode 100644
index 000000000000..0c590fc7a081
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c
@@ -0,0 +1,43 @@
1/*
2 * arch/sh/drivers/pci/fixups-rts7751r2d.c
3 *
4 * RTS7751R2D PCI fixups
5 *
6 * Copyright (C) 2003 Lineo uSolutions, Inc.
7 * Copyright (C) 2004 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 "pci-sh7751.h"
14#include <asm/io.h>
15
16#define PCIMCR_MRSET_OFF 0xBFFFFFFF
17#define PCIMCR_RFSH_OFF 0xFFFFFFFB
18
19int pci_fixup_pcic(void)
20{
21 unsigned long bcr1, mcr;
22
23 bcr1 = inl(SH7751_BCR1);
24 bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */
25 outl(bcr1, PCI_REG(SH7751_PCIBCR1));
26
27 /* Enable all interrupts, so we known what to fix */
28 outl(0x0000c3ff, PCI_REG(SH7751_PCIINTM));
29 outl(0x0000380f, PCI_REG(SH7751_PCIAINTM));
30
31 outl(0xfb900047, PCI_REG(SH7751_PCICONF1));
32 outl(0xab000001, PCI_REG(SH7751_PCICONF4));
33
34 mcr = inl(SH7751_MCR);
35 mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
36 outl(mcr, PCI_REG(SH7751_PCIMCR));
37
38 outl(0x0c000000, PCI_REG(SH7751_PCICONF5));
39 outl(0xd0000000, PCI_REG(SH7751_PCICONF6));
40 outl(0x0c000000, PCI_REG(SH7751_PCILAR0));
41 outl(0x00000000, PCI_REG(SH7751_PCILAR1));
42 return 0;
43}
diff --git a/arch/sh/drivers/pci/fixups-sh03.c b/arch/sh/drivers/pci/fixups-sh03.c
new file mode 100644
index 000000000000..57ac26c2171f
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-sh03.c
@@ -0,0 +1,61 @@
1#include <linux/kernel.h>
2#include <linux/init.h>
3#include <linux/types.h>
4#include <linux/pci.h>
5
6/*
7 * IRQ functions
8 */
9
10int __init pcibios_map_platform_irq(u8 slot, u8 pin, struct pci_dev *dev)
11{
12 int irq;
13
14 if (dev->bus->number == 0) {
15 switch (slot) {
16 case 4: return 5; /* eth0 */
17 case 8: return 5; /* eth1 */
18 case 6: return 2; /* PCI bridge */
19 default:
20 printk("PCI: Bad IRQ mapping request for slot %d\n", slot);
21 return 2;
22 }
23 } else {
24 switch (pin) {
25 case 0: irq = 2; break;
26 case 1: irq = 2; break;
27 case 2: irq = 2; break;
28 case 3: irq = 2; break;
29 case 4: irq = 2; break;
30 default: irq = -1; break;
31 }
32 }
33 return irq;
34}
35
36static u8 __init sh03_no_swizzle(struct pci_dev *dev, u8 *pin)
37{
38 /* no swizzling */
39 return PCI_SLOT(dev->devfn);
40}
41
42static int sh03_pci_lookup_irq(struct pci_dev *dev, u8 slot, u8 pin)
43{
44 int irq = -1;
45
46 /* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */
47 irq = pcibios_map_platform_irq(slot, pin, dev);
48 if( irq < 0 ) {
49 pr_debug("PCI: Error mapping IRQ on device %s\n", pci_name(dev));
50 return irq;
51 }
52
53 pr_debug("Setting IRQ for slot %s to %d\n", pci_name(dev), irq);
54
55 return irq;
56}
57
58void __init pcibios_fixup_irqs(void)
59{
60 pci_fixup_irqs(sh03_no_swizzle, sh03_pci_lookup_irq);
61}
diff --git a/arch/sh/drivers/pci/ops-bigsur.c b/arch/sh/drivers/pci/ops-bigsur.c
new file mode 100644
index 000000000000..9b43da67804b
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-bigsur.c
@@ -0,0 +1,88 @@
1/*
2 * linux/arch/sh/kernel/pci-bigsur.c
3 *
4 * By Dustin McIntire (dustin@sensoria.com) (c)2001
5 *
6 * Ported to new API by Paul Mundt <lethal@linux-sh.org>.
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 * PCI initialization for the Hitachi Big Sur Evaluation Board
12 */
13
14#include <linux/config.h>
15#include <linux/kernel.h>
16#include <linux/types.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pci.h>
20
21#include <asm/io.h>
22#include "pci-sh7751.h"
23#include <asm/bigsur/bigsur.h>
24
25#define BIGSUR_PCI_IO 0x4000
26#define BIGSUR_PCI_MEM 0xfd000000
27
28static struct resource sh7751_io_resource = {
29 .name = "SH7751 IO",
30 .start = BIGSUR_PCI_IO,
31 .end = BIGSUR_PCI_IO + (64*1024) - 1,
32 .flags = IORESOURCE_IO,
33};
34
35static struct resource sh7751_mem_resource = {
36 .name = "SH7751 mem",
37 .start = BIGSUR_PCI_MEM,
38 .end = BIGSUR_PCI_MEM + (64*1024*1024) - 1,
39 .flags = IORESOURCE_MEM,
40};
41
42extern struct pci_ops sh7751_pci_ops;
43
44struct pci_channel board_pci_channels[] = {
45 { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
46 { 0, }
47};
48
49static struct sh7751_pci_address_map sh7751_pci_map = {
50 .window0 = {
51 .base = SH7751_CS3_BASE_ADDR,
52 .size = BIGSUR_LSR0_SIZE,
53 },
54
55 .window1 = {
56 .base = SH7751_CS3_BASE_ADDR,
57 .size = BIGSUR_LSR1_SIZE,
58 },
59};
60
61/*
62 * Initialize the Big Sur PCI interface
63 * Setup hardware to be Central Funtion
64 * Copy the BSR regs to the PCI interface
65 * Setup PCI windows into local RAM
66 */
67int __init pcibios_init_platform(void)
68{
69 return sh7751_pcic_init(&sh7751_pci_map);
70}
71
72int pcibios_map_platform_irq(u8 slot, u8 pin)
73{
74 /*
75 * The Big Sur can be used in a CPCI chassis, but the SH7751 PCI
76 * interface is on the wrong end of the board so that it can also
77 * support a V320 CPI interface chip... Therefor the IRQ mapping is
78 * somewhat use dependent... I'l assume a linear map for now, i.e.
79 * INTA=slot0,pin0... INTD=slot3,pin0...
80 */
81 int irq = (slot + pin-1) % 4 + BIGSUR_SH7751_PCI_IRQ_BASE;
82
83 PCIDBG(2, "PCI: Mapping Big Sur IRQ for slot %d, pin %c to irq %d\n",
84 slot, pin-1+'A', irq);
85
86 return irq;
87}
88
diff --git a/arch/sh/drivers/pci/ops-dreamcast.c b/arch/sh/drivers/pci/ops-dreamcast.c
new file mode 100644
index 000000000000..69af80b93e3f
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-dreamcast.c
@@ -0,0 +1,169 @@
1/*
2 * arch/sh/pci/ops-dreamcast.c
3 *
4 * PCI operations 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/config.h>
19#include <linux/sched.h>
20#include <linux/kernel.h>
21#include <linux/param.h>
22#include <linux/interrupt.h>
23#include <linux/init.h>
24#include <linux/irq.h>
25#include <linux/pci.h>
26
27#include <asm/io.h>
28#include <asm/irq.h>
29#include <asm/mach/pci.h>
30
31static struct resource gapspci_io_resource = {
32 .name = "GAPSPCI IO",
33 .start = GAPSPCI_BBA_CONFIG,
34 .end = GAPSPCI_BBA_CONFIG + GAPSPCI_BBA_CONFIG_SIZE - 1,
35 .flags = IORESOURCE_IO,
36};
37
38static struct resource gapspci_mem_resource = {
39 .name = "GAPSPCI mem",
40 .start = GAPSPCI_DMA_BASE,
41 .end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1,
42 .flags = IORESOURCE_MEM,
43};
44
45static struct pci_ops gapspci_pci_ops;
46
47struct pci_channel board_pci_channels[] = {
48 { &gapspci_pci_ops, &gapspci_io_resource,
49 &gapspci_mem_resource, 0, 1 },
50 { 0, }
51};
52
53/*
54 * The !gapspci_config_access case really shouldn't happen, ever, unless
55 * someone implicitly messes around with the last devfn value.. otherwise we
56 * only support a single device anyways, and if we didn't have a BBA, we
57 * wouldn't make it terribly far through the PCI setup anyways.
58 *
59 * Also, we could very easily support both Type 0 and Type 1 configurations
60 * here, but since it doesn't seem that there is any such implementation in
61 * existance, we don't bother.
62 *
63 * I suppose if someone actually gets around to ripping the chip out of
64 * the BBA and hanging some more devices off of it, then this might be
65 * something to take into consideration. However, due to the cost of the BBA,
66 * and the general lack of activity by DC hardware hackers, this doesn't seem
67 * likely to happen anytime soon.
68 */
69static int gapspci_config_access(unsigned char bus, unsigned int devfn)
70{
71 return (bus == 0) && (devfn == 0);
72}
73
74/*
75 * We can also actually read and write in b/w/l sizes! Thankfully this part
76 * was at least done right, and we don't have to do the stupid masking and
77 * shifting that we do on the 7751! Small wonders never cease to amaze.
78 */
79static int gapspci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val)
80{
81 *val = 0xffffffff;
82
83 if (!gapspci_config_access(bus->number, devfn))
84 return PCIBIOS_DEVICE_NOT_FOUND;
85
86 switch (size) {
87 case 1: *val = inb(GAPSPCI_BBA_CONFIG+where); break;
88 case 2: *val = inw(GAPSPCI_BBA_CONFIG+where); break;
89 case 4: *val = inl(GAPSPCI_BBA_CONFIG+where); break;
90 }
91
92 return PCIBIOS_SUCCESSFUL;
93}
94
95static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
96{
97 if (!gapspci_config_access(bus->number, devfn))
98 return PCIBIOS_DEVICE_NOT_FOUND;
99
100 switch (size) {
101 case 1: outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break;
102 case 2: outw((u16)val, GAPSPCI_BBA_CONFIG+where); break;
103 case 4: outl((u32)val, GAPSPCI_BBA_CONFIG+where); break;
104 }
105
106 return PCIBIOS_SUCCESSFUL;
107}
108
109static struct pci_ops gapspci_pci_ops = {
110 .read = gapspci_read,
111 .write = gapspci_write,
112};
113
114/*
115 * gapspci init
116 */
117
118int __init gapspci_init(void)
119{
120 char idbuf[16];
121 int i;
122
123 /*
124 * FIXME: All of this wants documenting to some degree,
125 * even some basic register definitions would be nice.
126 *
127 * I haven't seen anything this ugly since.. maple.
128 */
129
130 for (i=0; i<16; i++)
131 idbuf[i] = inb(GAPSPCI_REGS+i);
132
133 if (strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16))
134 return -ENODEV;
135
136 outl(0x5a14a501, GAPSPCI_REGS+0x18);
137
138 for (i=0; i<1000000; i++)
139 ;
140
141 if (inl(GAPSPCI_REGS+0x18) != 1)
142 return -EINVAL;
143
144 outl(0x01000000, GAPSPCI_REGS+0x20);
145 outl(0x01000000, GAPSPCI_REGS+0x24);
146
147 outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28);
148 outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c);
149
150 outl(1, GAPSPCI_REGS+0x14);
151 outl(1, GAPSPCI_REGS+0x34);
152
153 /* Setting Broadband Adapter */
154 outw(0xf900, GAPSPCI_BBA_CONFIG+0x06);
155 outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30);
156 outb(0x00, GAPSPCI_BBA_CONFIG+0x3c);
157 outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d);
158 outw(0x0006, GAPSPCI_BBA_CONFIG+0x04);
159 outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10);
160 outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14);
161
162 return 0;
163}
164
165/* Haven't done anything here as yet */
166char * __devinit pcibios_setup(char *str)
167{
168 return str;
169}
diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c
new file mode 100644
index 000000000000..beafa11f4d0c
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-rts7751r2d.c
@@ -0,0 +1,79 @@
1/*
2 * linux/arch/sh/kernel/pci-rts7751r2d.c
3 *
4 * Author: Ian DaSilva (idasilva@mvista.com)
5 *
6 * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
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 * PCI initialization for the Renesas SH7751R RTS7751R2D board
12 */
13
14#include <linux/config.h>
15#include <linux/kernel.h>
16#include <linux/types.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pci.h>
20#include <linux/module.h>
21
22#include <asm/io.h>
23#include "pci-sh7751.h"
24#include <asm/rts7751r2d/rts7751r2d.h>
25
26int __init pcibios_map_platform_irq(u8 slot, u8 pin)
27{
28 switch (slot) {
29 case 0: return IRQ_PCISLOT1; /* PCI Extend slot #1 */
30 case 1: return IRQ_PCISLOT2; /* PCI Extend slot #2 */
31 case 2: return IRQ_PCMCIA; /* PCI Cardbus Bridge */
32 case 3: return IRQ_PCIETH; /* Realtek Ethernet controller */
33 default:
34 printk("PCI: Bad IRQ mapping request for slot %d\n", slot);
35 return -1;
36 }
37}
38
39static struct resource sh7751_io_resource = {
40 .name = "SH7751_IO",
41 .start = 0x4000,
42 .end = 0x4000 + SH7751_PCI_IO_SIZE - 1,
43 .flags = IORESOURCE_IO
44};
45
46static struct resource sh7751_mem_resource = {
47 .name = "SH7751_mem",
48 .start = SH7751_PCI_MEMORY_BASE,
49 .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
50 .flags = IORESOURCE_MEM
51};
52
53extern struct pci_ops sh7751_pci_ops;
54
55struct pci_channel board_pci_channels[] = {
56 { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
57 { NULL, NULL, NULL, 0, 0 },
58};
59EXPORT_SYMBOL(board_pci_channels);
60
61static struct sh7751_pci_address_map sh7751_pci_map = {
62 .window0 = {
63 .base = SH7751_CS3_BASE_ADDR,
64 .size = 0x04000000,
65 },
66
67 .window1 = {
68 .base = 0x00000000, /* Unused */
69 .size = 0x00000000, /* Unused */
70 },
71
72 .flags = SH7751_PCIC_NO_RESET,
73};
74
75int __init pcibios_init_platform(void)
76{
77 return sh7751_pcic_init(&sh7751_pci_map);
78}
79
diff --git a/arch/sh/drivers/pci/ops-sh03.c b/arch/sh/drivers/pci/ops-sh03.c
new file mode 100644
index 000000000000..df2199732348
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-sh03.c
@@ -0,0 +1,45 @@
1/*
2 * linux/arch/sh/drivers/pci/ops-sh03.c
3 *
4 * PCI initialization for the Interface CTP/PCI-SH03 board
5 */
6
7#include <linux/config.h>
8#include <linux/kernel.h>
9#include <linux/types.h>
10#include <linux/init.h>
11#include <linux/delay.h>
12#include <linux/pci.h>
13#include <asm/io.h>
14#include "pci-sh7751.h"
15
16/*
17 * Description: This function sets up and initializes the pcic, sets
18 * up the BARS, maps the DRAM into the address space etc, etc.
19 */
20int __init pcibios_init_platform(void)
21{
22 return 1;
23}
24
25static struct resource sh7751_io_resource = {
26 .name = "SH03 IO",
27 .start = SH7751_PCI_IO_BASE,
28 .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
29 .flags = IORESOURCE_IO
30};
31
32static struct resource sh7751_mem_resource = {
33 .name = "SH03 mem",
34 .start = SH7751_PCI_MEMORY_BASE,
35 .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
36 .flags = IORESOURCE_MEM
37};
38
39extern struct pci_ops sh7751_pci_ops;
40
41struct pci_channel board_pci_channels[] = {
42 { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
43 { NULL, NULL, NULL, 0, 0 },
44};
45
diff --git a/arch/sh/drivers/pci/ops-snapgear.c b/arch/sh/drivers/pci/ops-snapgear.c
new file mode 100644
index 000000000000..6fdb9765c99a
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-snapgear.c
@@ -0,0 +1,102 @@
1/*
2 * arch/sh/drivers/pci/ops-snapgear.c
3 *
4 * Author: David McCullough <davidm@snapgear.com>
5 *
6 * Ported to new API by Paul Mundt <lethal@linux-sh.org>
7 *
8 * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
9 *
10 * May be copied or modified under the terms of the GNU General Public
11 * License. See linux/COPYING for more information.
12 *
13 * PCI initialization for the SnapGear boards
14 */
15
16#include <linux/config.h>
17#include <linux/kernel.h>
18#include <linux/types.h>
19#include <linux/init.h>
20#include <linux/delay.h>
21#include <linux/pci.h>
22
23#include <asm/io.h>
24#include "pci-sh7751.h"
25
26#define SNAPGEAR_PCI_IO 0x4000
27#define SNAPGEAR_PCI_MEM 0xfd000000
28
29/* PCI: default LOCAL memory window sizes (seen from PCI bus) */
30#define SNAPGEAR_LSR0_SIZE (64*(1<<20)) //64MB
31#define SNAPGEAR_LSR1_SIZE (64*(1<<20)) //64MB
32
33static struct resource sh7751_io_resource = {
34 .name = "SH7751 IO",
35 .start = SNAPGEAR_PCI_IO,
36 .end = SNAPGEAR_PCI_IO + (64*1024) - 1, /* 64KiB I/O */
37 .flags = IORESOURCE_IO,
38};
39
40static struct resource sh7751_mem_resource = {
41 .name = "SH7751 mem",
42 .start = SNAPGEAR_PCI_MEM,
43 .end = SNAPGEAR_PCI_MEM + (64*1024*1024) - 1, /* 64MiB mem */
44 .flags = IORESOURCE_MEM,
45};
46
47extern struct pci_ops sh7751_pci_ops;
48
49struct pci_channel board_pci_channels[] = {
50 { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
51 { 0, }
52};
53
54static struct sh7751_pci_address_map sh7751_pci_map = {
55 .window0 = {
56 .base = SH7751_CS2_BASE_ADDR,
57 .size = SNAPGEAR_LSR0_SIZE,
58 },
59
60 .window1 = {
61 .base = SH7751_CS2_BASE_ADDR,
62 .size = SNAPGEAR_LSR1_SIZE,
63 },
64
65 .flags = SH7751_PCIC_NO_RESET,
66};
67
68/*
69 * Initialize the SnapGear PCI interface
70 * Setup hardware to be Central Funtion
71 * Copy the BSR regs to the PCI interface
72 * Setup PCI windows into local RAM
73 */
74int __init pcibios_init_platform(void)
75{
76 return sh7751_pcic_init(&sh7751_pci_map);
77}
78
79int __init pcibios_map_platform_irq(u8 slot, u8 pin)
80{
81 int irq = -1;
82
83 switch (slot) {
84 case 8: /* the PCI bridge */ break;
85 case 11: irq = 8; break; /* USB */
86 case 12: irq = 11; break; /* PCMCIA */
87 case 13: irq = 5; break; /* eth0 */
88 case 14: irq = 8; break; /* eth1 */
89 case 15: irq = 11; break; /* safenet (unused) */
90 }
91
92 printk("PCI: Mapping SnapGear IRQ for slot %d, pin %c to irq %d\n",
93 slot, pin - 1 + 'A', irq);
94
95 return irq;
96}
97
98void __init pcibios_fixup(void)
99{
100 /* Nothing to fixup .. */
101}
102
diff --git a/arch/sh/drivers/pci/pci-auto.c b/arch/sh/drivers/pci/pci-auto.c
new file mode 100644
index 000000000000..4cef4d1d8c84
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-auto.c
@@ -0,0 +1,555 @@
1/*
2 * PCI autoconfiguration library
3 *
4 * Author: Matt Porter <mporter@mvista.com>
5 *
6 * Copyright 2000, 2001 MontaVista Software Inc.
7 * Copyright 2001 Bradley D. LaRonde <brad@ltc.com>
8 * Copyright 2003 Paul Mundt <lethal@linux-sh.org>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16/*
17 * Modified for MIPS by Jun Sun, jsun@mvista.com
18 *
19 * . Simplify the interface between pci_auto and the rest: a single function.
20 * . Assign resources from low address to upper address.
21 * . change most int to u32.
22 *
23 * Further modified to include it as mips generic code, ppopov@mvista.com.
24 *
25 * 2001-10-26 Bradley D. LaRonde <brad@ltc.com>
26 * - Add a top_bus argument to the "early config" functions so that
27 * they can set a fake parent bus pointer to convince the underlying
28 * pci ops to use type 1 configuration for sub busses.
29 * - Set bridge base and limit registers correctly.
30 * - Align io and memory base properly before and after bridge setup.
31 * - Don't fall through to pci_setup_bars for bridge.
32 * - Reformat the debug output to look more like lspci's output.
33 *
34 * Cloned for SuperH by M. R. Brown, mrbrown@0xd6.org
35 *
36 * 2003-08-05 Paul Mundt <lethal@linux-sh.org>
37 * - Don't update the BAR values on systems that already have valid addresses
38 * and don't want these updated for whatever reason, by way of a new config
39 * option check. However, we still read in the old BAR values so that they
40 * can still be reported through the debug output.
41 */
42
43#include <linux/kernel.h>
44#include <linux/init.h>
45#include <linux/types.h>
46#include <linux/pci.h>
47
48#undef DEBUG
49#ifdef DEBUG
50#define DBG(x...) printk(x)
51#else
52#define DBG(x...)
53#endif
54
55/*
56 * These functions are used early on before PCI scanning is done
57 * and all of the pci_dev and pci_bus structures have been created.
58 */
59static struct pci_dev *fake_pci_dev(struct pci_channel *hose,
60 int top_bus, int busnr, int devfn)
61{
62 static struct pci_dev dev;
63 static struct pci_bus bus;
64
65 dev.bus = &bus;
66 dev.sysdata = hose;
67 dev.devfn = devfn;
68 bus.number = busnr;
69 bus.ops = hose->pci_ops;
70
71 if(busnr != top_bus)
72 /* Fake a parent bus structure. */
73 bus.parent = &bus;
74 else
75 bus.parent = NULL;
76
77 return &dev;
78}
79
80#define EARLY_PCI_OP(rw, size, type) \
81int early_##rw##_config_##size(struct pci_channel *hose, \
82 int top_bus, int bus, int devfn, int offset, type value) \
83{ \
84 return pci_##rw##_config_##size( \
85 fake_pci_dev(hose, top_bus, bus, devfn), \
86 offset, value); \
87}
88
89EARLY_PCI_OP(read, byte, u8 *)
90EARLY_PCI_OP(read, word, u16 *)
91EARLY_PCI_OP(read, dword, u32 *)
92EARLY_PCI_OP(write, byte, u8)
93EARLY_PCI_OP(write, word, u16)
94EARLY_PCI_OP(write, dword, u32)
95
96static struct resource *io_resource_inuse;
97static struct resource *mem_resource_inuse;
98
99static u32 pciauto_lower_iospc;
100static u32 pciauto_upper_iospc;
101
102static u32 pciauto_lower_memspc;
103static u32 pciauto_upper_memspc;
104
105static void __init
106pciauto_setup_bars(struct pci_channel *hose,
107 int top_bus,
108 int current_bus,
109 int pci_devfn,
110 int bar_limit)
111{
112 u32 bar_response, bar_size, bar_value;
113 u32 bar, addr_mask, bar_nr = 0;
114 u32 * upper_limit;
115 u32 * lower_limit;
116 int found_mem64 = 0;
117
118 for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4) {
119#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
120 u32 bar_addr;
121
122 /* Read the old BAR value */
123 early_read_config_dword(hose, top_bus,
124 current_bus,
125 pci_devfn,
126 bar,
127 &bar_addr);
128#endif
129
130 /* Tickle the BAR and get the response */
131 early_write_config_dword(hose, top_bus,
132 current_bus,
133 pci_devfn,
134 bar,
135 0xffffffff);
136
137 early_read_config_dword(hose, top_bus,
138 current_bus,
139 pci_devfn,
140 bar,
141 &bar_response);
142
143#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
144 /*
145 * Write the old BAR value back out, only update the BAR
146 * if we implicitly want resources to be updated, which
147 * is done by the generic code further down. -- PFM.
148 */
149 early_write_config_dword(hose, top_bus,
150 current_bus,
151 pci_devfn,
152 bar,
153 bar_addr);
154#endif
155
156 /* If BAR is not implemented go to the next BAR */
157 if (!bar_response)
158 continue;
159
160 /*
161 * Workaround for a BAR that doesn't use its upper word,
162 * like the ALi 1535D+ PCI DC-97 Controller Modem (M5457).
163 * bdl <brad@ltc.com>
164 */
165 if (!(bar_response & 0xffff0000))
166 bar_response |= 0xffff0000;
167
168retry:
169 /* Check the BAR type and set our address mask */
170 if (bar_response & PCI_BASE_ADDRESS_SPACE) {
171 addr_mask = PCI_BASE_ADDRESS_IO_MASK;
172 upper_limit = &pciauto_upper_iospc;
173 lower_limit = &pciauto_lower_iospc;
174 DBG(" I/O");
175 } else {
176 if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
177 PCI_BASE_ADDRESS_MEM_TYPE_64)
178 found_mem64 = 1;
179
180 addr_mask = PCI_BASE_ADDRESS_MEM_MASK;
181 upper_limit = &pciauto_upper_memspc;
182 lower_limit = &pciauto_lower_memspc;
183 DBG(" Mem");
184 }
185
186
187 /* Calculate requested size */
188 bar_size = ~(bar_response & addr_mask) + 1;
189
190 /* Allocate a base address */
191 bar_value = ((*lower_limit - 1) & ~(bar_size - 1)) + bar_size;
192
193 if ((bar_value + bar_size) > *upper_limit) {
194 if (bar_response & PCI_BASE_ADDRESS_SPACE) {
195 if (io_resource_inuse->child) {
196 io_resource_inuse =
197 io_resource_inuse->child;
198 pciauto_lower_iospc =
199 io_resource_inuse->start;
200 pciauto_upper_iospc =
201 io_resource_inuse->end + 1;
202 goto retry;
203 }
204
205 } else {
206 if (mem_resource_inuse->child) {
207 mem_resource_inuse =
208 mem_resource_inuse->child;
209 pciauto_lower_memspc =
210 mem_resource_inuse->start;
211 pciauto_upper_memspc =
212 mem_resource_inuse->end + 1;
213 goto retry;
214 }
215 }
216 DBG(" unavailable -- skipping, value %x size %x\n",
217 bar_value, bar_size);
218 continue;
219 }
220
221#ifdef CONFIG_PCI_AUTO_UPDATE_RESOURCES
222 /* Write it out and update our limit */
223 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
224 bar, bar_value);
225#endif
226
227 *lower_limit = bar_value + bar_size;
228
229 /*
230 * If we are a 64-bit decoder then increment to the
231 * upper 32 bits of the bar and force it to locate
232 * in the lower 4GB of memory.
233 */
234 if (found_mem64) {
235 bar += 4;
236 early_write_config_dword(hose, top_bus,
237 current_bus,
238 pci_devfn,
239 bar,
240 0x00000000);
241 }
242
243 DBG(" at 0x%.8x [size=0x%x]\n", bar_value, bar_size);
244
245 bar_nr++;
246 }
247
248}
249
250static void __init
251pciauto_prescan_setup_bridge(struct pci_channel *hose,
252 int top_bus,
253 int current_bus,
254 int pci_devfn,
255 int sub_bus)
256{
257 /* Configure bus number registers */
258 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
259 PCI_PRIMARY_BUS, current_bus);
260 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
261 PCI_SECONDARY_BUS, sub_bus + 1);
262 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
263 PCI_SUBORDINATE_BUS, 0xff);
264
265 /* Align memory and I/O to 1MB and 4KB boundaries. */
266 pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1))
267 & ~(0x100000 - 1);
268 pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1))
269 & ~(0x1000 - 1);
270
271 /* Set base (lower limit) of address range behind bridge. */
272 early_write_config_word(hose, top_bus, current_bus, pci_devfn,
273 PCI_MEMORY_BASE, pciauto_lower_memspc >> 16);
274 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
275 PCI_IO_BASE, (pciauto_lower_iospc & 0x0000f000) >> 8);
276 early_write_config_word(hose, top_bus, current_bus, pci_devfn,
277 PCI_IO_BASE_UPPER16, pciauto_lower_iospc >> 16);
278
279 /* We don't support prefetchable memory for now, so disable */
280 early_write_config_word(hose, top_bus, current_bus, pci_devfn,
281 PCI_PREF_MEMORY_BASE, 0);
282 early_write_config_word(hose, top_bus, current_bus, pci_devfn,
283 PCI_PREF_MEMORY_LIMIT, 0);
284}
285
286static void __init
287pciauto_postscan_setup_bridge(struct pci_channel *hose,
288 int top_bus,
289 int current_bus,
290 int pci_devfn,
291 int sub_bus)
292{
293 u32 temp;
294
295 /*
296 * [jsun] we always bump up baselines a little, so that if there
297 * nothing behind P2P bridge, we don't wind up overlapping IO/MEM
298 * spaces.
299 */
300 pciauto_lower_memspc += 1;
301 pciauto_lower_iospc += 1;
302
303 /* Configure bus number registers */
304 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
305 PCI_SUBORDINATE_BUS, sub_bus);
306
307 /* Set upper limit of address range behind bridge. */
308 early_write_config_word(hose, top_bus, current_bus, pci_devfn,
309 PCI_MEMORY_LIMIT, pciauto_lower_memspc >> 16);
310 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
311 PCI_IO_LIMIT, (pciauto_lower_iospc & 0x0000f000) >> 8);
312 early_write_config_word(hose, top_bus, current_bus, pci_devfn,
313 PCI_IO_LIMIT_UPPER16, pciauto_lower_iospc >> 16);
314
315 /* Align memory and I/O to 1MB and 4KB boundaries. */
316 pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1))
317 & ~(0x100000 - 1);
318 pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1))
319 & ~(0x1000 - 1);
320
321 /* Enable memory and I/O accesses, enable bus master */
322 early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
323 PCI_COMMAND, &temp);
324 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
325 PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY
326 | PCI_COMMAND_MASTER);
327}
328
329static void __init
330pciauto_prescan_setup_cardbus_bridge(struct pci_channel *hose,
331 int top_bus,
332 int current_bus,
333 int pci_devfn,
334 int sub_bus)
335{
336 /* Configure bus number registers */
337 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
338 PCI_PRIMARY_BUS, current_bus);
339 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
340 PCI_SECONDARY_BUS, sub_bus + 1);
341 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
342 PCI_SUBORDINATE_BUS, 0xff);
343
344 /* Align memory and I/O to 4KB and 4 byte boundaries. */
345 pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1))
346 & ~(0x1000 - 1);
347 pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1))
348 & ~(0x4 - 1);
349
350 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
351 PCI_CB_MEMORY_BASE_0, pciauto_lower_memspc);
352 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
353 PCI_CB_IO_BASE_0, pciauto_lower_iospc);
354}
355
356static void __init
357pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose,
358 int top_bus,
359 int current_bus,
360 int pci_devfn,
361 int sub_bus)
362{
363 u32 temp;
364
365#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
366 /*
367 * [jsun] we always bump up baselines a little, so that if there
368 * nothing behind P2P bridge, we don't wind up overlapping IO/MEM
369 * spaces.
370 */
371 pciauto_lower_memspc += 1;
372 pciauto_lower_iospc += 1;
373#endif
374
375 /*
376 * Configure subordinate bus number. The PCI subsystem
377 * bus scan will renumber buses (reserving three additional
378 * for this PCI<->CardBus bridge for the case where a CardBus
379 * adapter contains a P2P or CB2CB bridge.
380 */
381
382 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
383 PCI_SUBORDINATE_BUS, sub_bus);
384
385 /*
386 * Reserve an additional 4MB for mem space and 16KB for
387 * I/O space. This should cover any additional space
388 * requirement of unusual CardBus devices with
389 * additional bridges that can consume more address space.
390 *
391 * Although pcmcia-cs currently will reprogram bridge
392 * windows, the goal is to add an option to leave them
393 * alone and use the bridge window ranges as the regions
394 * that are searched for free resources upon hot-insertion
395 * of a device. This will allow a PCI<->CardBus bridge
396 * configured by this routine to happily live behind a
397 * P2P bridge in a system.
398 */
399#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D)
400 pciauto_lower_memspc += 0x00400000;
401 pciauto_lower_iospc += 0x00004000;
402#endif
403
404 /* Align memory and I/O to 4KB and 4 byte boundaries. */
405 pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1))
406 & ~(0x1000 - 1);
407 pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1))
408 & ~(0x4 - 1);
409 /* Set up memory and I/O filter limits, assume 32-bit I/O space */
410 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
411 PCI_CB_MEMORY_LIMIT_0, pciauto_lower_memspc - 1);
412 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
413 PCI_CB_IO_LIMIT_0, pciauto_lower_iospc - 1);
414
415 /* Enable memory and I/O accesses, enable bus master */
416 early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
417 PCI_COMMAND, &temp);
418 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
419 PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
420 PCI_COMMAND_MASTER);
421}
422
423#define PCIAUTO_IDE_MODE_MASK 0x05
424
425static int __init
426pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus)
427{
428 int sub_bus;
429 u32 pci_devfn, pci_class, cmdstat, found_multi=0;
430 unsigned short vid, did;
431 unsigned char header_type;
432 int devfn_start = 0;
433 int devfn_stop = 0xff;
434
435 sub_bus = current_bus;
436
437 if (hose->first_devfn)
438 devfn_start = hose->first_devfn;
439 if (hose->last_devfn)
440 devfn_stop = hose->last_devfn;
441
442 for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
443
444 if (PCI_FUNC(pci_devfn) && !found_multi)
445 continue;
446
447 early_read_config_word(hose, top_bus, current_bus, pci_devfn,
448 PCI_VENDOR_ID, &vid);
449
450 if (vid == 0xffff) continue;
451
452 early_read_config_byte(hose, top_bus, current_bus, pci_devfn,
453 PCI_HEADER_TYPE, &header_type);
454
455 if (!PCI_FUNC(pci_devfn))
456 found_multi = header_type & 0x80;
457
458 early_read_config_word(hose, top_bus, current_bus, pci_devfn,
459 PCI_DEVICE_ID, &did);
460
461 early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
462 PCI_CLASS_REVISION, &pci_class);
463
464 DBG("%.2x:%.2x.%x Class %.4x: %.4x:%.4x",
465 current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn),
466 pci_class >> 16, vid, did);
467 if (pci_class & 0xff)
468 DBG(" (rev %.2x)", pci_class & 0xff);
469 DBG("\n");
470
471 if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) {
472 DBG(" Bridge: primary=%.2x, secondary=%.2x\n",
473 current_bus, sub_bus + 1);
474#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D)
475 pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_1);
476#endif
477 pciauto_prescan_setup_bridge(hose, top_bus, current_bus,
478 pci_devfn, sub_bus);
479 DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n",
480 sub_bus + 1,
481 pciauto_lower_iospc, pciauto_lower_memspc);
482 sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1);
483 DBG("Back to bus %.2x\n", current_bus);
484 pciauto_postscan_setup_bridge(hose, top_bus, current_bus,
485 pci_devfn, sub_bus);
486 continue;
487 } else if ((pci_class >> 16) == PCI_CLASS_BRIDGE_CARDBUS) {
488 DBG(" CARDBUS Bridge: primary=%.2x, secondary=%.2x\n",
489 current_bus, sub_bus + 1);
490 DBG("PCI Autoconfig: Found CardBus bridge, device %d function %d\n", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn));
491 /* Place CardBus Socket/ExCA registers */
492 pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_0);
493
494 pciauto_prescan_setup_cardbus_bridge(hose, top_bus,
495 current_bus, pci_devfn, sub_bus);
496
497 DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n",
498 sub_bus + 1,
499 pciauto_lower_iospc, pciauto_lower_memspc);
500 sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1);
501 DBG("Back to bus %.2x, sub_bus is %x\n", current_bus, sub_bus);
502 pciauto_postscan_setup_cardbus_bridge(hose, top_bus,
503 current_bus, pci_devfn, sub_bus);
504 continue;
505 } else if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) {
506
507 unsigned char prg_iface;
508
509 early_read_config_byte(hose, top_bus, current_bus,
510 pci_devfn, PCI_CLASS_PROG, &prg_iface);
511 if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) {
512 DBG("Skipping legacy mode IDE controller\n");
513 continue;
514 }
515 }
516
517 /*
518 * Found a peripheral, enable some standard
519 * settings
520 */
521 early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
522 PCI_COMMAND, &cmdstat);
523 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
524 PCI_COMMAND, cmdstat | PCI_COMMAND_IO |
525 PCI_COMMAND_MEMORY |
526 PCI_COMMAND_MASTER);
527#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
528 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
529 PCI_LATENCY_TIMER, 0x80);
530#endif
531
532 /* Allocate PCI I/O and/or memory space */
533 pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_5);
534 }
535 return sub_bus;
536}
537
538int __init
539pciauto_assign_resources(int busno, struct pci_channel *hose)
540{
541 /* setup resource limits */
542 io_resource_inuse = hose->io_resource;
543 mem_resource_inuse = hose->mem_resource;
544
545 pciauto_lower_iospc = io_resource_inuse->start;
546 pciauto_upper_iospc = io_resource_inuse->end + 1;
547 pciauto_lower_memspc = mem_resource_inuse->start;
548 pciauto_upper_memspc = mem_resource_inuse->end + 1;
549 DBG("Autoconfig PCI channel 0x%p\n", hose);
550 DBG("Scanning bus %.2x, I/O 0x%.8x:0x%.8x, Mem 0x%.8x:0x%.8x\n",
551 busno, pciauto_lower_iospc, pciauto_upper_iospc,
552 pciauto_lower_memspc, pciauto_upper_memspc);
553
554 return pciauto_bus_scan(hose, busno, busno);
555}
diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c
new file mode 100644
index 000000000000..30b14ac7ae5a
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-sh7751.c
@@ -0,0 +1,417 @@
1/*
2 * Low-Level PCI Support for the SH7751
3 *
4 * Dustin McIntire (dustin@sensoria.com)
5 * Derived from arch/i386/kernel/pci-*.c which bore the message:
6 * (c) 1999--2000 Martin Mares <mj@ucw.cz>
7 *
8 * Ported to the new API by Paul Mundt <lethal@linux-sh.org>
9 * With cleanup by Paul van Gool <pvangool@mimotech.com>
10 *
11 * May be copied or modified under the terms of the GNU General Public
12 * License. See linux/COPYING for more information.
13 *
14 */
15
16#undef DEBUG
17
18#include <linux/config.h>
19#include <linux/types.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/pci.h>
23#include <linux/sched.h>
24#include <linux/ioport.h>
25#include <linux/errno.h>
26#include <linux/irq.h>
27#include <linux/delay.h>
28
29#include <asm/machvec.h>
30#include <asm/io.h>
31#include "pci-sh7751.h"
32
33static unsigned int pci_probe = PCI_PROBE_CONF1;
34extern int pci_fixup_pcic(void);
35
36void pcibios_fixup_irqs(void) __attribute__ ((weak));
37
38/*
39 * Direct access to PCI hardware...
40 */
41
42#define CONFIG_CMD(bus, devfn, where) (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
43
44/*
45 * Functions for accessing PCI configuration space with type 1 accesses
46 */
47static int sh7751_pci_read(struct pci_bus *bus, unsigned int devfn,
48 int where, int size, u32 *val)
49{
50 unsigned long flags;
51 u32 data;
52
53 /*
54 * PCIPDR may only be accessed as 32 bit words,
55 * so we must do byte alignment by hand
56 */
57 local_irq_save(flags);
58 outl(CONFIG_CMD(bus,devfn,where), PCI_REG(SH7751_PCIPAR));
59 data = inl(PCI_REG(SH7751_PCIPDR));
60 local_irq_restore(flags);
61
62 switch (size) {
63 case 1:
64 *val = (data >> ((where & 3) << 3)) & 0xff;
65 break;
66 case 2:
67 *val = (data >> ((where & 2) << 3)) & 0xffff;
68 break;
69 case 4:
70 *val = data;
71 break;
72 default:
73 return PCIBIOS_FUNC_NOT_SUPPORTED;
74 }
75
76 return PCIBIOS_SUCCESSFUL;
77}
78
79/*
80 * Since SH7751 only does 32bit access we'll have to do a read,
81 * mask,write operation.
82 * We'll allow an odd byte offset, though it should be illegal.
83 */
84static int sh7751_pci_write(struct pci_bus *bus, unsigned int devfn,
85 int where, int size, u32 val)
86{
87 unsigned long flags;
88 int shift;
89 u32 data;
90
91 local_irq_save(flags);
92 outl(CONFIG_CMD(bus,devfn,where), PCI_REG(SH7751_PCIPAR));
93 data = inl(PCI_REG(SH7751_PCIPDR));
94 local_irq_restore(flags);
95
96 switch (size) {
97 case 1:
98 shift = (where & 3) << 3;
99 data &= ~(0xff << shift);
100 data |= ((val & 0xff) << shift);
101 break;
102 case 2:
103 shift = (where & 2) << 3;
104 data &= ~(0xffff << shift);
105 data |= ((val & 0xffff) << shift);
106 break;
107 case 4:
108 data = val;
109 break;
110 default:
111 return PCIBIOS_FUNC_NOT_SUPPORTED;
112 }
113
114 outl(data, PCI_REG(SH7751_PCIPDR));
115
116 return PCIBIOS_SUCCESSFUL;
117}
118
119#undef CONFIG_CMD
120
121struct pci_ops sh7751_pci_ops = {
122 .read = sh7751_pci_read,
123 .write = sh7751_pci_write,
124};
125
126static int __init pci_check_direct(void)
127{
128 unsigned int tmp, id;
129
130 /* check for SH7751/SH7751R hardware */
131 id = inl(SH7751_PCIREG_BASE+SH7751_PCICONF0);
132 if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) &&
133 id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) {
134 pr_debug("PCI: This is not an SH7751(R) (%x)\n", id);
135 return -ENODEV;
136 }
137
138 /*
139 * Check if configuration works.
140 */
141 if (pci_probe & PCI_PROBE_CONF1) {
142 tmp = inl (PCI_REG(SH7751_PCIPAR));
143 outl (0x80000000, PCI_REG(SH7751_PCIPAR));
144 if (inl (PCI_REG(SH7751_PCIPAR)) == 0x80000000) {
145 outl (tmp, PCI_REG(SH7751_PCIPAR));
146 printk(KERN_INFO "PCI: Using configuration type 1\n");
147 request_region(PCI_REG(SH7751_PCIPAR), 8, "PCI conf1");
148 return 0;
149 }
150 outl (tmp, PCI_REG(SH7751_PCIPAR));
151 }
152
153 pr_debug("PCI: pci_check_direct failed\n");
154 return -EINVAL;
155}
156
157/***************************************************************************************/
158
159/*
160 * Handle bus scanning and fixups ....
161 */
162
163static void __init pci_fixup_ide_bases(struct pci_dev *d)
164{
165 int i;
166
167 /*
168 * PCI IDE controllers use non-standard I/O port decoding, respect it.
169 */
170 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
171 return;
172 pr_debug("PCI: IDE base address fixup for %s\n", pci_name(d));
173 for(i=0; i<4; i++) {
174 struct resource *r = &d->resource[i];
175 if ((r->start & ~0x80) == 0x374) {
176 r->start |= 2;
177 r->end = r->start;
178 }
179 }
180}
181
182DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
183
184/*
185 * Called after each bus is probed, but before its children
186 * are examined.
187 */
188
189void __init pcibios_fixup_bus(struct pci_bus *b)
190{
191 pci_read_bridge_bases(b);
192}
193
194/*
195 * Initialization. Try all known PCI access methods. Note that we support
196 * using both PCI BIOS and direct access: in such cases, we use I/O ports
197 * to access config space.
198 *
199 * Note that the platform specific initialization (BSC registers, and memory
200 * space mapping) will be called via the machine vectors (sh_mv.mv_pci_init()) if it
201 * exitst and via the platform defined function pcibios_init_platform().
202 * See pci_bigsur.c for implementation;
203 *
204 * The BIOS version of the pci functions is not yet implemented but it is left
205 * in for completeness. Currently an error will be genereated at compile time.
206 */
207
208static int __init sh7751_pci_init(void)
209{
210 int ret;
211
212 pr_debug("PCI: Starting intialization.\n");
213 if ((ret = pci_check_direct()) != 0)
214 return ret;
215
216 return pcibios_init_platform();
217}
218
219subsys_initcall(sh7751_pci_init);
220
221static int __init __area_sdram_check(unsigned int area)
222{
223 u32 word;
224
225 word = inl(SH7751_BCR1);
226 /* check BCR for SDRAM in area */
227 if(((word >> area) & 1) == 0) {
228 printk("PCI: Area %d is not configured for SDRAM. BCR1=0x%x\n",
229 area, word);
230 return 0;
231 }
232 outl(word, PCI_REG(SH7751_PCIBCR1));
233
234 word = (u16)inw(SH7751_BCR2);
235 /* check BCR2 for 32bit SDRAM interface*/
236 if(((word >> (area << 1)) & 0x3) != 0x3) {
237 printk("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%x\n",
238 area, word);
239 return 0;
240 }
241 outl(word, PCI_REG(SH7751_PCIBCR2));
242
243 return 1;
244}
245
246int __init sh7751_pcic_init(struct sh7751_pci_address_map *map)
247{
248 u32 reg;
249 u32 word;
250
251 /* Set the BCR's to enable PCI access */
252 reg = inl(SH7751_BCR1);
253 reg |= 0x80000;
254 outl(reg, SH7751_BCR1);
255
256 /* Turn the clocks back on (not done in reset)*/
257 outl(0, PCI_REG(SH7751_PCICLKR));
258 /* Clear Powerdown IRQ's (not done in reset) */
259 word = SH7751_PCIPINT_D3 | SH7751_PCIPINT_D0;
260 outl(word, PCI_REG(SH7751_PCIPINT));
261
262 /*
263 * This code is unused for some boards as it is done in the
264 * bootloader and doing it here means the MAC addresses loaded
265 * by the bootloader get lost.
266 */
267 if (!(map->flags & SH7751_PCIC_NO_RESET)) {
268 /* toggle PCI reset pin */
269 word = SH7751_PCICR_PREFIX | SH7751_PCICR_PRST;
270 outl(word,PCI_REG(SH7751_PCICR));
271 /* Wait for a long time... not 1 sec. but long enough */
272 mdelay(100);
273 word = SH7751_PCICR_PREFIX;
274 outl(word,PCI_REG(SH7751_PCICR));
275 }
276
277 /* set the command/status bits to:
278 * Wait Cycle Control + Parity Enable + Bus Master +
279 * Mem space enable
280 */
281 word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER |
282 SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES;
283 outl(word, PCI_REG(SH7751_PCICONF1));
284
285 /* define this host as the host bridge */
286 word = SH7751_PCI_HOST_BRIDGE << 24;
287 outl(word, PCI_REG(SH7751_PCICONF2));
288
289 /* Set IO and Mem windows to local address
290 * Make PCI and local address the same for easy 1 to 1 mapping
291 * Window0 = map->window0.size @ non-cached area base = SDRAM
292 * Window1 = map->window1.size @ cached area base = SDRAM
293 */
294 word = map->window0.size - 1;
295 outl(word, PCI_REG(SH7751_PCILSR0));
296 word = map->window1.size - 1;
297 outl(word, PCI_REG(SH7751_PCILSR1));
298 /* Set the values on window 0 PCI config registers */
299 word = P2SEGADDR(map->window0.base);
300 outl(word, PCI_REG(SH7751_PCILAR0));
301 outl(word, PCI_REG(SH7751_PCICONF5));
302 /* Set the values on window 1 PCI config registers */
303 word = PHYSADDR(map->window1.base);
304 outl(word, PCI_REG(SH7751_PCILAR1));
305 outl(word, PCI_REG(SH7751_PCICONF6));
306
307 /* Set the local 16MB PCI memory space window to
308 * the lowest PCI mapped address
309 */
310 word = PCIBIOS_MIN_MEM & SH7751_PCIMBR_MASK;
311 PCIDBG(2,"PCI: Setting upper bits of Memory window to 0x%x\n", word);
312 outl(word , PCI_REG(SH7751_PCIMBR));
313
314 /* Map IO space into PCI IO window
315 * The IO window is 64K-PCIBIOS_MIN_IO in size
316 * IO addresses will be translated to the
317 * PCI IO window base address
318 */
319 PCIDBG(3,"PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", PCIBIOS_MIN_IO,
320 (64*1024), SH7751_PCI_IO_BASE+PCIBIOS_MIN_IO);
321
322 /*
323 * XXX: For now, leave this board-specific. In the event we have other
324 * boards that need to do similar work, this can be wrapped.
325 */
326#ifdef CONFIG_SH_BIGSUR
327 bigsur_port_map(PCIBIOS_MIN_IO, (64*1024), SH7751_PCI_IO_BASE+PCIBIOS_MIN_IO,0);
328#endif
329
330 /* Make sure the MSB's of IO window are set to access PCI space correctly */
331 word = PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK;
332 PCIDBG(2,"PCI: Setting upper bits of IO window to 0x%x\n", word);
333 outl(word, PCI_REG(SH7751_PCIIOBR));
334
335 /* Set PCI WCRx, BCRx's, copy from BSC locations */
336
337 /* check BCR for SDRAM in specified area */
338 switch (map->window0.base) {
339 case SH7751_CS0_BASE_ADDR: word = __area_sdram_check(0); break;
340 case SH7751_CS1_BASE_ADDR: word = __area_sdram_check(1); break;
341 case SH7751_CS2_BASE_ADDR: word = __area_sdram_check(2); break;
342 case SH7751_CS3_BASE_ADDR: word = __area_sdram_check(3); break;
343 case SH7751_CS4_BASE_ADDR: word = __area_sdram_check(4); break;
344 case SH7751_CS5_BASE_ADDR: word = __area_sdram_check(5); break;
345 case SH7751_CS6_BASE_ADDR: word = __area_sdram_check(6); break;
346 }
347
348 if (!word)
349 return 0;
350
351 /* configure the wait control registers */
352 word = inl(SH7751_WCR1);
353 outl(word, PCI_REG(SH7751_PCIWCR1));
354 word = inl(SH7751_WCR2);
355 outl(word, PCI_REG(SH7751_PCIWCR2));
356 word = inl(SH7751_WCR3);
357 outl(word, PCI_REG(SH7751_PCIWCR3));
358 word = inl(SH7751_MCR);
359 outl(word, PCI_REG(SH7751_PCIMCR));
360
361 /* NOTE: I'm ignoring the PCI error IRQs for now..
362 * TODO: add support for the internal error interrupts and
363 * DMA interrupts...
364 */
365
366#ifdef CONFIG_SH_RTS7751R2D
367 pci_fixup_pcic();
368#endif
369
370 /* SH7751 init done, set central function init complete */
371 /* use round robin mode to stop a device starving/overruning */
372 word = SH7751_PCICR_PREFIX | SH7751_PCICR_CFIN | SH7751_PCICR_ARBM;
373 outl(word,PCI_REG(SH7751_PCICR));
374
375 return 1;
376}
377
378char * __init pcibios_setup(char *str)
379{
380 if (!strcmp(str, "off")) {
381 pci_probe = 0;
382 return NULL;
383 }
384
385 return str;
386}
387
388/*
389 * IRQ functions
390 */
391static u8 __init sh7751_no_swizzle(struct pci_dev *dev, u8 *pin)
392{
393 /* no swizzling */
394 return PCI_SLOT(dev->devfn);
395}
396
397static int sh7751_pci_lookup_irq(struct pci_dev *dev, u8 slot, u8 pin)
398{
399 int irq = -1;
400
401 /* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */
402 irq = pcibios_map_platform_irq(slot,pin);
403 if( irq < 0 ) {
404 pr_debug("PCI: Error mapping IRQ on device %s\n", pci_name(dev));
405 return irq;
406 }
407
408 pr_debug("Setting IRQ for slot %s to %d\n", pci_name(dev), irq);
409
410 return irq;
411}
412
413void __init pcibios_fixup_irqs(void)
414{
415 pci_fixup_irqs(sh7751_no_swizzle, sh7751_pci_lookup_irq);
416}
417
diff --git a/arch/sh/drivers/pci/pci-sh7751.h b/arch/sh/drivers/pci/pci-sh7751.h
new file mode 100644
index 000000000000..1fee5cae10d1
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-sh7751.h
@@ -0,0 +1,303 @@
1/*
2 * Low-Level PCI Support for SH7751 targets
3 *
4 * Dustin McIntire (dustin@sensoria.com) (c) 2001
5 * Paul Mundt (lethal@linux-sh.org) (c) 2003
6 *
7 * May be copied or modified under the terms of the GNU General Public
8 * License. See linux/COPYING for more information.
9 *
10 */
11
12#ifndef _PCI_SH7751_H_
13#define _PCI_SH7751_H_
14
15#include <linux/pci.h>
16
17/* set debug level 4=verbose...1=terse */
18//#define DEBUG_PCI 3
19#undef DEBUG_PCI
20
21#ifdef DEBUG_PCI
22#define PCIDBG(n, x...) { if(DEBUG_PCI>=n) printk(x); }
23#else
24#define PCIDBG(n, x...)
25#endif
26
27/* startup values */
28#define PCI_PROBE_BIOS 1
29#define PCI_PROBE_CONF1 2
30#define PCI_PROBE_CONF2 4
31#define PCI_NO_SORT 0x100
32#define PCI_BIOS_SORT 0x200
33#define PCI_NO_CHECKS 0x400
34#define PCI_ASSIGN_ROMS 0x1000
35#define PCI_BIOS_IRQ_SCAN 0x2000
36
37/* Platform Specific Values */
38#define SH7751_VENDOR_ID 0x1054
39#define SH7751_DEVICE_ID 0x3505
40#define SH7751R_DEVICE_ID 0x350e
41
42/* SH7751 Specific Values */
43#define SH7751_PCI_CONFIG_BASE 0xFD000000 /* Config space base addr */
44#define SH7751_PCI_CONFIG_SIZE 0x1000000 /* Config space size */
45#define SH7751_PCI_MEMORY_BASE 0xFD000000 /* Memory space base addr */
46#define SH7751_PCI_MEM_SIZE 0x01000000 /* Size of Memory window */
47#define SH7751_PCI_IO_BASE 0xFE240000 /* IO space base address */
48#define SH7751_PCI_IO_SIZE 0x40000 /* Size of IO window */
49
50#define SH7751_PCIREG_BASE 0xFE200000 /* PCI regs base address */
51#define PCI_REG(n) (SH7751_PCIREG_BASE+ n)
52
53#define SH7751_PCICONF0 0x0 /* PCI Config Reg 0 */
54 #define SH7751_PCICONF0_DEVID 0xFFFF0000 /* Device ID */
55 #define SH7751_PCICONF0_VNDID 0x0000FFFF /* Vendor ID */
56#define SH7751_PCICONF1 0x4 /* PCI Config Reg 1 */
57 #define SH7751_PCICONF1_DPE 0x80000000 /* Data Parity Error */
58 #define SH7751_PCICONF1_SSE 0x40000000 /* System Error Status */
59 #define SH7751_PCICONF1_RMA 0x20000000 /* Master Abort */
60 #define SH7751_PCICONF1_RTA 0x10000000 /* Target Abort Rx Status */
61 #define SH7751_PCICONF1_STA 0x08000000 /* Target Abort Exec Status */
62 #define SH7751_PCICONF1_DEV 0x06000000 /* Timing Status */
63 #define SH7751_PCICONF1_DPD 0x01000000 /* Data Parity Status */
64 #define SH7751_PCICONF1_FBBC 0x00800000 /* Back 2 Back Status */
65 #define SH7751_PCICONF1_UDF 0x00400000 /* User Defined Status */
66 #define SH7751_PCICONF1_66M 0x00200000 /* 66Mhz Operation Status */
67 #define SH7751_PCICONF1_PM 0x00100000 /* Power Management Status */
68 #define SH7751_PCICONF1_PBBE 0x00000200 /* Back 2 Back Control */
69 #define SH7751_PCICONF1_SER 0x00000100 /* SERR Output Control */
70 #define SH7751_PCICONF1_WCC 0x00000080 /* Wait Cycle Control */
71 #define SH7751_PCICONF1_PER 0x00000040 /* Parity Error Response */
72 #define SH7751_PCICONF1_VPS 0x00000020 /* VGA Pallet Snoop */
73 #define SH7751_PCICONF1_MWIE 0x00000010 /* Memory Write+Invalidate */
74 #define SH7751_PCICONF1_SPC 0x00000008 /* Special Cycle Control */
75 #define SH7751_PCICONF1_BUM 0x00000004 /* Bus Master Control */
76 #define SH7751_PCICONF1_MES 0x00000002 /* Memory Space Control */
77 #define SH7751_PCICONF1_IOS 0x00000001 /* I/O Space Control */
78#define SH7751_PCICONF2 0x8 /* PCI Config Reg 2 */
79 #define SH7751_PCICONF2_BCC 0xFF000000 /* Base Class Code */
80 #define SH7751_PCICONF2_SCC 0x00FF0000 /* Sub-Class Code */
81 #define SH7751_PCICONF2_RLPI 0x0000FF00 /* Programming Interface */
82 #define SH7751_PCICONF2_REV 0x000000FF /* Revision ID */
83#define SH7751_PCICONF3 0xC /* PCI Config Reg 3 */
84 #define SH7751_PCICONF3_BIST7 0x80000000 /* Bist Supported */
85 #define SH7751_PCICONF3_BIST6 0x40000000 /* Bist Executing */
86 #define SH7751_PCICONF3_BIST3_0 0x0F000000 /* Bist Passed */
87 #define SH7751_PCICONF3_HD7 0x00800000 /* Single Funtion device */
88 #define SH7751_PCICONF3_HD6_0 0x007F0000 /* Configuration Layout */
89 #define SH7751_PCICONF3_LAT 0x0000FF00 /* Latency Timer */
90 #define SH7751_PCICONF3_CLS 0x000000FF /* Cache Line Size */
91#define SH7751_PCICONF4 0x10 /* PCI Config Reg 4 */
92 #define SH7751_PCICONF4_BASE 0xFFFFFFFC /* I/O Space Base Addr */
93 #define SH7751_PCICONF4_ASI 0x00000001 /* Address Space Type */
94#define SH7751_PCICONF5 0x14 /* PCI Config Reg 5 */
95 #define SH7751_PCICONF5_BASE 0xFFFFFFF0 /* Mem Space Base Addr */
96 #define SH7751_PCICONF5_LAP 0x00000008 /* Prefetch Enabled */
97 #define SH7751_PCICONF5_LAT 0x00000006 /* Local Memory type */
98 #define SH7751_PCICONF5_ASI 0x00000001 /* Address Space Type */
99#define SH7751_PCICONF6 0x18 /* PCI Config Reg 6 */
100 #define SH7751_PCICONF6_BASE 0xFFFFFFF0 /* Mem Space Base Addr */
101 #define SH7751_PCICONF6_LAP 0x00000008 /* Prefetch Enabled */
102 #define SH7751_PCICONF6_LAT 0x00000006 /* Local Memory type */
103 #define SH7751_PCICONF6_ASI 0x00000001 /* Address Space Type */
104/* PCICONF7 - PCICONF10 are undefined */
105#define SH7751_PCICONF11 0x2C /* PCI Config Reg 11 */
106 #define SH7751_PCICONF11_SSID 0xFFFF0000 /* Subsystem ID */
107 #define SH7751_PCICONF11_SVID 0x0000FFFF /* Subsystem Vendor ID */
108/* PCICONF12 is undefined */
109#define SH7751_PCICONF13 0x34 /* PCI Config Reg 13 */
110 #define SH7751_PCICONF13_CPTR 0x000000FF /* PM function pointer */
111/* PCICONF14 is undefined */
112#define SH7751_PCICONF15 0x3C /* PCI Config Reg 15 */
113 #define SH7751_PCICONF15_IPIN 0x000000FF /* Interrupt Pin */
114#define SH7751_PCICONF16 0x40 /* PCI Config Reg 16 */
115 #define SH7751_PCICONF16_PMES 0xF8000000 /* PME Support */
116 #define SH7751_PCICONF16_D2S 0x04000000 /* D2 Support */
117 #define SH7751_PCICONF16_D1S 0x02000000 /* D1 Support */
118 #define SH7751_PCICONF16_DSI 0x00200000 /* Bit Device Init. */
119 #define SH7751_PCICONF16_PMCK 0x00080000 /* Clock for PME req. */
120 #define SH7751_PCICONF16_VER 0x00070000 /* PM Version */
121 #define SH7751_PCICONF16_NIP 0x0000FF00 /* Next Item Pointer */
122 #define SH7751_PCICONF16_CID 0x000000FF /* Capability Identifier */
123#define SH7751_PCICONF17 0x44 /* PCI Config Reg 17 */
124 #define SH7751_PCICONF17_DATA 0xFF000000 /* Data field for PM */
125 #define SH7751_PCICONF17_PMES 0x00800000 /* PME Status */
126 #define SH7751_PCICONF17_DSCL 0x00600000 /* Data Scaling Value */
127 #define SH7751_PCICONF17_DSEL 0x001E0000 /* Data Select */
128 #define SH7751_PCICONF17_PMEN 0x00010000 /* PME Enable */
129 #define SH7751_PCICONF17_PWST 0x00000003 /* Power State */
130/* SH7715 Internal PCI Registers */
131#define SH7751_PCICR 0x100 /* PCI Control Register */
132 #define SH7751_PCICR_PREFIX 0xA5000000 /* CR prefix for write */
133 #define SH7751_PCICR_TRSB 0x00000200 /* Target Read Single */
134 #define SH7751_PCICR_BSWP 0x00000100 /* Target Byte Swap */
135 #define SH7751_PCICR_PLUP 0x00000080 /* Enable PCI Pullup */
136 #define SH7751_PCICR_ARBM 0x00000040 /* PCI Arbitration Mode */
137 #define SH7751_PCICR_MD 0x00000030 /* MD9 and MD10 status */
138 #define SH7751_PCICR_SERR 0x00000008 /* SERR output assert */
139 #define SH7751_PCICR_INTA 0x00000004 /* INTA output assert */
140 #define SH7751_PCICR_PRST 0x00000002 /* PCI Reset Assert */
141 #define SH7751_PCICR_CFIN 0x00000001 /* Central Fun. Init Done */
142#define SH7751_PCILSR0 0x104 /* PCI Local Space Register0 */
143#define SH7751_PCILSR1 0x108 /* PCI Local Space Register1 */
144#define SH7751_PCILAR0 0x10C /* PCI Local Address Register1 */
145#define SH7751_PCILAR1 0x110 /* PCI Local Address Register1 */
146#define SH7751_PCIINT 0x114 /* PCI Interrupt Register */
147 #define SH7751_PCIINT_MLCK 0x00008000 /* Master Lock Error */
148 #define SH7751_PCIINT_TABT 0x00004000 /* Target Abort Error */
149 #define SH7751_PCIINT_TRET 0x00000200 /* Target Retry Error */
150 #define SH7751_PCIINT_MFDE 0x00000100 /* Master Func. Disable Error */
151 #define SH7751_PCIINT_PRTY 0x00000080 /* Address Parity Error */
152 #define SH7751_PCIINT_SERR 0x00000040 /* SERR Detection Error */
153 #define SH7751_PCIINT_TWDP 0x00000020 /* Tgt. Write Parity Error */
154 #define SH7751_PCIINT_TRDP 0x00000010 /* Tgt. Read Parity Error Det. */
155 #define SH7751_PCIINT_MTABT 0x00000008 /* Master-Tgt. Abort Error */
156 #define SH7751_PCIINT_MMABT 0x00000004 /* Master-Master Abort Error */
157 #define SH7751_PCIINT_MWPD 0x00000002 /* Master Write PERR Detect */
158 #define SH7751_PCIINT_MRPD 0x00000002 /* Master Read PERR Detect */
159#define SH7751_PCIINTM 0x118 /* PCI Interrupt Mask Register */
160#define SH7751_PCIALR 0x11C /* Error Address Register */
161#define SH7751_PCICLR 0x120 /* Error Command/Data Register */
162 #define SH7751_PCICLR_MPIO 0x80000000 /* Error Command/Data Register */
163 #define SH7751_PCICLR_MDMA0 0x40000000 /* DMA0 Transfer Error */
164 #define SH7751_PCICLR_MDMA1 0x20000000 /* DMA1 Transfer Error */
165 #define SH7751_PCICLR_MDMA2 0x10000000 /* DMA2 Transfer Error */
166 #define SH7751_PCICLR_MDMA3 0x08000000 /* DMA3 Transfer Error */
167 #define SH7751_PCICLR_TGT 0x04000000 /* Target Transfer Error */
168 #define SH7751_PCICLR_CMDL 0x0000000F /* PCI Command at Error */
169#define SH7751_PCIAINT 0x130 /* Arbiter Interrupt Register */
170 #define SH7751_PCIAINT_MBKN 0x00002000 /* Master Broken Interrupt */
171 #define SH7751_PCIAINT_TBTO 0x00001000 /* Target Bus Time Out */
172 #define SH7751_PCIAINT_MBTO 0x00001000 /* Master Bus Time Out */
173 #define SH7751_PCIAINT_TABT 0x00000008 /* Target Abort */
174 #define SH7751_PCIAINT_MABT 0x00000004 /* Master Abort */
175 #define SH7751_PCIAINT_RDPE 0x00000002 /* Read Data Parity Error */
176 #define SH7751_PCIAINT_WDPE 0x00000002 /* Write Data Parity Error */
177#define SH7751_PCIAINTM 0x134 /* Arbiter Int. Mask Register */
178#define SH7751_PCIBMLR 0x138 /* Error Bus Master Register */
179 #define SH7751_PCIBMLR_REQ4 0x00000010 /* REQ4 bus master at error */
180 #define SH7751_PCIBMLR_REQ3 0x00000008 /* REQ3 bus master at error */
181 #define SH7751_PCIBMLR_REQ2 0x00000004 /* REQ2 bus master at error */
182 #define SH7751_PCIBMLR_REQ1 0x00000002 /* REQ1 bus master at error */
183 #define SH7751_PCIBMLR_REQ0 0x00000001 /* REQ0 bus master at error */
184#define SH7751_PCIDMABT 0x140 /* DMA Transfer Arb. Register */
185 #define SH7751_PCIDMABT_RRBN 0x00000001 /* DMA Arbitor Round-Robin */
186#define SH7751_PCIDPA0 0x180 /* DMA0 Transfer Addr. Register */
187#define SH7751_PCIDLA0 0x184 /* DMA0 Local Addr. Register */
188#define SH7751_PCIDTC0 0x188 /* DMA0 Transfer Cnt. Register */
189#define SH7751_PCIDCR0 0x18C /* DMA0 Control Register */
190 #define SH7751_PCIDCR_ALGN 0x00000600 /* DMA Alignment Mode */
191 #define SH7751_PCIDCR_MAST 0x00000100 /* DMA Termination Type */
192 #define SH7751_PCIDCR_INTM 0x00000080 /* DMA Interrupt Done Mask*/
193 #define SH7751_PCIDCR_INTS 0x00000040 /* DMA Interrupt Done Status */
194 #define SH7751_PCIDCR_LHLD 0x00000020 /* Local Address Control */
195 #define SH7751_PCIDCR_PHLD 0x00000010 /* PCI Address Control*/
196 #define SH7751_PCIDCR_IOSEL 0x00000008 /* PCI Address Space Type */
197 #define SH7751_PCIDCR_DIR 0x00000004 /* DMA Transfer Direction */
198 #define SH7751_PCIDCR_STOP 0x00000002 /* Force DMA Stop */
199 #define SH7751_PCIDCR_STRT 0x00000001 /* DMA Start */
200#define SH7751_PCIDPA1 0x190 /* DMA1 Transfer Addr. Register */
201#define SH7751_PCIDLA1 0x194 /* DMA1 Local Addr. Register */
202#define SH7751_PCIDTC1 0x198 /* DMA1 Transfer Cnt. Register */
203#define SH7751_PCIDCR1 0x19C /* DMA1 Control Register */
204#define SH7751_PCIDPA2 0x1A0 /* DMA2 Transfer Addr. Register */
205#define SH7751_PCIDLA2 0x1A4 /* DMA2 Local Addr. Register */
206#define SH7751_PCIDTC2 0x1A8 /* DMA2 Transfer Cnt. Register */
207#define SH7751_PCIDCR2 0x1AC /* DMA2 Control Register */
208#define SH7751_PCIDPA3 0x1B0 /* DMA3 Transfer Addr. Register */
209#define SH7751_PCIDLA3 0x1B4 /* DMA3 Local Addr. Register */
210#define SH7751_PCIDTC3 0x1B8 /* DMA3 Transfer Cnt. Register */
211#define SH7751_PCIDCR3 0x1BC /* DMA3 Control Register */
212#define SH7751_PCIPAR 0x1C0 /* PIO Address Register */
213 #define SH7751_PCIPAR_CFGEN 0x80000000 /* Configuration Enable */
214 #define SH7751_PCIPAR_BUSNO 0x00FF0000 /* Config. Bus Number */
215 #define SH7751_PCIPAR_DEVNO 0x0000FF00 /* Config. Device Number */
216 #define SH7751_PCIPAR_REGAD 0x000000FC /* Register Address Number */
217#define SH7751_PCIMBR 0x1C4 /* Memory Base Address Register */
218 #define SH7751_PCIMBR_MASK 0xFF000000 /* Memory Space Mask */
219 #define SH7751_PCIMBR_LOCK 0x00000001 /* Lock Memory Space */
220#define SH7751_PCIIOBR 0x1C8 /* I/O Base Address Register */
221 #define SH7751_PCIIOBR_MASK 0xFFFC0000 /* IO Space Mask */
222 #define SH7751_PCIIOBR_LOCK 0x00000001 /* Lock IO Space */
223#define SH7751_PCIPINT 0x1CC /* Power Mgmnt Int. Register */
224 #define SH7751_PCIPINT_D3 0x00000002 /* D3 Pwr Mgmt. Interrupt */
225 #define SH7751_PCIPINT_D0 0x00000001 /* D0 Pwr Mgmt. Interrupt */
226#define SH7751_PCIPINTM 0x1D0 /* Power Mgmnt Mask Register */
227#define SH7751_PCICLKR 0x1D4 /* Clock Ctrl. Register */
228 #define SH7751_PCICLKR_PCSTP 0x00000002 /* PCI Clock Stop */
229 #define SH7751_PCICLKR_BCSTP 0x00000002 /* BCLK Clock Stop */
230/* For definitions of BCR, MCR see ... */
231#define SH7751_PCIBCR1 0x1E0 /* Memory BCR1 Register */
232#define SH7751_PCIBCR2 0x1E4 /* Memory BCR2 Register */
233#define SH7751_PCIWCR1 0x1E8 /* Wait Control 1 Register */
234#define SH7751_PCIWCR2 0x1EC /* Wait Control 2 Register */
235#define SH7751_PCIWCR3 0x1F0 /* Wait Control 3 Register */
236#define SH7751_PCIMCR 0x1F4 /* Memory Control Register */
237#define SH7751_PCIBCR3 0x1f8 /* Memory BCR3 Register */
238#define SH7751_PCIPCTR 0x200 /* Port Control Register */
239 #define SH7751_PCIPCTR_P2EN 0x000400000 /* Port 2 Enable */
240 #define SH7751_PCIPCTR_P1EN 0x000200000 /* Port 1 Enable */
241 #define SH7751_PCIPCTR_P0EN 0x000100000 /* Port 0 Enable */
242 #define SH7751_PCIPCTR_P2UP 0x000000020 /* Port2 Pull Up Enable */
243 #define SH7751_PCIPCTR_P2IO 0x000000010 /* Port2 Output Enable */
244 #define SH7751_PCIPCTR_P1UP 0x000000008 /* Port1 Pull Up Enable */
245 #define SH7751_PCIPCTR_P1IO 0x000000004 /* Port1 Output Enable */
246 #define SH7751_PCIPCTR_P0UP 0x000000002 /* Port0 Pull Up Enable */
247 #define SH7751_PCIPCTR_P0IO 0x000000001 /* Port0 Output Enable */
248#define SH7751_PCIPDTR 0x204 /* Port Data Register */
249 #define SH7751_PCIPDTR_PB5 0x000000020 /* Port 5 Enable */
250 #define SH7751_PCIPDTR_PB4 0x000000010 /* Port 4 Enable */
251 #define SH7751_PCIPDTR_PB3 0x000000008 /* Port 3 Enable */
252 #define SH7751_PCIPDTR_PB2 0x000000004 /* Port 2 Enable */
253 #define SH7751_PCIPDTR_PB1 0x000000002 /* Port 1 Enable */
254 #define SH7751_PCIPDTR_PB0 0x000000001 /* Port 0 Enable */
255#define SH7751_PCIPDR 0x220 /* Port IO Data Register */
256
257/* Memory Control Registers */
258#define SH7751_BCR1 0xFF800000 /* Memory BCR1 Register */
259#define SH7751_BCR2 0xFF800004 /* Memory BCR2 Register */
260#define SH7751_BCR3 0xFF800050 /* Memory BCR3 Register */
261#define SH7751_BCR4 0xFE0A00F0 /* Memory BCR4 Register */
262#define SH7751_WCR1 0xFF800008 /* Wait Control 1 Register */
263#define SH7751_WCR2 0xFF80000C /* Wait Control 2 Register */
264#define SH7751_WCR3 0xFF800010 /* Wait Control 3 Register */
265#define SH7751_MCR 0xFF800014 /* Memory Control Register */
266
267/* General Memory Config Addresses */
268#define SH7751_CS0_BASE_ADDR 0x0
269#define SH7751_MEM_REGION_SIZE 0x04000000
270#define SH7751_CS1_BASE_ADDR (SH7751_CS0_BASE_ADDR + SH7751_MEM_REGION_SIZE)
271#define SH7751_CS2_BASE_ADDR (SH7751_CS1_BASE_ADDR + SH7751_MEM_REGION_SIZE)
272#define SH7751_CS3_BASE_ADDR (SH7751_CS2_BASE_ADDR + SH7751_MEM_REGION_SIZE)
273#define SH7751_CS4_BASE_ADDR (SH7751_CS3_BASE_ADDR + SH7751_MEM_REGION_SIZE)
274#define SH7751_CS5_BASE_ADDR (SH7751_CS4_BASE_ADDR + SH7751_MEM_REGION_SIZE)
275#define SH7751_CS6_BASE_ADDR (SH7751_CS5_BASE_ADDR + SH7751_MEM_REGION_SIZE)
276
277/* General PCI values */
278#define SH7751_PCI_HOST_BRIDGE 0x6
279
280/* Flags */
281#define SH7751_PCIC_NO_RESET 0x0001
282
283/* External functions defined per platform i.e. Big Sur, SE... (these could be routed
284 * through the machine vectors... */
285extern int pcibios_init_platform(void);
286extern int pcibios_map_platform_irq(u8 slot, u8 pin);
287
288struct sh7751_pci_address_space {
289 unsigned long base;
290 unsigned long size;
291};
292
293struct sh7751_pci_address_map {
294 struct sh7751_pci_address_space window0;
295 struct sh7751_pci_address_space window1;
296 unsigned long flags;
297};
298
299/* arch/sh/drivers/pci/pci-sh7751.c */
300extern int sh7751_pcic_init(struct sh7751_pci_address_map *map);
301
302#endif /* _PCI_SH7751_H_ */
303
diff --git a/arch/sh/drivers/pci/pci-st40.c b/arch/sh/drivers/pci/pci-st40.c
new file mode 100644
index 000000000000..cb6752131156
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-st40.c
@@ -0,0 +1,509 @@
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 * Support functions for the ST40 PCI hardware.
8 */
9
10#include <linux/config.h>
11#include <linux/kernel.h>
12#include <linux/smp.h>
13#include <linux/smp_lock.h>
14#include <linux/init.h>
15#include <linux/errno.h>
16#include <linux/pci.h>
17#include <linux/delay.h>
18#include <linux/types.h>
19#include <asm/pci.h>
20#include <linux/irq.h>
21#include <linux/interrupt.h> /* irqreturn_t */
22
23#include "pci-st40.h"
24
25/* This is in P2 of course */
26#define ST40PCI_BASE_ADDRESS (0xb0000000)
27#define ST40PCI_MEM_ADDRESS (ST40PCI_BASE_ADDRESS+0x0)
28#define ST40PCI_IO_ADDRESS (ST40PCI_BASE_ADDRESS+0x06000000)
29#define ST40PCI_REG_ADDRESS (ST40PCI_BASE_ADDRESS+0x07000000)
30
31#define ST40PCI_REG(x) (ST40PCI_REG_ADDRESS+(ST40PCI_##x))
32#define ST40PCI_REG_INDEXED(reg, index) \
33 (ST40PCI_REG(reg##0) + \
34 ((ST40PCI_REG(reg##1) - ST40PCI_REG(reg##0))*index))
35
36#define ST40PCI_WRITE(reg,val) writel((val),ST40PCI_REG(reg))
37#define ST40PCI_WRITE_SHORT(reg,val) writew((val),ST40PCI_REG(reg))
38#define ST40PCI_WRITE_BYTE(reg,val) writeb((val),ST40PCI_REG(reg))
39#define ST40PCI_WRITE_INDEXED(reg, index, val) \
40 writel((val), ST40PCI_REG_INDEXED(reg, index));
41
42#define ST40PCI_READ(reg) readl(ST40PCI_REG(reg))
43#define ST40PCI_READ_SHORT(reg) readw(ST40PCI_REG(reg))
44#define ST40PCI_READ_BYTE(reg) readb(ST40PCI_REG(reg))
45
46#define ST40PCI_SERR_IRQ 64
47#define ST40PCI_ERR_IRQ 65
48
49
50/* Macros to extract PLL params */
51#define PLL_MDIV(reg) ( ((unsigned)reg) & 0xff )
52#define PLL_NDIV(reg) ( (((unsigned)reg)>>8) & 0xff )
53#define PLL_PDIV(reg) ( (((unsigned)reg)>>16) & 0x3 )
54#define PLL_SETUP(reg) ( (((unsigned)reg)>>19) & 0x1ff )
55
56/* Build up the appropriate settings */
57#define PLL_SET(mdiv,ndiv,pdiv,setup) \
58( ((mdiv)&0xff) | (((ndiv)&0xff)<<8) | (((pdiv)&3)<<16)| (((setup)&0x1ff)<<19))
59
60#define PLLPCICR (0xbb040000+0x10)
61
62#define PLLPCICR_POWERON (1<<28)
63#define PLLPCICR_OUT_EN (1<<29)
64#define PLLPCICR_LOCKSELECT (1<<30)
65#define PLLPCICR_LOCK (1<<31)
66
67
68#define PLL_25MHZ 0x793c8512
69#define PLL_33MHZ PLL_SET(18,88,3,295)
70
71static void pci_set_rbar_region(unsigned int region, unsigned long localAddr,
72 unsigned long pciOffset, unsigned long regionSize);
73
74/*
75 * The pcibios_map_platform_irq function is defined in the appropriate
76 * board specific code and referenced here
77 */
78extern int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin);
79
80static __init void SetPCIPLL(void)
81{
82 {
83 /* Lets play with the PLL values */
84 unsigned long pll1cr1;
85 unsigned long mdiv, ndiv, pdiv;
86 unsigned long muxcr;
87 unsigned int muxcr_ratios[4] = { 8, 16, 21, 1 };
88 unsigned int freq;
89
90#define CLKGENA 0xbb040000
91#define CLKGENA_PLL2_MUXCR CLKGENA + 0x48
92 pll1cr1 = ctrl_inl(PLLPCICR);
93 printk("PLL1CR1 %08lx\n", pll1cr1);
94 mdiv = PLL_MDIV(pll1cr1);
95 ndiv = PLL_NDIV(pll1cr1);
96 pdiv = PLL_PDIV(pll1cr1);
97 printk("mdiv %02lx ndiv %02lx pdiv %02lx\n", mdiv, ndiv, pdiv);
98 freq = ((2*27*ndiv)/mdiv) / (1 << pdiv);
99 printk("PLL freq %dMHz\n", freq);
100 muxcr = ctrl_inl(CLKGENA_PLL2_MUXCR);
101 printk("PCI freq %dMhz\n", freq / muxcr_ratios[muxcr & 3]);
102 }
103}
104
105
106struct pci_err {
107 unsigned mask;
108 const char *error_string;
109};
110
111static struct pci_err int_error[]={
112 { INT_MNLTDIM,"MNLTDIM: Master non-lock transfer"},
113 { INT_TTADI, "TTADI: Illegal byte enable in I/O transfer"},
114 { INT_TMTO, "TMTO: Target memory read/write timeout"},
115 { INT_MDEI, "MDEI: Master function disable error"},
116 { INT_APEDI, "APEDI: Address parity error"},
117 { INT_SDI, "SDI: SERR detected"},
118 { INT_DPEITW, "DPEITW: Data parity error target write"},
119 { INT_PEDITR, "PEDITR: PERR detected"},
120 { INT_TADIM, "TADIM: Target abort detected"},
121 { INT_MADIM, "MADIM: Master abort detected"},
122 { INT_MWPDI, "MWPDI: PERR from target at data write"},
123 { INT_MRDPEI, "MRDPEI: Master read data parity error"}
124};
125#define NUM_PCI_INT_ERRS (sizeof(int_error)/sizeof(struct pci_err))
126
127static struct pci_err aint_error[]={
128 { AINT_MBI, "MBI: Master broken"},
129 { AINT_TBTOI, "TBTOI: Target bus timeout"},
130 { AINT_MBTOI, "MBTOI: Master bus timeout"},
131 { AINT_TAI, "TAI: Target abort"},
132 { AINT_MAI, "MAI: Master abort"},
133 { AINT_RDPEI, "RDPEI: Read data parity"},
134 { AINT_WDPE, "WDPE: Write data parity"}
135};
136
137#define NUM_PCI_AINT_ERRS (sizeof(aint_error)/sizeof(struct pci_err))
138
139static void print_pci_errors(unsigned reg,struct pci_err *error,int num_errors)
140{
141 int i;
142
143 for(i=0;i<num_errors;i++) {
144 if(reg & error[i].mask) {
145 printk("%s\n",error[i].error_string);
146 }
147 }
148
149}
150
151
152static char * pci_commands[16]={
153 "Int Ack",
154 "Special Cycle",
155 "I/O Read",
156 "I/O Write",
157 "Reserved",
158 "Reserved",
159 "Memory Read",
160 "Memory Write",
161 "Reserved",
162 "Reserved",
163 "Configuration Read",
164 "Configuration Write",
165 "Memory Read Multiple",
166 "Dual Address Cycle",
167 "Memory Read Line",
168 "Memory Write-and-Invalidate"
169};
170
171static irqreturn_t st40_pci_irq(int irq, void *dev_instance, struct pt_regs *regs)
172{
173 unsigned pci_int, pci_air, pci_cir, pci_aint;
174 static int count=0;
175
176
177 pci_int = ST40PCI_READ(INT);pci_aint = ST40PCI_READ(AINT);
178 pci_cir = ST40PCI_READ(CIR);pci_air = ST40PCI_READ(AIR);
179
180 /* Reset state to stop multiple interrupts */
181 ST40PCI_WRITE(INT, ~0); ST40PCI_WRITE(AINT, ~0);
182
183
184 if(++count>1) return IRQ_HANDLED;
185
186 printk("** PCI ERROR **\n");
187
188 if(pci_int) {
189 printk("** INT register status\n");
190 print_pci_errors(pci_int,int_error,NUM_PCI_INT_ERRS);
191 }
192
193 if(pci_aint) {
194 printk("** AINT register status\n");
195 print_pci_errors(pci_aint,aint_error,NUM_PCI_AINT_ERRS);
196 }
197
198 printk("** Address and command info\n");
199
200 printk("** Command %s : Address 0x%x\n",
201 pci_commands[pci_cir&0xf],pci_air);
202
203 if(pci_cir&CIR_PIOTEM) {
204 printk("CIR_PIOTEM:PIO transfer error for master\n");
205 }
206 if(pci_cir&CIR_RWTET) {
207 printk("CIR_RWTET:Read/Write transfer error for target\n");
208 }
209
210 return IRQ_HANDLED;
211}
212
213
214/* Rounds a number UP to the nearest power of two. Used for
215 * sizing the PCI window.
216 */
217static u32 r2p2(u32 num)
218{
219 int i = 31;
220 u32 tmp = num;
221
222 if (num == 0)
223 return 0;
224
225 do {
226 if (tmp & (1 << 31))
227 break;
228 i--;
229 tmp <<= 1;
230 } while (i >= 0);
231
232 tmp = 1 << i;
233 /* If the original number isn't a power of 2, round it up */
234 if (tmp != num)
235 tmp <<= 1;
236
237 return tmp;
238}
239
240static void __init pci_fixup_ide_bases(struct pci_dev *d)
241{
242 int i;
243
244 /*
245 * PCI IDE controllers use non-standard I/O port decoding, respect it.
246 */
247 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
248 return;
249 printk("PCI: IDE base address fixup for %s\n", pci_name(d));
250 for(i=0; i<4; i++) {
251 struct resource *r = &d->resource[i];
252 if ((r->start & ~0x80) == 0x374) {
253 r->start |= 2;
254 r->end = r->start;
255 }
256 }
257}
258DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
259
260int __init st40pci_init(unsigned memStart, unsigned memSize)
261{
262 u32 lsr0;
263
264 SetPCIPLL();
265
266 /* Initialises the ST40 pci subsystem, performing a reset, then programming
267 * up the address space decoders appropriately
268 */
269
270 /* Should reset core here as well methink */
271
272 ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_SOFT_RESET);
273
274 /* Loop while core resets */
275 while (ST40PCI_READ(CR) & CR_SOFT_RESET);
276
277 /* Switch off interrupts */
278 ST40PCI_WRITE(INTM, 0);
279 ST40PCI_WRITE(AINT, 0);
280
281 /* Now, lets reset all the cards on the bus with extreme prejudice */
282 ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_RSTCTL);
283 udelay(250);
284
285 /* Set bus active, take it out of reset */
286 ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_BMAM | CR_CFINT | CR_PFCS | CR_PFE);
287
288 /* The PCI spec says that no access must be made to the bus until 1 second
289 * after reset. This seem ludicrously long, but some delay is needed here
290 */
291 mdelay(1000);
292
293 /* Switch off interrupts */
294 ST40PCI_WRITE(INTM, 0);
295 ST40PCI_WRITE(AINT, 0);
296
297 /* Allow it to be a master */
298
299 ST40PCI_WRITE_SHORT(CSR_CMD,
300 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
301 PCI_COMMAND_IO);
302
303 /* Accesse to the 0xb0000000 -> 0xb6000000 area will go through to 0x10000000 -> 0x16000000
304 * on the PCI bus. This allows a nice 1-1 bus to phys mapping.
305 */
306
307
308 ST40PCI_WRITE(MBR, 0x10000000);
309 /* Always set the max size 128M (actually, it is only 96MB wide) */
310 ST40PCI_WRITE(MBMR, 0x07ff0000);
311
312 /* I/O addresses are mapped at 0xb6000000 -> 0xb7000000. These are changed to 0, to
313 * allow cards that have legacy io such as vga to function correctly. This gives a
314 * maximum of 64K of io/space as only the bottom 16 bits of the address are copied
315 * over to the bus when the transaction is made. 64K of io space is more than enough
316 */
317 ST40PCI_WRITE(IOBR, 0x0);
318 /* Set up the 64K window */
319 ST40PCI_WRITE(IOBMR, 0x0);
320
321 /* Now we set up the mbars so the PCI bus can see the local memory */
322 /* Expose a 256M window starting at PCI address 0... */
323 ST40PCI_WRITE(CSR_MBAR0, 0);
324 ST40PCI_WRITE(LSR0, 0x0fff0001);
325
326 /* ... and set up the initial incomming window to expose all of RAM */
327 pci_set_rbar_region(7, memStart, memStart, memSize);
328
329 /* Maximise timeout values */
330 ST40PCI_WRITE_BYTE(CSR_TRDY, 0xff);
331 ST40PCI_WRITE_BYTE(CSR_RETRY, 0xff);
332 ST40PCI_WRITE_BYTE(CSR_MIT, 0xff);
333
334 ST40PCI_WRITE_BYTE(PERF,PERF_MASTER_WRITE_POSTING);
335
336 return 1;
337}
338
339char * __init pcibios_setup(char *str)
340{
341 return str;
342}
343
344
345#define SET_CONFIG_BITS(bus,devfn,where)\
346 (((bus) << 16) | ((devfn) << 8) | ((where) & ~3) | (bus!=0))
347
348#define CONFIG_CMD(bus, devfn, where) SET_CONFIG_BITS(bus->number,devfn,where)
349
350
351static int CheckForMasterAbort(void)
352{
353 if (ST40PCI_READ(INT) & INT_MADIM) {
354 /* Should we clear config space version as well ??? */
355 ST40PCI_WRITE(INT, INT_MADIM);
356 ST40PCI_WRITE_SHORT(CSR_STATUS, 0);
357 return 1;
358 }
359
360 return 0;
361}
362
363/* Write to config register */
364static int st40pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val)
365{
366 ST40PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
367 switch (size) {
368 case 1:
369 *val = (u8)ST40PCI_READ_BYTE(PDR + (where & 3));
370 break;
371 case 2:
372 *val = (u16)ST40PCI_READ_SHORT(PDR + (where & 2));
373 break;
374 case 4:
375 *val = ST40PCI_READ(PDR);
376 break;
377 }
378
379 if (CheckForMasterAbort()){
380 switch (size) {
381 case 1:
382 *val = (u8)0xff;
383 break;
384 case 2:
385 *val = (u16)0xffff;
386 break;
387 case 4:
388 *val = 0xffffffff;
389 break;
390 }
391 }
392
393 return PCIBIOS_SUCCESSFUL;
394}
395
396static int st40pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
397{
398 ST40PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
399
400 switch (size) {
401 case 1:
402 ST40PCI_WRITE_BYTE(PDR + (where & 3), (u8)val);
403 break;
404 case 2:
405 ST40PCI_WRITE_SHORT(PDR + (where & 2), (u16)val);
406 break;
407 case 4:
408 ST40PCI_WRITE(PDR, val);
409 break;
410 }
411
412 CheckForMasterAbort();
413
414 return PCIBIOS_SUCCESSFUL;
415}
416
417struct pci_ops st40pci_config_ops = {
418 .read = st40pci_read,
419 .write = st40pci_write,
420};
421
422
423/* Everything hangs off this */
424static struct pci_bus *pci_root_bus;
425
426
427static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
428{
429 return PCI_SLOT(dev->devfn);
430}
431
432
433static int __init pcibios_init(void)
434{
435 extern unsigned long memory_start, memory_end;
436
437 printk(KERN_ALERT "pci-st40.c: pcibios_init\n");
438
439 if (sh_mv.mv_init_pci != NULL) {
440 sh_mv.mv_init_pci();
441 }
442
443 /* The pci subsytem needs to know where memory is and how much
444 * of it there is. I've simply made these globals. A better mechanism
445 * is probably needed.
446 */
447 st40pci_init(PHYSADDR(memory_start),
448 PHYSADDR(memory_end) - PHYSADDR(memory_start));
449
450 if (request_irq(ST40PCI_ERR_IRQ, st40_pci_irq,
451 SA_INTERRUPT, "st40pci", NULL)) {
452 printk(KERN_ERR "st40pci: Cannot hook interrupt\n");
453 return -EIO;
454 }
455
456 /* Enable the PCI interrupts on the device */
457 ST40PCI_WRITE(INTM, ~0);
458 ST40PCI_WRITE(AINT, ~0);
459
460 /* Map the io address apprioately */
461#ifdef CONFIG_HD64465
462 hd64465_port_map(PCIBIOS_MIN_IO, (64 * 1024) - PCIBIOS_MIN_IO + 1,
463 ST40_IO_ADDR + PCIBIOS_MIN_IO, 0);
464#endif
465
466 /* ok, do the scan man */
467 pci_root_bus = pci_scan_bus(0, &st40pci_config_ops, NULL);
468 pci_assign_unassigned_resources();
469 pci_fixup_irqs(no_swizzle, pcibios_map_platform_irq);
470
471 return 0;
472}
473
474subsys_initcall(pcibios_init);
475
476void __init pcibios_fixup_bus(struct pci_bus *bus)
477{
478}
479
480/*
481 * Publish a region of local address space over the PCI bus
482 * to other devices.
483 */
484static void pci_set_rbar_region(unsigned int region, unsigned long localAddr,
485 unsigned long pciOffset, unsigned long regionSize)
486{
487 unsigned long mask;
488
489 if (region > 7)
490 return;
491
492 if (regionSize > (512 * 1024 * 1024))
493 return;
494
495 mask = r2p2(regionSize) - 0x10000;
496
497 /* Diable the region (in case currently in use, should never happen) */
498 ST40PCI_WRITE_INDEXED(RSR, region, 0);
499
500 /* Start of local address space to publish */
501 ST40PCI_WRITE_INDEXED(RLAR, region, PHYSADDR(localAddr) );
502
503 /* Start of region in PCI address space as an offset from MBAR0 */
504 ST40PCI_WRITE_INDEXED(RBAR, region, pciOffset);
505
506 /* Size of region */
507 ST40PCI_WRITE_INDEXED(RSR, region, mask | 1);
508}
509
diff --git a/arch/sh/drivers/pci/pci-st40.h b/arch/sh/drivers/pci/pci-st40.h
new file mode 100644
index 000000000000..d729e0c2d5fe
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-st40.h
@@ -0,0 +1,136 @@
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 * Defintions for the ST40 PCI hardware.
8 */
9
10#ifndef __PCI_ST40_H__
11#define __PCI_ST40_H__
12
13#define ST40PCI_VCR_STATUS 0x00
14
15#define ST40PCI_VCR_VERSION 0x08
16
17#define ST40PCI_CR 0x10
18
19#define CR_SOFT_RESET (1<<12)
20#define CR_PFCS (1<<11)
21#define CR_PFE (1<<9)
22#define CR_BMAM (1<<6)
23#define CR_HOST (1<<5)
24#define CR_CLKEN (1<<4)
25#define CR_SOCS (1<<3)
26#define CR_IOCS (1<<2)
27#define CR_RSTCTL (1<<1)
28#define CR_CFINT (1<<0)
29#define CR_LOCK_MASK 0x5a000000
30
31
32#define ST40PCI_LSR0 0X14
33#define ST40PCI_LAR0 0x1c
34
35#define ST40PCI_INT 0x24
36#define INT_MNLTDIM (1<<15)
37#define INT_TTADI (1<<14)
38#define INT_TMTO (1<<9)
39#define INT_MDEI (1<<8)
40#define INT_APEDI (1<<7)
41#define INT_SDI (1<<6)
42#define INT_DPEITW (1<<5)
43#define INT_PEDITR (1<<4)
44#define INT_TADIM (1<<3)
45#define INT_MADIM (1<<2)
46#define INT_MWPDI (1<<1)
47#define INT_MRDPEI (1<<0)
48
49
50#define ST40PCI_INTM 0x28
51#define ST40PCI_AIR 0x2c
52
53#define ST40PCI_CIR 0x30
54#define CIR_PIOTEM (1<<31)
55#define CIR_RWTET (1<<26)
56
57#define ST40PCI_AINT 0x40
58#define AINT_MBI (1<<13)
59#define AINT_TBTOI (1<<12)
60#define AINT_MBTOI (1<<11)
61#define AINT_TAI (1<<3)
62#define AINT_MAI (1<<2)
63#define AINT_RDPEI (1<<1)
64#define AINT_WDPE (1<<0)
65
66#define ST40PCI_AINTM 0x44
67#define ST40PCI_BMIR 0x48
68#define ST40PCI_PAR 0x4c
69#define ST40PCI_MBR 0x50
70#define ST40PCI_IOBR 0x54
71#define ST40PCI_PINT 0x58
72#define ST40PCI_PINTM 0x5c
73#define ST40PCI_MBMR 0x70
74#define ST40PCI_IOBMR 0x74
75#define ST40PCI_PDR 0x78
76
77/* H8 specific registers start here */
78#define ST40PCI_WCBAR 0x7c
79#define ST40PCI_LOCCFG_UNLOCK 0x34
80
81#define ST40PCI_RBAR0 0x100
82#define ST40PCI_RSR0 0x104
83#define ST40PCI_RLAR0 0x108
84
85#define ST40PCI_RBAR1 0x110
86#define ST40PCI_RSR1 0x114
87#define ST40PCI_RLAR1 0x118
88
89
90#define ST40PCI_RBAR2 0x120
91#define ST40PCI_RSR2 0x124
92#define ST40PCI_RLAR2 0x128
93
94#define ST40PCI_RBAR3 0x130
95#define ST40PCI_RSR3 0x134
96#define ST40PCI_RLAR3 0x138
97
98#define ST40PCI_RBAR4 0x140
99#define ST40PCI_RSR4 0x144
100#define ST40PCI_RLAR4 0x148
101
102#define ST40PCI_RBAR5 0x150
103#define ST40PCI_RSR5 0x154
104#define ST40PCI_RLAR5 0x158
105
106#define ST40PCI_RBAR6 0x160
107#define ST40PCI_RSR6 0x164
108#define ST40PCI_RLAR6 0x168
109
110#define ST40PCI_RBAR7 0x170
111#define ST40PCI_RSR7 0x174
112#define ST40PCI_RLAR7 0x178
113
114
115#define ST40PCI_RBAR(n) (0x100+(0x10*(n)))
116#define ST40PCI_RSR(n) (0x104+(0x10*(n)))
117#define ST40PCI_RLAR(n) (0x108+(0x10*(n)))
118
119#define ST40PCI_PERF 0x80
120#define PERF_MASTER_WRITE_POSTING (1<<4)
121/* H8 specific registers end here */
122
123
124/* These are configs space registers */
125#define ST40PCI_CSR_VID 0x10000
126#define ST40PCI_CSR_DID 0x10002
127#define ST40PCI_CSR_CMD 0x10004
128#define ST40PCI_CSR_STATUS 0x10006
129#define ST40PCI_CSR_MBAR0 0x10010
130#define ST40PCI_CSR_TRDY 0x10040
131#define ST40PCI_CSR_RETRY 0x10041
132#define ST40PCI_CSR_MIT 0x1000d
133
134#define ST40_IO_ADDR 0xb6000000
135
136#endif /* __PCI_ST40_H__ */
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
new file mode 100644
index 000000000000..c1669905abe4
--- /dev/null
+++ b/arch/sh/drivers/pci/pci.c
@@ -0,0 +1,155 @@
1/* arch/sh/kernel/pci.c
2 * $Id: pci.c,v 1.1 2003/08/24 19:15:45 lethal Exp $
3 *
4 * Copyright (c) 2002 M. R. Brown <mrbrown@linux-sh.org>
5 *
6 *
7 * These functions are collected here to reduce duplication of common
8 * code amongst the many platform-specific PCI support code files.
9 *
10 * These routines require the following board-specific routines:
11 * void pcibios_fixup_irqs();
12 *
13 * See include/asm-sh/pci.h for more information.
14 */
15
16#include <linux/kernel.h>
17#include <linux/pci.h>
18#include <linux/init.h>
19
20static int __init pcibios_init(void)
21{
22 struct pci_channel *p;
23 struct pci_bus *bus;
24 int busno;
25
26#ifdef CONFIG_PCI_AUTO
27 /* assign resources */
28 busno = 0;
29 for (p = board_pci_channels; p->pci_ops != NULL; p++) {
30 busno = pciauto_assign_resources(busno, p) + 1;
31 }
32#endif
33
34 /* scan the buses */
35 busno = 0;
36 for (p= board_pci_channels; p->pci_ops != NULL; p++) {
37 bus = pci_scan_bus(busno, p->pci_ops, p);
38 busno = bus->subordinate+1;
39 }
40
41 /* board-specific fixups */
42 pcibios_fixup_irqs();
43
44 return 0;
45}
46
47subsys_initcall(pcibios_init);
48
49void
50pcibios_update_resource(struct pci_dev *dev, struct resource *root,
51 struct resource *res, int resource)
52{
53 u32 new, check;
54 int reg;
55
56 new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
57 if (resource < 6) {
58 reg = PCI_BASE_ADDRESS_0 + 4*resource;
59 } else if (resource == PCI_ROM_RESOURCE) {
60 res->flags |= IORESOURCE_ROM_ENABLE;
61 new |= PCI_ROM_ADDRESS_ENABLE;
62 reg = dev->rom_base_reg;
63 } else {
64 /* Somebody might have asked allocation of a non-standard resource */
65 return;
66 }
67
68 pci_write_config_dword(dev, reg, new);
69 pci_read_config_dword(dev, reg, &check);
70 if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
71 printk(KERN_ERR "PCI: Error while updating region "
72 "%s/%d (%08x != %08x)\n", pci_name(dev), resource,
73 new, check);
74 }
75}
76
77void pcibios_align_resource(void *data, struct resource *res,
78 unsigned long size, unsigned long align)
79 __attribute__ ((weak));
80
81/*
82 * We need to avoid collisions with `mirrored' VGA ports
83 * and other strange ISA hardware, so we always want the
84 * addresses to be allocated in the 0x000-0x0ff region
85 * modulo 0x400.
86 */
87void pcibios_align_resource(void *data, struct resource *res,
88 unsigned long size, unsigned long align)
89{
90 if (res->flags & IORESOURCE_IO) {
91 unsigned long start = res->start;
92
93 if (start & 0x300) {
94 start = (start + 0x3ff) & ~0x3ff;
95 res->start = start;
96 }
97 }
98}
99
100int pcibios_enable_device(struct pci_dev *dev, int mask)
101{
102 u16 cmd, old_cmd;
103 int idx;
104 struct resource *r;
105
106 pci_read_config_word(dev, PCI_COMMAND, &cmd);
107 old_cmd = cmd;
108 for(idx=0; idx<6; idx++) {
109 if (!(mask & (1 << idx)))
110 continue;
111 r = &dev->resource[idx];
112 if (!r->start && r->end) {
113 printk(KERN_ERR "PCI: Device %s not available because "
114 "of resource collisions\n", pci_name(dev));
115 return -EINVAL;
116 }
117 if (r->flags & IORESOURCE_IO)
118 cmd |= PCI_COMMAND_IO;
119 if (r->flags & IORESOURCE_MEM)
120 cmd |= PCI_COMMAND_MEMORY;
121 }
122 if (dev->resource[PCI_ROM_RESOURCE].start)
123 cmd |= PCI_COMMAND_MEMORY;
124 if (cmd != old_cmd) {
125 printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n",
126 pci_name(dev), old_cmd, cmd);
127 pci_write_config_word(dev, PCI_COMMAND, cmd);
128 }
129 return 0;
130}
131
132/*
133 * If we set up a device for bus mastering, we need to check and set
134 * the latency timer as it may not be properly set.
135 */
136unsigned int pcibios_max_latency = 255;
137
138void pcibios_set_master(struct pci_dev *dev)
139{
140 u8 lat;
141 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
142 if (lat < 16)
143 lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
144 else if (lat > pcibios_max_latency)
145 lat = pcibios_max_latency;
146 else
147 return;
148 printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat);
149 pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
150}
151
152void __init pcibios_update_irq(struct pci_dev *dev, int irq)
153{
154 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
155}