1 /* 2 * Copyright (c) 2010 Broadcom Corporation 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #ifndef _siutils_h_ 18 #define _siutils_h_ 19 20 #include <hndsoc.h> 21 22 /* 23 * Data structure to export all chip specific common variables 24 * public (read-only) portion of siutils handle returned by si_attach() 25 */ 26 struct si_pub { 27 uint socitype; /* SOCI_SB, SOCI_AI */ 28 29 uint bustype; /* SI_BUS, PCI_BUS */ 30 uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */ 31 uint buscorerev; /* buscore rev */ 32 uint buscoreidx; /* buscore index */ 33 int ccrev; /* chip common core rev */ 34 u32 cccaps; /* chip common capabilities */ 35 u32 cccaps_ext; /* chip common capabilities extension */ 36 int pmurev; /* pmu core rev */ 37 u32 pmucaps; /* pmu capabilities */ 38 uint boardtype; /* board type */ 39 uint boardvendor; /* board vendor */ 40 uint boardflags; /* board flags */ 41 uint boardflags2; /* board flags2 */ 42 uint chip; /* chip number */ 43 uint chiprev; /* chip revision */ 44 uint chippkg; /* chip package option */ 45 u32 chipst; /* chip status */ 46 bool issim; /* chip is in simulation or emulation */ 47 uint socirev; /* SOC interconnect rev */ 48 bool pci_pr32414; 49 50 }; 51 52 /* for HIGH_ONLY driver, the si_t must be writable to allow states sync from BMAC to HIGH driver 53 * for monolithic driver, it is readonly to prevent accident change 54 */ 55 typedef const struct si_pub si_t; 56 57 /* 58 * Many of the routines below take an 'sih' handle as their first arg. 59 * Allocate this by calling si_attach(). Free it by calling si_detach(). 60 * At any one time, the sih is logically focused on one particular si core 61 * (the "current core"). 62 * Use si_setcore() or si_setcoreidx() to change the association to another core. 63 */ 64 65 #define BADIDX (SI_MAXCORES + 1) 66 67 /* clkctl xtal what flags */ 68 #define XTAL 0x1 /* primary crystal oscillator (2050) */ 69 #define PLL 0x2 /* main chip pll */ 70 71 /* clkctl clk mode */ 72 #define CLK_FAST 0 /* force fast (pll) clock */ 73 #define CLK_DYNAMIC 2 /* enable dynamic clock control */ 74 75 /* GPIO usage priorities */ 76 #define GPIO_DRV_PRIORITY 0 /* Driver */ 77 #define GPIO_APP_PRIORITY 1 /* Application */ 78 #define GPIO_HI_PRIORITY 2 /* Highest priority. Ignore GPIO reservation */ 79 80 /* GPIO pull up/down */ 81 #define GPIO_PULLUP 0 82 #define GPIO_PULLDN 1 83 84 /* GPIO event regtype */ 85 #define GPIO_REGEVT 0 /* GPIO register event */ 86 #define GPIO_REGEVT_INTMSK 1 /* GPIO register event int mask */ 87 #define GPIO_REGEVT_INTPOL 2 /* GPIO register event int polarity */ 88 89 /* device path */ 90 #define SI_DEVPATH_BUFSZ 16 /* min buffer size in bytes */ 91 92 /* SI routine enumeration: to be used by update function with multiple hooks */ 93 #define SI_DOATTACH 1 94 #define SI_PCIDOWN 2 95 #define SI_PCIUP 3 96 97 #define ISSIM_ENAB(sih) 0 98 99 /* PMU clock/power control */ 100 #if defined(BCMPMUCTL) 101 #define PMUCTL_ENAB(sih) (BCMPMUCTL) 102 #else 103 #define PMUCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PMU) 104 #endif 105 106 /* chipcommon clock/power control (exclusive with PMU's) */ 107 #if defined(BCMPMUCTL) && BCMPMUCTL 108 #define CCCTL_ENAB(sih) (0) 109 #define CCPLL_ENAB(sih) (0) 110 #else 111 #define CCCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PWR_CTL) 112 #define CCPLL_ENAB(sih) ((sih)->cccaps & CC_CAP_PLL_MASK) 113 #endif 114 115 typedef void (*gpio_handler_t) (u32 stat, void *arg); 116 117 /* External PA enable mask */ 118 #define GPIO_CTRL_EPA_EN_MASK 0x40 119 120 /* === exported functions === */ 121 extern si_t *si_attach(uint pcidev, void *regs, uint bustype, 122 void *sdh, char **vars, uint *varsz); 123 124 extern void si_detach(si_t *sih); 125 extern bool si_pci_war16165(si_t *sih); 126 127 extern uint si_coreid(si_t *sih); 128 extern uint si_flag(si_t *sih); 129 extern uint si_coreidx(si_t *sih); 130 extern uint si_corerev(si_t *sih); 131 extern uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, 132 uint val); 133 extern void si_write_wrapperreg(si_t *sih, u32 offset, u32 val); 134 extern u32 si_core_cflags(si_t *sih, u32 mask, u32 val); 135 extern u32 si_core_sflags(si_t *sih, u32 mask, u32 val); 136 extern bool si_iscoreup(si_t *sih); 137 extern uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit); 138 #ifndef BCMSDIO 139 extern void *si_setcoreidx(si_t *sih, uint coreidx); 140 #endif 141 extern void *si_setcore(si_t *sih, uint coreid, uint coreunit); 142 extern void *si_switch_core(si_t *sih, uint coreid, uint *origidx, 143 uint *intr_val); 144 extern void si_restore_core(si_t *sih, uint coreid, uint intr_val); 145 extern void si_core_reset(si_t *sih, u32 bits, u32 resetbits); 146 extern void si_core_disable(si_t *sih, u32 bits); 147 extern u32 si_alp_clock(si_t *sih); 148 extern u32 si_ilp_clock(si_t *sih); 149 extern void si_pci_setup(si_t *sih, uint coremask); 150 extern void si_setint(si_t *sih, int siflag); 151 extern bool si_backplane64(si_t *sih); 152 extern void si_register_intr_callback(si_t *sih, void *intrsoff_fn, 153 void *intrsrestore_fn, 154 void *intrsenabled_fn, void *intr_arg); 155 extern void si_deregister_intr_callback(si_t *sih); 156 extern void si_clkctl_init(si_t *sih); 157 extern u16 si_clkctl_fast_pwrup_delay(si_t *sih); 158 extern bool si_clkctl_cc(si_t *sih, uint mode); 159 extern int si_clkctl_xtal(si_t *sih, uint what, bool on); 160 extern bool si_deviceremoved(si_t *sih); 161 extern u32 si_socram_size(si_t *sih); 162 163 extern void si_watchdog(si_t *sih, uint ticks); 164 extern u32 si_gpiocontrol(si_t *sih, u32 mask, u32 val, 165 u8 priority); 166 167 #ifdef BCMSDIO 168 extern void si_sdio_init(si_t *sih); 169 #endif 170 171 #define si_eci(sih) 0 172 #define si_eci_init(sih) (0) 173 #define si_eci_notify_bt(sih, type, val) (0) 174 #define si_seci(sih) 0 175 176 /* OTP status */ 177 extern bool si_is_otp_disabled(si_t *sih); 178 extern bool si_is_otp_powered(si_t *sih); 179 extern void si_otp_power(si_t *sih, bool on); 180 181 /* SPROM availability */ 182 extern bool si_is_sprom_available(si_t *sih); 183 #ifdef SI_SPROM_PROBE 184 extern void si_sprom_init(si_t *sih); 185 #endif /* SI_SPROM_PROBE */ 186 187 #define SI_ERROR(args) 188 189 #ifdef BCMDBG 190 #define SI_MSG(args) printk args 191 #else 192 #define SI_MSG(args) 193 #endif /* BCMDBG */ 194 195 /* Define SI_VMSG to printf for verbose debugging, but don't check it in */ 196 #define SI_VMSG(args) 197 198 #define IS_SIM(chippkg) ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID)) 199 200 typedef u32(*si_intrsoff_t) (void *intr_arg); 201 typedef void (*si_intrsrestore_t) (void *intr_arg, u32 arg); 202 typedef bool(*si_intrsenabled_t) (void *intr_arg); 203 204 typedef struct gpioh_item { 205 void *arg; 206 bool level; 207 gpio_handler_t handler; 208 u32 event; 209 struct gpioh_item *next; 210 } gpioh_item_t; 211 212 /* misc si info needed by some of the routines */ 213 typedef struct si_info { 214 struct si_pub pub; /* back plane public state (must be first) */ 215 void *pbus; /* handle to bus (pci/sdio/..) */ 216 uint dev_coreid; /* the core provides driver functions */ 217 void *intr_arg; /* interrupt callback function arg */ 218 si_intrsoff_t intrsoff_fn; /* turns chip interrupts off */ 219 si_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */ 220 si_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */ 221 222 void *pch; /* PCI/E core handle */ 223 224 gpioh_item_t *gpioh_head; /* GPIO event handlers list */ 225 226 bool memseg; /* flag to toggle MEM_SEG register */ 227 228 char *vars; 229 uint varsz; 230 231 void *curmap; /* current regs va */ 232 void *regs[SI_MAXCORES]; /* other regs va */ 233 234 uint curidx; /* current core index */ 235 uint numcores; /* # discovered cores */ 236 uint coreid[SI_MAXCORES]; /* id of each core */ 237 u32 coresba[SI_MAXCORES]; /* backplane address of each core */ 238 void *regs2[SI_MAXCORES]; /* va of each core second register set (usbh20) */ 239 u32 coresba2[SI_MAXCORES]; /* address of each core second register set (usbh20) */ 240 u32 coresba_size[SI_MAXCORES]; /* backplane address space size */ 241 u32 coresba2_size[SI_MAXCORES]; /* second address space size */ 242 243 void *curwrap; /* current wrapper va */ 244 void *wrappers[SI_MAXCORES]; /* other cores wrapper va */ 245 u32 wrapba[SI_MAXCORES]; /* address of controlling wrapper */ 246 247 u32 cia[SI_MAXCORES]; /* erom cia entry for each core */ 248 u32 cib[SI_MAXCORES]; /* erom cia entry for each core */ 249 u32 oob_router; /* oob router registers for axi */ 250 } si_info_t; 251 252 #define SI_INFO(sih) ((si_info_t *)(sih)) 253 254 #define GOODCOREADDR(x, b) (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \ 255 IS_ALIGNED((x), SI_CORE_SIZE)) 256 #define GOODREGS(regs) ((regs) != NULL && IS_ALIGNED((unsigned long)(regs), SI_CORE_SIZE)) 257 #define BADCOREADDR 0 258 #define GOODIDX(idx) (((uint)idx) < SI_MAXCORES) 259 #define NOREV -1 /* Invalid rev */ 260 261 /* Newer chips can access PCI/PCIE and CC core without requiring to change 262 * PCI BAR0 WIN 263 */ 264 #define SI_FAST(si) (((si)->pub.buscoretype == PCIE_CORE_ID) || \ 265 (((si)->pub.buscoretype == PCI_CORE_ID) && (si)->pub.buscorerev >= 13)) 266 267 #define PCIEREGS(si) (((char *)((si)->curmap) + PCI_16KB0_PCIREGS_OFFSET)) 268 #define CCREGS_FAST(si) (((char *)((si)->curmap) + PCI_16KB0_CCREGS_OFFSET)) 269 270 /* 271 * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts 272 * before after core switching to avoid invalid register access inside ISR. 273 */ 274 #define INTR_OFF(si, intr_val) \ 275 if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ 276 intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); } 277 #define INTR_RESTORE(si, intr_val) \ 278 if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ 279 (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); } 280 281 /* dynamic clock control defines */ 282 #define LPOMINFREQ 25000 /* low power oscillator min */ 283 #define LPOMAXFREQ 43000 /* low power oscillator max */ 284 #define XTALMINFREQ 19800000 /* 20 MHz - 1% */ 285 #define XTALMAXFREQ 20200000 /* 20 MHz + 1% */ 286 #define PCIMINFREQ 25000000 /* 25 MHz */ 287 #define PCIMAXFREQ 34000000 /* 33 MHz + fudge */ 288 289 #define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */ 290 #define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ 291 292 #define PCI(si) (((si)->pub.bustype == PCI_BUS) && \ 293 ((si)->pub.buscoretype == PCI_CORE_ID)) 294 #define PCIE(si) (((si)->pub.bustype == PCI_BUS) && \ 295 ((si)->pub.buscoretype == PCIE_CORE_ID)) 296 #define PCI_FORCEHT(si) \ 297 (PCIE(si) && (si->pub.chip == BCM4716_CHIP_ID)) 298 299 /* GPIO Based LED powersave defines */ 300 #define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */ 301 #define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */ 302 303 #ifndef DEFAULT_GPIOTIMERVAL 304 #define DEFAULT_GPIOTIMERVAL ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME) 305 #endif 306 307 /* 308 * Build device path. Path size must be >= SI_DEVPATH_BUFSZ. 309 * The returned path is NULL terminated and has trailing '/'. 310 * Return 0 on success, nonzero otherwise. 311 */ 312 extern int si_devpath(si_t *sih, char *path, int size); 313 /* Read variable with prepending the devpath to the name */ 314 extern char *si_getdevpathvar(si_t *sih, const char *name); 315 extern int si_getdevpathintvar(si_t *sih, const char *name); 316 317 extern void si_war42780_clkreq(si_t *sih, bool clkreq); 318 extern void si_pci_sleep(si_t *sih); 319 extern void si_pci_down(si_t *sih); 320 extern void si_pci_up(si_t *sih); 321 extern void si_pcie_extendL1timer(si_t *sih, bool extend); 322 extern int si_pci_fixcfg(si_t *sih); 323 324 extern void si_chipcontrl_epa4331(si_t *sih, bool on); 325 /* Enable Ex-PA for 4313 */ 326 extern void si_epa_4313war(si_t *sih); 327 328 char *si_getnvramflvar(si_t *sih, const char *name); 329 330 /* AMBA Interconnect exported externs */ 331 extern si_t *ai_attach(uint pcidev, void *regs, uint bustype, 332 void *sdh, char **vars, uint *varsz); 333 extern si_t *ai_kattach(void); 334 extern void ai_scan(si_t *sih, void *regs, uint devid); 335 336 extern uint ai_flag(si_t *sih); 337 extern void ai_setint(si_t *sih, int siflag); 338 extern uint ai_coreidx(si_t *sih); 339 extern uint ai_corevendor(si_t *sih); 340 extern uint ai_corerev(si_t *sih); 341 extern bool ai_iscoreup(si_t *sih); 342 extern void *ai_setcoreidx(si_t *sih, uint coreidx); 343 extern u32 ai_core_cflags(si_t *sih, u32 mask, u32 val); 344 extern void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val); 345 extern u32 ai_core_sflags(si_t *sih, u32 mask, u32 val); 346 extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, 347 uint val); 348 extern void ai_core_reset(si_t *sih, u32 bits, u32 resetbits); 349 extern void ai_core_disable(si_t *sih, u32 bits); 350 extern int ai_numaddrspaces(si_t *sih); 351 extern u32 ai_addrspace(si_t *sih, uint asidx); 352 extern u32 ai_addrspacesize(si_t *sih, uint asidx); 353 extern void ai_write_wrap_reg(si_t *sih, u32 offset, u32 val); 354 355 #ifdef BCMSDIO 356 #define si_setcoreidx(sih, idx) sb_setcoreidx(sih, idx) 357 #define si_coreid(sih) sb_coreid(sih) 358 #define si_corerev(sih) sb_corerev(sih) 359 #endif 360 361 #endif /* _siutils_h_ */ 362