1/* $NetBSD: imxpcie.c,v 1.5 2024/06/02 13:28:45 andvar Exp $ */ 2 3/* 4 * Copyright (c) 2019 Genetec Corporation. All rights reserved. 5 * Written by Hashimoto Kenichi for Genetec Corporation. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29/* 30 * i.MX6 On-Chip PCI Express Controller 31 */ 32 33#include <sys/cdefs.h> 34__KERNEL_RCSID(0, "$NetBSD: imxpcie.c,v 1.5 2024/06/02 13:28:45 andvar Exp $"); 35 36#include "opt_pci.h" 37#include "opt_fdt.h" 38 39#include "pci.h" 40#include "locators.h" 41 42#define _INTR_PRIVATE 43 44#include <sys/bus.h> 45#include <sys/device.h> 46#include <sys/intr.h> 47#include <sys/systm.h> 48#include <sys/param.h> 49#include <sys/kernel.h> 50#include <sys/extent.h> 51#include <sys/queue.h> 52#include <sys/mutex.h> 53#include <sys/kmem.h> 54 55#include <machine/frame.h> 56#include <arm/cpufunc.h> 57 58#include <dev/pci/pcireg.h> 59#include <dev/pci/pcivar.h> 60#include <dev/pci/pciconf.h> 61#include <dev/clk/clk_backend.h> 62 63#include <arm/imx/imxpciereg.h> 64#include <arm/imx/imxpcievar.h> 65#include <arm/nxp/imx6_iomuxreg.h> 66 67#define PCIE_CONF_LOCK(s) (s) = disable_interrupts(I32_bit) 68#define PCIE_CONF_UNLOCK(s) restore_interrupts((s)) 69 70#define PCIE_READ(sc, reg) \ 71 bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, reg) 72#define PCIE_WRITE(sc, reg, val) \ 73 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, reg, val) 74 75static void imxpcie_init(pci_chipset_tag_t, void *); 76static void imxpcie_setup(struct imxpcie_softc * const); 77 78static void imxpcie_attach_hook(device_t, device_t, struct pcibus_attach_args *); 79static int imxpcie_bus_maxdevs(void *, int); 80static pcitag_t imxpcie_make_tag(void *, int, int, int); 81static void imxpcie_decompose_tag(void *, pcitag_t, int *, int *, int *); 82static pcireg_t imxpcie_conf_read(void *, pcitag_t, int); 83static void imxpcie_conf_write(void *, pcitag_t, int, pcireg_t); 84#ifdef __HAVE_PCI_CONF_HOOK 85static int imxpcie_conf_hook(void *, int, int, int, pcireg_t); 86#endif 87static void imxpcie_conf_interrupt(void *, int, int, int, int, int *); 88 89static int imxpcie_intr_map(const struct pci_attach_args *, pci_intr_handle_t *); 90static const char *imxpcie_intr_string(void *, pci_intr_handle_t, char *, size_t); 91const struct evcnt *imxpcie_intr_evcnt(void *, pci_intr_handle_t); 92static void * imxpcie_intr_establish(void *, pci_intr_handle_t, int, 93 int (*)(void *), void *, const char *); 94static void imxpcie_intr_disestablish(void *, void *); 95 96static int 97imxpcie_linkup_status(struct imxpcie_softc *sc) 98{ 99 return PCIE_READ(sc, PCIE_PL_DEBUG1) & PCIE_PL_DEBUG1_XMLH_LINK_UP; 100} 101 102static int 103imxpcie_valid_device(struct imxpcie_softc *sc, int bus, int dev) 104{ 105 if (bus != 0 && !imxpcie_linkup_status(sc)) 106 return 0; 107 if (bus <= 1 && dev > 0) 108 return 0; 109 110 return 1; 111} 112 113static int 114imxpcie_init_phy(struct imxpcie_softc *sc) 115{ 116 uint32_t v; 117 118 /* initialize IOMUX */ 119 v = sc->sc_gpr_read(sc, IOMUX_GPR12); 120 v &= ~IOMUX_GPR12_APP_LTSSM_ENABLE; 121 sc->sc_gpr_write(sc, IOMUX_GPR12, v); 122 123 v &= ~IOMUX_GPR12_LOS_LEVEL; 124 v |= __SHIFTIN(9, IOMUX_GPR12_LOS_LEVEL); 125 sc->sc_gpr_write(sc, IOMUX_GPR12, v); 126 127 v = 0; 128 v |= __SHIFTIN(0x7f, IOMUX_GPR8_PCS_TX_SWING_LOW); 129 v |= __SHIFTIN(0x7f, IOMUX_GPR8_PCS_TX_SWING_FULL); 130 v |= __SHIFTIN(20, IOMUX_GPR8_PCS_TX_DEEMPH_GEN2_6DB); 131 v |= __SHIFTIN(20, IOMUX_GPR8_PCS_TX_DEEMPH_GEN2_3P5DB); 132 v |= __SHIFTIN(20, IOMUX_GPR8_PCS_TX_DEEMPH_GEN1); 133 sc->sc_gpr_write(sc, IOMUX_GPR8, v); 134 135 v = sc->sc_gpr_read(sc, IOMUX_GPR12); 136 v &= ~IOMUX_GPR12_DEVICE_TYPE; 137 v |= IOMUX_GPR12_DEVICE_TYPE_PCIE_RC; 138 sc->sc_gpr_write(sc, IOMUX_GPR12, v); 139 140 return 0; 141} 142 143static int 144imxpcie_phy_wait_ack(struct imxpcie_softc *sc, int ack) 145{ 146 uint32_t v; 147 int timeout; 148 149 for (timeout = 10; timeout > 0; --timeout) { 150 v = PCIE_READ(sc, PCIE_PL_PHY_STATUS); 151 if (!!(v & PCIE_PL_PHY_STATUS_ACK) == !!ack) 152 return 0; 153 delay(1); 154 } 155 156 return -1; 157} 158 159static int 160imxpcie_phy_addr(struct imxpcie_softc *sc, uint32_t addr) 161{ 162 uint32_t v; 163 164 v = __SHIFTIN(addr, PCIE_PL_PHY_CTRL_DATA); 165 PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, v); 166 167 v |= PCIE_PL_PHY_CTRL_CAP_ADR; 168 PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, v); 169 170 if (imxpcie_phy_wait_ack(sc, 1)) 171 return -1; 172 173 v = __SHIFTIN(addr, PCIE_PL_PHY_CTRL_DATA); 174 PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, v); 175 176 if (imxpcie_phy_wait_ack(sc, 0)) 177 return -1; 178 179 return 0; 180} 181 182static int 183imxpcie_phy_write(struct imxpcie_softc *sc, uint32_t addr, uint16_t data) 184{ 185 /* write address */ 186 if (imxpcie_phy_addr(sc, addr) != 0) 187 return -1; 188 189 /* store data */ 190 PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, __SHIFTIN(data, PCIE_PL_PHY_CTRL_DATA)); 191 192 /* assert CAP_DAT and wait ack */ 193 PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, __SHIFTIN(data, PCIE_PL_PHY_CTRL_DATA) | PCIE_PL_PHY_CTRL_CAP_DAT); 194 if (imxpcie_phy_wait_ack(sc, 1)) 195 return -1; 196 197 /* deassert CAP_DAT and wait ack */ 198 PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, __SHIFTIN(data, PCIE_PL_PHY_CTRL_DATA)); 199 if (imxpcie_phy_wait_ack(sc, 0)) 200 return -1; 201 202 /* assert WR and wait ack */ 203 PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, PCIE_PL_PHY_CTRL_WR); 204 if (imxpcie_phy_wait_ack(sc, 1)) 205 return -1; 206 207 /* deassert WR and wait ack */ 208 PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, __SHIFTIN(data, PCIE_PL_PHY_CTRL_DATA)); 209 if (imxpcie_phy_wait_ack(sc, 0)) 210 return -1; 211 212 /* done */ 213 PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, 0); 214 215 return 0; 216} 217 218static int 219imxpcie_phy_read(struct imxpcie_softc *sc, uint32_t addr) 220{ 221 uint32_t v; 222 223 /* write address */ 224 if (imxpcie_phy_addr(sc, addr) != 0) 225 return -1; 226 227 /* assert RD */ 228 PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, PCIE_PL_PHY_CTRL_RD); 229 if (imxpcie_phy_wait_ack(sc, 1)) 230 return -1; 231 232 /* read data */ 233 v = __SHIFTOUT(PCIE_READ(sc, PCIE_PL_PHY_STATUS), 234 PCIE_PL_PHY_STATUS_DATA); 235 236 /* deassert RD */ 237 PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, 0); 238 if (imxpcie_phy_wait_ack(sc, 0)) 239 return -1; 240 241 return v; 242} 243 244static int 245imxpcie_assert_core_reset(struct imxpcie_softc *sc) 246{ 247 uint32_t gpr1 = sc->sc_gpr_read(sc, IOMUX_GPR1); 248 249 if (sc->sc_have_sw_reset) { 250 gpr1 |= IOMUX_GPR1_PCIE_SW_RST; 251 sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1); 252 } else { 253 uint32_t gpr12 = sc->sc_gpr_read(sc, IOMUX_GPR12); 254 255 /* already enabled by bootloader */ 256 if ((gpr1 & IOMUX_GPR1_REF_SSP_EN) && 257 (gpr12 & IOMUX_GPR12_APP_LTSSM_ENABLE)) { 258 uint32_t v = PCIE_READ(sc, PCIE_PL_PFLR); 259 v &= ~PCIE_PL_PFLR_LINK_STATE; 260 v |= PCIE_PL_PFLR_FORCE_LINK; 261 PCIE_WRITE(sc, PCIE_PL_PFLR, v); 262 263 gpr12 &= ~IOMUX_GPR12_APP_LTSSM_ENABLE; 264 sc->sc_gpr_write(sc, IOMUX_GPR12, gpr12); 265 } 266 } 267 268 gpr1 |= IOMUX_GPR1_TEST_POWERDOWN; 269 sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1); 270 gpr1 &= ~IOMUX_GPR1_REF_SSP_EN; 271 sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1); 272 273 return 0; 274} 275 276static int 277imxpcie_deassert_core_reset(struct imxpcie_softc *sc) 278{ 279 int error; 280 281 error = clk_enable(sc->sc_clk_pcie); 282 if (error) { 283 aprint_error_dev(sc->sc_dev, "couldn't enable pcie: %d\n", error); 284 return error; 285 } 286 287 if (sc->sc_ext_osc) { 288 error = clk_enable(sc->sc_clk_pcie_ext); 289 if (error) { 290 aprint_error_dev(sc->sc_dev, "couldn't enable ext: %d\n", error); 291 return error; 292 } 293 } else { 294 error = clk_enable(sc->sc_clk_pcie_bus); 295 if (error) { 296 aprint_error_dev(sc->sc_dev, "couldn't enable pcie_bus: %d\n", 297 error); 298 return error; 299 } 300 } 301 302 error = clk_enable(sc->sc_clk_pcie_phy); 303 if (error) { 304 aprint_error_dev(sc->sc_dev, "couldn't enable pcie_ref: %d\n", error); 305 return error; 306 } 307 308 uint32_t gpr1 = sc->sc_gpr_read(sc, IOMUX_GPR1); 309 310 delay(50 * 1000); 311 312 gpr1 &= ~IOMUX_GPR1_TEST_POWERDOWN; 313 sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1); 314 delay(10); 315 gpr1 |= IOMUX_GPR1_REF_SSP_EN; 316 sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1); 317 318 delay(50 * 1000); 319 320 /* Reset */ 321 if (sc->sc_reset != NULL) 322 sc->sc_reset(sc); 323 324 if (sc->sc_have_sw_reset) { 325 gpr1 &= ~IOMUX_GPR1_PCIE_SW_RST; 326 sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1); 327 delay(200); 328 } 329 330 uint64_t rate; 331 if (sc->sc_ext_osc) 332 rate = clk_get_rate(sc->sc_clk_pcie_ext); 333 else 334 rate = clk_get_rate(sc->sc_clk_pcie_phy); 335 aprint_normal_dev(sc->sc_dev, "PCIe ref clk %d MHz\n", (int)(rate / 1000 / 1000)); 336 337 int mult; 338 int div; 339 if (rate == 100000000) { 340 mult = 25; 341 div = 0; 342 } else if (rate == 125000000) { 343 mult = 40; 344 div = 1; 345 } else if (rate == 200000000) { 346 mult = 25; 347 div = 1; 348 } else { 349 return -1; 350 } 351 352 uint32_t val; 353 val = imxpcie_phy_read(sc, PCIE_PHY_MPLL_OVRD_IN_LO); 354 val &= ~MPLL_MULTIPLIER; 355 val |= __SHIFTIN(mult, MPLL_MULTIPLIER); 356 val |= MPLL_MULTIPLIER_OVRD; 357 imxpcie_phy_write(sc, PCIE_PHY_MPLL_OVRD_IN_LO, val); 358 359 val = imxpcie_phy_read(sc, PCIE_PHY_ATEOVRD); 360 val &= ~REF_CLKDIV2; 361 val |= __SHIFTIN(div, REF_CLKDIV2); 362 val |= ATEOVRD_EN; 363 imxpcie_phy_write(sc, PCIE_PHY_ATEOVRD, val); 364 365 return 0; 366} 367 368static int 369imxpcie_wait_for_link(struct imxpcie_softc *sc) 370{ 371#define LINKUP_RETRY 20000 372 for (int retry = LINKUP_RETRY; retry > 0; --retry) { 373 if (!imxpcie_linkup_status(sc)) { 374 delay(10); 375 continue; 376 } 377 378 uint32_t valid = imxpcie_phy_read(sc, PCIE_PHY_RX_ASIC_OUT) & 379 PCIE_PHY_RX_ASIC_OUT_VALID; 380 uint32_t ltssm = __SHIFTOUT(PCIE_READ(sc, PCIE_PL_DEBUG0), 381 PCIE_PL_DEBUG0_XMLH_LTSSM_STATE); 382 383 if ((ltssm == 0x0d) && !valid) { 384 aprint_normal_dev(sc->sc_dev, "resetting PCIe phy\n"); 385 386 uint32_t v = imxpcie_phy_read(sc, PCIE_PHY_RX_OVRD_IN_LO); 387 v |= PCIE_PHY_RX_OVRD_IN_LO_RX_PLL_EN_OVRD; 388 v |= PCIE_PHY_RX_OVRD_IN_LO_RX_DATA_EN_OVRD; 389 imxpcie_phy_write(sc, PCIE_PHY_RX_OVRD_IN_LO, v); 390 391 delay(3000); 392 393 v = imxpcie_phy_read(sc, PCIE_PHY_RX_OVRD_IN_LO); 394 v &= ~PCIE_PHY_RX_OVRD_IN_LO_RX_PLL_EN_OVRD; 395 v &= ~PCIE_PHY_RX_OVRD_IN_LO_RX_DATA_EN_OVRD; 396 imxpcie_phy_write(sc, PCIE_PHY_RX_OVRD_IN_LO, v); 397 } 398 399 return 0; 400 } 401 402 aprint_error_dev(sc->sc_dev, "Link Up failed.\n"); 403 404 return -1; 405} 406 407static int 408imxpcie_wait_for_changespeed(struct imxpcie_softc *sc) 409{ 410#define CHANGESPEED_RETRY 200 411 for (int retry = CHANGESPEED_RETRY; retry > 0; --retry) { 412 uint32_t v = PCIE_READ(sc, PCIE_PL_G2CR); 413 if (!(v & PCIE_PL_G2CR_DIRECTED_SPEED_CHANGE)) 414 return 0; 415 delay(100); 416 } 417 418 aprint_error_dev(sc->sc_dev, "Speed change timeout.\n"); 419 420 return -1; 421} 422 423static void 424imxpcie_linkup(struct imxpcie_softc *sc) 425{ 426 uint32_t v; 427 int ret; 428 429 imxpcie_assert_core_reset(sc); 430 imxpcie_init_phy(sc); 431 imxpcie_deassert_core_reset(sc); 432 433 imxpcie_setup(sc); 434 435 /* GEN1 Operation */ 436 v = PCIE_READ(sc, PCIE_RC_LCR); 437 v &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS; 438 v |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1; 439 PCIE_WRITE(sc, PCIE_RC_LCR, v); 440 441 /* Link Up */ 442 v = sc->sc_gpr_read(sc, IOMUX_GPR12); 443 v |= IOMUX_GPR12_APP_LTSSM_ENABLE; 444 sc->sc_gpr_write(sc, IOMUX_GPR12, v); 445 446 ret = imxpcie_wait_for_link(sc); 447 if (ret) 448 goto error; 449 450 /* Allow Gen2 mode */ 451 v = PCIE_READ(sc, PCIE_RC_LCR); 452 v &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS; 453 v |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2; 454 PCIE_WRITE(sc, PCIE_RC_LCR, v); 455 456 /* Change speed */ 457 v = PCIE_READ(sc, PCIE_PL_G2CR); 458 v |= PCIE_PL_G2CR_DIRECTED_SPEED_CHANGE; 459 PCIE_WRITE(sc, PCIE_PL_G2CR, v); 460 461 ret = imxpcie_wait_for_changespeed(sc); 462 if (ret) 463 goto error; 464 465 ret = imxpcie_wait_for_link(sc); 466 if (ret) 467 goto error; 468 469 v = PCIE_READ(sc, PCIE_RC_LCSR); 470 aprint_normal_dev(sc->sc_dev, "LinkUp, Gen %d\n", 471 (int)__SHIFTOUT(v, PCIE_RC_LCSR_LINK_SPEED)); 472 473 return; 474 475error: 476 aprint_error_dev(sc->sc_dev, "PCIE_PL_DEBUG0,1 = %08x, %08x\n", 477 PCIE_READ(sc, PCIE_PL_DEBUG0), PCIE_READ(sc, PCIE_PL_DEBUG1)); 478 479 return; 480} 481 482void 483imxpcie_attach_common(struct imxpcie_softc * const sc) 484{ 485 struct pcibus_attach_args pba; 486 487 if (bus_space_map(sc->sc_iot, sc->sc_root_addr, sc->sc_root_size, 0, 488 &sc->sc_root_ioh)) { 489 aprint_error_dev(sc->sc_dev, "Cannot map root config\n"); 490 return; 491 } 492 493 imxpcie_linkup(sc); 494 495 TAILQ_INIT(&sc->sc_intrs); 496 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); 497 498 imxpcie_init(&sc->sc_pc, sc); 499 500 if (sc->sc_pci_netbsd_configure != NULL) 501 sc->sc_pci_netbsd_configure(sc); 502 503 memset(&pba, 0, sizeof(pba)); 504 pba.pba_flags = PCI_FLAGS_MEM_OKAY | 505 PCI_FLAGS_IO_OKAY; 506 pba.pba_iot = sc->sc_iot; 507 pba.pba_memt = sc->sc_iot; 508 pba.pba_dmat = sc->sc_dmat; 509 pba.pba_pc = &sc->sc_pc; 510 pba.pba_bus = 0; 511 512 config_found(sc->sc_dev, &pba, pcibusprint, 513 CFARGS(.devhandle = device_handle(sc->sc_dev))); 514} 515 516int 517imxpcie_intr(void *priv) 518{ 519 struct imxpcie_softc *sc = priv; 520 struct imxpcie_ih *pcie_ih; 521 522 for (int i = 0; i < 8; i++) { 523 uint32_t v = PCIE_READ(sc, PCIE_PL_MSICIN_STATUS + i * 0xC); 524 int bit; 525 while ((bit = ffs(v) - 1) >= 0) { 526 PCIE_WRITE(sc, PCIE_PL_MSICIN_STATUS + i * 0xC, 527 __BIT(bit)); 528 v &= ~__BIT(bit); 529 } 530 } 531 532 mutex_enter(&sc->sc_lock); 533 int rv = 0; 534 const u_int lastgen = sc->sc_intrgen; 535 TAILQ_FOREACH(pcie_ih, &sc->sc_intrs, ih_entry) { 536 int (*callback)(void *) = pcie_ih->ih_handler; 537 void *arg = pcie_ih->ih_arg; 538 mutex_exit(&sc->sc_lock); 539 rv += callback(arg); 540 mutex_enter(&sc->sc_lock); 541 if (lastgen != sc->sc_intrgen) 542 break; 543 } 544 mutex_exit(&sc->sc_lock); 545 546 return rv; 547} 548 549static void 550imxpcie_setup(struct imxpcie_softc * const sc) 551{ 552 uint32_t v; 553 554 /* Setup RC */ 555 v = PCIE_READ(sc, PCIE_PL_PLCR); 556 v &= ~PCIE_PL_PLCR_LINK_MODE_ENABLE; 557 v |= __SHIFTIN(1, PCIE_PL_PLCR_LINK_MODE_ENABLE); 558 PCIE_WRITE(sc, PCIE_PL_PLCR, v); 559 560 v = PCIE_READ(sc, PCIE_PL_G2CR); 561 v &= ~PCIE_PL_G2CR_PREDETERMINED_NUMBER_OF_LANES; 562 v |= __SHIFTIN(1, PCIE_PL_G2CR_PREDETERMINED_NUMBER_OF_LANES); 563 PCIE_WRITE(sc, PCIE_PL_G2CR, v); 564 565 /* BARs */ 566 PCIE_WRITE(sc, PCI_BAR0, 0x00000004); 567 PCIE_WRITE(sc, PCI_BAR1, 0x00000000); 568 569 /* Interrupt pins */ 570 v = PCIE_READ(sc, PCI_INTERRUPT_REG); 571 v &= ~(PCI_INTERRUPT_PIN_MASK << PCI_INTERRUPT_PIN_SHIFT); 572 v |= PCI_INTERRUPT_PIN_A << PCI_INTERRUPT_PIN_SHIFT; 573 PCIE_WRITE(sc, PCI_INTERRUPT_REG, v); 574 575 /* Bus number */ 576 v = PCIE_READ(sc, PCI_BRIDGE_BUS_REG); 577 v &= ~(PCI_BRIDGE_BUS_SUBORDINATE | PCI_BRIDGE_BUS_SECONDARY | 578 PCI_BRIDGE_BUS_PRIMARY); 579 v |= PCI_BRIDGE_BUS_NUM_SUBORDINATE(1); 580 v |= PCI_BRIDGE_BUS_NUM_SECONDARY(1); 581 v |= PCI_BRIDGE_BUS_NUM_PRIMARY(0); 582 PCIE_WRITE(sc, PCI_BRIDGE_BUS_REG, v); 583 584 /* Command register */ 585 v = PCIE_READ(sc, PCI_COMMAND_STATUS_REG); 586 v |= PCI_COMMAND_IO_ENABLE | 587 PCI_COMMAND_MEM_ENABLE | 588 PCI_COMMAND_MASTER_ENABLE | 589 PCI_COMMAND_SERR_ENABLE; 590 PCIE_WRITE(sc, PCI_COMMAND_STATUS_REG, v); 591 592 PCIE_WRITE(sc, PCI_CLASS_REG, 593 PCI_CLASS_CODE(PCI_CLASS_BRIDGE, 594 PCI_SUBCLASS_BRIDGE_PCI, 595 PCI_INTERFACE_BRIDGE_PCI_PCI)); 596 597 PCIE_WRITE(sc, PCIE_PL_IATUVR, 0); 598 599 PCIE_WRITE(sc, PCIE_PL_IATURLBA, sc->sc_root_addr); 600 PCIE_WRITE(sc, PCIE_PL_IATURUBA, 0); 601 PCIE_WRITE(sc, PCIE_PL_IATURLA, sc->sc_root_addr + sc->sc_root_size); 602 603 PCIE_WRITE(sc, PCIE_PL_IATURLTA, 0); 604 PCIE_WRITE(sc, PCIE_PL_IATURUTA, 0); 605 PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG0); 606 PCIE_WRITE(sc, PCIE_PL_IATURC2, PCIE_PL_IATURC2_REGION_ENABLE); 607} 608 609void 610imxpcie_init(pci_chipset_tag_t pc, void *priv) 611{ 612 pc->pc_conf_v = priv; 613 pc->pc_attach_hook = imxpcie_attach_hook; 614 pc->pc_bus_maxdevs = imxpcie_bus_maxdevs; 615 pc->pc_make_tag = imxpcie_make_tag; 616 pc->pc_decompose_tag = imxpcie_decompose_tag; 617 pc->pc_conf_read = imxpcie_conf_read; 618 pc->pc_conf_write = imxpcie_conf_write; 619#ifdef __HAVE_PCI_CONF_HOOK 620 pc->pc_conf_hook = imxpcie_conf_hook; 621#endif 622 pc->pc_conf_interrupt = imxpcie_conf_interrupt; 623 624 pc->pc_intr_v = priv; 625 pc->pc_intr_map = imxpcie_intr_map; 626 pc->pc_intr_string = imxpcie_intr_string; 627 pc->pc_intr_evcnt = imxpcie_intr_evcnt; 628 pc->pc_intr_establish = imxpcie_intr_establish; 629 pc->pc_intr_disestablish = imxpcie_intr_disestablish; 630} 631 632static void 633imxpcie_attach_hook(device_t parent, device_t self, 634 struct pcibus_attach_args *pba) 635{ 636 /* nothing to do */ 637} 638 639static int 640imxpcie_bus_maxdevs(void *v, int busno) 641{ 642 return 32; 643} 644 645static pcitag_t 646imxpcie_make_tag(void *v, int b, int d, int f) 647{ 648 return (b << 16) | (d << 11) | (f << 8); 649} 650 651static void 652imxpcie_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp) 653{ 654 if (bp) 655 *bp = (tag >> 16) & 0xff; 656 if (dp) 657 *dp = (tag >> 11) & 0x1f; 658 if (fp) 659 *fp = (tag >> 8) & 0x7; 660} 661 662/* 663 * work around. 664 * If there is no PCIe devices, DABT will be generated by read/write access to 665 * config area, so replace original DABT handler with simple jump-back one. 666 */ 667extern u_int data_abort_handler_address; 668static bool data_abort_flag; 669static void 670imxpcie_data_abort_handler(trapframe_t *tf) 671{ 672 data_abort_flag = true; 673 tf->tf_pc += 0x4; 674 return; 675} 676 677static pcireg_t 678imxpcie_conf_read(void *v, pcitag_t tag, int offset) 679{ 680 struct imxpcie_softc *sc = v; 681 bus_space_handle_t bsh; 682 int b, d, f; 683 pcireg_t ret = -1; 684 int s; 685 686 imxpcie_decompose_tag(v, tag, &b, &d, &f); 687 688 if ((unsigned int)offset >= PCI_EXTCONF_SIZE) 689 return ret; 690 if (!imxpcie_valid_device(sc, b, d)) 691 return ret; 692 693 PCIE_WRITE(sc, PCIE_PL_IATUVR, 0); 694 if (b < 2) 695 PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG0); 696 else 697 PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG1); 698 699 if (b == 0) { 700 bsh = sc->sc_ioh; 701 } else { 702 PCIE_WRITE(sc, PCIE_PL_IATURLTA, tag << 8); 703 bsh = sc->sc_root_ioh; 704 } 705 PCIE_READ(sc, PCIE_PL_IATURC2); 706 707 PCIE_CONF_LOCK(s); 708 709 u_int saved = data_abort_handler_address; 710 data_abort_handler_address = (u_int)imxpcie_data_abort_handler; 711 data_abort_flag = false; 712 713 ret = bus_space_read_4(sc->sc_iot, bsh, offset & ~0x3); 714 715 data_abort_handler_address = saved; 716 717 PCIE_CONF_UNLOCK(s); 718 719 if (data_abort_flag) 720 ret = -1; 721 722 return ret; 723} 724 725static void 726imxpcie_conf_write(void *v, pcitag_t tag, int offset, pcireg_t val) 727{ 728 struct imxpcie_softc *sc = v; 729 bus_space_handle_t bsh; 730 int b, d, f; 731 int s; 732 733 imxpcie_decompose_tag(v, tag, &b, &d, &f); 734 735 if ((unsigned int)offset >= PCI_EXTCONF_SIZE) 736 return; 737 if (!imxpcie_valid_device(sc, b, d)) 738 return; 739 740 PCIE_WRITE(sc, PCIE_PL_IATUVR, 0); 741 if (b < 2) 742 PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG0); 743 else 744 PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG1); 745 746 if (b == 0) { 747 bsh = sc->sc_ioh; 748 } else { 749 PCIE_WRITE(sc, PCIE_PL_IATURLTA, tag << 8); 750 bsh = sc->sc_root_ioh; 751 } 752 PCIE_READ(sc, PCIE_PL_IATURC2); 753 754 PCIE_CONF_LOCK(s); 755 756 u_int saved = data_abort_handler_address; 757 data_abort_handler_address = (u_int)imxpcie_data_abort_handler; 758 759 bus_space_write_4(sc->sc_iot, bsh, offset & ~0x3, val); 760 761 data_abort_handler_address = saved; 762 763 PCIE_CONF_UNLOCK(s); 764 765 return; 766} 767 768#ifdef __HAVE_PCI_CONF_HOOK 769static int 770imxpcie_conf_hook(void *v, int b, int d, int f, pcireg_t id) 771{ 772 return PCI_CONF_DEFAULT; 773} 774#endif 775 776static void 777imxpcie_conf_interrupt(void *v, int bus, int dev, int ipin, int swiz, 778 int *ilinep) 779{ 780 /* nothing to do */ 781} 782 783static int 784imxpcie_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ih) 785{ 786 if (pa->pa_intrpin == 0) 787 return EINVAL; 788 *ih = pa->pa_intrpin; 789 return 0; 790} 791 792static const char * 793imxpcie_intr_string(void *v, pci_intr_handle_t ih, char *buf, size_t len) 794{ 795 if (ih == PCI_INTERRUPT_PIN_NONE) 796 return NULL; 797 798 snprintf(buf, len, "pci"); 799 800 return buf; 801} 802 803const struct evcnt * 804imxpcie_intr_evcnt(void *v, pci_intr_handle_t ih) 805{ 806 return NULL; 807} 808 809static void * 810imxpcie_intr_establish(void *v, pci_intr_handle_t ih, int ipl, 811 int (*callback)(void *), void *arg, const char *xname) 812{ 813 struct imxpcie_softc *sc = v; 814 struct imxpcie_ih *pcie_ih; 815 816 if (ih == 0) 817 return NULL; 818 819 pcie_ih = kmem_alloc(sizeof(*pcie_ih), KM_SLEEP); 820 pcie_ih->ih_handler = callback; 821 pcie_ih->ih_arg = arg; 822 pcie_ih->ih_ipl = ipl; 823 824 mutex_enter(&sc->sc_lock); 825 TAILQ_INSERT_TAIL(&sc->sc_intrs, pcie_ih, ih_entry); 826 sc->sc_intrgen++; 827 mutex_exit(&sc->sc_lock); 828 829 return pcie_ih; 830} 831 832static void 833imxpcie_intr_disestablish(void *v, void *vih) 834{ 835 struct imxpcie_softc *sc = v; 836 struct imxpcie_ih *pcie_ih = vih; 837 838 mutex_enter(&sc->sc_lock); 839 TAILQ_REMOVE(&sc->sc_intrs, pcie_ih, ih_entry); 840 sc->sc_intrgen++; 841 mutex_exit(&sc->sc_lock); 842 843 kmem_free(pcie_ih, sizeof(*pcie_ih)); 844} 845