• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
set_val(u32 v,int where,int size,u32 * val)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 
handle_ea_bar(u32 e0,int bar,struct pci_bus * bus,unsigned int devfn,int where,int size,u32 * val)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 
thunder_ecam_p2_config_read(struct pci_bus * bus,unsigned int devfn,int where,int size,u32 * val)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 
thunder_ecam_config_read(struct pci_bus * bus,unsigned int devfn,int where,int size,u32 * val)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 
thunder_ecam_config_write(struct pci_bus * bus,unsigned int devfn,int where,int size,u32 val)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 
thunder_ecam_probe(struct platform_device * pdev)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);
376