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