diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-05-22 00:29:37 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-05-22 00:29:37 -0400 |
commit | 5f8371cec93b94a24a55ba1de642ce6eade6d62c (patch) | |
tree | 61b6d2acb10226b3c0f2d31bda3a49288e540eba /arch/sh/drivers/pci | |
parent | 8e9bb19ef97d6594e735bee64b6d72103e350854 (diff) | |
parent | d8586ba6e1415150e1bab89f0a05447bb6f2d6d5 (diff) |
Merge branches 'sh/stable-updates' and 'sh/sparseirq'
Diffstat (limited to 'arch/sh/drivers/pci')
35 files changed, 869 insertions, 1982 deletions
diff --git a/arch/sh/drivers/pci/Kconfig b/arch/sh/drivers/pci/Kconfig index 7e816ededed7..e8db585a6638 100644 --- a/arch/sh/drivers/pci/Kconfig +++ b/arch/sh/drivers/pci/Kconfig | |||
@@ -17,21 +17,3 @@ config SH_PCIDMA_NONCOHERENT | |||
17 | code will not have to flush the CPU's caches. If you have a PCI host | 17 | code will not have to flush the CPU's caches. If you have a PCI host |
18 | bridge integrated with your SH CPU, refer carefully to the chip specs | 18 | bridge integrated with your SH CPU, refer carefully to the chip specs |
19 | to see if you can say 'N' here. Otherwise, leave it as 'Y'. | 19 | to see if you can say 'N' here. Otherwise, leave it as 'Y'. |
20 | |||
21 | # This is also board-specific | ||
22 | config PCI_AUTO | ||
23 | bool | ||
24 | depends on PCI | ||
25 | default y | ||
26 | |||
27 | config PCI_AUTO_UPDATE_RESOURCES | ||
28 | bool | ||
29 | depends on PCI_AUTO | ||
30 | default y if !SH_DREAMCAST | ||
31 | help | ||
32 | Selecting this option will cause the PCI auto code to leave your | ||
33 | BAR values alone. Otherwise they will be updated automatically. If | ||
34 | for some reason, you have a board that simply refuses to work | ||
35 | with its resources updated beyond what they are when the device | ||
36 | is powered up, set this to N. Everyone else will want this as Y. | ||
37 | |||
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index 847e90894d1b..d2ffc477549a 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile | |||
@@ -1,9 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Makefile for the PCI specific kernel interface routines under Linux. | 2 | # Makefile for the PCI specific kernel interface routines under Linux. |
3 | # | 3 | # |
4 | |||
5 | obj-y += pci.o | 4 | obj-y += pci.o |
6 | obj-$(CONFIG_PCI_AUTO) += pci-auto.o | ||
7 | 5 | ||
8 | obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o | 6 | obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o |
9 | obj-$(CONFIG_CPU_SUBTYPE_SH7751R) += pci-sh7751.o ops-sh4.o | 7 | obj-$(CONFIG_CPU_SUBTYPE_SH7751R) += pci-sh7751.o ops-sh4.o |
@@ -12,15 +10,17 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o | |||
12 | obj-$(CONFIG_CPU_SUBTYPE_SH7785) += pci-sh7780.o ops-sh4.o | 10 | obj-$(CONFIG_CPU_SUBTYPE_SH7785) += pci-sh7780.o ops-sh4.o |
13 | obj-$(CONFIG_CPU_SH5) += pci-sh5.o ops-sh5.o | 11 | obj-$(CONFIG_CPU_SH5) += pci-sh5.o ops-sh5.o |
14 | 12 | ||
15 | obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o | 13 | obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \ |
16 | obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o | 14 | pci-dreamcast.o |
17 | obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o | 15 | obj-$(CONFIG_SH_SECUREEDGE5410) += fixups-snapgear.o |
18 | obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o | 16 | obj-$(CONFIG_SH_7751_SOLUTION_ENGINE) += fixups-se7751.o |
19 | obj-$(CONFIG_SH_HIGHLANDER) += ops-r7780rp.o fixups-r7780rp.o | 17 | obj-$(CONFIG_SH_RTS7751R2D) += fixups-rts7751r2d.o |
20 | obj-$(CONFIG_SH_SDK7780) += ops-sdk7780.o fixups-sdk7780.o | 18 | obj-$(CONFIG_SH_SH03) += fixups-sh03.o |
21 | obj-$(CONFIG_SH_TITAN) += ops-titan.o | 19 | obj-$(CONFIG_SH_HIGHLANDER) += fixups-r7780rp.o |
22 | obj-$(CONFIG_SH_LANDISK) += ops-landisk.o | 20 | obj-$(CONFIG_SH_SH7785LCR) += fixups-r7780rp.o |
23 | obj-$(CONFIG_SH_LBOX_RE2) += ops-lboxre2.o fixups-lboxre2.o | 21 | obj-$(CONFIG_SH_SDK7780) += fixups-sdk7780.o |
24 | obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += ops-se7780.o fixups-se7780.o | 22 | obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += fixups-sdk7780.o |
25 | obj-$(CONFIG_SH_CAYMAN) += ops-cayman.o | 23 | obj-$(CONFIG_SH_TITAN) += fixups-titan.o |
26 | obj-$(CONFIG_SH_SH7785LCR) += ops-sh7785lcr.o fixups-sh7785lcr.o | 24 | obj-$(CONFIG_SH_LANDISK) += fixups-landisk.o |
25 | obj-$(CONFIG_SH_LBOX_RE2) += fixups-rts7751r2d.o | ||
26 | obj-$(CONFIG_SH_CAYMAN) += fixups-cayman.o | ||
diff --git a/arch/sh/drivers/pci/ops-cayman.c b/arch/sh/drivers/pci/fixups-cayman.c index 38ef76207af6..b68b61d22c6c 100644 --- a/arch/sh/drivers/pci/ops-cayman.c +++ b/arch/sh/drivers/pci/fixups-cayman.c | |||
@@ -75,15 +75,3 @@ int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) | |||
75 | 75 | ||
76 | return result; | 76 | return result; |
77 | } | 77 | } |
78 | |||
79 | struct pci_channel board_pci_channels[] = { | ||
80 | { &sh5_pci_ops, NULL, NULL, 0, 0xff }, | ||
81 | { NULL, NULL, NULL, 0, 0 }, | ||
82 | }; | ||
83 | EXPORT_SYMBOL(board_pci_channels); | ||
84 | |||
85 | int __init pcibios_init_platform(void) | ||
86 | { | ||
87 | return sh5pci_init(__pa(memory_start), | ||
88 | __pa(memory_end) - __pa(memory_start)); | ||
89 | } | ||
diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c index 2bf85cf091e1..ed7f489936f1 100644 --- a/arch/sh/drivers/pci/fixups-dreamcast.c +++ b/arch/sh/drivers/pci/fixups-dreamcast.c | |||
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | static void __init gapspci_fixup_resources(struct pci_dev *dev) | 31 | static void __init gapspci_fixup_resources(struct pci_dev *dev) |
32 | { | 32 | { |
33 | struct pci_channel *p = board_pci_channels; | 33 | struct pci_channel *p = dev->sysdata; |
34 | 34 | ||
35 | printk(KERN_NOTICE "PCI: Fixing up device %s\n", pci_name(dev)); | 35 | printk(KERN_NOTICE "PCI: Fixing up device %s\n", pci_name(dev)); |
36 | 36 | ||
@@ -41,6 +41,13 @@ static void __init gapspci_fixup_resources(struct pci_dev *dev) | |||
41 | */ | 41 | */ |
42 | dev->resource[1].start = p->io_resource->start + 0x100; | 42 | dev->resource[1].start = p->io_resource->start + 0x100; |
43 | dev->resource[1].end = dev->resource[1].start + 0x200 - 1; | 43 | dev->resource[1].end = dev->resource[1].start + 0x200 - 1; |
44 | |||
45 | /* | ||
46 | * This is not a normal BAR, prevent any attempts to move | ||
47 | * the BAR, as this will result in a bus lock. | ||
48 | */ | ||
49 | dev->resource[1].flags |= IORESOURCE_PCI_FIXED; | ||
50 | |||
44 | /* | 51 | /* |
45 | * Redirect dma memory allocations to special memory window. | 52 | * Redirect dma memory allocations to special memory window. |
46 | */ | 53 | */ |
diff --git a/arch/sh/drivers/pci/ops-landisk.c b/arch/sh/drivers/pci/fixups-landisk.c index bff09ecf3419..bb1a6bb5149e 100644 --- a/arch/sh/drivers/pci/ops-landisk.c +++ b/arch/sh/drivers/pci/fixups-landisk.c | |||
@@ -15,39 +15,6 @@ | |||
15 | #include <linux/pci.h> | 15 | #include <linux/pci.h> |
16 | #include "pci-sh4.h" | 16 | #include "pci-sh4.h" |
17 | 17 | ||
18 | static struct resource sh7751_io_resource = { | ||
19 | .name = "SH7751 IO", | ||
20 | .start = SH7751_PCI_IO_BASE, | ||
21 | .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, | ||
22 | .flags = IORESOURCE_IO | ||
23 | }; | ||
24 | |||
25 | static struct resource sh7751_mem_resource = { | ||
26 | .name = "SH7751 mem", | ||
27 | .start = SH7751_PCI_MEMORY_BASE, | ||
28 | .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, | ||
29 | .flags = IORESOURCE_MEM | ||
30 | }; | ||
31 | |||
32 | struct pci_channel board_pci_channels[] = { | ||
33 | {&sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0x3ff}, | ||
34 | {NULL, NULL, NULL, 0, 0}, | ||
35 | }; | ||
36 | |||
37 | static struct sh4_pci_address_map sh7751_pci_map = { | ||
38 | .window0 = { | ||
39 | .base = SH7751_CS3_BASE_ADDR, | ||
40 | .size = (64 << 20), /* 64MB */ | ||
41 | }, | ||
42 | |||
43 | .flags = SH4_PCIC_NO_RESET, | ||
44 | }; | ||
45 | |||
46 | int __init pcibios_init_platform(void) | ||
47 | { | ||
48 | return sh7751_pcic_init(&sh7751_pci_map); | ||
49 | } | ||
50 | |||
51 | int pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) | 18 | int pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) |
52 | { | 19 | { |
53 | /* | 20 | /* |
diff --git a/arch/sh/drivers/pci/fixups-lboxre2.c b/arch/sh/drivers/pci/fixups-lboxre2.c deleted file mode 100644 index 1c1d41255ec0..000000000000 --- a/arch/sh/drivers/pci/fixups-lboxre2.c +++ /dev/null | |||
@@ -1,41 +0,0 @@ | |||
1 | /* | ||
2 | * arch/sh/drivers/pci/fixups-lboxre2.c | ||
3 | * | ||
4 | * L-BOX RE2 PCI fixups | ||
5 | * | ||
6 | * Copyright (C) 2007 Nobuhiro Iwamatsu | ||
7 | * | ||
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 | ||
10 | * for more details. | ||
11 | */ | ||
12 | #include "pci-sh4.h" | ||
13 | |||
14 | #define PCIMCR_MRSET_OFF 0xBFFFFFFF | ||
15 | #define PCIMCR_RFSH_OFF 0xFFFFFFFB | ||
16 | |||
17 | int pci_fixup_pcic(void) | ||
18 | { | ||
19 | unsigned long bcr1, mcr; | ||
20 | |||
21 | bcr1 = ctrl_inl(SH7751_BCR1); | ||
22 | bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ | ||
23 | pci_write_reg(bcr1, SH4_PCIBCR1); | ||
24 | |||
25 | /* Enable all interrupts, so we known what to fix */ | ||
26 | pci_write_reg(0x0000c3ff, SH4_PCIINTM); | ||
27 | pci_write_reg(0x0000380f, SH4_PCIAINTM); | ||
28 | pci_write_reg(0xfb900047, SH7751_PCICONF1); | ||
29 | pci_write_reg(0xab000001, SH7751_PCICONF4); | ||
30 | |||
31 | mcr = ctrl_inl(SH7751_MCR); | ||
32 | mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; | ||
33 | pci_write_reg(mcr, SH4_PCIMCR); | ||
34 | |||
35 | pci_write_reg(0x0c000000, SH7751_PCICONF5); | ||
36 | pci_write_reg(0xd0000000, SH7751_PCICONF6); | ||
37 | pci_write_reg(0x0c000000, SH4_PCILAR0); | ||
38 | pci_write_reg(0x00000000, SH4_PCILAR1); | ||
39 | |||
40 | return 0; | ||
41 | } | ||
diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c index 3e321df65d22..15ca65cb667e 100644 --- a/arch/sh/drivers/pci/fixups-r7780rp.c +++ b/arch/sh/drivers/pci/fixups-r7780rp.c | |||
@@ -11,35 +11,26 @@ | |||
11 | * for more details. | 11 | * for more details. |
12 | */ | 12 | */ |
13 | #include <linux/pci.h> | 13 | #include <linux/pci.h> |
14 | #include <linux/io.h> | ||
14 | #include "pci-sh4.h" | 15 | #include "pci-sh4.h" |
15 | #include <asm/io.h> | ||
16 | 16 | ||
17 | int pci_fixup_pcic(void) | 17 | static char irq_tab[] __initdata = { |
18 | { | 18 | 65, 66, 67, 68, |
19 | pci_write_reg(0x000043ff, SH4_PCIINTM); | 19 | }; |
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 | 20 | ||
34 | #ifdef CONFIG_32BIT | 21 | int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) |
35 | pci_write_reg(0xc0000000, SH7780_PCIMBR2); | 22 | { |
36 | pci_write_reg(0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2); | 23 | return irq_tab[slot]; |
37 | #endif | 24 | } |
38 | 25 | ||
39 | /* Set IOBR for windows containing area specified in pci.h */ | 26 | int pci_fixup_pcic(struct pci_channel *chan) |
40 | pci_write_reg((PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE - 1)), | 27 | { |
41 | SH7780_PCIIOBR); | 28 | pci_write_reg(chan, 0x000043ff, SH4_PCIINTM); |
42 | pci_write_reg(((SH7780_PCI_IO_SIZE-1) & (7<<18)), SH7780_PCIIOBMR); | 29 | pci_write_reg(chan, 0x00000000, SH7780_PCIIBAR); |
30 | pci_write_reg(chan, 0x08000000, SH7780_PCICSCR0); | ||
31 | pci_write_reg(chan, 0x0000001b, SH7780_PCICSAR0); | ||
32 | pci_write_reg(chan, 0xfd000000, SH7780_PCICSCR1); | ||
33 | pci_write_reg(chan, 0x0000000f, SH7780_PCICSAR1); | ||
43 | 34 | ||
44 | return 0; | 35 | return 0; |
45 | } | 36 | } |
diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c index 904bce8768d3..052b354236dc 100644 --- a/arch/sh/drivers/pci/fixups-rts7751r2d.c +++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c | |||
@@ -1,43 +1,67 @@ | |||
1 | /* | 1 | /* |
2 | * arch/sh/drivers/pci/fixups-rts7751r2d.c | 2 | * arch/sh/drivers/pci/fixups-rts7751r2d.c |
3 | * | 3 | * |
4 | * RTS7751R2D PCI fixups | 4 | * RTS7751R2D / LBOXRE2 PCI fixups |
5 | * | 5 | * |
6 | * Copyright (C) 2003 Lineo uSolutions, Inc. | 6 | * Copyright (C) 2003 Lineo uSolutions, Inc. |
7 | * Copyright (C) 2004 Paul Mundt | 7 | * Copyright (C) 2004 Paul Mundt |
8 | * Copyright (C) 2007 Nobuhiro Iwamatsu | ||
8 | * | 9 | * |
9 | * This file is subject to the terms and conditions of the GNU General Public | 10 | * 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 | * License. See the file "COPYING" in the main directory of this archive |
11 | * for more details. | 12 | * for more details. |
12 | */ | 13 | */ |
14 | #include <linux/pci.h> | ||
15 | #include <mach/lboxre2.h> | ||
16 | #include <mach/r2d.h> | ||
13 | #include "pci-sh4.h" | 17 | #include "pci-sh4.h" |
18 | #include <asm/machtypes.h> | ||
14 | 19 | ||
15 | #define PCIMCR_MRSET_OFF 0xBFFFFFFF | 20 | #define PCIMCR_MRSET_OFF 0xBFFFFFFF |
16 | #define PCIMCR_RFSH_OFF 0xFFFFFFFB | 21 | #define PCIMCR_RFSH_OFF 0xFFFFFFFB |
17 | 22 | ||
18 | int pci_fixup_pcic(void) | 23 | static u8 rts7751r2d_irq_tab[] __initdata = { |
24 | IRQ_PCI_INTA, | ||
25 | IRQ_PCI_INTB, | ||
26 | IRQ_PCI_INTC, | ||
27 | IRQ_PCI_INTD, | ||
28 | }; | ||
29 | |||
30 | static char lboxre2_irq_tab[] __initdata = { | ||
31 | IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD, | ||
32 | }; | ||
33 | |||
34 | int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) | ||
35 | { | ||
36 | if (mach_is_lboxre2()) | ||
37 | return lboxre2_irq_tab[slot]; | ||
38 | else | ||
39 | return rts7751r2d_irq_tab[slot]; | ||
40 | } | ||
41 | |||
42 | int pci_fixup_pcic(struct pci_channel *chan) | ||
19 | { | 43 | { |
20 | unsigned long bcr1, mcr; | 44 | unsigned long bcr1, mcr; |
21 | 45 | ||
22 | bcr1 = ctrl_inl(SH7751_BCR1); | 46 | bcr1 = ctrl_inl(SH7751_BCR1); |
23 | bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ | 47 | bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ |
24 | pci_write_reg(bcr1, SH4_PCIBCR1); | 48 | pci_write_reg(chan, bcr1, SH4_PCIBCR1); |
25 | 49 | ||
26 | /* Enable all interrupts, so we known what to fix */ | 50 | /* Enable all interrupts, so we known what to fix */ |
27 | pci_write_reg(0x0000c3ff, SH4_PCIINTM); | 51 | pci_write_reg(chan, 0x0000c3ff, SH4_PCIINTM); |
28 | pci_write_reg(0x0000380f, SH4_PCIAINTM); | 52 | pci_write_reg(chan, 0x0000380f, SH4_PCIAINTM); |
29 | 53 | ||
30 | pci_write_reg(0xfb900047, SH7751_PCICONF1); | 54 | pci_write_reg(chan, 0xfb900047, SH7751_PCICONF1); |
31 | pci_write_reg(0xab000001, SH7751_PCICONF4); | 55 | pci_write_reg(chan, 0xab000001, SH7751_PCICONF4); |
32 | 56 | ||
33 | mcr = ctrl_inl(SH7751_MCR); | 57 | mcr = ctrl_inl(SH7751_MCR); |
34 | mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; | 58 | mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; |
35 | pci_write_reg(mcr, SH4_PCIMCR); | 59 | pci_write_reg(chan, mcr, SH4_PCIMCR); |
36 | 60 | ||
37 | pci_write_reg(0x0c000000, SH7751_PCICONF5); | 61 | pci_write_reg(chan, 0x0c000000, SH7751_PCICONF5); |
38 | pci_write_reg(0xd0000000, SH7751_PCICONF6); | 62 | pci_write_reg(chan, 0xd0000000, SH7751_PCICONF6); |
39 | pci_write_reg(0x0c000000, SH4_PCILAR0); | 63 | pci_write_reg(chan, 0x0c000000, SH4_PCILAR0); |
40 | pci_write_reg(0x00000000, SH4_PCILAR1); | 64 | pci_write_reg(chan, 0x00000000, SH4_PCILAR1); |
41 | 65 | ||
42 | return 0; | 66 | return 0; |
43 | } | 67 | } |
diff --git a/arch/sh/drivers/pci/fixups-sdk7780.c b/arch/sh/drivers/pci/fixups-sdk7780.c index 2f8863099dd1..250b0edd7365 100644 --- a/arch/sh/drivers/pci/fixups-sdk7780.c +++ b/arch/sh/drivers/pci/fixups-sdk7780.c | |||
@@ -5,55 +5,48 @@ | |||
5 | * | 5 | * |
6 | * Copyright (C) 2003 Lineo uSolutions, Inc. | 6 | * Copyright (C) 2003 Lineo uSolutions, Inc. |
7 | * Copyright (C) 2004 - 2006 Paul Mundt | 7 | * Copyright (C) 2004 - 2006 Paul Mundt |
8 | * Copyright (C) 2006 Nobuhiro Iwamatsu | ||
8 | * | 9 | * |
9 | * This file is subject to the terms and conditions of the GNU General Public | 10 | * 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 | * License. See the file "COPYING" in the main directory of this archive |
11 | * for more details. | 12 | * for more details. |
12 | */ | 13 | */ |
13 | #include <linux/pci.h> | 14 | #include <linux/pci.h> |
15 | #include <linux/io.h> | ||
14 | #include "pci-sh4.h" | 16 | #include "pci-sh4.h" |
15 | #include <asm/io.h> | ||
16 | 17 | ||
17 | int pci_fixup_pcic(void) | 18 | /* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */ |
19 | static char sdk7780_irq_tab[4][16] __initdata = { | ||
20 | /* INTA */ | ||
21 | { 65, 68, 67, 68, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||
22 | /* INTB */ | ||
23 | { 66, 65, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||
24 | /* INTC */ | ||
25 | { 67, 66, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||
26 | /* INTD */ | ||
27 | { 68, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||
28 | }; | ||
29 | |||
30 | int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) | ||
31 | { | ||
32 | return sdk7780_irq_tab[pin-1][slot]; | ||
33 | } | ||
34 | int pci_fixup_pcic(struct pci_channel *chan) | ||
18 | { | 35 | { |
19 | ctrl_outl(0x00000001, SH7780_PCI_VCR2); | ||
20 | |||
21 | /* Enable all interrupts, so we know what to fix */ | 36 | /* Enable all interrupts, so we know what to fix */ |
22 | pci_write_reg(0x0000C3FF, SH7780_PCIIMR); | 37 | pci_write_reg(chan, 0x0000C3FF, SH7780_PCIIMR); |
23 | pci_write_reg(0x0000380F, SH7780_PCIAINTM); | ||
24 | 38 | ||
25 | /* Set up standard PCI config registers */ | 39 | /* Set up standard PCI config registers */ |
26 | pci_write_reg(0xFB00, SH7780_PCISTATUS); | 40 | pci_write_reg(chan, 0x08000000, SH7780_PCIMBAR0); /* PCI */ |
27 | pci_write_reg(0x0047, SH7780_PCICMD); | 41 | pci_write_reg(chan, 0x08000000, SH4_PCILAR0); /* SHwy */ |
28 | pci_write_reg(0x00, SH7780_PCIPIF); | 42 | pci_write_reg(chan, 0x07F00001, SH4_PCILSR0); /* size 128M w/ MBAR */ |
29 | pci_write_reg(0x00, SH7780_PCISUB); | ||
30 | pci_write_reg(0x06, SH7780_PCIBCC); | ||
31 | pci_write_reg(0x1912, SH7780_PCISVID); | ||
32 | pci_write_reg(0x0001, SH7780_PCISID); | ||
33 | |||
34 | pci_write_reg(0x08000000, SH7780_PCIMBAR0); /* PCI */ | ||
35 | pci_write_reg(0x08000000, SH7780_PCILAR0); /* SHwy */ | ||
36 | pci_write_reg(0x07F00001, SH7780_PCILSR); /* size 128M w/ MBAR */ | ||
37 | |||
38 | pci_write_reg(0x00000000, SH7780_PCIMBAR1); | ||
39 | pci_write_reg(0x00000000, SH7780_PCILAR1); | ||
40 | pci_write_reg(0x00000000, SH7780_PCILSR1); | ||
41 | |||
42 | pci_write_reg(0xAB000801, SH7780_PCIIBAR); | ||
43 | |||
44 | /* | ||
45 | * Set the MBR so PCI address is one-to-one with window, | ||
46 | * meaning all calls go straight through... use ifdef to | ||
47 | * catch erroneous assumption. | ||
48 | */ | ||
49 | pci_write_reg(0xFD000000 , SH7780_PCIMBR0); | ||
50 | pci_write_reg(0x00FC0000 , SH7780_PCIMBMR0); /* 16M */ | ||
51 | 43 | ||
52 | /* Set IOBR for window containing area specified in pci.h */ | 44 | pci_write_reg(chan, 0x00000000, SH7780_PCIMBAR1); |
53 | pci_write_reg(PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE-1), SH7780_PCIIOBR); | 45 | pci_write_reg(chan, 0x00000000, SH4_PCILAR1); |
54 | pci_write_reg((SH7780_PCI_IO_SIZE-1) & (7 << 18), SH7780_PCIIOBMR); | 46 | pci_write_reg(chan, 0x00000000, SH4_PCILSR1); |
55 | 47 | ||
56 | pci_write_reg(0xA5000C01, SH7780_PCICR); | 48 | pci_write_reg(chan, 0xAB000801, SH7780_PCIIBAR); |
49 | pci_write_reg(chan, 0xA5000C01, SH4_PCICR); | ||
57 | 50 | ||
58 | return 0; | 51 | return 0; |
59 | } | 52 | } |
diff --git a/arch/sh/drivers/pci/fixups-se7751.c b/arch/sh/drivers/pci/fixups-se7751.c new file mode 100644 index 000000000000..475fa9f0fe2c --- /dev/null +++ b/arch/sh/drivers/pci/fixups-se7751.c | |||
@@ -0,0 +1,111 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | #include <linux/types.h> | ||
3 | #include <linux/init.h> | ||
4 | #include <linux/delay.h> | ||
5 | #include <linux/pci.h> | ||
6 | #include <linux/io.h> | ||
7 | #include "pci-sh4.h" | ||
8 | |||
9 | int __init pcibios_map_platform_irq(u8 slot, u8 pin) | ||
10 | { | ||
11 | switch (slot) { | ||
12 | case 0: return 13; | ||
13 | case 1: return 13; /* AMD Ethernet controller */ | ||
14 | case 2: return -1; | ||
15 | case 3: return -1; | ||
16 | case 4: return -1; | ||
17 | default: | ||
18 | printk("PCI: Bad IRQ mapping request for slot %d\n", slot); | ||
19 | return -1; | ||
20 | } | ||
21 | } | ||
22 | |||
23 | #define PCIMCR_MRSET_OFF 0xBFFFFFFF | ||
24 | #define PCIMCR_RFSH_OFF 0xFFFFFFFB | ||
25 | |||
26 | /* | ||
27 | * Only long word accesses of the PCIC's internal local registers and the | ||
28 | * configuration registers from the CPU is supported. | ||
29 | */ | ||
30 | #define PCIC_WRITE(x,v) writel((v), PCI_REG(x)) | ||
31 | #define PCIC_READ(x) readl(PCI_REG(x)) | ||
32 | |||
33 | /* | ||
34 | * Description: This function sets up and initializes the pcic, sets | ||
35 | * up the BARS, maps the DRAM into the address space etc, etc. | ||
36 | */ | ||
37 | int pci_fixup_pcic(struct pci_channel *chan) | ||
38 | { | ||
39 | unsigned long bcr1, wcr1, wcr2, wcr3, mcr; | ||
40 | unsigned short bcr2; | ||
41 | |||
42 | /* | ||
43 | * Initialize the slave bus controller on the pcic. The values used | ||
44 | * here should not be hardcoded, but they should be taken from the bsc | ||
45 | * on the processor, to make this function as generic as possible. | ||
46 | * (i.e. Another sbc may usr different SDRAM timing settings -- in order | ||
47 | * for the pcic to work, its settings need to be exactly the same.) | ||
48 | */ | ||
49 | bcr1 = (*(volatile unsigned long*)(SH7751_BCR1)); | ||
50 | bcr2 = (*(volatile unsigned short*)(SH7751_BCR2)); | ||
51 | wcr1 = (*(volatile unsigned long*)(SH7751_WCR1)); | ||
52 | wcr2 = (*(volatile unsigned long*)(SH7751_WCR2)); | ||
53 | wcr3 = (*(volatile unsigned long*)(SH7751_WCR3)); | ||
54 | mcr = (*(volatile unsigned long*)(SH7751_MCR)); | ||
55 | |||
56 | bcr1 = bcr1 | 0x00080000; /* Enable Bit 19, BREQEN */ | ||
57 | (*(volatile unsigned long*)(SH7751_BCR1)) = bcr1; | ||
58 | |||
59 | bcr1 = bcr1 | 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ | ||
60 | PCIC_WRITE(SH7751_PCIBCR1, bcr1); /* PCIC BCR1 */ | ||
61 | PCIC_WRITE(SH7751_PCIBCR2, bcr2); /* PCIC BCR2 */ | ||
62 | PCIC_WRITE(SH7751_PCIWCR1, wcr1); /* PCIC WCR1 */ | ||
63 | PCIC_WRITE(SH7751_PCIWCR2, wcr2); /* PCIC WCR2 */ | ||
64 | PCIC_WRITE(SH7751_PCIWCR3, wcr3); /* PCIC WCR3 */ | ||
65 | mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; | ||
66 | PCIC_WRITE(SH7751_PCIMCR, mcr); /* PCIC MCR */ | ||
67 | |||
68 | |||
69 | /* Enable all interrupts, so we know what to fix */ | ||
70 | PCIC_WRITE(SH7751_PCIINTM, 0x0000c3ff); | ||
71 | PCIC_WRITE(SH7751_PCIAINTM, 0x0000380f); | ||
72 | |||
73 | /* Set up standard PCI config registers */ | ||
74 | PCIC_WRITE(SH7751_PCICONF1, 0xF39000C7); /* Bus Master, Mem & I/O access */ | ||
75 | PCIC_WRITE(SH7751_PCICONF2, 0x00000000); /* PCI Class code & Revision ID */ | ||
76 | PCIC_WRITE(SH7751_PCICONF4, 0xab000001); /* PCI I/O address (local regs) */ | ||
77 | PCIC_WRITE(SH7751_PCICONF5, 0x0c000000); /* PCI MEM address (local RAM) */ | ||
78 | PCIC_WRITE(SH7751_PCICONF6, 0xd0000000); /* PCI MEM address (unused) */ | ||
79 | PCIC_WRITE(SH7751_PCICONF11, 0x35051054); /* PCI Subsystem ID & Vendor ID */ | ||
80 | PCIC_WRITE(SH7751_PCILSR0, 0x03f00000); /* MEM (full 64M exposed) */ | ||
81 | PCIC_WRITE(SH7751_PCILSR1, 0x00000000); /* MEM (unused) */ | ||
82 | PCIC_WRITE(SH7751_PCILAR0, 0x0c000000); /* MEM (direct map from PCI) */ | ||
83 | PCIC_WRITE(SH7751_PCILAR1, 0x00000000); /* MEM (unused) */ | ||
84 | |||
85 | /* Now turn it on... */ | ||
86 | PCIC_WRITE(SH7751_PCICR, 0xa5000001); | ||
87 | |||
88 | /* | ||
89 | * Set PCIMBR and PCIIOBR here, assuming a single window | ||
90 | * (16M MEM, 256K IO) is enough. If a larger space is | ||
91 | * needed, the readx/writex and inx/outx functions will | ||
92 | * have to do more (e.g. setting registers for each call). | ||
93 | */ | ||
94 | |||
95 | /* | ||
96 | * Set the MBR so PCI address is one-to-one with window, | ||
97 | * meaning all calls go straight through... use BUG_ON to | ||
98 | * catch erroneous assumption. | ||
99 | */ | ||
100 | BUG_ON(chan->mem_resource->start != SH7751_PCI_MEMORY_BASE); | ||
101 | |||
102 | PCIC_WRITE(SH7751_PCIMBR, chan->mem_resource->start); | ||
103 | |||
104 | /* Set IOBR for window containing area specified in pci.h */ | ||
105 | PCIC_WRITE(SH7751_PCIIOBR, (chan->io_resource->start & SH7751_PCIIOBR_MASK)); | ||
106 | |||
107 | /* All done, may as well say so... */ | ||
108 | printk("SH7751 PCI: Finished initialization of the PCI controller\n"); | ||
109 | |||
110 | return 1; | ||
111 | } | ||
diff --git a/arch/sh/drivers/pci/fixups-se7780.c b/arch/sh/drivers/pci/fixups-se7780.c deleted file mode 100644 index 880cea1c0d89..000000000000 --- a/arch/sh/drivers/pci/fixups-se7780.c +++ /dev/null | |||
@@ -1,60 +0,0 @@ | |||
1 | /* | ||
2 | * arch/sh/drivers/pci/fixups-se7780.c | ||
3 | * | ||
4 | * HITACHI UL Solution Engine 7780 PCI fixups | ||
5 | * | ||
6 | * Copyright (C) 2003 Lineo uSolutions, Inc. | ||
7 | * Copyright (C) 2004 - 2006 Paul Mundt | ||
8 | * Copyright (C) 2006 Nobuhiro Iwamatsu | ||
9 | * | ||
10 | * This file is subject to the terms and conditions of the GNU General Public | ||
11 | * License. See the file "COPYING" in the main directory of this archive | ||
12 | * for more details. | ||
13 | */ | ||
14 | #include <linux/pci.h> | ||
15 | #include "pci-sh4.h" | ||
16 | #include <asm/io.h> | ||
17 | |||
18 | int pci_fixup_pcic(void) | ||
19 | { | ||
20 | ctrl_outl(0x00000001, SH7780_PCI_VCR2); | ||
21 | |||
22 | /* Enable all interrupts, so we know what to fix */ | ||
23 | pci_write_reg(0x0000C3FF, SH7780_PCIIMR); | ||
24 | pci_write_reg(0x0000380F, SH7780_PCIAINTM); | ||
25 | |||
26 | /* Set up standard PCI config registers */ | ||
27 | ctrl_outw(0xFB00, PCI_REG(SH7780_PCISTATUS)); | ||
28 | ctrl_outw(0x0047, PCI_REG(SH7780_PCICMD)); | ||
29 | ctrl_outb( 0x00, PCI_REG(SH7780_PCIPIF)); | ||
30 | ctrl_outb( 0x00, PCI_REG(SH7780_PCISUB)); | ||
31 | ctrl_outb( 0x06, PCI_REG(SH7780_PCIBCC)); | ||
32 | ctrl_outw(0x1912, PCI_REG(SH7780_PCISVID)); | ||
33 | ctrl_outw(0x0001, PCI_REG(SH7780_PCISID)); | ||
34 | |||
35 | pci_write_reg(0x08000000, SH7780_PCIMBAR0); /* PCI */ | ||
36 | pci_write_reg(0x08000000, SH7780_PCILAR0); /* SHwy */ | ||
37 | pci_write_reg(0x07F00001, SH7780_PCILSR); /* size 128M w/ MBAR */ | ||
38 | |||
39 | pci_write_reg(0x00000000, SH7780_PCIMBAR1); | ||
40 | pci_write_reg(0x00000000, SH7780_PCILAR1); | ||
41 | pci_write_reg(0x00000000, SH7780_PCILSR1); | ||
42 | |||
43 | pci_write_reg(0xAB000801, SH7780_PCIIBAR); | ||
44 | |||
45 | /* | ||
46 | * Set the MBR so PCI address is one-to-one with window, | ||
47 | * meaning all calls go straight through... use ifdef to | ||
48 | * catch erroneous assumption. | ||
49 | */ | ||
50 | pci_write_reg(0xFD000000 , SH7780_PCIMBR0); | ||
51 | pci_write_reg(0x00FC0000 , SH7780_PCIMBMR0); /* 16M */ | ||
52 | |||
53 | /* Set IOBR for window containing area specified in pci.h */ | ||
54 | pci_write_reg(PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE-1), SH7780_PCIIOBR); | ||
55 | pci_write_reg((SH7780_PCI_IO_SIZE-1) & (7 << 18), SH7780_PCIIOBMR); | ||
56 | |||
57 | pci_write_reg(0xA5000C01, SH7780_PCICR); | ||
58 | |||
59 | return 0; | ||
60 | } | ||
diff --git a/arch/sh/drivers/pci/fixups-sh7785lcr.c b/arch/sh/drivers/pci/fixups-sh7785lcr.c deleted file mode 100644 index 4949e601387a..000000000000 --- a/arch/sh/drivers/pci/fixups-sh7785lcr.c +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | /* | ||
2 | * arch/sh/drivers/pci/fixups-sh7785lcr.c | ||
3 | * | ||
4 | * R0P7785LC0011RL PCI fixups | ||
5 | * Copyright (C) 2008 Yoshihiro Shimoda | ||
6 | * | ||
7 | * Based on arch/sh/drivers/pci/fixups-r7780rp.c | ||
8 | * Copyright (C) 2003 Lineo uSolutions, Inc. | ||
9 | * Copyright (C) 2004 - 2006 Paul Mundt | ||
10 | * | ||
11 | * This file is subject to the terms and conditions of the GNU General Public | ||
12 | * License. See the file "COPYING" in the main directory of this archive | ||
13 | * for more details. | ||
14 | */ | ||
15 | #include <linux/pci.h> | ||
16 | #include "pci-sh4.h" | ||
17 | |||
18 | int pci_fixup_pcic(void) | ||
19 | { | ||
20 | pci_write_reg(0x000043ff, SH4_PCIINTM); | ||
21 | pci_write_reg(0x0000380f, SH4_PCIAINTM); | ||
22 | |||
23 | pci_write_reg(0xfbb00047, SH7780_PCICMD); | ||
24 | pci_write_reg(0x00000000, SH7780_PCIIBAR); | ||
25 | |||
26 | pci_write_reg(0x00011912, SH7780_PCISVID); | ||
27 | pci_write_reg(0x08000000, SH7780_PCICSCR0); | ||
28 | pci_write_reg(0x0000001b, SH7780_PCICSAR0); | ||
29 | pci_write_reg(0xfd000000, SH7780_PCICSCR1); | ||
30 | pci_write_reg(0x0000000f, SH7780_PCICSAR1); | ||
31 | |||
32 | pci_write_reg(0xfd000000, SH7780_PCIMBR0); | ||
33 | pci_write_reg(0x00fc0000, SH7780_PCIMBMR0); | ||
34 | |||
35 | #ifdef CONFIG_32BIT | ||
36 | pci_write_reg(0xc0000000, SH7780_PCIMBR2); | ||
37 | pci_write_reg(0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2); | ||
38 | #endif | ||
39 | |||
40 | /* Set IOBR for windows containing area specified in pci.h */ | ||
41 | pci_write_reg((PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE - 1)), | ||
42 | SH7780_PCIIOBR); | ||
43 | pci_write_reg(((SH7780_PCI_IO_SIZE - 1) & (7 << 18)), SH7780_PCIIOBMR); | ||
44 | |||
45 | return 0; | ||
46 | } | ||
diff --git a/arch/sh/drivers/pci/fixups-snapgear.c b/arch/sh/drivers/pci/fixups-snapgear.c new file mode 100644 index 000000000000..5a39ecc1adb8 --- /dev/null +++ b/arch/sh/drivers/pci/fixups-snapgear.c | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * arch/sh/drivers/pci/ops-snapgear.c | ||
3 | * | ||
4 | * Author: David McCullough <davidm@snapgear.com> | ||
5 | * | ||
6 | * Ported to new API by Paul Mundt <lethal@linux-sh.org> | ||
7 | * | ||
8 | * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. | ||
9 | * | ||
10 | * May be copied or modified under the terms of the GNU General Public | ||
11 | * License. See linux/COPYING for more information. | ||
12 | * | ||
13 | * PCI initialization for the SnapGear boards | ||
14 | */ | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/types.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/pci.h> | ||
19 | #include "pci-sh4.h" | ||
20 | |||
21 | int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) | ||
22 | { | ||
23 | int irq = -1; | ||
24 | |||
25 | switch (slot) { | ||
26 | case 8: /* the PCI bridge */ break; | ||
27 | case 11: irq = 8; break; /* USB */ | ||
28 | case 12: irq = 11; break; /* PCMCIA */ | ||
29 | case 13: irq = 5; break; /* eth0 */ | ||
30 | case 14: irq = 8; break; /* eth1 */ | ||
31 | case 15: irq = 11; break; /* safenet (unused) */ | ||
32 | } | ||
33 | |||
34 | printk("PCI: Mapping SnapGear IRQ for slot %d, pin %c to irq %d\n", | ||
35 | slot, pin - 1 + 'A', irq); | ||
36 | |||
37 | return irq; | ||
38 | } | ||
diff --git a/arch/sh/drivers/pci/ops-titan.c b/arch/sh/drivers/pci/fixups-titan.c index a8f7801a34af..3a79fa8254a6 100644 --- a/arch/sh/drivers/pci/ops-titan.c +++ b/arch/sh/drivers/pci/fixups-titan.c | |||
@@ -36,42 +36,3 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) | |||
36 | 36 | ||
37 | return irq; | 37 | return irq; |
38 | } | 38 | } |
39 | |||
40 | static struct resource sh7751_io_resource = { | ||
41 | .name = "SH7751_IO", | ||
42 | .start = SH7751_PCI_IO_BASE, | ||
43 | .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, | ||
44 | .flags = IORESOURCE_IO | ||
45 | }; | ||
46 | |||
47 | static struct resource sh7751_mem_resource = { | ||
48 | .name = "SH7751_mem", | ||
49 | .start = SH7751_PCI_MEMORY_BASE, | ||
50 | .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, | ||
51 | .flags = IORESOURCE_MEM | ||
52 | }; | ||
53 | |||
54 | struct pci_channel board_pci_channels[] = { | ||
55 | { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, | ||
56 | { NULL, NULL, NULL, 0, 0 }, | ||
57 | }; | ||
58 | EXPORT_SYMBOL(board_pci_channels); | ||
59 | |||
60 | static struct sh4_pci_address_map sh7751_pci_map = { | ||
61 | .window0 = { | ||
62 | .base = SH7751_CS2_BASE_ADDR, | ||
63 | .size = SH7751_MEM_REGION_SIZE*2, /* cs2 and cs3 */ | ||
64 | }, | ||
65 | |||
66 | .window1 = { | ||
67 | .base = SH7751_CS2_BASE_ADDR, | ||
68 | .size = SH7751_MEM_REGION_SIZE*2, | ||
69 | }, | ||
70 | |||
71 | .flags = SH4_PCIC_NO_RESET, | ||
72 | }; | ||
73 | |||
74 | int __init pcibios_init_platform(void) | ||
75 | { | ||
76 | return sh7751_pcic_init(&sh7751_pci_map); | ||
77 | } | ||
diff --git a/arch/sh/drivers/pci/ops-dreamcast.c b/arch/sh/drivers/pci/ops-dreamcast.c index f5d2a2aa6f3f..e83d0d3aabe2 100644 --- a/arch/sh/drivers/pci/ops-dreamcast.c +++ b/arch/sh/drivers/pci/ops-dreamcast.c | |||
@@ -1,15 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * arch/sh/drivers/pci/ops-dreamcast.c | ||
3 | * | ||
4 | * PCI operations for the Sega Dreamcast | 2 | * PCI operations for the Sega Dreamcast |
5 | * | 3 | * |
6 | * Copyright (C) 2001, 2002 M. R. Brown | 4 | * Copyright (C) 2001, 2002 M. R. Brown |
7 | * Copyright (C) 2002, 2003 Paul Mundt | 5 | * Copyright (C) 2002, 2003 Paul Mundt |
8 | * | 6 | * |
9 | * This file originally bore the message (with enclosed-$): | ||
10 | * Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp | ||
11 | * Dreamcast PCI: Supports SEGA Broadband Adaptor only. | ||
12 | * | ||
13 | * This file is subject to the terms and conditions of the GNU General Public | 7 | * This file is subject to the terms and conditions of the GNU General Public |
14 | * License. See the file "COPYING" in the main directory of this archive | 8 | * License. See the file "COPYING" in the main directory of this archive |
15 | * for more details. | 9 | * for more details. |
@@ -23,34 +17,10 @@ | |||
23 | #include <linux/irq.h> | 17 | #include <linux/irq.h> |
24 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
25 | #include <linux/module.h> | 19 | #include <linux/module.h> |
26 | 20 | #include <linux/io.h> | |
27 | #include <asm/io.h> | 21 | #include <linux/irq.h> |
28 | #include <asm/irq.h> | ||
29 | #include <mach/pci.h> | 22 | #include <mach/pci.h> |
30 | 23 | ||
31 | static struct resource gapspci_io_resource = { | ||
32 | .name = "GAPSPCI IO", | ||
33 | .start = GAPSPCI_BBA_CONFIG, | ||
34 | .end = GAPSPCI_BBA_CONFIG + GAPSPCI_BBA_CONFIG_SIZE - 1, | ||
35 | .flags = IORESOURCE_IO, | ||
36 | }; | ||
37 | |||
38 | static struct resource gapspci_mem_resource = { | ||
39 | .name = "GAPSPCI mem", | ||
40 | .start = GAPSPCI_DMA_BASE, | ||
41 | .end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1, | ||
42 | .flags = IORESOURCE_MEM, | ||
43 | }; | ||
44 | |||
45 | static struct pci_ops gapspci_pci_ops; | ||
46 | |||
47 | struct pci_channel board_pci_channels[] = { | ||
48 | { &gapspci_pci_ops, &gapspci_io_resource, | ||
49 | &gapspci_mem_resource, 0, 1 }, | ||
50 | { 0, } | ||
51 | }; | ||
52 | EXPORT_SYMBOL(board_pci_channels); | ||
53 | |||
54 | /* | 24 | /* |
55 | * The !gapspci_config_access case really shouldn't happen, ever, unless | 25 | * The !gapspci_config_access case really shouldn't happen, ever, unless |
56 | * someone implicitly messes around with the last devfn value.. otherwise we | 26 | * someone implicitly messes around with the last devfn value.. otherwise we |
@@ -85,10 +55,10 @@ static int gapspci_read(struct pci_bus *bus, unsigned int devfn, int where, int | |||
85 | return PCIBIOS_DEVICE_NOT_FOUND; | 55 | return PCIBIOS_DEVICE_NOT_FOUND; |
86 | 56 | ||
87 | switch (size) { | 57 | switch (size) { |
88 | case 1: *val = inb(GAPSPCI_BBA_CONFIG+where); break; | 58 | case 1: *val = inb(GAPSPCI_BBA_CONFIG+where); break; |
89 | case 2: *val = inw(GAPSPCI_BBA_CONFIG+where); break; | 59 | case 2: *val = inw(GAPSPCI_BBA_CONFIG+where); break; |
90 | case 4: *val = inl(GAPSPCI_BBA_CONFIG+where); break; | 60 | case 4: *val = inl(GAPSPCI_BBA_CONFIG+where); break; |
91 | } | 61 | } |
92 | 62 | ||
93 | return PCIBIOS_SUCCESSFUL; | 63 | return PCIBIOS_SUCCESSFUL; |
94 | } | 64 | } |
@@ -99,72 +69,15 @@ static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int | |||
99 | return PCIBIOS_DEVICE_NOT_FOUND; | 69 | return PCIBIOS_DEVICE_NOT_FOUND; |
100 | 70 | ||
101 | switch (size) { | 71 | switch (size) { |
102 | case 1: outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break; | 72 | case 1: outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break; |
103 | case 2: outw((u16)val, GAPSPCI_BBA_CONFIG+where); break; | 73 | case 2: outw((u16)val, GAPSPCI_BBA_CONFIG+where); break; |
104 | case 4: outl((u32)val, GAPSPCI_BBA_CONFIG+where); break; | 74 | case 4: outl((u32)val, GAPSPCI_BBA_CONFIG+where); break; |
105 | } | 75 | } |
106 | 76 | ||
107 | return PCIBIOS_SUCCESSFUL; | 77 | return PCIBIOS_SUCCESSFUL; |
108 | } | 78 | } |
109 | 79 | ||
110 | static struct pci_ops gapspci_pci_ops = { | 80 | struct pci_ops gapspci_pci_ops = { |
111 | .read = gapspci_read, | 81 | .read = gapspci_read, |
112 | .write = gapspci_write, | 82 | .write = gapspci_write, |
113 | }; | 83 | }; |
114 | |||
115 | /* | ||
116 | * gapspci init | ||
117 | */ | ||
118 | |||
119 | int __init gapspci_init(void) | ||
120 | { | ||
121 | char idbuf[16]; | ||
122 | int i; | ||
123 | |||
124 | /* | ||
125 | * FIXME: All of this wants documenting to some degree, | ||
126 | * even some basic register definitions would be nice. | ||
127 | * | ||
128 | * I haven't seen anything this ugly since.. maple. | ||
129 | */ | ||
130 | |||
131 | for (i=0; i<16; i++) | ||
132 | idbuf[i] = inb(GAPSPCI_REGS+i); | ||
133 | |||
134 | if (strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16)) | ||
135 | return -ENODEV; | ||
136 | |||
137 | outl(0x5a14a501, GAPSPCI_REGS+0x18); | ||
138 | |||
139 | for (i=0; i<1000000; i++) | ||
140 | ; | ||
141 | |||
142 | if (inl(GAPSPCI_REGS+0x18) != 1) | ||
143 | return -EINVAL; | ||
144 | |||
145 | outl(0x01000000, GAPSPCI_REGS+0x20); | ||
146 | outl(0x01000000, GAPSPCI_REGS+0x24); | ||
147 | |||
148 | outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28); | ||
149 | outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c); | ||
150 | |||
151 | outl(1, GAPSPCI_REGS+0x14); | ||
152 | outl(1, GAPSPCI_REGS+0x34); | ||
153 | |||
154 | /* Setting Broadband Adapter */ | ||
155 | outw(0xf900, GAPSPCI_BBA_CONFIG+0x06); | ||
156 | outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30); | ||
157 | outb(0x00, GAPSPCI_BBA_CONFIG+0x3c); | ||
158 | outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d); | ||
159 | outw(0x0006, GAPSPCI_BBA_CONFIG+0x04); | ||
160 | outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10); | ||
161 | outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14); | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | /* Haven't done anything here as yet */ | ||
167 | char * __devinit pcibios_setup(char *str) | ||
168 | { | ||
169 | return str; | ||
170 | } | ||
diff --git a/arch/sh/drivers/pci/ops-lboxre2.c b/arch/sh/drivers/pci/ops-lboxre2.c deleted file mode 100644 index 86c0b6fb7375..000000000000 --- a/arch/sh/drivers/pci/ops-lboxre2.c +++ /dev/null | |||
@@ -1,63 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/drivers/pci/ops-lboxre2.c | ||
3 | * | ||
4 | * Copyright (C) 2007 Nobuhiro Iwamatsu | ||
5 | * | ||
6 | * PCI initialization for the NTT COMWARE L-BOX RE2 | ||
7 | */ | ||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/types.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/pci.h> | ||
12 | #include <linux/io.h> | ||
13 | #include <mach/lboxre2.h> | ||
14 | #include "pci-sh4.h" | ||
15 | |||
16 | static char lboxre2_irq_tab[] __initdata = { | ||
17 | IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD, | ||
18 | }; | ||
19 | |||
20 | int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) | ||
21 | { | ||
22 | return lboxre2_irq_tab[slot]; | ||
23 | } | ||
24 | |||
25 | static struct resource sh7751_io_resource = { | ||
26 | .name = "SH7751_IO", | ||
27 | .start = SH7751_PCI_IO_BASE , | ||
28 | .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, | ||
29 | .flags = IORESOURCE_IO | ||
30 | }; | ||
31 | |||
32 | static struct resource sh7751_mem_resource = { | ||
33 | .name = "SH7751_mem", | ||
34 | .start = SH7751_PCI_MEMORY_BASE, | ||
35 | .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, | ||
36 | .flags = IORESOURCE_MEM | ||
37 | }; | ||
38 | |||
39 | extern struct pci_ops sh7751_pci_ops; | ||
40 | |||
41 | struct pci_channel board_pci_channels[] = { | ||
42 | { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, | ||
43 | { NULL, NULL, NULL, 0, 0 }, | ||
44 | }; | ||
45 | |||
46 | EXPORT_SYMBOL(board_pci_channels); | ||
47 | |||
48 | static struct sh4_pci_address_map sh7751_pci_map = { | ||
49 | .window0 = { | ||
50 | .base = SH7751_CS3_BASE_ADDR, | ||
51 | .size = 0x04000000, | ||
52 | }, | ||
53 | .window1 = { | ||
54 | .base = 0x00000000, /* Unused */ | ||
55 | .size = 0x00000000, /* Unused */ | ||
56 | }, | ||
57 | .flags = SH4_PCIC_NO_RESET, | ||
58 | }; | ||
59 | |||
60 | int __init pcibios_init_platform(void) | ||
61 | { | ||
62 | return sh7751_pcic_init(&sh7751_pci_map); | ||
63 | } | ||
diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c deleted file mode 100644 index 8555238e63eb..000000000000 --- a/arch/sh/drivers/pci/ops-r7780rp.c +++ /dev/null | |||
@@ -1,68 +0,0 @@ | |||
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 | #include <linux/kernel.h> | ||
12 | #include <linux/types.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/pci.h> | ||
16 | #include <mach/highlander.h> | ||
17 | #include <asm/io.h> | ||
18 | #include "pci-sh4.h" | ||
19 | |||
20 | static char irq_tab[] __initdata = { | ||
21 | 65, 66, 67, 68, | ||
22 | }; | ||
23 | |||
24 | int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) | ||
25 | { | ||
26 | return irq_tab[slot]; | ||
27 | } | ||
28 | |||
29 | static struct resource sh7780_io_resource = { | ||
30 | .name = "SH7780_IO", | ||
31 | .start = SH7780_PCI_IO_BASE, | ||
32 | .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1, | ||
33 | .flags = IORESOURCE_IO | ||
34 | }; | ||
35 | |||
36 | static struct resource sh7780_mem_resource = { | ||
37 | .name = "SH7780_mem", | ||
38 | .start = SH7780_PCI_MEMORY_BASE, | ||
39 | .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, | ||
40 | .flags = IORESOURCE_MEM | ||
41 | }; | ||
42 | |||
43 | extern struct pci_ops sh7780_pci_ops; | ||
44 | |||
45 | struct pci_channel board_pci_channels[] = { | ||
46 | { &sh4_pci_ops, &sh7780_io_resource, &sh7780_mem_resource, 0, 0xff }, | ||
47 | { NULL, NULL, NULL, 0, 0 }, | ||
48 | }; | ||
49 | EXPORT_SYMBOL(board_pci_channels); | ||
50 | |||
51 | static struct sh4_pci_address_map sh7780_pci_map = { | ||
52 | .window0 = { | ||
53 | .base = SH7780_CS2_BASE_ADDR, | ||
54 | .size = 0x04000000, | ||
55 | }, | ||
56 | |||
57 | .window1 = { | ||
58 | .base = SH7780_CS3_BASE_ADDR, | ||
59 | .size = 0x04000000, | ||
60 | }, | ||
61 | |||
62 | .flags = SH4_PCIC_NO_RESET, | ||
63 | }; | ||
64 | |||
65 | int __init pcibios_init_platform(void) | ||
66 | { | ||
67 | return sh7780_pcic_init(&sh7780_pci_map); | ||
68 | } | ||
diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c deleted file mode 100644 index d6ca74b25d5f..000000000000 --- a/arch/sh/drivers/pci/ops-rts7751r2d.c +++ /dev/null | |||
@@ -1,74 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/drivers/pci/ops-rts7751r2d.c | ||
3 | * | ||
4 | * Author: Ian DaSilva (idasilva@mvista.com) | ||
5 | * | ||
6 | * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. | ||
7 | * | ||
8 | * May be copied or modified under the terms of the GNU General Public | ||
9 | * License. See linux/COPYING for more information. | ||
10 | * | ||
11 | * PCI initialization for the Renesas SH7751R RTS7751R2D board | ||
12 | */ | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/pci.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <mach/r2d.h> | ||
19 | #include "pci-sh4.h" | ||
20 | |||
21 | static u8 rts7751r2d_irq_tab[] __initdata = { | ||
22 | IRQ_PCI_INTA, | ||
23 | IRQ_PCI_INTB, | ||
24 | IRQ_PCI_INTC, | ||
25 | IRQ_PCI_INTD, | ||
26 | }; | ||
27 | |||
28 | int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) | ||
29 | { | ||
30 | return rts7751r2d_irq_tab[slot]; | ||
31 | } | ||
32 | |||
33 | static struct resource sh7751_io_resource = { | ||
34 | .name = "SH7751_IO", | ||
35 | .start = 0x4000, | ||
36 | .end = SH7751_PCI_IO_SIZE - 1, | ||
37 | .flags = IORESOURCE_IO | ||
38 | }; | ||
39 | |||
40 | static struct resource sh7751_mem_resource = { | ||
41 | .name = "SH7751_mem", | ||
42 | .start = SH7751_PCI_MEMORY_BASE, | ||
43 | .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, | ||
44 | .flags = IORESOURCE_MEM | ||
45 | }; | ||
46 | |||
47 | extern struct pci_ops sh7751_pci_ops; | ||
48 | |||
49 | struct pci_channel board_pci_channels[] = { | ||
50 | { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, | ||
51 | { NULL, NULL, NULL, 0, 0 }, | ||
52 | }; | ||
53 | EXPORT_SYMBOL(board_pci_channels); | ||
54 | |||
55 | static struct sh4_pci_address_map sh7751_pci_map = { | ||
56 | .window0 = { | ||
57 | .base = SH7751_CS3_BASE_ADDR, | ||
58 | .size = 0x04000000, | ||
59 | }, | ||
60 | |||
61 | .window1 = { | ||
62 | .base = 0x00000000, /* Unused */ | ||
63 | .size = 0x00000000, /* Unused */ | ||
64 | }, | ||
65 | |||
66 | .flags = SH4_PCIC_NO_RESET, | ||
67 | }; | ||
68 | |||
69 | int __init pcibios_init_platform(void) | ||
70 | { | ||
71 | __set_io_port_base(SH7751_PCI_IO_BASE); | ||
72 | return sh7751_pcic_init(&sh7751_pci_map); | ||
73 | } | ||
74 | |||
diff --git a/arch/sh/drivers/pci/ops-sdk7780.c b/arch/sh/drivers/pci/ops-sdk7780.c deleted file mode 100644 index 4dcc64184b23..000000000000 --- a/arch/sh/drivers/pci/ops-sdk7780.c +++ /dev/null | |||
@@ -1,73 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/drivers/pci/ops-sdk7780.c | ||
3 | * | ||
4 | * Copyright (C) 2006 Nobuhiro Iwamatsu | ||
5 | * | ||
6 | * PCI initialization for the SDK7780SE03 | ||
7 | * | ||
8 | * May be copied or modified under the terms of the GNU General Public | ||
9 | * License. See linux/COPYING for more information. | ||
10 | */ | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/types.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/pci.h> | ||
16 | #include <mach/sdk7780.h> | ||
17 | #include <asm/io.h> | ||
18 | #include "pci-sh4.h" | ||
19 | |||
20 | /* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */ | ||
21 | static char sdk7780_irq_tab[4][16] __initdata = { | ||
22 | /* INTA */ | ||
23 | { 65, 68, 67, 68, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||
24 | /* INTB */ | ||
25 | { 66, 65, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||
26 | /* INTC */ | ||
27 | { 67, 66, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||
28 | /* INTD */ | ||
29 | { 68, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||
30 | }; | ||
31 | |||
32 | int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) | ||
33 | { | ||
34 | return sdk7780_irq_tab[pin-1][slot]; | ||
35 | } | ||
36 | |||
37 | static struct resource sdk7780_io_resource = { | ||
38 | .name = "SH7780_IO", | ||
39 | .start = SH7780_PCI_IO_BASE, | ||
40 | .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1, | ||
41 | .flags = IORESOURCE_IO | ||
42 | }; | ||
43 | |||
44 | static struct resource sdk7780_mem_resource = { | ||
45 | .name = "SH7780_mem", | ||
46 | .start = SH7780_PCI_MEMORY_BASE, | ||
47 | .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, | ||
48 | .flags = IORESOURCE_MEM | ||
49 | }; | ||
50 | |||
51 | struct pci_channel board_pci_channels[] = { | ||
52 | { &sh4_pci_ops, &sdk7780_io_resource, &sdk7780_mem_resource, 0, 0xff }, | ||
53 | { NULL, NULL, NULL, 0, 0 }, | ||
54 | }; | ||
55 | EXPORT_SYMBOL(board_pci_channels); | ||
56 | |||
57 | static struct sh4_pci_address_map sdk7780_pci_map = { | ||
58 | .window0 = { | ||
59 | .base = SH7780_CS2_BASE_ADDR, | ||
60 | .size = 0x04000000, | ||
61 | }, | ||
62 | .window1 = { | ||
63 | .base = SH7780_CS3_BASE_ADDR, | ||
64 | .size = 0x04000000, | ||
65 | }, | ||
66 | .flags = SH4_PCIC_NO_RESET, | ||
67 | }; | ||
68 | |||
69 | int __init pcibios_init_platform(void) | ||
70 | { | ||
71 | printk(KERN_INFO "SH7780 PCI: Finished initializing PCI controller\n"); | ||
72 | return sh7780_pcic_init(&sdk7780_pci_map); | ||
73 | } | ||
diff --git a/arch/sh/drivers/pci/ops-se7780.c b/arch/sh/drivers/pci/ops-se7780.c deleted file mode 100644 index 3145c62484d6..000000000000 --- a/arch/sh/drivers/pci/ops-se7780.c +++ /dev/null | |||
@@ -1,96 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/drivers/pci/ops-se7780.c | ||
3 | * | ||
4 | * Copyright (C) 2006 Nobuhiro Iwamatsu | ||
5 | * | ||
6 | * PCI initialization for the Hitachi UL Solution Engine 7780SE03 | ||
7 | * | ||
8 | * May be copied or modified under the terms of the GNU General Public | ||
9 | * License. See linux/COPYING for more information. | ||
10 | */ | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/types.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/pci.h> | ||
16 | #include <mach-se/mach/se7780.h> | ||
17 | #include <asm/io.h> | ||
18 | #include "pci-sh4.h" | ||
19 | |||
20 | /* | ||
21 | * IDSEL = AD16 PCI slot | ||
22 | * IDSEL = AD17 PCI slot | ||
23 | * IDSEL = AD18 Serial ATA Controller (Silicon Image SiL3512A) | ||
24 | * IDSEL = AD19 USB Host Controller (NEC uPD7210100A) | ||
25 | */ | ||
26 | |||
27 | /* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */ | ||
28 | static char se7780_irq_tab[4][16] __initdata = { | ||
29 | /* INTA */ | ||
30 | { 65, 68, 67, 68, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||
31 | /* INTB */ | ||
32 | { 66, 65, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||
33 | /* INTC */ | ||
34 | { 67, 66, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||
35 | /* INTD */ | ||
36 | { 68, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||
37 | }; | ||
38 | |||
39 | int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) | ||
40 | { | ||
41 | return se7780_irq_tab[pin-1][slot]; | ||
42 | } | ||
43 | |||
44 | static struct resource se7780_io_resource = { | ||
45 | .name = "SH7780_IO", | ||
46 | .start = SH7780_PCI_IO_BASE, | ||
47 | .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1, | ||
48 | .flags = IORESOURCE_IO | ||
49 | }; | ||
50 | |||
51 | static struct resource se7780_mem_resource = { | ||
52 | .name = "SH7780_mem", | ||
53 | .start = SH7780_PCI_MEMORY_BASE, | ||
54 | .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, | ||
55 | .flags = IORESOURCE_MEM | ||
56 | }; | ||
57 | |||
58 | extern struct pci_ops se7780_pci_ops; | ||
59 | |||
60 | struct pci_channel board_pci_channels[] = { | ||
61 | { &sh4_pci_ops, &se7780_io_resource, &se7780_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 se7780_pci_map = { | ||
67 | .window0 = { | ||
68 | .base = SH7780_CS2_BASE_ADDR, | ||
69 | .size = 0x04000000, | ||
70 | }, | ||
71 | .flags = SH4_PCIC_NO_RESET, | ||
72 | }; | ||
73 | |||
74 | int __init pcibios_init_platform(void) | ||
75 | { | ||
76 | printk("SH7780 PCI: Finished initialization of the PCI controller\n"); | ||
77 | |||
78 | /* | ||
79 | * FPGA PCISEL register initialize | ||
80 | * | ||
81 | * CPU || SLOT1 | SLOT2 | S-ATA | USB | ||
82 | * ------------------------------------- | ||
83 | * INTA || INTA | INTD | -- | INTB | ||
84 | * ------------------------------------- | ||
85 | * INTB || INTB | INTA | -- | INTC | ||
86 | * ------------------------------------- | ||
87 | * INTC || INTC | INTB | INTA | -- | ||
88 | * ------------------------------------- | ||
89 | * INTD || INTD | INTC | -- | INTA | ||
90 | * ------------------------------------- | ||
91 | */ | ||
92 | ctrl_outw(0x0013, FPGA_PCI_INTSEL1); | ||
93 | ctrl_outw(0xE402, FPGA_PCI_INTSEL2); | ||
94 | |||
95 | return sh7780_pcic_init(&se7780_pci_map); | ||
96 | } | ||
diff --git a/arch/sh/drivers/pci/ops-sh03.c b/arch/sh/drivers/pci/ops-sh03.c deleted file mode 100644 index e1703ff5a4d2..000000000000 --- a/arch/sh/drivers/pci/ops-sh03.c +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/drivers/pci/ops-sh03.c | ||
3 | * | ||
4 | * PCI initialization for the Interface CTP/PCI-SH03 board | ||
5 | */ | ||
6 | |||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/types.h> | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/delay.h> | ||
11 | #include <linux/pci.h> | ||
12 | #include <asm/io.h> | ||
13 | #include "pci-sh7751.h" | ||
14 | |||
15 | /* | ||
16 | * Description: This function sets up and initializes the pcic, sets | ||
17 | * up the BARS, maps the DRAM into the address space etc, etc. | ||
18 | */ | ||
19 | int __init pcibios_init_platform(void) | ||
20 | { | ||
21 | __set_io_port_base(SH7751_PCI_IO_BASE); | ||
22 | return 1; | ||
23 | } | ||
24 | |||
25 | static struct resource sh7751_io_resource = { | ||
26 | .name = "SH03 IO", | ||
27 | .start = SH7751_PCI_IO_BASE, | ||
28 | .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, | ||
29 | .flags = IORESOURCE_IO | ||
30 | }; | ||
31 | |||
32 | static struct resource sh7751_mem_resource = { | ||
33 | .name = "SH03 mem", | ||
34 | .start = SH7751_PCI_MEMORY_BASE, | ||
35 | .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, | ||
36 | .flags = IORESOURCE_MEM | ||
37 | }; | ||
38 | |||
39 | extern struct pci_ops sh4_pci_ops; | ||
40 | |||
41 | struct pci_channel board_pci_channels[] = { | ||
42 | { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, | ||
43 | { NULL, NULL, NULL, 0, 0 }, | ||
44 | }; | ||
45 | |||
diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c index 710a3b0306e5..78bebebdc99c 100644 --- a/arch/sh/drivers/pci/ops-sh4.c +++ b/arch/sh/drivers/pci/ops-sh4.c | |||
@@ -1,22 +1,22 @@ | |||
1 | /* | 1 | /* |
2 | * Generic SH-4 / SH-4A PCIC operations (SH7751, SH7780). | 2 | * Generic SH-4 / SH-4A PCIC operations (SH7751, SH7780). |
3 | * | 3 | * |
4 | * Copyright (C) 2002 - 2006 Paul Mundt | 4 | * Copyright (C) 2002 - 2009 Paul Mundt |
5 | * | 5 | * |
6 | * This file is subject to the terms and conditions of the GNU General Public | 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 | 7 | * License v2. See the file "COPYING" in the main directory of this archive |
8 | * for more details. | 8 | * for more details. |
9 | */ | 9 | */ |
10 | #include <linux/pci.h> | 10 | #include <linux/pci.h> |
11 | #include <linux/io.h> | ||
11 | #include <asm/addrspace.h> | 12 | #include <asm/addrspace.h> |
12 | #include <asm/io.h> | ||
13 | #include "pci-sh4.h" | 13 | #include "pci-sh4.h" |
14 | 14 | ||
15 | /* | 15 | /* |
16 | * Direct access to PCI hardware... | 16 | * Direct access to PCI hardware... |
17 | */ | 17 | */ |
18 | #define CONFIG_CMD(bus, devfn, where) \ | 18 | #define CONFIG_CMD(bus, devfn, where) \ |
19 | P1SEGADDR((bus->number << 16) | (devfn << 8) | (where & ~3)) | 19 | (P1SEG | (bus->number << 16) | (devfn << 8) | (where & ~3)) |
20 | 20 | ||
21 | static DEFINE_SPINLOCK(sh4_pci_lock); | 21 | static DEFINE_SPINLOCK(sh4_pci_lock); |
22 | 22 | ||
@@ -26,6 +26,7 @@ static DEFINE_SPINLOCK(sh4_pci_lock); | |||
26 | static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn, | 26 | static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn, |
27 | int where, int size, u32 *val) | 27 | int where, int size, u32 *val) |
28 | { | 28 | { |
29 | struct pci_channel *chan = bus->sysdata; | ||
29 | unsigned long flags; | 30 | unsigned long flags; |
30 | u32 data; | 31 | u32 data; |
31 | 32 | ||
@@ -34,8 +35,8 @@ static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn, | |||
34 | * so we must do byte alignment by hand | 35 | * so we must do byte alignment by hand |
35 | */ | 36 | */ |
36 | spin_lock_irqsave(&sh4_pci_lock, flags); | 37 | spin_lock_irqsave(&sh4_pci_lock, flags); |
37 | pci_write_reg(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); | 38 | pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); |
38 | data = pci_read_reg(SH4_PCIPDR); | 39 | data = pci_read_reg(chan, SH4_PCIPDR); |
39 | spin_unlock_irqrestore(&sh4_pci_lock, flags); | 40 | spin_unlock_irqrestore(&sh4_pci_lock, flags); |
40 | 41 | ||
41 | switch (size) { | 42 | switch (size) { |
@@ -63,13 +64,14 @@ static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn, | |||
63 | static int sh4_pci_write(struct pci_bus *bus, unsigned int devfn, | 64 | static int sh4_pci_write(struct pci_bus *bus, unsigned int devfn, |
64 | int where, int size, u32 val) | 65 | int where, int size, u32 val) |
65 | { | 66 | { |
67 | struct pci_channel *chan = bus->sysdata; | ||
66 | unsigned long flags; | 68 | unsigned long flags; |
67 | int shift; | 69 | int shift; |
68 | u32 data; | 70 | u32 data; |
69 | 71 | ||
70 | spin_lock_irqsave(&sh4_pci_lock, flags); | 72 | spin_lock_irqsave(&sh4_pci_lock, flags); |
71 | pci_write_reg(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); | 73 | pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); |
72 | data = pci_read_reg(SH4_PCIPDR); | 74 | data = pci_read_reg(chan, SH4_PCIPDR); |
73 | spin_unlock_irqrestore(&sh4_pci_lock, flags); | 75 | spin_unlock_irqrestore(&sh4_pci_lock, flags); |
74 | 76 | ||
75 | switch (size) { | 77 | switch (size) { |
@@ -90,7 +92,7 @@ static int sh4_pci_write(struct pci_bus *bus, unsigned int devfn, | |||
90 | return PCIBIOS_FUNC_NOT_SUPPORTED; | 92 | return PCIBIOS_FUNC_NOT_SUPPORTED; |
91 | } | 93 | } |
92 | 94 | ||
93 | pci_write_reg(data, SH4_PCIPDR); | 95 | pci_write_reg(chan, data, SH4_PCIPDR); |
94 | 96 | ||
95 | return PCIBIOS_SUCCESSFUL; | 97 | return PCIBIOS_SUCCESSFUL; |
96 | } | 98 | } |
@@ -104,66 +106,31 @@ struct pci_ops sh4_pci_ops = { | |||
104 | * Not really related to pci_ops, but it's common and not worth shoving | 106 | * Not really related to pci_ops, but it's common and not worth shoving |
105 | * somewhere else for now.. | 107 | * somewhere else for now.. |
106 | */ | 108 | */ |
107 | static unsigned int pci_probe = PCI_PROBE_CONF1; | 109 | int __init sh4_pci_check_direct(struct pci_channel *chan) |
108 | |||
109 | int __init sh4_pci_check_direct(void) | ||
110 | { | 110 | { |
111 | /* | 111 | /* |
112 | * Check if configuration works. | 112 | * Check if configuration works. |
113 | */ | 113 | */ |
114 | if (pci_probe & PCI_PROBE_CONF1) { | 114 | unsigned int tmp = pci_read_reg(chan, SH4_PCIPAR); |
115 | unsigned int tmp = pci_read_reg(SH4_PCIPAR); | ||
116 | |||
117 | pci_write_reg(P1SEG, SH4_PCIPAR); | ||
118 | 115 | ||
119 | if (pci_read_reg(SH4_PCIPAR) == P1SEG) { | 116 | pci_write_reg(chan, P1SEG, SH4_PCIPAR); |
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 | 117 | ||
124 | return 0; | 118 | if (pci_read_reg(chan, SH4_PCIPAR) == P1SEG) { |
125 | } | 119 | pci_write_reg(chan, tmp, SH4_PCIPAR); |
126 | 120 | printk(KERN_INFO "PCI: Using configuration type 1\n"); | |
127 | pci_write_reg(tmp, SH4_PCIPAR); | 121 | request_region(chan->reg_base + SH4_PCIPAR, 8, |
122 | "PCI conf1"); | ||
123 | return 0; | ||
128 | } | 124 | } |
129 | 125 | ||
130 | pr_debug("PCI: pci_check_direct failed\n"); | 126 | pci_write_reg(chan, tmp, SH4_PCIPAR); |
131 | return -EINVAL; | ||
132 | } | ||
133 | 127 | ||
134 | /* Handle generic fixups */ | 128 | printk(KERN_ERR "PCI: %s failed\n", __func__); |
135 | static void __init pci_fixup_ide_bases(struct pci_dev *d) | ||
136 | { | ||
137 | int i; | ||
138 | 129 | ||
139 | /* | 130 | return -EINVAL; |
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 * __devinit pcibios_setup(char *str) | ||
157 | { | ||
158 | if (!strcmp(str, "off")) { | ||
159 | pci_probe = 0; | ||
160 | return NULL; | ||
161 | } | ||
162 | |||
163 | return str; | ||
164 | } | 131 | } |
165 | 132 | ||
166 | int __attribute__((weak)) pci_fixup_pcic(void) | 133 | int __attribute__((weak)) pci_fixup_pcic(struct pci_channel *chan) |
167 | { | 134 | { |
168 | /* Nothing to do. */ | 135 | /* Nothing to do. */ |
169 | return 0; | 136 | return 0; |
diff --git a/arch/sh/drivers/pci/ops-sh5.c b/arch/sh/drivers/pci/ops-sh5.c index 729e38a6fe07..4ce95a001b80 100644 --- a/arch/sh/drivers/pci/ops-sh5.c +++ b/arch/sh/drivers/pci/ops-sh5.c | |||
@@ -22,31 +22,6 @@ | |||
22 | #include <asm/io.h> | 22 | #include <asm/io.h> |
23 | #include "pci-sh5.h" | 23 | #include "pci-sh5.h" |
24 | 24 | ||
25 | static void __init pci_fixup_ide_bases(struct pci_dev *d) | ||
26 | { | ||
27 | int i; | ||
28 | |||
29 | /* | ||
30 | * PCI IDE controllers use non-standard I/O port decoding, respect it. | ||
31 | */ | ||
32 | if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE) | ||
33 | return; | ||
34 | printk("PCI: IDE base address fixup for %s\n", pci_name(d)); | ||
35 | for(i=0; i<4; i++) { | ||
36 | struct resource *r = &d->resource[i]; | ||
37 | if ((r->start & ~0x80) == 0x374) { | ||
38 | r->start |= 2; | ||
39 | r->end = r->start; | ||
40 | } | ||
41 | } | ||
42 | } | ||
43 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); | ||
44 | |||
45 | char * __devinit pcibios_setup(char *str) | ||
46 | { | ||
47 | return str; | ||
48 | } | ||
49 | |||
50 | static int sh5pci_read(struct pci_bus *bus, unsigned int devfn, int where, | 25 | static int sh5pci_read(struct pci_bus *bus, unsigned int devfn, int where, |
51 | int size, u32 *val) | 26 | int size, u32 *val) |
52 | { | 27 | { |
diff --git a/arch/sh/drivers/pci/ops-sh7785lcr.c b/arch/sh/drivers/pci/ops-sh7785lcr.c deleted file mode 100644 index fb0869f0bef8..000000000000 --- a/arch/sh/drivers/pci/ops-sh7785lcr.c +++ /dev/null | |||
@@ -1,66 +0,0 @@ | |||
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 R0P7785LC0011RL board | ||
10 | * Based on arch/sh/drivers/pci/ops-r7780rp.c | ||
11 | * | ||
12 | */ | ||
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 "pci-sh4.h" | ||
19 | |||
20 | static char irq_tab[] __initdata = { | ||
21 | 65, 66, 67, 68, | ||
22 | }; | ||
23 | |||
24 | int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) | ||
25 | { | ||
26 | return irq_tab[slot]; | ||
27 | } | ||
28 | |||
29 | static struct resource sh7785_io_resource = { | ||
30 | .name = "SH7785_IO", | ||
31 | .start = SH7780_PCI_IO_BASE, | ||
32 | .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1, | ||
33 | .flags = IORESOURCE_IO | ||
34 | }; | ||
35 | |||
36 | static struct resource sh7785_mem_resource = { | ||
37 | .name = "SH7785_mem", | ||
38 | .start = SH7780_PCI_MEMORY_BASE, | ||
39 | .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, | ||
40 | .flags = IORESOURCE_MEM | ||
41 | }; | ||
42 | |||
43 | struct pci_channel board_pci_channels[] = { | ||
44 | { &sh4_pci_ops, &sh7785_io_resource, &sh7785_mem_resource, 0, 0xff }, | ||
45 | { NULL, NULL, NULL, 0, 0 }, | ||
46 | }; | ||
47 | EXPORT_SYMBOL(board_pci_channels); | ||
48 | |||
49 | static struct sh4_pci_address_map sh7785_pci_map = { | ||
50 | .window0 = { | ||
51 | #if defined(CONFIG_32BIT) | ||
52 | .base = SH7780_32BIT_DDR_BASE_ADDR, | ||
53 | .size = 0x40000000, | ||
54 | #else | ||
55 | .base = SH7780_CS0_BASE_ADDR, | ||
56 | .size = 0x20000000, | ||
57 | #endif | ||
58 | }, | ||
59 | |||
60 | .flags = SH4_PCIC_NO_RESET, | ||
61 | }; | ||
62 | |||
63 | int __init pcibios_init_platform(void) | ||
64 | { | ||
65 | return sh7780_pcic_init(&sh7785_pci_map); | ||
66 | } | ||
diff --git a/arch/sh/drivers/pci/ops-snapgear.c b/arch/sh/drivers/pci/ops-snapgear.c deleted file mode 100644 index 53dd893d4e54..000000000000 --- a/arch/sh/drivers/pci/ops-snapgear.c +++ /dev/null | |||
@@ -1,94 +0,0 @@ | |||
1 | /* | ||
2 | * arch/sh/drivers/pci/ops-snapgear.c | ||
3 | * | ||
4 | * Author: David McCullough <davidm@snapgear.com> | ||
5 | * | ||
6 | * Ported to new API by Paul Mundt <lethal@linux-sh.org> | ||
7 | * | ||
8 | * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. | ||
9 | * | ||
10 | * May be copied or modified under the terms of the GNU General Public | ||
11 | * License. See linux/COPYING for more information. | ||
12 | * | ||
13 | * PCI initialization for the SnapGear boards | ||
14 | */ | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/types.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/pci.h> | ||
19 | #include "pci-sh4.h" | ||
20 | |||
21 | #define SNAPGEAR_PCI_IO 0x4000 | ||
22 | #define SNAPGEAR_PCI_MEM 0xfd000000 | ||
23 | |||
24 | /* PCI: default LOCAL memory window sizes (seen from PCI bus) */ | ||
25 | #define SNAPGEAR_LSR0_SIZE (64*(1<<20)) //64MB | ||
26 | #define SNAPGEAR_LSR1_SIZE (64*(1<<20)) //64MB | ||
27 | |||
28 | static struct resource sh7751_io_resource = { | ||
29 | .name = "SH7751 IO", | ||
30 | .start = SNAPGEAR_PCI_IO, | ||
31 | .end = SNAPGEAR_PCI_IO + (64*1024) - 1, /* 64KiB I/O */ | ||
32 | .flags = IORESOURCE_IO, | ||
33 | }; | ||
34 | |||
35 | static struct resource sh7751_mem_resource = { | ||
36 | .name = "SH7751 mem", | ||
37 | .start = SNAPGEAR_PCI_MEM, | ||
38 | .end = SNAPGEAR_PCI_MEM + (64*1024*1024) - 1, /* 64MiB mem */ | ||
39 | .flags = IORESOURCE_MEM, | ||
40 | }; | ||
41 | |||
42 | struct pci_channel board_pci_channels[] = { | ||
43 | { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, | ||
44 | { 0, } | ||
45 | }; | ||
46 | |||
47 | static struct sh4_pci_address_map sh7751_pci_map = { | ||
48 | .window0 = { | ||
49 | .base = SH7751_CS2_BASE_ADDR, | ||
50 | .size = SNAPGEAR_LSR0_SIZE, | ||
51 | }, | ||
52 | |||
53 | .window1 = { | ||
54 | .base = SH7751_CS2_BASE_ADDR, | ||
55 | .size = SNAPGEAR_LSR1_SIZE, | ||
56 | }, | ||
57 | |||
58 | .flags = SH4_PCIC_NO_RESET, | ||
59 | }; | ||
60 | |||
61 | /* | ||
62 | * Initialize the SnapGear PCI interface | ||
63 | * Setup hardware to be Central Funtion | ||
64 | * Copy the BSR regs to the PCI interface | ||
65 | * Setup PCI windows into local RAM | ||
66 | */ | ||
67 | int __init pcibios_init_platform(void) | ||
68 | { | ||
69 | return sh7751_pcic_init(&sh7751_pci_map); | ||
70 | } | ||
71 | |||
72 | int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) | ||
73 | { | ||
74 | int irq = -1; | ||
75 | |||
76 | switch (slot) { | ||
77 | case 8: /* the PCI bridge */ break; | ||
78 | case 11: irq = 8; break; /* USB */ | ||
79 | case 12: irq = 11; break; /* PCMCIA */ | ||
80 | case 13: irq = 5; break; /* eth0 */ | ||
81 | case 14: irq = 8; break; /* eth1 */ | ||
82 | case 15: irq = 11; break; /* safenet (unused) */ | ||
83 | } | ||
84 | |||
85 | printk("PCI: Mapping SnapGear IRQ for slot %d, pin %c to irq %d\n", | ||
86 | slot, pin - 1 + 'A', irq); | ||
87 | |||
88 | return irq; | ||
89 | } | ||
90 | |||
91 | void __init pcibios_fixup(void) | ||
92 | { | ||
93 | /* Nothing to fixup .. */ | ||
94 | } | ||
diff --git a/arch/sh/drivers/pci/pci-auto.c b/arch/sh/drivers/pci/pci-auto.c deleted file mode 100644 index cf48b12ee58c..000000000000 --- a/arch/sh/drivers/pci/pci-auto.c +++ /dev/null | |||
@@ -1,545 +0,0 @@ | |||
1 | /* | ||
2 | * PCI autoconfiguration library | ||
3 | * | ||
4 | * Author: Matt Porter <mporter@mvista.com> | ||
5 | * | ||
6 | * Copyright 2000, 2001 MontaVista Software Inc. | ||
7 | * Copyright 2001 Bradley D. LaRonde <brad@ltc.com> | ||
8 | * Copyright 2003 Paul Mundt <lethal@linux-sh.org> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | */ | ||
15 | |||
16 | /* | ||
17 | * Modified for MIPS by Jun Sun, jsun@mvista.com | ||
18 | * | ||
19 | * . Simplify the interface between pci_auto and the rest: a single function. | ||
20 | * . Assign resources from low address to upper address. | ||
21 | * . change most int to u32. | ||
22 | * | ||
23 | * Further modified to include it as mips generic code, ppopov@mvista.com. | ||
24 | * | ||
25 | * 2001-10-26 Bradley D. LaRonde <brad@ltc.com> | ||
26 | * - Add a top_bus argument to the "early config" functions so that | ||
27 | * they can set a fake parent bus pointer to convince the underlying | ||
28 | * pci ops to use type 1 configuration for sub busses. | ||
29 | * - Set bridge base and limit registers correctly. | ||
30 | * - Align io and memory base properly before and after bridge setup. | ||
31 | * - Don't fall through to pci_setup_bars for bridge. | ||
32 | * - Reformat the debug output to look more like lspci's output. | ||
33 | * | ||
34 | * Cloned for SuperH by M. R. Brown, mrbrown@0xd6.org | ||
35 | * | ||
36 | * 2003-08-05 Paul Mundt <lethal@linux-sh.org> | ||
37 | * - Don't update the BAR values on systems that already have valid addresses | ||
38 | * and don't want these updated for whatever reason, by way of a new config | ||
39 | * option check. However, we still read in the old BAR values so that they | ||
40 | * can still be reported through the debug output. | ||
41 | */ | ||
42 | |||
43 | #include <linux/kernel.h> | ||
44 | #include <linux/init.h> | ||
45 | #include <linux/types.h> | ||
46 | #include <linux/pci.h> | ||
47 | |||
48 | #define DEBUG | ||
49 | #ifdef DEBUG | ||
50 | #define DBG(x...) printk(x) | ||
51 | #else | ||
52 | #define DBG(x...) | ||
53 | #endif | ||
54 | |||
55 | /* | ||
56 | * These functions are used early on before PCI scanning is done | ||
57 | * and all of the pci_dev and pci_bus structures have been created. | ||
58 | */ | ||
59 | static struct pci_dev *fake_pci_dev(struct pci_channel *hose, | ||
60 | int top_bus, int busnr, int devfn) | ||
61 | { | ||
62 | static struct pci_dev dev; | ||
63 | static struct pci_bus bus; | ||
64 | |||
65 | dev.bus = &bus; | ||
66 | dev.sysdata = hose; | ||
67 | dev.devfn = devfn; | ||
68 | bus.number = busnr; | ||
69 | bus.ops = hose->pci_ops; | ||
70 | |||
71 | if(busnr != top_bus) | ||
72 | /* Fake a parent bus structure. */ | ||
73 | bus.parent = &bus; | ||
74 | else | ||
75 | bus.parent = NULL; | ||
76 | |||
77 | return &dev; | ||
78 | } | ||
79 | |||
80 | #define EARLY_PCI_OP(rw, size, type) \ | ||
81 | static int early_##rw##_config_##size(struct pci_channel *hose, \ | ||
82 | int top_bus, int bus, int devfn, int offset, type value) \ | ||
83 | { \ | ||
84 | return pci_##rw##_config_##size( \ | ||
85 | fake_pci_dev(hose, top_bus, bus, devfn), \ | ||
86 | offset, value); \ | ||
87 | } | ||
88 | |||
89 | EARLY_PCI_OP(read, byte, u8 *) | ||
90 | EARLY_PCI_OP(read, word, u16 *) | ||
91 | EARLY_PCI_OP(read, dword, u32 *) | ||
92 | EARLY_PCI_OP(write, byte, u8) | ||
93 | EARLY_PCI_OP(write, word, u16) | ||
94 | EARLY_PCI_OP(write, dword, u32) | ||
95 | |||
96 | static struct resource *io_resource_inuse; | ||
97 | static struct resource *mem_resource_inuse; | ||
98 | |||
99 | static u32 pciauto_lower_iospc; | ||
100 | static u32 pciauto_upper_iospc; | ||
101 | |||
102 | static u32 pciauto_lower_memspc; | ||
103 | static u32 pciauto_upper_memspc; | ||
104 | |||
105 | static void __init | ||
106 | pciauto_setup_bars(struct pci_channel *hose, | ||
107 | int top_bus, | ||
108 | int current_bus, | ||
109 | int pci_devfn, | ||
110 | int bar_limit) | ||
111 | { | ||
112 | u32 bar_response, bar_size, bar_value; | ||
113 | u32 bar, addr_mask, bar_nr = 0; | ||
114 | u32 * upper_limit; | ||
115 | u32 * lower_limit; | ||
116 | int found_mem64 = 0; | ||
117 | |||
118 | for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4) { | ||
119 | u32 bar_addr; | ||
120 | |||
121 | /* Read the old BAR value */ | ||
122 | early_read_config_dword(hose, top_bus, | ||
123 | current_bus, | ||
124 | pci_devfn, | ||
125 | bar, | ||
126 | &bar_addr); | ||
127 | |||
128 | /* Tickle the BAR and get the response */ | ||
129 | early_write_config_dword(hose, top_bus, | ||
130 | current_bus, | ||
131 | pci_devfn, | ||
132 | bar, | ||
133 | 0xffffffff); | ||
134 | |||
135 | early_read_config_dword(hose, top_bus, | ||
136 | current_bus, | ||
137 | pci_devfn, | ||
138 | bar, | ||
139 | &bar_response); | ||
140 | |||
141 | /* | ||
142 | * Write the old BAR value back out, only update the BAR | ||
143 | * if we implicitly want resources to be updated, which | ||
144 | * is done by the generic code further down. -- PFM. | ||
145 | */ | ||
146 | early_write_config_dword(hose, top_bus, | ||
147 | current_bus, | ||
148 | pci_devfn, | ||
149 | bar, | ||
150 | bar_addr); | ||
151 | |||
152 | /* If BAR is not implemented go to the next BAR */ | ||
153 | if (!bar_response) | ||
154 | continue; | ||
155 | |||
156 | /* | ||
157 | * Workaround for a BAR that doesn't use its upper word, | ||
158 | * like the ALi 1535D+ PCI DC-97 Controller Modem (M5457). | ||
159 | * bdl <brad@ltc.com> | ||
160 | */ | ||
161 | if (!(bar_response & 0xffff0000)) | ||
162 | bar_response |= 0xffff0000; | ||
163 | |||
164 | retry: | ||
165 | /* Check the BAR type and set our address mask */ | ||
166 | if (bar_response & PCI_BASE_ADDRESS_SPACE) { | ||
167 | addr_mask = PCI_BASE_ADDRESS_IO_MASK; | ||
168 | upper_limit = &pciauto_upper_iospc; | ||
169 | lower_limit = &pciauto_lower_iospc; | ||
170 | DBG(" I/O"); | ||
171 | } else { | ||
172 | if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == | ||
173 | PCI_BASE_ADDRESS_MEM_TYPE_64) | ||
174 | found_mem64 = 1; | ||
175 | |||
176 | addr_mask = PCI_BASE_ADDRESS_MEM_MASK; | ||
177 | upper_limit = &pciauto_upper_memspc; | ||
178 | lower_limit = &pciauto_lower_memspc; | ||
179 | DBG(" Mem"); | ||
180 | } | ||
181 | |||
182 | |||
183 | /* Calculate requested size */ | ||
184 | bar_size = ~(bar_response & addr_mask) + 1; | ||
185 | |||
186 | /* Allocate a base address */ | ||
187 | bar_value = ((*lower_limit - 1) & ~(bar_size - 1)) + bar_size; | ||
188 | |||
189 | if ((bar_value + bar_size) > *upper_limit) { | ||
190 | if (bar_response & PCI_BASE_ADDRESS_SPACE) { | ||
191 | if (io_resource_inuse->child) { | ||
192 | io_resource_inuse = | ||
193 | io_resource_inuse->child; | ||
194 | pciauto_lower_iospc = | ||
195 | io_resource_inuse->start; | ||
196 | pciauto_upper_iospc = | ||
197 | io_resource_inuse->end + 1; | ||
198 | goto retry; | ||
199 | } | ||
200 | |||
201 | } else { | ||
202 | if (mem_resource_inuse->child) { | ||
203 | mem_resource_inuse = | ||
204 | mem_resource_inuse->child; | ||
205 | pciauto_lower_memspc = | ||
206 | mem_resource_inuse->start; | ||
207 | pciauto_upper_memspc = | ||
208 | mem_resource_inuse->end + 1; | ||
209 | goto retry; | ||
210 | } | ||
211 | } | ||
212 | DBG(" unavailable -- skipping, value %x size %x\n", | ||
213 | bar_value, bar_size); | ||
214 | continue; | ||
215 | } | ||
216 | |||
217 | if (bar_value < *lower_limit || (bar_value + bar_size) >= *upper_limit) { | ||
218 | DBG(" unavailable -- skipping, value %x size %x\n", | ||
219 | bar_value, bar_size); | ||
220 | continue; | ||
221 | } | ||
222 | |||
223 | #ifdef CONFIG_PCI_AUTO_UPDATE_RESOURCES | ||
224 | /* Write it out and update our limit */ | ||
225 | early_write_config_dword(hose, top_bus, current_bus, pci_devfn, | ||
226 | bar, bar_value); | ||
227 | #endif | ||
228 | |||
229 | *lower_limit = bar_value + bar_size; | ||
230 | |||
231 | /* | ||
232 | * If we are a 64-bit decoder then increment to the | ||
233 | * upper 32 bits of the bar and force it to locate | ||
234 | * in the lower 4GB of memory. | ||
235 | */ | ||
236 | if (found_mem64) { | ||
237 | bar += 4; | ||
238 | early_write_config_dword(hose, top_bus, | ||
239 | current_bus, | ||
240 | pci_devfn, | ||
241 | bar, | ||
242 | 0x00000000); | ||
243 | } | ||
244 | |||
245 | DBG(" at 0x%.8x [size=0x%x]\n", bar_value, bar_size); | ||
246 | |||
247 | bar_nr++; | ||
248 | } | ||
249 | |||
250 | } | ||
251 | |||
252 | static void __init | ||
253 | pciauto_prescan_setup_bridge(struct pci_channel *hose, | ||
254 | int top_bus, | ||
255 | int current_bus, | ||
256 | int pci_devfn, | ||
257 | int sub_bus) | ||
258 | { | ||
259 | /* Configure bus number registers */ | ||
260 | early_write_config_byte(hose, top_bus, current_bus, pci_devfn, | ||
261 | PCI_PRIMARY_BUS, current_bus); | ||
262 | early_write_config_byte(hose, top_bus, current_bus, pci_devfn, | ||
263 | PCI_SECONDARY_BUS, sub_bus + 1); | ||
264 | early_write_config_byte(hose, top_bus, current_bus, pci_devfn, | ||
265 | PCI_SUBORDINATE_BUS, 0xff); | ||
266 | |||
267 | /* Align memory and I/O to 1MB and 4KB boundaries. */ | ||
268 | pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1)) | ||
269 | & ~(0x100000 - 1); | ||
270 | pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1)) | ||
271 | & ~(0x1000 - 1); | ||
272 | |||
273 | /* Set base (lower limit) of address range behind bridge. */ | ||
274 | early_write_config_word(hose, top_bus, current_bus, pci_devfn, | ||
275 | PCI_MEMORY_BASE, pciauto_lower_memspc >> 16); | ||
276 | early_write_config_byte(hose, top_bus, current_bus, pci_devfn, | ||
277 | PCI_IO_BASE, (pciauto_lower_iospc & 0x0000f000) >> 8); | ||
278 | early_write_config_word(hose, top_bus, current_bus, pci_devfn, | ||
279 | PCI_IO_BASE_UPPER16, pciauto_lower_iospc >> 16); | ||
280 | |||
281 | /* We don't support prefetchable memory for now, so disable */ | ||
282 | early_write_config_word(hose, top_bus, current_bus, pci_devfn, | ||
283 | PCI_PREF_MEMORY_BASE, 0); | ||
284 | early_write_config_word(hose, top_bus, current_bus, pci_devfn, | ||
285 | PCI_PREF_MEMORY_LIMIT, 0); | ||
286 | } | ||
287 | |||
288 | static void __init | ||
289 | pciauto_postscan_setup_bridge(struct pci_channel *hose, | ||
290 | int top_bus, | ||
291 | int current_bus, | ||
292 | int pci_devfn, | ||
293 | int sub_bus) | ||
294 | { | ||
295 | u32 temp; | ||
296 | |||
297 | /* | ||
298 | * [jsun] we always bump up baselines a little, so that if there | ||
299 | * nothing behind P2P bridge, we don't wind up overlapping IO/MEM | ||
300 | * spaces. | ||
301 | */ | ||
302 | pciauto_lower_memspc += 1; | ||
303 | pciauto_lower_iospc += 1; | ||
304 | |||
305 | /* Configure bus number registers */ | ||
306 | early_write_config_byte(hose, top_bus, current_bus, pci_devfn, | ||
307 | PCI_SUBORDINATE_BUS, sub_bus); | ||
308 | |||
309 | /* Set upper limit of address range behind bridge. */ | ||
310 | early_write_config_word(hose, top_bus, current_bus, pci_devfn, | ||
311 | PCI_MEMORY_LIMIT, pciauto_lower_memspc >> 16); | ||
312 | early_write_config_byte(hose, top_bus, current_bus, pci_devfn, | ||
313 | PCI_IO_LIMIT, (pciauto_lower_iospc & 0x0000f000) >> 8); | ||
314 | early_write_config_word(hose, top_bus, current_bus, pci_devfn, | ||
315 | PCI_IO_LIMIT_UPPER16, pciauto_lower_iospc >> 16); | ||
316 | |||
317 | /* Align memory and I/O to 1MB and 4KB boundaries. */ | ||
318 | pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1)) | ||
319 | & ~(0x100000 - 1); | ||
320 | pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1)) | ||
321 | & ~(0x1000 - 1); | ||
322 | |||
323 | /* Enable memory and I/O accesses, enable bus master */ | ||
324 | early_read_config_dword(hose, top_bus, current_bus, pci_devfn, | ||
325 | PCI_COMMAND, &temp); | ||
326 | early_write_config_dword(hose, top_bus, current_bus, pci_devfn, | ||
327 | PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | ||
328 | | PCI_COMMAND_MASTER); | ||
329 | } | ||
330 | |||
331 | static void __init | ||
332 | pciauto_prescan_setup_cardbus_bridge(struct pci_channel *hose, | ||
333 | int top_bus, | ||
334 | int current_bus, | ||
335 | int pci_devfn, | ||
336 | int sub_bus) | ||
337 | { | ||
338 | /* Configure bus number registers */ | ||
339 | early_write_config_byte(hose, top_bus, current_bus, pci_devfn, | ||
340 | PCI_PRIMARY_BUS, current_bus); | ||
341 | early_write_config_byte(hose, top_bus, current_bus, pci_devfn, | ||
342 | PCI_SECONDARY_BUS, sub_bus + 1); | ||
343 | early_write_config_byte(hose, top_bus, current_bus, pci_devfn, | ||
344 | PCI_SUBORDINATE_BUS, 0xff); | ||
345 | |||
346 | /* Align memory and I/O to 4KB and 4 byte boundaries. */ | ||
347 | pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1)) | ||
348 | & ~(0x1000 - 1); | ||
349 | pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1)) | ||
350 | & ~(0x4 - 1); | ||
351 | |||
352 | early_write_config_dword(hose, top_bus, current_bus, pci_devfn, | ||
353 | PCI_CB_MEMORY_BASE_0, pciauto_lower_memspc); | ||
354 | early_write_config_dword(hose, top_bus, current_bus, pci_devfn, | ||
355 | PCI_CB_IO_BASE_0, pciauto_lower_iospc); | ||
356 | } | ||
357 | |||
358 | static void __init | ||
359 | pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose, | ||
360 | int top_bus, | ||
361 | int current_bus, | ||
362 | int pci_devfn, | ||
363 | int sub_bus) | ||
364 | { | ||
365 | u32 temp; | ||
366 | |||
367 | /* | ||
368 | * [jsun] we always bump up baselines a little, so that if there | ||
369 | * nothing behind P2P bridge, we don't wind up overlapping IO/MEM | ||
370 | * spaces. | ||
371 | */ | ||
372 | pciauto_lower_memspc += 1; | ||
373 | pciauto_lower_iospc += 1; | ||
374 | |||
375 | /* | ||
376 | * Configure subordinate bus number. The PCI subsystem | ||
377 | * bus scan will renumber buses (reserving three additional | ||
378 | * for this PCI<->CardBus bridge for the case where a CardBus | ||
379 | * adapter contains a P2P or CB2CB bridge. | ||
380 | */ | ||
381 | |||
382 | early_write_config_byte(hose, top_bus, current_bus, pci_devfn, | ||
383 | PCI_SUBORDINATE_BUS, sub_bus); | ||
384 | |||
385 | /* | ||
386 | * Reserve an additional 4MB for mem space and 16KB for | ||
387 | * I/O space. This should cover any additional space | ||
388 | * requirement of unusual CardBus devices with | ||
389 | * additional bridges that can consume more address space. | ||
390 | * | ||
391 | * Although pcmcia-cs currently will reprogram bridge | ||
392 | * windows, the goal is to add an option to leave them | ||
393 | * alone and use the bridge window ranges as the regions | ||
394 | * that are searched for free resources upon hot-insertion | ||
395 | * of a device. This will allow a PCI<->CardBus bridge | ||
396 | * configured by this routine to happily live behind a | ||
397 | * P2P bridge in a system. | ||
398 | */ | ||
399 | /* Align memory and I/O to 4KB and 4 byte boundaries. */ | ||
400 | pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1)) | ||
401 | & ~(0x1000 - 1); | ||
402 | pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1)) | ||
403 | & ~(0x4 - 1); | ||
404 | /* Set up memory and I/O filter limits, assume 32-bit I/O space */ | ||
405 | early_write_config_dword(hose, top_bus, current_bus, pci_devfn, | ||
406 | PCI_CB_MEMORY_LIMIT_0, pciauto_lower_memspc - 1); | ||
407 | early_write_config_dword(hose, top_bus, current_bus, pci_devfn, | ||
408 | PCI_CB_IO_LIMIT_0, pciauto_lower_iospc - 1); | ||
409 | |||
410 | /* Enable memory and I/O accesses, enable bus master */ | ||
411 | early_read_config_dword(hose, top_bus, current_bus, pci_devfn, | ||
412 | PCI_COMMAND, &temp); | ||
413 | early_write_config_dword(hose, top_bus, current_bus, pci_devfn, | ||
414 | PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | | ||
415 | PCI_COMMAND_MASTER); | ||
416 | } | ||
417 | |||
418 | #define PCIAUTO_IDE_MODE_MASK 0x05 | ||
419 | |||
420 | static int __init | ||
421 | pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus) | ||
422 | { | ||
423 | int sub_bus; | ||
424 | u32 pci_devfn, pci_class, cmdstat, found_multi=0; | ||
425 | unsigned short vid, did; | ||
426 | unsigned char header_type; | ||
427 | int devfn_start = 0; | ||
428 | int devfn_stop = 0xff; | ||
429 | |||
430 | sub_bus = current_bus; | ||
431 | |||
432 | if (hose->first_devfn) | ||
433 | devfn_start = hose->first_devfn; | ||
434 | if (hose->last_devfn) | ||
435 | devfn_stop = hose->last_devfn; | ||
436 | |||
437 | for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) { | ||
438 | |||
439 | if (PCI_FUNC(pci_devfn) && !found_multi) | ||
440 | continue; | ||
441 | |||
442 | early_read_config_word(hose, top_bus, current_bus, pci_devfn, | ||
443 | PCI_VENDOR_ID, &vid); | ||
444 | |||
445 | if (vid == 0xffff) continue; | ||
446 | |||
447 | early_read_config_byte(hose, top_bus, current_bus, pci_devfn, | ||
448 | PCI_HEADER_TYPE, &header_type); | ||
449 | |||
450 | if (!PCI_FUNC(pci_devfn)) | ||
451 | found_multi = header_type & 0x80; | ||
452 | |||
453 | early_read_config_word(hose, top_bus, current_bus, pci_devfn, | ||
454 | PCI_DEVICE_ID, &did); | ||
455 | |||
456 | early_read_config_dword(hose, top_bus, current_bus, pci_devfn, | ||
457 | PCI_CLASS_REVISION, &pci_class); | ||
458 | |||
459 | DBG("%.2x:%.2x.%x Class %.4x: %.4x:%.4x", | ||
460 | current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn), | ||
461 | pci_class >> 16, vid, did); | ||
462 | if (pci_class & 0xff) | ||
463 | DBG(" (rev %.2x)", pci_class & 0xff); | ||
464 | DBG("\n"); | ||
465 | |||
466 | if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) { | ||
467 | DBG(" Bridge: primary=%.2x, secondary=%.2x\n", | ||
468 | current_bus, sub_bus + 1); | ||
469 | pciauto_prescan_setup_bridge(hose, top_bus, current_bus, | ||
470 | pci_devfn, sub_bus); | ||
471 | DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", | ||
472 | sub_bus + 1, | ||
473 | pciauto_lower_iospc, pciauto_lower_memspc); | ||
474 | sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1); | ||
475 | DBG("Back to bus %.2x\n", current_bus); | ||
476 | pciauto_postscan_setup_bridge(hose, top_bus, current_bus, | ||
477 | pci_devfn, sub_bus); | ||
478 | continue; | ||
479 | } else if ((pci_class >> 16) == PCI_CLASS_BRIDGE_CARDBUS) { | ||
480 | DBG(" CARDBUS Bridge: primary=%.2x, secondary=%.2x\n", | ||
481 | current_bus, sub_bus + 1); | ||
482 | DBG("PCI Autoconfig: Found CardBus bridge, device %d function %d\n", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn)); | ||
483 | /* Place CardBus Socket/ExCA registers */ | ||
484 | pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_0); | ||
485 | |||
486 | pciauto_prescan_setup_cardbus_bridge(hose, top_bus, | ||
487 | current_bus, pci_devfn, sub_bus); | ||
488 | |||
489 | DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", | ||
490 | sub_bus + 1, | ||
491 | pciauto_lower_iospc, pciauto_lower_memspc); | ||
492 | sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1); | ||
493 | DBG("Back to bus %.2x, sub_bus is %x\n", current_bus, sub_bus); | ||
494 | pciauto_postscan_setup_cardbus_bridge(hose, top_bus, | ||
495 | current_bus, pci_devfn, sub_bus); | ||
496 | continue; | ||
497 | } else if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) { | ||
498 | |||
499 | unsigned char prg_iface; | ||
500 | |||
501 | early_read_config_byte(hose, top_bus, current_bus, | ||
502 | pci_devfn, PCI_CLASS_PROG, &prg_iface); | ||
503 | if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) { | ||
504 | DBG("Skipping legacy mode IDE controller\n"); | ||
505 | continue; | ||
506 | } | ||
507 | } | ||
508 | |||
509 | /* | ||
510 | * Found a peripheral, enable some standard | ||
511 | * settings | ||
512 | */ | ||
513 | early_read_config_dword(hose, top_bus, current_bus, pci_devfn, | ||
514 | PCI_COMMAND, &cmdstat); | ||
515 | early_write_config_dword(hose, top_bus, current_bus, pci_devfn, | ||
516 | PCI_COMMAND, cmdstat | PCI_COMMAND_IO | | ||
517 | PCI_COMMAND_MEMORY | | ||
518 | PCI_COMMAND_MASTER); | ||
519 | early_write_config_byte(hose, top_bus, current_bus, pci_devfn, | ||
520 | PCI_LATENCY_TIMER, 0x80); | ||
521 | |||
522 | /* Allocate PCI I/O and/or memory space */ | ||
523 | pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_5); | ||
524 | } | ||
525 | return sub_bus; | ||
526 | } | ||
527 | |||
528 | int __init | ||
529 | pciauto_assign_resources(int busno, struct pci_channel *hose) | ||
530 | { | ||
531 | /* setup resource limits */ | ||
532 | io_resource_inuse = hose->io_resource; | ||
533 | mem_resource_inuse = hose->mem_resource; | ||
534 | |||
535 | pciauto_lower_iospc = io_resource_inuse->start; | ||
536 | pciauto_upper_iospc = io_resource_inuse->end + 1; | ||
537 | pciauto_lower_memspc = mem_resource_inuse->start; | ||
538 | pciauto_upper_memspc = mem_resource_inuse->end + 1; | ||
539 | DBG("Autoconfig PCI channel 0x%p\n", hose); | ||
540 | DBG("Scanning bus %.2x, I/O 0x%.8x:0x%.8x, Mem 0x%.8x:0x%.8x\n", | ||
541 | busno, pciauto_lower_iospc, pciauto_upper_iospc, | ||
542 | pciauto_lower_memspc, pciauto_upper_memspc); | ||
543 | |||
544 | return pciauto_bus_scan(hose, busno, busno); | ||
545 | } | ||
diff --git a/arch/sh/drivers/pci/pci-dreamcast.c b/arch/sh/drivers/pci/pci-dreamcast.c new file mode 100644 index 000000000000..210f9d4af141 --- /dev/null +++ b/arch/sh/drivers/pci/pci-dreamcast.c | |||
@@ -0,0 +1,102 @@ | |||
1 | /* | ||
2 | * PCI support for the Sega Dreamcast | ||
3 | * | ||
4 | * Copyright (C) 2001, 2002 M. R. Brown | ||
5 | * Copyright (C) 2002, 2003 Paul Mundt | ||
6 | * | ||
7 | * This file originally bore the message (with enclosed-$): | ||
8 | * Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp | ||
9 | * Dreamcast PCI: Supports SEGA Broadband Adaptor only. | ||
10 | * | ||
11 | * This file is subject to the terms and conditions of the GNU General Public | ||
12 | * License. See the file "COPYING" in the main directory of this archive | ||
13 | * for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/sched.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/param.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/irq.h> | ||
22 | #include <linux/pci.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <asm/io.h> | ||
25 | #include <asm/irq.h> | ||
26 | #include <mach/pci.h> | ||
27 | |||
28 | static struct resource gapspci_io_resource = { | ||
29 | .name = "GAPSPCI IO", | ||
30 | .start = GAPSPCI_BBA_CONFIG, | ||
31 | .end = GAPSPCI_BBA_CONFIG + GAPSPCI_BBA_CONFIG_SIZE - 1, | ||
32 | .flags = IORESOURCE_IO, | ||
33 | }; | ||
34 | |||
35 | static struct resource gapspci_mem_resource = { | ||
36 | .name = "GAPSPCI mem", | ||
37 | .start = GAPSPCI_DMA_BASE, | ||
38 | .end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1, | ||
39 | .flags = IORESOURCE_MEM, | ||
40 | }; | ||
41 | |||
42 | static struct pci_channel dreamcast_pci_controller = { | ||
43 | .pci_ops = &gapspci_pci_ops, | ||
44 | .io_resource = &gapspci_io_resource, | ||
45 | .io_offset = 0x00000000, | ||
46 | .mem_resource = &gapspci_mem_resource, | ||
47 | .mem_offset = 0x00000000, | ||
48 | }; | ||
49 | |||
50 | /* | ||
51 | * gapspci init | ||
52 | */ | ||
53 | |||
54 | static int __init gapspci_init(void) | ||
55 | { | ||
56 | char idbuf[16]; | ||
57 | int i; | ||
58 | |||
59 | /* | ||
60 | * FIXME: All of this wants documenting to some degree, | ||
61 | * even some basic register definitions would be nice. | ||
62 | * | ||
63 | * I haven't seen anything this ugly since.. maple. | ||
64 | */ | ||
65 | |||
66 | for (i=0; i<16; i++) | ||
67 | idbuf[i] = inb(GAPSPCI_REGS+i); | ||
68 | |||
69 | if (strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16)) | ||
70 | return -ENODEV; | ||
71 | |||
72 | outl(0x5a14a501, GAPSPCI_REGS+0x18); | ||
73 | |||
74 | for (i=0; i<1000000; i++) | ||
75 | cpu_relax(); | ||
76 | |||
77 | if (inl(GAPSPCI_REGS+0x18) != 1) | ||
78 | return -EINVAL; | ||
79 | |||
80 | outl(0x01000000, GAPSPCI_REGS+0x20); | ||
81 | outl(0x01000000, GAPSPCI_REGS+0x24); | ||
82 | |||
83 | outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28); | ||
84 | outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c); | ||
85 | |||
86 | outl(1, GAPSPCI_REGS+0x14); | ||
87 | outl(1, GAPSPCI_REGS+0x34); | ||
88 | |||
89 | /* Setting Broadband Adapter */ | ||
90 | outw(0xf900, GAPSPCI_BBA_CONFIG+0x06); | ||
91 | outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30); | ||
92 | outb(0x00, GAPSPCI_BBA_CONFIG+0x3c); | ||
93 | outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d); | ||
94 | outw(0x0006, GAPSPCI_BBA_CONFIG+0x04); | ||
95 | outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10); | ||
96 | outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14); | ||
97 | |||
98 | register_pci_controller(&dreamcast_pci_controller); | ||
99 | |||
100 | return 0; | ||
101 | } | ||
102 | arch_initcall(gapspci_init); | ||
diff --git a/arch/sh/drivers/pci/pci-sh4.h b/arch/sh/drivers/pci/pci-sh4.h index a83dcf70c13b..3d5296cde622 100644 --- a/arch/sh/drivers/pci/pci-sh4.h +++ b/arch/sh/drivers/pci/pci-sh4.h | |||
@@ -149,13 +149,10 @@ | |||
149 | #define SH4_PCIPDTR_PB0 0x000000001 /* Port 0 Enable */ | 149 | #define SH4_PCIPDTR_PB0 0x000000001 /* Port 0 Enable */ |
150 | #define SH4_PCIPDR 0x220 /* Port IO Data Register */ | 150 | #define SH4_PCIPDR 0x220 /* Port IO Data Register */ |
151 | 151 | ||
152 | /* Flags */ | ||
153 | #define SH4_PCIC_NO_RESET 0x0001 | ||
154 | |||
155 | /* arch/sh/kernel/drivers/pci/ops-sh4.c */ | 152 | /* arch/sh/kernel/drivers/pci/ops-sh4.c */ |
156 | extern struct pci_ops sh4_pci_ops; | 153 | extern struct pci_ops sh4_pci_ops; |
157 | int sh4_pci_check_direct(void); | 154 | int sh4_pci_check_direct(struct pci_channel *chan); |
158 | int pci_fixup_pcic(void); | 155 | int pci_fixup_pcic(struct pci_channel *chan); |
159 | 156 | ||
160 | struct sh4_pci_address_space { | 157 | struct sh4_pci_address_space { |
161 | unsigned long base; | 158 | unsigned long base; |
@@ -165,16 +162,18 @@ struct sh4_pci_address_space { | |||
165 | struct sh4_pci_address_map { | 162 | struct sh4_pci_address_map { |
166 | struct sh4_pci_address_space window0; | 163 | struct sh4_pci_address_space window0; |
167 | struct sh4_pci_address_space window1; | 164 | struct sh4_pci_address_space window1; |
168 | unsigned long flags; | ||
169 | }; | 165 | }; |
170 | 166 | ||
171 | static inline void pci_write_reg(unsigned long val, unsigned long reg) | 167 | static inline void pci_write_reg(struct pci_channel *chan, |
168 | unsigned long val, unsigned long reg) | ||
172 | { | 169 | { |
173 | ctrl_outl(val, PCI_REG(reg)); | 170 | ctrl_outl(val, chan->reg_base + reg); |
174 | } | 171 | } |
175 | 172 | ||
176 | static inline unsigned long pci_read_reg(unsigned long reg) | 173 | static inline unsigned long pci_read_reg(struct pci_channel *chan, |
174 | unsigned long reg) | ||
177 | { | 175 | { |
178 | return ctrl_inl(PCI_REG(reg)); | 176 | return ctrl_inl(chan->reg_base + reg); |
179 | } | 177 | } |
178 | |||
180 | #endif /* __PCI_SH4_H */ | 179 | #endif /* __PCI_SH4_H */ |
diff --git a/arch/sh/drivers/pci/pci-sh5.c b/arch/sh/drivers/pci/pci-sh5.c index 7a97438762c8..873ed2b44055 100644 --- a/arch/sh/drivers/pci/pci-sh5.c +++ b/arch/sh/drivers/pci/pci-sh5.c | |||
@@ -89,8 +89,21 @@ static irqreturn_t pcish5_serr_irq(int irq, void *dev_id) | |||
89 | return IRQ_NONE; | 89 | return IRQ_NONE; |
90 | } | 90 | } |
91 | 91 | ||
92 | int __init sh5pci_init(unsigned long memStart, unsigned long memSize) | 92 | static struct resource sh5_io_resource = { /* place holder */ }; |
93 | static struct resource sh5_mem_resource = { /* place holder */ }; | ||
94 | |||
95 | static struct pci_channel sh5pci_controller = { | ||
96 | .pci_ops = &sh5_pci_ops, | ||
97 | .mem_resource = &sh5_mem_resource, | ||
98 | .mem_offset = 0x00000000, | ||
99 | .io_resource = &sh5_io_resource, | ||
100 | .io_offset = 0x00000000, | ||
101 | }; | ||
102 | |||
103 | static int __init sh5pci_init(void) | ||
93 | { | 104 | { |
105 | unsigned long memStart = __pa(memory_start); | ||
106 | unsigned long memSize = __pa(memory_end) - memStart; | ||
94 | u32 lsr0; | 107 | u32 lsr0; |
95 | u32 uval; | 108 | u32 uval; |
96 | 109 | ||
@@ -106,12 +119,12 @@ int __init sh5pci_init(unsigned long memStart, unsigned long memSize) | |||
106 | return -EINVAL; | 119 | return -EINVAL; |
107 | } | 120 | } |
108 | 121 | ||
109 | pcicr_virt = onchip_remap(SH5PCI_ICR_BASE, 1024, "PCICR"); | 122 | pcicr_virt = (unsigned long)ioremap_nocache(SH5PCI_ICR_BASE, 1024); |
110 | if (!pcicr_virt) { | 123 | if (!pcicr_virt) { |
111 | panic("Unable to remap PCICR\n"); | 124 | panic("Unable to remap PCICR\n"); |
112 | } | 125 | } |
113 | 126 | ||
114 | PCI_IO_AREA = onchip_remap(SH5PCI_IO_BASE, 0x10000, "PCIIO"); | 127 | PCI_IO_AREA = (unsigned long)ioremap_nocache(SH5PCI_IO_BASE, 0x10000); |
115 | if (!PCI_IO_AREA) { | 128 | if (!PCI_IO_AREA) { |
116 | panic("Unable to remap PCIIO\n"); | 129 | panic("Unable to remap PCIIO\n"); |
117 | } | 130 | } |
@@ -197,32 +210,14 @@ int __init sh5pci_init(unsigned long memStart, unsigned long memSize) | |||
197 | SH5PCI_WRITE(AINTM, ~0); | 210 | SH5PCI_WRITE(AINTM, ~0); |
198 | SH5PCI_WRITE(PINTM, ~0); | 211 | SH5PCI_WRITE(PINTM, ~0); |
199 | 212 | ||
200 | return 0; | 213 | sh5_io_resource.start = PCI_IO_AREA; |
201 | } | 214 | sh5_io_resource.end = PCI_IO_AREA + 0x10000; |
202 | 215 | ||
203 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) | 216 | sh5_mem_resource.start = memStart; |
204 | { | 217 | sh5_mem_resource.end = memStart + memSize; |
205 | struct pci_dev *dev = bus->self; | 218 | |
206 | int i; | 219 | register_pci_controller(&sh5pci_controller); |
207 | 220 | ||
208 | if (dev) { | 221 | return 0; |
209 | for (i= 0; i < 3; i++) { | ||
210 | bus->resource[i] = | ||
211 | &dev->resource[PCI_BRIDGE_RESOURCES+i]; | ||
212 | bus->resource[i]->name = bus->name; | ||
213 | } | ||
214 | bus->resource[0]->flags |= IORESOURCE_IO; | ||
215 | bus->resource[1]->flags |= IORESOURCE_MEM; | ||
216 | |||
217 | /* For now, propagate host limits to the bus; | ||
218 | * we'll adjust them later. */ | ||
219 | bus->resource[0]->end = 64*1024 - 1 ; | ||
220 | bus->resource[1]->end = PCIBIOS_MIN_MEM+(256*1024*1024)-1; | ||
221 | bus->resource[0]->start = PCIBIOS_MIN_IO; | ||
222 | bus->resource[1]->start = PCIBIOS_MIN_MEM; | ||
223 | |||
224 | /* Turn off downstream PF memory address range by default */ | ||
225 | bus->resource[2]->start = 1024*1024; | ||
226 | bus->resource[2]->end = bus->resource[2]->start - 1; | ||
227 | } | ||
228 | } | 222 | } |
223 | arch_initcall(sh5pci_init); | ||
diff --git a/arch/sh/drivers/pci/pci-sh5.h b/arch/sh/drivers/pci/pci-sh5.h index 7cff3fc04d30..f277628221f3 100644 --- a/arch/sh/drivers/pci/pci-sh5.h +++ b/arch/sh/drivers/pci/pci-sh5.h | |||
@@ -107,7 +107,4 @@ extern unsigned long pcicr_virt; | |||
107 | 107 | ||
108 | extern struct pci_ops sh5_pci_ops; | 108 | extern struct pci_ops sh5_pci_ops; |
109 | 109 | ||
110 | /* arch/sh/drivers/pci/pci-sh5.c */ | ||
111 | int sh5pci_init(unsigned long memStart, unsigned long memSize); | ||
112 | |||
113 | #endif /* __PCI_SH5_H */ | 110 | #endif /* __PCI_SH5_H */ |
diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 3065eb184f01..c4fa0bb13976 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c | |||
@@ -1,88 +1,99 @@ | |||
1 | /* | 1 | /* |
2 | * Low-Level PCI Support for the SH7751 | 2 | * Low-Level PCI Support for the SH7751 |
3 | * | 3 | * |
4 | * Dustin McIntire (dustin@sensoria.com) | 4 | * Copyright (C) 2003 - 2009 Paul Mundt |
5 | * Derived from arch/i386/kernel/pci-*.c which bore the message: | 5 | * Copyright (C) 2001 Dustin McIntire |
6 | * (c) 1999--2000 Martin Mares <mj@ucw.cz> | ||
7 | * | 6 | * |
8 | * Ported to the new API by Paul Mundt <lethal@linux-sh.org> | 7 | * With cleanup by Paul van Gool <pvangool@mimotech.com>, 2003. |
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 | * | 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. | ||
14 | */ | 12 | */ |
15 | #undef DEBUG | ||
16 | |||
17 | #include <linux/init.h> | 13 | #include <linux/init.h> |
18 | #include <linux/pci.h> | 14 | #include <linux/pci.h> |
19 | #include <linux/types.h> | 15 | #include <linux/types.h> |
20 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
21 | #include <linux/delay.h> | 17 | #include <linux/io.h> |
22 | #include "pci-sh4.h" | 18 | #include "pci-sh4.h" |
23 | #include <asm/addrspace.h> | 19 | #include <asm/addrspace.h> |
24 | #include <asm/io.h> | ||
25 | 20 | ||
26 | /* | 21 | static int __init __area_sdram_check(struct pci_channel *chan, |
27 | * Initialization. Try all known PCI access methods. Note that we support | 22 | unsigned int area) |
28 | * using both PCI BIOS and direct access: in such cases, we use I/O ports | ||
29 | * to access config space. | ||
30 | * | ||
31 | * Note that the platform specific initialization (BSC registers, and memory | ||
32 | * space mapping) will be called via the platform defined function | ||
33 | * pcibios_init_platform(). | ||
34 | */ | ||
35 | static int __init sh7751_pci_init(void) | ||
36 | { | 23 | { |
37 | unsigned int id; | 24 | unsigned long word; |
38 | int ret; | ||
39 | |||
40 | pr_debug("PCI: Starting intialization.\n"); | ||
41 | 25 | ||
42 | /* check for SH7751/SH7751R hardware */ | 26 | word = __raw_readl(SH7751_BCR1); |
43 | id = pci_read_reg(SH7751_PCICONF0); | ||
44 | if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) && | ||
45 | id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) { | ||
46 | pr_debug("PCI: This is not an SH7751(R) (%x)\n", id); | ||
47 | return -ENODEV; | ||
48 | } | ||
49 | |||
50 | if ((ret = sh4_pci_check_direct()) != 0) | ||
51 | return ret; | ||
52 | |||
53 | return pcibios_init_platform(); | ||
54 | } | ||
55 | subsys_initcall(sh7751_pci_init); | ||
56 | |||
57 | static int __init __area_sdram_check(unsigned int area) | ||
58 | { | ||
59 | u32 word; | ||
60 | |||
61 | word = ctrl_inl(SH7751_BCR1); | ||
62 | /* check BCR for SDRAM in area */ | 27 | /* check BCR for SDRAM in area */ |
63 | if (((word >> area) & 1) == 0) { | 28 | if (((word >> area) & 1) == 0) { |
64 | printk("PCI: Area %d is not configured for SDRAM. BCR1=0x%x\n", | 29 | printk("PCI: Area %d is not configured for SDRAM. BCR1=0x%lx\n", |
65 | area, word); | 30 | area, word); |
66 | return 0; | 31 | return 0; |
67 | } | 32 | } |
68 | pci_write_reg(word, SH4_PCIBCR1); | 33 | pci_write_reg(chan, word, SH4_PCIBCR1); |
69 | 34 | ||
70 | word = (u16)ctrl_inw(SH7751_BCR2); | 35 | word = __raw_readw(SH7751_BCR2); |
71 | /* check BCR2 for 32bit SDRAM interface*/ | 36 | /* check BCR2 for 32bit SDRAM interface*/ |
72 | if (((word >> (area << 1)) & 0x3) != 0x3) { | 37 | if (((word >> (area << 1)) & 0x3) != 0x3) { |
73 | printk("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%x\n", | 38 | printk("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%lx\n", |
74 | area, word); | 39 | area, word); |
75 | return 0; | 40 | return 0; |
76 | } | 41 | } |
77 | pci_write_reg(word, SH4_PCIBCR2); | 42 | pci_write_reg(chan, word, SH4_PCIBCR2); |
78 | 43 | ||
79 | return 1; | 44 | return 1; |
80 | } | 45 | } |
81 | 46 | ||
82 | int __init sh7751_pcic_init(struct sh4_pci_address_map *map) | 47 | static struct resource sh7751_io_resource = { |
48 | .name = "SH7751_IO", | ||
49 | .start = SH7751_PCI_IO_BASE, | ||
50 | .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, | ||
51 | .flags = IORESOURCE_IO | ||
52 | }; | ||
53 | |||
54 | static struct resource sh7751_mem_resource = { | ||
55 | .name = "SH7785_mem", | ||
56 | .start = SH7751_PCI_MEMORY_BASE, | ||
57 | .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, | ||
58 | .flags = IORESOURCE_MEM | ||
59 | }; | ||
60 | |||
61 | static struct pci_channel sh7751_pci_controller = { | ||
62 | .pci_ops = &sh4_pci_ops, | ||
63 | .mem_resource = &sh7751_mem_resource, | ||
64 | .mem_offset = 0x00000000, | ||
65 | .io_resource = &sh7751_io_resource, | ||
66 | .io_offset = 0x00000000, | ||
67 | }; | ||
68 | |||
69 | static struct sh4_pci_address_map sh7751_pci_map = { | ||
70 | .window0 = { | ||
71 | .base = SH7751_CS3_BASE_ADDR, | ||
72 | .size = 0x04000000, | ||
73 | }, | ||
74 | }; | ||
75 | |||
76 | static int __init sh7751_pci_init(void) | ||
83 | { | 77 | { |
84 | u32 reg; | 78 | struct pci_channel *chan = &sh7751_pci_controller; |
85 | u32 word; | 79 | unsigned int id; |
80 | u32 word, reg; | ||
81 | int ret; | ||
82 | |||
83 | printk(KERN_NOTICE "PCI: Starting intialization.\n"); | ||
84 | |||
85 | chan->reg_base = 0xfe200000; | ||
86 | |||
87 | /* check for SH7751/SH7751R hardware */ | ||
88 | id = pci_read_reg(chan, SH7751_PCICONF0); | ||
89 | if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) && | ||
90 | id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) { | ||
91 | pr_debug("PCI: This is not an SH7751(R) (%x)\n", id); | ||
92 | return -ENODEV; | ||
93 | } | ||
94 | |||
95 | if ((ret = sh4_pci_check_direct(chan)) != 0) | ||
96 | return ret; | ||
86 | 97 | ||
87 | /* Set the BCR's to enable PCI access */ | 98 | /* Set the BCR's to enable PCI access */ |
88 | reg = ctrl_inl(SH7751_BCR1); | 99 | reg = ctrl_inl(SH7751_BCR1); |
@@ -90,25 +101,10 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) | |||
90 | ctrl_outl(reg, SH7751_BCR1); | 101 | ctrl_outl(reg, SH7751_BCR1); |
91 | 102 | ||
92 | /* Turn the clocks back on (not done in reset)*/ | 103 | /* Turn the clocks back on (not done in reset)*/ |
93 | pci_write_reg(0, SH4_PCICLKR); | 104 | pci_write_reg(chan, 0, SH4_PCICLKR); |
94 | /* Clear Powerdown IRQ's (not done in reset) */ | 105 | /* Clear Powerdown IRQ's (not done in reset) */ |
95 | word = SH4_PCIPINT_D3 | SH4_PCIPINT_D0; | 106 | word = SH4_PCIPINT_D3 | SH4_PCIPINT_D0; |
96 | pci_write_reg(word, SH4_PCIPINT); | 107 | pci_write_reg(chan, word, SH4_PCIPINT); |
97 | |||
98 | /* | ||
99 | * This code is unused for some boards as it is done in the | ||
100 | * bootloader and doing it here means the MAC addresses loaded | ||
101 | * by the bootloader get lost. | ||
102 | */ | ||
103 | if (!(map->flags & SH4_PCIC_NO_RESET)) { | ||
104 | /* toggle PCI reset pin */ | ||
105 | word = SH4_PCICR_PREFIX | SH4_PCICR_PRST; | ||
106 | pci_write_reg(word, SH4_PCICR); | ||
107 | /* Wait for a long time... not 1 sec. but long enough */ | ||
108 | mdelay(100); | ||
109 | word = SH4_PCICR_PREFIX; | ||
110 | pci_write_reg(word, SH4_PCICR); | ||
111 | } | ||
112 | 108 | ||
113 | /* set the command/status bits to: | 109 | /* set the command/status bits to: |
114 | * Wait Cycle Control + Parity Enable + Bus Master + | 110 | * Wait Cycle Control + Parity Enable + Bus Master + |
@@ -116,89 +112,77 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) | |||
116 | */ | 112 | */ |
117 | word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER | | 113 | word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER | |
118 | SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES; | 114 | SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES; |
119 | pci_write_reg(word, SH7751_PCICONF1); | 115 | pci_write_reg(chan, word, SH7751_PCICONF1); |
120 | 116 | ||
121 | /* define this host as the host bridge */ | 117 | /* define this host as the host bridge */ |
122 | word = PCI_BASE_CLASS_BRIDGE << 24; | 118 | word = PCI_BASE_CLASS_BRIDGE << 24; |
123 | pci_write_reg(word, SH7751_PCICONF2); | 119 | pci_write_reg(chan, word, SH7751_PCICONF2); |
124 | 120 | ||
125 | /* Set IO and Mem windows to local address | 121 | /* Set IO and Mem windows to local address |
126 | * Make PCI and local address the same for easy 1 to 1 mapping | 122 | * Make PCI and local address the same for easy 1 to 1 mapping |
127 | * Window0 = map->window0.size @ non-cached area base = SDRAM | ||
128 | * Window1 = map->window1.size @ cached area base = SDRAM | ||
129 | */ | 123 | */ |
130 | word = map->window0.size - 1; | 124 | word = sh7751_pci_map.window0.size - 1; |
131 | pci_write_reg(word, SH4_PCILSR0); | 125 | pci_write_reg(chan, word, SH4_PCILSR0); |
132 | word = map->window1.size - 1; | ||
133 | pci_write_reg(word, SH4_PCILSR1); | ||
134 | /* Set the values on window 0 PCI config registers */ | 126 | /* Set the values on window 0 PCI config registers */ |
135 | word = P2SEGADDR(map->window0.base); | 127 | word = P2SEGADDR(sh7751_pci_map.window0.base); |
136 | pci_write_reg(word, SH4_PCILAR0); | 128 | pci_write_reg(chan, word, SH4_PCILAR0); |
137 | pci_write_reg(word, SH7751_PCICONF5); | 129 | pci_write_reg(chan, word, SH7751_PCICONF5); |
138 | /* Set the values on window 1 PCI config registers */ | ||
139 | word = PHYSADDR(map->window1.base); | ||
140 | pci_write_reg(word, SH4_PCILAR1); | ||
141 | pci_write_reg(word, SH7751_PCICONF6); | ||
142 | 130 | ||
143 | /* Set the local 16MB PCI memory space window to | 131 | /* Set the local 16MB PCI memory space window to |
144 | * the lowest PCI mapped address | 132 | * the lowest PCI mapped address |
145 | */ | 133 | */ |
146 | word = PCIBIOS_MIN_MEM & SH4_PCIMBR_MASK; | 134 | word = chan->mem_resource->start & SH4_PCIMBR_MASK; |
147 | pr_debug("PCI: Setting upper bits of Memory window to 0x%x\n", word); | 135 | pr_debug("PCI: Setting upper bits of Memory window to 0x%x\n", word); |
148 | pci_write_reg(word , SH4_PCIMBR); | 136 | pci_write_reg(chan, word , SH4_PCIMBR); |
149 | |||
150 | /* Map IO space into PCI IO window | ||
151 | * The IO window is 64K-PCIBIOS_MIN_IO in size | ||
152 | * IO addresses will be translated to the | ||
153 | * PCI IO window base address | ||
154 | */ | ||
155 | pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", | ||
156 | PCIBIOS_MIN_IO, (64 << 10), | ||
157 | SH7751_PCI_IO_BASE + PCIBIOS_MIN_IO); | ||
158 | 137 | ||
159 | /* Make sure the MSB's of IO window are set to access PCI space | 138 | /* Make sure the MSB's of IO window are set to access PCI space |
160 | * correctly */ | 139 | * correctly */ |
161 | word = PCIBIOS_MIN_IO & SH4_PCIIOBR_MASK; | 140 | word = chan->io_resource->start & SH4_PCIIOBR_MASK; |
162 | pr_debug("PCI: Setting upper bits of IO window to 0x%x\n", word); | 141 | pr_debug("PCI: Setting upper bits of IO window to 0x%x\n", word); |
163 | pci_write_reg(word, SH4_PCIIOBR); | 142 | pci_write_reg(chan, word, SH4_PCIIOBR); |
164 | 143 | ||
165 | /* Set PCI WCRx, BCRx's, copy from BSC locations */ | 144 | /* Set PCI WCRx, BCRx's, copy from BSC locations */ |
166 | 145 | ||
167 | /* check BCR for SDRAM in specified area */ | 146 | /* check BCR for SDRAM in specified area */ |
168 | switch (map->window0.base) { | 147 | switch (sh7751_pci_map.window0.base) { |
169 | case SH7751_CS0_BASE_ADDR: word = __area_sdram_check(0); break; | 148 | case SH7751_CS0_BASE_ADDR: word = __area_sdram_check(chan, 0); break; |
170 | case SH7751_CS1_BASE_ADDR: word = __area_sdram_check(1); break; | 149 | case SH7751_CS1_BASE_ADDR: word = __area_sdram_check(chan, 1); break; |
171 | case SH7751_CS2_BASE_ADDR: word = __area_sdram_check(2); break; | 150 | case SH7751_CS2_BASE_ADDR: word = __area_sdram_check(chan, 2); break; |
172 | case SH7751_CS3_BASE_ADDR: word = __area_sdram_check(3); break; | 151 | case SH7751_CS3_BASE_ADDR: word = __area_sdram_check(chan, 3); break; |
173 | case SH7751_CS4_BASE_ADDR: word = __area_sdram_check(4); break; | 152 | case SH7751_CS4_BASE_ADDR: word = __area_sdram_check(chan, 4); break; |
174 | case SH7751_CS5_BASE_ADDR: word = __area_sdram_check(5); break; | 153 | case SH7751_CS5_BASE_ADDR: word = __area_sdram_check(chan, 5); break; |
175 | case SH7751_CS6_BASE_ADDR: word = __area_sdram_check(6); break; | 154 | case SH7751_CS6_BASE_ADDR: word = __area_sdram_check(chan, 6); break; |
176 | } | 155 | } |
177 | 156 | ||
178 | if (!word) | 157 | if (!word) |
179 | return 0; | 158 | return -1; |
180 | 159 | ||
181 | /* configure the wait control registers */ | 160 | /* configure the wait control registers */ |
182 | word = ctrl_inl(SH7751_WCR1); | 161 | word = ctrl_inl(SH7751_WCR1); |
183 | pci_write_reg(word, SH4_PCIWCR1); | 162 | pci_write_reg(chan, word, SH4_PCIWCR1); |
184 | word = ctrl_inl(SH7751_WCR2); | 163 | word = ctrl_inl(SH7751_WCR2); |
185 | pci_write_reg(word, SH4_PCIWCR2); | 164 | pci_write_reg(chan, word, SH4_PCIWCR2); |
186 | word = ctrl_inl(SH7751_WCR3); | 165 | word = ctrl_inl(SH7751_WCR3); |
187 | pci_write_reg(word, SH4_PCIWCR3); | 166 | pci_write_reg(chan, word, SH4_PCIWCR3); |
188 | word = ctrl_inl(SH7751_MCR); | 167 | word = ctrl_inl(SH7751_MCR); |
189 | pci_write_reg(word, SH4_PCIMCR); | 168 | pci_write_reg(chan, word, SH4_PCIMCR); |
190 | 169 | ||
191 | /* NOTE: I'm ignoring the PCI error IRQs for now.. | 170 | /* NOTE: I'm ignoring the PCI error IRQs for now.. |
192 | * TODO: add support for the internal error interrupts and | 171 | * TODO: add support for the internal error interrupts and |
193 | * DMA interrupts... | 172 | * DMA interrupts... |
194 | */ | 173 | */ |
195 | 174 | ||
196 | pci_fixup_pcic(); | 175 | pci_fixup_pcic(chan); |
197 | 176 | ||
198 | /* SH7751 init done, set central function init complete */ | 177 | /* SH7751 init done, set central function init complete */ |
199 | /* use round robin mode to stop a device starving/overruning */ | 178 | /* use round robin mode to stop a device starving/overruning */ |
200 | word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM; | 179 | word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM; |
201 | pci_write_reg(word, SH4_PCICR); | 180 | pci_write_reg(chan, word, SH4_PCICR); |
202 | 181 | ||
203 | return 1; | 182 | __set_io_port_base(SH7751_PCI_IO_BASE); |
183 | |||
184 | register_pci_controller(chan); | ||
185 | |||
186 | return 0; | ||
204 | } | 187 | } |
188 | arch_initcall(sh7751_pci_init); | ||
diff --git a/arch/sh/drivers/pci/pci-sh7751.h b/arch/sh/drivers/pci/pci-sh7751.h index 68e3cb5e6bec..4983a4d20355 100644 --- a/arch/sh/drivers/pci/pci-sh7751.h +++ b/arch/sh/drivers/pci/pci-sh7751.h | |||
@@ -26,7 +26,6 @@ | |||
26 | #define SH7751_PCI_IO_SIZE 0x40000 /* Size of IO window */ | 26 | #define SH7751_PCI_IO_SIZE 0x40000 /* Size of IO window */ |
27 | 27 | ||
28 | #define SH7751_PCIREG_BASE 0xFE200000 /* PCI regs base address */ | 28 | #define SH7751_PCIREG_BASE 0xFE200000 /* PCI regs base address */ |
29 | #define PCI_REG(n) (SH7751_PCIREG_BASE+ n) | ||
30 | 29 | ||
31 | #define SH7751_PCICONF0 0x0 /* PCI Config Reg 0 */ | 30 | #define SH7751_PCICONF0 0x0 /* PCI Config Reg 0 */ |
32 | #define SH7751_PCICONF0_DEVID 0xFFFF0000 /* Device ID */ | 31 | #define SH7751_PCICONF0_DEVID 0xFFFF0000 /* Device ID */ |
@@ -58,7 +57,7 @@ | |||
58 | #define SH7751_PCICONF2_SCC 0x00FF0000 /* Sub-Class Code */ | 57 | #define SH7751_PCICONF2_SCC 0x00FF0000 /* Sub-Class Code */ |
59 | #define SH7751_PCICONF2_RLPI 0x0000FF00 /* Programming Interface */ | 58 | #define SH7751_PCICONF2_RLPI 0x0000FF00 /* Programming Interface */ |
60 | #define SH7751_PCICONF2_REV 0x000000FF /* Revision ID */ | 59 | #define SH7751_PCICONF2_REV 0x000000FF /* Revision ID */ |
61 | #define SH7751_PCICONF3 0xC /* PCI Config Reg 3 */ | 60 | #define SH7751_PCICONF3 0xC /* PCI Config Reg 3 */ |
62 | #define SH7751_PCICONF3_BIST7 0x80000000 /* Bist Supported */ | 61 | #define SH7751_PCICONF3_BIST7 0x80000000 /* Bist Supported */ |
63 | #define SH7751_PCICONF3_BIST6 0x40000000 /* Bist Executing */ | 62 | #define SH7751_PCICONF3_BIST6 0x40000000 /* Bist Executing */ |
64 | #define SH7751_PCICONF3_BIST3_0 0x0F000000 /* Bist Passed */ | 63 | #define SH7751_PCICONF3_BIST3_0 0x0F000000 /* Bist Passed */ |
@@ -73,12 +72,12 @@ | |||
73 | #define SH7751_PCICONF5_BASE 0xFFFFFFF0 /* Mem Space Base Addr */ | 72 | #define SH7751_PCICONF5_BASE 0xFFFFFFF0 /* Mem Space Base Addr */ |
74 | #define SH7751_PCICONF5_LAP 0x00000008 /* Prefetch Enabled */ | 73 | #define SH7751_PCICONF5_LAP 0x00000008 /* Prefetch Enabled */ |
75 | #define SH7751_PCICONF5_LAT 0x00000006 /* Local Memory type */ | 74 | #define SH7751_PCICONF5_LAT 0x00000006 /* Local Memory type */ |
76 | #define SH7751_PCICONF5_ASI 0x00000001 /* Address Space Type */ | 75 | #define SH7751_PCICONF5_ASI 0x00000001 /* Address Space Type */ |
77 | #define SH7751_PCICONF6 0x18 /* PCI Config Reg 6 */ | 76 | #define SH7751_PCICONF6 0x18 /* PCI Config Reg 6 */ |
78 | #define SH7751_PCICONF6_BASE 0xFFFFFFF0 /* Mem Space Base Addr */ | 77 | #define SH7751_PCICONF6_BASE 0xFFFFFFF0 /* Mem Space Base Addr */ |
79 | #define SH7751_PCICONF6_LAP 0x00000008 /* Prefetch Enabled */ | 78 | #define SH7751_PCICONF6_LAP 0x00000008 /* Prefetch Enabled */ |
80 | #define SH7751_PCICONF6_LAT 0x00000006 /* Local Memory type */ | 79 | #define SH7751_PCICONF6_LAT 0x00000006 /* Local Memory type */ |
81 | #define SH7751_PCICONF6_ASI 0x00000001 /* Address Space Type */ | 80 | #define SH7751_PCICONF6_ASI 0x00000001 /* Address Space Type */ |
82 | /* PCICONF7 - PCICONF10 are undefined */ | 81 | /* PCICONF7 - PCICONF10 are undefined */ |
83 | #define SH7751_PCICONF11 0x2C /* PCI Config Reg 11 */ | 82 | #define SH7751_PCICONF11 0x2C /* PCI Config Reg 11 */ |
84 | #define SH7751_PCICONF11_SSID 0xFFFF0000 /* Subsystem ID */ | 83 | #define SH7751_PCICONF11_SSID 0xFFFF0000 /* Subsystem ID */ |
@@ -127,9 +126,4 @@ | |||
127 | #define SH7751_CS5_BASE_ADDR (SH7751_CS4_BASE_ADDR + SH7751_MEM_REGION_SIZE) | 126 | #define SH7751_CS5_BASE_ADDR (SH7751_CS4_BASE_ADDR + SH7751_MEM_REGION_SIZE) |
128 | #define SH7751_CS6_BASE_ADDR (SH7751_CS5_BASE_ADDR + SH7751_MEM_REGION_SIZE) | 127 | #define SH7751_CS6_BASE_ADDR (SH7751_CS5_BASE_ADDR + SH7751_MEM_REGION_SIZE) |
129 | 128 | ||
130 | struct sh4_pci_address_map; | ||
131 | |||
132 | /* arch/sh/drivers/pci/pci-sh7751.c */ | ||
133 | int sh7751_pcic_init(struct sh4_pci_address_map *map); | ||
134 | |||
135 | #endif /* _PCI_SH7751_H_ */ | 129 | #endif /* _PCI_SH7751_H_ */ |
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index bae6a2cf047d..ae13ff925c61 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c | |||
@@ -1,19 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * Low-Level PCI Support for the SH7780 | 2 | * Low-Level PCI Support for the SH7780 |
3 | * | 3 | * |
4 | * Dustin McIntire (dustin@sensoria.com) | 4 | * Copyright (C) 2005 - 2009 Paul Mundt |
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 | * | 5 | * |
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
14 | */ | 9 | */ |
15 | #undef DEBUG | ||
16 | |||
17 | #include <linux/types.h> | 10 | #include <linux/types.h> |
18 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
19 | #include <linux/init.h> | 12 | #include <linux/init.h> |
@@ -22,135 +15,137 @@ | |||
22 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
23 | #include "pci-sh4.h" | 16 | #include "pci-sh4.h" |
24 | 17 | ||
25 | #define INTC_BASE 0xffd00000 | 18 | extern u8 pci_cache_line_size; |
26 | #define INTC_ICR0 (INTC_BASE+0x0) | 19 | |
27 | #define INTC_ICR1 (INTC_BASE+0x1c) | 20 | static struct resource sh7785_io_resource = { |
28 | #define INTC_INTPRI (INTC_BASE+0x10) | 21 | .name = "SH7785_IO", |
29 | #define INTC_INTREQ (INTC_BASE+0x24) | 22 | .start = SH7780_PCI_IO_BASE, |
30 | #define INTC_INTMSK0 (INTC_BASE+0x44) | 23 | .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1, |
31 | #define INTC_INTMSK1 (INTC_BASE+0x48) | 24 | .flags = IORESOURCE_IO |
32 | #define INTC_INTMSK2 (INTC_BASE+0x40080) | 25 | }; |
33 | #define INTC_INTMSKCLR0 (INTC_BASE+0x64) | 26 | |
34 | #define INTC_INTMSKCLR1 (INTC_BASE+0x68) | 27 | static struct resource sh7785_mem_resource = { |
35 | #define INTC_INTMSKCLR2 (INTC_BASE+0x40084) | 28 | .name = "SH7785_mem", |
36 | #define INTC_INT2MSKR (INTC_BASE+0x40038) | 29 | .start = SH7780_PCI_MEMORY_BASE, |
37 | #define INTC_INT2MSKCR (INTC_BASE+0x4003c) | 30 | .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, |
31 | .flags = IORESOURCE_MEM | ||
32 | }; | ||
33 | |||
34 | static struct pci_channel sh7780_pci_controller = { | ||
35 | .pci_ops = &sh4_pci_ops, | ||
36 | .mem_resource = &sh7785_mem_resource, | ||
37 | .mem_offset = 0x00000000, | ||
38 | .io_resource = &sh7785_io_resource, | ||
39 | .io_offset = 0x00000000, | ||
40 | }; | ||
41 | |||
42 | static struct sh4_pci_address_map sh7780_pci_map = { | ||
43 | .window0 = { | ||
44 | #if defined(CONFIG_32BIT) | ||
45 | .base = SH7780_32BIT_DDR_BASE_ADDR, | ||
46 | .size = 0x40000000, | ||
47 | #else | ||
48 | .base = SH7780_CS0_BASE_ADDR, | ||
49 | .size = 0x20000000, | ||
50 | #endif | ||
51 | }, | ||
52 | }; | ||
38 | 53 | ||
39 | /* | ||
40 | * Initialization. Try all known PCI access methods. Note that we support | ||
41 | * using both PCI BIOS and direct access: in such cases, we use I/O ports | ||
42 | * to access config space. | ||
43 | * | ||
44 | * Note that the platform specific initialization (BSC registers, and memory | ||
45 | * space mapping) will be called via the platform defined function | ||
46 | * pcibios_init_platform(). | ||
47 | */ | ||
48 | static int __init sh7780_pci_init(void) | 54 | static int __init sh7780_pci_init(void) |
49 | { | 55 | { |
56 | struct pci_channel *chan = &sh7780_pci_controller; | ||
50 | unsigned int id; | 57 | unsigned int id; |
51 | int ret, match = 0; | 58 | const char *type = NULL; |
52 | 59 | int ret; | |
53 | pr_debug("PCI: Starting intialization.\n"); | 60 | u32 word; |
54 | |||
55 | ctrl_outl(0x00000001, SH7780_PCI_VCR2); /* Enable PCIC */ | ||
56 | |||
57 | /* check for SH7780/SH7780R hardware */ | ||
58 | id = pci_read_reg(SH7780_PCIVID); | ||
59 | if ((id & 0xffff) == SH7780_VENDOR_ID) { | ||
60 | switch ((id >> 16) & 0xffff) { | ||
61 | case SH7763_DEVICE_ID: | ||
62 | case SH7780_DEVICE_ID: | ||
63 | case SH7781_DEVICE_ID: | ||
64 | case SH7785_DEVICE_ID: | ||
65 | match = 1; | ||
66 | break; | ||
67 | } | ||
68 | } | ||
69 | 61 | ||
70 | if (unlikely(!match)) { | 62 | printk(KERN_NOTICE "PCI: Starting intialization.\n"); |
71 | printk(KERN_ERR "PCI: This is not an SH7780 (%x)\n", id); | 63 | |
64 | chan->reg_base = 0xfe040000; | ||
65 | |||
66 | /* Enable CPU access to the PCIC registers. */ | ||
67 | __raw_writel(PCIECR_ENBL, PCIECR); | ||
68 | |||
69 | id = __raw_readw(chan->reg_base + SH7780_PCIVID); | ||
70 | if (id != SH7780_VENDOR_ID) { | ||
71 | printk(KERN_ERR "PCI: Unknown vendor ID 0x%04x.\n", id); | ||
72 | return -ENODEV; | 72 | return -ENODEV; |
73 | } | 73 | } |
74 | 74 | ||
75 | /* Setup the INTC */ | 75 | id = __raw_readw(chan->reg_base + SH7780_PCIDID); |
76 | if (mach_is_7780se()) { | 76 | type = (id == SH7763_DEVICE_ID) ? "SH7763" : |
77 | /* ICR0: IRL=use separately */ | 77 | (id == SH7780_DEVICE_ID) ? "SH7780" : |
78 | ctrl_outl(0x00C00020, INTC_ICR0); | 78 | (id == SH7781_DEVICE_ID) ? "SH7781" : |
79 | /* ICR1: detect low level(for 2ndcut) */ | 79 | (id == SH7785_DEVICE_ID) ? "SH7785" : |
80 | ctrl_outl(0xAAAA0000, INTC_ICR1); | 80 | NULL; |
81 | /* INTPRI: priority=3(all) */ | 81 | if (unlikely(!type)) { |
82 | ctrl_outl(0x33333333, INTC_INTPRI); | 82 | printk(KERN_ERR "PCI: Found an unsupported Renesas host " |
83 | "controller, device id 0x%04x.\n", id); | ||
84 | return -EINVAL; | ||
83 | } | 85 | } |
84 | 86 | ||
85 | if ((ret = sh4_pci_check_direct()) != 0) | 87 | printk(KERN_NOTICE "PCI: Found a Renesas %s host " |
86 | return ret; | 88 | "controller, revision %d.\n", type, |
89 | __raw_readb(chan->reg_base + SH7780_PCIRID)); | ||
87 | 90 | ||
88 | return pcibios_init_platform(); | 91 | if ((ret = sh4_pci_check_direct(chan)) != 0) |
89 | } | 92 | return ret; |
90 | core_initcall(sh7780_pci_init); | ||
91 | |||
92 | int __init sh7780_pcic_init(struct sh4_pci_address_map *map) | ||
93 | { | ||
94 | u32 word; | ||
95 | 93 | ||
96 | /* | 94 | /* |
97 | * This code is unused for some boards as it is done in the | 95 | * Set the class and sub-class codes. |
98 | * bootloader and doing it here means the MAC addresses loaded | ||
99 | * by the bootloader get lost. | ||
100 | */ | ||
101 | if (!(map->flags & SH4_PCIC_NO_RESET)) { | ||
102 | /* toggle PCI reset pin */ | ||
103 | word = SH4_PCICR_PREFIX | SH4_PCICR_PRST; | ||
104 | pci_write_reg(word, SH4_PCICR); | ||
105 | /* Wait for a long time... not 1 sec. but long enough */ | ||
106 | mdelay(100); | ||
107 | word = SH4_PCICR_PREFIX; | ||
108 | pci_write_reg(word, SH4_PCICR); | ||
109 | } | ||
110 | |||
111 | /* set the command/status bits to: | ||
112 | * Wait Cycle Control + Parity Enable + Bus Master + | ||
113 | * Mem space enable | ||
114 | */ | 96 | */ |
115 | pci_write_reg(0x00000046, SH7780_PCICMD); | 97 | __raw_writeb(PCI_CLASS_BRIDGE_HOST >> 8, |
98 | chan->reg_base + SH7780_PCIBCC); | ||
99 | __raw_writeb(PCI_CLASS_BRIDGE_HOST & 0xff, | ||
100 | chan->reg_base + SH7780_PCISUB); | ||
116 | 101 | ||
117 | /* define this host as the host bridge */ | 102 | pci_cache_line_size = pci_read_reg(chan, SH7780_PCICLS) / 4; |
118 | word = PCI_BASE_CLASS_BRIDGE << 24; | ||
119 | pci_write_reg(word, SH7780_PCIRID); | ||
120 | 103 | ||
121 | /* Set IO and Mem windows to local address | 104 | /* |
105 | * Set IO and Mem windows to local address | ||
122 | * Make PCI and local address the same for easy 1 to 1 mapping | 106 | * Make PCI and local address the same for easy 1 to 1 mapping |
123 | */ | 107 | */ |
124 | pci_write_reg(map->window0.size - 0xfffff, SH4_PCILSR0); | 108 | pci_write_reg(chan, sh7780_pci_map.window0.size - 0xfffff, SH4_PCILSR0); |
125 | pci_write_reg(map->window1.size - 0xfffff, SH4_PCILSR1); | ||
126 | /* Set the values on window 0 PCI config registers */ | 109 | /* Set the values on window 0 PCI config registers */ |
127 | pci_write_reg(map->window0.base, SH4_PCILAR0); | 110 | pci_write_reg(chan, sh7780_pci_map.window0.base, SH4_PCILAR0); |
128 | pci_write_reg(map->window0.base, SH7780_PCIMBAR0); | 111 | pci_write_reg(chan, sh7780_pci_map.window0.base, SH7780_PCIMBAR0); |
129 | /* Set the values on window 1 PCI config registers */ | ||
130 | pci_write_reg(map->window1.base, SH4_PCILAR1); | ||
131 | pci_write_reg(map->window1.base, SH7780_PCIMBAR1); | ||
132 | |||
133 | /* Map IO space into PCI IO window | ||
134 | * The IO window is 64K-PCIBIOS_MIN_IO in size | ||
135 | * IO addresses will be translated to the | ||
136 | * PCI IO window base address | ||
137 | */ | ||
138 | pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", | ||
139 | PCIBIOS_MIN_IO, (64 << 10), | ||
140 | SH7780_PCI_IO_BASE + PCIBIOS_MIN_IO); | ||
141 | 112 | ||
142 | /* NOTE: I'm ignoring the PCI error IRQs for now.. | 113 | pci_write_reg(chan, 0x0000380f, SH4_PCIAINTM); |
143 | * TODO: add support for the internal error interrupts and | 114 | |
144 | * DMA interrupts... | 115 | /* Set up standard PCI config registers */ |
145 | */ | 116 | __raw_writew(0xFB00, chan->reg_base + SH7780_PCISTATUS); |
117 | __raw_writew(0x0047, chan->reg_base + SH7780_PCICMD); | ||
118 | __raw_writew(0x1912, chan->reg_base + SH7780_PCISVID); | ||
119 | __raw_writew(0x0001, chan->reg_base + SH7780_PCISID); | ||
120 | |||
121 | __raw_writeb(0x00, chan->reg_base + SH7780_PCIPIF); | ||
146 | 122 | ||
147 | /* Apply any last-minute PCIC fixups */ | 123 | /* Apply any last-minute PCIC fixups */ |
148 | pci_fixup_pcic(); | 124 | pci_fixup_pcic(chan); |
125 | |||
126 | pci_write_reg(chan, 0xfd000000, SH7780_PCIMBR0); | ||
127 | pci_write_reg(chan, 0x00fc0000, SH7780_PCIMBMR0); | ||
128 | |||
129 | #ifdef CONFIG_32BIT | ||
130 | pci_write_reg(chan, 0xc0000000, SH7780_PCIMBR2); | ||
131 | pci_write_reg(chan, 0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2); | ||
132 | #endif | ||
133 | |||
134 | /* Set IOBR for windows containing area specified in pci.h */ | ||
135 | pci_write_reg(chan, chan->io_resource->start & ~(SH7780_PCI_IO_SIZE-1), | ||
136 | SH7780_PCIIOBR); | ||
137 | pci_write_reg(chan, ((SH7780_PCI_IO_SIZE-1) & (7<<18)), | ||
138 | SH7780_PCIIOBMR); | ||
149 | 139 | ||
150 | /* SH7780 init done, set central function init complete */ | 140 | /* SH7780 init done, set central function init complete */ |
151 | /* use round robin mode to stop a device starving/overruning */ | 141 | /* use round robin mode to stop a device starving/overruning */ |
152 | word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO; | 142 | word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO; |
153 | pci_write_reg(word, SH4_PCICR); | 143 | pci_write_reg(chan, word, SH4_PCICR); |
144 | |||
145 | __set_io_port_base(SH7780_PCI_IO_BASE); | ||
146 | |||
147 | register_pci_controller(chan); | ||
154 | 148 | ||
155 | return 1; | 149 | return 0; |
156 | } | 150 | } |
151 | arch_initcall(sh7780_pci_init); | ||
diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h index 93adc7119b79..4a52478c97cf 100644 --- a/arch/sh/drivers/pci/pci-sh7780.h +++ b/arch/sh/drivers/pci/pci-sh7780.h | |||
@@ -20,9 +20,8 @@ | |||
20 | #define SH7785_DEVICE_ID 0x0007 | 20 | #define SH7785_DEVICE_ID 0x0007 |
21 | 21 | ||
22 | /* SH7780 Control Registers */ | 22 | /* SH7780 Control Registers */ |
23 | #define SH7780_PCI_VCR0 0xFE000000 | 23 | #define PCIECR 0xFE000008 |
24 | #define SH7780_PCI_VCR1 0xFE000004 | 24 | #define PCIECR_ENBL 0x01 |
25 | #define SH7780_PCI_VCR2 0xFE000008 | ||
26 | 25 | ||
27 | /* SH7780 Specific Values */ | 26 | /* SH7780 Specific Values */ |
28 | #define SH7780_PCI_CONFIG_BASE 0xFD000000 /* Config space base addr */ | 27 | #define SH7780_PCI_CONFIG_BASE 0xFD000000 /* Config space base addr */ |
@@ -35,7 +34,6 @@ | |||
35 | #define SH7780_PCI_IO_SIZE 0x00400000 /* Size of IO window */ | 34 | #define SH7780_PCI_IO_SIZE 0x00400000 /* Size of IO window */ |
36 | 35 | ||
37 | #define SH7780_PCIREG_BASE 0xFE040000 /* PCI regs base address */ | 36 | #define SH7780_PCIREG_BASE 0xFE040000 /* PCI regs base address */ |
38 | #define PCI_REG(n) (SH7780_PCIREG_BASE+n) | ||
39 | 37 | ||
40 | /* SH7780 PCI Config Registers */ | 38 | /* SH7780 PCI Config Registers */ |
41 | #define SH7780_PCIVID 0x000 /* Vendor ID */ | 39 | #define SH7780_PCIVID 0x000 /* Vendor ID */ |
@@ -67,11 +65,6 @@ | |||
67 | #define SH7780_PCIPMCSR_BSE 0x046 | 65 | #define SH7780_PCIPMCSR_BSE 0x046 |
68 | #define SH7780_PCICDD 0x047 | 66 | #define SH7780_PCICDD 0x047 |
69 | 67 | ||
70 | #define SH7780_PCICR 0x100 /* PCI Control Register */ | ||
71 | #define SH7780_PCILSR 0x104 /* PCI Local Space Register0 */ | ||
72 | #define SH7780_PCILSR1 0x108 /* PCI Local Space Register1 */ | ||
73 | #define SH7780_PCILAR0 0x10C /* PCI Local Address Register1 */ | ||
74 | #define SH7780_PCILAR1 0x110 /* PCI Local Address Register1 */ | ||
75 | #define SH7780_PCIIR 0x114 /* PCI Interrupt Register */ | 68 | #define SH7780_PCIIR 0x114 /* PCI Interrupt Register */ |
76 | #define SH7780_PCIIMR 0x118 /* PCI Interrupt Mask Register */ | 69 | #define SH7780_PCIIMR 0x118 /* PCI Interrupt Mask Register */ |
77 | #define SH7780_PCIAIR 0x11C /* Error Address Register */ | 70 | #define SH7780_PCIAIR 0x11C /* Error Address Register */ |
@@ -106,9 +99,4 @@ | |||
106 | 99 | ||
107 | #define SH7780_32BIT_DDR_BASE_ADDR 0x40000000 | 100 | #define SH7780_32BIT_DDR_BASE_ADDR 0x40000000 |
108 | 101 | ||
109 | struct sh4_pci_address_map; | ||
110 | |||
111 | /* arch/sh/drivers/pci/pci-sh7780.c */ | ||
112 | int sh7780_pcic_init(struct sh4_pci_address_map *map); | ||
113 | |||
114 | #endif /* _PCI_SH7780_H_ */ | 102 | #endif /* _PCI_SH7780_H_ */ |
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 0d6ac7a1db49..54d77cbb8b39 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c | |||
@@ -1,67 +1,156 @@ | |||
1 | /* | 1 | /* |
2 | * arch/sh/drivers/pci/pci.c | 2 | * New-style PCI core. |
3 | * | 3 | * |
4 | * Copyright (c) 2002 M. R. Brown <mrbrown@linux-sh.org> | 4 | * Copyright (c) 2004 - 2009 Paul Mundt |
5 | * Copyright (c) 2004 - 2006 Paul Mundt <lethal@linux-sh.org> | 5 | * Copyright (c) 2002 M. R. Brown |
6 | * | 6 | * |
7 | * These functions are collected here to reduce duplication of common | 7 | * Modelled after arch/mips/pci/pci.c: |
8 | * code amongst the many platform-specific PCI support code files. | 8 | * Copyright (C) 2003, 04 Ralf Baechle (ralf@linux-mips.org) |
9 | * | ||
10 | * These routines require the following board-specific routines: | ||
11 | * void pcibios_fixup_irqs(); | ||
12 | * | ||
13 | * See include/asm-sh/pci.h for more information. | ||
14 | * | 9 | * |
15 | * This file is subject to the terms and conditions of the GNU General Public | 10 | * 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 | 11 | * License. See the file "COPYING" in the main directory of this archive |
17 | * for more details. | 12 | * for more details. |
18 | */ | 13 | */ |
19 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/mm.h> | ||
20 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
21 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/types.h> | ||
22 | #include <linux/dma-debug.h> | 19 | #include <linux/dma-debug.h> |
23 | #include <asm/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/mutex.h> | ||
24 | 22 | ||
25 | static int __init pcibios_init(void) | 23 | unsigned long PCIBIOS_MIN_IO = 0x0000; |
24 | unsigned long PCIBIOS_MIN_MEM = 0; | ||
25 | |||
26 | /* | ||
27 | * The PCI controller list. | ||
28 | */ | ||
29 | static struct pci_channel *hose_head, **hose_tail = &hose_head; | ||
30 | |||
31 | static int pci_initialized; | ||
32 | |||
33 | static void __devinit pcibios_scanbus(struct pci_channel *hose) | ||
26 | { | 34 | { |
27 | struct pci_channel *p; | 35 | static int next_busno; |
28 | struct pci_bus *bus; | 36 | struct pci_bus *bus; |
29 | int busno; | ||
30 | 37 | ||
31 | #ifdef CONFIG_PCI_AUTO | 38 | bus = pci_scan_bus(next_busno, hose->pci_ops, hose); |
32 | /* assign resources */ | 39 | if (bus) { |
33 | busno = 0; | 40 | next_busno = bus->subordinate + 1; |
34 | for (p = board_pci_channels; p->pci_ops != NULL; p++) | 41 | /* Don't allow 8-bit bus number overflow inside the hose - |
35 | busno = pciauto_assign_resources(busno, p) + 1; | 42 | reserve some space for bridges. */ |
36 | #endif | 43 | if (next_busno > 224) |
44 | next_busno = 0; | ||
45 | |||
46 | pci_bus_size_bridges(bus); | ||
47 | pci_bus_assign_resources(bus); | ||
48 | pci_enable_bridges(bus); | ||
49 | } | ||
50 | } | ||
51 | |||
52 | static DEFINE_MUTEX(pci_scan_mutex); | ||
37 | 53 | ||
38 | /* scan the buses */ | 54 | void __devinit register_pci_controller(struct pci_channel *hose) |
39 | busno = 0; | 55 | { |
40 | for (p = board_pci_channels; p->pci_ops != NULL; p++) { | 56 | if (request_resource(&iomem_resource, hose->mem_resource) < 0) |
41 | bus = pci_scan_bus(busno, p->pci_ops, p); | 57 | goto out; |
42 | busno = bus->subordinate + 1; | 58 | if (request_resource(&ioport_resource, hose->io_resource) < 0) { |
59 | release_resource(hose->mem_resource); | ||
60 | goto out; | ||
43 | } | 61 | } |
44 | 62 | ||
63 | *hose_tail = hose; | ||
64 | hose_tail = &hose->next; | ||
65 | |||
66 | /* | ||
67 | * Do not panic here but later - this might hapen before console init. | ||
68 | */ | ||
69 | if (!hose->io_map_base) { | ||
70 | printk(KERN_WARNING | ||
71 | "registering PCI controller with io_map_base unset\n"); | ||
72 | } | ||
73 | |||
74 | /* | ||
75 | * Scan the bus if it is register after the PCI subsystem | ||
76 | * initialization. | ||
77 | */ | ||
78 | if (pci_initialized) { | ||
79 | mutex_lock(&pci_scan_mutex); | ||
80 | pcibios_scanbus(hose); | ||
81 | mutex_unlock(&pci_scan_mutex); | ||
82 | } | ||
83 | |||
84 | return; | ||
85 | |||
86 | out: | ||
87 | printk(KERN_WARNING | ||
88 | "Skipping PCI bus scan due to resource conflict\n"); | ||
89 | } | ||
90 | |||
91 | static int __init pcibios_init(void) | ||
92 | { | ||
93 | struct pci_channel *hose; | ||
94 | |||
95 | /* Scan all of the recorded PCI controllers. */ | ||
96 | for (hose = hose_head; hose; hose = hose->next) | ||
97 | pcibios_scanbus(hose); | ||
98 | |||
45 | pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq); | 99 | pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq); |
46 | 100 | ||
47 | dma_debug_add_bus(&pci_bus_type); | 101 | dma_debug_add_bus(&pci_bus_type); |
48 | 102 | ||
103 | pci_initialized = 1; | ||
104 | |||
49 | return 0; | 105 | return 0; |
50 | } | 106 | } |
51 | subsys_initcall(pcibios_init); | 107 | subsys_initcall(pcibios_init); |
52 | 108 | ||
109 | static void pcibios_fixup_device_resources(struct pci_dev *dev, | ||
110 | struct pci_bus *bus) | ||
111 | { | ||
112 | /* Update device resources. */ | ||
113 | struct pci_channel *hose = bus->sysdata; | ||
114 | unsigned long offset = 0; | ||
115 | int i; | ||
116 | |||
117 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
118 | if (!dev->resource[i].start) | ||
119 | continue; | ||
120 | if (dev->resource[i].flags & IORESOURCE_PCI_FIXED) | ||
121 | continue; | ||
122 | if (dev->resource[i].flags & IORESOURCE_IO) | ||
123 | offset = hose->io_offset; | ||
124 | else if (dev->resource[i].flags & IORESOURCE_MEM) | ||
125 | offset = hose->mem_offset; | ||
126 | |||
127 | dev->resource[i].start += offset; | ||
128 | dev->resource[i].end += offset; | ||
129 | } | ||
130 | } | ||
131 | |||
53 | /* | 132 | /* |
54 | * Called after each bus is probed, but before its children | 133 | * Called after each bus is probed, but before its children |
55 | * are examined. | 134 | * are examined. |
56 | */ | 135 | */ |
57 | void __devinit __weak pcibios_fixup_bus(struct pci_bus *bus) | 136 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) |
58 | { | 137 | { |
59 | pci_read_bridge_bases(bus); | 138 | struct pci_dev *dev = bus->self; |
60 | } | 139 | struct list_head *ln; |
140 | struct pci_channel *chan = bus->sysdata; | ||
61 | 141 | ||
62 | void pcibios_align_resource(void *data, struct resource *res, | 142 | if (!dev) { |
63 | resource_size_t size, resource_size_t align) | 143 | bus->resource[0] = chan->io_resource; |
64 | __attribute__ ((weak)); | 144 | bus->resource[1] = chan->mem_resource; |
145 | } | ||
146 | |||
147 | for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { | ||
148 | dev = pci_dev_b(ln); | ||
149 | |||
150 | if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) | ||
151 | pcibios_fixup_device_resources(dev, bus); | ||
152 | } | ||
153 | } | ||
65 | 154 | ||
66 | /* | 155 | /* |
67 | * We need to avoid collisions with `mirrored' VGA ports | 156 | * We need to avoid collisions with `mirrored' VGA ports |
@@ -72,14 +161,58 @@ void pcibios_align_resource(void *data, struct resource *res, | |||
72 | void pcibios_align_resource(void *data, struct resource *res, | 161 | void pcibios_align_resource(void *data, struct resource *res, |
73 | resource_size_t size, resource_size_t align) | 162 | resource_size_t size, resource_size_t align) |
74 | { | 163 | { |
164 | struct pci_dev *dev = data; | ||
165 | struct pci_channel *chan = dev->sysdata; | ||
166 | resource_size_t start = res->start; | ||
167 | |||
75 | if (res->flags & IORESOURCE_IO) { | 168 | if (res->flags & IORESOURCE_IO) { |
76 | resource_size_t start = res->start; | 169 | if (start < PCIBIOS_MIN_IO + chan->io_resource->start) |
170 | start = PCIBIOS_MIN_IO + chan->io_resource->start; | ||
77 | 171 | ||
172 | /* | ||
173 | * Put everything into 0x00-0xff region modulo 0x400. | ||
174 | */ | ||
78 | if (start & 0x300) { | 175 | if (start & 0x300) { |
79 | start = (start + 0x3ff) & ~0x3ff; | 176 | start = (start + 0x3ff) & ~0x3ff; |
80 | res->start = start; | 177 | res->start = start; |
81 | } | 178 | } |
179 | } else if (res->flags & IORESOURCE_MEM) { | ||
180 | if (start < PCIBIOS_MIN_MEM + chan->mem_resource->start) | ||
181 | start = PCIBIOS_MIN_MEM + chan->mem_resource->start; | ||
82 | } | 182 | } |
183 | |||
184 | res->start = start; | ||
185 | } | ||
186 | |||
187 | void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | ||
188 | struct resource *res) | ||
189 | { | ||
190 | struct pci_channel *hose = dev->sysdata; | ||
191 | unsigned long offset = 0; | ||
192 | |||
193 | if (res->flags & IORESOURCE_IO) | ||
194 | offset = hose->io_offset; | ||
195 | else if (res->flags & IORESOURCE_MEM) | ||
196 | offset = hose->mem_offset; | ||
197 | |||
198 | region->start = res->start - offset; | ||
199 | region->end = res->end - offset; | ||
200 | } | ||
201 | |||
202 | void __devinit | ||
203 | pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
204 | struct pci_bus_region *region) | ||
205 | { | ||
206 | struct pci_channel *hose = dev->sysdata; | ||
207 | unsigned long offset = 0; | ||
208 | |||
209 | if (res->flags & IORESOURCE_IO) | ||
210 | offset = hose->io_offset; | ||
211 | else if (res->flags & IORESOURCE_MEM) | ||
212 | offset = hose->mem_offset; | ||
213 | |||
214 | res->start = region->start + offset; | ||
215 | res->end = region->end + offset; | ||
83 | } | 216 | } |
84 | 217 | ||
85 | int pcibios_enable_device(struct pci_dev *dev, int mask) | 218 | int pcibios_enable_device(struct pci_dev *dev, int mask) |
@@ -90,13 +223,21 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
90 | 223 | ||
91 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | 224 | pci_read_config_word(dev, PCI_COMMAND, &cmd); |
92 | old_cmd = cmd; | 225 | old_cmd = cmd; |
93 | for(idx=0; idx<6; idx++) { | 226 | for (idx=0; idx < PCI_NUM_RESOURCES; idx++) { |
94 | if (!(mask & (1 << idx))) | 227 | /* Only set up the requested stuff */ |
228 | if (!(mask & (1<<idx))) | ||
95 | continue; | 229 | continue; |
230 | |||
96 | r = &dev->resource[idx]; | 231 | r = &dev->resource[idx]; |
232 | if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM))) | ||
233 | continue; | ||
234 | if ((idx == PCI_ROM_RESOURCE) && | ||
235 | (!(r->flags & IORESOURCE_ROM_ENABLE))) | ||
236 | continue; | ||
97 | if (!r->start && r->end) { | 237 | if (!r->start && r->end) { |
98 | printk(KERN_ERR "PCI: Device %s not available because " | 238 | printk(KERN_ERR "PCI: Device %s not available " |
99 | "of resource collisions\n", pci_name(dev)); | 239 | "because of resource collisions\n", |
240 | pci_name(dev)); | ||
100 | return -EINVAL; | 241 | return -EINVAL; |
101 | } | 242 | } |
102 | if (r->flags & IORESOURCE_IO) | 243 | if (r->flags & IORESOURCE_IO) |
@@ -104,10 +245,8 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
104 | if (r->flags & IORESOURCE_MEM) | 245 | if (r->flags & IORESOURCE_MEM) |
105 | cmd |= PCI_COMMAND_MEMORY; | 246 | cmd |= PCI_COMMAND_MEMORY; |
106 | } | 247 | } |
107 | if (dev->resource[PCI_ROM_RESOURCE].start) | ||
108 | cmd |= PCI_COMMAND_MEMORY; | ||
109 | if (cmd != old_cmd) { | 248 | if (cmd != old_cmd) { |
110 | printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", | 249 | printk("PCI: Enabling device %s (%04x -> %04x)\n", |
111 | pci_name(dev), old_cmd, cmd); | 250 | pci_name(dev), old_cmd, cmd); |
112 | pci_write_config_word(dev, PCI_COMMAND, cmd); | 251 | pci_write_config_word(dev, PCI_COMMAND, cmd); |
113 | } | 252 | } |
@@ -140,6 +279,43 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq) | |||
140 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); | 279 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); |
141 | } | 280 | } |
142 | 281 | ||
282 | char * __devinit pcibios_setup(char *str) | ||
283 | { | ||
284 | return str; | ||
285 | } | ||
286 | |||
287 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | ||
288 | enum pci_mmap_state mmap_state, int write_combine) | ||
289 | { | ||
290 | /* | ||
291 | * I/O space can be accessed via normal processor loads and stores on | ||
292 | * this platform but for now we elect not to do this and portable | ||
293 | * drivers should not do this anyway. | ||
294 | */ | ||
295 | if (mmap_state == pci_mmap_io) | ||
296 | return -EINVAL; | ||
297 | |||
298 | /* | ||
299 | * Ignore write-combine; for now only return uncached mappings. | ||
300 | */ | ||
301 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
302 | |||
303 | return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, | ||
304 | vma->vm_end - vma->vm_start, | ||
305 | vma->vm_page_prot); | ||
306 | } | ||
307 | |||
308 | static void __iomem *ioport_map_pci(struct pci_dev *dev, | ||
309 | unsigned long port, unsigned int nr) | ||
310 | { | ||
311 | struct pci_channel *chan = dev->sysdata; | ||
312 | |||
313 | if (!chan->io_map_base) | ||
314 | chan->io_map_base = generic_io_base; | ||
315 | |||
316 | return (void __iomem *)(chan->io_map_base + port); | ||
317 | } | ||
318 | |||
143 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) | 319 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) |
144 | { | 320 | { |
145 | resource_size_t start = pci_resource_start(dev, bar); | 321 | resource_size_t start = pci_resource_start(dev, bar); |
@@ -151,20 +327,24 @@ void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) | |||
151 | if (maxlen && len > maxlen) | 327 | if (maxlen && len > maxlen) |
152 | len = maxlen; | 328 | len = maxlen; |
153 | 329 | ||
330 | if (flags & IORESOURCE_IO) | ||
331 | return ioport_map_pci(dev, start, len); | ||
332 | |||
154 | /* | 333 | /* |
155 | * Presently the IORESOURCE_MEM case is a bit special, most | 334 | * Presently the IORESOURCE_MEM case is a bit special, most |
156 | * SH7751 style PCI controllers have PCI memory at a fixed | 335 | * SH7751 style PCI controllers have PCI memory at a fixed |
157 | * location in the address space where no remapping is desired | 336 | * location in the address space where no remapping is desired. |
158 | * (typically at 0xfd000000, but is_pci_memaddr() will know | 337 | * With the IORESOURCE_MEM case more care has to be taken |
159 | * best). With the IORESOURCE_MEM case more care has to be taken | ||
160 | * to inhibit page table mapping for legacy cores, but this is | 338 | * to inhibit page table mapping for legacy cores, but this is |
161 | * punted off to __ioremap(). | 339 | * punted off to __ioremap(). |
162 | * -- PFM. | 340 | * -- PFM. |
163 | */ | 341 | */ |
164 | if (flags & IORESOURCE_IO) | 342 | if (flags & IORESOURCE_MEM) { |
165 | return ioport_map(start, len); | 343 | if (flags & IORESOURCE_CACHEABLE) |
166 | if (flags & IORESOURCE_MEM) | 344 | return ioremap(start, len); |
167 | return ioremap(start, len); | 345 | |
346 | return ioremap_nocache(start, len); | ||
347 | } | ||
168 | 348 | ||
169 | return NULL; | 349 | return NULL; |
170 | } | 350 | } |
@@ -175,3 +355,10 @@ void pci_iounmap(struct pci_dev *dev, void __iomem *addr) | |||
175 | iounmap(addr); | 355 | iounmap(addr); |
176 | } | 356 | } |
177 | EXPORT_SYMBOL(pci_iounmap); | 357 | EXPORT_SYMBOL(pci_iounmap); |
358 | |||
359 | #ifdef CONFIG_HOTPLUG | ||
360 | EXPORT_SYMBOL(pcibios_resource_to_bus); | ||
361 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
362 | EXPORT_SYMBOL(PCIBIOS_MIN_IO); | ||
363 | EXPORT_SYMBOL(PCIBIOS_MIN_MEM); | ||
364 | #endif | ||