Merge branch 'for-linus' into next
[cascardo/linux.git] / drivers / pci / host / pci-thunder-ecam.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 2015, 2016 Cavium, Inc.
7  */
8
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/ioport.h>
12 #include <linux/of_pci.h>
13 #include <linux/of.h>
14 #include <linux/platform_device.h>
15
16 #include "pci-host-common.h"
17
18 /* Mapping is standard ECAM */
19 static void __iomem *thunder_ecam_map_bus(struct pci_bus *bus,
20                                           unsigned int devfn,
21                                           int where)
22 {
23         struct gen_pci *pci = bus->sysdata;
24         resource_size_t idx = bus->number - pci->cfg.bus_range->start;
25
26         return pci->cfg.win[idx] + ((devfn << 12) | where);
27 }
28
29 static void set_val(u32 v, int where, int size, u32 *val)
30 {
31         int shift = (where & 3) * 8;
32
33         pr_debug("set_val %04x: %08x\n", (unsigned)(where & ~3), v);
34         v >>= shift;
35         if (size == 1)
36                 v &= 0xff;
37         else if (size == 2)
38                 v &= 0xffff;
39         *val = v;
40 }
41
42 static int handle_ea_bar(u32 e0, int bar, struct pci_bus *bus,
43                          unsigned int devfn, int where, int size, u32 *val)
44 {
45         void __iomem *addr;
46         u32 v;
47
48         /* Entries are 16-byte aligned; bits[2,3] select word in entry */
49         int where_a = where & 0xc;
50
51         if (where_a == 0) {
52                 set_val(e0, where, size, val);
53                 return PCIBIOS_SUCCESSFUL;
54         }
55         if (where_a == 0x4) {
56                 addr = bus->ops->map_bus(bus, devfn, bar); /* BAR 0 */
57                 if (!addr) {
58                         *val = ~0;
59                         return PCIBIOS_DEVICE_NOT_FOUND;
60                 }
61                 v = readl(addr);
62                 v &= ~0xf;
63                 v |= 2; /* EA entry-1. Base-L */
64                 set_val(v, where, size, val);
65                 return PCIBIOS_SUCCESSFUL;
66         }
67         if (where_a == 0x8) {
68                 u32 barl_orig;
69                 u32 barl_rb;
70
71                 addr = bus->ops->map_bus(bus, devfn, bar); /* BAR 0 */
72                 if (!addr) {
73                         *val = ~0;
74                         return PCIBIOS_DEVICE_NOT_FOUND;
75                 }
76                 barl_orig = readl(addr + 0);
77                 writel(0xffffffff, addr + 0);
78                 barl_rb = readl(addr + 0);
79                 writel(barl_orig, addr + 0);
80                 /* zeros in unsettable bits */
81                 v = ~barl_rb & ~3;
82                 v |= 0xc; /* EA entry-2. Offset-L */
83                 set_val(v, where, size, val);
84                 return PCIBIOS_SUCCESSFUL;
85         }
86         if (where_a == 0xc) {
87                 addr = bus->ops->map_bus(bus, devfn, bar + 4); /* BAR 1 */
88                 if (!addr) {
89                         *val = ~0;
90                         return PCIBIOS_DEVICE_NOT_FOUND;
91                 }
92                 v = readl(addr); /* EA entry-3. Base-H */
93                 set_val(v, where, size, val);
94                 return PCIBIOS_SUCCESSFUL;
95         }
96         return PCIBIOS_DEVICE_NOT_FOUND;
97 }
98
99 static int thunder_ecam_p2_config_read(struct pci_bus *bus, unsigned int devfn,
100                                        int where, int size, u32 *val)
101 {
102         struct gen_pci *pci = bus->sysdata;
103         int where_a = where & ~3;
104         void __iomem *addr;
105         u32 node_bits;
106         u32 v;
107
108         /* EA Base[63:32] may be missing some bits ... */
109         switch (where_a) {
110         case 0xa8:
111         case 0xbc:
112         case 0xd0:
113         case 0xe4:
114                 break;
115         default:
116                 return pci_generic_config_read(bus, devfn, where, size, val);
117         }
118
119         addr = bus->ops->map_bus(bus, devfn, where_a);
120         if (!addr) {
121                 *val = ~0;
122                 return PCIBIOS_DEVICE_NOT_FOUND;
123         }
124
125         v = readl(addr);
126
127         /*
128          * Bit 44 of the 64-bit Base must match the same bit in
129          * the config space access window.  Since we are working with
130          * the high-order 32 bits, shift everything down by 32 bits.
131          */
132         node_bits = (pci->cfg.res.start >> 32) & (1 << 12);
133
134         v |= node_bits;
135         set_val(v, where, size, val);
136
137         return PCIBIOS_SUCCESSFUL;
138 }
139
140 static int thunder_ecam_config_read(struct pci_bus *bus, unsigned int devfn,
141                                     int where, int size, u32 *val)
142 {
143         u32 v;
144         u32 vendor_device;
145         u32 class_rev;
146         void __iomem *addr;
147         int cfg_type;
148         int where_a = where & ~3;
149
150         addr = bus->ops->map_bus(bus, devfn, 0xc);
151         if (!addr) {
152                 *val = ~0;
153                 return PCIBIOS_DEVICE_NOT_FOUND;
154         }
155
156         v = readl(addr);
157
158         /* Check for non type-00 header */
159         cfg_type = (v >> 16) & 0x7f;
160
161         addr = bus->ops->map_bus(bus, devfn, 8);
162         if (!addr) {
163                 *val = ~0;
164                 return PCIBIOS_DEVICE_NOT_FOUND;
165         }
166
167         class_rev = readl(addr);
168         if (class_rev == 0xffffffff)
169                 goto no_emulation;
170
171         if ((class_rev & 0xff) >= 8) {
172                 /* Pass-2 handling */
173                 if (cfg_type)
174                         goto no_emulation;
175                 return thunder_ecam_p2_config_read(bus, devfn, where,
176                                                    size, val);
177         }
178
179         /*
180          * All BARs have fixed addresses specified by the EA
181          * capability; they must return zero on read.
182          */
183         if (cfg_type == 0 &&
184             ((where >= 0x10 && where < 0x2c) ||
185              (where >= 0x1a4 && where < 0x1bc))) {
186                 /* BAR or SR-IOV BAR */
187                 *val = 0;
188                 return PCIBIOS_SUCCESSFUL;
189         }
190
191         addr = bus->ops->map_bus(bus, devfn, 0);
192         if (!addr) {
193                 *val = ~0;
194                 return PCIBIOS_DEVICE_NOT_FOUND;
195         }
196
197         vendor_device = readl(addr);
198         if (vendor_device == 0xffffffff)
199                 goto no_emulation;
200
201         pr_debug("%04x:%04x - Fix pass#: %08x, where: %03x, devfn: %03x\n",
202                  vendor_device & 0xffff, vendor_device >> 16, class_rev,
203                  (unsigned) where, devfn);
204
205         /* Check for non type-00 header */
206         if (cfg_type == 0) {
207                 bool has_msix;
208                 bool is_nic = (vendor_device == 0xa01e177d);
209                 bool is_tns = (vendor_device == 0xa01f177d);
210
211                 addr = bus->ops->map_bus(bus, devfn, 0x70);
212                 if (!addr) {
213                         *val = ~0;
214                         return PCIBIOS_DEVICE_NOT_FOUND;
215                 }
216                 /* E_CAP */
217                 v = readl(addr);
218                 has_msix = (v & 0xff00) != 0;
219
220                 if (!has_msix && where_a == 0x70) {
221                         v |= 0xbc00; /* next capability is EA at 0xbc */
222                         set_val(v, where, size, val);
223                         return PCIBIOS_SUCCESSFUL;
224                 }
225                 if (where_a == 0xb0) {
226                         addr = bus->ops->map_bus(bus, devfn, where_a);
227                         if (!addr) {
228                                 *val = ~0;
229                                 return PCIBIOS_DEVICE_NOT_FOUND;
230                         }
231                         v = readl(addr);
232                         if (v & 0xff00)
233                                 pr_err("Bad MSIX cap header: %08x\n", v);
234                         v |= 0xbc00; /* next capability is EA at 0xbc */
235                         set_val(v, where, size, val);
236                         return PCIBIOS_SUCCESSFUL;
237                 }
238                 if (where_a == 0xbc) {
239                         if (is_nic)
240                                 v = 0x40014; /* EA last in chain, 4 entries */
241                         else if (is_tns)
242                                 v = 0x30014; /* EA last in chain, 3 entries */
243                         else if (has_msix)
244                                 v = 0x20014; /* EA last in chain, 2 entries */
245                         else
246                                 v = 0x10014; /* EA last in chain, 1 entry */
247                         set_val(v, where, size, val);
248                         return PCIBIOS_SUCCESSFUL;
249                 }
250                 if (where_a >= 0xc0 && where_a < 0xd0)
251                         /* EA entry-0. PP=0, BAR0 Size:3 */
252                         return handle_ea_bar(0x80ff0003,
253                                              0x10, bus, devfn, where,
254                                              size, val);
255                 if (where_a >= 0xd0 && where_a < 0xe0 && has_msix)
256                          /* EA entry-1. PP=0, BAR4 Size:3 */
257                         return handle_ea_bar(0x80ff0043,
258                                              0x20, bus, devfn, where,
259                                              size, val);
260                 if (where_a >= 0xe0 && where_a < 0xf0 && is_tns)
261                         /* EA entry-2. PP=0, BAR2, Size:3 */
262                         return handle_ea_bar(0x80ff0023,
263                                              0x18, bus, devfn, where,
264                                              size, val);
265                 if (where_a >= 0xe0 && where_a < 0xf0 && is_nic)
266                         /* EA entry-2. PP=4, VF_BAR0 (9), Size:3 */
267                         return handle_ea_bar(0x80ff0493,
268                                              0x1a4, bus, devfn, where,
269                                              size, val);
270                 if (where_a >= 0xf0 && where_a < 0x100 && is_nic)
271                         /* EA entry-3. PP=4, VF_BAR4 (d), Size:3 */
272                         return handle_ea_bar(0x80ff04d3,
273                                              0x1b4, bus, devfn, where,
274                                              size, val);
275         } else if (cfg_type == 1) {
276                 bool is_rsl_bridge = devfn == 0x08;
277                 bool is_rad_bridge = devfn == 0xa0;
278                 bool is_zip_bridge = devfn == 0xa8;
279                 bool is_dfa_bridge = devfn == 0xb0;
280                 bool is_nic_bridge = devfn == 0x10;
281
282                 if (where_a == 0x70) {
283                         addr = bus->ops->map_bus(bus, devfn, where_a);
284                         if (!addr) {
285                                 *val = ~0;
286                                 return PCIBIOS_DEVICE_NOT_FOUND;
287                         }
288                         v = readl(addr);
289                         if (v & 0xff00)
290                                 pr_err("Bad PCIe cap header: %08x\n", v);
291                         v |= 0xbc00; /* next capability is EA at 0xbc */
292                         set_val(v, where, size, val);
293                         return PCIBIOS_SUCCESSFUL;
294                 }
295                 if (where_a == 0xbc) {
296                         if (is_nic_bridge)
297                                 v = 0x10014; /* EA last in chain, 1 entry */
298                         else
299                                 v = 0x00014; /* EA last in chain, no entries */
300                         set_val(v, where, size, val);
301                         return PCIBIOS_SUCCESSFUL;
302                 }
303                 if (where_a == 0xc0) {
304                         if (is_rsl_bridge || is_nic_bridge)
305                                 v = 0x0101; /* subordinate:secondary = 1:1 */
306                         else if (is_rad_bridge)
307                                 v = 0x0202; /* subordinate:secondary = 2:2 */
308                         else if (is_zip_bridge)
309                                 v = 0x0303; /* subordinate:secondary = 3:3 */
310                         else if (is_dfa_bridge)
311                                 v = 0x0404; /* subordinate:secondary = 4:4 */
312                         set_val(v, where, size, val);
313                         return PCIBIOS_SUCCESSFUL;
314                 }
315                 if (where_a == 0xc4 && is_nic_bridge) {
316                         /* Enabled, not-Write, SP=ff, PP=05, BEI=6, ES=4 */
317                         v = 0x80ff0564;
318                         set_val(v, where, size, val);
319                         return PCIBIOS_SUCCESSFUL;
320                 }
321                 if (where_a == 0xc8 && is_nic_bridge) {
322                         v = 0x00000002; /* Base-L 64-bit */
323                         set_val(v, where, size, val);
324                         return PCIBIOS_SUCCESSFUL;
325                 }
326                 if (where_a == 0xcc && is_nic_bridge) {
327                         v = 0xfffffffe; /* MaxOffset-L 64-bit */
328                         set_val(v, where, size, val);
329                         return PCIBIOS_SUCCESSFUL;
330                 }
331                 if (where_a == 0xd0 && is_nic_bridge) {
332                         v = 0x00008430; /* NIC Base-H */
333                         set_val(v, where, size, val);
334                         return PCIBIOS_SUCCESSFUL;
335                 }
336                 if (where_a == 0xd4 && is_nic_bridge) {
337                         v = 0x0000000f; /* MaxOffset-H */
338                         set_val(v, where, size, val);
339                         return PCIBIOS_SUCCESSFUL;
340                 }
341         }
342 no_emulation:
343         return pci_generic_config_read(bus, devfn, where, size, val);
344 }
345
346 static int thunder_ecam_config_write(struct pci_bus *bus, unsigned int devfn,
347                                      int where, int size, u32 val)
348 {
349         /*
350          * All BARs have fixed addresses; ignore BAR writes so they
351          * don't get corrupted.
352          */
353         if ((where >= 0x10 && where < 0x2c) ||
354             (where >= 0x1a4 && where < 0x1bc))
355                 /* BAR or SR-IOV BAR */
356                 return PCIBIOS_SUCCESSFUL;
357
358         return pci_generic_config_write(bus, devfn, where, size, val);
359 }
360
361 static struct gen_pci_cfg_bus_ops thunder_ecam_bus_ops = {
362         .bus_shift      = 20,
363         .ops            = {
364                 .map_bus        = thunder_ecam_map_bus,
365                 .read           = thunder_ecam_config_read,
366                 .write          = thunder_ecam_config_write,
367         }
368 };
369
370 static const struct of_device_id thunder_ecam_of_match[] = {
371         { .compatible = "cavium,pci-host-thunder-ecam",
372           .data = &thunder_ecam_bus_ops },
373
374         { },
375 };
376 MODULE_DEVICE_TABLE(of, thunder_ecam_of_match);
377
378 static int thunder_ecam_probe(struct platform_device *pdev)
379 {
380         struct device *dev = &pdev->dev;
381         const struct of_device_id *of_id;
382         struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
383
384         if (!pci)
385                 return -ENOMEM;
386
387         of_id = of_match_node(thunder_ecam_of_match, dev->of_node);
388         pci->cfg.ops = (struct gen_pci_cfg_bus_ops *)of_id->data;
389
390         return pci_host_common_probe(pdev, pci);
391 }
392
393 static struct platform_driver thunder_ecam_driver = {
394         .driver = {
395                 .name = KBUILD_MODNAME,
396                 .of_match_table = thunder_ecam_of_match,
397         },
398         .probe = thunder_ecam_probe,
399 };
400 module_platform_driver(thunder_ecam_driver);
401
402 MODULE_DESCRIPTION("Thunder ECAM PCI host driver");
403 MODULE_LICENSE("GPL v2");