1300015Sadrian/*- 2300015Sadrian * Copyright (c) 2015 Landon Fuller <landon@landonf.org> 3300015Sadrian * All rights reserved. 4300015Sadrian * 5300015Sadrian * Redistribution and use in source and binary forms, with or without 6300015Sadrian * modification, are permitted provided that the following conditions 7300015Sadrian * are met: 8300015Sadrian * 1. Redistributions of source code must retain the above copyright 9300015Sadrian * notice, this list of conditions and the following disclaimer, 10300015Sadrian * without modification. 11300015Sadrian * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12300015Sadrian * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13300015Sadrian * redistribution must be conditioned upon including a substantially 14300015Sadrian * similar Disclaimer requirement for further binary redistribution. 15300015Sadrian * 16300015Sadrian * NO WARRANTY 17300015Sadrian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18300015Sadrian * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19300015Sadrian * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20300015Sadrian * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21300015Sadrian * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22300015Sadrian * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23300015Sadrian * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24300015Sadrian * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25300015Sadrian * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26300015Sadrian * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27300015Sadrian * THE POSSIBILITY OF SUCH DAMAGES. 28300015Sadrian */ 29300015Sadrian 30300015Sadrian#include <sys/cdefs.h> 31300015Sadrian__FBSDID("$FreeBSD: releng/11.0/sys/dev/bhnd/cores/pcie2/bhnd_pcie2.c 301697 2016-06-08 21:31:33Z landonf $"); 32300015Sadrian 33300015Sadrian/* 34300015Sadrian * Broadcom Common PCIe-G2 Support. 35300015Sadrian * 36300015Sadrian * This base driver implementation is shared by the bhnd_pcib_g2 (root complex) 37300015Sadrian * and bhnd_pci_hostb_g2 (host bridge) drivers. 38300015Sadrian */ 39300015Sadrian 40300015Sadrian#include <sys/param.h> 41300015Sadrian#include <sys/malloc.h> 42300015Sadrian#include <sys/kernel.h> 43300015Sadrian#include <sys/bus.h> 44300015Sadrian#include <sys/module.h> 45300015Sadrian#include <sys/systm.h> 46300015Sadrian 47300015Sadrian#include <machine/bus.h> 48300015Sadrian#include <sys/rman.h> 49300015Sadrian#include <machine/resource.h> 50300015Sadrian 51300015Sadrian#include <dev/bhnd/bhnd.h> 52300015Sadrian#include <dev/mdio/mdio.h> 53300015Sadrian 54300015Sadrian#include "bhnd_pcie2_reg.h" 55300015Sadrian#include "bhnd_pcie2_var.h" 56300015Sadrian 57300015Sadrianstatic struct bhnd_device_quirk bhnd_pcie2_quirks[]; 58300015Sadrian 59300015Sadrian#define BHND_PCIE_DEV(_core, _desc, ...) \ 60301697Slandonf BHND_DEVICE(BCM, _core, _desc, bhnd_pcie2_quirks, ## __VA_ARGS__) 61300015Sadrian 62300015Sadrianstatic const struct bhnd_device bhnd_pcie2_devs[] = { 63300015Sadrian BHND_PCIE_DEV(PCIE2, "PCIe-G2 Host-PCI bridge", BHND_DF_HOSTB), 64300628Sadrian BHND_PCIE_DEV(PCIE2, "PCIe-G2 PCI-BHND bridge", BHND_DF_SOC), 65300015Sadrian 66300015Sadrian BHND_DEVICE_END 67300015Sadrian}; 68300015Sadrian 69300015Sadrian/* Device quirks tables */ 70300015Sadrianstatic struct bhnd_device_quirk bhnd_pcie2_quirks[] = { 71300015Sadrian BHND_DEVICE_QUIRK_END 72300015Sadrian}; 73300015Sadrian 74300015Sadrianint 75300015Sadrianbhnd_pcie2_generic_probe(device_t dev) 76300015Sadrian{ 77300015Sadrian const struct bhnd_device *id; 78300015Sadrian 79300015Sadrian id = bhnd_device_lookup(dev, bhnd_pcie2_devs, 80300015Sadrian sizeof(bhnd_pcie2_devs[0])); 81300015Sadrian if (id == NULL) 82300015Sadrian return (ENXIO); 83300015Sadrian 84300015Sadrian bhnd_set_custom_core_desc(dev, id->desc); 85300015Sadrian return (BUS_PROBE_DEFAULT); 86300015Sadrian} 87300015Sadrian 88300015Sadrianint 89300015Sadrianbhnd_pcie2_generic_attach(device_t dev) 90300015Sadrian{ 91300015Sadrian struct bhnd_pcie2_softc *sc; 92300015Sadrian int error; 93300015Sadrian 94300015Sadrian sc = device_get_softc(dev); 95300015Sadrian sc->dev = dev; 96300015Sadrian sc->quirks = bhnd_device_quirks(dev, bhnd_pcie2_devs, 97300015Sadrian sizeof(bhnd_pcie2_devs[0])); 98300015Sadrian 99300015Sadrian /* Allocate bus resources */ 100300015Sadrian sc->mem_res = bhnd_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid, 101300015Sadrian RF_ACTIVE); 102300015Sadrian if (sc->mem_res == NULL) 103300015Sadrian return (ENXIO); 104300015Sadrian 105300015Sadrian BHND_PCIE2_LOCK_INIT(sc); 106300015Sadrian 107300015Sadrian /* Probe and attach children */ 108300015Sadrian if ((error = bus_generic_attach(dev))) 109300015Sadrian goto cleanup; 110300015Sadrian 111300015Sadrian return (0); 112300015Sadrian 113300015Sadriancleanup: 114300015Sadrian bhnd_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem_res); 115300015Sadrian BHND_PCIE2_LOCK_DESTROY(sc); 116300015Sadrian 117300015Sadrian return (error); 118300015Sadrian} 119300015Sadrian 120300015Sadrianint 121300015Sadrianbhnd_pcie2_generic_detach(device_t dev) 122300015Sadrian{ 123300015Sadrian struct bhnd_pcie2_softc *sc; 124300015Sadrian int error; 125300015Sadrian 126300015Sadrian sc = device_get_softc(dev); 127300015Sadrian 128300015Sadrian if ((error = bus_generic_detach(dev))) 129300015Sadrian return (error); 130300015Sadrian 131300015Sadrian bhnd_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem_res); 132300015Sadrian 133300015Sadrian BHND_PCIE2_LOCK_DESTROY(sc); 134300015Sadrian 135300015Sadrian return (0); 136300015Sadrian} 137300015Sadrian 138300015Sadrianstatic struct resource_list * 139300015Sadrianbhnd_pcie2_get_resource_list(device_t dev, device_t child) 140300015Sadrian{ 141300015Sadrian struct bhnd_pcie2_devinfo *dinfo; 142300015Sadrian 143300015Sadrian if (device_get_parent(child) != dev) 144300015Sadrian return (NULL); 145300015Sadrian 146300015Sadrian dinfo = device_get_ivars(child); 147300015Sadrian return (&dinfo->resources); 148300015Sadrian} 149300015Sadrian 150300015Sadrianstatic device_t 151300015Sadrianbhnd_pcie2_add_child(device_t dev, u_int order, const char *name, int unit) 152300015Sadrian{ 153300015Sadrian struct bhnd_pcie2_devinfo *dinfo; 154300015Sadrian device_t child; 155300015Sadrian 156300015Sadrian child = device_add_child_ordered(dev, order, name, unit); 157300015Sadrian if (child == NULL) 158300015Sadrian return (NULL); 159300015Sadrian 160300015Sadrian dinfo = malloc(sizeof(struct bhnd_pcie2_devinfo), M_DEVBUF, M_NOWAIT); 161300015Sadrian if (dinfo == NULL) { 162300015Sadrian device_delete_child(dev, child); 163300015Sadrian return (NULL); 164300015Sadrian } 165300015Sadrian 166300015Sadrian resource_list_init(&dinfo->resources); 167300015Sadrian 168300015Sadrian device_set_ivars(child, dinfo); 169300015Sadrian return (child); 170300015Sadrian} 171300015Sadrian 172300015Sadrianstatic void 173300015Sadrianbhnd_pcie2_child_deleted(device_t dev, device_t child) 174300015Sadrian{ 175300015Sadrian struct bhnd_pcie2_devinfo *dinfo; 176300015Sadrian 177300015Sadrian if (device_get_parent(child) != dev) 178300015Sadrian return; 179300015Sadrian 180300015Sadrian dinfo = device_get_ivars(child); 181300015Sadrian if (dinfo != NULL) { 182300015Sadrian resource_list_free(&dinfo->resources); 183300015Sadrian free(dinfo, M_DEVBUF); 184300015Sadrian } 185300015Sadrian 186300015Sadrian device_set_ivars(child, NULL); 187300015Sadrian} 188300015Sadrian 189300015Sadrianint 190300015Sadrianbhnd_pcie2_generic_suspend(device_t dev) 191300015Sadrian{ 192300015Sadrian return (bus_generic_suspend(dev)); 193300015Sadrian} 194300015Sadrian 195300015Sadrianint 196300015Sadrianbhnd_pcie2_generic_resume(device_t dev) 197300015Sadrian{ 198300015Sadrian return (bus_generic_resume(dev)); 199300015Sadrian} 200300015Sadrian 201300015Sadrian/** 202300015Sadrian * Read a 32-bit PCIe TLP/DLLP/PLP protocol register. 203300015Sadrian * 204300015Sadrian * @param sc The bhndb_pci driver state. 205300015Sadrian * @param addr The protocol register offset. 206300015Sadrian */ 207300015Sadrianuint32_t 208300015Sadrianbhnd_pcie2_read_proto_reg(struct bhnd_pcie2_softc *sc, uint32_t addr) 209300015Sadrian{ 210300015Sadrian // TODO 211300015Sadrian return (ENXIO); 212300015Sadrian} 213300015Sadrian 214300015Sadrian/** 215300015Sadrian * Write a 32-bit PCIe TLP/DLLP/PLP protocol register value. 216300015Sadrian * 217300015Sadrian * @param sc The bhndb_pci driver state. 218300015Sadrian * @param addr The protocol register offset. 219300015Sadrian * @param val The value to write to @p addr. 220300015Sadrian */ 221300015Sadrianvoid 222300015Sadrianbhnd_pcie2_write_proto_reg(struct bhnd_pcie2_softc *sc, uint32_t addr, 223300015Sadrian uint32_t val) 224300015Sadrian{ 225300015Sadrian // TODO 226300015Sadrian panic("unimplemented"); 227300015Sadrian} 228300015Sadrian 229300015Sadrianint 230300015Sadrianbhnd_pcie2_mdio_read(struct bhnd_pcie2_softc *sc, int phy, int reg) 231300015Sadrian{ 232300015Sadrian // TODO 233300015Sadrian return (ENXIO); 234300015Sadrian} 235300015Sadrian 236300015Sadrianint 237300015Sadrianbhnd_pcie2_mdio_write(struct bhnd_pcie2_softc *sc, int phy, int reg, int val) 238300015Sadrian{ 239300015Sadrian // TODO 240300015Sadrian return (ENXIO); 241300015Sadrian} 242300015Sadrian 243300015Sadrianint 244300015Sadrianbhnd_pcie2_mdio_read_ext(struct bhnd_pcie2_softc *sc, int phy, int devaddr, 245300015Sadrian int reg) 246300015Sadrian{ 247300015Sadrian // TODO 248300015Sadrian return (ENXIO); 249300015Sadrian} 250300015Sadrian 251300015Sadrianint 252300015Sadrianbhnd_pcie2_mdio_write_ext(struct bhnd_pcie2_softc *sc, int phy, int devaddr, 253300015Sadrian int reg, int val) 254300015Sadrian{ 255300015Sadrian // TODO 256300015Sadrian return (ENXIO); 257300015Sadrian} 258300015Sadrian 259300015Sadrianstatic device_method_t bhnd_pcie2_methods[] = { 260300015Sadrian /* Device interface */ 261300015Sadrian DEVMETHOD(device_probe, bhnd_pcie2_generic_probe), 262300015Sadrian DEVMETHOD(device_attach, bhnd_pcie2_generic_attach), 263300015Sadrian DEVMETHOD(device_detach, bhnd_pcie2_generic_detach), 264300015Sadrian DEVMETHOD(device_suspend, bhnd_pcie2_generic_suspend), 265300015Sadrian DEVMETHOD(device_resume, bhnd_pcie2_generic_resume), 266300015Sadrian 267300015Sadrian /* Bus interface */ 268300015Sadrian DEVMETHOD(bus_add_child, bhnd_pcie2_add_child), 269300015Sadrian DEVMETHOD(bus_child_deleted, bhnd_pcie2_child_deleted), 270300015Sadrian DEVMETHOD(bus_print_child, bus_generic_print_child), 271300015Sadrian DEVMETHOD(bus_get_resource_list, bhnd_pcie2_get_resource_list), 272300015Sadrian DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), 273300015Sadrian DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), 274300015Sadrian DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), 275300015Sadrian 276300015Sadrian DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource), 277300015Sadrian DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 278300015Sadrian DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 279300015Sadrian DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), 280300015Sadrian DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), 281300015Sadrian 282300015Sadrian DEVMETHOD_END 283300015Sadrian}; 284300015Sadrian 285300015SadrianDEFINE_CLASS_0(bhnd_pcie2, bhnd_pcie2_driver, bhnd_pcie2_methods, 286300015Sadrian sizeof(struct bhnd_pcie2_softc)); 287300015SadrianMODULE_DEPEND(bhnd_pcie2, bhnd, 1, 1, 1); 288300015SadrianMODULE_DEPEND(bhnd_pcie2, pci, 1, 1, 1); 289300015SadrianMODULE_VERSION(bhnd_pcie2, 1); 290