diff options
Diffstat (limited to 'arch/sh/drivers')
-rw-r--r-- | arch/sh/drivers/dma/dma-api.c | 4 | ||||
-rw-r--r-- | arch/sh/drivers/pci/Makefile | 1 | ||||
-rw-r--r-- | arch/sh/drivers/pci/fixups-sdk7786.c | 67 | ||||
-rw-r--r-- | arch/sh/drivers/pci/ops-sh4.c | 11 | ||||
-rw-r--r-- | arch/sh/drivers/pci/ops-sh7786.c | 69 | ||||
-rw-r--r-- | arch/sh/drivers/pci/pci-sh7751.c | 2 | ||||
-rw-r--r-- | arch/sh/drivers/pci/pci-sh7780.c | 2 | ||||
-rw-r--r-- | arch/sh/drivers/pci/pci-sh7780.h | 6 | ||||
-rw-r--r-- | arch/sh/drivers/pci/pci.c | 43 | ||||
-rw-r--r-- | arch/sh/drivers/pci/pcie-sh7786.c | 251 | ||||
-rw-r--r-- | arch/sh/drivers/pci/pcie-sh7786.h | 56 |
11 files changed, 387 insertions, 125 deletions
diff --git a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c index 4a277224a871..f46848f088e4 100644 --- a/arch/sh/drivers/dma/dma-api.c +++ b/arch/sh/drivers/dma/dma-api.c | |||
@@ -412,8 +412,8 @@ EXPORT_SYMBOL(unregister_dmac); | |||
412 | static int __init dma_api_init(void) | 412 | static int __init dma_api_init(void) |
413 | { | 413 | { |
414 | printk(KERN_NOTICE "DMA: Registering DMA API.\n"); | 414 | printk(KERN_NOTICE "DMA: Registering DMA API.\n"); |
415 | create_proc_read_entry("dma", 0, 0, dma_read_proc, 0); | 415 | return create_proc_read_entry("dma", 0, 0, dma_read_proc, 0) |
416 | return 0; | 416 | ? 0 : -ENOMEM; |
417 | } | 417 | } |
418 | subsys_initcall(dma_api_init); | 418 | subsys_initcall(dma_api_init); |
419 | 419 | ||
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index 4a59e6890876..82f0a335fd19 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile | |||
@@ -19,6 +19,7 @@ obj-$(CONFIG_SH_RTS7751R2D) += fixups-rts7751r2d.o | |||
19 | obj-$(CONFIG_SH_SH03) += fixups-sh03.o | 19 | obj-$(CONFIG_SH_SH03) += fixups-sh03.o |
20 | obj-$(CONFIG_SH_HIGHLANDER) += fixups-r7780rp.o | 20 | obj-$(CONFIG_SH_HIGHLANDER) += fixups-r7780rp.o |
21 | obj-$(CONFIG_SH_SH7785LCR) += fixups-r7780rp.o | 21 | obj-$(CONFIG_SH_SH7785LCR) += fixups-r7780rp.o |
22 | obj-$(CONFIG_SH_SDK7786) += fixups-sdk7786.o | ||
22 | obj-$(CONFIG_SH_SDK7780) += fixups-sdk7780.o | 23 | obj-$(CONFIG_SH_SDK7780) += fixups-sdk7780.o |
23 | obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += fixups-sdk7780.o | 24 | obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += fixups-sdk7780.o |
24 | obj-$(CONFIG_SH_TITAN) += fixups-titan.o | 25 | obj-$(CONFIG_SH_TITAN) += fixups-titan.o |
diff --git a/arch/sh/drivers/pci/fixups-sdk7786.c b/arch/sh/drivers/pci/fixups-sdk7786.c new file mode 100644 index 000000000000..0e18ee332553 --- /dev/null +++ b/arch/sh/drivers/pci/fixups-sdk7786.c | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * SDK7786 FPGA PCIe mux handling | ||
3 | * | ||
4 | * Copyright (C) 2010 Paul Mundt | ||
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. | ||
9 | */ | ||
10 | #define pr_fmt(fmt) "PCI: " fmt | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/pci.h> | ||
15 | #include <mach/fpga.h> | ||
16 | |||
17 | /* | ||
18 | * The SDK7786 FPGA supports mangling of most of the slots in some way or | ||
19 | * another. Slots 3/4 are special in that only one can be supported at a | ||
20 | * time, and both appear on port 3 to the PCI bus scan. Enabling slot 4 | ||
21 | * (the horizontal edge connector) will disable slot 3 entirely. | ||
22 | * | ||
23 | * Misconfigurations can be detected through the FPGA via the slot | ||
24 | * resistors to determine card presence. Hotplug remains unsupported. | ||
25 | */ | ||
26 | static unsigned int slot4en __devinitdata; | ||
27 | |||
28 | char *__devinit pcibios_setup(char *str) | ||
29 | { | ||
30 | if (strcmp(str, "slot4en") == 0) { | ||
31 | slot4en = 1; | ||
32 | return NULL; | ||
33 | } | ||
34 | |||
35 | return str; | ||
36 | } | ||
37 | |||
38 | static int __init sdk7786_pci_init(void) | ||
39 | { | ||
40 | u16 data = fpga_read_reg(PCIECR); | ||
41 | |||
42 | /* | ||
43 | * Enable slot #4 if it's been specified on the command line. | ||
44 | * | ||
45 | * Optionally reroute if slot #4 has a card present while slot #3 | ||
46 | * does not, regardless of command line value. | ||
47 | * | ||
48 | * Card presence is logically inverted. | ||
49 | */ | ||
50 | slot4en ?: (!(data & PCIECR_PRST4) && (data & PCIECR_PRST3)); | ||
51 | if (slot4en) { | ||
52 | pr_info("Activating PCIe slot#4 (disabling slot#3)\n"); | ||
53 | |||
54 | data &= ~PCIECR_PCIEMUX1; | ||
55 | fpga_write_reg(data, PCIECR); | ||
56 | |||
57 | /* Warn about forced rerouting if slot#3 is occupied */ | ||
58 | if ((data & PCIECR_PRST3) == 0) { | ||
59 | pr_warning("Unreachable card detected in slot#3\n"); | ||
60 | return -EBUSY; | ||
61 | } | ||
62 | } else | ||
63 | pr_info("PCIe slot#4 disabled\n"); | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | postcore_initcall(sdk7786_pci_init); | ||
diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c index 0b81999fb88b..b6234203e0ac 100644 --- a/arch/sh/drivers/pci/ops-sh4.c +++ b/arch/sh/drivers/pci/ops-sh4.c | |||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | #include <linux/pci.h> | 10 | #include <linux/pci.h> |
11 | #include <linux/io.h> | 11 | #include <linux/io.h> |
12 | #include <linux/spinlock.h> | ||
12 | #include <asm/addrspace.h> | 13 | #include <asm/addrspace.h> |
13 | #include "pci-sh4.h" | 14 | #include "pci-sh4.h" |
14 | 15 | ||
@@ -18,8 +19,6 @@ | |||
18 | #define CONFIG_CMD(bus, devfn, where) \ | 19 | #define CONFIG_CMD(bus, devfn, where) \ |
19 | (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) | 20 | (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) |
20 | 21 | ||
21 | static DEFINE_SPINLOCK(sh4_pci_lock); | ||
22 | |||
23 | /* | 22 | /* |
24 | * Functions for accessing PCI configuration space with type 1 accesses | 23 | * Functions for accessing PCI configuration space with type 1 accesses |
25 | */ | 24 | */ |
@@ -34,10 +33,10 @@ static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn, | |||
34 | * PCIPDR may only be accessed as 32 bit words, | 33 | * PCIPDR may only be accessed as 32 bit words, |
35 | * so we must do byte alignment by hand | 34 | * so we must do byte alignment by hand |
36 | */ | 35 | */ |
37 | spin_lock_irqsave(&sh4_pci_lock, flags); | 36 | raw_spin_lock_irqsave(&pci_config_lock, flags); |
38 | pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); | 37 | pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); |
39 | data = pci_read_reg(chan, SH4_PCIPDR); | 38 | data = pci_read_reg(chan, SH4_PCIPDR); |
40 | spin_unlock_irqrestore(&sh4_pci_lock, flags); | 39 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); |
41 | 40 | ||
42 | switch (size) { | 41 | switch (size) { |
43 | case 1: | 42 | case 1: |
@@ -69,10 +68,10 @@ static int sh4_pci_write(struct pci_bus *bus, unsigned int devfn, | |||
69 | int shift; | 68 | int shift; |
70 | u32 data; | 69 | u32 data; |
71 | 70 | ||
72 | spin_lock_irqsave(&sh4_pci_lock, flags); | 71 | raw_spin_lock_irqsave(&pci_config_lock, flags); |
73 | pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); | 72 | pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); |
74 | data = pci_read_reg(chan, SH4_PCIPDR); | 73 | data = pci_read_reg(chan, SH4_PCIPDR); |
75 | spin_unlock_irqrestore(&sh4_pci_lock, flags); | 74 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); |
76 | 75 | ||
77 | switch (size) { | 76 | switch (size) { |
78 | case 1: | 77 | case 1: |
diff --git a/arch/sh/drivers/pci/ops-sh7786.c b/arch/sh/drivers/pci/ops-sh7786.c index 48f594b9582b..128421009e3f 100644 --- a/arch/sh/drivers/pci/ops-sh7786.c +++ b/arch/sh/drivers/pci/ops-sh7786.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Generic SH7786 PCI-Express operations. | 2 | * Generic SH7786 PCI-Express operations. |
3 | * | 3 | * |
4 | * Copyright (C) 2009 Paul Mundt | 4 | * Copyright (C) 2009 - 2010 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 |
@@ -19,37 +19,72 @@ enum { | |||
19 | PCI_ACCESS_WRITE, | 19 | PCI_ACCESS_WRITE, |
20 | }; | 20 | }; |
21 | 21 | ||
22 | static DEFINE_SPINLOCK(sh7786_pcie_lock); | ||
23 | |||
24 | static int sh7786_pcie_config_access(unsigned char access_type, | 22 | static int sh7786_pcie_config_access(unsigned char access_type, |
25 | struct pci_bus *bus, unsigned int devfn, int where, u32 *data) | 23 | struct pci_bus *bus, unsigned int devfn, int where, u32 *data) |
26 | { | 24 | { |
27 | struct pci_channel *chan = bus->sysdata; | 25 | struct pci_channel *chan = bus->sysdata; |
28 | int dev, func; | 26 | int dev, func, type, reg; |
29 | 27 | ||
30 | dev = PCI_SLOT(devfn); | 28 | dev = PCI_SLOT(devfn); |
31 | func = PCI_FUNC(devfn); | 29 | func = PCI_FUNC(devfn); |
30 | type = !!bus->parent; | ||
31 | reg = where & ~3; | ||
32 | 32 | ||
33 | if (bus->number > 255 || dev > 31 || func > 7) | 33 | if (bus->number > 255 || dev > 31 || func > 7) |
34 | return PCIBIOS_FUNC_NOT_SUPPORTED; | 34 | return PCIBIOS_FUNC_NOT_SUPPORTED; |
35 | if (devfn) | 35 | |
36 | return PCIBIOS_DEVICE_NOT_FOUND; | 36 | /* |
37 | * While each channel has its own memory-mapped extended config | ||
38 | * space, it's generally only accessible when in endpoint mode. | ||
39 | * When in root complex mode, the controller is unable to target | ||
40 | * itself with either type 0 or type 1 accesses, and indeed, any | ||
41 | * controller initiated target transfer to its own config space | ||
42 | * result in a completer abort. | ||
43 | * | ||
44 | * Each channel effectively only supports a single device, but as | ||
45 | * the same channel <-> device access works for any PCI_SLOT() | ||
46 | * value, we cheat a bit here and bind the controller's config | ||
47 | * space to devfn 0 in order to enable self-enumeration. In this | ||
48 | * case the regular PAR/PDR path is sidelined and the mangled | ||
49 | * config access itself is initiated as a SuperHyway transaction. | ||
50 | */ | ||
51 | if (pci_is_root_bus(bus)) { | ||
52 | if (dev == 0) { | ||
53 | if (access_type == PCI_ACCESS_READ) | ||
54 | *data = pci_read_reg(chan, PCI_REG(reg)); | ||
55 | else | ||
56 | pci_write_reg(chan, *data, PCI_REG(reg)); | ||
57 | |||
58 | return PCIBIOS_SUCCESSFUL; | ||
59 | } else if (dev > 1) | ||
60 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
61 | } | ||
62 | |||
63 | /* Clear errors */ | ||
64 | pci_write_reg(chan, pci_read_reg(chan, SH4A_PCIEERRFR), SH4A_PCIEERRFR); | ||
37 | 65 | ||
38 | /* Set the PIO address */ | 66 | /* Set the PIO address */ |
39 | pci_write_reg(chan, (bus->number << 24) | (dev << 19) | | 67 | pci_write_reg(chan, (bus->number << 24) | (dev << 19) | |
40 | (func << 16) | (where & ~3), SH4A_PCIEPAR); | 68 | (func << 16) | reg, SH4A_PCIEPAR); |
41 | 69 | ||
42 | /* Enable the configuration access */ | 70 | /* Enable the configuration access */ |
43 | pci_write_reg(chan, (1 << 31), SH4A_PCIEPCTLR); | 71 | pci_write_reg(chan, (1 << 31) | (type << 8), SH4A_PCIEPCTLR); |
72 | |||
73 | /* Check for errors */ | ||
74 | if (pci_read_reg(chan, SH4A_PCIEERRFR) & 0x10) | ||
75 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
76 | |||
77 | /* Check for master and target aborts */ | ||
78 | if (pci_read_reg(chan, SH4A_PCIEPCICONF1) & ((1 << 29) | (1 << 28))) | ||
79 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
44 | 80 | ||
45 | if (access_type == PCI_ACCESS_READ) | 81 | if (access_type == PCI_ACCESS_READ) |
46 | *data = pci_read_reg(chan, SH4A_PCIEPDR); | 82 | *data = pci_read_reg(chan, SH4A_PCIEPDR); |
47 | else | 83 | else |
48 | pci_write_reg(chan, *data, SH4A_PCIEPDR); | 84 | pci_write_reg(chan, *data, SH4A_PCIEPDR); |
49 | 85 | ||
50 | /* Check for master and target aborts */ | 86 | /* Disable the configuration access */ |
51 | if (pci_read_reg(chan, SH4A_PCIEPCICONF1) & ((1 << 29) | (1 << 28))) | 87 | pci_write_reg(chan, 0, SH4A_PCIEPCTLR); |
52 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
53 | 88 | ||
54 | return PCIBIOS_SUCCESSFUL; | 89 | return PCIBIOS_SUCCESSFUL; |
55 | } | 90 | } |
@@ -66,11 +101,13 @@ static int sh7786_pcie_read(struct pci_bus *bus, unsigned int devfn, | |||
66 | else if ((size == 4) && (where & 3)) | 101 | else if ((size == 4) && (where & 3)) |
67 | return PCIBIOS_BAD_REGISTER_NUMBER; | 102 | return PCIBIOS_BAD_REGISTER_NUMBER; |
68 | 103 | ||
69 | spin_lock_irqsave(&sh7786_pcie_lock, flags); | 104 | raw_spin_lock_irqsave(&pci_config_lock, flags); |
70 | ret = sh7786_pcie_config_access(PCI_ACCESS_READ, bus, | 105 | ret = sh7786_pcie_config_access(PCI_ACCESS_READ, bus, |
71 | devfn, where, &data); | 106 | devfn, where, &data); |
72 | if (ret != PCIBIOS_SUCCESSFUL) | 107 | if (ret != PCIBIOS_SUCCESSFUL) { |
108 | *val = 0xffffffff; | ||
73 | goto out; | 109 | goto out; |
110 | } | ||
74 | 111 | ||
75 | if (size == 1) | 112 | if (size == 1) |
76 | *val = (data >> ((where & 3) << 3)) & 0xff; | 113 | *val = (data >> ((where & 3) << 3)) & 0xff; |
@@ -84,7 +121,7 @@ static int sh7786_pcie_read(struct pci_bus *bus, unsigned int devfn, | |||
84 | devfn, where, size, (unsigned long)*val); | 121 | devfn, where, size, (unsigned long)*val); |
85 | 122 | ||
86 | out: | 123 | out: |
87 | spin_unlock_irqrestore(&sh7786_pcie_lock, flags); | 124 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); |
88 | return ret; | 125 | return ret; |
89 | } | 126 | } |
90 | 127 | ||
@@ -100,7 +137,7 @@ static int sh7786_pcie_write(struct pci_bus *bus, unsigned int devfn, | |||
100 | else if ((size == 4) && (where & 3)) | 137 | else if ((size == 4) && (where & 3)) |
101 | return PCIBIOS_BAD_REGISTER_NUMBER; | 138 | return PCIBIOS_BAD_REGISTER_NUMBER; |
102 | 139 | ||
103 | spin_lock_irqsave(&sh7786_pcie_lock, flags); | 140 | raw_spin_lock_irqsave(&pci_config_lock, flags); |
104 | ret = sh7786_pcie_config_access(PCI_ACCESS_READ, bus, | 141 | ret = sh7786_pcie_config_access(PCI_ACCESS_READ, bus, |
105 | devfn, where, &data); | 142 | devfn, where, &data); |
106 | if (ret != PCIBIOS_SUCCESSFUL) | 143 | if (ret != PCIBIOS_SUCCESSFUL) |
@@ -124,7 +161,7 @@ static int sh7786_pcie_write(struct pci_bus *bus, unsigned int devfn, | |||
124 | ret = sh7786_pcie_config_access(PCI_ACCESS_WRITE, bus, | 161 | ret = sh7786_pcie_config_access(PCI_ACCESS_WRITE, bus, |
125 | devfn, where, &data); | 162 | devfn, where, &data); |
126 | out: | 163 | out: |
127 | spin_unlock_irqrestore(&sh7786_pcie_lock, flags); | 164 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); |
128 | return ret; | 165 | return ret; |
129 | } | 166 | } |
130 | 167 | ||
diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index f98141b3b7d7..86adb1e235cd 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c | |||
@@ -81,7 +81,7 @@ static int __init sh7751_pci_init(void) | |||
81 | unsigned int id; | 81 | unsigned int id; |
82 | u32 word, reg; | 82 | u32 word, reg; |
83 | 83 | ||
84 | printk(KERN_NOTICE "PCI: Starting intialization.\n"); | 84 | printk(KERN_NOTICE "PCI: Starting initialization.\n"); |
85 | 85 | ||
86 | chan->reg_base = 0xfe200000; | 86 | chan->reg_base = 0xfe200000; |
87 | 87 | ||
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index ffdcbf10b95e..edb7cca14882 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c | |||
@@ -246,7 +246,7 @@ static int __init sh7780_pci_init(void) | |||
246 | const char *type; | 246 | const char *type; |
247 | int ret, i; | 247 | int ret, i; |
248 | 248 | ||
249 | printk(KERN_NOTICE "PCI: Starting intialization.\n"); | 249 | printk(KERN_NOTICE "PCI: Starting initialization.\n"); |
250 | 250 | ||
251 | chan->reg_base = 0xfe040000; | 251 | chan->reg_base = 0xfe040000; |
252 | 252 | ||
diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h index 205dcbefe275..1742e2c9db7a 100644 --- a/arch/sh/drivers/pci/pci-sh7780.h +++ b/arch/sh/drivers/pci/pci-sh7780.h | |||
@@ -12,12 +12,6 @@ | |||
12 | #ifndef _PCI_SH7780_H_ | 12 | #ifndef _PCI_SH7780_H_ |
13 | #define _PCI_SH7780_H_ | 13 | #define _PCI_SH7780_H_ |
14 | 14 | ||
15 | #define PCI_VENDOR_ID_RENESAS 0x1912 | ||
16 | #define PCI_DEVICE_ID_RENESAS_SH7781 0x0001 | ||
17 | #define PCI_DEVICE_ID_RENESAS_SH7780 0x0002 | ||
18 | #define PCI_DEVICE_ID_RENESAS_SH7763 0x0004 | ||
19 | #define PCI_DEVICE_ID_RENESAS_SH7785 0x0007 | ||
20 | |||
21 | /* SH7780 Control Registers */ | 15 | /* SH7780 Control Registers */ |
22 | #define PCIECR 0xFE000008 | 16 | #define PCIECR 0xFE000008 |
23 | #define PCIECR_ENBL 0x01 | 17 | #define PCIECR_ENBL 0x01 |
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 1e9598d2bbf4..60ee09a4e121 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/dma-debug.h> | 19 | #include <linux/dma-debug.h> |
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
22 | #include <linux/spinlock.h> | ||
22 | 23 | ||
23 | unsigned long PCIBIOS_MIN_IO = 0x0000; | 24 | unsigned long PCIBIOS_MIN_IO = 0x0000; |
24 | unsigned long PCIBIOS_MIN_MEM = 0; | 25 | unsigned long PCIBIOS_MIN_MEM = 0; |
@@ -56,6 +57,11 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose) | |||
56 | } | 57 | } |
57 | } | 58 | } |
58 | 59 | ||
60 | /* | ||
61 | * This interrupt-safe spinlock protects all accesses to PCI | ||
62 | * configuration space. | ||
63 | */ | ||
64 | DEFINE_RAW_SPINLOCK(pci_config_lock); | ||
59 | static DEFINE_MUTEX(pci_scan_mutex); | 65 | static DEFINE_MUTEX(pci_scan_mutex); |
60 | 66 | ||
61 | int __devinit register_pci_controller(struct pci_channel *hose) | 67 | int __devinit register_pci_controller(struct pci_channel *hose) |
@@ -233,40 +239,7 @@ void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | |||
233 | 239 | ||
234 | int pcibios_enable_device(struct pci_dev *dev, int mask) | 240 | int pcibios_enable_device(struct pci_dev *dev, int mask) |
235 | { | 241 | { |
236 | u16 cmd, old_cmd; | 242 | return pci_enable_resources(dev, mask); |
237 | int idx; | ||
238 | struct resource *r; | ||
239 | |||
240 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
241 | old_cmd = cmd; | ||
242 | for (idx=0; idx < PCI_NUM_RESOURCES; idx++) { | ||
243 | /* Only set up the requested stuff */ | ||
244 | if (!(mask & (1<<idx))) | ||
245 | continue; | ||
246 | |||
247 | r = &dev->resource[idx]; | ||
248 | if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM))) | ||
249 | continue; | ||
250 | if ((idx == PCI_ROM_RESOURCE) && | ||
251 | (!(r->flags & IORESOURCE_ROM_ENABLE))) | ||
252 | continue; | ||
253 | if (!r->start && r->end) { | ||
254 | printk(KERN_ERR "PCI: Device %s not available " | ||
255 | "because of resource collisions\n", | ||
256 | pci_name(dev)); | ||
257 | return -EINVAL; | ||
258 | } | ||
259 | if (r->flags & IORESOURCE_IO) | ||
260 | cmd |= PCI_COMMAND_IO; | ||
261 | if (r->flags & IORESOURCE_MEM) | ||
262 | cmd |= PCI_COMMAND_MEMORY; | ||
263 | } | ||
264 | if (cmd != old_cmd) { | ||
265 | printk("PCI: Enabling device %s (%04x -> %04x)\n", | ||
266 | pci_name(dev), old_cmd, cmd); | ||
267 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
268 | } | ||
269 | return 0; | ||
270 | } | 243 | } |
271 | 244 | ||
272 | /* | 245 | /* |
@@ -295,7 +268,7 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq) | |||
295 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); | 268 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); |
296 | } | 269 | } |
297 | 270 | ||
298 | char * __devinit pcibios_setup(char *str) | 271 | char * __devinit __weak pcibios_setup(char *str) |
299 | { | 272 | { |
300 | return str; | 273 | return str; |
301 | } | 274 | } |
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index 68cb9b0ac9d2..96e9b058aa1d 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c | |||
@@ -13,11 +13,14 @@ | |||
13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/clk.h> | ||
17 | #include <linux/sh_clk.h> | ||
16 | #include "pcie-sh7786.h" | 18 | #include "pcie-sh7786.h" |
17 | #include <asm/sizes.h> | 19 | #include <asm/sizes.h> |
18 | 20 | ||
19 | struct sh7786_pcie_port { | 21 | struct sh7786_pcie_port { |
20 | struct pci_channel *hose; | 22 | struct pci_channel *hose; |
23 | struct clk *fclk, phy_clk; | ||
21 | unsigned int index; | 24 | unsigned int index; |
22 | int endpoint; | 25 | int endpoint; |
23 | int link; | 26 | int link; |
@@ -51,6 +54,7 @@ static struct resource sh7786_pci0_resources[] = { | |||
51 | .name = "PCIe0 MEM 2", | 54 | .name = "PCIe0 MEM 2", |
52 | .start = 0xfe100000, | 55 | .start = 0xfe100000, |
53 | .end = 0xfe100000 + SZ_1M - 1, | 56 | .end = 0xfe100000 + SZ_1M - 1, |
57 | .flags = IORESOURCE_MEM, | ||
54 | }, | 58 | }, |
55 | }; | 59 | }; |
56 | 60 | ||
@@ -74,6 +78,7 @@ static struct resource sh7786_pci1_resources[] = { | |||
74 | .name = "PCIe1 MEM 2", | 78 | .name = "PCIe1 MEM 2", |
75 | .start = 0xfe300000, | 79 | .start = 0xfe300000, |
76 | .end = 0xfe300000 + SZ_1M - 1, | 80 | .end = 0xfe300000 + SZ_1M - 1, |
81 | .flags = IORESOURCE_MEM, | ||
77 | }, | 82 | }, |
78 | }; | 83 | }; |
79 | 84 | ||
@@ -82,6 +87,7 @@ static struct resource sh7786_pci2_resources[] = { | |||
82 | .name = "PCIe2 IO", | 87 | .name = "PCIe2 IO", |
83 | .start = 0xfc800000, | 88 | .start = 0xfc800000, |
84 | .end = 0xfc800000 + SZ_4M - 1, | 89 | .end = 0xfc800000 + SZ_4M - 1, |
90 | .flags = IORESOURCE_IO, | ||
85 | }, { | 91 | }, { |
86 | .name = "PCIe2 MEM 0", | 92 | .name = "PCIe2 MEM 0", |
87 | .start = 0x80000000, | 93 | .start = 0x80000000, |
@@ -96,6 +102,7 @@ static struct resource sh7786_pci2_resources[] = { | |||
96 | .name = "PCIe2 MEM 2", | 102 | .name = "PCIe2 MEM 2", |
97 | .start = 0xfcd00000, | 103 | .start = 0xfcd00000, |
98 | .end = 0xfcd00000 + SZ_1M - 1, | 104 | .end = 0xfcd00000 + SZ_1M - 1, |
105 | .flags = IORESOURCE_MEM, | ||
99 | }, | 106 | }, |
100 | }; | 107 | }; |
101 | 108 | ||
@@ -117,7 +124,29 @@ static struct pci_channel sh7786_pci_channels[] = { | |||
117 | DEFINE_CONTROLLER(0xfcc00000, 2), | 124 | DEFINE_CONTROLLER(0xfcc00000, 2), |
118 | }; | 125 | }; |
119 | 126 | ||
120 | static int phy_wait_for_ack(struct pci_channel *chan) | 127 | static struct clk fixed_pciexclkp = { |
128 | .rate = 100000000, /* 100 MHz reference clock */ | ||
129 | }; | ||
130 | |||
131 | static void __devinit sh7786_pci_fixup(struct pci_dev *dev) | ||
132 | { | ||
133 | /* | ||
134 | * Prevent enumeration of root complex resources. | ||
135 | */ | ||
136 | if (pci_is_root_bus(dev->bus) && dev->devfn == 0) { | ||
137 | int i; | ||
138 | |||
139 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | ||
140 | dev->resource[i].start = 0; | ||
141 | dev->resource[i].end = 0; | ||
142 | dev->resource[i].flags = 0; | ||
143 | } | ||
144 | } | ||
145 | } | ||
146 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_SH7786, | ||
147 | sh7786_pci_fixup); | ||
148 | |||
149 | static int __init phy_wait_for_ack(struct pci_channel *chan) | ||
121 | { | 150 | { |
122 | unsigned int timeout = 100; | 151 | unsigned int timeout = 100; |
123 | 152 | ||
@@ -131,7 +160,7 @@ static int phy_wait_for_ack(struct pci_channel *chan) | |||
131 | return -ETIMEDOUT; | 160 | return -ETIMEDOUT; |
132 | } | 161 | } |
133 | 162 | ||
134 | static int pci_wait_for_irq(struct pci_channel *chan, unsigned int mask) | 163 | static int __init pci_wait_for_irq(struct pci_channel *chan, unsigned int mask) |
135 | { | 164 | { |
136 | unsigned int timeout = 100; | 165 | unsigned int timeout = 100; |
137 | 166 | ||
@@ -145,19 +174,14 @@ static int pci_wait_for_irq(struct pci_channel *chan, unsigned int mask) | |||
145 | return -ETIMEDOUT; | 174 | return -ETIMEDOUT; |
146 | } | 175 | } |
147 | 176 | ||
148 | static void phy_write_reg(struct pci_channel *chan, unsigned int addr, | 177 | static void __init phy_write_reg(struct pci_channel *chan, unsigned int addr, |
149 | unsigned int lane, unsigned int data) | 178 | unsigned int lane, unsigned int data) |
150 | { | 179 | { |
151 | unsigned long phyaddr, ctrl; | 180 | unsigned long phyaddr; |
152 | 181 | ||
153 | phyaddr = (1 << BITS_CMD) + ((lane & 0xf) << BITS_LANE) + | 182 | phyaddr = (1 << BITS_CMD) + ((lane & 0xf) << BITS_LANE) + |
154 | ((addr & 0xff) << BITS_ADR); | 183 | ((addr & 0xff) << BITS_ADR); |
155 | 184 | ||
156 | /* Enable clock */ | ||
157 | ctrl = pci_read_reg(chan, SH4A_PCIEPHYCTLR); | ||
158 | ctrl |= (1 << BITS_CKE); | ||
159 | pci_write_reg(chan, ctrl, SH4A_PCIEPHYCTLR); | ||
160 | |||
161 | /* Set write data */ | 185 | /* Set write data */ |
162 | pci_write_reg(chan, data, SH4A_PCIEPHYDOUTR); | 186 | pci_write_reg(chan, data, SH4A_PCIEPHYDOUTR); |
163 | pci_write_reg(chan, phyaddr, SH4A_PCIEPHYADRR); | 187 | pci_write_reg(chan, phyaddr, SH4A_PCIEPHYADRR); |
@@ -165,20 +189,74 @@ static void phy_write_reg(struct pci_channel *chan, unsigned int addr, | |||
165 | phy_wait_for_ack(chan); | 189 | phy_wait_for_ack(chan); |
166 | 190 | ||
167 | /* Clear command */ | 191 | /* Clear command */ |
192 | pci_write_reg(chan, 0, SH4A_PCIEPHYDOUTR); | ||
168 | pci_write_reg(chan, 0, SH4A_PCIEPHYADRR); | 193 | pci_write_reg(chan, 0, SH4A_PCIEPHYADRR); |
169 | 194 | ||
170 | phy_wait_for_ack(chan); | 195 | phy_wait_for_ack(chan); |
196 | } | ||
171 | 197 | ||
172 | /* Disable clock */ | 198 | static int __init pcie_clk_init(struct sh7786_pcie_port *port) |
173 | ctrl = pci_read_reg(chan, SH4A_PCIEPHYCTLR); | 199 | { |
174 | ctrl &= ~(1 << BITS_CKE); | 200 | struct pci_channel *chan = port->hose; |
175 | pci_write_reg(chan, ctrl, SH4A_PCIEPHYCTLR); | 201 | struct clk *clk; |
202 | char fclk_name[16]; | ||
203 | int ret; | ||
204 | |||
205 | /* | ||
206 | * First register the fixed clock | ||
207 | */ | ||
208 | ret = clk_register(&fixed_pciexclkp); | ||
209 | if (unlikely(ret != 0)) | ||
210 | return ret; | ||
211 | |||
212 | /* | ||
213 | * Grab the port's function clock, which the PHY clock depends | ||
214 | * on. clock lookups don't help us much at this point, since no | ||
215 | * dev_id is available this early. Lame. | ||
216 | */ | ||
217 | snprintf(fclk_name, sizeof(fclk_name), "pcie%d_fck", port->index); | ||
218 | |||
219 | port->fclk = clk_get(NULL, fclk_name); | ||
220 | if (IS_ERR(port->fclk)) { | ||
221 | ret = PTR_ERR(port->fclk); | ||
222 | goto err_fclk; | ||
223 | } | ||
224 | |||
225 | clk_enable(port->fclk); | ||
226 | |||
227 | /* | ||
228 | * And now, set up the PHY clock | ||
229 | */ | ||
230 | clk = &port->phy_clk; | ||
231 | |||
232 | memset(clk, 0, sizeof(struct clk)); | ||
233 | |||
234 | clk->parent = &fixed_pciexclkp; | ||
235 | clk->enable_reg = (void __iomem *)(chan->reg_base + SH4A_PCIEPHYCTLR); | ||
236 | clk->enable_bit = BITS_CKE; | ||
237 | |||
238 | ret = sh_clk_mstp32_register(clk, 1); | ||
239 | if (unlikely(ret < 0)) | ||
240 | goto err_phy; | ||
241 | |||
242 | return 0; | ||
243 | |||
244 | err_phy: | ||
245 | clk_disable(port->fclk); | ||
246 | clk_put(port->fclk); | ||
247 | err_fclk: | ||
248 | clk_unregister(&fixed_pciexclkp); | ||
249 | |||
250 | return ret; | ||
176 | } | 251 | } |
177 | 252 | ||
178 | static int phy_init(struct pci_channel *chan) | 253 | static int __init phy_init(struct sh7786_pcie_port *port) |
179 | { | 254 | { |
255 | struct pci_channel *chan = port->hose; | ||
180 | unsigned int timeout = 100; | 256 | unsigned int timeout = 100; |
181 | 257 | ||
258 | clk_enable(&port->phy_clk); | ||
259 | |||
182 | /* Initialize the phy */ | 260 | /* Initialize the phy */ |
183 | phy_write_reg(chan, 0x60, 0xf, 0x004b008b); | 261 | phy_write_reg(chan, 0x60, 0xf, 0x004b008b); |
184 | phy_write_reg(chan, 0x61, 0xf, 0x00007b41); | 262 | phy_write_reg(chan, 0x61, 0xf, 0x00007b41); |
@@ -187,9 +265,13 @@ static int phy_init(struct pci_channel *chan) | |||
187 | phy_write_reg(chan, 0x66, 0xf, 0x00000010); | 265 | phy_write_reg(chan, 0x66, 0xf, 0x00000010); |
188 | phy_write_reg(chan, 0x74, 0xf, 0x0007001c); | 266 | phy_write_reg(chan, 0x74, 0xf, 0x0007001c); |
189 | phy_write_reg(chan, 0x79, 0xf, 0x01fc000d); | 267 | phy_write_reg(chan, 0x79, 0xf, 0x01fc000d); |
268 | phy_write_reg(chan, 0xb0, 0xf, 0x00000610); | ||
190 | 269 | ||
191 | /* Deassert Standby */ | 270 | /* Deassert Standby */ |
192 | phy_write_reg(chan, 0x67, 0xf, 0x00000400); | 271 | phy_write_reg(chan, 0x67, 0x1, 0x00000400); |
272 | |||
273 | /* Disable clock */ | ||
274 | clk_disable(&port->phy_clk); | ||
193 | 275 | ||
194 | while (timeout--) { | 276 | while (timeout--) { |
195 | if (pci_read_reg(chan, SH4A_PCIEPHYSR)) | 277 | if (pci_read_reg(chan, SH4A_PCIEPHYSR)) |
@@ -201,22 +283,33 @@ static int phy_init(struct pci_channel *chan) | |||
201 | return -ETIMEDOUT; | 283 | return -ETIMEDOUT; |
202 | } | 284 | } |
203 | 285 | ||
204 | static int pcie_init(struct sh7786_pcie_port *port) | 286 | static void __init pcie_reset(struct sh7786_pcie_port *port) |
287 | { | ||
288 | struct pci_channel *chan = port->hose; | ||
289 | |||
290 | pci_write_reg(chan, 1, SH4A_PCIESRSTR); | ||
291 | pci_write_reg(chan, 0, SH4A_PCIETCTLR); | ||
292 | pci_write_reg(chan, 0, SH4A_PCIESRSTR); | ||
293 | pci_write_reg(chan, 0, SH4A_PCIETXVC0SR); | ||
294 | } | ||
295 | |||
296 | static int __init pcie_init(struct sh7786_pcie_port *port) | ||
205 | { | 297 | { |
206 | struct pci_channel *chan = port->hose; | 298 | struct pci_channel *chan = port->hose; |
207 | unsigned int data; | 299 | unsigned int data; |
208 | phys_addr_t memphys; | 300 | phys_addr_t memphys; |
209 | size_t memsize; | 301 | size_t memsize; |
210 | int ret, i; | 302 | int ret, i, win; |
211 | 303 | ||
212 | /* Begin initialization */ | 304 | /* Begin initialization */ |
213 | pci_write_reg(chan, 0, SH4A_PCIETCTLR); | 305 | pcie_reset(port); |
214 | 306 | ||
215 | /* Initialize as type1. */ | 307 | /* |
216 | data = pci_read_reg(chan, SH4A_PCIEPCICONF3); | 308 | * Initial header for port config space is type 1, set the device |
217 | data &= ~(0x7f << 16); | 309 | * class to match. Hardware takes care of propagating the IDSETR |
218 | data |= PCI_HEADER_TYPE_BRIDGE << 16; | 310 | * settings, so there is no need to bother with a quirk. |
219 | pci_write_reg(chan, data, SH4A_PCIEPCICONF3); | 311 | */ |
312 | pci_write_reg(chan, PCI_CLASS_BRIDGE_PCI << 16, SH4A_PCIEIDSETR1); | ||
220 | 313 | ||
221 | /* Initialize default capabilities. */ | 314 | /* Initialize default capabilities. */ |
222 | data = pci_read_reg(chan, SH4A_PCIEEXPCAP0); | 315 | data = pci_read_reg(chan, SH4A_PCIEEXPCAP0); |
@@ -268,30 +361,33 @@ static int pcie_init(struct sh7786_pcie_port *port) | |||
268 | * LAR1/LAMR1. | 361 | * LAR1/LAMR1. |
269 | */ | 362 | */ |
270 | if (memsize > SZ_512M) { | 363 | if (memsize > SZ_512M) { |
271 | __raw_writel(memphys + SZ_512M, chan->reg_base + SH4A_PCIELAR1); | 364 | pci_write_reg(chan, memphys + SZ_512M, SH4A_PCIELAR1); |
272 | __raw_writel(((memsize - SZ_512M) - SZ_256) | 1, | 365 | pci_write_reg(chan, ((memsize - SZ_512M) - SZ_256) | 1, |
273 | chan->reg_base + SH4A_PCIELAMR1); | 366 | SH4A_PCIELAMR1); |
274 | memsize = SZ_512M; | 367 | memsize = SZ_512M; |
275 | } else { | 368 | } else { |
276 | /* | 369 | /* |
277 | * Otherwise just zero it out and disable it. | 370 | * Otherwise just zero it out and disable it. |
278 | */ | 371 | */ |
279 | __raw_writel(0, chan->reg_base + SH4A_PCIELAR1); | 372 | pci_write_reg(chan, 0, SH4A_PCIELAR1); |
280 | __raw_writel(0, chan->reg_base + SH4A_PCIELAMR1); | 373 | pci_write_reg(chan, 0, SH4A_PCIELAMR1); |
281 | } | 374 | } |
282 | 375 | ||
283 | /* | 376 | /* |
284 | * LAR0/LAMR0 covers up to the first 512MB, which is enough to | 377 | * LAR0/LAMR0 covers up to the first 512MB, which is enough to |
285 | * cover all of lowmem on most platforms. | 378 | * cover all of lowmem on most platforms. |
286 | */ | 379 | */ |
287 | __raw_writel(memphys, chan->reg_base + SH4A_PCIELAR0); | 380 | pci_write_reg(chan, memphys, SH4A_PCIELAR0); |
288 | __raw_writel((memsize - SZ_256) | 1, chan->reg_base + SH4A_PCIELAMR0); | 381 | pci_write_reg(chan, (memsize - SZ_256) | 1, SH4A_PCIELAMR0); |
289 | 382 | ||
290 | /* Finish initialization */ | 383 | /* Finish initialization */ |
291 | data = pci_read_reg(chan, SH4A_PCIETCTLR); | 384 | data = pci_read_reg(chan, SH4A_PCIETCTLR); |
292 | data |= 0x1; | 385 | data |= 0x1; |
293 | pci_write_reg(chan, data, SH4A_PCIETCTLR); | 386 | pci_write_reg(chan, data, SH4A_PCIETCTLR); |
294 | 387 | ||
388 | /* Let things settle down a bit.. */ | ||
389 | mdelay(100); | ||
390 | |||
295 | /* Enable DL_Active Interrupt generation */ | 391 | /* Enable DL_Active Interrupt generation */ |
296 | data = pci_read_reg(chan, SH4A_PCIEDLINTENR); | 392 | data = pci_read_reg(chan, SH4A_PCIEDLINTENR); |
297 | data |= PCIEDLINTENR_DLL_ACT_ENABLE; | 393 | data |= PCIEDLINTENR_DLL_ACT_ENABLE; |
@@ -302,9 +398,12 @@ static int pcie_init(struct sh7786_pcie_port *port) | |||
302 | data |= PCIEMACCTLR_SCR_DIS | (0xff << 16); | 398 | data |= PCIEMACCTLR_SCR_DIS | (0xff << 16); |
303 | pci_write_reg(chan, data, SH4A_PCIEMACCTLR); | 399 | pci_write_reg(chan, data, SH4A_PCIEMACCTLR); |
304 | 400 | ||
401 | /* | ||
402 | * This will timeout if we don't have a link, but we permit the | ||
403 | * port to register anyways in order to support hotplug on future | ||
404 | * hardware. | ||
405 | */ | ||
305 | ret = pci_wait_for_irq(chan, MASK_INT_TX_CTRL); | 406 | ret = pci_wait_for_irq(chan, MASK_INT_TX_CTRL); |
306 | if (unlikely(ret != 0)) | ||
307 | return -ENODEV; | ||
308 | 407 | ||
309 | data = pci_read_reg(chan, SH4A_PCIEPCICONF1); | 408 | data = pci_read_reg(chan, SH4A_PCIEPCICONF1); |
310 | data &= ~(PCI_STATUS_DEVSEL_MASK << 16); | 409 | data &= ~(PCI_STATUS_DEVSEL_MASK << 16); |
@@ -317,35 +416,48 @@ static int pcie_init(struct sh7786_pcie_port *port) | |||
317 | 416 | ||
318 | wmb(); | 417 | wmb(); |
319 | 418 | ||
320 | data = pci_read_reg(chan, SH4A_PCIEMACSR); | 419 | if (ret == 0) { |
321 | printk(KERN_NOTICE "PCI: PCIe#%d link width %d\n", | 420 | data = pci_read_reg(chan, SH4A_PCIEMACSR); |
322 | port->index, (data >> 20) & 0x3f); | 421 | printk(KERN_NOTICE "PCI: PCIe#%d x%d link detected\n", |
323 | 422 | port->index, (data >> 20) & 0x3f); | |
423 | } else | ||
424 | printk(KERN_NOTICE "PCI: PCIe#%d link down\n", | ||
425 | port->index); | ||
324 | 426 | ||
325 | for (i = 0; i < chan->nr_resources; i++) { | 427 | for (i = win = 0; i < chan->nr_resources; i++) { |
326 | struct resource *res = chan->resources + i; | 428 | struct resource *res = chan->resources + i; |
327 | resource_size_t size; | 429 | resource_size_t size; |
328 | u32 enable_mask; | 430 | u32 mask; |
329 | 431 | ||
330 | pci_write_reg(chan, 0x00000000, SH4A_PCIEPTCTLR(i)); | 432 | /* |
433 | * We can't use the 32-bit mode windows in legacy 29-bit | ||
434 | * mode, so just skip them entirely. | ||
435 | */ | ||
436 | if ((res->flags & IORESOURCE_MEM_32BIT) && __in_29bit_mode()) | ||
437 | continue; | ||
331 | 438 | ||
332 | size = resource_size(res); | 439 | pci_write_reg(chan, 0x00000000, SH4A_PCIEPTCTLR(win)); |
333 | 440 | ||
334 | /* | 441 | /* |
335 | * The PAMR mask is calculated in units of 256kB, which | 442 | * The PAMR mask is calculated in units of 256kB, which |
336 | * keeps things pretty simple. | 443 | * keeps things pretty simple. |
337 | */ | 444 | */ |
338 | __raw_writel(((roundup_pow_of_two(size) / SZ_256K) - 1) << 18, | 445 | size = resource_size(res); |
339 | chan->reg_base + SH4A_PCIEPAMR(i)); | 446 | mask = (roundup_pow_of_two(size) / SZ_256K) - 1; |
447 | pci_write_reg(chan, mask << 18, SH4A_PCIEPAMR(win)); | ||
340 | 448 | ||
341 | pci_write_reg(chan, 0x00000000, SH4A_PCIEPARH(i)); | 449 | pci_write_reg(chan, upper_32_bits(res->start), |
342 | pci_write_reg(chan, 0x00000000, SH4A_PCIEPARL(i)); | 450 | SH4A_PCIEPARH(win)); |
451 | pci_write_reg(chan, lower_32_bits(res->start), | ||
452 | SH4A_PCIEPARL(win)); | ||
343 | 453 | ||
344 | enable_mask = MASK_PARE; | 454 | mask = MASK_PARE; |
345 | if (res->flags & IORESOURCE_IO) | 455 | if (res->flags & IORESOURCE_IO) |
346 | enable_mask |= MASK_SPC; | 456 | mask |= MASK_SPC; |
457 | |||
458 | pci_write_reg(chan, mask, SH4A_PCIEPTCTLR(win)); | ||
347 | 459 | ||
348 | pci_write_reg(chan, enable_mask, SH4A_PCIEPTCTLR(i)); | 460 | win++; |
349 | } | 461 | } |
350 | 462 | ||
351 | return 0; | 463 | return 0; |
@@ -356,26 +468,33 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) | |||
356 | return 71; | 468 | return 71; |
357 | } | 469 | } |
358 | 470 | ||
359 | static int sh7786_pcie_core_init(void) | 471 | static int __init sh7786_pcie_core_init(void) |
360 | { | 472 | { |
361 | /* Return the number of ports */ | 473 | /* Return the number of ports */ |
362 | return test_mode_pin(MODE_PIN12) ? 3 : 2; | 474 | return test_mode_pin(MODE_PIN12) ? 3 : 2; |
363 | } | 475 | } |
364 | 476 | ||
365 | static int __devinit sh7786_pcie_init_hw(struct sh7786_pcie_port *port) | 477 | static int __init sh7786_pcie_init_hw(struct sh7786_pcie_port *port) |
366 | { | 478 | { |
367 | int ret; | 479 | int ret; |
368 | 480 | ||
369 | ret = phy_init(port->hose); | ||
370 | if (unlikely(ret < 0)) | ||
371 | return ret; | ||
372 | |||
373 | /* | 481 | /* |
374 | * Check if we are configured in endpoint or root complex mode, | 482 | * Check if we are configured in endpoint or root complex mode, |
375 | * this is a fixed pin setting that applies to all PCIe ports. | 483 | * this is a fixed pin setting that applies to all PCIe ports. |
376 | */ | 484 | */ |
377 | port->endpoint = test_mode_pin(MODE_PIN11); | 485 | port->endpoint = test_mode_pin(MODE_PIN11); |
378 | 486 | ||
487 | /* | ||
488 | * Setup clocks, needed both for PHY and PCIe registers. | ||
489 | */ | ||
490 | ret = pcie_clk_init(port); | ||
491 | if (unlikely(ret < 0)) | ||
492 | return ret; | ||
493 | |||
494 | ret = phy_init(port); | ||
495 | if (unlikely(ret < 0)) | ||
496 | return ret; | ||
497 | |||
379 | ret = pcie_init(port); | 498 | ret = pcie_init(port); |
380 | if (unlikely(ret < 0)) | 499 | if (unlikely(ret < 0)) |
381 | return ret; | 500 | return ret; |
@@ -390,9 +509,10 @@ static struct sh7786_pcie_hwops sh7786_65nm_pcie_hwops __initdata = { | |||
390 | 509 | ||
391 | static int __init sh7786_pcie_init(void) | 510 | static int __init sh7786_pcie_init(void) |
392 | { | 511 | { |
512 | struct clk *platclk; | ||
393 | int ret = 0, i; | 513 | int ret = 0, i; |
394 | 514 | ||
395 | printk(KERN_NOTICE "PCI: Starting intialization.\n"); | 515 | printk(KERN_NOTICE "PCI: Starting initialization.\n"); |
396 | 516 | ||
397 | sh7786_pcie_hwops = &sh7786_65nm_pcie_hwops; | 517 | sh7786_pcie_hwops = &sh7786_65nm_pcie_hwops; |
398 | 518 | ||
@@ -407,6 +527,22 @@ static int __init sh7786_pcie_init(void) | |||
407 | if (unlikely(!sh7786_pcie_ports)) | 527 | if (unlikely(!sh7786_pcie_ports)) |
408 | return -ENOMEM; | 528 | return -ENOMEM; |
409 | 529 | ||
530 | /* | ||
531 | * Fetch any optional platform clock associated with this block. | ||
532 | * | ||
533 | * This is a rather nasty hack for boards with spec-mocking FPGAs | ||
534 | * that have a secondary set of clocks outside of the on-chip | ||
535 | * ones that need to be accounted for before there is any chance | ||
536 | * of touching the existing MSTP bits or CPG clocks. | ||
537 | */ | ||
538 | platclk = clk_get(NULL, "pcie_plat_clk"); | ||
539 | if (IS_ERR(platclk)) { | ||
540 | /* Sane hardware should probably get a WARN_ON.. */ | ||
541 | platclk = NULL; | ||
542 | } | ||
543 | |||
544 | clk_enable(platclk); | ||
545 | |||
410 | printk(KERN_NOTICE "PCI: probing %d ports.\n", nr_ports); | 546 | printk(KERN_NOTICE "PCI: probing %d ports.\n", nr_ports); |
411 | 547 | ||
412 | for (i = 0; i < nr_ports; i++) { | 548 | for (i = 0; i < nr_ports; i++) { |
@@ -419,8 +555,11 @@ static int __init sh7786_pcie_init(void) | |||
419 | ret |= sh7786_pcie_hwops->port_init_hw(port); | 555 | ret |= sh7786_pcie_hwops->port_init_hw(port); |
420 | } | 556 | } |
421 | 557 | ||
422 | if (unlikely(ret)) | 558 | if (unlikely(ret)) { |
559 | clk_disable(platclk); | ||
560 | clk_put(platclk); | ||
423 | return ret; | 561 | return ret; |
562 | } | ||
424 | 563 | ||
425 | return 0; | 564 | return 0; |
426 | } | 565 | } |
diff --git a/arch/sh/drivers/pci/pcie-sh7786.h b/arch/sh/drivers/pci/pcie-sh7786.h index 90a6992576b0..1ee054e47eae 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.h +++ b/arch/sh/drivers/pci/pcie-sh7786.h | |||
@@ -55,8 +55,11 @@ | |||
55 | #define BITS_ERRRCV (0) /* 0 ERRRCV 0 */ | 55 | #define BITS_ERRRCV (0) /* 0 ERRRCV 0 */ |
56 | #define MASK_ERRRCV (1<<BITS_ERRRCV) | 56 | #define MASK_ERRRCV (1<<BITS_ERRRCV) |
57 | 57 | ||
58 | /* PCIEENBLR */ | ||
59 | #define SH4A_PCIEENBLR (0x000008) /* R/W - 0x0000 0001 32 */ | ||
60 | |||
58 | /* PCIEECR */ | 61 | /* PCIEECR */ |
59 | #define SH4A_PCIEECR (0x000008) /* R/W - 0x0000 0000 32 */ | 62 | #define SH4A_PCIEECR (0x00000C) /* R/W - 0x0000 0000 32 */ |
60 | #define BITS_ENBL (0) /* 0 ENBL 0 R/W */ | 63 | #define BITS_ENBL (0) /* 0 ENBL 0 R/W */ |
61 | #define MASK_ENBL (1<<BITS_ENBL) | 64 | #define MASK_ENBL (1<<BITS_ENBL) |
62 | 65 | ||
@@ -113,6 +116,27 @@ | |||
113 | #define BITS_MDATA (0) | 116 | #define BITS_MDATA (0) |
114 | #define MASK_MDATA (0xffffffff<<BITS_MDATA) | 117 | #define MASK_MDATA (0xffffffff<<BITS_MDATA) |
115 | 118 | ||
119 | /* PCIEUNLOCKCR */ | ||
120 | #define SH4A_PCIEUNLOCKCR (0x000048) /* R/W - 0x0000 0000 32 */ | ||
121 | |||
122 | /* PCIEIDR */ | ||
123 | #define SH4A_PCIEIDR (0x000060) /* R/W - 0x0101 1101 32 */ | ||
124 | |||
125 | /* PCIEDBGCTLR */ | ||
126 | #define SH4A_PCIEDBGCTLR (0x000100) /* R/W - 0x0000 0000 32 */ | ||
127 | |||
128 | /* PCIEINTXR */ | ||
129 | #define SH4A_PCIEINTXR (0x004000) /* R/W - 0x0000 0000 32 */ | ||
130 | |||
131 | /* PCIERMSGR */ | ||
132 | #define SH4A_PCIERMSGR (0x004010) /* R/W - 0x0000 0000 32 */ | ||
133 | |||
134 | /* PCIERSTR */ | ||
135 | #define SH4A_PCIERSTR(x) (0x008000 + ((x) * 0x4)) /* R/W - 0x0000 0000 32 */ | ||
136 | |||
137 | /* PCIESRSTR */ | ||
138 | #define SH4A_PCIESRSTR (0x008040) /* R/W - 0x0000 0000 32 */ | ||
139 | |||
116 | /* PCIEPHYCTLR */ | 140 | /* PCIEPHYCTLR */ |
117 | #define SH4A_PCIEPHYCTLR (0x010000) /* R/W - 0x0000 0000 32 */ | 141 | #define SH4A_PCIEPHYCTLR (0x010000) /* R/W - 0x0000 0000 32 */ |
118 | #define BITS_CKE (0) | 142 | #define BITS_CKE (0) |
@@ -121,6 +145,9 @@ | |||
121 | /* PCIERMSGIER */ | 145 | /* PCIERMSGIER */ |
122 | #define SH4A_PCIERMSGIER (0x004040) /* R/W - 0x0000 0000 32 */ | 146 | #define SH4A_PCIERMSGIER (0x004040) /* R/W - 0x0000 0000 32 */ |
123 | 147 | ||
148 | /* PCIEPHYCTLR */ | ||
149 | #define SH4A_PCIEPHYCTLR (0x010000) /* R/W - 0x0000 0000 32 */ | ||
150 | |||
124 | /* PCIEPHYADRR */ | 151 | /* PCIEPHYADRR */ |
125 | #define SH4A_PCIEPHYADRR (0x010004) /* R/W - 0x0000 0000 32 */ | 152 | #define SH4A_PCIEPHYADRR (0x010004) /* R/W - 0x0000 0000 32 */ |
126 | #define BITS_ACK (24) // Rev1.171 | 153 | #define BITS_ACK (24) // Rev1.171 |
@@ -152,7 +179,7 @@ | |||
152 | #define MASK_CFINT (1<<BITS_CFINT) | 179 | #define MASK_CFINT (1<<BITS_CFINT) |
153 | 180 | ||
154 | /* PCIETSTR */ | 181 | /* PCIETSTR */ |
155 | #define SH4A_PCIETSTR (0x020004) /* R/W R/W 0x0000 0000 32 */ | 182 | #define SH4A_PCIETSTR (0x020004) /* R 0x0000 0000 32 */ |
156 | 183 | ||
157 | /* PCIEINTR */ | 184 | /* PCIEINTR */ |
158 | #define SH4A_PCIEINTR (0x020008) /* R/W R/W 0x0000 0000 32 */ | 185 | #define SH4A_PCIEINTR (0x020008) /* R/W R/W 0x0000 0000 32 */ |
@@ -236,6 +263,9 @@ | |||
236 | #define BITS_INTPM (8) | 263 | #define BITS_INTPM (8) |
237 | #define MASK_INTPM (1<<BITS_INTPM) | 264 | #define MASK_INTPM (1<<BITS_INTPM) |
238 | 265 | ||
266 | /* PCIEEH0R */ | ||
267 | #define SH4A_PCIEEHR(x) (0x020010 + ((x) * 0x4)) /* R - 0x0000 0000 32 */ | ||
268 | |||
239 | /* PCIEAIR */ | 269 | /* PCIEAIR */ |
240 | #define SH4A_PCIEAIR (SH4A_PCIE_BASE + 0x020010) /* R/W R/W 0xxxxx xxxx 32 */ | 270 | #define SH4A_PCIEAIR (SH4A_PCIE_BASE + 0x020010) /* R/W R/W 0xxxxx xxxx 32 */ |
241 | 271 | ||
@@ -244,6 +274,25 @@ | |||
244 | 274 | ||
245 | /* PCIEERRFR */ // Rev1.18 | 275 | /* PCIEERRFR */ // Rev1.18 |
246 | #define SH4A_PCIEERRFR (0x020020) /* R/W R/W 0xxxxx xxxx 32 */ // Rev1.18 | 276 | #define SH4A_PCIEERRFR (0x020020) /* R/W R/W 0xxxxx xxxx 32 */ // Rev1.18 |
277 | |||
278 | /* PCIEERRFER */ | ||
279 | #define SH4A_PCIEERRFER (0x020024) /* R/W R/W 0x0000 0000 32 */ | ||
280 | |||
281 | /* PCIEERRFR2 */ | ||
282 | #define SH4A_PCIEERRFR2 (0x020028) /* R/W R/W 0x0000 0000 32 */ | ||
283 | |||
284 | /* PCIEMSIR */ | ||
285 | #define SH4A_PCIEMSIR (0x020040) /* R/W - 0x0000 0000 32 */ | ||
286 | |||
287 | /* PCIEMSIFR */ | ||
288 | #define SH4A_PCIEMSIFR (0x020044) /* R/W R/W 0x0000 0000 32 */ | ||
289 | |||
290 | /* PCIEPWRCTLR */ | ||
291 | #define SH4A_PCIEPWRCTLR (0x020100) /* R/W - 0x0000 0000 32 */ | ||
292 | |||
293 | /* PCIEPCCTLR */ | ||
294 | #define SH4A_PCIEPCCTLR (0x020180) /* R/W - 0x0000 0000 32 */ | ||
295 | |||
247 | // Rev1.18 | 296 | // Rev1.18 |
248 | /* PCIELAR0 */ | 297 | /* PCIELAR0 */ |
249 | #define SH4A_PCIELAR0 (0x020200) /* R/W R/W 0x0000 0000 32 */ | 298 | #define SH4A_PCIELAR0 (0x020200) /* R/W R/W 0x0000 0000 32 */ |
@@ -352,6 +401,7 @@ | |||
352 | #define SH4A_PCIEDMCCR0 (0x021120) /* R/W R/W 0x0000 0000 32 */ | 401 | #define SH4A_PCIEDMCCR0 (0x021120) /* R/W R/W 0x0000 0000 32 */ |
353 | #define SH4A_PCIEDMCC2R0 (0x021124) /* R/W R/W 0x0000 0000 - */ | 402 | #define SH4A_PCIEDMCC2R0 (0x021124) /* R/W R/W 0x0000 0000 - */ |
354 | #define SH4A_PCIEDMCCCR0 (0x021128) /* R/W R/W 0x0000 0000 32 */ | 403 | #define SH4A_PCIEDMCCCR0 (0x021128) /* R/W R/W 0x0000 0000 32 */ |
404 | #define SH4A_PCIEDMCHSR0 (0x02112C) /* R/W - 0x0000 0000 32 */ | ||
355 | #define SH4A_PCIEDMSAR1 (0x021140) /* R/W R/W 0x0000 0000 32 */ | 405 | #define SH4A_PCIEDMSAR1 (0x021140) /* R/W R/W 0x0000 0000 32 */ |
356 | #define SH4A_PCIEDMSAHR1 (0x021144) /* R/W R/W 0x0000 0000 32 */ | 406 | #define SH4A_PCIEDMSAHR1 (0x021144) /* R/W R/W 0x0000 0000 32 */ |
357 | #define SH4A_PCIEDMDAR1 (0x021148) /* R/W R/W 0x0000 0000 32 */ | 407 | #define SH4A_PCIEDMDAR1 (0x021148) /* R/W R/W 0x0000 0000 32 */ |
@@ -363,6 +413,7 @@ | |||
363 | #define SH4A_PCIEDMCCR1 (0x021160) /* R/W R/W 0x0000 0000 32 */ | 413 | #define SH4A_PCIEDMCCR1 (0x021160) /* R/W R/W 0x0000 0000 32 */ |
364 | #define SH4A_PCIEDMCC2R1 (0x021164) /* R/W R/W 0x0000 0000 - */ | 414 | #define SH4A_PCIEDMCC2R1 (0x021164) /* R/W R/W 0x0000 0000 - */ |
365 | #define SH4A_PCIEDMCCCR1 (0x021168) /* R/W R/W 0x0000 0000 32 */ | 415 | #define SH4A_PCIEDMCCCR1 (0x021168) /* R/W R/W 0x0000 0000 32 */ |
416 | #define SH4A_PCIEDMCHSR1 (0x02116C) /* R/W - 0x0000 0000 32 */ | ||
366 | #define SH4A_PCIEDMSAR2 (0x021180) /* R/W R/W 0x0000 0000 32 */ | 417 | #define SH4A_PCIEDMSAR2 (0x021180) /* R/W R/W 0x0000 0000 32 */ |
367 | #define SH4A_PCIEDMSAHR2 (0x021184) /* R/W R/W 0x0000 0000 32 */ | 418 | #define SH4A_PCIEDMSAHR2 (0x021184) /* R/W R/W 0x0000 0000 32 */ |
368 | #define SH4A_PCIEDMDAR2 (0x021188) /* R/W R/W 0x0000 0000 32 */ | 419 | #define SH4A_PCIEDMDAR2 (0x021188) /* R/W R/W 0x0000 0000 32 */ |
@@ -385,6 +436,7 @@ | |||
385 | #define SH4A_PCIEDMCCR3 (0x0211E0) /* R/W R/W 0x0000 0000 32 */ | 436 | #define SH4A_PCIEDMCCR3 (0x0211E0) /* R/W R/W 0x0000 0000 32 */ |
386 | #define SH4A_PCIEDMCC2R3 (0x0211E4) /* R/W R/W 0x0000 0000 - */ | 437 | #define SH4A_PCIEDMCC2R3 (0x0211E4) /* R/W R/W 0x0000 0000 - */ |
387 | #define SH4A_PCIEDMCCCR3 (0x0211E8) /* R/W R/W 0x0000 0000 32 */ | 438 | #define SH4A_PCIEDMCCCR3 (0x0211E8) /* R/W R/W 0x0000 0000 32 */ |
439 | #define SH4A_PCIEDMCHSR3 (0x0211EC) /* R/W R/W 0x0000 0000 32 */ | ||
388 | #define SH4A_PCIEPCICONF0 (0x040000) /* R R - 8/16/32 */ | 440 | #define SH4A_PCIEPCICONF0 (0x040000) /* R R - 8/16/32 */ |
389 | #define SH4A_PCIEPCICONF1 (0x040004) /* R/W R/W 0x0008 0000 8/16/32 */ | 441 | #define SH4A_PCIEPCICONF1 (0x040004) /* R/W R/W 0x0008 0000 8/16/32 */ |
390 | #define SH4A_PCIEPCICONF2 (0x040008) /* R/W R/W 0xFF00 0000 8/16/32 */ | 442 | #define SH4A_PCIEPCICONF2 (0x040008) /* R/W R/W 0xFF00 0000 8/16/32 */ |