mv_pci.c (240489) | mv_pci.c (240493) |
---|---|
1/*- 2 * Copyright (c) 2008 MARVELL INTERNATIONAL LTD. 3 * Copyright (c) 2010 The FreeBSD Foundation 4 * Copyright (c) 2010-2012 Semihalf 5 * All rights reserved. 6 * 7 * Developed by Semihalf. 8 * --- 25 unchanged lines hidden (view full) --- 34 * SUCH DAMAGE. 35 */ 36 37/* 38 * Marvell integrated PCI/PCI-Express controller driver. 39 */ 40 41#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2008 MARVELL INTERNATIONAL LTD. 3 * Copyright (c) 2010 The FreeBSD Foundation 4 * Copyright (c) 2010-2012 Semihalf 5 * All rights reserved. 6 * 7 * Developed by Semihalf. 8 * --- 25 unchanged lines hidden (view full) --- 34 * SUCH DAMAGE. 35 */ 36 37/* 38 * Marvell integrated PCI/PCI-Express controller driver. 39 */ 40 41#include <sys/cdefs.h> |
42__FBSDID("$FreeBSD: head/sys/arm/mv/mv_pci.c 240489 2012-09-14 09:57:41Z gber $"); | 42__FBSDID("$FreeBSD: head/sys/arm/mv/mv_pci.c 240493 2012-09-14 10:06:56Z gber $"); |
43 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/kernel.h> 47#include <sys/lock.h> 48#include <sys/malloc.h> 49#include <sys/module.h> 50#include <sys/mutex.h> 51#include <sys/queue.h> 52#include <sys/bus.h> 53#include <sys/rman.h> 54#include <sys/endian.h> 55 | 43 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/kernel.h> 47#include <sys/lock.h> 48#include <sys/malloc.h> 49#include <sys/module.h> 50#include <sys/mutex.h> 51#include <sys/queue.h> 52#include <sys/bus.h> 53#include <sys/rman.h> 54#include <sys/endian.h> 55 |
56#include <machine/intr.h> 57 |
|
56#include <vm/vm.h> 57#include <vm/pmap.h> 58 59#include <dev/fdt/fdt_common.h> 60#include <dev/ofw/ofw_bus.h> 61#include <dev/ofw/ofw_bus_subr.h> 62#include <dev/pci/pcivar.h> 63#include <dev/pci/pcireg.h> --- 4 unchanged lines hidden (view full) --- 68 69#include <machine/resource.h> 70#include <machine/bus.h> 71 72#include <arm/mv/mvreg.h> 73#include <arm/mv/mvvar.h> 74#include <arm/mv/mvwin.h> 75 | 58#include <vm/vm.h> 59#include <vm/pmap.h> 60 61#include <dev/fdt/fdt_common.h> 62#include <dev/ofw/ofw_bus.h> 63#include <dev/ofw/ofw_bus_subr.h> 64#include <dev/pci/pcivar.h> 65#include <dev/pci/pcireg.h> --- 4 unchanged lines hidden (view full) --- 70 71#include <machine/resource.h> 72#include <machine/bus.h> 73 74#include <arm/mv/mvreg.h> 75#include <arm/mv/mvvar.h> 76#include <arm/mv/mvwin.h> 77 |
78#ifdef DEBUG 79#define debugf(fmt, args...) do { printf(fmt,##args); } while (0) 80#else 81#define debugf(fmt, args...) 82#endif 83 |
|
76#define PCI_CFG_ENA (1 << 31) 77#define PCI_CFG_BUS(bus) (((bus) & 0xff) << 16) 78#define PCI_CFG_DEV(dev) (((dev) & 0x1f) << 11) 79#define PCI_CFG_FUN(fun) (((fun) & 0x7) << 8) 80#define PCI_CFG_PCIE_REG(reg) ((reg) & 0xfc) 81 82#define PCI_REG_CFG_ADDR 0x0C78 83#define PCI_REG_CFG_DATA 0x0C7C | 84#define PCI_CFG_ENA (1 << 31) 85#define PCI_CFG_BUS(bus) (((bus) & 0xff) << 16) 86#define PCI_CFG_DEV(dev) (((dev) & 0x1f) << 11) 87#define PCI_CFG_FUN(fun) (((fun) & 0x7) << 8) 88#define PCI_CFG_PCIE_REG(reg) ((reg) & 0xfc) 89 90#define PCI_REG_CFG_ADDR 0x0C78 91#define PCI_REG_CFG_DATA 0x0C7C |
84#define PCI_REG_P2P_CONF 0x1D14 | |
85 86#define PCIE_REG_CFG_ADDR 0x18F8 87#define PCIE_REG_CFG_DATA 0x18FC 88#define PCIE_REG_CONTROL 0x1A00 89#define PCIE_CTRL_LINK1X 0x00000001 90#define PCIE_REG_STATUS 0x1A04 91#define PCIE_REG_IRQ_MASK 0x1910 92 --- 29 unchanged lines hidden (view full) --- 122 (PCI_MIN_IO_ALLOC * BITS_PER_UINT32)]; 123 int sc_io_win_attr; 124 125 struct resource *sc_res; 126 bus_space_handle_t sc_bsh; 127 bus_space_tag_t sc_bst; 128 int sc_rid; 129 | 92 93#define PCIE_REG_CFG_ADDR 0x18F8 94#define PCIE_REG_CFG_DATA 0x18FC 95#define PCIE_REG_CONTROL 0x1A00 96#define PCIE_CTRL_LINK1X 0x00000001 97#define PCIE_REG_STATUS 0x1A04 98#define PCIE_REG_IRQ_MASK 0x1910 99 --- 29 unchanged lines hidden (view full) --- 129 (PCI_MIN_IO_ALLOC * BITS_PER_UINT32)]; 130 int sc_io_win_attr; 131 132 struct resource *sc_res; 133 bus_space_handle_t sc_bsh; 134 bus_space_tag_t sc_bst; 135 int sc_rid; 136 |
137 struct mtx sc_msi_mtx; 138 uint32_t sc_msi_bitmap; 139 |
|
130 int sc_busnr; /* Host bridge bus number */ 131 int sc_devnr; /* Host bridge device number */ 132 int sc_type; 133 int sc_mode; /* Endpoint / Root Complex */ 134 135 struct fdt_pci_intr sc_intr_info; 136}; 137 --- 23 unchanged lines hidden (view full) --- 161static int mv_pcib_read_ivar(device_t, device_t, int, uintptr_t *); 162static int mv_pcib_write_ivar(device_t, device_t, int, uintptr_t); 163 164static int mv_pcib_maxslots(device_t); 165static uint32_t mv_pcib_read_config(device_t, u_int, u_int, u_int, u_int, int); 166static void mv_pcib_write_config(device_t, u_int, u_int, u_int, u_int, 167 uint32_t, int); 168static int mv_pcib_route_interrupt(device_t, device_t, int); | 140 int sc_busnr; /* Host bridge bus number */ 141 int sc_devnr; /* Host bridge device number */ 142 int sc_type; 143 int sc_mode; /* Endpoint / Root Complex */ 144 145 struct fdt_pci_intr sc_intr_info; 146}; 147 --- 23 unchanged lines hidden (view full) --- 171static int mv_pcib_read_ivar(device_t, device_t, int, uintptr_t *); 172static int mv_pcib_write_ivar(device_t, device_t, int, uintptr_t); 173 174static int mv_pcib_maxslots(device_t); 175static uint32_t mv_pcib_read_config(device_t, u_int, u_int, u_int, u_int, int); 176static void mv_pcib_write_config(device_t, u_int, u_int, u_int, u_int, 177 uint32_t, int); 178static int mv_pcib_route_interrupt(device_t, device_t, int); |
179#if defined(SOC_MV_ARMADAXP) 180static int mv_pcib_alloc_msi(device_t, device_t, int, int, int *); 181static int mv_pcib_map_msi(device_t, device_t, int, uint64_t *, uint32_t *); 182static int mv_pcib_release_msi(device_t, device_t, int, int *); 183#endif |
|
169 170/* 171 * Bus interface definitions. 172 */ 173static device_method_t mv_pcib_methods[] = { 174 /* Device interface */ 175 DEVMETHOD(device_probe, mv_pcib_probe), 176 DEVMETHOD(device_attach, mv_pcib_attach), --- 8 unchanged lines hidden (view full) --- 185 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 186 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 187 188 /* pcib interface */ 189 DEVMETHOD(pcib_maxslots, mv_pcib_maxslots), 190 DEVMETHOD(pcib_read_config, mv_pcib_read_config), 191 DEVMETHOD(pcib_write_config, mv_pcib_write_config), 192 DEVMETHOD(pcib_route_interrupt, mv_pcib_route_interrupt), | 184 185/* 186 * Bus interface definitions. 187 */ 188static device_method_t mv_pcib_methods[] = { 189 /* Device interface */ 190 DEVMETHOD(device_probe, mv_pcib_probe), 191 DEVMETHOD(device_attach, mv_pcib_attach), --- 8 unchanged lines hidden (view full) --- 200 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 201 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 202 203 /* pcib interface */ 204 DEVMETHOD(pcib_maxslots, mv_pcib_maxslots), 205 DEVMETHOD(pcib_read_config, mv_pcib_read_config), 206 DEVMETHOD(pcib_write_config, mv_pcib_write_config), 207 DEVMETHOD(pcib_route_interrupt, mv_pcib_route_interrupt), |
193 | 208 209#if defined(SOC_MV_ARMADAXP) 210 DEVMETHOD(pcib_alloc_msi, mv_pcib_alloc_msi), 211 DEVMETHOD(pcib_release_msi, mv_pcib_release_msi), 212 DEVMETHOD(pcib_map_msi, mv_pcib_map_msi), 213#endif 214 |
194 /* OFW bus interface */ 195 DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), 196 DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), 197 DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), 198 DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), 199 DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), 200 201 DEVMETHOD_END --- 111 unchanged lines hidden (view full) --- 313 device_add_child(self, "pci", -1); 314 } else { 315 sc->sc_devnr = 1; 316 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 317 PCIE_REG_STATUS, 1 << PCIE_STATUS_DEV_OFFS); 318 device_add_child(self, "pci_ep", -1); 319 } 320 | 215 /* OFW bus interface */ 216 DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), 217 DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), 218 DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), 219 DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), 220 DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), 221 222 DEVMETHOD_END --- 111 unchanged lines hidden (view full) --- 334 device_add_child(self, "pci", -1); 335 } else { 336 sc->sc_devnr = 1; 337 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 338 PCIE_REG_STATUS, 1 << PCIE_STATUS_DEV_OFFS); 339 device_add_child(self, "pci_ep", -1); 340 } 341 |
342 mtx_init(&sc->sc_msi_mtx, "msi_mtx", NULL, MTX_DEF); |
|
321 return (bus_generic_attach(self)); 322 323error: 324 /* XXX SYS_RES_ should be released here */ 325 rman_fini(&sc->sc_mem_rman); 326 rman_fini(&sc->sc_io_rman); 327 328 return (err); --- 593 unchanged lines hidden (view full) --- 922 int error; 923 924 if ((error = fdt_pci_intr_info(node, &sc->sc_intr_info)) != 0) 925 return (error); 926 927 return (0); 928} 929 | 343 return (bus_generic_attach(self)); 344 345error: 346 /* XXX SYS_RES_ should be released here */ 347 rman_fini(&sc->sc_mem_rman); 348 rman_fini(&sc->sc_io_rman); 349 350 return (err); --- 593 unchanged lines hidden (view full) --- 944 int error; 945 946 if ((error = fdt_pci_intr_info(node, &sc->sc_intr_info)) != 0) 947 return (error); 948 949 return (0); 950} 951 |
952#if defined(SOC_MV_ARMADAXP) 953static int 954mv_pcib_map_msi(device_t dev, device_t child, int irq, uint64_t *addr, 955 uint32_t *data) 956{ 957 struct mv_pcib_softc *sc; 958 959 sc = device_get_softc(dev); 960 irq = irq - MSI_IRQ; 961 962 /* validate parameters */ 963 if (isclr(&sc->sc_msi_bitmap, irq)) { 964 device_printf(dev, "invalid MSI 0x%x\n", irq); 965 return (EINVAL); 966 } 967 968 mv_msi_data(irq, addr, data); 969 970 debugf("%s: irq: %d addr: %jx data: %x\n", 971 __func__, irq, *addr, *data); 972 973 return (0); 974} 975 976static int 977mv_pcib_alloc_msi(device_t dev, device_t child, int count, 978 int maxcount __unused, int *irqs) 979{ 980 struct mv_pcib_softc *sc; 981 u_int start = 0, i; 982 983 if (powerof2(count) == 0 || count > MSI_IRQ_NUM) 984 return (EINVAL); 985 986 sc = device_get_softc(dev); 987 mtx_lock(&sc->sc_msi_mtx); 988 989 for (start = 0; (start + count) < MSI_IRQ_NUM; start++) { 990 for (i = start; i < start + count; i++) { 991 if (isset(&sc->sc_msi_bitmap, i)) 992 break; 993 } 994 if (i == start + count) 995 break; 996 } 997 998 if ((start + count) == MSI_IRQ_NUM) { 999 mtx_unlock(&sc->sc_msi_mtx); 1000 return (ENXIO); 1001 } 1002 1003 for (i = start; i < start + count; i++) { 1004 setbit(&sc->sc_msi_bitmap, i); 1005 irqs[i] = MSI_IRQ + i; 1006 } 1007 debugf("%s: start: %x count: %x\n", __func__, start, count); 1008 1009 mtx_unlock(&sc->sc_msi_mtx); 1010 return (0); 1011} 1012 1013static int 1014mv_pcib_release_msi(device_t dev, device_t child, int count, int *irqs) 1015{ 1016 struct mv_pcib_softc *sc; 1017 u_int i; 1018 1019 sc = device_get_softc(dev); 1020 mtx_lock(&sc->sc_msi_mtx); 1021 1022 for (i = 0; i < count; i++) 1023 clrbit(&sc->sc_msi_bitmap, irqs[i] - MSI_IRQ); 1024 1025 mtx_unlock(&sc->sc_msi_mtx); 1026 return (0); 1027} 1028#endif |
|