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