Deleted Added
full compact
pci_host_generic.c (284319) pci_host_generic.c (292215)
1/*-
2 * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
3 * Copyright (c) 2014 The FreeBSD Foundation
4 * All rights reserved.
5 *
6 * This software was developed by Semihalf under
7 * the sponsorship of the FreeBSD Foundation.
8 *

--- 17 unchanged lines hidden (view full) ---

26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31/* Generic ECAM PCIe driver */
32
33#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
3 * Copyright (c) 2014 The FreeBSD Foundation
4 * All rights reserved.
5 *
6 * This software was developed by Semihalf under
7 * the sponsorship of the FreeBSD Foundation.
8 *

--- 17 unchanged lines hidden (view full) ---

26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31/* Generic ECAM PCIe driver */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/dev/pci/pci_host_generic.c 284319 2015-06-12 13:54:25Z br $");
34__FBSDID("$FreeBSD: head/sys/dev/pci/pci_host_generic.c 292215 2015-12-14 17:08:40Z andrew $");
35
36#include <sys/param.h>
37#include <sys/systm.h>
38#include <sys/malloc.h>
39#include <sys/kernel.h>
40#include <sys/rman.h>
41#include <sys/module.h>
42#include <sys/bus.h>
43#include <sys/endian.h>
44#include <sys/cpuset.h>
45#include <sys/rwlock.h>
35
36#include <sys/param.h>
37#include <sys/systm.h>
38#include <sys/malloc.h>
39#include <sys/kernel.h>
40#include <sys/rman.h>
41#include <sys/module.h>
42#include <sys/bus.h>
43#include <sys/endian.h>
44#include <sys/cpuset.h>
45#include <sys/rwlock.h>
46
46#include <dev/ofw/openfirm.h>
47#include <dev/ofw/ofw_bus.h>
48#include <dev/ofw/ofw_bus_subr.h>
47#include <dev/ofw/openfirm.h>
48#include <dev/ofw/ofw_bus.h>
49#include <dev/ofw/ofw_bus_subr.h>
50#include <dev/ofw/ofw_pci.h>
49#include <dev/pci/pcivar.h>
50#include <dev/pci/pcireg.h>
51#include <dev/pci/pcib_private.h>
51#include <dev/pci/pcivar.h>
52#include <dev/pci/pcireg.h>
53#include <dev/pci/pcib_private.h>
54
52#include <machine/cpu.h>
53#include <machine/bus.h>
54#include <machine/intr.h>
55#include <vm/vm_page.h>
56
57#include "pcib_if.h"
58
59/* Assembling ECAM Configuration Address */

--- 10 unchanged lines hidden (view full) ---

70 (((slot) & PCIE_SLOT_MASK) << PCIE_SLOT_SHIFT) | \
71 (((func) & PCIE_FUNC_MASK) << PCIE_FUNC_SHIFT) | \
72 ((reg) & PCIE_REG_MASK))
73
74#define MAX_RANGES_TUPLES 5
75#define MIN_RANGES_TUPLES 2
76
77#define PCI_IO_WINDOW_OFFSET 0x1000
55#include <machine/cpu.h>
56#include <machine/bus.h>
57#include <machine/intr.h>
58#include <vm/vm_page.h>
59
60#include "pcib_if.h"
61
62/* Assembling ECAM Configuration Address */

--- 10 unchanged lines hidden (view full) ---

73 (((slot) & PCIE_SLOT_MASK) << PCIE_SLOT_SHIFT) | \
74 (((func) & PCIE_FUNC_MASK) << PCIE_FUNC_SHIFT) | \
75 ((reg) & PCIE_REG_MASK))
76
77#define MAX_RANGES_TUPLES 5
78#define MIN_RANGES_TUPLES 2
79
80#define PCI_IO_WINDOW_OFFSET 0x1000
78#define PCI_IRQ_START 32
79#define PCI_IRQ_END (PCI_IRQ_START + 4)
80
81#define SPACE_CODE_SHIFT 24
82#define SPACE_CODE_MASK 0x3
83#define SPACE_CODE_IO_SPACE 0x1
84#define PROPS_CELL_SIZE 1
85#define PCI_ADDR_CELL_SIZE 2
86
87struct pcie_range {

--- 5 unchanged lines hidden (view full) ---

93#define FLAG_MEM (1 << 1)
94};
95
96struct generic_pcie_softc {
97 struct pcie_range ranges[MAX_RANGES_TUPLES];
98 int nranges;
99 struct rman mem_rman;
100 struct rman io_rman;
81
82#define SPACE_CODE_SHIFT 24
83#define SPACE_CODE_MASK 0x3
84#define SPACE_CODE_IO_SPACE 0x1
85#define PROPS_CELL_SIZE 1
86#define PCI_ADDR_CELL_SIZE 2
87
88struct pcie_range {

--- 5 unchanged lines hidden (view full) ---

94#define FLAG_MEM (1 << 1)
95};
96
97struct generic_pcie_softc {
98 struct pcie_range ranges[MAX_RANGES_TUPLES];
99 int nranges;
100 struct rman mem_rman;
101 struct rman io_rman;
101 struct rman irq_rman;
102 struct resource *res;
103 struct resource *res1;
104 int ecam;
105 bus_space_tag_t bst;
106 bus_space_handle_t bsh;
107 device_t dev;
108 bus_space_handle_t ioh;
102 struct resource *res;
103 struct resource *res1;
104 int ecam;
105 bus_space_tag_t bst;
106 bus_space_handle_t bsh;
107 device_t dev;
108 bus_space_handle_t ioh;
109 struct ofw_bus_iinfo pci_iinfo;
109};
110
111/* Forward prototypes */
112
113static int generic_pcie_probe(device_t dev);
114static int generic_pcie_attach(device_t dev);
115static int parse_pci_mem_ranges(struct generic_pcie_softc *sc);
116static uint32_t generic_pcie_read_config(device_t dev, u_int bus, u_int slot,

--- 94 unchanged lines hidden (view full) ---

211 if (error) {
212 device_printf(dev, "rman_manage_region() failed."
213 "error = %d\n", error);
214 rman_fini(&sc->mem_rman);
215 return (error);
216 }
217 }
218
110};
111
112/* Forward prototypes */
113
114static int generic_pcie_probe(device_t dev);
115static int generic_pcie_attach(device_t dev);
116static int parse_pci_mem_ranges(struct generic_pcie_softc *sc);
117static uint32_t generic_pcie_read_config(device_t dev, u_int bus, u_int slot,

--- 94 unchanged lines hidden (view full) ---

212 if (error) {
213 device_printf(dev, "rman_manage_region() failed."
214 "error = %d\n", error);
215 rman_fini(&sc->mem_rman);
216 return (error);
217 }
218 }
219
219 /* TODO: get IRQ numbers from FDT */
220 sc->irq_rman.rm_type = RMAN_ARRAY;
221 sc->irq_rman.rm_descr = "Generic PCIe IRQs";
222 if (rman_init(&sc->irq_rman) != 0 ||
223 rman_manage_region(&sc->irq_rman, PCI_IRQ_START,
224 PCI_IRQ_END) != 0) {
225 panic("Generic PCI: failed to set up IRQ rman");
226 }
220 ofw_bus_setup_iinfo(ofw_bus_get_node(dev), &sc->pci_iinfo,
221 sizeof(cell_t));
227
222
223
228 device_add_child(dev, "pci", -1);
229 return (bus_generic_attach(dev));
230}
231
232static int
233parse_pci_mem_ranges(struct generic_pcie_softc *sc)
234{
235 pcell_t pci_addr_cells, parent_addr_cells;

--- 100 unchanged lines hidden (view full) ---

336 break;
337 case 4:
338 data = le32toh(bus_space_read_4(t, h, offset));
339 break;
340 default:
341 return (~0U);
342 }
343
224 device_add_child(dev, "pci", -1);
225 return (bus_generic_attach(dev));
226}
227
228static int
229parse_pci_mem_ranges(struct generic_pcie_softc *sc)
230{
231 pcell_t pci_addr_cells, parent_addr_cells;

--- 100 unchanged lines hidden (view full) ---

332 break;
333 case 4:
334 data = le32toh(bus_space_read_4(t, h, offset));
335 break;
336 default:
337 return (~0U);
338 }
339
344 if (reg == PCIR_INTLINE) {
345 data += PCI_IRQ_START;
346 }
347
348 return (data);
349}
350
351static void
352generic_pcie_write_config(device_t dev, u_int bus, u_int slot,
353 u_int func, u_int reg, uint32_t val, int bytes)
354{
355 struct generic_pcie_softc *sc;

--- 29 unchanged lines hidden (view full) ---

385static int
386generic_pcie_maxslots(device_t dev)
387{
388
389 return (31); /* max slots per bus acc. to standard */
390}
391
392static int
340 return (data);
341}
342
343static void
344generic_pcie_write_config(device_t dev, u_int bus, u_int slot,
345 u_int func, u_int reg, uint32_t val, int bytes)
346{
347 struct generic_pcie_softc *sc;

--- 29 unchanged lines hidden (view full) ---

377static int
378generic_pcie_maxslots(device_t dev)
379{
380
381 return (31); /* max slots per bus acc. to standard */
382}
383
384static int
385generic_pcie_route_interrupt(device_t bus, device_t dev, int pin)
386{
387 struct generic_pcie_softc *sc;
388 struct ofw_pci_register reg;
389 uint32_t pintr, mintr[2];
390 phandle_t iparent;
391 int intrcells;
392
393 sc = device_get_softc(bus);
394 pintr = pin;
395
396 bzero(&reg, sizeof(reg));
397 reg.phys_hi = (pci_get_bus(dev) << OFW_PCI_PHYS_HI_BUSSHIFT) |
398 (pci_get_slot(dev) << OFW_PCI_PHYS_HI_DEVICESHIFT) |
399 (pci_get_function(dev) << OFW_PCI_PHYS_HI_FUNCTIONSHIFT);
400
401 intrcells = ofw_bus_lookup_imap(ofw_bus_get_node(dev),
402 &sc->pci_iinfo, &reg, sizeof(reg), &pintr, sizeof(pintr),
403 mintr, sizeof(mintr), &iparent);
404 if (intrcells) {
405 pintr = ofw_bus_map_intr(dev, iparent, intrcells, mintr);
406 return (pintr);
407 }
408
409 device_printf(bus, "could not route pin %d for device %d.%d\n",
410 pin, pci_get_slot(dev), pci_get_function(dev));
411 return (PCI_INVALID_IRQ);
412}
413
414
415static int
393generic_pcie_read_ivar(device_t dev, device_t child, int index,
394 uintptr_t *result)
395{
396 struct generic_pcie_softc *sc;
397 int secondary_bus;
398
399 sc = device_get_softc(dev);
400

--- 26 unchanged lines hidden (view full) ---

427generic_pcie_rman(struct generic_pcie_softc *sc, int type)
428{
429
430 switch (type) {
431 case SYS_RES_IOPORT:
432 return (&sc->io_rman);
433 case SYS_RES_MEMORY:
434 return (&sc->mem_rman);
416generic_pcie_read_ivar(device_t dev, device_t child, int index,
417 uintptr_t *result)
418{
419 struct generic_pcie_softc *sc;
420 int secondary_bus;
421
422 sc = device_get_softc(dev);
423

--- 26 unchanged lines hidden (view full) ---

450generic_pcie_rman(struct generic_pcie_softc *sc, int type)
451{
452
453 switch (type) {
454 case SYS_RES_IOPORT:
455 return (&sc->io_rman);
456 case SYS_RES_MEMORY:
457 return (&sc->mem_rman);
435 case SYS_RES_IRQ:
436 return (&sc->irq_rman);
437 default:
438 break;
439 }
440
441 return (NULL);
442}
443
444static int

--- 156 unchanged lines hidden (view full) ---

601 DEVMETHOD(bus_write_ivar, generic_pcie_write_ivar),
602 DEVMETHOD(bus_alloc_resource, generic_pcie_alloc_resource),
603 DEVMETHOD(bus_adjust_resource, generic_pcie_adjust_resource),
604 DEVMETHOD(bus_release_resource, generic_pcie_release_resource),
605 DEVMETHOD(bus_activate_resource, generic_pcie_activate_resource),
606 DEVMETHOD(bus_deactivate_resource, generic_pcie_deactivate_resource),
607 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
608 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
458 default:
459 break;
460 }
461
462 return (NULL);
463}
464
465static int

--- 156 unchanged lines hidden (view full) ---

622 DEVMETHOD(bus_write_ivar, generic_pcie_write_ivar),
623 DEVMETHOD(bus_alloc_resource, generic_pcie_alloc_resource),
624 DEVMETHOD(bus_adjust_resource, generic_pcie_adjust_resource),
625 DEVMETHOD(bus_release_resource, generic_pcie_release_resource),
626 DEVMETHOD(bus_activate_resource, generic_pcie_activate_resource),
627 DEVMETHOD(bus_deactivate_resource, generic_pcie_deactivate_resource),
628 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
629 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
630
631 /* pcib interface */
609 DEVMETHOD(pcib_maxslots, generic_pcie_maxslots),
632 DEVMETHOD(pcib_maxslots, generic_pcie_maxslots),
633 DEVMETHOD(pcib_route_interrupt, generic_pcie_route_interrupt),
610 DEVMETHOD(pcib_read_config, generic_pcie_read_config),
611 DEVMETHOD(pcib_write_config, generic_pcie_write_config),
634 DEVMETHOD(pcib_read_config, generic_pcie_read_config),
635 DEVMETHOD(pcib_write_config, generic_pcie_write_config),
636#if defined(__aarch64__)
637 DEVMETHOD(pcib_alloc_msi, arm_alloc_msi),
638 DEVMETHOD(pcib_release_msi, arm_release_msi),
639 DEVMETHOD(pcib_alloc_msix, arm_alloc_msix),
640 DEVMETHOD(pcib_release_msix, arm_release_msix),
641 DEVMETHOD(pcib_map_msi, arm_map_msi),
642#endif
643
612 DEVMETHOD_END
613};
614
615static driver_t generic_pcie_driver = {
616 "pcib",
617 generic_pcie_methods,
618 sizeof(struct generic_pcie_softc),
619};
620
621static devclass_t generic_pcie_devclass;
622
623DRIVER_MODULE(pcib, simplebus, generic_pcie_driver,
624generic_pcie_devclass, 0, 0);
625DRIVER_MODULE(pcib, ofwbus, generic_pcie_driver,
626generic_pcie_devclass, 0, 0);
644 DEVMETHOD_END
645};
646
647static driver_t generic_pcie_driver = {
648 "pcib",
649 generic_pcie_methods,
650 sizeof(struct generic_pcie_softc),
651};
652
653static devclass_t generic_pcie_devclass;
654
655DRIVER_MODULE(pcib, simplebus, generic_pcie_driver,
656generic_pcie_devclass, 0, 0);
657DRIVER_MODULE(pcib, ofwbus, generic_pcie_driver,
658generic_pcie_devclass, 0, 0);