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