1 /*- 2 * Copyright (c) 2015 Landon Fuller <landon@landonf.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification. 11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13 * redistribution must be conditioned upon including a substantially 14 * similar Disclaimer requirement for further binary redistribution. 15 * 16 * NO WARRANTY 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGES. 28 * 29 * $FreeBSD$ 30 */ 31 32 #ifndef _BHND_BHNDB_PCIVAR_H_ 33 #define _BHND_BHNDB_PCIVAR_H_ 34 35 #include <sys/stdint.h> 36 37 #include <dev/bhnd/cores/pci/bhnd_pcivar.h> 38 39 #include "bhndbvar.h" 40 41 /* 42 * bhndb(4) PCI driver subclass. 43 */ 44 45 DECLARE_CLASS(bhndb_pci_driver); 46 47 struct bhndb_pci_softc; 48 49 /* 50 * An interconnect-specific function implementing BHNDB_SET_WINDOW_ADDR 51 */ 52 typedef int (*bhndb_pci_set_regwin_t)(struct bhndb_pci_softc *sc, 53 const struct bhndb_regwin *rw, bhnd_addr_t addr); 54 55 56 /** 57 * PCI bridge core identification table. 58 */ 59 struct bhndb_pci_id { 60 uint16_t device; /**< bhnd device ID */ 61 bhnd_pci_regfmt_t regfmt; /**< register format */ 62 struct bhnd_device_quirk *quirks; /**< quirks table */ 63 }; 64 65 struct bhndb_pci_softc { 66 struct bhndb_softc bhndb; /**< parent softc */ 67 device_t dev; /**< bridge device */ 68 bhnd_devclass_t pci_devclass; /**< PCI core's devclass */ 69 bhndb_pci_set_regwin_t set_regwin; /**< regwin handler */ 70 71 /* 72 * Initialized in BHNDB_INIT_FULL_CONFIG() 73 */ 74 75 device_t mdio; /**< PCIe MDIO device. NULL if not PCIe. */ 76 bhnd_pci_regfmt_t regfmt; /**< device register format */ 77 78 struct resource *mem_res; /**< pci core's registers (borrowed reference) */ 79 bus_size_t mem_off; /**< offset to the PCI core's registers within `mem_res` . */ 80 81 struct bhnd_resource bhnd_mem_res; /**< bhnd resource representation of mem_res. 82 this is a simple 'direct' resource mapping */ 83 84 uint32_t quirks; /**< BHNDB_PCI(E)_QUIRK flags */ 85 86 /** 87 * Driver state specific to BHNDB_PCIE_QUIRK_SDR9_POLARITY. 88 */ 89 struct { 90 /** 91 * PCIe SerDes RX polarity. 92 * 93 * Initialized to the PCIe link's RX polarity 94 * at attach time. This is used to restore the 95 * correct polarity on resume */ 96 bool inv; 97 } sdr9_quirk_polarity; 98 }; 99 100 /* Declare a bhndb_pci_id entry */ 101 #define BHNDB_PCI_ID(_device, _desc, ...) { \ 102 BHND_COREID_ ## _device, \ 103 BHND_PCI_REGFMT_ ## _device, \ 104 (struct bhnd_device_quirk[]) { \ 105 __VA_ARGS__ \ 106 } \ 107 } 108 109 /* 110 * PCI/PCIe-Gen1 endpoint-mode device quirks 111 */ 112 enum { 113 /** No quirks */ 114 BHNDB_PCI_QUIRK_NONE = 0, 115 116 /** 117 * BCM4306 chips (and possibly others) do not support the idle 118 * low-power clock. Clocking must be bootstrapped at attach/resume by 119 * directly adjusting GPIO registers exposed in the PCI config space, 120 * and correspondingly, explicitly shutdown at detach/suspend. 121 */ 122 BHNDB_PCI_QUIRK_EXT_CLOCK_GATING = (1<<1), 123 124 /** 125 * SBTOPCI_PREF and SBTOPCI_BURST must be set on the 126 * SSB_PCICORE_SBTOPCI2 register. 127 */ 128 BHNDB_PCI_QUIRK_SBTOPCI2_PREF_BURST = (1<<2), 129 130 /** 131 * SBTOPCI_RC_READMULTI must be set on the SSB_PCICORE_SBTOPCI2 132 * register. 133 */ 134 BHNDB_PCI_QUIRK_SBTOPCI2_READMULTI = (1<<3), 135 136 /** 137 * Interrupt masking is handled via the interconnect configuration 138 * registers (SBINTVEC on siba), rather than the PCI_INT_MASK 139 * config register. 140 */ 141 BHNDB_PCI_QUIRK_SBINTVEC = (1<<4), 142 143 /** 144 * PCI CLKRUN# should be disabled on attach (via CLKRUN_DSBL). 145 * 146 * The purpose of this work-around is unclear; there is some 147 * documentation regarding earlier Broadcom drivers supporting 148 * a "force CLKRUN#" *enable* registry key for use on mobile 149 * hardware. 150 */ 151 BHNDB_PCI_QUIRK_CLKRUN_DSBL = (1<<5), 152 153 /** 154 * TLP workaround for unmatched address handling is required. 155 * 156 * This TLP workaround will enable setting of the PCIe UR status bit 157 * on memory access to an unmatched address. 158 */ 159 BHNDB_PCIE_QUIRK_UR_STATUS_FIX = (1<<6), 160 161 /** 162 * PCI-PM power management must be explicitly enabled via 163 * the data link control register. 164 */ 165 BHNDB_PCIE_QUIRK_PCIPM_REQEN = (1<<7), 166 167 /** 168 * Fix L0s to L0 exit transition on SerDes <= rev9 devices. 169 * 170 * On these devices, PCIe/SerDes symbol lock can be lost if the 171 * reference clock has not fully stabilized during the L0s to L0 172 * exit transition, triggering an internal reset of the chip. 173 * 174 * The SerDes RX CDR phase lock timers and proportional/integral 175 * filters must be tweaked to ensure the CDR has fully stabilized 176 * before asserting receive sequencer completion. 177 */ 178 BHNDB_PCIE_QUIRK_SDR9_L0s_HANG = (1<<8), 179 180 /** 181 * The idle time for entering L1 low-power state must be 182 * explicitly set (to 114ns) to fix slow L1->L0 transition issues. 183 */ 184 BHNDB_PCIE_QUIRK_L1_IDLE_THRESH = (1<<9), 185 186 /** 187 * The ASPM L1 entry timer should be extended for better performance, 188 * and restored for better power savings. 189 */ 190 BHNDB_PCIE_QUIRK_L1_TIMER_PERF = (1<<10), 191 192 /** 193 * ASPM and ECPM settings must be overridden manually. 194 * 195 * The override behavior is controlled by the BHND_BFL2_PCIEWAR_OVR 196 * flag. If this flag is set, ASPM/CLKREQ should be overridden as 197 * enabled; otherwise, they should be overridden as disabled. 198 * 199 * Attach/Resume: 200 * - Set SRSH_ASPM_ENB flag in the SPROM ASPM register. 201 * - Set ASPM L0S/L1 in the PCIER_LINK_CTL register. 202 * - Set SRSH_CLKREQ_ENB flag in the SPROM CLKREQ_REV5 register. 203 * - Clear ECPM in the PCIER_LINK_CTL register. 204 * 205 * Detach/Suspend: 206 * - 207 * - When the device enters D3 state, or system enters S3/S4 state, 208 * clear ASPM L1 in the PCIER_LINK_CTL register. 209 */ 210 BHNDB_PCIE_QUIRK_ASPM_OVR = (1<<11), 211 212 /** 213 * Fix SerDes polarity on SerDes <= rev9 devices. 214 * 215 * The SerDes polarity must be saved at device attachment, and 216 * restored on suspend/resume. 217 */ 218 BHNDB_PCIE_QUIRK_SDR9_POLARITY = (1<<12), 219 220 /** 221 * The SerDes PLL override flag (CHIPCTRL_4321_PLL_DOWN) must be set on 222 * the ChipCommon core on resume. 223 */ 224 BHNDB_PCIE_QUIRK_SERDES_NOPLLDOWN = (1<<13), 225 226 /** 227 * On attach and resume, consult the SPROM to determine whether 228 * the L2/L3-Ready w/o PCI RESET work-around must be applied. 229 * 230 * If L23READY_EXIT_NOPRST is not already set in the SPROM, set it 231 */ 232 BHNDB_PCIE_QUIRK_SPROM_L23_PCI_RESET = (1<<14), 233 234 /** 235 * The PCIe SerDes supports non-standard extended MDIO register access. 236 * 237 * The PCIe SerDes supports access to extended MDIO registers via 238 * a non-standard Clause 22 address extension mechanism. 239 */ 240 BHNDB_PCIE_QUIRK_SD_C22_EXTADDR = (1<<15), 241 242 /** 243 * The PCIe SerDes PLL must be configured to not retry the startup 244 * sequence upon frequency detection failure on SerDes <= rev9 devices 245 * 246 * The issue this workaround resolves has not be determined. 247 */ 248 BHNDB_PCIE_QUIRK_SDR9_NO_FREQRETRY = (1<<16), 249 }; 250 251 #endif /* _BHND_BHNDB_PCIVAR_H_ */