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 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 /* 34 * Broadcom ChipCommon driver. 35 * 36 * With the exception of some very early chipsets, the ChipCommon core 37 * has been included in all HND SoCs and chipsets based on the siba(4) 38 * and bcma(4) interconnects, providing a common interface to chipset 39 * identification, bus enumeration, UARTs, clocks, watchdog interrupts, GPIO, 40 * flash, etc. 41 */ 42 43 #include <sys/param.h> 44 #include <sys/kernel.h> 45 #include <sys/bus.h> 46 #include <sys/module.h> 47 #include <sys/systm.h> 48 49 #include <machine/bus.h> 50 #include <sys/rman.h> 51 #include <machine/resource.h> 52 53 #include <dev/bhnd/bhnd.h> 54 55 #include "bhnd_nvram_if.h" 56 57 #include "chipcreg.h" 58 #include "chipcvar.h" 59 60 devclass_t bhnd_chipc_devclass; /**< bhnd(4) chipcommon device class */ 61 62 static const struct resource_spec chipc_rspec[CHIPC_MAX_RSPEC] = { 63 { SYS_RES_MEMORY, 0, RF_ACTIVE }, 64 { -1, -1, 0 } 65 }; 66 67 static struct bhnd_device_quirk chipc_quirks[]; 68 static struct bhnd_chip_quirk chipc_chip_quirks[]; 69 70 /* Supported device identifiers */ 71 static const struct bhnd_device chipc_devices[] = { 72 BHND_DEVICE(CC, "CC", chipc_quirks, chipc_chip_quirks), 73 BHND_DEVICE_END 74 }; 75 76 77 /* Device quirks table */ 78 static struct bhnd_device_quirk chipc_quirks[] = { 79 { BHND_HWREV_GTE (32), CHIPC_QUIRK_SUPPORTS_SPROM }, 80 { BHND_HWREV_GTE (35), CHIPC_QUIRK_SUPPORTS_NFLASH }, 81 BHND_DEVICE_QUIRK_END 82 }; 83 84 /* Chip-specific quirks table */ 85 static struct bhnd_chip_quirk chipc_chip_quirks[] = { 86 /* 4331 12x9 packages */ 87 {{ BHND_CHIP_IP(4331, 4331TN) }, 88 CHIPC_QUIRK_4331_GPIO2_5_MUX_SPROM 89 }, 90 {{ BHND_CHIP_IP(4331, 4331TNA0) }, 91 CHIPC_QUIRK_4331_GPIO2_5_MUX_SPROM 92 }, 93 94 /* 4331 12x12 packages */ 95 {{ BHND_CHIP_IPR(4331, 4331TT, HWREV_GTE(1)) }, 96 CHIPC_QUIRK_4331_EXTPA2_MUX_SPROM 97 }, 98 99 /* 4331 (all packages/revisions) */ 100 {{ BHND_CHIP_ID(4331) }, 101 CHIPC_QUIRK_4331_EXTPA_MUX_SPROM 102 }, 103 104 /* 4360 family (all revs <= 2) */ 105 {{ BHND_CHIP_IR(4352, HWREV_LTE(2)) }, 106 CHIPC_QUIRK_4360_FEM_MUX_SPROM }, 107 {{ BHND_CHIP_IR(43460, HWREV_LTE(2)) }, 108 CHIPC_QUIRK_4360_FEM_MUX_SPROM }, 109 {{ BHND_CHIP_IR(43462, HWREV_LTE(2)) }, 110 CHIPC_QUIRK_4360_FEM_MUX_SPROM }, 111 {{ BHND_CHIP_IR(43602, HWREV_LTE(2)) }, 112 CHIPC_QUIRK_4360_FEM_MUX_SPROM }, 113 114 BHND_CHIP_QUIRK_END 115 }; 116 117 /* quirk and capability flag convenience macros */ 118 #define CHIPC_QUIRK(_sc, _name) \ 119 ((_sc)->quirks & CHIPC_QUIRK_ ## _name) 120 121 #define CHIPC_CAP(_sc, _name) \ 122 ((_sc)->caps & CHIPC_ ## _name) 123 124 #define CHIPC_ASSERT_QUIRK(_sc, name) \ 125 KASSERT(CHIPC_QUIRK((_sc), name), ("quirk " __STRING(_name) " not set")) 126 127 #define CHIPC_ASSERT_CAP(_sc, name) \ 128 KASSERT(CHIPC_CAP((_sc), name), ("capability " __STRING(_name) " not set")) 129 130 static bhnd_nvram_src_t chipc_nvram_identify(struct chipc_softc *sc); 131 static int chipc_sprom_init(struct chipc_softc *); 132 static int chipc_enable_sprom_pins(struct chipc_softc *); 133 static int chipc_disable_sprom_pins(struct chipc_softc *); 134 135 136 static int 137 chipc_probe(device_t dev) 138 { 139 const struct bhnd_device *id; 140 141 id = bhnd_device_lookup(dev, chipc_devices, sizeof(chipc_devices[0])); 142 if (id == NULL) 143 return (ENXIO); 144 145 bhnd_set_default_core_desc(dev); 146 return (BUS_PROBE_DEFAULT); 147 } 148 149 static int 150 chipc_attach(device_t dev) 151 { 152 struct chipc_softc *sc; 153 bhnd_addr_t enum_addr; 154 uint32_t ccid_reg; 155 uint8_t chip_type; 156 int error; 157 158 sc = device_get_softc(dev); 159 sc->dev = dev; 160 sc->quirks = bhnd_device_quirks(dev, chipc_devices, 161 sizeof(chipc_devices[0])); 162 163 CHIPC_LOCK_INIT(sc); 164 165 /* Allocate bus resources */ 166 memcpy(sc->rspec, chipc_rspec, sizeof(sc->rspec)); 167 if ((error = bhnd_alloc_resources(dev, sc->rspec, sc->res))) 168 return (error); 169 170 sc->core = sc->res[0]; 171 172 /* Fetch our chipset identification data */ 173 ccid_reg = bhnd_bus_read_4(sc->core, CHIPC_ID); 174 chip_type = CHIPC_GET_ATTR(ccid_reg, ID_BUS); 175 176 switch (chip_type) { 177 case BHND_CHIPTYPE_SIBA: 178 /* enumeration space starts at the ChipCommon register base. */ 179 enum_addr = rman_get_start(sc->core->res); 180 break; 181 case BHND_CHIPTYPE_BCMA: 182 case BHND_CHIPTYPE_BCMA_ALT: 183 enum_addr = bhnd_bus_read_4(sc->core, CHIPC_EROMPTR); 184 break; 185 default: 186 device_printf(dev, "unsupported chip type %hhu\n", chip_type); 187 error = ENODEV; 188 goto cleanup; 189 } 190 191 sc->ccid = bhnd_parse_chipid(ccid_reg, enum_addr); 192 193 /* Fetch capability and status register values */ 194 sc->caps = bhnd_bus_read_4(sc->core, CHIPC_CAPABILITIES); 195 sc->cst = bhnd_bus_read_4(sc->core, CHIPC_CHIPST); 196 197 /* Identify NVRAM source */ 198 sc->nvram_src = chipc_nvram_identify(sc); 199 200 /* Read NVRAM data */ 201 switch (sc->nvram_src) { 202 case BHND_NVRAM_SRC_OTP: 203 // TODO (requires access to OTP hardware) 204 device_printf(sc->dev, "NVRAM-OTP unsupported\n"); 205 break; 206 207 case BHND_NVRAM_SRC_NFLASH: 208 // TODO (requires access to NFLASH hardware) 209 device_printf(sc->dev, "NVRAM-NFLASH unsupported\n"); 210 break; 211 212 case BHND_NVRAM_SRC_SPROM: 213 if ((error = chipc_sprom_init(sc))) 214 goto cleanup; 215 break; 216 217 case BHND_NVRAM_SRC_UNKNOWN: 218 /* Handled externally */ 219 break; 220 } 221 222 return (0); 223 224 cleanup: 225 bhnd_release_resources(dev, sc->rspec, sc->res); 226 CHIPC_LOCK_DESTROY(sc); 227 return (error); 228 } 229 230 static int 231 chipc_detach(device_t dev) 232 { 233 struct chipc_softc *sc; 234 235 sc = device_get_softc(dev); 236 bhnd_release_resources(dev, sc->rspec, sc->res); 237 bhnd_sprom_fini(&sc->sprom); 238 239 CHIPC_LOCK_DESTROY(sc); 240 241 return (0); 242 } 243 244 static int 245 chipc_suspend(device_t dev) 246 { 247 return (0); 248 } 249 250 static int 251 chipc_resume(device_t dev) 252 { 253 return (0); 254 } 255 256 /** 257 * Initialize local SPROM shadow, if required. 258 * 259 * @param sc chipc driver state. 260 */ 261 static int 262 chipc_sprom_init(struct chipc_softc *sc) 263 { 264 int error; 265 266 KASSERT(sc->nvram_src == BHND_NVRAM_SRC_SPROM, 267 ("non-SPROM source (%u)\n", sc->nvram_src)); 268 269 /* Enable access to the SPROM */ 270 CHIPC_LOCK(sc); 271 if ((error = chipc_enable_sprom_pins(sc))) 272 goto failed; 273 274 /* Initialize SPROM parser */ 275 error = bhnd_sprom_init(&sc->sprom, sc->core, CHIPC_SPROM_OTP); 276 if (error) { 277 device_printf(sc->dev, "SPROM identification failed: %d\n", 278 error); 279 280 chipc_disable_sprom_pins(sc); 281 goto failed; 282 } 283 284 /* Drop access to the SPROM lines */ 285 if ((error = chipc_disable_sprom_pins(sc))) { 286 bhnd_sprom_fini(&sc->sprom); 287 goto failed; 288 } 289 CHIPC_UNLOCK(sc); 290 291 return (0); 292 293 failed: 294 CHIPC_UNLOCK(sc); 295 return (error); 296 } 297 298 /** 299 * Determine the NVRAM data source for this device. 300 * 301 * @param sc chipc driver state. 302 */ 303 static bhnd_nvram_src_t 304 chipc_nvram_identify(struct chipc_softc *sc) 305 { 306 uint32_t srom_ctrl; 307 308 /* Very early devices vend SPROM/OTP/CIS (if at all) via the 309 * host bridge interface instead of ChipCommon. */ 310 if (!CHIPC_QUIRK(sc, SUPPORTS_SPROM)) 311 return (BHND_NVRAM_SRC_UNKNOWN); 312 313 /* 314 * Later chipset revisions standardized the SPROM capability flags and 315 * register interfaces. 316 * 317 * We check for hardware presence in order of precedence. For example, 318 * SPROM is is always used in preference to internal OTP if found. 319 */ 320 if (CHIPC_CAP(sc, CAP_SPROM)) { 321 srom_ctrl = bhnd_bus_read_4(sc->core, CHIPC_SPROM_CTRL); 322 if (srom_ctrl & CHIPC_SRC_PRESENT) 323 return (BHND_NVRAM_SRC_SPROM); 324 } 325 326 /* Check for OTP */ 327 if (CHIPC_CAP(sc, CAP_OTP_SIZE)) 328 return (BHND_NVRAM_SRC_OTP); 329 330 /* 331 * Finally, Northstar chipsets (and possibly other chipsets?) support 332 * external NAND flash. 333 */ 334 if (CHIPC_QUIRK(sc, SUPPORTS_NFLASH) && CHIPC_CAP(sc, CAP_NFLASH)) 335 return (BHND_NVRAM_SRC_NFLASH); 336 337 /* No NVRAM hardware capability declared */ 338 return (BHND_NVRAM_SRC_UNKNOWN); 339 } 340 341 342 /** 343 * If required by this device, enable access to the SPROM. 344 * 345 * @param sc chipc driver state. 346 */ 347 static int 348 chipc_enable_sprom_pins(struct chipc_softc *sc) 349 { 350 uint32_t cctrl; 351 352 CHIPC_LOCK_ASSERT(sc, MA_OWNED); 353 354 /* Nothing to do? */ 355 if (!CHIPC_QUIRK(sc, MUX_SPROM)) 356 return (0); 357 358 cctrl = bhnd_bus_read_4(sc->core, CHIPC_CHIPCTRL); 359 360 /* 4331 devices */ 361 if (CHIPC_QUIRK(sc, 4331_EXTPA_MUX_SPROM)) { 362 cctrl &= ~CHIPC_CCTRL4331_EXTPA_EN; 363 364 if (CHIPC_QUIRK(sc, 4331_GPIO2_5_MUX_SPROM)) 365 cctrl &= ~CHIPC_CCTRL4331_EXTPA_ON_GPIO2_5; 366 367 if (CHIPC_QUIRK(sc, 4331_EXTPA2_MUX_SPROM)) 368 cctrl &= ~CHIPC_CCTRL4331_EXTPA_EN2; 369 370 bhnd_bus_write_4(sc->core, CHIPC_CHIPCTRL, cctrl); 371 return (0); 372 } 373 374 /* 4360 devices */ 375 if (CHIPC_QUIRK(sc, 4360_FEM_MUX_SPROM)) { 376 /* Unimplemented */ 377 } 378 379 /* Refuse to proceed on unsupported devices with muxed SPROM pins */ 380 device_printf(sc->dev, "muxed sprom lines on unrecognized device\n"); 381 return (ENXIO); 382 } 383 384 /** 385 * If required by this device, revert any GPIO/pin configuration applied 386 * to allow SPROM access. 387 * 388 * @param sc chipc driver state. 389 */ 390 static int 391 chipc_disable_sprom_pins(struct chipc_softc *sc) 392 { 393 uint32_t cctrl; 394 395 CHIPC_LOCK_ASSERT(sc, MA_OWNED); 396 397 /* Nothing to do? */ 398 if (!CHIPC_QUIRK(sc, MUX_SPROM)) 399 return (0); 400 401 cctrl = bhnd_bus_read_4(sc->core, CHIPC_CHIPCTRL); 402 403 /* 4331 devices */ 404 if (CHIPC_QUIRK(sc, 4331_EXTPA_MUX_SPROM)) { 405 cctrl |= CHIPC_CCTRL4331_EXTPA_EN; 406 407 if (CHIPC_QUIRK(sc, 4331_GPIO2_5_MUX_SPROM)) 408 cctrl |= CHIPC_CCTRL4331_EXTPA_ON_GPIO2_5; 409 410 if (CHIPC_QUIRK(sc, 4331_EXTPA2_MUX_SPROM)) 411 cctrl |= CHIPC_CCTRL4331_EXTPA_EN2; 412 413 bhnd_bus_write_4(sc->core, CHIPC_CHIPCTRL, cctrl); 414 return (0); 415 } 416 417 /* 4360 devices */ 418 if (CHIPC_QUIRK(sc, 4360_FEM_MUX_SPROM)) { 419 /* Unimplemented */ 420 } 421 422 /* Refuse to proceed on unsupported devices with muxed SPROM pins */ 423 device_printf(sc->dev, "muxed sprom lines on unrecognized device\n"); 424 return (ENXIO); 425 } 426 427 static bhnd_nvram_src_t 428 chipc_nvram_src(device_t dev) 429 { 430 struct chipc_softc *sc = device_get_softc(dev); 431 return (sc->nvram_src); 432 } 433 434 static int 435 chipc_nvram_getvar(device_t dev, const char *name, void *buf, size_t *len) 436 { 437 struct chipc_softc *sc; 438 int error; 439 440 sc = device_get_softc(dev); 441 442 switch (sc->nvram_src) { 443 case BHND_NVRAM_SRC_SPROM: 444 CHIPC_LOCK(sc); 445 error = bhnd_sprom_getvar(&sc->sprom, name, buf, len); 446 CHIPC_UNLOCK(sc); 447 return (error); 448 449 case BHND_NVRAM_SRC_OTP: 450 case BHND_NVRAM_SRC_NFLASH: 451 /* Currently unsupported */ 452 return (ENXIO); 453 454 case BHND_NVRAM_SRC_UNKNOWN: 455 return (ENODEV); 456 } 457 458 /* Unknown NVRAM source */ 459 return (ENODEV); 460 } 461 462 static int 463 chipc_nvram_setvar(device_t dev, const char *name, const void *buf, 464 size_t len) 465 { 466 struct chipc_softc *sc; 467 int error; 468 469 sc = device_get_softc(dev); 470 471 switch (sc->nvram_src) { 472 case BHND_NVRAM_SRC_SPROM: 473 CHIPC_LOCK(sc); 474 error = bhnd_sprom_setvar(&sc->sprom, name, buf, len); 475 CHIPC_UNLOCK(sc); 476 return (error); 477 478 case BHND_NVRAM_SRC_OTP: 479 case BHND_NVRAM_SRC_NFLASH: 480 /* Currently unsupported */ 481 return (ENXIO); 482 483 case BHND_NVRAM_SRC_UNKNOWN: 484 default: 485 return (ENODEV); 486 } 487 488 /* Unknown NVRAM source */ 489 return (ENODEV); 490 } 491 492 static void 493 chipc_write_chipctrl(device_t dev, uint32_t value, uint32_t mask) 494 { 495 struct chipc_softc *sc; 496 uint32_t cctrl; 497 498 sc = device_get_softc(dev); 499 500 CHIPC_LOCK(sc); 501 502 cctrl = bhnd_bus_read_4(sc->core, CHIPC_CHIPCTRL); 503 cctrl = (cctrl & ~mask) | (value | mask); 504 bhnd_bus_write_4(sc->core, CHIPC_CHIPCTRL, cctrl); 505 506 CHIPC_UNLOCK(sc); 507 } 508 509 static device_method_t chipc_methods[] = { 510 /* Device interface */ 511 DEVMETHOD(device_probe, chipc_probe), 512 DEVMETHOD(device_attach, chipc_attach), 513 DEVMETHOD(device_detach, chipc_detach), 514 DEVMETHOD(device_suspend, chipc_suspend), 515 DEVMETHOD(device_resume, chipc_resume), 516 517 /* ChipCommon interface */ 518 DEVMETHOD(bhnd_chipc_nvram_src, chipc_nvram_src), 519 DEVMETHOD(bhnd_chipc_write_chipctrl, chipc_write_chipctrl), 520 521 /* NVRAM interface */ 522 DEVMETHOD(bhnd_nvram_getvar, chipc_nvram_getvar), 523 DEVMETHOD(bhnd_nvram_setvar, chipc_nvram_setvar), 524 525 DEVMETHOD_END 526 }; 527 528 DEFINE_CLASS_0(bhnd_chipc, chipc_driver, chipc_methods, sizeof(struct chipc_softc)); 529 DRIVER_MODULE(bhnd_chipc, bhnd, chipc_driver, bhnd_chipc_devclass, 0, 0); 530 MODULE_DEPEND(bhnd_chipc, bhnd, 1, 1, 1); 531 MODULE_VERSION(bhnd_chipc, 1); 532