xref: /linux/drivers/pci/of_property.c (revision 2a31b5378c6db9c4a8d399e5d10d32cd4b732bef)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2022-2023, Advanced Micro Devices, Inc.
4  */
5 
6 #include <linux/pci.h>
7 #include <linux/of.h>
8 #include <linux/of_irq.h>
9 #include <linux/bitfield.h>
10 #include <linux/bits.h>
11 #include "pci.h"
12 
13 #define OF_PCI_ADDRESS_CELLS		3
14 #define OF_PCI_SIZE_CELLS		2
15 #define OF_PCI_MAX_INT_PIN		4
16 
17 struct of_pci_addr_pair {
18 	u32		phys_addr[OF_PCI_ADDRESS_CELLS];
19 	u32		size[OF_PCI_SIZE_CELLS];
20 };
21 
22 /*
23  * Each entry in the ranges table is a tuple containing the child address,
24  * the parent address, and the size of the region in the child address space.
25  * Thus, for PCI, in each entry parent address is an address on the primary
26  * side and the child address is the corresponding address on the secondary
27  * side.
28  */
29 struct of_pci_range_entry {
30 	u32		child_addr[OF_PCI_ADDRESS_CELLS];
31 	u32		parent_addr[OF_PCI_ADDRESS_CELLS];
32 	u32		size[OF_PCI_SIZE_CELLS];
33 };
34 
35 #define OF_PCI_ADDR_SPACE_IO		0x1
36 #define OF_PCI_ADDR_SPACE_MEM32		0x2
37 #define OF_PCI_ADDR_SPACE_MEM64		0x3
38 
39 #define OF_PCI_ADDR_FIELD_NONRELOC	BIT(31)
40 #define OF_PCI_ADDR_FIELD_SS		GENMASK(25, 24)
41 #define OF_PCI_ADDR_FIELD_PREFETCH	BIT(30)
42 #define OF_PCI_ADDR_FIELD_BUS		GENMASK(23, 16)
43 #define OF_PCI_ADDR_FIELD_DEV		GENMASK(15, 11)
44 #define OF_PCI_ADDR_FIELD_FUNC		GENMASK(10, 8)
45 #define OF_PCI_ADDR_FIELD_REG		GENMASK(7, 0)
46 
47 enum of_pci_prop_compatible {
48 	PROP_COMPAT_PCI_VVVV_DDDD,
49 	PROP_COMPAT_PCICLASS_CCSSPP,
50 	PROP_COMPAT_PCICLASS_CCSS,
51 	PROP_COMPAT_NUM,
52 };
53 
54 static void of_pci_set_address(struct pci_dev *pdev, u32 *prop, u64 addr,
55 			       u32 reg_num, u32 flags, bool reloc)
56 {
57 	if (pdev) {
58 		prop[0] = FIELD_PREP(OF_PCI_ADDR_FIELD_BUS, pdev->bus->number) |
59 			  FIELD_PREP(OF_PCI_ADDR_FIELD_DEV, PCI_SLOT(pdev->devfn)) |
60 			  FIELD_PREP(OF_PCI_ADDR_FIELD_FUNC, PCI_FUNC(pdev->devfn));
61 	} else
62 		prop[0] = 0;
63 
64 	prop[0] |= flags | reg_num;
65 	if (!reloc) {
66 		prop[0] |= OF_PCI_ADDR_FIELD_NONRELOC;
67 		prop[1] = upper_32_bits(addr);
68 		prop[2] = lower_32_bits(addr);
69 	}
70 }
71 
72 static int of_pci_get_addr_flags(const struct resource *res, u32 *flags)
73 {
74 	u32 ss;
75 
76 	if (res->flags & IORESOURCE_IO)
77 		ss = OF_PCI_ADDR_SPACE_IO;
78 	else if (res->flags & IORESOURCE_MEM_64)
79 		ss = OF_PCI_ADDR_SPACE_MEM64;
80 	else if (res->flags & IORESOURCE_MEM)
81 		ss = OF_PCI_ADDR_SPACE_MEM32;
82 	else
83 		return -EINVAL;
84 
85 	*flags = 0;
86 	if (res->flags & IORESOURCE_PREFETCH)
87 		*flags |= OF_PCI_ADDR_FIELD_PREFETCH;
88 
89 	*flags |= FIELD_PREP(OF_PCI_ADDR_FIELD_SS, ss);
90 
91 	return 0;
92 }
93 
94 static int of_pci_prop_bus_range(struct pci_dev *pdev,
95 				 struct of_changeset *ocs,
96 				 struct device_node *np)
97 {
98 	u32 bus_range[2];
99 
100 	if (!pdev->subordinate)
101 		return 0;
102 
103 	bus_range[0] = pdev->subordinate->busn_res.start;
104 	bus_range[1] = pdev->subordinate->busn_res.end;
105 	return of_changeset_add_prop_u32_array(ocs, np, "bus-range", bus_range,
106 					       ARRAY_SIZE(bus_range));
107 }
108 
109 static int of_pci_prop_ranges(struct pci_dev *pdev, struct of_changeset *ocs,
110 			      struct device_node *np)
111 {
112 	struct of_pci_range_entry *rp;
113 	struct resource *res;
114 	int i, j, ret;
115 	u32 flags, num;
116 	u64 val64;
117 
118 	if (pci_is_bridge(pdev)) {
119 		num = PCI_BRIDGE_RESOURCE_NUM;
120 		res = &pdev->resource[PCI_BRIDGE_RESOURCES];
121 	} else {
122 		num = PCI_STD_NUM_BARS;
123 		res = &pdev->resource[PCI_STD_RESOURCES];
124 	}
125 
126 	rp = kzalloc_objs(*rp, num);
127 	if (!rp)
128 		return -ENOMEM;
129 
130 	for (i = 0, j = 0; j < num; j++) {
131 		if (!resource_size(&res[j]))
132 			continue;
133 
134 		if (of_pci_get_addr_flags(&res[j], &flags))
135 			continue;
136 
137 		val64 = pci_bus_address(pdev, &res[j] - pdev->resource);
138 		of_pci_set_address(pdev, rp[i].parent_addr, val64, 0, flags,
139 				   false);
140 		if (pci_is_bridge(pdev)) {
141 			memcpy(rp[i].child_addr, rp[i].parent_addr,
142 			       sizeof(rp[i].child_addr));
143 		} else {
144 			/*
145 			 * For endpoint device, the lower 64-bits of child
146 			 * address is always zero.
147 			 */
148 			rp[i].child_addr[0] = j;
149 		}
150 
151 		val64 = resource_size(&res[j]);
152 		rp[i].size[0] = upper_32_bits(val64);
153 		rp[i].size[1] = lower_32_bits(val64);
154 
155 		i++;
156 	}
157 
158 	ret = of_changeset_add_prop_u32_array(ocs, np, "ranges", (u32 *)rp,
159 					      i * sizeof(*rp) / sizeof(u32));
160 	kfree(rp);
161 
162 	return ret;
163 }
164 
165 static int of_pci_prop_reg(struct pci_dev *pdev, struct of_changeset *ocs,
166 			   struct device_node *np)
167 {
168 	struct of_pci_addr_pair reg = { 0 };
169 
170 	/* configuration space */
171 	of_pci_set_address(pdev, reg.phys_addr, 0, 0, 0, true);
172 
173 	return of_changeset_add_prop_u32_array(ocs, np, "reg", (u32 *)&reg,
174 					       sizeof(reg) / sizeof(u32));
175 }
176 
177 static int of_pci_prop_interrupts(struct pci_dev *pdev,
178 				  struct of_changeset *ocs,
179 				  struct device_node *np)
180 {
181 	int ret;
182 	u8 pin;
183 
184 	ret = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
185 	if (ret != 0)
186 		return ret;
187 
188 	if (!pin)
189 		return 0;
190 
191 	return of_changeset_add_prop_u32(ocs, np, "interrupts", (u32)pin);
192 }
193 
194 static int of_pci_prop_intr_ctrl(struct pci_dev *pdev, struct of_changeset *ocs,
195 				 struct device_node *np)
196 {
197 	int ret;
198 	u8 pin;
199 
200 	ret = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
201 	if (ret != 0)
202 		return ret;
203 
204 	if (!pin)
205 		return 0;
206 
207 	ret = of_changeset_add_prop_u32(ocs, np, "#interrupt-cells", 1);
208 	if (ret)
209 		return ret;
210 
211 	return of_changeset_add_prop_bool(ocs, np, "interrupt-controller");
212 }
213 
214 static int of_pci_prop_intr_map(struct pci_dev *pdev, struct of_changeset *ocs,
215 				struct device_node *np)
216 {
217 	u32 i, addr_sz[OF_PCI_MAX_INT_PIN] = { 0 }, map_sz = 0;
218 	struct of_phandle_args out_irq[OF_PCI_MAX_INT_PIN];
219 	__be32 laddr[OF_PCI_ADDRESS_CELLS] = { 0 };
220 	u32 int_map_mask[] = { 0xffff00, 0, 0, 7 };
221 	struct device_node *pnode;
222 	struct pci_dev *child;
223 	u32 *int_map, *mapp;
224 	int ret;
225 	u8 pin;
226 
227 	if (!pdev->subordinate)
228 		return 0;
229 
230 	pnode = pci_device_to_OF_node(pdev->bus->self);
231 	if (!pnode)
232 		pnode = pci_bus_to_OF_node(pdev->bus);
233 
234 	if (!pnode) {
235 		pci_err(pdev, "failed to get parent device node");
236 		return -EINVAL;
237 	}
238 
239 	laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8));
240 	for (pin = 1; pin <= OF_PCI_MAX_INT_PIN;  pin++) {
241 		i = pin - 1;
242 		out_irq[i].np = pnode;
243 		out_irq[i].args_count = 1;
244 		out_irq[i].args[0] = pin;
245 		ret = of_irq_parse_raw(laddr, &out_irq[i]);
246 		if (ret) {
247 			out_irq[i].np = NULL;
248 			pci_dbg(pdev, "parse irq %d failed, ret %d", pin, ret);
249 			continue;
250 		}
251 		of_property_read_u32(out_irq[i].np, "#address-cells",
252 				     &addr_sz[i]);
253 	}
254 
255 	list_for_each_entry(child, &pdev->subordinate->devices, bus_list) {
256 		for (pin = 1; pin <= OF_PCI_MAX_INT_PIN; pin++) {
257 			i = pci_swizzle_interrupt_pin(child, pin) - 1;
258 			if (!out_irq[i].np)
259 				continue;
260 			map_sz += 5 + addr_sz[i] + out_irq[i].args_count;
261 		}
262 	}
263 
264 	/*
265 	 * Parsing interrupt failed for all pins. In this case, it does not
266 	 * need to generate interrupt-map property.
267 	 */
268 	if (!map_sz)
269 		return 0;
270 
271 	int_map = kcalloc(map_sz, sizeof(u32), GFP_KERNEL);
272 	if (!int_map)
273 		return -ENOMEM;
274 	mapp = int_map;
275 
276 	list_for_each_entry(child, &pdev->subordinate->devices, bus_list) {
277 		for (pin = 1; pin <= OF_PCI_MAX_INT_PIN; pin++) {
278 			i = pci_swizzle_interrupt_pin(child, pin) - 1;
279 			if (!out_irq[i].np)
280 				continue;
281 
282 			*mapp = (child->bus->number << 16) |
283 				(child->devfn << 8);
284 			mapp += OF_PCI_ADDRESS_CELLS;
285 			*mapp = pin;
286 			mapp++;
287 			*mapp = out_irq[i].np->phandle;
288 			mapp++;
289 
290 			/*
291 			 * A device address does not affect the device <->
292 			 * interrupt-controller HW connection for all
293 			 * modern interrupt controllers; moreover, the
294 			 * kernel (i.e., of_irq_parse_raw()) ignores the
295 			 * values in the parent unit address cells while
296 			 * parsing the interrupt-map property because they
297 			 * are irrelevant for interrupt mapping in modern
298 			 * systems.
299 			 *
300 			 * Leave the parent unit address initialized to 0 --
301 			 * just take into account the #address-cells size
302 			 * to build the property properly.
303 			 */
304 			mapp += addr_sz[i];
305 			memcpy(mapp, out_irq[i].args,
306 			       out_irq[i].args_count * sizeof(u32));
307 			mapp += out_irq[i].args_count;
308 		}
309 	}
310 
311 	ret = of_changeset_add_prop_u32_array(ocs, np, "interrupt-map", int_map,
312 					      map_sz);
313 	if (ret)
314 		goto failed;
315 
316 	ret = of_changeset_add_prop_u32(ocs, np, "#interrupt-cells", 1);
317 	if (ret)
318 		goto failed;
319 
320 	ret = of_changeset_add_prop_u32_array(ocs, np, "interrupt-map-mask",
321 					      int_map_mask,
322 					      ARRAY_SIZE(int_map_mask));
323 	if (ret)
324 		goto failed;
325 
326 	kfree(int_map);
327 	return 0;
328 
329 failed:
330 	kfree(int_map);
331 	return ret;
332 }
333 
334 static int of_pci_prop_compatible(struct pci_dev *pdev,
335 				  struct of_changeset *ocs,
336 				  struct device_node *np)
337 {
338 	const char *compat_strs[PROP_COMPAT_NUM] = { 0 };
339 	int i, ret;
340 
341 	compat_strs[PROP_COMPAT_PCI_VVVV_DDDD] =
342 		kasprintf(GFP_KERNEL, "pci%x,%x", pdev->vendor, pdev->device);
343 	compat_strs[PROP_COMPAT_PCICLASS_CCSSPP] =
344 		kasprintf(GFP_KERNEL, "pciclass,%06x", pdev->class);
345 	compat_strs[PROP_COMPAT_PCICLASS_CCSS] =
346 		kasprintf(GFP_KERNEL, "pciclass,%04x", pdev->class >> 8);
347 
348 	ret = of_changeset_add_prop_string_array(ocs, np, "compatible",
349 						 compat_strs, PROP_COMPAT_NUM);
350 	for (i = 0; i < PROP_COMPAT_NUM; i++)
351 		kfree(compat_strs[i]);
352 
353 	return ret;
354 }
355 
356 int of_pci_add_properties(struct pci_dev *pdev, struct of_changeset *ocs,
357 			  struct device_node *np)
358 {
359 	int ret;
360 
361 	/*
362 	 * The added properties will be released when the
363 	 * changeset is destroyed.
364 	 */
365 	if (pci_is_bridge(pdev)) {
366 		ret = of_changeset_add_prop_string(ocs, np, "device_type",
367 						   "pci");
368 		if (ret)
369 			return ret;
370 
371 		ret = of_pci_prop_bus_range(pdev, ocs, np);
372 		if (ret)
373 			return ret;
374 
375 		ret = of_pci_prop_intr_map(pdev, ocs, np);
376 		if (ret)
377 			return ret;
378 	} else {
379 		ret = of_pci_prop_intr_ctrl(pdev, ocs, np);
380 		if (ret)
381 			return ret;
382 	}
383 
384 	ret = of_pci_prop_ranges(pdev, ocs, np);
385 	if (ret)
386 		return ret;
387 
388 	ret = of_changeset_add_prop_u32(ocs, np, "#address-cells",
389 					OF_PCI_ADDRESS_CELLS);
390 	if (ret)
391 		return ret;
392 
393 	ret = of_changeset_add_prop_u32(ocs, np, "#size-cells",
394 					OF_PCI_SIZE_CELLS);
395 	if (ret)
396 		return ret;
397 
398 	ret = of_pci_prop_reg(pdev, ocs, np);
399 	if (ret)
400 		return ret;
401 
402 	ret = of_pci_prop_compatible(pdev, ocs, np);
403 	if (ret)
404 		return ret;
405 
406 	ret = of_pci_prop_interrupts(pdev, ocs, np);
407 	if (ret)
408 		return ret;
409 
410 	return 0;
411 }
412 
413 static bool of_pci_is_range_resource(const struct resource *res, u32 *flags)
414 {
415 	if (!(resource_type(res) & IORESOURCE_MEM) &&
416 	    !(resource_type(res) & IORESOURCE_MEM_64))
417 		return false;
418 
419 	if (of_pci_get_addr_flags(res, flags))
420 		return false;
421 
422 	return true;
423 }
424 
425 static int of_pci_host_bridge_prop_ranges(struct pci_host_bridge *bridge,
426 					  struct of_changeset *ocs,
427 					  struct device_node *np)
428 {
429 	struct resource_entry *window;
430 	unsigned int ranges_sz = 0;
431 	unsigned int n_range = 0;
432 	struct resource *res;
433 	int n_addr_cells;
434 	u32 *ranges;
435 	u64 val64;
436 	u32 flags;
437 	int ret;
438 
439 	n_addr_cells = of_n_addr_cells(np);
440 	if (n_addr_cells <= 0 || n_addr_cells > 2)
441 		return -EINVAL;
442 
443 	resource_list_for_each_entry(window, &bridge->windows) {
444 		res = window->res;
445 		if (!of_pci_is_range_resource(res, &flags))
446 			continue;
447 		n_range++;
448 	}
449 
450 	if (!n_range)
451 		return 0;
452 
453 	ranges = kcalloc(n_range,
454 			 (OF_PCI_ADDRESS_CELLS + OF_PCI_SIZE_CELLS +
455 			  n_addr_cells) * sizeof(*ranges),
456 			 GFP_KERNEL);
457 	if (!ranges)
458 		return -ENOMEM;
459 
460 	resource_list_for_each_entry(window, &bridge->windows) {
461 		res = window->res;
462 		if (!of_pci_is_range_resource(res, &flags))
463 			continue;
464 
465 		/* PCI bus address */
466 		val64 = res->start;
467 		of_pci_set_address(NULL, &ranges[ranges_sz],
468 				   val64 - window->offset, 0, flags, false);
469 		ranges_sz += OF_PCI_ADDRESS_CELLS;
470 
471 		/* Host bus address */
472 		if (n_addr_cells == 2)
473 			ranges[ranges_sz++] = upper_32_bits(val64);
474 		ranges[ranges_sz++] = lower_32_bits(val64);
475 
476 		/* Size */
477 		val64 = resource_size(res);
478 		ranges[ranges_sz] = upper_32_bits(val64);
479 		ranges[ranges_sz + 1] = lower_32_bits(val64);
480 		ranges_sz += OF_PCI_SIZE_CELLS;
481 	}
482 
483 	ret = of_changeset_add_prop_u32_array(ocs, np, "ranges", ranges,
484 					      ranges_sz);
485 	kfree(ranges);
486 	return ret;
487 }
488 
489 int of_pci_add_host_bridge_properties(struct pci_host_bridge *bridge,
490 				      struct of_changeset *ocs,
491 				      struct device_node *np)
492 {
493 	int ret;
494 
495 	ret = of_changeset_add_prop_string(ocs, np, "device_type", "pci");
496 	if (ret)
497 		return ret;
498 
499 	ret = of_changeset_add_prop_u32(ocs, np, "#address-cells",
500 					OF_PCI_ADDRESS_CELLS);
501 	if (ret)
502 		return ret;
503 
504 	ret = of_changeset_add_prop_u32(ocs, np, "#size-cells",
505 					OF_PCI_SIZE_CELLS);
506 	if (ret)
507 		return ret;
508 
509 	ret = of_pci_host_bridge_prop_ranges(bridge, ocs, np);
510 	if (ret)
511 		return ret;
512 
513 	return 0;
514 }
515