16975124cSRafal Jaworowski /*- 2*db5ef4fcSRafal Jaworowski * Copyright (c) 2008 MARVELL INTERNATIONAL LTD. 3*db5ef4fcSRafal Jaworowski * Copyright (c) 2010 The FreeBSD Foundation 46975124cSRafal Jaworowski * All rights reserved. 56975124cSRafal Jaworowski * 66975124cSRafal Jaworowski * Developed by Semihalf. 76975124cSRafal Jaworowski * 8*db5ef4fcSRafal Jaworowski * Portions of this software were developed by Semihalf 9*db5ef4fcSRafal Jaworowski * under sponsorship from the FreeBSD Foundation. 10*db5ef4fcSRafal Jaworowski * 116975124cSRafal Jaworowski * Redistribution and use in source and binary forms, with or without 126975124cSRafal Jaworowski * modification, are permitted provided that the following conditions 136975124cSRafal Jaworowski * are met: 146975124cSRafal Jaworowski * 1. Redistributions of source code must retain the above copyright 156975124cSRafal Jaworowski * notice, this list of conditions and the following disclaimer. 166975124cSRafal Jaworowski * 2. Redistributions in binary form must reproduce the above copyright 176975124cSRafal Jaworowski * notice, this list of conditions and the following disclaimer in the 186975124cSRafal Jaworowski * documentation and/or other materials provided with the distribution. 196975124cSRafal Jaworowski * 3. Neither the name of MARVELL nor the names of contributors 206975124cSRafal Jaworowski * may be used to endorse or promote products derived from this software 216975124cSRafal Jaworowski * without specific prior written permission. 226975124cSRafal Jaworowski * 236975124cSRafal Jaworowski * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 246975124cSRafal Jaworowski * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 256975124cSRafal Jaworowski * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 266975124cSRafal Jaworowski * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 276975124cSRafal Jaworowski * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 286975124cSRafal Jaworowski * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 296975124cSRafal Jaworowski * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 306975124cSRafal Jaworowski * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 316975124cSRafal Jaworowski * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 326975124cSRafal Jaworowski * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 336975124cSRafal Jaworowski * SUCH DAMAGE. 346975124cSRafal Jaworowski */ 356975124cSRafal Jaworowski 366975124cSRafal Jaworowski /* 376975124cSRafal Jaworowski * Marvell integrated PCI/PCI-Express controller driver. 386975124cSRafal Jaworowski */ 396975124cSRafal Jaworowski 406975124cSRafal Jaworowski #include <sys/cdefs.h> 416975124cSRafal Jaworowski __FBSDID("$FreeBSD$"); 426975124cSRafal Jaworowski 436975124cSRafal Jaworowski #include <sys/param.h> 446975124cSRafal Jaworowski #include <sys/systm.h> 456975124cSRafal Jaworowski #include <sys/kernel.h> 466975124cSRafal Jaworowski #include <sys/lock.h> 476975124cSRafal Jaworowski #include <sys/malloc.h> 486975124cSRafal Jaworowski #include <sys/module.h> 496975124cSRafal Jaworowski #include <sys/mutex.h> 506975124cSRafal Jaworowski #include <sys/queue.h> 516975124cSRafal Jaworowski #include <sys/bus.h> 526975124cSRafal Jaworowski #include <sys/rman.h> 536975124cSRafal Jaworowski #include <sys/endian.h> 546975124cSRafal Jaworowski 556975124cSRafal Jaworowski #include <vm/vm.h> 566975124cSRafal Jaworowski #include <vm/pmap.h> 576975124cSRafal Jaworowski 58*db5ef4fcSRafal Jaworowski #include <dev/fdt/fdt_common.h> 59*db5ef4fcSRafal Jaworowski #include <dev/ofw/ofw_bus.h> 60*db5ef4fcSRafal Jaworowski #include <dev/ofw/ofw_bus_subr.h> 616975124cSRafal Jaworowski #include <dev/pci/pcivar.h> 626975124cSRafal Jaworowski #include <dev/pci/pcireg.h> 636975124cSRafal Jaworowski #include <dev/pci/pcib_private.h> 646975124cSRafal Jaworowski 65*db5ef4fcSRafal Jaworowski #include "ofw_bus_if.h" 666975124cSRafal Jaworowski #include "pcib_if.h" 676975124cSRafal Jaworowski 686975124cSRafal Jaworowski #include <machine/resource.h> 696975124cSRafal Jaworowski #include <machine/bus.h> 706975124cSRafal Jaworowski 716975124cSRafal Jaworowski #include <arm/mv/mvreg.h> 726975124cSRafal Jaworowski #include <arm/mv/mvvar.h> 73*db5ef4fcSRafal Jaworowski #include <arm/mv/mvwin.h> 746975124cSRafal Jaworowski 756975124cSRafal Jaworowski #define PCI_CFG_ENA (1 << 31) 766975124cSRafal Jaworowski #define PCI_CFG_BUS(bus) (((bus) & 0xff) << 16) 776975124cSRafal Jaworowski #define PCI_CFG_DEV(dev) (((dev) & 0x1f) << 11) 786975124cSRafal Jaworowski #define PCI_CFG_FUN(fun) (((fun) & 0x7) << 8) 796975124cSRafal Jaworowski #define PCI_CFG_PCIE_REG(reg) ((reg) & 0xfc) 806975124cSRafal Jaworowski 816975124cSRafal Jaworowski #define PCI_REG_CFG_ADDR 0x0C78 826975124cSRafal Jaworowski #define PCI_REG_CFG_DATA 0x0C7C 836975124cSRafal Jaworowski #define PCI_REG_P2P_CONF 0x1D14 846975124cSRafal Jaworowski 856975124cSRafal Jaworowski #define PCIE_REG_CFG_ADDR 0x18F8 866975124cSRafal Jaworowski #define PCIE_REG_CFG_DATA 0x18FC 876975124cSRafal Jaworowski #define PCIE_REG_CONTROL 0x1A00 886975124cSRafal Jaworowski #define PCIE_CTRL_LINK1X 0x00000001 896975124cSRafal Jaworowski #define PCIE_REG_STATUS 0x1A04 906975124cSRafal Jaworowski #define PCIE_REG_IRQ_MASK 0x1910 916975124cSRafal Jaworowski 924e883c81SRafal Jaworowski #define STATUS_LINK_DOWN 1 936975124cSRafal Jaworowski #define STATUS_BUS_OFFS 8 946975124cSRafal Jaworowski #define STATUS_BUS_MASK (0xFF << STATUS_BUS_OFFS) 956975124cSRafal Jaworowski #define STATUS_DEV_OFFS 16 966975124cSRafal Jaworowski #define STATUS_DEV_MASK (0x1F << STATUS_DEV_OFFS) 976975124cSRafal Jaworowski 986975124cSRafal Jaworowski #define P2P_CONF_BUS_OFFS 16 996975124cSRafal Jaworowski #define P2P_CONF_BUS_MASK (0xFF << P2P_CONF_BUS_OFFS) 1006975124cSRafal Jaworowski #define P2P_CONF_DEV_OFFS 24 1016975124cSRafal Jaworowski #define P2P_CONF_DEV_MASK (0x1F << P2P_CONF_DEV_OFFS) 1026975124cSRafal Jaworowski 1036975124cSRafal Jaworowski #define PCI_VENDORID_MRVL 0x11AB 1046975124cSRafal Jaworowski 105*db5ef4fcSRafal Jaworowski struct mv_pcib_softc { 1066975124cSRafal Jaworowski device_t sc_dev; 1076975124cSRafal Jaworowski 108*db5ef4fcSRafal Jaworowski struct rman sc_mem_rman; 109*db5ef4fcSRafal Jaworowski bus_addr_t sc_mem_base; 110*db5ef4fcSRafal Jaworowski bus_addr_t sc_mem_size; 111*db5ef4fcSRafal Jaworowski bus_addr_t sc_mem_alloc; /* Next allocation. */ 112*db5ef4fcSRafal Jaworowski int sc_mem_win_target; 113*db5ef4fcSRafal Jaworowski int sc_mem_win_attr; 1146975124cSRafal Jaworowski 115*db5ef4fcSRafal Jaworowski struct rman sc_io_rman; 116*db5ef4fcSRafal Jaworowski bus_addr_t sc_io_base; 117*db5ef4fcSRafal Jaworowski bus_addr_t sc_io_size; 118*db5ef4fcSRafal Jaworowski bus_addr_t sc_io_alloc; /* Next allocation. */ 119*db5ef4fcSRafal Jaworowski int sc_io_win_target; 120*db5ef4fcSRafal Jaworowski int sc_io_win_attr; 1216975124cSRafal Jaworowski 1226975124cSRafal Jaworowski struct resource *sc_res; 1236975124cSRafal Jaworowski bus_space_handle_t sc_bsh; 1246975124cSRafal Jaworowski bus_space_tag_t sc_bst; 1256975124cSRafal Jaworowski int sc_rid; 1266975124cSRafal Jaworowski 1276975124cSRafal Jaworowski int sc_busnr; /* Host bridge bus number */ 1286975124cSRafal Jaworowski int sc_devnr; /* Host bridge device number */ 129*db5ef4fcSRafal Jaworowski int sc_type; 1306975124cSRafal Jaworowski 131*db5ef4fcSRafal Jaworowski struct fdt_pci_intr sc_intr_info; 1326975124cSRafal Jaworowski }; 1336975124cSRafal Jaworowski 134*db5ef4fcSRafal Jaworowski /* Local forward prototypes */ 135*db5ef4fcSRafal Jaworowski static int mv_pcib_decode_win(phandle_t, struct mv_pcib_softc *); 136*db5ef4fcSRafal Jaworowski static void mv_pcib_hw_cfginit(void); 137*db5ef4fcSRafal Jaworowski static uint32_t mv_pcib_hw_cfgread(struct mv_pcib_softc *, u_int, u_int, 138*db5ef4fcSRafal Jaworowski u_int, u_int, int); 139*db5ef4fcSRafal Jaworowski static void mv_pcib_hw_cfgwrite(struct mv_pcib_softc *, u_int, u_int, 140*db5ef4fcSRafal Jaworowski u_int, u_int, uint32_t, int); 141*db5ef4fcSRafal Jaworowski static int mv_pcib_init(struct mv_pcib_softc *, int, int); 142*db5ef4fcSRafal Jaworowski static int mv_pcib_init_all_bars(struct mv_pcib_softc *, int, int, int, int); 143*db5ef4fcSRafal Jaworowski static void mv_pcib_init_bridge(struct mv_pcib_softc *, int, int, int); 144*db5ef4fcSRafal Jaworowski static int mv_pcib_intr_info(phandle_t, struct mv_pcib_softc *); 145*db5ef4fcSRafal Jaworowski static inline void pcib_write_irq_mask(struct mv_pcib_softc *, uint32_t); 1466975124cSRafal Jaworowski 147*db5ef4fcSRafal Jaworowski 148*db5ef4fcSRafal Jaworowski /* Forward prototypes */ 149*db5ef4fcSRafal Jaworowski static int mv_pcib_probe(device_t); 150*db5ef4fcSRafal Jaworowski static int mv_pcib_attach(device_t); 151*db5ef4fcSRafal Jaworowski 152*db5ef4fcSRafal Jaworowski static struct resource *mv_pcib_alloc_resource(device_t, device_t, int, int *, 1536975124cSRafal Jaworowski u_long, u_long, u_long, u_int); 154*db5ef4fcSRafal Jaworowski static int mv_pcib_release_resource(device_t, device_t, int, int, 1556975124cSRafal Jaworowski struct resource *); 156*db5ef4fcSRafal Jaworowski static int mv_pcib_read_ivar(device_t, device_t, int, uintptr_t *); 157*db5ef4fcSRafal Jaworowski static int mv_pcib_write_ivar(device_t, device_t, int, uintptr_t); 1586975124cSRafal Jaworowski 159*db5ef4fcSRafal Jaworowski static int mv_pcib_maxslots(device_t); 160*db5ef4fcSRafal Jaworowski static uint32_t mv_pcib_read_config(device_t, u_int, u_int, u_int, u_int, int); 161*db5ef4fcSRafal Jaworowski static void mv_pcib_write_config(device_t, u_int, u_int, u_int, u_int, 1626975124cSRafal Jaworowski uint32_t, int); 163*db5ef4fcSRafal Jaworowski static int mv_pcib_route_interrupt(device_t, device_t, int); 1646975124cSRafal Jaworowski 1656975124cSRafal Jaworowski /* 1666975124cSRafal Jaworowski * Bus interface definitions. 1676975124cSRafal Jaworowski */ 168*db5ef4fcSRafal Jaworowski static device_method_t mv_pcib_methods[] = { 1696975124cSRafal Jaworowski /* Device interface */ 170*db5ef4fcSRafal Jaworowski DEVMETHOD(device_probe, mv_pcib_probe), 171*db5ef4fcSRafal Jaworowski DEVMETHOD(device_attach, mv_pcib_attach), 1726975124cSRafal Jaworowski 1736975124cSRafal Jaworowski /* Bus interface */ 1746975124cSRafal Jaworowski DEVMETHOD(bus_print_child, bus_generic_print_child), 175*db5ef4fcSRafal Jaworowski DEVMETHOD(bus_read_ivar, mv_pcib_read_ivar), 176*db5ef4fcSRafal Jaworowski DEVMETHOD(bus_write_ivar, mv_pcib_write_ivar), 177*db5ef4fcSRafal Jaworowski DEVMETHOD(bus_alloc_resource, mv_pcib_alloc_resource), 178*db5ef4fcSRafal Jaworowski DEVMETHOD(bus_release_resource, mv_pcib_release_resource), 1796975124cSRafal Jaworowski DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 1806975124cSRafal Jaworowski DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 1816975124cSRafal Jaworowski DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 1826975124cSRafal Jaworowski DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 1836975124cSRafal Jaworowski 1846975124cSRafal Jaworowski /* pcib interface */ 185*db5ef4fcSRafal Jaworowski DEVMETHOD(pcib_maxslots, mv_pcib_maxslots), 186*db5ef4fcSRafal Jaworowski DEVMETHOD(pcib_read_config, mv_pcib_read_config), 187*db5ef4fcSRafal Jaworowski DEVMETHOD(pcib_write_config, mv_pcib_write_config), 188*db5ef4fcSRafal Jaworowski DEVMETHOD(pcib_route_interrupt, mv_pcib_route_interrupt), 189*db5ef4fcSRafal Jaworowski 190*db5ef4fcSRafal Jaworowski /* OFW bus interface */ 191*db5ef4fcSRafal Jaworowski DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), 192*db5ef4fcSRafal Jaworowski DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), 193*db5ef4fcSRafal Jaworowski DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), 194*db5ef4fcSRafal Jaworowski DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), 195*db5ef4fcSRafal Jaworowski DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), 1966975124cSRafal Jaworowski 1976975124cSRafal Jaworowski { 0, 0 } 1986975124cSRafal Jaworowski }; 1996975124cSRafal Jaworowski 200*db5ef4fcSRafal Jaworowski static driver_t mv_pcib_driver = { 2016975124cSRafal Jaworowski "pcib", 202*db5ef4fcSRafal Jaworowski mv_pcib_methods, 203*db5ef4fcSRafal Jaworowski sizeof(struct mv_pcib_softc), 2046975124cSRafal Jaworowski }; 2056975124cSRafal Jaworowski 2066975124cSRafal Jaworowski devclass_t pcib_devclass; 2076975124cSRafal Jaworowski 208*db5ef4fcSRafal Jaworowski DRIVER_MODULE(pcib, fdtbus, mv_pcib_driver, pcib_devclass, 0, 0); 2096975124cSRafal Jaworowski 2106975124cSRafal Jaworowski static struct mtx pcicfg_mtx; 2116975124cSRafal Jaworowski 212*db5ef4fcSRafal Jaworowski static int 213*db5ef4fcSRafal Jaworowski mv_pcib_probe(device_t self) 2146975124cSRafal Jaworowski { 215*db5ef4fcSRafal Jaworowski phandle_t parnode; 2166975124cSRafal Jaworowski 217*db5ef4fcSRafal Jaworowski /* 218*db5ef4fcSRafal Jaworowski * The PCI subnode does not have the 'compatible' property, so we need 219*db5ef4fcSRafal Jaworowski * to check in the parent PCI node. However the parent is not 220*db5ef4fcSRafal Jaworowski * represented by a separate ofw_bus child, and therefore 221*db5ef4fcSRafal Jaworowski * ofw_bus_is_compatible() cannot be used, but direct fdt equivalent. 222*db5ef4fcSRafal Jaworowski */ 223*db5ef4fcSRafal Jaworowski parnode = OF_parent(ofw_bus_get_node(self)); 224*db5ef4fcSRafal Jaworowski if (parnode == 0) 225*db5ef4fcSRafal Jaworowski return (ENXIO); 226*db5ef4fcSRafal Jaworowski if (!(fdt_is_compatible(parnode, "mrvl,pcie") || 227*db5ef4fcSRafal Jaworowski fdt_is_compatible(parnode, "mrvl,pci"))) 228*db5ef4fcSRafal Jaworowski return (ENXIO); 2296975124cSRafal Jaworowski 230*db5ef4fcSRafal Jaworowski device_set_desc(self, "Marvell Integrated PCI/PCI-E Controller"); 231*db5ef4fcSRafal Jaworowski 232*db5ef4fcSRafal Jaworowski return (BUS_PROBE_DEFAULT); 233*db5ef4fcSRafal Jaworowski } 234*db5ef4fcSRafal Jaworowski 235*db5ef4fcSRafal Jaworowski static int 236*db5ef4fcSRafal Jaworowski mv_pcib_attach(device_t self) 237*db5ef4fcSRafal Jaworowski { 238*db5ef4fcSRafal Jaworowski struct mv_pcib_softc *sc; 239*db5ef4fcSRafal Jaworowski phandle_t node, parnode; 240*db5ef4fcSRafal Jaworowski uint32_t val; 241*db5ef4fcSRafal Jaworowski int err; 242*db5ef4fcSRafal Jaworowski 243*db5ef4fcSRafal Jaworowski sc = device_get_softc(self); 244*db5ef4fcSRafal Jaworowski sc->sc_dev = self; 245*db5ef4fcSRafal Jaworowski 246*db5ef4fcSRafal Jaworowski parnode = OF_parent(ofw_bus_get_node(self)); 247*db5ef4fcSRafal Jaworowski if (fdt_is_compatible(parnode, "mrvl,pcie")) { 248*db5ef4fcSRafal Jaworowski sc->sc_type = MV_TYPE_PCIE; 249*db5ef4fcSRafal Jaworowski sc->sc_mem_win_target = MV_WIN_PCIE_MEM_TARGET; 250*db5ef4fcSRafal Jaworowski sc->sc_mem_win_attr = MV_WIN_PCIE_MEM_ATTR; 251*db5ef4fcSRafal Jaworowski sc->sc_io_win_target = MV_WIN_PCIE_IO_TARGET; 252*db5ef4fcSRafal Jaworowski sc->sc_io_win_attr = MV_WIN_PCIE_IO_ATTR; 253*db5ef4fcSRafal Jaworowski #ifdef SOC_MV_ORION 254*db5ef4fcSRafal Jaworowski } else if (fdt_is_compatible(parnode, "mrvl,pci")) { 255*db5ef4fcSRafal Jaworowski sc->sc_type = MV_TYPE_PCI; 256*db5ef4fcSRafal Jaworowski sc->sc_mem_win_target = MV_WIN_PCI_MEM_TARGET; 257*db5ef4fcSRafal Jaworowski sc->sc_mem_win_attr = MV_WIN_PCI_MEM_ATTR; 258*db5ef4fcSRafal Jaworowski sc->sc_io_win_target = MV_WIN_PCI_IO_TARGET; 259*db5ef4fcSRafal Jaworowski sc->sc_io_win_attr = MV_WIN_PCI_IO_ATTR; 260*db5ef4fcSRafal Jaworowski #endif 261*db5ef4fcSRafal Jaworowski } else 262*db5ef4fcSRafal Jaworowski return (ENXIO); 263*db5ef4fcSRafal Jaworowski 264*db5ef4fcSRafal Jaworowski node = ofw_bus_get_node(self); 265*db5ef4fcSRafal Jaworowski 266*db5ef4fcSRafal Jaworowski /* 267*db5ef4fcSRafal Jaworowski * Get PCI interrupt info. 268*db5ef4fcSRafal Jaworowski */ 269*db5ef4fcSRafal Jaworowski if (mv_pcib_intr_info(node, sc) != 0) { 270*db5ef4fcSRafal Jaworowski device_printf(self, "could not retrieve interrupt info\n"); 271*db5ef4fcSRafal Jaworowski return (ENXIO); 272*db5ef4fcSRafal Jaworowski } 273*db5ef4fcSRafal Jaworowski 274*db5ef4fcSRafal Jaworowski /* 275*db5ef4fcSRafal Jaworowski * Retrieve our mem-mapped registers range. 276*db5ef4fcSRafal Jaworowski */ 277*db5ef4fcSRafal Jaworowski sc->sc_rid = 0; 278*db5ef4fcSRafal Jaworowski sc->sc_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &sc->sc_rid, 279*db5ef4fcSRafal Jaworowski RF_ACTIVE); 280*db5ef4fcSRafal Jaworowski if (sc->sc_res == NULL) { 281*db5ef4fcSRafal Jaworowski device_printf(self, "could not map memory\n"); 282*db5ef4fcSRafal Jaworowski return (ENXIO); 283*db5ef4fcSRafal Jaworowski } 284*db5ef4fcSRafal Jaworowski sc->sc_bst = rman_get_bustag(sc->sc_res); 285*db5ef4fcSRafal Jaworowski sc->sc_bsh = rman_get_bushandle(sc->sc_res); 286*db5ef4fcSRafal Jaworowski 287*db5ef4fcSRafal Jaworowski /* 288*db5ef4fcSRafal Jaworowski * Configure decode windows for PCI(E) access. 289*db5ef4fcSRafal Jaworowski */ 290*db5ef4fcSRafal Jaworowski if (mv_pcib_decode_win(node, sc) != 0) 291*db5ef4fcSRafal Jaworowski return (ENXIO); 292*db5ef4fcSRafal Jaworowski 293*db5ef4fcSRafal Jaworowski mv_pcib_hw_cfginit(); 294*db5ef4fcSRafal Jaworowski 295*db5ef4fcSRafal Jaworowski /* 296*db5ef4fcSRafal Jaworowski * Enable PCI bridge. 297*db5ef4fcSRafal Jaworowski */ 298*db5ef4fcSRafal Jaworowski val = mv_pcib_hw_cfgread(sc, sc->sc_busnr, sc->sc_devnr, 0, 299*db5ef4fcSRafal Jaworowski PCIR_COMMAND, 2); 300*db5ef4fcSRafal Jaworowski val |= PCIM_CMD_SERRESPEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN | 301*db5ef4fcSRafal Jaworowski PCIM_CMD_PORTEN; 302*db5ef4fcSRafal Jaworowski mv_pcib_hw_cfgwrite(sc, sc->sc_busnr, sc->sc_devnr, 0, 303*db5ef4fcSRafal Jaworowski PCIR_COMMAND, val, 2); 304*db5ef4fcSRafal Jaworowski 305*db5ef4fcSRafal Jaworowski sc->sc_mem_alloc = sc->sc_mem_base; 306*db5ef4fcSRafal Jaworowski sc->sc_io_alloc = sc->sc_io_base; 307*db5ef4fcSRafal Jaworowski 308*db5ef4fcSRafal Jaworowski sc->sc_mem_rman.rm_type = RMAN_ARRAY; 309*db5ef4fcSRafal Jaworowski err = rman_init(&sc->sc_mem_rman); 310*db5ef4fcSRafal Jaworowski if (err) 311*db5ef4fcSRafal Jaworowski return (err); 312*db5ef4fcSRafal Jaworowski 313*db5ef4fcSRafal Jaworowski sc->sc_io_rman.rm_type = RMAN_ARRAY; 314*db5ef4fcSRafal Jaworowski err = rman_init(&sc->sc_io_rman); 315*db5ef4fcSRafal Jaworowski if (err) { 316*db5ef4fcSRafal Jaworowski rman_fini(&sc->sc_mem_rman); 317*db5ef4fcSRafal Jaworowski return (err); 318*db5ef4fcSRafal Jaworowski } 319*db5ef4fcSRafal Jaworowski 320*db5ef4fcSRafal Jaworowski err = rman_manage_region(&sc->sc_mem_rman, sc->sc_mem_base, 321*db5ef4fcSRafal Jaworowski sc->sc_mem_base + sc->sc_mem_size - 1); 322*db5ef4fcSRafal Jaworowski if (err) 323*db5ef4fcSRafal Jaworowski goto error; 324*db5ef4fcSRafal Jaworowski 325*db5ef4fcSRafal Jaworowski err = rman_manage_region(&sc->sc_io_rman, sc->sc_io_base, 326*db5ef4fcSRafal Jaworowski sc->sc_io_base + sc->sc_io_size - 1); 327*db5ef4fcSRafal Jaworowski if (err) 328*db5ef4fcSRafal Jaworowski goto error; 329*db5ef4fcSRafal Jaworowski 330*db5ef4fcSRafal Jaworowski err = mv_pcib_init(sc, sc->sc_busnr, mv_pcib_maxslots(sc->sc_dev)); 331*db5ef4fcSRafal Jaworowski if (err) 332*db5ef4fcSRafal Jaworowski goto error; 333*db5ef4fcSRafal Jaworowski 334*db5ef4fcSRafal Jaworowski device_add_child(self, "pci", -1); 335*db5ef4fcSRafal Jaworowski return (bus_generic_attach(self)); 336*db5ef4fcSRafal Jaworowski 337*db5ef4fcSRafal Jaworowski error: 338*db5ef4fcSRafal Jaworowski /* XXX SYS_RES_ should be released here */ 339*db5ef4fcSRafal Jaworowski rman_fini(&sc->sc_mem_rman); 340*db5ef4fcSRafal Jaworowski rman_fini(&sc->sc_io_rman); 341*db5ef4fcSRafal Jaworowski return (err); 342*db5ef4fcSRafal Jaworowski } 343*db5ef4fcSRafal Jaworowski 344*db5ef4fcSRafal Jaworowski static int 345*db5ef4fcSRafal Jaworowski mv_pcib_init_bar(struct mv_pcib_softc *sc, int bus, int slot, int func, 346*db5ef4fcSRafal Jaworowski int barno) 347*db5ef4fcSRafal Jaworowski { 348*db5ef4fcSRafal Jaworowski bus_addr_t *allocp, limit; 349*db5ef4fcSRafal Jaworowski uint32_t addr, bar, mask, size; 350*db5ef4fcSRafal Jaworowski int reg, width; 351*db5ef4fcSRafal Jaworowski 352*db5ef4fcSRafal Jaworowski reg = PCIR_BAR(barno); 353*db5ef4fcSRafal Jaworowski bar = mv_pcib_read_config(sc->sc_dev, bus, slot, func, reg, 4); 354*db5ef4fcSRafal Jaworowski if (bar == 0) 355*db5ef4fcSRafal Jaworowski return (1); 356*db5ef4fcSRafal Jaworowski 357*db5ef4fcSRafal Jaworowski /* Calculate BAR size: 64 or 32 bit (in 32-bit units) */ 358*db5ef4fcSRafal Jaworowski width = ((bar & 7) == 4) ? 2 : 1; 359*db5ef4fcSRafal Jaworowski 360*db5ef4fcSRafal Jaworowski mv_pcib_write_config(sc->sc_dev, bus, slot, func, reg, ~0, 4); 361*db5ef4fcSRafal Jaworowski size = mv_pcib_read_config(sc->sc_dev, bus, slot, func, reg, 4); 362*db5ef4fcSRafal Jaworowski 363*db5ef4fcSRafal Jaworowski /* Get BAR type and size */ 364*db5ef4fcSRafal Jaworowski if (bar & 1) { 365*db5ef4fcSRafal Jaworowski /* I/O port */ 366*db5ef4fcSRafal Jaworowski allocp = &sc->sc_io_alloc; 367*db5ef4fcSRafal Jaworowski limit = sc->sc_io_base + sc->sc_io_size; 368*db5ef4fcSRafal Jaworowski size &= ~0x3; 369*db5ef4fcSRafal Jaworowski if ((size & 0xffff0000) == 0) 370*db5ef4fcSRafal Jaworowski size |= 0xffff0000; 371*db5ef4fcSRafal Jaworowski } else { 372*db5ef4fcSRafal Jaworowski /* Memory */ 373*db5ef4fcSRafal Jaworowski allocp = &sc->sc_mem_alloc; 374*db5ef4fcSRafal Jaworowski limit = sc->sc_mem_base + sc->sc_mem_size; 375*db5ef4fcSRafal Jaworowski size &= ~0xF; 376*db5ef4fcSRafal Jaworowski } 377*db5ef4fcSRafal Jaworowski mask = ~size; 378*db5ef4fcSRafal Jaworowski size = mask + 1; 379*db5ef4fcSRafal Jaworowski 380*db5ef4fcSRafal Jaworowski /* Sanity check (must be a power of 2) */ 381*db5ef4fcSRafal Jaworowski if (size & mask) 382*db5ef4fcSRafal Jaworowski return (width); 383*db5ef4fcSRafal Jaworowski 384*db5ef4fcSRafal Jaworowski addr = (*allocp + mask) & ~mask; 385*db5ef4fcSRafal Jaworowski if ((*allocp = addr + size) > limit) 386*db5ef4fcSRafal Jaworowski return (-1); 387*db5ef4fcSRafal Jaworowski 388*db5ef4fcSRafal Jaworowski if (bootverbose) 389*db5ef4fcSRafal Jaworowski printf("PCI %u:%u:%u: reg %x: size=%08x: addr=%08x\n", 390*db5ef4fcSRafal Jaworowski bus, slot, func, reg, size, addr); 391*db5ef4fcSRafal Jaworowski 392*db5ef4fcSRafal Jaworowski mv_pcib_write_config(sc->sc_dev, bus, slot, func, reg, addr, 4); 393*db5ef4fcSRafal Jaworowski if (width == 2) 394*db5ef4fcSRafal Jaworowski mv_pcib_write_config(sc->sc_dev, bus, slot, func, reg + 4, 395*db5ef4fcSRafal Jaworowski 0, 4); 396*db5ef4fcSRafal Jaworowski 397*db5ef4fcSRafal Jaworowski return (width); 3986975124cSRafal Jaworowski } 3996975124cSRafal Jaworowski 4006975124cSRafal Jaworowski static void 401*db5ef4fcSRafal Jaworowski mv_pcib_init_bridge(struct mv_pcib_softc *sc, int bus, int slot, int func) 402*db5ef4fcSRafal Jaworowski { 403*db5ef4fcSRafal Jaworowski bus_addr_t io_base, mem_base; 404*db5ef4fcSRafal Jaworowski uint32_t io_limit, mem_limit; 405*db5ef4fcSRafal Jaworowski int secbus; 406*db5ef4fcSRafal Jaworowski 407*db5ef4fcSRafal Jaworowski io_base = sc->sc_io_base; 408*db5ef4fcSRafal Jaworowski io_limit = io_base + sc->sc_io_size - 1; 409*db5ef4fcSRafal Jaworowski mem_base = sc->sc_mem_base; 410*db5ef4fcSRafal Jaworowski mem_limit = mem_base + sc->sc_mem_size - 1; 411*db5ef4fcSRafal Jaworowski 412*db5ef4fcSRafal Jaworowski /* Configure I/O decode registers */ 413*db5ef4fcSRafal Jaworowski mv_pcib_write_config(sc->sc_dev, bus, slot, func, PCIR_IOBASEL_1, 414*db5ef4fcSRafal Jaworowski io_base >> 8, 1); 415*db5ef4fcSRafal Jaworowski mv_pcib_write_config(sc->sc_dev, bus, slot, func, PCIR_IOBASEH_1, 416*db5ef4fcSRafal Jaworowski io_base >> 16, 2); 417*db5ef4fcSRafal Jaworowski mv_pcib_write_config(sc->sc_dev, bus, slot, func, PCIR_IOLIMITL_1, 418*db5ef4fcSRafal Jaworowski io_limit >> 8, 1); 419*db5ef4fcSRafal Jaworowski mv_pcib_write_config(sc->sc_dev, bus, slot, func, PCIR_IOLIMITH_1, 420*db5ef4fcSRafal Jaworowski io_limit >> 16, 2); 421*db5ef4fcSRafal Jaworowski 422*db5ef4fcSRafal Jaworowski /* Configure memory decode registers */ 423*db5ef4fcSRafal Jaworowski mv_pcib_write_config(sc->sc_dev, bus, slot, func, PCIR_MEMBASE_1, 424*db5ef4fcSRafal Jaworowski mem_base >> 16, 2); 425*db5ef4fcSRafal Jaworowski mv_pcib_write_config(sc->sc_dev, bus, slot, func, PCIR_MEMLIMIT_1, 426*db5ef4fcSRafal Jaworowski mem_limit >> 16, 2); 427*db5ef4fcSRafal Jaworowski 428*db5ef4fcSRafal Jaworowski /* Disable memory prefetch decode */ 429*db5ef4fcSRafal Jaworowski mv_pcib_write_config(sc->sc_dev, bus, slot, func, PCIR_PMBASEL_1, 430*db5ef4fcSRafal Jaworowski 0x10, 2); 431*db5ef4fcSRafal Jaworowski mv_pcib_write_config(sc->sc_dev, bus, slot, func, PCIR_PMBASEH_1, 432*db5ef4fcSRafal Jaworowski 0x0, 4); 433*db5ef4fcSRafal Jaworowski mv_pcib_write_config(sc->sc_dev, bus, slot, func, PCIR_PMLIMITL_1, 434*db5ef4fcSRafal Jaworowski 0xF, 2); 435*db5ef4fcSRafal Jaworowski mv_pcib_write_config(sc->sc_dev, bus, slot, func, PCIR_PMLIMITH_1, 436*db5ef4fcSRafal Jaworowski 0x0, 4); 437*db5ef4fcSRafal Jaworowski 438*db5ef4fcSRafal Jaworowski secbus = mv_pcib_read_config(sc->sc_dev, bus, slot, func, 439*db5ef4fcSRafal Jaworowski PCIR_SECBUS_1, 1); 440*db5ef4fcSRafal Jaworowski 441*db5ef4fcSRafal Jaworowski /* Configure buses behind the bridge */ 442*db5ef4fcSRafal Jaworowski mv_pcib_init(sc, secbus, PCI_SLOTMAX); 443*db5ef4fcSRafal Jaworowski } 444*db5ef4fcSRafal Jaworowski 445*db5ef4fcSRafal Jaworowski static int 446*db5ef4fcSRafal Jaworowski mv_pcib_init(struct mv_pcib_softc *sc, int bus, int maxslot) 447*db5ef4fcSRafal Jaworowski { 448*db5ef4fcSRafal Jaworowski int slot, func, maxfunc, error; 449*db5ef4fcSRafal Jaworowski uint8_t hdrtype, command, class, subclass; 450*db5ef4fcSRafal Jaworowski 451*db5ef4fcSRafal Jaworowski for (slot = 0; slot <= maxslot; slot++) { 452*db5ef4fcSRafal Jaworowski maxfunc = 0; 453*db5ef4fcSRafal Jaworowski for (func = 0; func <= maxfunc; func++) { 454*db5ef4fcSRafal Jaworowski hdrtype = mv_pcib_read_config(sc->sc_dev, bus, slot, 455*db5ef4fcSRafal Jaworowski func, PCIR_HDRTYPE, 1); 456*db5ef4fcSRafal Jaworowski 457*db5ef4fcSRafal Jaworowski if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE) 458*db5ef4fcSRafal Jaworowski continue; 459*db5ef4fcSRafal Jaworowski 460*db5ef4fcSRafal Jaworowski if (func == 0 && (hdrtype & PCIM_MFDEV)) 461*db5ef4fcSRafal Jaworowski maxfunc = PCI_FUNCMAX; 462*db5ef4fcSRafal Jaworowski 463*db5ef4fcSRafal Jaworowski command = mv_pcib_read_config(sc->sc_dev, bus, slot, 464*db5ef4fcSRafal Jaworowski func, PCIR_COMMAND, 1); 465*db5ef4fcSRafal Jaworowski command &= ~(PCIM_CMD_MEMEN | PCIM_CMD_PORTEN); 466*db5ef4fcSRafal Jaworowski mv_pcib_write_config(sc->sc_dev, bus, slot, func, 467*db5ef4fcSRafal Jaworowski PCIR_COMMAND, command, 1); 468*db5ef4fcSRafal Jaworowski 469*db5ef4fcSRafal Jaworowski error = mv_pcib_init_all_bars(sc, bus, slot, func, 470*db5ef4fcSRafal Jaworowski hdrtype); 471*db5ef4fcSRafal Jaworowski 472*db5ef4fcSRafal Jaworowski if (error) 473*db5ef4fcSRafal Jaworowski return (error); 474*db5ef4fcSRafal Jaworowski 475*db5ef4fcSRafal Jaworowski command |= PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN | 476*db5ef4fcSRafal Jaworowski PCIM_CMD_PORTEN; 477*db5ef4fcSRafal Jaworowski mv_pcib_write_config(sc->sc_dev, bus, slot, func, 478*db5ef4fcSRafal Jaworowski PCIR_COMMAND, command, 1); 479*db5ef4fcSRafal Jaworowski 480*db5ef4fcSRafal Jaworowski /* Handle PCI-PCI bridges */ 481*db5ef4fcSRafal Jaworowski class = mv_pcib_read_config(sc->sc_dev, bus, slot, 482*db5ef4fcSRafal Jaworowski func, PCIR_CLASS, 1); 483*db5ef4fcSRafal Jaworowski subclass = mv_pcib_read_config(sc->sc_dev, bus, slot, 484*db5ef4fcSRafal Jaworowski func, PCIR_SUBCLASS, 1); 485*db5ef4fcSRafal Jaworowski 486*db5ef4fcSRafal Jaworowski if (class != PCIC_BRIDGE || 487*db5ef4fcSRafal Jaworowski subclass != PCIS_BRIDGE_PCI) 488*db5ef4fcSRafal Jaworowski continue; 489*db5ef4fcSRafal Jaworowski 490*db5ef4fcSRafal Jaworowski mv_pcib_init_bridge(sc, bus, slot, func); 491*db5ef4fcSRafal Jaworowski } 492*db5ef4fcSRafal Jaworowski } 493*db5ef4fcSRafal Jaworowski 494*db5ef4fcSRafal Jaworowski /* Enable all ABCD interrupts */ 495*db5ef4fcSRafal Jaworowski pcib_write_irq_mask(sc, (0xF << 24)); 496*db5ef4fcSRafal Jaworowski 497*db5ef4fcSRafal Jaworowski return (0); 498*db5ef4fcSRafal Jaworowski } 499*db5ef4fcSRafal Jaworowski 500*db5ef4fcSRafal Jaworowski static int 501*db5ef4fcSRafal Jaworowski mv_pcib_init_all_bars(struct mv_pcib_softc *sc, int bus, int slot, 502*db5ef4fcSRafal Jaworowski int func, int hdrtype) 503*db5ef4fcSRafal Jaworowski { 504*db5ef4fcSRafal Jaworowski int maxbar, bar, i; 505*db5ef4fcSRafal Jaworowski 506*db5ef4fcSRafal Jaworowski maxbar = (hdrtype & PCIM_HDRTYPE) ? 0 : 6; 507*db5ef4fcSRafal Jaworowski bar = 0; 508*db5ef4fcSRafal Jaworowski 509*db5ef4fcSRafal Jaworowski /* Program the base address registers */ 510*db5ef4fcSRafal Jaworowski while (bar < maxbar) { 511*db5ef4fcSRafal Jaworowski i = mv_pcib_init_bar(sc, bus, slot, func, bar); 512*db5ef4fcSRafal Jaworowski bar += i; 513*db5ef4fcSRafal Jaworowski if (i < 0) { 514*db5ef4fcSRafal Jaworowski device_printf(sc->sc_dev, 515*db5ef4fcSRafal Jaworowski "PCI IO/Memory space exhausted\n"); 516*db5ef4fcSRafal Jaworowski return (ENOMEM); 517*db5ef4fcSRafal Jaworowski } 518*db5ef4fcSRafal Jaworowski } 519*db5ef4fcSRafal Jaworowski 520*db5ef4fcSRafal Jaworowski return (0); 521*db5ef4fcSRafal Jaworowski } 522*db5ef4fcSRafal Jaworowski 523*db5ef4fcSRafal Jaworowski static struct resource * 524*db5ef4fcSRafal Jaworowski mv_pcib_alloc_resource(device_t dev, device_t child, int type, int *rid, 525*db5ef4fcSRafal Jaworowski u_long start, u_long end, u_long count, u_int flags) 526*db5ef4fcSRafal Jaworowski { 527*db5ef4fcSRafal Jaworowski struct mv_pcib_softc *sc = device_get_softc(dev); 528*db5ef4fcSRafal Jaworowski struct rman *rm = NULL; 529*db5ef4fcSRafal Jaworowski struct resource *res; 530*db5ef4fcSRafal Jaworowski 531*db5ef4fcSRafal Jaworowski switch (type) { 532*db5ef4fcSRafal Jaworowski case SYS_RES_IOPORT: 533*db5ef4fcSRafal Jaworowski rm = &sc->sc_io_rman; 534*db5ef4fcSRafal Jaworowski break; 535*db5ef4fcSRafal Jaworowski case SYS_RES_MEMORY: 536*db5ef4fcSRafal Jaworowski rm = &sc->sc_mem_rman; 537*db5ef4fcSRafal Jaworowski break; 538*db5ef4fcSRafal Jaworowski default: 539*db5ef4fcSRafal Jaworowski return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, 540*db5ef4fcSRafal Jaworowski type, rid, start, end, count, flags)); 541*db5ef4fcSRafal Jaworowski }; 542*db5ef4fcSRafal Jaworowski 543*db5ef4fcSRafal Jaworowski res = rman_reserve_resource(rm, start, end, count, flags, child); 544*db5ef4fcSRafal Jaworowski if (res == NULL) 545*db5ef4fcSRafal Jaworowski return (NULL); 546*db5ef4fcSRafal Jaworowski 547*db5ef4fcSRafal Jaworowski rman_set_rid(res, *rid); 548*db5ef4fcSRafal Jaworowski rman_set_bustag(res, fdtbus_bs_tag); 549*db5ef4fcSRafal Jaworowski rman_set_bushandle(res, start); 550*db5ef4fcSRafal Jaworowski 551*db5ef4fcSRafal Jaworowski if (flags & RF_ACTIVE) 552*db5ef4fcSRafal Jaworowski if (bus_activate_resource(child, type, *rid, res)) { 553*db5ef4fcSRafal Jaworowski rman_release_resource(res); 554*db5ef4fcSRafal Jaworowski return (NULL); 555*db5ef4fcSRafal Jaworowski } 556*db5ef4fcSRafal Jaworowski 557*db5ef4fcSRafal Jaworowski return (res); 558*db5ef4fcSRafal Jaworowski } 559*db5ef4fcSRafal Jaworowski 560*db5ef4fcSRafal Jaworowski static int 561*db5ef4fcSRafal Jaworowski mv_pcib_release_resource(device_t dev, device_t child, int type, int rid, 562*db5ef4fcSRafal Jaworowski struct resource *res) 563*db5ef4fcSRafal Jaworowski { 564*db5ef4fcSRafal Jaworowski 565*db5ef4fcSRafal Jaworowski if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY) 566*db5ef4fcSRafal Jaworowski return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child, 567*db5ef4fcSRafal Jaworowski type, rid, res)); 568*db5ef4fcSRafal Jaworowski 569*db5ef4fcSRafal Jaworowski return (rman_release_resource(res)); 570*db5ef4fcSRafal Jaworowski } 571*db5ef4fcSRafal Jaworowski 572*db5ef4fcSRafal Jaworowski static int 573*db5ef4fcSRafal Jaworowski mv_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 574*db5ef4fcSRafal Jaworowski { 575*db5ef4fcSRafal Jaworowski struct mv_pcib_softc *sc = device_get_softc(dev); 576*db5ef4fcSRafal Jaworowski 577*db5ef4fcSRafal Jaworowski switch (which) { 578*db5ef4fcSRafal Jaworowski case PCIB_IVAR_BUS: 579*db5ef4fcSRafal Jaworowski *result = sc->sc_busnr; 580*db5ef4fcSRafal Jaworowski return (0); 581*db5ef4fcSRafal Jaworowski case PCIB_IVAR_DOMAIN: 582*db5ef4fcSRafal Jaworowski *result = device_get_unit(dev); 583*db5ef4fcSRafal Jaworowski return (0); 584*db5ef4fcSRafal Jaworowski } 585*db5ef4fcSRafal Jaworowski 586*db5ef4fcSRafal Jaworowski return (ENOENT); 587*db5ef4fcSRafal Jaworowski } 588*db5ef4fcSRafal Jaworowski 589*db5ef4fcSRafal Jaworowski static int 590*db5ef4fcSRafal Jaworowski mv_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value) 591*db5ef4fcSRafal Jaworowski { 592*db5ef4fcSRafal Jaworowski struct mv_pcib_softc *sc = device_get_softc(dev); 593*db5ef4fcSRafal Jaworowski 594*db5ef4fcSRafal Jaworowski switch (which) { 595*db5ef4fcSRafal Jaworowski case PCIB_IVAR_BUS: 596*db5ef4fcSRafal Jaworowski sc->sc_busnr = value; 597*db5ef4fcSRafal Jaworowski return (0); 598*db5ef4fcSRafal Jaworowski } 599*db5ef4fcSRafal Jaworowski 600*db5ef4fcSRafal Jaworowski return (ENOENT); 601*db5ef4fcSRafal Jaworowski } 602*db5ef4fcSRafal Jaworowski 603*db5ef4fcSRafal Jaworowski static inline void 604*db5ef4fcSRafal Jaworowski pcib_write_irq_mask(struct mv_pcib_softc *sc, uint32_t mask) 605*db5ef4fcSRafal Jaworowski { 606*db5ef4fcSRafal Jaworowski 607*db5ef4fcSRafal Jaworowski if (!sc->sc_type != MV_TYPE_PCI) 608*db5ef4fcSRafal Jaworowski return; 609*db5ef4fcSRafal Jaworowski 610*db5ef4fcSRafal Jaworowski bus_space_write_4(sc->sc_bst, sc->sc_bsh, PCIE_REG_IRQ_MASK, mask); 611*db5ef4fcSRafal Jaworowski } 612*db5ef4fcSRafal Jaworowski 613*db5ef4fcSRafal Jaworowski static void 614*db5ef4fcSRafal Jaworowski mv_pcib_hw_cfginit(void) 6156975124cSRafal Jaworowski { 6166975124cSRafal Jaworowski static int opened = 0; 6176975124cSRafal Jaworowski 6186975124cSRafal Jaworowski if (opened) 6196975124cSRafal Jaworowski return; 6206975124cSRafal Jaworowski 6216975124cSRafal Jaworowski mtx_init(&pcicfg_mtx, "pcicfg", NULL, MTX_SPIN); 6226975124cSRafal Jaworowski opened = 1; 6236975124cSRafal Jaworowski } 6246975124cSRafal Jaworowski 6256975124cSRafal Jaworowski static uint32_t 626*db5ef4fcSRafal Jaworowski mv_pcib_hw_cfgread(struct mv_pcib_softc *sc, u_int bus, u_int slot, 6276975124cSRafal Jaworowski u_int func, u_int reg, int bytes) 6286975124cSRafal Jaworowski { 6296975124cSRafal Jaworowski uint32_t addr, data, ca, cd; 6306975124cSRafal Jaworowski 631*db5ef4fcSRafal Jaworowski ca = (sc->sc_type != MV_TYPE_PCI) ? 6326975124cSRafal Jaworowski PCIE_REG_CFG_ADDR : PCI_REG_CFG_ADDR; 633*db5ef4fcSRafal Jaworowski cd = (sc->sc_type != MV_TYPE_PCI) ? 6346975124cSRafal Jaworowski PCIE_REG_CFG_DATA : PCI_REG_CFG_DATA; 6356975124cSRafal Jaworowski addr = PCI_CFG_ENA | PCI_CFG_BUS(bus) | PCI_CFG_DEV(slot) | 6366975124cSRafal Jaworowski PCI_CFG_FUN(func) | PCI_CFG_PCIE_REG(reg); 6376975124cSRafal Jaworowski 6386975124cSRafal Jaworowski mtx_lock_spin(&pcicfg_mtx); 6396975124cSRafal Jaworowski bus_space_write_4(sc->sc_bst, sc->sc_bsh, ca, addr); 6406975124cSRafal Jaworowski 6416975124cSRafal Jaworowski data = ~0; 6426975124cSRafal Jaworowski switch (bytes) { 6436975124cSRafal Jaworowski case 1: 6446975124cSRafal Jaworowski data = bus_space_read_1(sc->sc_bst, sc->sc_bsh, 6456975124cSRafal Jaworowski cd + (reg & 3)); 6466975124cSRafal Jaworowski break; 6476975124cSRafal Jaworowski case 2: 6486975124cSRafal Jaworowski data = le16toh(bus_space_read_2(sc->sc_bst, sc->sc_bsh, 6496975124cSRafal Jaworowski cd + (reg & 2))); 6506975124cSRafal Jaworowski break; 6516975124cSRafal Jaworowski case 4: 6526975124cSRafal Jaworowski data = le32toh(bus_space_read_4(sc->sc_bst, sc->sc_bsh, 6536975124cSRafal Jaworowski cd)); 6546975124cSRafal Jaworowski break; 6556975124cSRafal Jaworowski } 6566975124cSRafal Jaworowski mtx_unlock_spin(&pcicfg_mtx); 6576975124cSRafal Jaworowski return (data); 6586975124cSRafal Jaworowski } 6596975124cSRafal Jaworowski 6606975124cSRafal Jaworowski static void 661*db5ef4fcSRafal Jaworowski mv_pcib_hw_cfgwrite(struct mv_pcib_softc *sc, u_int bus, u_int slot, 6626975124cSRafal Jaworowski u_int func, u_int reg, uint32_t data, int bytes) 6636975124cSRafal Jaworowski { 6646975124cSRafal Jaworowski uint32_t addr, ca, cd; 6656975124cSRafal Jaworowski 666*db5ef4fcSRafal Jaworowski ca = (sc->sc_type != MV_TYPE_PCI) ? 6676975124cSRafal Jaworowski PCIE_REG_CFG_ADDR : PCI_REG_CFG_ADDR; 668*db5ef4fcSRafal Jaworowski cd = (sc->sc_type != MV_TYPE_PCI) ? 6696975124cSRafal Jaworowski PCIE_REG_CFG_DATA : PCI_REG_CFG_DATA; 6706975124cSRafal Jaworowski addr = PCI_CFG_ENA | PCI_CFG_BUS(bus) | PCI_CFG_DEV(slot) | 6716975124cSRafal Jaworowski PCI_CFG_FUN(func) | PCI_CFG_PCIE_REG(reg); 6726975124cSRafal Jaworowski 6736975124cSRafal Jaworowski mtx_lock_spin(&pcicfg_mtx); 6746975124cSRafal Jaworowski bus_space_write_4(sc->sc_bst, sc->sc_bsh, ca, addr); 6756975124cSRafal Jaworowski 6766975124cSRafal Jaworowski switch (bytes) { 6776975124cSRafal Jaworowski case 1: 6786975124cSRafal Jaworowski bus_space_write_1(sc->sc_bst, sc->sc_bsh, 6796975124cSRafal Jaworowski cd + (reg & 3), data); 6806975124cSRafal Jaworowski break; 6816975124cSRafal Jaworowski case 2: 6826975124cSRafal Jaworowski bus_space_write_2(sc->sc_bst, sc->sc_bsh, 6836975124cSRafal Jaworowski cd + (reg & 2), htole16(data)); 6846975124cSRafal Jaworowski break; 6856975124cSRafal Jaworowski case 4: 6866975124cSRafal Jaworowski bus_space_write_4(sc->sc_bst, sc->sc_bsh, 6876975124cSRafal Jaworowski cd, htole32(data)); 6886975124cSRafal Jaworowski break; 6896975124cSRafal Jaworowski } 6906975124cSRafal Jaworowski mtx_unlock_spin(&pcicfg_mtx); 6916975124cSRafal Jaworowski } 6926975124cSRafal Jaworowski 6936975124cSRafal Jaworowski static int 694*db5ef4fcSRafal Jaworowski mv_pcib_maxslots(device_t dev) 6956975124cSRafal Jaworowski { 696*db5ef4fcSRafal Jaworowski struct mv_pcib_softc *sc = device_get_softc(dev); 6976975124cSRafal Jaworowski 698*db5ef4fcSRafal Jaworowski return ((sc->sc_type != MV_TYPE_PCI) ? 1 : PCI_SLOTMAX); 6996975124cSRafal Jaworowski } 7006975124cSRafal Jaworowski 7016975124cSRafal Jaworowski static uint32_t 702*db5ef4fcSRafal Jaworowski mv_pcib_read_config(device_t dev, u_int bus, u_int slot, u_int func, 7036975124cSRafal Jaworowski u_int reg, int bytes) 7046975124cSRafal Jaworowski { 705*db5ef4fcSRafal Jaworowski struct mv_pcib_softc *sc = device_get_softc(dev); 7066975124cSRafal Jaworowski 7076975124cSRafal Jaworowski /* Skip self */ 7086975124cSRafal Jaworowski if (bus == sc->sc_busnr && slot == sc->sc_devnr) 7096975124cSRafal Jaworowski return (~0U); 7106975124cSRafal Jaworowski 711*db5ef4fcSRafal Jaworowski return (mv_pcib_hw_cfgread(sc, bus, slot, func, reg, bytes)); 7126975124cSRafal Jaworowski } 7136975124cSRafal Jaworowski 7146975124cSRafal Jaworowski static void 715*db5ef4fcSRafal Jaworowski mv_pcib_write_config(device_t dev, u_int bus, u_int slot, u_int func, 7166975124cSRafal Jaworowski u_int reg, uint32_t val, int bytes) 7176975124cSRafal Jaworowski { 718*db5ef4fcSRafal Jaworowski struct mv_pcib_softc *sc = device_get_softc(dev); 7196975124cSRafal Jaworowski 7206975124cSRafal Jaworowski /* Skip self */ 7216975124cSRafal Jaworowski if (bus == sc->sc_busnr && slot == sc->sc_devnr) 7226975124cSRafal Jaworowski return; 7236975124cSRafal Jaworowski 724*db5ef4fcSRafal Jaworowski mv_pcib_hw_cfgwrite(sc, bus, slot, func, reg, val, bytes); 7256975124cSRafal Jaworowski } 7266975124cSRafal Jaworowski 727*db5ef4fcSRafal Jaworowski static int 728*db5ef4fcSRafal Jaworowski mv_pcib_route_interrupt(device_t pcib, device_t dev, int pin) 7296975124cSRafal Jaworowski { 730*db5ef4fcSRafal Jaworowski struct mv_pcib_softc *sc; 731*db5ef4fcSRafal Jaworowski int err, interrupt; 732*db5ef4fcSRafal Jaworowski 733*db5ef4fcSRafal Jaworowski sc = device_get_softc(pcib); 734*db5ef4fcSRafal Jaworowski 735*db5ef4fcSRafal Jaworowski err = fdt_pci_route_intr(pci_get_bus(dev), pci_get_slot(dev), 736*db5ef4fcSRafal Jaworowski pci_get_function(dev), pin, &sc->sc_intr_info, &interrupt); 737*db5ef4fcSRafal Jaworowski if (err == 0) 738*db5ef4fcSRafal Jaworowski return (interrupt); 739*db5ef4fcSRafal Jaworowski 740*db5ef4fcSRafal Jaworowski device_printf(pcib, "could not route pin %d for device %d.%d\n", 741*db5ef4fcSRafal Jaworowski pin, pci_get_slot(dev), pci_get_function(dev)); 742*db5ef4fcSRafal Jaworowski return (PCI_INVALID_IRQ); 743*db5ef4fcSRafal Jaworowski } 744*db5ef4fcSRafal Jaworowski 745*db5ef4fcSRafal Jaworowski static int 746*db5ef4fcSRafal Jaworowski mv_pcib_decode_win(phandle_t node, struct mv_pcib_softc *sc) 747*db5ef4fcSRafal Jaworowski { 748*db5ef4fcSRafal Jaworowski struct fdt_pci_range io_space, mem_space; 749*db5ef4fcSRafal Jaworowski device_t dev; 7506975124cSRafal Jaworowski int error; 7516975124cSRafal Jaworowski 752*db5ef4fcSRafal Jaworowski dev = sc->sc_dev; 753*db5ef4fcSRafal Jaworowski 754*db5ef4fcSRafal Jaworowski if ((error = fdt_pci_ranges(node, &io_space, &mem_space)) != 0) { 755*db5ef4fcSRafal Jaworowski device_printf(dev, "could not retrieve 'ranges' data\n"); 756*db5ef4fcSRafal Jaworowski return (error); 757*db5ef4fcSRafal Jaworowski } 758*db5ef4fcSRafal Jaworowski 7596975124cSRafal Jaworowski /* Configure CPU decoding windows */ 760*db5ef4fcSRafal Jaworowski error = decode_win_cpu_set(sc->sc_io_win_target, 761*db5ef4fcSRafal Jaworowski sc->sc_io_win_attr, io_space.base_parent, io_space.len, -1); 7626975124cSRafal Jaworowski if (error < 0) { 763*db5ef4fcSRafal Jaworowski device_printf(dev, "could not set up CPU decode " 7646975124cSRafal Jaworowski "window for PCI IO\n"); 765*db5ef4fcSRafal Jaworowski return (ENXIO); 7666975124cSRafal Jaworowski } 767*db5ef4fcSRafal Jaworowski error = decode_win_cpu_set(sc->sc_mem_win_target, 768*db5ef4fcSRafal Jaworowski sc->sc_mem_win_attr, mem_space.base_parent, mem_space.len, -1); 7696975124cSRafal Jaworowski if (error < 0) { 770*db5ef4fcSRafal Jaworowski device_printf(dev, "could not set up CPU decode " 7716975124cSRafal Jaworowski "windows for PCI MEM\n"); 772*db5ef4fcSRafal Jaworowski return (ENXIO); 7736975124cSRafal Jaworowski } 7746975124cSRafal Jaworowski 775*db5ef4fcSRafal Jaworowski sc->sc_io_base = io_space.base_parent; 776*db5ef4fcSRafal Jaworowski sc->sc_io_size = io_space.len; 777*db5ef4fcSRafal Jaworowski 778*db5ef4fcSRafal Jaworowski sc->sc_mem_base = mem_space.base_parent; 779*db5ef4fcSRafal Jaworowski sc->sc_mem_size = mem_space.len; 780*db5ef4fcSRafal Jaworowski 781*db5ef4fcSRafal Jaworowski return (0); 7826975124cSRafal Jaworowski } 7836975124cSRafal Jaworowski 784*db5ef4fcSRafal Jaworowski static int 785*db5ef4fcSRafal Jaworowski mv_pcib_intr_info(phandle_t node, struct mv_pcib_softc *sc) 7866975124cSRafal Jaworowski { 787*db5ef4fcSRafal Jaworowski int error; 7886975124cSRafal Jaworowski 789*db5ef4fcSRafal Jaworowski if ((error = fdt_pci_intr_info(node, &sc->sc_intr_info)) != 0) 790*db5ef4fcSRafal Jaworowski return (error); 7916975124cSRafal Jaworowski 792*db5ef4fcSRafal Jaworowski return (0); 7936975124cSRafal Jaworowski } 7946975124cSRafal Jaworowski 795*db5ef4fcSRafal Jaworowski #if 0 7966975124cSRafal Jaworowski control = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 7976975124cSRafal Jaworowski PCIE_REG_CONTROL); 7986975124cSRafal Jaworowski 7996975124cSRafal Jaworowski /* 8006975124cSRafal Jaworowski * If this PCI-E port (controller) is configured (by the 8016975124cSRafal Jaworowski * underlying firmware) with lane width other than 1x, there 8026975124cSRafal Jaworowski * are auxiliary resources defined for aggregating more width 8036975124cSRafal Jaworowski * on our lane. Skip all such entries as they are not 8046975124cSRafal Jaworowski * standalone ports and must not have a device object 8056975124cSRafal Jaworowski * instantiated. 8066975124cSRafal Jaworowski */ 8076975124cSRafal Jaworowski if ((control & PCIE_CTRL_LINK1X) == 0) 8086975124cSRafal Jaworowski while (info->op_base && 8096975124cSRafal Jaworowski info->op_type == MV_TYPE_PCIE_AGGR_LANE) 8106975124cSRafal Jaworowski info++; 8116975124cSRafal Jaworowski 812*db5ef4fcSRafal Jaworowski mv_pcib_add_child(driver, parent, sc); 813*db5ef4fcSRafal Jaworowski #endif 814