diff options
Diffstat (limited to 'arch/sh/drivers')
24 files changed, 1124 insertions, 635 deletions
diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig index 0f15216cd39d..defc13c37d48 100644 --- a/arch/sh/drivers/dma/Kconfig +++ b/arch/sh/drivers/dma/Kconfig | |||
@@ -11,6 +11,8 @@ config SH_DMA | |||
11 | config NR_ONCHIP_DMA_CHANNELS | 11 | config NR_ONCHIP_DMA_CHANNELS |
12 | depends on SH_DMA | 12 | depends on SH_DMA |
13 | int "Number of on-chip DMAC channels" | 13 | int "Number of on-chip DMAC channels" |
14 | default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R | ||
15 | default "12" if CPU_SUBTYPE_SH7780 | ||
14 | default "4" | 16 | default "4" |
15 | help | 17 | help |
16 | This allows you to specify the number of channels that the on-chip | 18 | This allows you to specify the number of channels that the on-chip |
@@ -52,4 +54,3 @@ config DMA_PAGE_OPS_CHANNEL | |||
52 | are dual-address capable. | 54 | are dual-address capable. |
53 | 55 | ||
54 | endmenu | 56 | endmenu |
55 | |||
diff --git a/arch/sh/drivers/dma/dma-g2.c b/arch/sh/drivers/dma/dma-g2.c index 0f866f8789f0..9cb070924180 100644 --- a/arch/sh/drivers/dma/dma-g2.c +++ b/arch/sh/drivers/dma/dma-g2.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * G2 bus DMA support | 4 | * G2 bus DMA support |
5 | * | 5 | * |
6 | * Copyright (C) 2003, 2004 Paul Mundt | 6 | * Copyright (C) 2003 - 2006 Paul Mundt |
7 | * | 7 | * |
8 | * This file is subject to the terms and conditions of the GNU General Public | 8 | * This file is subject to the terms and conditions of the GNU General Public |
9 | * License. See the file "COPYING" in the main directory of this archive | 9 | * License. See the file "COPYING" in the main directory of this archive |
@@ -13,7 +13,7 @@ | |||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | 16 | #include <asm/cacheflush.h> | |
17 | #include <asm/mach/sysasic.h> | 17 | #include <asm/mach/sysasic.h> |
18 | #include <asm/mach/dma.h> | 18 | #include <asm/mach/dma.h> |
19 | #include <asm/dma.h> | 19 | #include <asm/dma.h> |
@@ -47,17 +47,31 @@ struct g2_dma_info { | |||
47 | 47 | ||
48 | static volatile struct g2_dma_info *g2_dma = (volatile struct g2_dma_info *)0xa05f7800; | 48 | static volatile struct g2_dma_info *g2_dma = (volatile struct g2_dma_info *)0xa05f7800; |
49 | 49 | ||
50 | #define g2_bytes_remaining(i) \ | ||
51 | ((g2_dma->channel[i].size - \ | ||
52 | g2_dma->status[i].size) & 0x0fffffff) | ||
53 | |||
50 | static irqreturn_t g2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 54 | static irqreturn_t g2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
51 | { | 55 | { |
52 | /* FIXME: Do some meaningful completion work here.. */ | 56 | int i; |
53 | return IRQ_HANDLED; | ||
54 | } | ||
55 | 57 | ||
56 | static struct irqaction g2_dma_irq = { | 58 | for (i = 0; i < G2_NR_DMA_CHANNELS; i++) { |
57 | .name = "g2 DMA handler", | 59 | if (g2_dma->status[i].status & 0x20000000) { |
58 | .handler = g2_dma_interrupt, | 60 | unsigned int bytes = g2_bytes_remaining(i); |
59 | .flags = IRQF_DISABLED, | 61 | |
60 | }; | 62 | if (likely(bytes == 0)) { |
63 | struct dma_info *info = dev_id; | ||
64 | struct dma_channel *chan = info->channels + i; | ||
65 | |||
66 | wake_up(&chan->wait_queue); | ||
67 | |||
68 | return IRQ_HANDLED; | ||
69 | } | ||
70 | } | ||
71 | } | ||
72 | |||
73 | return IRQ_NONE; | ||
74 | } | ||
61 | 75 | ||
62 | static int g2_enable_dma(struct dma_channel *chan) | 76 | static int g2_enable_dma(struct dma_channel *chan) |
63 | { | 77 | { |
@@ -135,8 +149,14 @@ static int g2_xfer_dma(struct dma_channel *chan) | |||
135 | return 0; | 149 | return 0; |
136 | } | 150 | } |
137 | 151 | ||
152 | static int g2_get_residue(struct dma_channel *chan) | ||
153 | { | ||
154 | return g2_bytes_remaining(chan->chan); | ||
155 | } | ||
156 | |||
138 | static struct dma_ops g2_dma_ops = { | 157 | static struct dma_ops g2_dma_ops = { |
139 | .xfer = g2_xfer_dma, | 158 | .xfer = g2_xfer_dma, |
159 | .get_residue = g2_get_residue, | ||
140 | }; | 160 | }; |
141 | 161 | ||
142 | static struct dma_info g2_dma_info = { | 162 | static struct dma_info g2_dma_info = { |
@@ -148,13 +168,22 @@ static struct dma_info g2_dma_info = { | |||
148 | 168 | ||
149 | static int __init g2_dma_init(void) | 169 | static int __init g2_dma_init(void) |
150 | { | 170 | { |
151 | setup_irq(HW_EVENT_G2_DMA, &g2_dma_irq); | 171 | int ret; |
172 | |||
173 | ret = request_irq(HW_EVENT_G2_DMA, g2_dma_interrupt, IRQF_DISABLED, | ||
174 | "g2 DMA handler", &g2_dma_info); | ||
175 | if (unlikely(ret)) | ||
176 | return -EINVAL; | ||
152 | 177 | ||
153 | /* Magic */ | 178 | /* Magic */ |
154 | g2_dma->wait_state = 27; | 179 | g2_dma->wait_state = 27; |
155 | g2_dma->magic = 0x4659404f; | 180 | g2_dma->magic = 0x4659404f; |
156 | 181 | ||
157 | return register_dmac(&g2_dma_info); | 182 | ret = register_dmac(&g2_dma_info); |
183 | if (unlikely(ret != 0)) | ||
184 | free_irq(HW_EVENT_G2_DMA, 0); | ||
185 | |||
186 | return ret; | ||
158 | } | 187 | } |
159 | 188 | ||
160 | static void __exit g2_dma_exit(void) | 189 | static void __exit g2_dma_exit(void) |
@@ -169,4 +198,3 @@ module_exit(g2_dma_exit); | |||
169 | MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); | 198 | MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); |
170 | MODULE_DESCRIPTION("G2 bus DMA driver"); | 199 | MODULE_DESCRIPTION("G2 bus DMA driver"); |
171 | MODULE_LICENSE("GPL"); | 200 | MODULE_LICENSE("GPL"); |
172 | |||
diff --git a/arch/sh/drivers/dma/dma-pvr2.c b/arch/sh/drivers/dma/dma-pvr2.c index 30a580aa7cbd..3b0b0f60bb3c 100644 --- a/arch/sh/drivers/dma/dma-pvr2.c +++ b/arch/sh/drivers/dma/dma-pvr2.c | |||
@@ -18,8 +18,8 @@ | |||
18 | #include <asm/dma.h> | 18 | #include <asm/dma.h> |
19 | #include <asm/io.h> | 19 | #include <asm/io.h> |
20 | 20 | ||
21 | static unsigned int xfer_complete = 0; | 21 | static unsigned int xfer_complete; |
22 | static int count = 0; | 22 | static int count; |
23 | 23 | ||
24 | static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 24 | static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
25 | { | 25 | { |
@@ -107,4 +107,3 @@ module_exit(pvr2_dma_exit); | |||
107 | MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); | 107 | MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); |
108 | MODULE_DESCRIPTION("NEC PowerVR 2 DMA driver"); | 108 | MODULE_DESCRIPTION("NEC PowerVR 2 DMA driver"); |
109 | MODULE_LICENSE("GPL"); | 109 | MODULE_LICENSE("GPL"); |
110 | |||
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c index e028a2d2a4ea..cbbe8bce3d67 100644 --- a/arch/sh/drivers/dma/dma-sh.c +++ b/arch/sh/drivers/dma/dma-sh.c | |||
@@ -11,14 +11,10 @@ | |||
11 | * License. See the file "COPYING" in the main directory of this archive | 11 | * License. See the file "COPYING" in the main directory of this archive |
12 | * for more details. | 12 | * for more details. |
13 | */ | 13 | */ |
14 | |||
15 | #include <linux/init.h> | 14 | #include <linux/init.h> |
16 | #include <linux/irq.h> | ||
17 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
18 | #include <linux/module.h> | 16 | #include <linux/module.h> |
19 | #include <asm/dreamcast/dma.h> | 17 | #include <asm/dreamcast/dma.h> |
20 | #include <asm/signal.h> | ||
21 | #include <asm/irq.h> | ||
22 | #include <asm/dma.h> | 18 | #include <asm/dma.h> |
23 | #include <asm/io.h> | 19 | #include <asm/io.h> |
24 | #include "dma-sh.h" | 20 | #include "dma-sh.h" |
@@ -84,18 +80,23 @@ static irqreturn_t dma_tei(int irq, void *dev_id, struct pt_regs *regs) | |||
84 | 80 | ||
85 | static int sh_dmac_request_dma(struct dma_channel *chan) | 81 | static int sh_dmac_request_dma(struct dma_channel *chan) |
86 | { | 82 | { |
87 | char name[32]; | 83 | if (unlikely(!chan->flags & DMA_TEI_CAPABLE)) |
84 | return 0; | ||
88 | 85 | ||
89 | snprintf(name, sizeof(name), "DMAC Transfer End (Channel %d)", | 86 | chan->name = kzalloc(32, GFP_KERNEL); |
87 | if (unlikely(chan->name == NULL)) | ||
88 | return -ENOMEM; | ||
89 | snprintf(chan->name, 32, "DMAC Transfer End (Channel %d)", | ||
90 | chan->chan); | 90 | chan->chan); |
91 | 91 | ||
92 | return request_irq(get_dmte_irq(chan->chan), dma_tei, | 92 | return request_irq(get_dmte_irq(chan->chan), dma_tei, |
93 | IRQF_DISABLED, name, chan); | 93 | IRQF_DISABLED, chan->name, chan); |
94 | } | 94 | } |
95 | 95 | ||
96 | static void sh_dmac_free_dma(struct dma_channel *chan) | 96 | static void sh_dmac_free_dma(struct dma_channel *chan) |
97 | { | 97 | { |
98 | free_irq(get_dmte_irq(chan->chan), chan); | 98 | free_irq(get_dmte_irq(chan->chan), chan); |
99 | kfree(chan->name); | ||
99 | } | 100 | } |
100 | 101 | ||
101 | static void | 102 | static void |
@@ -259,7 +260,7 @@ static int __init sh_dmac_init(void) | |||
259 | #ifdef CONFIG_CPU_SH4 | 260 | #ifdef CONFIG_CPU_SH4 |
260 | make_ipr_irq(DMAE_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); | 261 | make_ipr_irq(DMAE_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); |
261 | i = request_irq(DMAE_IRQ, dma_err, IRQF_DISABLED, "DMAC Address Error", 0); | 262 | i = request_irq(DMAE_IRQ, dma_err, IRQF_DISABLED, "DMAC Address Error", 0); |
262 | if (i < 0) | 263 | if (unlikely(i < 0)) |
263 | return i; | 264 | return i; |
264 | #endif | 265 | #endif |
265 | 266 | ||
@@ -274,7 +275,7 @@ static int __init sh_dmac_init(void) | |||
274 | * been set. | 275 | * been set. |
275 | */ | 276 | */ |
276 | i = dmaor_reset(); | 277 | i = dmaor_reset(); |
277 | if (i < 0) | 278 | if (unlikely(i != 0)) |
278 | return i; | 279 | return i; |
279 | 280 | ||
280 | return register_dmac(info); | 281 | return register_dmac(info); |
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index 365bc16a4a83..9e00cb8a39e9 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile | |||
@@ -6,7 +6,8 @@ obj-y += pci.o | |||
6 | obj-$(CONFIG_PCI_AUTO) += pci-auto.o | 6 | obj-$(CONFIG_PCI_AUTO) += pci-auto.o |
7 | 7 | ||
8 | obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += pci-st40.o | 8 | obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += pci-st40.o |
9 | obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o | 9 | obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o |
10 | obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o | ||
10 | 11 | ||
11 | obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \ | 12 | obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \ |
12 | dma-dreamcast.o | 13 | dma-dreamcast.o |
@@ -14,3 +15,6 @@ obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o | |||
14 | obj-$(CONFIG_SH_BIGSUR) += ops-bigsur.o | 15 | obj-$(CONFIG_SH_BIGSUR) += ops-bigsur.o |
15 | obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o | 16 | obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o |
16 | obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o | 17 | obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o |
18 | obj-$(CONFIG_SH_R7780RP) += ops-r7780rp.o fixups-r7780rp.o | ||
19 | obj-$(CONFIG_SH_TITAN) += ops-titan.o | ||
20 | obj-$(CONFIG_SH_LANDISK) += ops-landisk.o | ||
diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c index 63b1c6f4b8d2..c0af5f7ef414 100644 --- a/arch/sh/drivers/pci/fixups-dreamcast.c +++ b/arch/sh/drivers/pci/fixups-dreamcast.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * PCI fixups for the Sega Dreamcast | 4 | * PCI fixups for the Sega Dreamcast |
5 | * | 5 | * |
6 | * Copyright (C) 2001, 2002 M. R. Brown | 6 | * Copyright (C) 2001, 2002 M. R. Brown |
7 | * Copyright (C) 2002, 2003 Paul Mundt | 7 | * Copyright (C) 2002, 2003, 2006 Paul Mundt |
8 | * | 8 | * |
9 | * This file originally bore the message (with enclosed-$): | 9 | * This file originally bore the message (with enclosed-$): |
10 | * Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp | 10 | * Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp |
@@ -45,36 +45,16 @@ static void __init gapspci_fixup_resources(struct pci_dev *dev) | |||
45 | printk("PCI: Failed resource fixup\n"); | 45 | printk("PCI: Failed resource fixup\n"); |
46 | } | 46 | } |
47 | } | 47 | } |
48 | |||
49 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources); | 48 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources); |
50 | 49 | ||
51 | void __init pcibios_fixup_bus(struct pci_bus *bus) | 50 | int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) |
52 | { | 51 | { |
53 | /* | 52 | /* |
54 | * We don't have any sub bus to fix up, and this is a rather | 53 | * The interrupt routing semantics here are quite trivial. |
55 | * stupid place to put general device fixups. Don't do it. | 54 | * |
56 | * Use the pcibios_fixups table or suffer the consequences. | 55 | * We basically only support one interrupt, so we only bother |
56 | * updating a device's interrupt line with this single shared | ||
57 | * interrupt. Keeps routing quite simple, doesn't it? | ||
57 | */ | 58 | */ |
59 | return GAPSPCI_IRQ; | ||
58 | } | 60 | } |
59 | |||
60 | void __init pcibios_fixup_irqs(void) | ||
61 | { | ||
62 | struct pci_dev *dev = 0; | ||
63 | |||
64 | for_each_pci_dev(dev) { | ||
65 | /* | ||
66 | * The interrupt routing semantics here are quite trivial. | ||
67 | * | ||
68 | * We basically only support one interrupt, so we only bother | ||
69 | * updating a device's interrupt line with this single shared | ||
70 | * interrupt. Keeps routing quite simple, doesn't it? | ||
71 | */ | ||
72 | printk(KERN_NOTICE "PCI: Fixing up IRQ routing for device %s\n", | ||
73 | pci_name(dev)); | ||
74 | |||
75 | dev->irq = GAPSPCI_IRQ; | ||
76 | |||
77 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); | ||
78 | } | ||
79 | } | ||
80 | |||
diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c new file mode 100644 index 000000000000..3e321df65d22 --- /dev/null +++ b/arch/sh/drivers/pci/fixups-r7780rp.c | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * arch/sh/drivers/pci/fixups-r7780rp.c | ||
3 | * | ||
4 | * Highlander R7780RP-1 PCI fixups | ||
5 | * | ||
6 | * Copyright (C) 2003 Lineo uSolutions, Inc. | ||
7 | * Copyright (C) 2004 - 2006 Paul Mundt | ||
8 | * | ||
9 | * This file is subject to the terms and conditions of the GNU General Public | ||
10 | * License. See the file "COPYING" in the main directory of this archive | ||
11 | * for more details. | ||
12 | */ | ||
13 | #include <linux/pci.h> | ||
14 | #include "pci-sh4.h" | ||
15 | #include <asm/io.h> | ||
16 | |||
17 | int pci_fixup_pcic(void) | ||
18 | { | ||
19 | pci_write_reg(0x000043ff, SH4_PCIINTM); | ||
20 | pci_write_reg(0x0000380f, SH4_PCIAINTM); | ||
21 | |||
22 | pci_write_reg(0xfbb00047, SH7780_PCICMD); | ||
23 | pci_write_reg(0x00000000, SH7780_PCIIBAR); | ||
24 | |||
25 | pci_write_reg(0x00011912, SH7780_PCISVID); | ||
26 | pci_write_reg(0x08000000, SH7780_PCICSCR0); | ||
27 | pci_write_reg(0x0000001b, SH7780_PCICSAR0); | ||
28 | pci_write_reg(0xfd000000, SH7780_PCICSCR1); | ||
29 | pci_write_reg(0x0000000f, SH7780_PCICSAR1); | ||
30 | |||
31 | pci_write_reg(0xfd000000, SH7780_PCIMBR0); | ||
32 | pci_write_reg(0x00fc0000, SH7780_PCIMBMR0); | ||
33 | |||
34 | #ifdef CONFIG_32BIT | ||
35 | pci_write_reg(0xc0000000, SH7780_PCIMBR2); | ||
36 | pci_write_reg(0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2); | ||
37 | #endif | ||
38 | |||
39 | /* Set IOBR for windows containing area specified in pci.h */ | ||
40 | pci_write_reg((PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE - 1)), | ||
41 | SH7780_PCIIOBR); | ||
42 | pci_write_reg(((SH7780_PCI_IO_SIZE-1) & (7<<18)), SH7780_PCIIOBMR); | ||
43 | |||
44 | return 0; | ||
45 | } | ||
diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c index 0c590fc7a081..e72ceb560d5b 100644 --- a/arch/sh/drivers/pci/fixups-rts7751r2d.c +++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c | |||
@@ -10,8 +10,7 @@ | |||
10 | * License. See the file "COPYING" in the main directory of this archive | 10 | * License. See the file "COPYING" in the main directory of this archive |
11 | * for more details. | 11 | * for more details. |
12 | */ | 12 | */ |
13 | #include "pci-sh7751.h" | 13 | #include "pci-sh4.h" |
14 | #include <asm/io.h> | ||
15 | 14 | ||
16 | #define PCIMCR_MRSET_OFF 0xBFFFFFFF | 15 | #define PCIMCR_MRSET_OFF 0xBFFFFFFF |
17 | #define PCIMCR_RFSH_OFF 0xFFFFFFFB | 16 | #define PCIMCR_RFSH_OFF 0xFFFFFFFB |
@@ -22,22 +21,23 @@ int pci_fixup_pcic(void) | |||
22 | 21 | ||
23 | bcr1 = inl(SH7751_BCR1); | 22 | bcr1 = inl(SH7751_BCR1); |
24 | bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ | 23 | bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ |
25 | outl(bcr1, PCI_REG(SH7751_PCIBCR1)); | 24 | pci_write_reg(bcr1, SH4_PCIBCR1); |
26 | 25 | ||
27 | /* Enable all interrupts, so we known what to fix */ | 26 | /* Enable all interrupts, so we known what to fix */ |
28 | outl(0x0000c3ff, PCI_REG(SH7751_PCIINTM)); | 27 | pci_write_reg(0x0000c3ff, SH4_PCIINTM); |
29 | outl(0x0000380f, PCI_REG(SH7751_PCIAINTM)); | 28 | pci_write_reg(0x0000380f, SH4_PCIAINTM); |
30 | 29 | ||
31 | outl(0xfb900047, PCI_REG(SH7751_PCICONF1)); | 30 | pci_write_reg(0xfb900047, SH7751_PCICONF1); |
32 | outl(0xab000001, PCI_REG(SH7751_PCICONF4)); | 31 | pci_write_reg(0xab000001, SH7751_PCICONF4); |
33 | 32 | ||
34 | mcr = inl(SH7751_MCR); | 33 | mcr = inl(SH7751_MCR); |
35 | mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; | 34 | mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; |
36 | outl(mcr, PCI_REG(SH7751_PCIMCR)); | 35 | pci_write_reg(mcr, SH4_PCIMCR); |
36 | |||
37 | pci_write_reg(0x0c000000, SH7751_PCICONF5); | ||
38 | pci_write_reg(0xd0000000, SH7751_PCICONF6); | ||
39 | pci_write_reg(0x0c000000, SH4_PCILAR0); | ||
40 | pci_write_reg(0x00000000, SH4_PCILAR1); | ||
37 | 41 | ||
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; | 42 | return 0; |
43 | } | 43 | } |
diff --git a/arch/sh/drivers/pci/fixups-sh03.c b/arch/sh/drivers/pci/fixups-sh03.c index 57ac26c2171f..2e8a18b7ee53 100644 --- a/arch/sh/drivers/pci/fixups-sh03.c +++ b/arch/sh/drivers/pci/fixups-sh03.c | |||
@@ -3,11 +3,7 @@ | |||
3 | #include <linux/types.h> | 3 | #include <linux/types.h> |
4 | #include <linux/pci.h> | 4 | #include <linux/pci.h> |
5 | 5 | ||
6 | /* | 6 | int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) |
7 | * IRQ functions | ||
8 | */ | ||
9 | |||
10 | int __init pcibios_map_platform_irq(u8 slot, u8 pin, struct pci_dev *dev) | ||
11 | { | 7 | { |
12 | int irq; | 8 | int irq; |
13 | 9 | ||
@@ -17,8 +13,9 @@ int __init pcibios_map_platform_irq(u8 slot, u8 pin, struct pci_dev *dev) | |||
17 | case 8: return 5; /* eth1 */ | 13 | case 8: return 5; /* eth1 */ |
18 | case 6: return 2; /* PCI bridge */ | 14 | case 6: return 2; /* PCI bridge */ |
19 | default: | 15 | default: |
20 | printk("PCI: Bad IRQ mapping request for slot %d\n", slot); | 16 | printk(KERN_ERR "PCI: Bad IRQ mapping request " |
21 | return 2; | 17 | "for slot %d\n", slot); |
18 | return 2; | ||
22 | } | 19 | } |
23 | } else { | 20 | } else { |
24 | switch (pin) { | 21 | switch (pin) { |
@@ -32,30 +29,3 @@ int __init pcibios_map_platform_irq(u8 slot, u8 pin, struct pci_dev *dev) | |||
32 | } | 29 | } |
33 | return irq; | 30 | return irq; |
34 | } | 31 | } |
35 | |||
36 | static u8 __init sh03_no_swizzle(struct pci_dev *dev, u8 *pin) | ||
37 | { | ||
38 | /* no swizzling */ | ||
39 | return PCI_SLOT(dev->devfn); | ||
40 | } | ||
41 | |||
42 | static 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 | |||
58 | void __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 index ae82c6ca05e5..5da501bd77b5 100644 --- a/arch/sh/drivers/pci/ops-bigsur.c +++ b/arch/sh/drivers/pci/ops-bigsur.c | |||
@@ -10,15 +10,12 @@ | |||
10 | * | 10 | * |
11 | * PCI initialization for the Hitachi Big Sur Evaluation Board | 11 | * PCI initialization for the Hitachi Big Sur Evaluation Board |
12 | */ | 12 | */ |
13 | |||
14 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
15 | #include <linux/types.h> | 14 | #include <linux/types.h> |
16 | #include <linux/init.h> | 15 | #include <linux/init.h> |
17 | #include <linux/delay.h> | ||
18 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
19 | |||
20 | #include <asm/io.h> | 17 | #include <asm/io.h> |
21 | #include "pci-sh7751.h" | 18 | #include "pci-sh4.h" |
22 | #include <asm/bigsur/bigsur.h> | 19 | #include <asm/bigsur/bigsur.h> |
23 | 20 | ||
24 | #define BIGSUR_PCI_IO 0x4000 | 21 | #define BIGSUR_PCI_IO 0x4000 |
@@ -41,11 +38,11 @@ static struct resource sh7751_mem_resource = { | |||
41 | extern struct pci_ops sh7751_pci_ops; | 38 | extern struct pci_ops sh7751_pci_ops; |
42 | 39 | ||
43 | struct pci_channel board_pci_channels[] = { | 40 | struct pci_channel board_pci_channels[] = { |
44 | { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, | 41 | { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, |
45 | { 0, } | 42 | { 0, } |
46 | }; | 43 | }; |
47 | 44 | ||
48 | static struct sh7751_pci_address_map sh7751_pci_map = { | 45 | static struct sh4_pci_address_map sh7751_pci_map = { |
49 | .window0 = { | 46 | .window0 = { |
50 | .base = SH7751_CS3_BASE_ADDR, | 47 | .base = SH7751_CS3_BASE_ADDR, |
51 | .size = BIGSUR_LSR0_SIZE, | 48 | .size = BIGSUR_LSR0_SIZE, |
@@ -58,7 +55,7 @@ static struct sh7751_pci_address_map sh7751_pci_map = { | |||
58 | }; | 55 | }; |
59 | 56 | ||
60 | /* | 57 | /* |
61 | * Initialize the Big Sur PCI interface | 58 | * Initialize the Big Sur PCI interface |
62 | * Setup hardware to be Central Funtion | 59 | * Setup hardware to be Central Funtion |
63 | * Copy the BSR regs to the PCI interface | 60 | * Copy the BSR regs to the PCI interface |
64 | * Setup PCI windows into local RAM | 61 | * Setup PCI windows into local RAM |
@@ -68,15 +65,15 @@ int __init pcibios_init_platform(void) | |||
68 | return sh7751_pcic_init(&sh7751_pci_map); | 65 | return sh7751_pcic_init(&sh7751_pci_map); |
69 | } | 66 | } |
70 | 67 | ||
71 | int pcibios_map_platform_irq(u8 slot, u8 pin) | 68 | int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) |
72 | { | 69 | { |
73 | /* | 70 | /* |
74 | * The Big Sur can be used in a CPCI chassis, but the SH7751 PCI | 71 | * The Big Sur can be used in a CPCI chassis, but the SH7751 PCI |
75 | * interface is on the wrong end of the board so that it can also | 72 | * interface is on the wrong end of the board so that it can also |
76 | * support a V320 CPI interface chip... Therefor the IRQ mapping is | 73 | * support a V320 CPI interface chip... Therefor the IRQ mapping is |
77 | * somewhat use dependent... I'l assume a linear map for now, i.e. | 74 | * somewhat use dependent... I'l assume a linear map for now, i.e. |
78 | * INTA=slot0,pin0... INTD=slot3,pin0... | 75 | * INTA=slot0,pin0... INTD=slot3,pin0... |
79 | */ | 76 | */ |
80 | int irq = (slot + pin-1) % 4 + BIGSUR_SH7751_PCI_IRQ_BASE; | 77 | int irq = (slot + pin-1) % 4 + BIGSUR_SH7751_PCI_IRQ_BASE; |
81 | 78 | ||
82 | PCIDBG(2, "PCI: Mapping Big Sur IRQ for slot %d, pin %c to irq %d\n", | 79 | PCIDBG(2, "PCI: Mapping Big Sur IRQ for slot %d, pin %c to irq %d\n", |
@@ -84,4 +81,3 @@ int pcibios_map_platform_irq(u8 slot, u8 pin) | |||
84 | 81 | ||
85 | return irq; | 82 | return irq; |
86 | } | 83 | } |
87 | |||
diff --git a/arch/sh/drivers/pci/ops-landisk.c b/arch/sh/drivers/pci/ops-landisk.c new file mode 100644 index 000000000000..ada301c21fe7 --- /dev/null +++ b/arch/sh/drivers/pci/ops-landisk.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | * arch/sh/drivers/pci/ops-landisk.c | ||
3 | * | ||
4 | * PCI initialization for the I-O DATA Device, Inc. LANDISK board | ||
5 | * | ||
6 | * Copyright (C) 2006 kogiidena | ||
7 | * | ||
8 | * May be copied or modified under the terms of the GNU General Public | ||
9 | * License. See linux/COPYING for more information. | ||
10 | */ | ||
11 | #include <linux/config.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/pci.h> | ||
17 | #include "pci-sh4.h" | ||
18 | |||
19 | static struct resource sh7751_io_resource = { | ||
20 | .name = "SH7751 IO", | ||
21 | .start = 0x4000, | ||
22 | .end = 0x4000 + SH7751_PCI_IO_SIZE - 1, | ||
23 | .flags = IORESOURCE_IO | ||
24 | }; | ||
25 | |||
26 | static struct resource sh7751_mem_resource = { | ||
27 | .name = "SH7751 mem", | ||
28 | .start = SH7751_PCI_MEMORY_BASE, | ||
29 | .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, | ||
30 | .flags = IORESOURCE_MEM | ||
31 | }; | ||
32 | |||
33 | struct pci_channel board_pci_channels[] = { | ||
34 | {&sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0x3ff}, | ||
35 | {NULL, NULL, NULL, 0, 0}, | ||
36 | }; | ||
37 | |||
38 | static struct sh4_pci_address_map sh7751_pci_map = { | ||
39 | .window0 = { | ||
40 | .base = SH7751_CS3_BASE_ADDR, | ||
41 | .size = (64 << 20), /* 64MB */ | ||
42 | }, | ||
43 | |||
44 | .flags = SH4_PCIC_NO_RESET, | ||
45 | }; | ||
46 | |||
47 | int __init pcibios_init_platform(void) | ||
48 | { | ||
49 | return sh7751_pcic_init(&sh7751_pci_map); | ||
50 | } | ||
51 | |||
52 | int pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) | ||
53 | { | ||
54 | /* | ||
55 | * slot0: pin1-4 = irq5,6,7,8 | ||
56 | * slot1: pin1-4 = irq6,7,8,5 | ||
57 | * slot2: pin1-4 = irq7,8,5,6 | ||
58 | * slot3: pin1-4 = irq8,5,6,7 | ||
59 | */ | ||
60 | int irq = ((slot + pin - 1) & 0x3) + 5; | ||
61 | |||
62 | if ((slot | (pin - 1)) > 0x3) { | ||
63 | printk("PCI: Bad IRQ mapping request for slot %d pin %c\n", | ||
64 | slot, pin - 1 + 'A'); | ||
65 | return -1; | ||
66 | } | ||
67 | return irq; | ||
68 | } | ||
diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c new file mode 100644 index 000000000000..554d5ed2c586 --- /dev/null +++ b/arch/sh/drivers/pci/ops-r7780rp.c | |||
@@ -0,0 +1,75 @@ | |||
1 | /* | ||
2 | * Author: Ian DaSilva (idasilva@mvista.com) | ||
3 | * | ||
4 | * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. | ||
5 | * | ||
6 | * May be copied or modified under the terms of the GNU General Public | ||
7 | * License. See linux/COPYING for more information. | ||
8 | * | ||
9 | * PCI initialization for the Renesas SH7780 Highlander R7780RP-1 board | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/pci.h> | ||
18 | #include <asm/r7780rp/r7780rp.h> | ||
19 | #include <asm/io.h> | ||
20 | #include "pci-sh4.h" | ||
21 | |||
22 | int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) | ||
23 | { | ||
24 | switch (slot) { | ||
25 | case 0: return IRQ_PCISLOT1; /* PCI Interrupt #1 */ | ||
26 | case 1: return IRQ_PCISLOT2; /* PCI Interrupt #2 */ | ||
27 | case 2: return IRQ_PCISLOT3; /* PCI Interrupt #3 */ | ||
28 | case 3: return IRQ_PCISLOT4; /* PCI Interrupt E4 */ | ||
29 | default: | ||
30 | printk(KERN_ERR "PCI: Bad IRQ mapping " | ||
31 | "request for slot %d, func %d\n", slot, pin-1); | ||
32 | return -1; | ||
33 | } | ||
34 | } | ||
35 | |||
36 | static struct resource sh7780_io_resource = { | ||
37 | .name = "SH7780_IO", | ||
38 | .start = 0x2000, | ||
39 | .end = 0x2000 + SH7780_PCI_IO_SIZE - 1, | ||
40 | .flags = IORESOURCE_IO | ||
41 | }; | ||
42 | |||
43 | static struct resource sh7780_mem_resource = { | ||
44 | .name = "SH7780_mem", | ||
45 | .start = SH7780_PCI_MEMORY_BASE, | ||
46 | .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, | ||
47 | .flags = IORESOURCE_MEM | ||
48 | }; | ||
49 | |||
50 | extern struct pci_ops sh7780_pci_ops; | ||
51 | |||
52 | struct pci_channel board_pci_channels[] = { | ||
53 | { &sh4_pci_ops, &sh7780_io_resource, &sh7780_mem_resource, 0, 0xff }, | ||
54 | { NULL, NULL, NULL, 0, 0 }, | ||
55 | }; | ||
56 | EXPORT_SYMBOL(board_pci_channels); | ||
57 | |||
58 | static struct sh4_pci_address_map sh7780_pci_map = { | ||
59 | .window0 = { | ||
60 | .base = SH7780_CS2_BASE_ADDR, | ||
61 | .size = 0x04000000, | ||
62 | }, | ||
63 | |||
64 | .window1 = { | ||
65 | .base = SH7780_CS3_BASE_ADDR, | ||
66 | .size = 0x04000000, | ||
67 | }, | ||
68 | |||
69 | .flags = SH4_PCIC_NO_RESET, | ||
70 | }; | ||
71 | |||
72 | int __init pcibios_init_platform(void) | ||
73 | { | ||
74 | return sh7780_pcic_init(&sh7780_pci_map); | ||
75 | } | ||
diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c index 83171d10141a..88f44e245424 100644 --- a/arch/sh/drivers/pci/ops-rts7751r2d.c +++ b/arch/sh/drivers/pci/ops-rts7751r2d.c | |||
@@ -17,12 +17,11 @@ | |||
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | |||
21 | #include <asm/io.h> | ||
22 | #include "pci-sh7751.h" | ||
23 | #include <asm/rts7751r2d/rts7751r2d.h> | 20 | #include <asm/rts7751r2d/rts7751r2d.h> |
21 | #include <asm/io.h> | ||
22 | #include "pci-sh4.h" | ||
24 | 23 | ||
25 | int __init pcibios_map_platform_irq(u8 slot, u8 pin) | 24 | int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) |
26 | { | 25 | { |
27 | switch (slot) { | 26 | switch (slot) { |
28 | case 0: return IRQ_PCISLOT1; /* PCI Extend slot #1 */ | 27 | case 0: return IRQ_PCISLOT1; /* PCI Extend slot #1 */ |
@@ -52,12 +51,12 @@ static struct resource sh7751_mem_resource = { | |||
52 | extern struct pci_ops sh7751_pci_ops; | 51 | extern struct pci_ops sh7751_pci_ops; |
53 | 52 | ||
54 | struct pci_channel board_pci_channels[] = { | 53 | struct pci_channel board_pci_channels[] = { |
55 | { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, | 54 | { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, |
56 | { NULL, NULL, NULL, 0, 0 }, | 55 | { NULL, NULL, NULL, 0, 0 }, |
57 | }; | 56 | }; |
58 | EXPORT_SYMBOL(board_pci_channels); | 57 | EXPORT_SYMBOL(board_pci_channels); |
59 | 58 | ||
60 | static struct sh7751_pci_address_map sh7751_pci_map = { | 59 | static struct sh4_pci_address_map sh7751_pci_map = { |
61 | .window0 = { | 60 | .window0 = { |
62 | .base = SH7751_CS3_BASE_ADDR, | 61 | .base = SH7751_CS3_BASE_ADDR, |
63 | .size = 0x04000000, | 62 | .size = 0x04000000, |
@@ -68,7 +67,7 @@ static struct sh7751_pci_address_map sh7751_pci_map = { | |||
68 | .size = 0x00000000, /* Unused */ | 67 | .size = 0x00000000, /* Unused */ |
69 | }, | 68 | }, |
70 | 69 | ||
71 | .flags = SH7751_PCIC_NO_RESET, | 70 | .flags = SH4_PCIC_NO_RESET, |
72 | }; | 71 | }; |
73 | 72 | ||
74 | int __init pcibios_init_platform(void) | 73 | int __init pcibios_init_platform(void) |
diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c new file mode 100644 index 000000000000..2d4371009a5e --- /dev/null +++ b/arch/sh/drivers/pci/ops-sh4.c | |||
@@ -0,0 +1,164 @@ | |||
1 | /* | ||
2 | * Generic SH-4 / SH-4A PCIC operations (SH7751, SH7780). | ||
3 | * | ||
4 | * Copyright (C) 2002 - 2006 Paul Mundt | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License v2. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | #include <linux/pci.h> | ||
11 | #include <asm/addrspace.h> | ||
12 | #include <asm/io.h> | ||
13 | #include "pci-sh4.h" | ||
14 | |||
15 | /* | ||
16 | * Direct access to PCI hardware... | ||
17 | */ | ||
18 | #define CONFIG_CMD(bus, devfn, where) \ | ||
19 | P1SEGADDR((bus->number << 16) | (devfn << 8) | (where & ~3)) | ||
20 | |||
21 | static DEFINE_SPINLOCK(sh4_pci_lock); | ||
22 | |||
23 | /* | ||
24 | * Functions for accessing PCI configuration space with type 1 accesses | ||
25 | */ | ||
26 | static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn, | ||
27 | int where, int size, u32 *val) | ||
28 | { | ||
29 | unsigned long flags; | ||
30 | u32 data; | ||
31 | |||
32 | /* | ||
33 | * PCIPDR may only be accessed as 32 bit words, | ||
34 | * so we must do byte alignment by hand | ||
35 | */ | ||
36 | spin_lock_irqsave(&sh4_pci_lock, flags); | ||
37 | pci_write_reg(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); | ||
38 | data = pci_read_reg(SH4_PCIPDR); | ||
39 | spin_unlock_irqrestore(&sh4_pci_lock, flags); | ||
40 | |||
41 | switch (size) { | ||
42 | case 1: | ||
43 | *val = (data >> ((where & 3) << 3)) & 0xff; | ||
44 | break; | ||
45 | case 2: | ||
46 | *val = (data >> ((where & 2) << 3)) & 0xffff; | ||
47 | break; | ||
48 | case 4: | ||
49 | *val = data; | ||
50 | break; | ||
51 | default: | ||
52 | return PCIBIOS_FUNC_NOT_SUPPORTED; | ||
53 | } | ||
54 | |||
55 | return PCIBIOS_SUCCESSFUL; | ||
56 | } | ||
57 | |||
58 | /* | ||
59 | * Since SH4 only does 32bit access we'll have to do a read, | ||
60 | * mask,write operation. | ||
61 | * We'll allow an odd byte offset, though it should be illegal. | ||
62 | */ | ||
63 | static int sh4_pci_write(struct pci_bus *bus, unsigned int devfn, | ||
64 | int where, int size, u32 val) | ||
65 | { | ||
66 | unsigned long flags; | ||
67 | int shift; | ||
68 | u32 data; | ||
69 | |||
70 | spin_lock_irqsave(&sh4_pci_lock, flags); | ||
71 | pci_write_reg(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); | ||
72 | data = pci_read_reg(SH4_PCIPDR); | ||
73 | spin_unlock_irqrestore(&sh4_pci_lock, flags); | ||
74 | |||
75 | switch (size) { | ||
76 | case 1: | ||
77 | shift = (where & 3) << 3; | ||
78 | data &= ~(0xff << shift); | ||
79 | data |= ((val & 0xff) << shift); | ||
80 | break; | ||
81 | case 2: | ||
82 | shift = (where & 2) << 3; | ||
83 | data &= ~(0xffff << shift); | ||
84 | data |= ((val & 0xffff) << shift); | ||
85 | break; | ||
86 | case 4: | ||
87 | data = val; | ||
88 | break; | ||
89 | default: | ||
90 | return PCIBIOS_FUNC_NOT_SUPPORTED; | ||
91 | } | ||
92 | |||
93 | pci_write_reg(data, SH4_PCIPDR); | ||
94 | |||
95 | return PCIBIOS_SUCCESSFUL; | ||
96 | } | ||
97 | |||
98 | struct pci_ops sh4_pci_ops = { | ||
99 | .read = sh4_pci_read, | ||
100 | .write = sh4_pci_write, | ||
101 | }; | ||
102 | |||
103 | /* | ||
104 | * Not really related to pci_ops, but it's common and not worth shoving | ||
105 | * somewhere else for now.. | ||
106 | */ | ||
107 | static unsigned int pci_probe = PCI_PROBE_CONF1; | ||
108 | |||
109 | int __init sh4_pci_check_direct(void) | ||
110 | { | ||
111 | /* | ||
112 | * Check if configuration works. | ||
113 | */ | ||
114 | if (pci_probe & PCI_PROBE_CONF1) { | ||
115 | unsigned int tmp = pci_read_reg(SH4_PCIPAR); | ||
116 | |||
117 | pci_write_reg(P1SEG, SH4_PCIPAR); | ||
118 | |||
119 | if (pci_read_reg(SH4_PCIPAR) == P1SEG) { | ||
120 | pci_write_reg(tmp, SH4_PCIPAR); | ||
121 | printk(KERN_INFO "PCI: Using configuration type 1\n"); | ||
122 | request_region(PCI_REG(SH4_PCIPAR), 8, "PCI conf1"); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | pci_write_reg(tmp, SH4_PCIPAR); | ||
128 | } | ||
129 | |||
130 | pr_debug("PCI: pci_check_direct failed\n"); | ||
131 | return -EINVAL; | ||
132 | } | ||
133 | |||
134 | /* Handle generic fixups */ | ||
135 | static void __init pci_fixup_ide_bases(struct pci_dev *d) | ||
136 | { | ||
137 | int i; | ||
138 | |||
139 | /* | ||
140 | * PCI IDE controllers use non-standard I/O port decoding, respect it. | ||
141 | */ | ||
142 | if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE) | ||
143 | return; | ||
144 | pr_debug("PCI: IDE base address fixup for %s\n", pci_name(d)); | ||
145 | for(i = 0; i < 4; i++) { | ||
146 | struct resource *r = &d->resource[i]; | ||
147 | |||
148 | if ((r->start & ~0x80) == 0x374) { | ||
149 | r->start |= 2; | ||
150 | r->end = r->start; | ||
151 | } | ||
152 | } | ||
153 | } | ||
154 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); | ||
155 | |||
156 | char * __init pcibios_setup(char *str) | ||
157 | { | ||
158 | if (!strcmp(str, "off")) { | ||
159 | pci_probe = 0; | ||
160 | return NULL; | ||
161 | } | ||
162 | |||
163 | return str; | ||
164 | } | ||
diff --git a/arch/sh/drivers/pci/ops-snapgear.c b/arch/sh/drivers/pci/ops-snapgear.c index 3cbd14dd28fe..53dd893d4e54 100644 --- a/arch/sh/drivers/pci/ops-snapgear.c +++ b/arch/sh/drivers/pci/ops-snapgear.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * arch/sh/drivers/pci/ops-snapgear.c | 2 | * arch/sh/drivers/pci/ops-snapgear.c |
3 | * | 3 | * |
4 | * Author: David McCullough <davidm@snapgear.com> | 4 | * Author: David McCullough <davidm@snapgear.com> |
5 | * | 5 | * |
6 | * Ported to new API by Paul Mundt <lethal@linux-sh.org> | 6 | * Ported to new API by Paul Mundt <lethal@linux-sh.org> |
7 | * | 7 | * |
8 | * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. | 8 | * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. |
@@ -12,15 +12,11 @@ | |||
12 | * | 12 | * |
13 | * PCI initialization for the SnapGear boards | 13 | * PCI initialization for the SnapGear boards |
14 | */ | 14 | */ |
15 | |||
16 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
17 | #include <linux/types.h> | 16 | #include <linux/types.h> |
18 | #include <linux/init.h> | 17 | #include <linux/init.h> |
19 | #include <linux/delay.h> | ||
20 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
21 | 19 | #include "pci-sh4.h" | |
22 | #include <asm/io.h> | ||
23 | #include "pci-sh7751.h" | ||
24 | 20 | ||
25 | #define SNAPGEAR_PCI_IO 0x4000 | 21 | #define SNAPGEAR_PCI_IO 0x4000 |
26 | #define SNAPGEAR_PCI_MEM 0xfd000000 | 22 | #define SNAPGEAR_PCI_MEM 0xfd000000 |
@@ -43,14 +39,12 @@ static struct resource sh7751_mem_resource = { | |||
43 | .flags = IORESOURCE_MEM, | 39 | .flags = IORESOURCE_MEM, |
44 | }; | 40 | }; |
45 | 41 | ||
46 | extern struct pci_ops sh7751_pci_ops; | ||
47 | |||
48 | struct pci_channel board_pci_channels[] = { | 42 | struct pci_channel board_pci_channels[] = { |
49 | { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, | 43 | { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, |
50 | { 0, } | 44 | { 0, } |
51 | }; | 45 | }; |
52 | 46 | ||
53 | static struct sh7751_pci_address_map sh7751_pci_map = { | 47 | static struct sh4_pci_address_map sh7751_pci_map = { |
54 | .window0 = { | 48 | .window0 = { |
55 | .base = SH7751_CS2_BASE_ADDR, | 49 | .base = SH7751_CS2_BASE_ADDR, |
56 | .size = SNAPGEAR_LSR0_SIZE, | 50 | .size = SNAPGEAR_LSR0_SIZE, |
@@ -61,11 +55,11 @@ static struct sh7751_pci_address_map sh7751_pci_map = { | |||
61 | .size = SNAPGEAR_LSR1_SIZE, | 55 | .size = SNAPGEAR_LSR1_SIZE, |
62 | }, | 56 | }, |
63 | 57 | ||
64 | .flags = SH7751_PCIC_NO_RESET, | 58 | .flags = SH4_PCIC_NO_RESET, |
65 | }; | 59 | }; |
66 | 60 | ||
67 | /* | 61 | /* |
68 | * Initialize the SnapGear PCI interface | 62 | * Initialize the SnapGear PCI interface |
69 | * Setup hardware to be Central Funtion | 63 | * Setup hardware to be Central Funtion |
70 | * Copy the BSR regs to the PCI interface | 64 | * Copy the BSR regs to the PCI interface |
71 | * Setup PCI windows into local RAM | 65 | * Setup PCI windows into local RAM |
@@ -75,7 +69,7 @@ int __init pcibios_init_platform(void) | |||
75 | return sh7751_pcic_init(&sh7751_pci_map); | 69 | return sh7751_pcic_init(&sh7751_pci_map); |
76 | } | 70 | } |
77 | 71 | ||
78 | int __init pcibios_map_platform_irq(u8 slot, u8 pin) | 72 | int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) |
79 | { | 73 | { |
80 | int irq = -1; | 74 | int irq = -1; |
81 | 75 | ||
@@ -98,4 +92,3 @@ void __init pcibios_fixup(void) | |||
98 | { | 92 | { |
99 | /* Nothing to fixup .. */ | 93 | /* Nothing to fixup .. */ |
100 | } | 94 | } |
101 | |||
diff --git a/arch/sh/drivers/pci/ops-titan.c b/arch/sh/drivers/pci/ops-titan.c new file mode 100644 index 000000000000..c6097bcd97fd --- /dev/null +++ b/arch/sh/drivers/pci/ops-titan.c | |||
@@ -0,0 +1,83 @@ | |||
1 | /* | ||
2 | * arch/sh/drivers/pci/ops-titan.c | ||
3 | * | ||
4 | * Ported to new API by Paul Mundt <lethal@linux-sh.org> | ||
5 | * | ||
6 | * Modified from ops-snapgear.c written by David McCullough | ||
7 | * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. | ||
8 | * | ||
9 | * May be copied or modified under the terms of the GNU General Public | ||
10 | * License. See linux/COPYING for more information. | ||
11 | * | ||
12 | * PCI initialization for the Titan boards | ||
13 | */ | ||
14 | |||
15 | #include <linux/config.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/types.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/pci.h> | ||
20 | #include <asm/io.h> | ||
21 | #include <asm/titan.h> | ||
22 | #include "pci-sh4.h" | ||
23 | |||
24 | int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) | ||
25 | { | ||
26 | int irq = -1; | ||
27 | |||
28 | switch (slot) { | ||
29 | case 0: irq = TITAN_IRQ_WAN; break; /* eth0 (WAN) */ | ||
30 | case 1: irq = TITAN_IRQ_LAN; break; /* eth1 (LAN) */ | ||
31 | case 2: irq = TITAN_IRQ_MPCIA; break; /* mPCI A */ | ||
32 | case 3: irq = TITAN_IRQ_MPCIB; break; /* mPCI B */ | ||
33 | case 4: irq = TITAN_IRQ_USB; break; /* USB */ | ||
34 | default: | ||
35 | printk(KERN_INFO "PCI: Bad IRQ mapping " | ||
36 | "request for slot %d\n", slot); | ||
37 | return -1; | ||
38 | } | ||
39 | |||
40 | printk("PCI: Mapping TITAN IRQ for slot %d, pin %c to irq %d\n", | ||
41 | slot, pin - 1 + 'A', irq); | ||
42 | |||
43 | return irq; | ||
44 | } | ||
45 | |||
46 | static struct resource sh7751_io_resource = { | ||
47 | .name = "SH7751_IO", | ||
48 | .start = SH7751_PCI_IO_BASE, | ||
49 | .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, | ||
50 | .flags = IORESOURCE_IO | ||
51 | }; | ||
52 | |||
53 | static struct resource sh7751_mem_resource = { | ||
54 | .name = "SH7751_mem", | ||
55 | .start = SH7751_PCI_MEMORY_BASE, | ||
56 | .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, | ||
57 | .flags = IORESOURCE_MEM | ||
58 | }; | ||
59 | |||
60 | struct pci_channel board_pci_channels[] = { | ||
61 | { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, | ||
62 | { NULL, NULL, NULL, 0, 0 }, | ||
63 | }; | ||
64 | EXPORT_SYMBOL(board_pci_channels); | ||
65 | |||
66 | static struct sh4_pci_address_map sh7751_pci_map = { | ||
67 | .window0 = { | ||
68 | .base = SH7751_CS2_BASE_ADDR, | ||
69 | .size = SH7751_MEM_REGION_SIZE*2, /* cs2 and cs3 */ | ||
70 | }, | ||
71 | |||
72 | .window1 = { | ||
73 | .base = SH7751_CS2_BASE_ADDR, | ||
74 | .size = SH7751_MEM_REGION_SIZE*2, | ||
75 | }, | ||
76 | |||
77 | .flags = SH4_PCIC_NO_RESET, | ||
78 | }; | ||
79 | |||
80 | int __init pcibios_init_platform(void) | ||
81 | { | ||
82 | return sh7751_pcic_init(&sh7751_pci_map); | ||
83 | } | ||
diff --git a/arch/sh/drivers/pci/pci-auto.c b/arch/sh/drivers/pci/pci-auto.c index 4cef4d1d8c84..ecf16344f94a 100644 --- a/arch/sh/drivers/pci/pci-auto.c +++ b/arch/sh/drivers/pci/pci-auto.c | |||
@@ -45,11 +45,11 @@ | |||
45 | #include <linux/types.h> | 45 | #include <linux/types.h> |
46 | #include <linux/pci.h> | 46 | #include <linux/pci.h> |
47 | 47 | ||
48 | #undef DEBUG | 48 | #define DEBUG |
49 | #ifdef DEBUG | 49 | #ifdef DEBUG |
50 | #define DBG(x...) printk(x) | 50 | #define DBG(x...) printk(x) |
51 | #else | 51 | #else |
52 | #define DBG(x...) | 52 | #define DBG(x...) |
53 | #endif | 53 | #endif |
54 | 54 | ||
55 | /* | 55 | /* |
@@ -102,7 +102,7 @@ static u32 pciauto_upper_iospc; | |||
102 | static u32 pciauto_lower_memspc; | 102 | static u32 pciauto_lower_memspc; |
103 | static u32 pciauto_upper_memspc; | 103 | static u32 pciauto_upper_memspc; |
104 | 104 | ||
105 | static void __init | 105 | static void __init |
106 | pciauto_setup_bars(struct pci_channel *hose, | 106 | pciauto_setup_bars(struct pci_channel *hose, |
107 | int top_bus, | 107 | int top_bus, |
108 | int current_bus, | 108 | int current_bus, |
@@ -116,7 +116,6 @@ pciauto_setup_bars(struct pci_channel *hose, | |||
116 | int found_mem64 = 0; | 116 | int found_mem64 = 0; |
117 | 117 | ||
118 | for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4) { | 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; | 119 | u32 bar_addr; |
121 | 120 | ||
122 | /* Read the old BAR value */ | 121 | /* Read the old BAR value */ |
@@ -125,7 +124,6 @@ pciauto_setup_bars(struct pci_channel *hose, | |||
125 | pci_devfn, | 124 | pci_devfn, |
126 | bar, | 125 | bar, |
127 | &bar_addr); | 126 | &bar_addr); |
128 | #endif | ||
129 | 127 | ||
130 | /* Tickle the BAR and get the response */ | 128 | /* Tickle the BAR and get the response */ |
131 | early_write_config_dword(hose, top_bus, | 129 | early_write_config_dword(hose, top_bus, |
@@ -140,8 +138,7 @@ pciauto_setup_bars(struct pci_channel *hose, | |||
140 | bar, | 138 | bar, |
141 | &bar_response); | 139 | &bar_response); |
142 | 140 | ||
143 | #if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D) | 141 | /* |
144 | /* | ||
145 | * Write the old BAR value back out, only update the BAR | 142 | * Write the old BAR value back out, only update the BAR |
146 | * if we implicitly want resources to be updated, which | 143 | * if we implicitly want resources to be updated, which |
147 | * is done by the generic code further down. -- PFM. | 144 | * is done by the generic code further down. -- PFM. |
@@ -151,7 +148,6 @@ pciauto_setup_bars(struct pci_channel *hose, | |||
151 | pci_devfn, | 148 | pci_devfn, |
152 | bar, | 149 | bar, |
153 | bar_addr); | 150 | bar_addr); |
154 | #endif | ||
155 | 151 | ||
156 | /* If BAR is not implemented go to the next BAR */ | 152 | /* If BAR is not implemented go to the next BAR */ |
157 | if (!bar_response) | 153 | if (!bar_response) |
@@ -177,7 +173,7 @@ retry: | |||
177 | PCI_BASE_ADDRESS_MEM_TYPE_64) | 173 | PCI_BASE_ADDRESS_MEM_TYPE_64) |
178 | found_mem64 = 1; | 174 | found_mem64 = 1; |
179 | 175 | ||
180 | addr_mask = PCI_BASE_ADDRESS_MEM_MASK; | 176 | addr_mask = PCI_BASE_ADDRESS_MEM_MASK; |
181 | upper_limit = &pciauto_upper_memspc; | 177 | upper_limit = &pciauto_upper_memspc; |
182 | lower_limit = &pciauto_lower_memspc; | 178 | lower_limit = &pciauto_lower_memspc; |
183 | DBG(" Mem"); | 179 | DBG(" Mem"); |
@@ -193,22 +189,22 @@ retry: | |||
193 | if ((bar_value + bar_size) > *upper_limit) { | 189 | if ((bar_value + bar_size) > *upper_limit) { |
194 | if (bar_response & PCI_BASE_ADDRESS_SPACE) { | 190 | if (bar_response & PCI_BASE_ADDRESS_SPACE) { |
195 | if (io_resource_inuse->child) { | 191 | if (io_resource_inuse->child) { |
196 | io_resource_inuse = | 192 | io_resource_inuse = |
197 | io_resource_inuse->child; | 193 | io_resource_inuse->child; |
198 | pciauto_lower_iospc = | 194 | pciauto_lower_iospc = |
199 | io_resource_inuse->start; | 195 | io_resource_inuse->start; |
200 | pciauto_upper_iospc = | 196 | pciauto_upper_iospc = |
201 | io_resource_inuse->end + 1; | 197 | io_resource_inuse->end + 1; |
202 | goto retry; | 198 | goto retry; |
203 | } | 199 | } |
204 | 200 | ||
205 | } else { | 201 | } else { |
206 | if (mem_resource_inuse->child) { | 202 | if (mem_resource_inuse->child) { |
207 | mem_resource_inuse = | 203 | mem_resource_inuse = |
208 | mem_resource_inuse->child; | 204 | mem_resource_inuse->child; |
209 | pciauto_lower_memspc = | 205 | pciauto_lower_memspc = |
210 | mem_resource_inuse->start; | 206 | mem_resource_inuse->start; |
211 | pciauto_upper_memspc = | 207 | pciauto_upper_memspc = |
212 | mem_resource_inuse->end + 1; | 208 | mem_resource_inuse->end + 1; |
213 | goto retry; | 209 | goto retry; |
214 | } | 210 | } |
@@ -230,7 +226,7 @@ retry: | |||
230 | * If we are a 64-bit decoder then increment to the | 226 | * If we are a 64-bit decoder then increment to the |
231 | * upper 32 bits of the bar and force it to locate | 227 | * upper 32 bits of the bar and force it to locate |
232 | * in the lower 4GB of memory. | 228 | * in the lower 4GB of memory. |
233 | */ | 229 | */ |
234 | if (found_mem64) { | 230 | if (found_mem64) { |
235 | bar += 4; | 231 | bar += 4; |
236 | early_write_config_dword(hose, top_bus, | 232 | early_write_config_dword(hose, top_bus, |
@@ -362,7 +358,6 @@ pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose, | |||
362 | { | 358 | { |
363 | u32 temp; | 359 | u32 temp; |
364 | 360 | ||
365 | #if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D) | ||
366 | /* | 361 | /* |
367 | * [jsun] we always bump up baselines a little, so that if there | 362 | * [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 | 363 | * nothing behind P2P bridge, we don't wind up overlapping IO/MEM |
@@ -370,7 +365,6 @@ pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose, | |||
370 | */ | 365 | */ |
371 | pciauto_lower_memspc += 1; | 366 | pciauto_lower_memspc += 1; |
372 | pciauto_lower_iospc += 1; | 367 | pciauto_lower_iospc += 1; |
373 | #endif | ||
374 | 368 | ||
375 | /* | 369 | /* |
376 | * Configure subordinate bus number. The PCI subsystem | 370 | * Configure subordinate bus number. The PCI subsystem |
@@ -396,11 +390,6 @@ pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose, | |||
396 | * configured by this routine to happily live behind a | 390 | * configured by this routine to happily live behind a |
397 | * P2P bridge in a system. | 391 | * P2P bridge in a system. |
398 | */ | 392 | */ |
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. */ | 393 | /* Align memory and I/O to 4KB and 4 byte boundaries. */ |
405 | pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1)) | 394 | pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1)) |
406 | & ~(0x1000 - 1); | 395 | & ~(0x1000 - 1); |
@@ -433,12 +422,12 @@ pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus) | |||
433 | int devfn_stop = 0xff; | 422 | int devfn_stop = 0xff; |
434 | 423 | ||
435 | sub_bus = current_bus; | 424 | sub_bus = current_bus; |
436 | 425 | ||
437 | if (hose->first_devfn) | 426 | if (hose->first_devfn) |
438 | devfn_start = hose->first_devfn; | 427 | devfn_start = hose->first_devfn; |
439 | if (hose->last_devfn) | 428 | if (hose->last_devfn) |
440 | devfn_stop = hose->last_devfn; | 429 | devfn_stop = hose->last_devfn; |
441 | 430 | ||
442 | for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) { | 431 | for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) { |
443 | 432 | ||
444 | if (PCI_FUNC(pci_devfn) && !found_multi) | 433 | if (PCI_FUNC(pci_devfn) && !found_multi) |
@@ -471,9 +460,6 @@ pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus) | |||
471 | if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) { | 460 | if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) { |
472 | DBG(" Bridge: primary=%.2x, secondary=%.2x\n", | 461 | DBG(" Bridge: primary=%.2x, secondary=%.2x\n", |
473 | current_bus, sub_bus + 1); | 462 | 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, | 463 | pciauto_prescan_setup_bridge(hose, top_bus, current_bus, |
478 | pci_devfn, sub_bus); | 464 | pci_devfn, sub_bus); |
479 | DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", | 465 | DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", |
@@ -490,10 +476,10 @@ pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus) | |||
490 | DBG("PCI Autoconfig: Found CardBus bridge, device %d function %d\n", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn)); | 476 | 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 */ | 477 | /* Place CardBus Socket/ExCA registers */ |
492 | pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_0); | 478 | pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_0); |
493 | 479 | ||
494 | pciauto_prescan_setup_cardbus_bridge(hose, top_bus, | 480 | pciauto_prescan_setup_cardbus_bridge(hose, top_bus, |
495 | current_bus, pci_devfn, sub_bus); | 481 | current_bus, pci_devfn, sub_bus); |
496 | 482 | ||
497 | DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", | 483 | DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", |
498 | sub_bus + 1, | 484 | sub_bus + 1, |
499 | pciauto_lower_iospc, pciauto_lower_memspc); | 485 | pciauto_lower_iospc, pciauto_lower_memspc); |
diff --git a/arch/sh/drivers/pci/pci-sh4.h b/arch/sh/drivers/pci/pci-sh4.h new file mode 100644 index 000000000000..5a61d6041f2c --- /dev/null +++ b/arch/sh/drivers/pci/pci-sh4.h | |||
@@ -0,0 +1,180 @@ | |||
1 | #ifndef __PCI_SH4_H | ||
2 | #define __PCI_SH4_H | ||
3 | |||
4 | #ifdef CONFIG_CPU_SUBTYPE_SH7780 | ||
5 | #include "pci-sh7780.h" | ||
6 | #else | ||
7 | #include "pci-sh7751.h" | ||
8 | #endif | ||
9 | |||
10 | #include <asm/io.h> | ||
11 | |||
12 | /* startup values */ | ||
13 | #define PCI_PROBE_BIOS 1 | ||
14 | #define PCI_PROBE_CONF1 2 | ||
15 | #define PCI_PROBE_CONF2 4 | ||
16 | #define PCI_NO_SORT 0x100 | ||
17 | #define PCI_BIOS_SORT 0x200 | ||
18 | #define PCI_NO_CHECKS 0x400 | ||
19 | #define PCI_ASSIGN_ROMS 0x1000 | ||
20 | #define PCI_BIOS_IRQ_SCAN 0x2000 | ||
21 | |||
22 | #define SH4_PCICR 0x100 /* PCI Control Register */ | ||
23 | #define SH4_PCICR_PREFIX 0xA5000000 /* CR prefix for write */ | ||
24 | #define SH4_PCICR_FTO 0x00000400 /* TRDY/IRDY Enable */ | ||
25 | #define SH4_PCICR_TRSB 0x00000200 /* Target Read Single */ | ||
26 | #define SH4_PCICR_BSWP 0x00000100 /* Target Byte Swap */ | ||
27 | #define SH4_PCICR_PLUP 0x00000080 /* Enable PCI Pullup */ | ||
28 | #define SH4_PCICR_ARBM 0x00000040 /* PCI Arbitration Mode */ | ||
29 | #define SH4_PCICR_MD 0x00000030 /* MD9 and MD10 status */ | ||
30 | #define SH4_PCICR_SERR 0x00000008 /* SERR output assert */ | ||
31 | #define SH4_PCICR_INTA 0x00000004 /* INTA output assert */ | ||
32 | #define SH4_PCICR_PRST 0x00000002 /* PCI Reset Assert */ | ||
33 | #define SH4_PCICR_CFIN 0x00000001 /* Central Fun. Init Done */ | ||
34 | #define SH4_PCILSR0 0x104 /* PCI Local Space Register0 */ | ||
35 | #define SH4_PCILSR1 0x108 /* PCI Local Space Register1 */ | ||
36 | #define SH4_PCILAR0 0x10C /* PCI Local Addr Register1 */ | ||
37 | #define SH4_PCILAR1 0x110 /* PCI Local Addr Register1 */ | ||
38 | #define SH4_PCIINT 0x114 /* PCI Interrupt Register */ | ||
39 | #define SH4_PCIINT_MLCK 0x00008000 /* Master Lock Error */ | ||
40 | #define SH4_PCIINT_TABT 0x00004000 /* Target Abort Error */ | ||
41 | #define SH4_PCIINT_TRET 0x00000200 /* Target Retry Error */ | ||
42 | #define SH4_PCIINT_MFDE 0x00000100 /* Master Func. Disable Error */ | ||
43 | #define SH4_PCIINT_PRTY 0x00000080 /* Address Parity Error */ | ||
44 | #define SH4_PCIINT_SERR 0x00000040 /* SERR Detection Error */ | ||
45 | #define SH4_PCIINT_TWDP 0x00000020 /* Tgt. Write Parity Error */ | ||
46 | #define SH4_PCIINT_TRDP 0x00000010 /* Tgt. Read Parity Err Det. */ | ||
47 | #define SH4_PCIINT_MTABT 0x00000008 /* Master-Tgt. Abort Error */ | ||
48 | #define SH4_PCIINT_MMABT 0x00000004 /* Master-Master Abort Error */ | ||
49 | #define SH4_PCIINT_MWPD 0x00000002 /* Master Write PERR Detect */ | ||
50 | #define SH4_PCIINT_MRPD 0x00000001 /* Master Read PERR Detect */ | ||
51 | #define SH4_PCIINTM 0x118 /* PCI Interrupt Mask */ | ||
52 | #define SH4_PCIALR 0x11C /* Error Address Register */ | ||
53 | #define SH4_PCICLR 0x120 /* Error Command/Data */ | ||
54 | #define SH4_PCICLR_MPIO 0x80000000 | ||
55 | #define SH4_PCICLR_MDMA0 0x40000000 /* DMA0 Transfer Error */ | ||
56 | #define SH4_PCICLR_MDMA1 0x20000000 /* DMA1 Transfer Error */ | ||
57 | #define SH4_PCICLR_MDMA2 0x10000000 /* DMA2 Transfer Error */ | ||
58 | #define SH4_PCICLR_MDMA3 0x08000000 /* DMA3 Transfer Error */ | ||
59 | #define SH4_PCICLR_TGT 0x04000000 /* Target Transfer Error */ | ||
60 | #define SH4_PCICLR_CMDL 0x0000000F /* PCI Command at Error */ | ||
61 | #define SH4_PCIAINT 0x130 /* Arbiter Interrupt Register */ | ||
62 | #define SH4_PCIAINT_MBKN 0x00002000 /* Master Broken Interrupt */ | ||
63 | #define SH4_PCIAINT_TBTO 0x00001000 /* Target Bus Time Out */ | ||
64 | #define SH4_PCIAINT_MBTO 0x00001000 /* Master Bus Time Out */ | ||
65 | #define SH4_PCIAINT_TABT 0x00000008 /* Target Abort */ | ||
66 | #define SH4_PCIAINT_MABT 0x00000004 /* Master Abort */ | ||
67 | #define SH4_PCIAINT_RDPE 0x00000002 /* Read Data Parity Error */ | ||
68 | #define SH4_PCIAINT_WDPE 0x00000001 /* Write Data Parity Error */ | ||
69 | #define SH4_PCIAINTM 0x134 /* Arbiter Int. Mask Register */ | ||
70 | #define SH4_PCIBMLR 0x138 /* Error Bus Master Register */ | ||
71 | #define SH4_PCIBMLR_REQ4 0x00000010 /* REQ4 bus master at error */ | ||
72 | #define SH4_PCIBMLR_REQ3 0x00000008 /* REQ3 bus master at error */ | ||
73 | #define SH4_PCIBMLR_REQ2 0x00000004 /* REQ2 bus master at error */ | ||
74 | #define SH4_PCIBMLR_REQ1 0x00000002 /* REQ1 bus master at error */ | ||
75 | #define SH4_PCIBMLR_REQ0 0x00000001 /* REQ0 bus master at error */ | ||
76 | #define SH4_PCIDMABT 0x140 /* DMA Transfer Arb. Register */ | ||
77 | #define SH4_PCIDMABT_RRBN 0x00000001 /* DMA Arbitor Round-Robin */ | ||
78 | #define SH4_PCIDPA0 0x180 /* DMA0 Transfer Addr. */ | ||
79 | #define SH4_PCIDLA0 0x184 /* DMA0 Local Addr. */ | ||
80 | #define SH4_PCIDTC0 0x188 /* DMA0 Transfer Cnt. */ | ||
81 | #define SH4_PCIDCR0 0x18C /* DMA0 Control Register */ | ||
82 | #define SH4_PCIDCR_ALGN 0x00000600 /* DMA Alignment Mode */ | ||
83 | #define SH4_PCIDCR_MAST 0x00000100 /* DMA Termination Type */ | ||
84 | #define SH4_PCIDCR_INTM 0x00000080 /* DMA Interrupt Done Mask*/ | ||
85 | #define SH4_PCIDCR_INTS 0x00000040 /* DMA Interrupt Done Status */ | ||
86 | #define SH4_PCIDCR_LHLD 0x00000020 /* Local Address Control */ | ||
87 | #define SH4_PCIDCR_PHLD 0x00000010 /* PCI Address Control*/ | ||
88 | #define SH4_PCIDCR_IOSEL 0x00000008 /* PCI Address Space Type */ | ||
89 | #define SH4_PCIDCR_DIR 0x00000004 /* DMA Transfer Direction */ | ||
90 | #define SH4_PCIDCR_STOP 0x00000002 /* Force DMA Stop */ | ||
91 | #define SH4_PCIDCR_STRT 0x00000001 /* DMA Start */ | ||
92 | #define SH4_PCIDPA1 0x190 /* DMA1 Transfer Addr. */ | ||
93 | #define SH4_PCIDLA1 0x194 /* DMA1 Local Addr. */ | ||
94 | #define SH4_PCIDTC1 0x198 /* DMA1 Transfer Cnt. */ | ||
95 | #define SH4_PCIDCR1 0x19C /* DMA1 Control Register */ | ||
96 | #define SH4_PCIDPA2 0x1A0 /* DMA2 Transfer Addr. */ | ||
97 | #define SH4_PCIDLA2 0x1A4 /* DMA2 Local Addr. */ | ||
98 | #define SH4_PCIDTC2 0x1A8 /* DMA2 Transfer Cnt. */ | ||
99 | #define SH4_PCIDCR2 0x1AC /* DMA2 Control Register */ | ||
100 | #define SH4_PCIDPA3 0x1B0 /* DMA3 Transfer Addr. */ | ||
101 | #define SH4_PCIDLA3 0x1B4 /* DMA3 Local Addr. */ | ||
102 | #define SH4_PCIDTC3 0x1B8 /* DMA3 Transfer Cnt. */ | ||
103 | #define SH4_PCIDCR3 0x1BC /* DMA3 Control Register */ | ||
104 | #define SH4_PCIPAR 0x1C0 /* PIO Address Register */ | ||
105 | #define SH4_PCIPAR_CFGEN 0x80000000 /* Configuration Enable */ | ||
106 | #define SH4_PCIPAR_BUSNO 0x00FF0000 /* Config. Bus Number */ | ||
107 | #define SH4_PCIPAR_DEVNO 0x0000FF00 /* Config. Device Number */ | ||
108 | #define SH4_PCIPAR_REGAD 0x000000FC /* Register Address Number */ | ||
109 | #define SH4_PCIMBR 0x1C4 /* Memory Base Address */ | ||
110 | #define SH4_PCIMBR_MASK 0xFF000000 /* Memory Space Mask */ | ||
111 | #define SH4_PCIMBR_LOCK 0x00000001 /* Lock Memory Space */ | ||
112 | #define SH4_PCIIOBR 0x1C8 /* I/O Base Address Register */ | ||
113 | #define SH4_PCIIOBR_MASK 0xFFFC0000 /* IO Space Mask */ | ||
114 | #define SH4_PCIIOBR_LOCK 0x00000001 /* Lock IO Space */ | ||
115 | #define SH4_PCIPINT 0x1CC /* Power Mgmnt Int. Register */ | ||
116 | #define SH4_PCIPINT_D3 0x00000002 /* D3 Pwr Mgmt. Interrupt */ | ||
117 | #define SH4_PCIPINT_D0 0x00000001 /* D0 Pwr Mgmt. Interrupt */ | ||
118 | #define SH4_PCIPINTM 0x1D0 /* Power Mgmnt Mask Register */ | ||
119 | #define SH4_PCICLKR 0x1D4 /* Clock Ctrl. Register */ | ||
120 | #define SH4_PCICLKR_PCSTP 0x00000002 /* PCI Clock Stop */ | ||
121 | #define SH4_PCICLKR_BCSTP 0x00000001 /* BCLK Clock Stop */ | ||
122 | /* For definitions of BCR, MCR see ... */ | ||
123 | #define SH4_PCIBCR1 0x1E0 /* Memory BCR1 Register */ | ||
124 | #define SH4_PCIMBR0 SH4_PCIBCR1 | ||
125 | #define SH4_PCIBCR2 0x1E4 /* Memory BCR2 Register */ | ||
126 | #define SH4_PCIMBMR0 SH4_PCIBCR2 | ||
127 | #define SH4_PCIWCR1 0x1E8 /* Wait Control 1 Register */ | ||
128 | #define SH4_PCIWCR2 0x1EC /* Wait Control 2 Register */ | ||
129 | #define SH4_PCIWCR3 0x1F0 /* Wait Control 3 Register */ | ||
130 | #define SH4_PCIMBR2 SH4_PCIWCR3 | ||
131 | #define SH4_PCIMCR 0x1F4 /* Memory Control Register */ | ||
132 | #define SH4_PCIBCR3 0x1f8 /* Memory BCR3 Register */ | ||
133 | #define SH4_PCIPCTR 0x200 /* Port Control Register */ | ||
134 | #define SH4_PCIPCTR_P2EN 0x000400000 /* Port 2 Enable */ | ||
135 | #define SH4_PCIPCTR_P1EN 0x000200000 /* Port 1 Enable */ | ||
136 | #define SH4_PCIPCTR_P0EN 0x000100000 /* Port 0 Enable */ | ||
137 | #define SH4_PCIPCTR_P2UP 0x000000020 /* Port2 Pull Up Enable */ | ||
138 | #define SH4_PCIPCTR_P2IO 0x000000010 /* Port2 Output Enable */ | ||
139 | #define SH4_PCIPCTR_P1UP 0x000000008 /* Port1 Pull Up Enable */ | ||
140 | #define SH4_PCIPCTR_P1IO 0x000000004 /* Port1 Output Enable */ | ||
141 | #define SH4_PCIPCTR_P0UP 0x000000002 /* Port0 Pull Up Enable */ | ||
142 | #define SH4_PCIPCTR_P0IO 0x000000001 /* Port0 Output Enable */ | ||
143 | #define SH4_PCIPDTR 0x204 /* Port Data Register */ | ||
144 | #define SH4_PCIPDTR_PB5 0x000000020 /* Port 5 Enable */ | ||
145 | #define SH4_PCIPDTR_PB4 0x000000010 /* Port 4 Enable */ | ||
146 | #define SH4_PCIPDTR_PB3 0x000000008 /* Port 3 Enable */ | ||
147 | #define SH4_PCIPDTR_PB2 0x000000004 /* Port 2 Enable */ | ||
148 | #define SH4_PCIPDTR_PB1 0x000000002 /* Port 1 Enable */ | ||
149 | #define SH4_PCIPDTR_PB0 0x000000001 /* Port 0 Enable */ | ||
150 | #define SH4_PCIPDR 0x220 /* Port IO Data Register */ | ||
151 | |||
152 | /* Flags */ | ||
153 | #define SH4_PCIC_NO_RESET 0x0001 | ||
154 | |||
155 | /* arch/sh/kernel/drivers/pci/ops-sh4.c */ | ||
156 | extern struct pci_ops sh4_pci_ops; | ||
157 | int sh4_pci_check_direct(void); | ||
158 | int pci_fixup_pcic(void); | ||
159 | |||
160 | struct sh4_pci_address_space { | ||
161 | unsigned long base; | ||
162 | unsigned long size; | ||
163 | }; | ||
164 | |||
165 | struct sh4_pci_address_map { | ||
166 | struct sh4_pci_address_space window0; | ||
167 | struct sh4_pci_address_space window1; | ||
168 | unsigned long flags; | ||
169 | }; | ||
170 | |||
171 | static inline void pci_write_reg(unsigned long val, unsigned long reg) | ||
172 | { | ||
173 | outl(val, PCI_REG(reg)); | ||
174 | } | ||
175 | |||
176 | static inline unsigned long pci_read_reg(unsigned long reg) | ||
177 | { | ||
178 | return inl(PCI_REG(reg)); | ||
179 | } | ||
180 | #endif /* __PCI_SH4_H */ | ||
diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 682f3dae305d..dbe837884983 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c | |||
@@ -15,180 +15,14 @@ | |||
15 | 15 | ||
16 | #undef DEBUG | 16 | #undef DEBUG |
17 | 17 | ||
18 | #include <linux/types.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | 18 | #include <linux/init.h> |
21 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
22 | #include <linux/sched.h> | 20 | #include <linux/types.h> |
23 | #include <linux/ioport.h> | ||
24 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
25 | #include <linux/irq.h> | ||
26 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
27 | 23 | #include "pci-sh4.h" | |
28 | #include <asm/machvec.h> | 24 | #include <asm/addrspace.h> |
29 | #include <asm/io.h> | 25 | #include <asm/io.h> |
30 | #include "pci-sh7751.h" | ||
31 | |||
32 | static unsigned int pci_probe = PCI_PROBE_CONF1; | ||
33 | extern int pci_fixup_pcic(void); | ||
34 | |||
35 | void pcibios_fixup_irqs(void) __attribute__ ((weak)); | ||
36 | |||
37 | /* | ||
38 | * Direct access to PCI hardware... | ||
39 | */ | ||
40 | |||
41 | #define CONFIG_CMD(bus, devfn, where) (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) | ||
42 | |||
43 | /* | ||
44 | * Functions for accessing PCI configuration space with type 1 accesses | ||
45 | */ | ||
46 | static int sh7751_pci_read(struct pci_bus *bus, unsigned int devfn, | ||
47 | int where, int size, u32 *val) | ||
48 | { | ||
49 | unsigned long flags; | ||
50 | u32 data; | ||
51 | |||
52 | /* | ||
53 | * PCIPDR may only be accessed as 32 bit words, | ||
54 | * so we must do byte alignment by hand | ||
55 | */ | ||
56 | local_irq_save(flags); | ||
57 | outl(CONFIG_CMD(bus,devfn,where), PCI_REG(SH7751_PCIPAR)); | ||
58 | data = inl(PCI_REG(SH7751_PCIPDR)); | ||
59 | local_irq_restore(flags); | ||
60 | |||
61 | switch (size) { | ||
62 | case 1: | ||
63 | *val = (data >> ((where & 3) << 3)) & 0xff; | ||
64 | break; | ||
65 | case 2: | ||
66 | *val = (data >> ((where & 2) << 3)) & 0xffff; | ||
67 | break; | ||
68 | case 4: | ||
69 | *val = data; | ||
70 | break; | ||
71 | default: | ||
72 | return PCIBIOS_FUNC_NOT_SUPPORTED; | ||
73 | } | ||
74 | |||
75 | return PCIBIOS_SUCCESSFUL; | ||
76 | } | ||
77 | |||
78 | /* | ||
79 | * Since SH7751 only does 32bit access we'll have to do a read, | ||
80 | * mask,write operation. | ||
81 | * We'll allow an odd byte offset, though it should be illegal. | ||
82 | */ | ||
83 | static int sh7751_pci_write(struct pci_bus *bus, unsigned int devfn, | ||
84 | int where, int size, u32 val) | ||
85 | { | ||
86 | unsigned long flags; | ||
87 | int shift; | ||
88 | u32 data; | ||
89 | |||
90 | local_irq_save(flags); | ||
91 | outl(CONFIG_CMD(bus,devfn,where), PCI_REG(SH7751_PCIPAR)); | ||
92 | data = inl(PCI_REG(SH7751_PCIPDR)); | ||
93 | local_irq_restore(flags); | ||
94 | |||
95 | switch (size) { | ||
96 | case 1: | ||
97 | shift = (where & 3) << 3; | ||
98 | data &= ~(0xff << shift); | ||
99 | data |= ((val & 0xff) << shift); | ||
100 | break; | ||
101 | case 2: | ||
102 | shift = (where & 2) << 3; | ||
103 | data &= ~(0xffff << shift); | ||
104 | data |= ((val & 0xffff) << shift); | ||
105 | break; | ||
106 | case 4: | ||
107 | data = val; | ||
108 | break; | ||
109 | default: | ||
110 | return PCIBIOS_FUNC_NOT_SUPPORTED; | ||
111 | } | ||
112 | |||
113 | outl(data, PCI_REG(SH7751_PCIPDR)); | ||
114 | |||
115 | return PCIBIOS_SUCCESSFUL; | ||
116 | } | ||
117 | |||
118 | #undef CONFIG_CMD | ||
119 | |||
120 | struct pci_ops sh7751_pci_ops = { | ||
121 | .read = sh7751_pci_read, | ||
122 | .write = sh7751_pci_write, | ||
123 | }; | ||
124 | |||
125 | static int __init pci_check_direct(void) | ||
126 | { | ||
127 | unsigned int tmp, id; | ||
128 | |||
129 | /* check for SH7751/SH7751R hardware */ | ||
130 | id = inl(SH7751_PCIREG_BASE+SH7751_PCICONF0); | ||
131 | if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) && | ||
132 | id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) { | ||
133 | pr_debug("PCI: This is not an SH7751(R) (%x)\n", id); | ||
134 | return -ENODEV; | ||
135 | } | ||
136 | |||
137 | /* | ||
138 | * Check if configuration works. | ||
139 | */ | ||
140 | if (pci_probe & PCI_PROBE_CONF1) { | ||
141 | tmp = inl (PCI_REG(SH7751_PCIPAR)); | ||
142 | outl (0x80000000, PCI_REG(SH7751_PCIPAR)); | ||
143 | if (inl (PCI_REG(SH7751_PCIPAR)) == 0x80000000) { | ||
144 | outl (tmp, PCI_REG(SH7751_PCIPAR)); | ||
145 | printk(KERN_INFO "PCI: Using configuration type 1\n"); | ||
146 | request_region(PCI_REG(SH7751_PCIPAR), 8, "PCI conf1"); | ||
147 | return 0; | ||
148 | } | ||
149 | outl (tmp, PCI_REG(SH7751_PCIPAR)); | ||
150 | } | ||
151 | |||
152 | pr_debug("PCI: pci_check_direct failed\n"); | ||
153 | return -EINVAL; | ||
154 | } | ||
155 | |||
156 | /***************************************************************************************/ | ||
157 | |||
158 | /* | ||
159 | * Handle bus scanning and fixups .... | ||
160 | */ | ||
161 | |||
162 | static void __init pci_fixup_ide_bases(struct pci_dev *d) | ||
163 | { | ||
164 | int i; | ||
165 | |||
166 | /* | ||
167 | * PCI IDE controllers use non-standard I/O port decoding, respect it. | ||
168 | */ | ||
169 | if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE) | ||
170 | return; | ||
171 | pr_debug("PCI: IDE base address fixup for %s\n", pci_name(d)); | ||
172 | for(i=0; i<4; i++) { | ||
173 | struct resource *r = &d->resource[i]; | ||
174 | if ((r->start & ~0x80) == 0x374) { | ||
175 | r->start |= 2; | ||
176 | r->end = r->start; | ||
177 | } | ||
178 | } | ||
179 | } | ||
180 | |||
181 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); | ||
182 | |||
183 | /* | ||
184 | * Called after each bus is probed, but before its children | ||
185 | * are examined. | ||
186 | */ | ||
187 | |||
188 | void __init pcibios_fixup_bus(struct pci_bus *b) | ||
189 | { | ||
190 | pci_read_bridge_bases(b); | ||
191 | } | ||
192 | 26 | ||
193 | /* | 27 | /* |
194 | * Initialization. Try all known PCI access methods. Note that we support | 28 | * Initialization. Try all known PCI access methods. Note that we support |
@@ -196,25 +30,29 @@ void __init pcibios_fixup_bus(struct pci_bus *b) | |||
196 | * to access config space. | 30 | * to access config space. |
197 | * | 31 | * |
198 | * Note that the platform specific initialization (BSC registers, and memory | 32 | * Note that the platform specific initialization (BSC registers, and memory |
199 | * space mapping) will be called via the machine vectors (sh_mv.mv_pci_init()) if it | 33 | * space mapping) will be called via the platform defined function |
200 | * exitst and via the platform defined function pcibios_init_platform(). | 34 | * pcibios_init_platform(). |
201 | * See pci_bigsur.c for implementation; | ||
202 | * | ||
203 | * The BIOS version of the pci functions is not yet implemented but it is left | ||
204 | * in for completeness. Currently an error will be genereated at compile time. | ||
205 | */ | 35 | */ |
206 | |||
207 | static int __init sh7751_pci_init(void) | 36 | static int __init sh7751_pci_init(void) |
208 | { | 37 | { |
38 | unsigned int id; | ||
209 | int ret; | 39 | int ret; |
210 | 40 | ||
211 | pr_debug("PCI: Starting intialization.\n"); | 41 | pr_debug("PCI: Starting intialization.\n"); |
212 | if ((ret = pci_check_direct()) != 0) | 42 | |
43 | /* check for SH7751/SH7751R hardware */ | ||
44 | id = pci_read_reg(SH7751_PCICONF0); | ||
45 | if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) && | ||
46 | id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) { | ||
47 | pr_debug("PCI: This is not an SH7751(R) (%x)\n", id); | ||
48 | return -ENODEV; | ||
49 | } | ||
50 | |||
51 | if ((ret = sh4_pci_check_direct()) != 0) | ||
213 | return ret; | 52 | return ret; |
214 | 53 | ||
215 | return pcibios_init_platform(); | 54 | return pcibios_init_platform(); |
216 | } | 55 | } |
217 | |||
218 | subsys_initcall(sh7751_pci_init); | 56 | subsys_initcall(sh7751_pci_init); |
219 | 57 | ||
220 | static int __init __area_sdram_check(unsigned int area) | 58 | static int __init __area_sdram_check(unsigned int area) |
@@ -223,26 +61,26 @@ static int __init __area_sdram_check(unsigned int area) | |||
223 | 61 | ||
224 | word = inl(SH7751_BCR1); | 62 | word = inl(SH7751_BCR1); |
225 | /* check BCR for SDRAM in area */ | 63 | /* check BCR for SDRAM in area */ |
226 | if(((word >> area) & 1) == 0) { | 64 | if (((word >> area) & 1) == 0) { |
227 | printk("PCI: Area %d is not configured for SDRAM. BCR1=0x%x\n", | 65 | printk("PCI: Area %d is not configured for SDRAM. BCR1=0x%x\n", |
228 | area, word); | 66 | area, word); |
229 | return 0; | 67 | return 0; |
230 | } | 68 | } |
231 | outl(word, PCI_REG(SH7751_PCIBCR1)); | 69 | pci_write_reg(word, SH4_PCIBCR1); |
232 | 70 | ||
233 | word = (u16)inw(SH7751_BCR2); | 71 | word = (u16)inw(SH7751_BCR2); |
234 | /* check BCR2 for 32bit SDRAM interface*/ | 72 | /* check BCR2 for 32bit SDRAM interface*/ |
235 | if(((word >> (area << 1)) & 0x3) != 0x3) { | 73 | if (((word >> (area << 1)) & 0x3) != 0x3) { |
236 | printk("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%x\n", | 74 | printk("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%x\n", |
237 | area, word); | 75 | area, word); |
238 | return 0; | 76 | return 0; |
239 | } | 77 | } |
240 | outl(word, PCI_REG(SH7751_PCIBCR2)); | 78 | pci_write_reg(word, SH4_PCIBCR2); |
241 | 79 | ||
242 | return 1; | 80 | return 1; |
243 | } | 81 | } |
244 | 82 | ||
245 | int __init sh7751_pcic_init(struct sh7751_pci_address_map *map) | 83 | int __init sh7751_pcic_init(struct sh4_pci_address_map *map) |
246 | { | 84 | { |
247 | u32 reg; | 85 | u32 reg; |
248 | u32 word; | 86 | u32 word; |
@@ -251,39 +89,39 @@ int __init sh7751_pcic_init(struct sh7751_pci_address_map *map) | |||
251 | reg = inl(SH7751_BCR1); | 89 | reg = inl(SH7751_BCR1); |
252 | reg |= 0x80000; | 90 | reg |= 0x80000; |
253 | outl(reg, SH7751_BCR1); | 91 | outl(reg, SH7751_BCR1); |
254 | 92 | ||
255 | /* Turn the clocks back on (not done in reset)*/ | 93 | /* Turn the clocks back on (not done in reset)*/ |
256 | outl(0, PCI_REG(SH7751_PCICLKR)); | 94 | pci_write_reg(0, SH4_PCICLKR); |
257 | /* Clear Powerdown IRQ's (not done in reset) */ | 95 | /* Clear Powerdown IRQ's (not done in reset) */ |
258 | word = SH7751_PCIPINT_D3 | SH7751_PCIPINT_D0; | 96 | word = SH4_PCIPINT_D3 | SH4_PCIPINT_D0; |
259 | outl(word, PCI_REG(SH7751_PCIPINT)); | 97 | pci_write_reg(word, SH4_PCIPINT); |
260 | 98 | ||
261 | /* | 99 | /* |
262 | * This code is unused for some boards as it is done in the | 100 | * This code is unused for some boards as it is done in the |
263 | * bootloader and doing it here means the MAC addresses loaded | 101 | * bootloader and doing it here means the MAC addresses loaded |
264 | * by the bootloader get lost. | 102 | * by the bootloader get lost. |
265 | */ | 103 | */ |
266 | if (!(map->flags & SH7751_PCIC_NO_RESET)) { | 104 | if (!(map->flags & SH4_PCIC_NO_RESET)) { |
267 | /* toggle PCI reset pin */ | 105 | /* toggle PCI reset pin */ |
268 | word = SH7751_PCICR_PREFIX | SH7751_PCICR_PRST; | 106 | word = SH4_PCICR_PREFIX | SH4_PCICR_PRST; |
269 | outl(word,PCI_REG(SH7751_PCICR)); | 107 | pci_write_reg(word, SH4_PCICR); |
270 | /* Wait for a long time... not 1 sec. but long enough */ | 108 | /* Wait for a long time... not 1 sec. but long enough */ |
271 | mdelay(100); | 109 | mdelay(100); |
272 | word = SH7751_PCICR_PREFIX; | 110 | word = SH4_PCICR_PREFIX; |
273 | outl(word,PCI_REG(SH7751_PCICR)); | 111 | pci_write_reg(word, SH4_PCICR); |
274 | } | 112 | } |
275 | 113 | ||
276 | /* set the command/status bits to: | 114 | /* set the command/status bits to: |
277 | * Wait Cycle Control + Parity Enable + Bus Master + | 115 | * Wait Cycle Control + Parity Enable + Bus Master + |
278 | * Mem space enable | 116 | * Mem space enable |
279 | */ | 117 | */ |
280 | word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER | | 118 | word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER | |
281 | SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES; | 119 | SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES; |
282 | outl(word, PCI_REG(SH7751_PCICONF1)); | 120 | pci_write_reg(word, SH7751_PCICONF1); |
283 | 121 | ||
284 | /* define this host as the host bridge */ | 122 | /* define this host as the host bridge */ |
285 | word = SH7751_PCI_HOST_BRIDGE << 24; | 123 | word = PCI_BASE_CLASS_BRIDGE << 24; |
286 | outl(word, PCI_REG(SH7751_PCICONF2)); | 124 | pci_write_reg(word, SH7751_PCICONF2); |
287 | 125 | ||
288 | /* Set IO and Mem windows to local address | 126 | /* Set IO and Mem windows to local address |
289 | * Make PCI and local address the same for easy 1 to 1 mapping | 127 | * Make PCI and local address the same for easy 1 to 1 mapping |
@@ -291,46 +129,49 @@ int __init sh7751_pcic_init(struct sh7751_pci_address_map *map) | |||
291 | * Window1 = map->window1.size @ cached area base = SDRAM | 129 | * Window1 = map->window1.size @ cached area base = SDRAM |
292 | */ | 130 | */ |
293 | word = map->window0.size - 1; | 131 | word = map->window0.size - 1; |
294 | outl(word, PCI_REG(SH7751_PCILSR0)); | 132 | pci_write_reg(word, SH4_PCILSR0); |
295 | word = map->window1.size - 1; | 133 | word = map->window1.size - 1; |
296 | outl(word, PCI_REG(SH7751_PCILSR1)); | 134 | pci_write_reg(word, SH4_PCILSR1); |
297 | /* Set the values on window 0 PCI config registers */ | 135 | /* Set the values on window 0 PCI config registers */ |
298 | word = P2SEGADDR(map->window0.base); | 136 | word = P2SEGADDR(map->window0.base); |
299 | outl(word, PCI_REG(SH7751_PCILAR0)); | 137 | pci_write_reg(word, SH4_PCILAR0); |
300 | outl(word, PCI_REG(SH7751_PCICONF5)); | 138 | pci_write_reg(word, SH7751_PCICONF5); |
301 | /* Set the values on window 1 PCI config registers */ | 139 | /* Set the values on window 1 PCI config registers */ |
302 | word = PHYSADDR(map->window1.base); | 140 | word = PHYSADDR(map->window1.base); |
303 | outl(word, PCI_REG(SH7751_PCILAR1)); | 141 | pci_write_reg(word, SH4_PCILAR1); |
304 | outl(word, PCI_REG(SH7751_PCICONF6)); | 142 | pci_write_reg(word, SH7751_PCICONF6); |
305 | 143 | ||
306 | /* Set the local 16MB PCI memory space window to | 144 | /* Set the local 16MB PCI memory space window to |
307 | * the lowest PCI mapped address | 145 | * the lowest PCI mapped address |
308 | */ | 146 | */ |
309 | word = PCIBIOS_MIN_MEM & SH7751_PCIMBR_MASK; | 147 | word = PCIBIOS_MIN_MEM & SH4_PCIMBR_MASK; |
310 | PCIDBG(2,"PCI: Setting upper bits of Memory window to 0x%x\n", word); | 148 | pr_debug("PCI: Setting upper bits of Memory window to 0x%x\n", word); |
311 | outl(word , PCI_REG(SH7751_PCIMBR)); | 149 | pci_write_reg(word , SH4_PCIMBR); |
312 | 150 | ||
313 | /* Map IO space into PCI IO window | 151 | /* Map IO space into PCI IO window |
314 | * The IO window is 64K-PCIBIOS_MIN_IO in size | 152 | * The IO window is 64K-PCIBIOS_MIN_IO in size |
315 | * IO addresses will be translated to the | 153 | * IO addresses will be translated to the |
316 | * PCI IO window base address | 154 | * PCI IO window base address |
317 | */ | 155 | */ |
318 | PCIDBG(3,"PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", PCIBIOS_MIN_IO, | 156 | pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", |
319 | (64*1024), SH7751_PCI_IO_BASE+PCIBIOS_MIN_IO); | 157 | PCIBIOS_MIN_IO, (64 << 10), |
158 | SH4_PCI_IO_BASE + PCIBIOS_MIN_IO); | ||
320 | 159 | ||
321 | /* | 160 | /* |
322 | * XXX: For now, leave this board-specific. In the event we have other | 161 | * XXX: For now, leave this board-specific. In the event we have other |
323 | * boards that need to do similar work, this can be wrapped. | 162 | * boards that need to do similar work, this can be wrapped. |
324 | */ | 163 | */ |
325 | #ifdef CONFIG_SH_BIGSUR | 164 | #ifdef CONFIG_SH_BIGSUR |
326 | bigsur_port_map(PCIBIOS_MIN_IO, (64*1024), SH7751_PCI_IO_BASE+PCIBIOS_MIN_IO,0); | 165 | bigsur_port_map(PCIBIOS_MIN_IO, (64 << 10), |
166 | SH4_PCI_IO_BASE + PCIBIOS_MIN_IO, 0); | ||
327 | #endif | 167 | #endif |
328 | 168 | ||
329 | /* Make sure the MSB's of IO window are set to access PCI space correctly */ | 169 | /* Make sure the MSB's of IO window are set to access PCI space |
330 | word = PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK; | 170 | * correctly */ |
331 | PCIDBG(2,"PCI: Setting upper bits of IO window to 0x%x\n", word); | 171 | word = PCIBIOS_MIN_IO & SH4_PCIIOBR_MASK; |
332 | outl(word, PCI_REG(SH7751_PCIIOBR)); | 172 | pr_debug("PCI: Setting upper bits of IO window to 0x%x\n", word); |
333 | 173 | pci_write_reg(word, SH4_PCIIOBR); | |
174 | |||
334 | /* Set PCI WCRx, BCRx's, copy from BSC locations */ | 175 | /* Set PCI WCRx, BCRx's, copy from BSC locations */ |
335 | 176 | ||
336 | /* check BCR for SDRAM in specified area */ | 177 | /* check BCR for SDRAM in specified area */ |
@@ -349,13 +190,13 @@ int __init sh7751_pcic_init(struct sh7751_pci_address_map *map) | |||
349 | 190 | ||
350 | /* configure the wait control registers */ | 191 | /* configure the wait control registers */ |
351 | word = inl(SH7751_WCR1); | 192 | word = inl(SH7751_WCR1); |
352 | outl(word, PCI_REG(SH7751_PCIWCR1)); | 193 | pci_write_reg(word, SH4_PCIWCR1); |
353 | word = inl(SH7751_WCR2); | 194 | word = inl(SH7751_WCR2); |
354 | outl(word, PCI_REG(SH7751_PCIWCR2)); | 195 | pci_write_reg(word, SH4_PCIWCR2); |
355 | word = inl(SH7751_WCR3); | 196 | word = inl(SH7751_WCR3); |
356 | outl(word, PCI_REG(SH7751_PCIWCR3)); | 197 | pci_write_reg(word, SH4_PCIWCR3); |
357 | word = inl(SH7751_MCR); | 198 | word = inl(SH7751_MCR); |
358 | outl(word, PCI_REG(SH7751_PCIMCR)); | 199 | pci_write_reg(word, SH4_PCIMCR); |
359 | 200 | ||
360 | /* NOTE: I'm ignoring the PCI error IRQs for now.. | 201 | /* NOTE: I'm ignoring the PCI error IRQs for now.. |
361 | * TODO: add support for the internal error interrupts and | 202 | * TODO: add support for the internal error interrupts and |
@@ -368,49 +209,8 @@ int __init sh7751_pcic_init(struct sh7751_pci_address_map *map) | |||
368 | 209 | ||
369 | /* SH7751 init done, set central function init complete */ | 210 | /* SH7751 init done, set central function init complete */ |
370 | /* use round robin mode to stop a device starving/overruning */ | 211 | /* use round robin mode to stop a device starving/overruning */ |
371 | word = SH7751_PCICR_PREFIX | SH7751_PCICR_CFIN | SH7751_PCICR_ARBM; | 212 | word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM; |
372 | outl(word,PCI_REG(SH7751_PCICR)); | 213 | pci_write_reg(word, SH4_PCICR); |
373 | 214 | ||
374 | return 1; | 215 | return 1; |
375 | } | 216 | } |
376 | |||
377 | char * __init pcibios_setup(char *str) | ||
378 | { | ||
379 | if (!strcmp(str, "off")) { | ||
380 | pci_probe = 0; | ||
381 | return NULL; | ||
382 | } | ||
383 | |||
384 | return str; | ||
385 | } | ||
386 | |||
387 | /* | ||
388 | * IRQ functions | ||
389 | */ | ||
390 | static u8 __init sh7751_no_swizzle(struct pci_dev *dev, u8 *pin) | ||
391 | { | ||
392 | /* no swizzling */ | ||
393 | return PCI_SLOT(dev->devfn); | ||
394 | } | ||
395 | |||
396 | static int sh7751_pci_lookup_irq(struct pci_dev *dev, u8 slot, u8 pin) | ||
397 | { | ||
398 | int irq = -1; | ||
399 | |||
400 | /* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */ | ||
401 | irq = pcibios_map_platform_irq(slot,pin); | ||
402 | if( irq < 0 ) { | ||
403 | pr_debug("PCI: Error mapping IRQ on device %s\n", pci_name(dev)); | ||
404 | return irq; | ||
405 | } | ||
406 | |||
407 | pr_debug("Setting IRQ for slot %s to %d\n", pci_name(dev), irq); | ||
408 | |||
409 | return irq; | ||
410 | } | ||
411 | |||
412 | void __init pcibios_fixup_irqs(void) | ||
413 | { | ||
414 | pci_fixup_irqs(sh7751_no_swizzle, sh7751_pci_lookup_irq); | ||
415 | } | ||
416 | |||
diff --git a/arch/sh/drivers/pci/pci-sh7751.h b/arch/sh/drivers/pci/pci-sh7751.h index 1fee5cae10d1..68e3cb5e6bec 100644 --- a/arch/sh/drivers/pci/pci-sh7751.h +++ b/arch/sh/drivers/pci/pci-sh7751.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Dustin McIntire (dustin@sensoria.com) (c) 2001 | 4 | * Dustin McIntire (dustin@sensoria.com) (c) 2001 |
5 | * Paul Mundt (lethal@linux-sh.org) (c) 2003 | 5 | * Paul Mundt (lethal@linux-sh.org) (c) 2003 |
6 | * | 6 | * |
7 | * May be copied or modified under the terms of the GNU General Public | 7 | * May be copied or modified under the terms of the GNU General Public |
8 | * License. See linux/COPYING for more information. | 8 | * License. See linux/COPYING for more information. |
9 | * | 9 | * |
@@ -12,28 +12,6 @@ | |||
12 | #ifndef _PCI_SH7751_H_ | 12 | #ifndef _PCI_SH7751_H_ |
13 | #define _PCI_SH7751_H_ | 13 | #define _PCI_SH7751_H_ |
14 | 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 */ | 15 | /* Platform Specific Values */ |
38 | #define SH7751_VENDOR_ID 0x1054 | 16 | #define SH7751_VENDOR_ID 0x1054 |
39 | #define SH7751_DEVICE_ID 0x3505 | 17 | #define SH7751_DEVICE_ID 0x3505 |
@@ -128,131 +106,6 @@ | |||
128 | #define SH7751_PCICONF17_PMEN 0x00010000 /* PME Enable */ | 106 | #define SH7751_PCICONF17_PMEN 0x00010000 /* PME Enable */ |
129 | #define SH7751_PCICONF17_PWST 0x00000003 /* Power State */ | 107 | #define SH7751_PCICONF17_PWST 0x00000003 /* Power State */ |
130 | /* SH7715 Internal PCI Registers */ | 108 | /* 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 | 109 | ||
257 | /* Memory Control Registers */ | 110 | /* Memory Control Registers */ |
258 | #define SH7751_BCR1 0xFF800000 /* Memory BCR1 Register */ | 111 | #define SH7751_BCR1 0xFF800000 /* Memory BCR1 Register */ |
@@ -274,30 +127,9 @@ | |||
274 | #define SH7751_CS5_BASE_ADDR (SH7751_CS4_BASE_ADDR + SH7751_MEM_REGION_SIZE) | 127 | #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) | 128 | #define SH7751_CS6_BASE_ADDR (SH7751_CS5_BASE_ADDR + SH7751_MEM_REGION_SIZE) |
276 | 129 | ||
277 | /* General PCI values */ | 130 | struct sh4_pci_address_map; |
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... */ | ||
285 | extern int pcibios_init_platform(void); | ||
286 | extern int pcibios_map_platform_irq(u8 slot, u8 pin); | ||
287 | |||
288 | struct sh7751_pci_address_space { | ||
289 | unsigned long base; | ||
290 | unsigned long size; | ||
291 | }; | ||
292 | |||
293 | struct sh7751_pci_address_map { | ||
294 | struct sh7751_pci_address_space window0; | ||
295 | struct sh7751_pci_address_space window1; | ||
296 | unsigned long flags; | ||
297 | }; | ||
298 | 131 | ||
299 | /* arch/sh/drivers/pci/pci-sh7751.c */ | 132 | /* arch/sh/drivers/pci/pci-sh7751.c */ |
300 | extern int sh7751_pcic_init(struct sh7751_pci_address_map *map); | 133 | int sh7751_pcic_init(struct sh4_pci_address_map *map); |
301 | 134 | ||
302 | #endif /* _PCI_SH7751_H_ */ | 135 | #endif /* _PCI_SH7751_H_ */ |
303 | |||
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c new file mode 100644 index 000000000000..bd3064a82087 --- /dev/null +++ b/arch/sh/drivers/pci/pci-sh7780.c | |||
@@ -0,0 +1,139 @@ | |||
1 | /* | ||
2 | * Low-Level PCI Support for the SH7780 | ||
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/errno.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include "pci-sh4.h" | ||
26 | |||
27 | /* | ||
28 | * Initialization. Try all known PCI access methods. Note that we support | ||
29 | * using both PCI BIOS and direct access: in such cases, we use I/O ports | ||
30 | * to access config space. | ||
31 | * | ||
32 | * Note that the platform specific initialization (BSC registers, and memory | ||
33 | * space mapping) will be called via the platform defined function | ||
34 | * pcibios_init_platform(). | ||
35 | */ | ||
36 | static int __init sh7780_pci_init(void) | ||
37 | { | ||
38 | unsigned int id; | ||
39 | int ret; | ||
40 | |||
41 | pr_debug("PCI: Starting intialization.\n"); | ||
42 | |||
43 | outl(0x00000001, SH7780_PCI_VCR2); /* Enable PCIC */ | ||
44 | |||
45 | /* check for SH7780/SH7780R hardware */ | ||
46 | id = pci_read_reg(SH7780_PCIVID); | ||
47 | if ((id != ((SH7780_DEVICE_ID << 16) | SH7780_VENDOR_ID)) && | ||
48 | (id != ((SH7781_DEVICE_ID << 16) | SH7780_VENDOR_ID))) { | ||
49 | printk(KERN_ERR "PCI: This is not an SH7780 (%x)\n", id); | ||
50 | return -ENODEV; | ||
51 | } | ||
52 | |||
53 | /* Setup the INTC */ | ||
54 | ctrl_outl(0x00200000, INTC_ICR0); /* INTC SH-4 Mode */ | ||
55 | ctrl_outl(0x00078000, INTC_INT2MSKCR); /* enable PCIINTA - PCIINTD */ | ||
56 | ctrl_outl(0x40000000, INTC_INTMSK1); /* disable IRL4-7 Interrupt */ | ||
57 | ctrl_outl(0x0000fffe, INTC_INTMSK2); /* disable IRL4-7 Interrupt */ | ||
58 | ctrl_outl(0x80000000, INTC_INTMSKCLR1); /* enable IRL0-3 Interrupt */ | ||
59 | ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); /* enable IRL0-3 Interrupt */ | ||
60 | |||
61 | if ((ret = sh4_pci_check_direct()) != 0) | ||
62 | return ret; | ||
63 | |||
64 | return pcibios_init_platform(); | ||
65 | } | ||
66 | core_initcall(sh7780_pci_init); | ||
67 | |||
68 | int __init sh7780_pcic_init(struct sh4_pci_address_map *map) | ||
69 | { | ||
70 | u32 word; | ||
71 | |||
72 | /* | ||
73 | * This code is unused for some boards as it is done in the | ||
74 | * bootloader and doing it here means the MAC addresses loaded | ||
75 | * by the bootloader get lost. | ||
76 | */ | ||
77 | if (!(map->flags & SH4_PCIC_NO_RESET)) { | ||
78 | /* toggle PCI reset pin */ | ||
79 | word = SH4_PCICR_PREFIX | SH4_PCICR_PRST; | ||
80 | pci_write_reg(word, SH4_PCICR); | ||
81 | /* Wait for a long time... not 1 sec. but long enough */ | ||
82 | mdelay(100); | ||
83 | word = SH4_PCICR_PREFIX; | ||
84 | pci_write_reg(word, SH4_PCICR); | ||
85 | } | ||
86 | |||
87 | /* set the command/status bits to: | ||
88 | * Wait Cycle Control + Parity Enable + Bus Master + | ||
89 | * Mem space enable | ||
90 | */ | ||
91 | pci_write_reg(0x00000046, SH7780_PCICMD); | ||
92 | |||
93 | /* define this host as the host bridge */ | ||
94 | word = PCI_BASE_CLASS_BRIDGE << 24; | ||
95 | pci_write_reg(word, SH7780_PCIRID); | ||
96 | |||
97 | /* Set IO and Mem windows to local address | ||
98 | * Make PCI and local address the same for easy 1 to 1 mapping | ||
99 | * Window0 = map->window0.size @ non-cached area base = SDRAM | ||
100 | * Window1 = map->window1.size @ cached area base = SDRAM | ||
101 | */ | ||
102 | word = ((map->window0.size - 1) & 0x1ff00001) | 0x01; | ||
103 | pci_write_reg(0x07f00001, SH4_PCILSR0); | ||
104 | word = ((map->window1.size - 1) & 0x1ff00001) | 0x01; | ||
105 | pci_write_reg(0x00000001, SH4_PCILSR1); | ||
106 | /* Set the values on window 0 PCI config registers */ | ||
107 | word = P2SEGADDR(map->window0.base); | ||
108 | pci_write_reg(0xa8000000, SH4_PCILAR0); | ||
109 | pci_write_reg(0x08000000, SH7780_PCIMBAR0); | ||
110 | /* Set the values on window 1 PCI config registers */ | ||
111 | word = P2SEGADDR(map->window1.base); | ||
112 | pci_write_reg(0x00000000, SH4_PCILAR1); | ||
113 | pci_write_reg(0x00000000, SH7780_PCIMBAR1); | ||
114 | |||
115 | /* Map IO space into PCI IO window | ||
116 | * The IO window is 64K-PCIBIOS_MIN_IO in size | ||
117 | * IO addresses will be translated to the | ||
118 | * PCI IO window base address | ||
119 | */ | ||
120 | pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", | ||
121 | PCIBIOS_MIN_IO, (64 << 10), | ||
122 | SH7780_PCI_IO_BASE + PCIBIOS_MIN_IO); | ||
123 | |||
124 | /* NOTE: I'm ignoring the PCI error IRQs for now.. | ||
125 | * TODO: add support for the internal error interrupts and | ||
126 | * DMA interrupts... | ||
127 | */ | ||
128 | |||
129 | #ifdef CONFIG_SH_R7780RP | ||
130 | pci_fixup_pcic(); | ||
131 | #endif | ||
132 | |||
133 | /* SH7780 init done, set central function init complete */ | ||
134 | /* use round robin mode to stop a device starving/overruning */ | ||
135 | word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO; | ||
136 | pci_write_reg(word, SH4_PCICR); | ||
137 | |||
138 | return 1; | ||
139 | } | ||
diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h new file mode 100644 index 000000000000..f02d2180a4bc --- /dev/null +++ b/arch/sh/drivers/pci/pci-sh7780.h | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * Low-Level PCI Support for SH7780 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_SH7780_H_ | ||
13 | #define _PCI_SH7780_H_ | ||
14 | |||
15 | /* Platform Specific Values */ | ||
16 | #define SH7780_VENDOR_ID 0x1912 | ||
17 | #define SH7780_DEVICE_ID 0x0002 | ||
18 | #define SH7781_DEVICE_ID 0x0001 | ||
19 | |||
20 | /* SH7780 Control Registers */ | ||
21 | #define SH7780_PCI_VCR0 0xFE000000 | ||
22 | #define SH7780_PCI_VCR1 0xFE000004 | ||
23 | #define SH7780_PCI_VCR2 0xFE000008 | ||
24 | |||
25 | /* SH7780 Specific Values */ | ||
26 | #define SH7780_PCI_CONFIG_BASE 0xFD000000 /* Config space base addr */ | ||
27 | #define SH7780_PCI_CONFIG_SIZE 0x01000000 /* Config space size */ | ||
28 | |||
29 | #define SH7780_PCI_MEMORY_BASE 0xFD000000 /* Memory space base addr */ | ||
30 | #define SH7780_PCI_MEM_SIZE 0x01000000 /* Size of Memory window */ | ||
31 | |||
32 | #define SH7780_PCI_IO_BASE 0xFE400000 /* IO space base address */ | ||
33 | #define SH7780_PCI_IO_SIZE 0x00400000 /* Size of IO window */ | ||
34 | |||
35 | #define SH7780_PCIREG_BASE 0xFE040000 /* PCI regs base address */ | ||
36 | #define PCI_REG(n) (SH7780_PCIREG_BASE+n) | ||
37 | |||
38 | /* SH7780 PCI Config Registers */ | ||
39 | #define SH7780_PCIVID 0x000 /* Vendor ID */ | ||
40 | #define SH7780_PCIDID 0x002 /* Device ID */ | ||
41 | #define SH7780_PCICMD 0x004 /* Command */ | ||
42 | #define SH7780_PCISTATUS 0x006 /* Status */ | ||
43 | #define SH7780_PCIRID 0x008 /* Revision ID */ | ||
44 | #define SH7780_PCIPIF 0x009 /* Program Interface */ | ||
45 | #define SH7780_PCISUB 0x00a /* Sub class code */ | ||
46 | #define SH7780_PCIBCC 0x00b /* Base class code */ | ||
47 | #define SH7780_PCICLS 0x00c /* Cache line size */ | ||
48 | #define SH7780_PCILTM 0x00d /* latency timer */ | ||
49 | #define SH7780_PCIHDR 0x00e /* Header type */ | ||
50 | #define SH7780_PCIBIST 0x00f /* BIST */ | ||
51 | #define SH7780_PCIIBAR 0x010 /* IO Base address */ | ||
52 | #define SH7780_PCIMBAR0 0x014 /* Memory base address0 */ | ||
53 | #define SH7780_PCIMBAR1 0x018 /* Memory base address1 */ | ||
54 | #define SH7780_PCISVID 0x02c /* Sub system vendor ID */ | ||
55 | #define SH7780_PCISID 0x02e /* Sub system ID */ | ||
56 | #define SH7780_PCICP 0x034 | ||
57 | #define SH7780_PCIINTLINE 0x03c /* Interrupt line */ | ||
58 | #define SH7780_PCIINTPIN 0x03d /* Interrupt pin */ | ||
59 | #define SH7780_PCIMINGNT 0x03e /* Minumum grand */ | ||
60 | #define SH7780_PCIMAXLAT 0x03f /* Maxmum latency */ | ||
61 | #define SH7780_PCICID 0x040 | ||
62 | #define SH7780_PCINIP 0x041 | ||
63 | #define SH7780_PCIPMC 0x042 | ||
64 | #define SH7780_PCIPMCSR 0x044 | ||
65 | #define SH7780_PCIPMCSR_BSE 0x046 | ||
66 | #define SH7780_PCICDD 0x047 | ||
67 | |||
68 | #define SH7780_PCIMBR0 0x1E0 | ||
69 | #define SH7780_PCIMBMR0 0x1E4 | ||
70 | #define SH7780_PCIMBR2 0x1F0 | ||
71 | #define SH7780_PCIMBMR2 0x1F4 | ||
72 | #define SH7780_PCIIOBR 0x1F8 | ||
73 | #define SH7780_PCIIOBMR 0x1FC | ||
74 | #define SH7780_PCICSCR0 0x210 /* Cache Snoop1 Cnt. Register */ | ||
75 | #define SH7780_PCICSCR1 0x214 /* Cache Snoop2 Cnt. Register */ | ||
76 | #define SH7780_PCICSAR0 0x218 /* Cache Snoop1 Addr. Register */ | ||
77 | #define SH7780_PCICSAR1 0x21C /* Cache Snoop2 Addr. Register */ | ||
78 | |||
79 | /* General Memory Config Addresses */ | ||
80 | #define SH7780_CS0_BASE_ADDR 0x0 | ||
81 | #define SH7780_MEM_REGION_SIZE 0x04000000 | ||
82 | #define SH7780_CS1_BASE_ADDR (SH7780_CS0_BASE_ADDR + SH7780_MEM_REGION_SIZE) | ||
83 | #define SH7780_CS2_BASE_ADDR (SH7780_CS1_BASE_ADDR + SH7780_MEM_REGION_SIZE) | ||
84 | #define SH7780_CS3_BASE_ADDR (SH7780_CS2_BASE_ADDR + SH7780_MEM_REGION_SIZE) | ||
85 | #define SH7780_CS4_BASE_ADDR (SH7780_CS3_BASE_ADDR + SH7780_MEM_REGION_SIZE) | ||
86 | #define SH7780_CS5_BASE_ADDR (SH7780_CS4_BASE_ADDR + SH7780_MEM_REGION_SIZE) | ||
87 | #define SH7780_CS6_BASE_ADDR (SH7780_CS5_BASE_ADDR + SH7780_MEM_REGION_SIZE) | ||
88 | |||
89 | struct sh4_pci_address_map; | ||
90 | |||
91 | /* arch/sh/drivers/pci/pci-sh7780.c */ | ||
92 | int sh7780_pcic_init(struct sh4_pci_address_map *map); | ||
93 | |||
94 | #endif /* _PCI_SH7780_H_ */ | ||
diff --git a/arch/sh/drivers/pci/pci-st40.c b/arch/sh/drivers/pci/pci-st40.c index 7c81b8b65bb5..4ab5ea6b35fb 100644 --- a/arch/sh/drivers/pci/pci-st40.c +++ b/arch/sh/drivers/pci/pci-st40.c | |||
@@ -70,12 +70,6 @@ | |||
70 | static void pci_set_rbar_region(unsigned int region, unsigned long localAddr, | 70 | static void pci_set_rbar_region(unsigned int region, unsigned long localAddr, |
71 | unsigned long pciOffset, unsigned long regionSize); | 71 | unsigned long pciOffset, unsigned long regionSize); |
72 | 72 | ||
73 | /* | ||
74 | * The pcibios_map_platform_irq function is defined in the appropriate | ||
75 | * board specific code and referenced here | ||
76 | */ | ||
77 | extern int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin); | ||
78 | |||
79 | static __init void SetPCIPLL(void) | 73 | static __init void SetPCIPLL(void) |
80 | { | 74 | { |
81 | { | 75 | { |
@@ -422,13 +416,6 @@ struct pci_ops st40pci_config_ops = { | |||
422 | /* Everything hangs off this */ | 416 | /* Everything hangs off this */ |
423 | static struct pci_bus *pci_root_bus; | 417 | static struct pci_bus *pci_root_bus; |
424 | 418 | ||
425 | |||
426 | static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin) | ||
427 | { | ||
428 | return PCI_SLOT(dev->devfn); | ||
429 | } | ||
430 | |||
431 | |||
432 | static int __init pcibios_init(void) | 419 | static int __init pcibios_init(void) |
433 | { | 420 | { |
434 | extern unsigned long memory_start, memory_end; | 421 | extern unsigned long memory_start, memory_end; |
@@ -465,17 +452,11 @@ static int __init pcibios_init(void) | |||
465 | /* ok, do the scan man */ | 452 | /* ok, do the scan man */ |
466 | pci_root_bus = pci_scan_bus(0, &st40pci_config_ops, NULL); | 453 | pci_root_bus = pci_scan_bus(0, &st40pci_config_ops, NULL); |
467 | pci_assign_unassigned_resources(); | 454 | pci_assign_unassigned_resources(); |
468 | pci_fixup_irqs(no_swizzle, pcibios_map_platform_irq); | ||
469 | 455 | ||
470 | return 0; | 456 | return 0; |
471 | } | 457 | } |
472 | |||
473 | subsys_initcall(pcibios_init); | 458 | subsys_initcall(pcibios_init); |
474 | 459 | ||
475 | void __init pcibios_fixup_bus(struct pci_bus *bus) | ||
476 | { | ||
477 | } | ||
478 | |||
479 | /* | 460 | /* |
480 | * Publish a region of local address space over the PCI bus | 461 | * Publish a region of local address space over the PCI bus |
481 | * to other devices. | 462 | * to other devices. |
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 3d546ba329cf..d439336d2e18 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c | |||
@@ -1,21 +1,45 @@ | |||
1 | /* arch/sh/kernel/pci.c | 1 | /* |
2 | * $Id: pci.c,v 1.1 2003/08/24 19:15:45 lethal Exp $ | 2 | * arch/sh/drivers/pci/pci.c |
3 | * | 3 | * |
4 | * Copyright (c) 2002 M. R. Brown <mrbrown@linux-sh.org> | 4 | * Copyright (c) 2002 M. R. Brown <mrbrown@linux-sh.org> |
5 | * | 5 | * Copyright (c) 2004 - 2006 Paul Mundt <lethal@linux-sh.org> |
6 | * | 6 | * |
7 | * These functions are collected here to reduce duplication of common | 7 | * These functions are collected here to reduce duplication of common |
8 | * code amongst the many platform-specific PCI support code files. | 8 | * code amongst the many platform-specific PCI support code files. |
9 | * | 9 | * |
10 | * These routines require the following board-specific routines: | 10 | * These routines require the following board-specific routines: |
11 | * void pcibios_fixup_irqs(); | 11 | * void pcibios_fixup_irqs(); |
12 | * | 12 | * |
13 | * See include/asm-sh/pci.h for more information. | 13 | * See include/asm-sh/pci.h for more information. |
14 | * | ||
15 | * This file is subject to the terms and conditions of the GNU General Public | ||
16 | * License. See the file "COPYING" in the main directory of this archive | ||
17 | * for more details. | ||
14 | */ | 18 | */ |
15 | |||
16 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
17 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
18 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <asm/io.h> | ||
23 | |||
24 | static inline u8 bridge_swizzle(u8 pin, u8 slot) | ||
25 | { | ||
26 | return (((pin - 1) + slot) % 4) + 1; | ||
27 | } | ||
28 | |||
29 | static u8 __init simple_swizzle(struct pci_dev *dev, u8 *pinp) | ||
30 | { | ||
31 | u8 pin = *pinp; | ||
32 | |||
33 | while (dev->bus->parent) { | ||
34 | pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)); | ||
35 | /* Move up the chain of bridges. */ | ||
36 | dev = dev->bus->self; | ||
37 | } | ||
38 | *pinp = pin; | ||
39 | |||
40 | /* The slot is the slot of the last bridge. */ | ||
41 | return PCI_SLOT(dev->devfn); | ||
42 | } | ||
19 | 43 | ||
20 | static int __init pcibios_init(void) | 44 | static int __init pcibios_init(void) |
21 | { | 45 | { |
@@ -26,26 +50,32 @@ static int __init pcibios_init(void) | |||
26 | #ifdef CONFIG_PCI_AUTO | 50 | #ifdef CONFIG_PCI_AUTO |
27 | /* assign resources */ | 51 | /* assign resources */ |
28 | busno = 0; | 52 | busno = 0; |
29 | for (p = board_pci_channels; p->pci_ops != NULL; p++) { | 53 | for (p = board_pci_channels; p->pci_ops != NULL; p++) |
30 | busno = pciauto_assign_resources(busno, p) + 1; | 54 | busno = pciauto_assign_resources(busno, p) + 1; |
31 | } | ||
32 | #endif | 55 | #endif |
33 | 56 | ||
34 | /* scan the buses */ | 57 | /* scan the buses */ |
35 | busno = 0; | 58 | busno = 0; |
36 | for (p= board_pci_channels; p->pci_ops != NULL; p++) { | 59 | for (p = board_pci_channels; p->pci_ops != NULL; p++) { |
37 | bus = pci_scan_bus(busno, p->pci_ops, p); | 60 | bus = pci_scan_bus(busno, p->pci_ops, p); |
38 | busno = bus->subordinate+1; | 61 | busno = bus->subordinate + 1; |
39 | } | 62 | } |
40 | 63 | ||
41 | /* board-specific fixups */ | 64 | pci_fixup_irqs(simple_swizzle, pcibios_map_platform_irq); |
42 | pcibios_fixup_irqs(); | ||
43 | 65 | ||
44 | return 0; | 66 | return 0; |
45 | } | 67 | } |
46 | |||
47 | subsys_initcall(pcibios_init); | 68 | subsys_initcall(pcibios_init); |
48 | 69 | ||
70 | /* | ||
71 | * Called after each bus is probed, but before its children | ||
72 | * are examined. | ||
73 | */ | ||
74 | void __init pcibios_fixup_bus(struct pci_bus *bus) | ||
75 | { | ||
76 | pci_read_bridge_bases(bus); | ||
77 | } | ||
78 | |||
49 | void | 79 | void |
50 | pcibios_update_resource(struct pci_dev *dev, struct resource *root, | 80 | pcibios_update_resource(struct pci_dev *dev, struct resource *root, |
51 | struct resource *res, int resource) | 81 | struct resource *res, int resource) |
@@ -61,13 +91,17 @@ pcibios_update_resource(struct pci_dev *dev, struct resource *root, | |||
61 | new |= PCI_ROM_ADDRESS_ENABLE; | 91 | new |= PCI_ROM_ADDRESS_ENABLE; |
62 | reg = dev->rom_base_reg; | 92 | reg = dev->rom_base_reg; |
63 | } else { | 93 | } else { |
64 | /* Somebody might have asked allocation of a non-standard resource */ | 94 | /* |
95 | * Somebody might have asked allocation of a non-standard | ||
96 | * resource | ||
97 | */ | ||
65 | return; | 98 | return; |
66 | } | 99 | } |
67 | 100 | ||
68 | pci_write_config_dword(dev, reg, new); | 101 | pci_write_config_dword(dev, reg, new); |
69 | pci_read_config_dword(dev, reg, &check); | 102 | 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)) { | 103 | if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? |
104 | PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) { | ||
71 | printk(KERN_ERR "PCI: Error while updating region " | 105 | printk(KERN_ERR "PCI: Error while updating region " |
72 | "%s/%d (%08x != %08x)\n", pci_name(dev), resource, | 106 | "%s/%d (%08x != %08x)\n", pci_name(dev), resource, |
73 | new, check); | 107 | new, check); |
@@ -145,7 +179,8 @@ void pcibios_set_master(struct pci_dev *dev) | |||
145 | lat = pcibios_max_latency; | 179 | lat = pcibios_max_latency; |
146 | else | 180 | else |
147 | return; | 181 | return; |
148 | printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat); | 182 | printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", |
183 | pci_name(dev), lat); | ||
149 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); | 184 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); |
150 | } | 185 | } |
151 | 186 | ||
@@ -153,3 +188,39 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq) | |||
153 | { | 188 | { |
154 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); | 189 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); |
155 | } | 190 | } |
191 | |||
192 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) | ||
193 | { | ||
194 | unsigned long start = pci_resource_start(dev, bar); | ||
195 | unsigned long len = pci_resource_len(dev, bar); | ||
196 | unsigned long flags = pci_resource_flags(dev, bar); | ||
197 | |||
198 | if (unlikely(!len || !start)) | ||
199 | return NULL; | ||
200 | if (maxlen && len > maxlen) | ||
201 | len = maxlen; | ||
202 | |||
203 | /* | ||
204 | * Presently the IORESOURCE_MEM case is a bit special, most | ||
205 | * SH7751 style PCI controllers have PCI memory at a fixed | ||
206 | * location in the address space where no remapping is desired | ||
207 | * (typically at 0xfd000000, but is_pci_memaddr() will know | ||
208 | * best). With the IORESOURCE_MEM case more care has to be taken | ||
209 | * to inhibit page table mapping for legacy cores, but this is | ||
210 | * punted off to __ioremap(). | ||
211 | * -- PFM. | ||
212 | */ | ||
213 | if (flags & IORESOURCE_IO) | ||
214 | return ioport_map(start, len); | ||
215 | if (flags & IORESOURCE_MEM) | ||
216 | return ioremap(start, len); | ||
217 | |||
218 | return NULL; | ||
219 | } | ||
220 | EXPORT_SYMBOL(pci_iomap); | ||
221 | |||
222 | void pci_iounmap(struct pci_dev *dev, void __iomem *addr) | ||
223 | { | ||
224 | iounmap(addr); | ||
225 | } | ||
226 | EXPORT_SYMBOL(pci_iounmap); | ||