diff options
Diffstat (limited to 'drivers/pci/host/pci-xgene.c')
-rw-r--r-- | drivers/pci/host/pci-xgene.c | 156 |
1 files changed, 12 insertions, 144 deletions
diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c index b1d0596457c5..aab55474dd0d 100644 --- a/drivers/pci/host/pci-xgene.c +++ b/drivers/pci/host/pci-xgene.c | |||
@@ -16,7 +16,7 @@ | |||
16 | * GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
17 | * | 17 | * |
18 | */ | 18 | */ |
19 | #include <linux/clk-private.h> | 19 | #include <linux/clk.h> |
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/jiffies.h> | 22 | #include <linux/jiffies.h> |
@@ -74,92 +74,6 @@ static inline u32 pcie_bar_low_val(u32 addr, u32 flags) | |||
74 | return (addr & PCI_BASE_ADDRESS_MEM_MASK) | flags; | 74 | return (addr & PCI_BASE_ADDRESS_MEM_MASK) | flags; |
75 | } | 75 | } |
76 | 76 | ||
77 | /* PCIe Configuration Out/In */ | ||
78 | static inline void xgene_pcie_cfg_out32(void __iomem *addr, int offset, u32 val) | ||
79 | { | ||
80 | writel(val, addr + offset); | ||
81 | } | ||
82 | |||
83 | static inline void xgene_pcie_cfg_out16(void __iomem *addr, int offset, u16 val) | ||
84 | { | ||
85 | u32 val32 = readl(addr + (offset & ~0x3)); | ||
86 | |||
87 | switch (offset & 0x3) { | ||
88 | case 2: | ||
89 | val32 &= ~0xFFFF0000; | ||
90 | val32 |= (u32)val << 16; | ||
91 | break; | ||
92 | case 0: | ||
93 | default: | ||
94 | val32 &= ~0xFFFF; | ||
95 | val32 |= val; | ||
96 | break; | ||
97 | } | ||
98 | writel(val32, addr + (offset & ~0x3)); | ||
99 | } | ||
100 | |||
101 | static inline void xgene_pcie_cfg_out8(void __iomem *addr, int offset, u8 val) | ||
102 | { | ||
103 | u32 val32 = readl(addr + (offset & ~0x3)); | ||
104 | |||
105 | switch (offset & 0x3) { | ||
106 | case 0: | ||
107 | val32 &= ~0xFF; | ||
108 | val32 |= val; | ||
109 | break; | ||
110 | case 1: | ||
111 | val32 &= ~0xFF00; | ||
112 | val32 |= (u32)val << 8; | ||
113 | break; | ||
114 | case 2: | ||
115 | val32 &= ~0xFF0000; | ||
116 | val32 |= (u32)val << 16; | ||
117 | break; | ||
118 | case 3: | ||
119 | default: | ||
120 | val32 &= ~0xFF000000; | ||
121 | val32 |= (u32)val << 24; | ||
122 | break; | ||
123 | } | ||
124 | writel(val32, addr + (offset & ~0x3)); | ||
125 | } | ||
126 | |||
127 | static inline void xgene_pcie_cfg_in32(void __iomem *addr, int offset, u32 *val) | ||
128 | { | ||
129 | *val = readl(addr + offset); | ||
130 | } | ||
131 | |||
132 | static inline void xgene_pcie_cfg_in16(void __iomem *addr, int offset, u32 *val) | ||
133 | { | ||
134 | *val = readl(addr + (offset & ~0x3)); | ||
135 | |||
136 | switch (offset & 0x3) { | ||
137 | case 2: | ||
138 | *val >>= 16; | ||
139 | break; | ||
140 | } | ||
141 | |||
142 | *val &= 0xFFFF; | ||
143 | } | ||
144 | |||
145 | static inline void xgene_pcie_cfg_in8(void __iomem *addr, int offset, u32 *val) | ||
146 | { | ||
147 | *val = readl(addr + (offset & ~0x3)); | ||
148 | |||
149 | switch (offset & 0x3) { | ||
150 | case 3: | ||
151 | *val = *val >> 24; | ||
152 | break; | ||
153 | case 2: | ||
154 | *val = *val >> 16; | ||
155 | break; | ||
156 | case 1: | ||
157 | *val = *val >> 8; | ||
158 | break; | ||
159 | } | ||
160 | *val &= 0xFF; | ||
161 | } | ||
162 | |||
163 | /* | 77 | /* |
164 | * When the address bit [17:16] is 2'b01, the Configuration access will be | 78 | * When the address bit [17:16] is 2'b01, the Configuration access will be |
165 | * treated as Type 1 and it will be forwarded to external PCIe device. | 79 | * treated as Type 1 and it will be forwarded to external PCIe device. |
@@ -213,69 +127,23 @@ static bool xgene_pcie_hide_rc_bars(struct pci_bus *bus, int offset) | |||
213 | return false; | 127 | return false; |
214 | } | 128 | } |
215 | 129 | ||
216 | static int xgene_pcie_read_config(struct pci_bus *bus, unsigned int devfn, | 130 | static int xgene_pcie_map_bus(struct pci_bus *bus, unsigned int devfn, |
217 | int offset, int len, u32 *val) | 131 | int offset) |
218 | { | ||
219 | struct xgene_pcie_port *port = bus->sysdata; | ||
220 | void __iomem *addr; | ||
221 | |||
222 | if ((pci_is_root_bus(bus) && devfn != 0) || !port->link_up) | ||
223 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
224 | |||
225 | if (xgene_pcie_hide_rc_bars(bus, offset)) { | ||
226 | *val = 0; | ||
227 | return PCIBIOS_SUCCESSFUL; | ||
228 | } | ||
229 | |||
230 | xgene_pcie_set_rtdid_reg(bus, devfn); | ||
231 | addr = xgene_pcie_get_cfg_base(bus); | ||
232 | switch (len) { | ||
233 | case 1: | ||
234 | xgene_pcie_cfg_in8(addr, offset, val); | ||
235 | break; | ||
236 | case 2: | ||
237 | xgene_pcie_cfg_in16(addr, offset, val); | ||
238 | break; | ||
239 | default: | ||
240 | xgene_pcie_cfg_in32(addr, offset, val); | ||
241 | break; | ||
242 | } | ||
243 | |||
244 | return PCIBIOS_SUCCESSFUL; | ||
245 | } | ||
246 | |||
247 | static int xgene_pcie_write_config(struct pci_bus *bus, unsigned int devfn, | ||
248 | int offset, int len, u32 val) | ||
249 | { | 132 | { |
250 | struct xgene_pcie_port *port = bus->sysdata; | 133 | struct xgene_pcie_port *port = bus->sysdata; |
251 | void __iomem *addr; | ||
252 | 134 | ||
253 | if ((pci_is_root_bus(bus) && devfn != 0) || !port->link_up) | 135 | if ((pci_is_root_bus(bus) && devfn != 0) || !port->link_up || |
254 | return PCIBIOS_DEVICE_NOT_FOUND; | 136 | xgene_pcie_hide_rc_bars(bus, offset)) |
255 | 137 | return NULL; | |
256 | if (xgene_pcie_hide_rc_bars(bus, offset)) | ||
257 | return PCIBIOS_SUCCESSFUL; | ||
258 | 138 | ||
259 | xgene_pcie_set_rtdid_reg(bus, devfn); | 139 | xgene_pcie_set_rtdid_reg(bus, devfn); |
260 | addr = xgene_pcie_get_cfg_base(bus); | 140 | return xgene_pcie_get_cfg_base(bus); |
261 | switch (len) { | ||
262 | case 1: | ||
263 | xgene_pcie_cfg_out8(addr, offset, (u8)val); | ||
264 | break; | ||
265 | case 2: | ||
266 | xgene_pcie_cfg_out16(addr, offset, (u16)val); | ||
267 | break; | ||
268 | default: | ||
269 | xgene_pcie_cfg_out32(addr, offset, val); | ||
270 | break; | ||
271 | } | ||
272 | |||
273 | return PCIBIOS_SUCCESSFUL; | ||
274 | } | 141 | } |
275 | 142 | ||
276 | static struct pci_ops xgene_pcie_ops = { | 143 | static struct pci_ops xgene_pcie_ops = { |
277 | .read = xgene_pcie_read_config, | 144 | .map_bus = xgene_pcie_map_bus, |
278 | .write = xgene_pcie_write_config | 145 | .read = pci_generic_config_read32, |
146 | .write = pci_generic_config_write32, | ||
279 | }; | 147 | }; |
280 | 148 | ||
281 | static u64 xgene_pcie_set_ib_mask(void __iomem *csr_base, u32 addr, | 149 | static u64 xgene_pcie_set_ib_mask(void __iomem *csr_base, u32 addr, |
@@ -401,11 +269,11 @@ static int xgene_pcie_map_ranges(struct xgene_pcie_port *port, | |||
401 | struct list_head *res, | 269 | struct list_head *res, |
402 | resource_size_t io_base) | 270 | resource_size_t io_base) |
403 | { | 271 | { |
404 | struct pci_host_bridge_window *window; | 272 | struct resource_entry *window; |
405 | struct device *dev = port->dev; | 273 | struct device *dev = port->dev; |
406 | int ret; | 274 | int ret; |
407 | 275 | ||
408 | list_for_each_entry(window, res, list) { | 276 | resource_list_for_each_entry(window, res) { |
409 | struct resource *res = window->res; | 277 | struct resource *res = window->res; |
410 | u64 restype = resource_type(res); | 278 | u64 restype = resource_type(res); |
411 | 279 | ||