diff options
Diffstat (limited to 'drivers/pci/host/pci-imx6.c')
-rw-r--r-- | drivers/pci/host/pci-imx6.c | 225 |
1 files changed, 145 insertions, 80 deletions
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index bd70af8f31ac..e8663a8c3406 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c | |||
@@ -44,10 +44,18 @@ struct imx6_pcie { | |||
44 | void __iomem *mem_base; | 44 | void __iomem *mem_base; |
45 | }; | 45 | }; |
46 | 46 | ||
47 | /* PCIe Root Complex registers (memory-mapped) */ | ||
48 | #define PCIE_RC_LCR 0x7c | ||
49 | #define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1 0x1 | ||
50 | #define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2 0x2 | ||
51 | #define PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK 0xf | ||
52 | |||
47 | /* PCIe Port Logic registers (memory-mapped) */ | 53 | /* PCIe Port Logic registers (memory-mapped) */ |
48 | #define PL_OFFSET 0x700 | 54 | #define PL_OFFSET 0x700 |
49 | #define PCIE_PHY_DEBUG_R0 (PL_OFFSET + 0x28) | 55 | #define PCIE_PHY_DEBUG_R0 (PL_OFFSET + 0x28) |
50 | #define PCIE_PHY_DEBUG_R1 (PL_OFFSET + 0x2c) | 56 | #define PCIE_PHY_DEBUG_R1 (PL_OFFSET + 0x2c) |
57 | #define PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING (1 << 29) | ||
58 | #define PCIE_PHY_DEBUG_R1_XMLH_LINK_UP (1 << 4) | ||
51 | 59 | ||
52 | #define PCIE_PHY_CTRL (PL_OFFSET + 0x114) | 60 | #define PCIE_PHY_CTRL (PL_OFFSET + 0x114) |
53 | #define PCIE_PHY_CTRL_DATA_LOC 0 | 61 | #define PCIE_PHY_CTRL_DATA_LOC 0 |
@@ -59,6 +67,9 @@ struct imx6_pcie { | |||
59 | #define PCIE_PHY_STAT (PL_OFFSET + 0x110) | 67 | #define PCIE_PHY_STAT (PL_OFFSET + 0x110) |
60 | #define PCIE_PHY_STAT_ACK_LOC 16 | 68 | #define PCIE_PHY_STAT_ACK_LOC 16 |
61 | 69 | ||
70 | #define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C | ||
71 | #define PORT_LOGIC_SPEED_CHANGE (0x1 << 17) | ||
72 | |||
62 | /* PHY registers (not memory-mapped) */ | 73 | /* PHY registers (not memory-mapped) */ |
63 | #define PCIE_PHY_RX_ASIC_OUT 0x100D | 74 | #define PCIE_PHY_RX_ASIC_OUT 0x100D |
64 | 75 | ||
@@ -209,15 +220,9 @@ static int imx6_pcie_assert_core_reset(struct pcie_port *pp) | |||
209 | 220 | ||
210 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, | 221 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, |
211 | IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18); | 222 | IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18); |
212 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, | ||
213 | IMX6Q_GPR12_PCIE_CTL_2, 1 << 10); | ||
214 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, | 223 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, |
215 | IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16); | 224 | IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16); |
216 | 225 | ||
217 | gpio_set_value(imx6_pcie->reset_gpio, 0); | ||
218 | msleep(100); | ||
219 | gpio_set_value(imx6_pcie->reset_gpio, 1); | ||
220 | |||
221 | return 0; | 226 | return 0; |
222 | } | 227 | } |
223 | 228 | ||
@@ -261,6 +266,12 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp) | |||
261 | /* allow the clocks to stabilize */ | 266 | /* allow the clocks to stabilize */ |
262 | usleep_range(200, 500); | 267 | usleep_range(200, 500); |
263 | 268 | ||
269 | /* Some boards don't have PCIe reset GPIO. */ | ||
270 | if (gpio_is_valid(imx6_pcie->reset_gpio)) { | ||
271 | gpio_set_value(imx6_pcie->reset_gpio, 0); | ||
272 | msleep(100); | ||
273 | gpio_set_value(imx6_pcie->reset_gpio, 1); | ||
274 | } | ||
264 | return 0; | 275 | return 0; |
265 | 276 | ||
266 | err_pcie_axi: | 277 | err_pcie_axi: |
@@ -299,11 +310,90 @@ static void imx6_pcie_init_phy(struct pcie_port *pp) | |||
299 | IMX6Q_GPR8_TX_SWING_LOW, 127 << 25); | 310 | IMX6Q_GPR8_TX_SWING_LOW, 127 << 25); |
300 | } | 311 | } |
301 | 312 | ||
302 | static void imx6_pcie_host_init(struct pcie_port *pp) | 313 | static int imx6_pcie_wait_for_link(struct pcie_port *pp) |
314 | { | ||
315 | int count = 200; | ||
316 | |||
317 | while (!dw_pcie_link_up(pp)) { | ||
318 | usleep_range(100, 1000); | ||
319 | if (--count) | ||
320 | continue; | ||
321 | |||
322 | dev_err(pp->dev, "phy link never came up\n"); | ||
323 | dev_dbg(pp->dev, "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n", | ||
324 | readl(pp->dbi_base + PCIE_PHY_DEBUG_R0), | ||
325 | readl(pp->dbi_base + PCIE_PHY_DEBUG_R1)); | ||
326 | return -EINVAL; | ||
327 | } | ||
328 | |||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | static int imx6_pcie_start_link(struct pcie_port *pp) | ||
303 | { | 333 | { |
304 | int count = 0; | ||
305 | struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp); | 334 | struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp); |
335 | uint32_t tmp; | ||
336 | int ret, count; | ||
306 | 337 | ||
338 | /* | ||
339 | * Force Gen1 operation when starting the link. In case the link is | ||
340 | * started in Gen2 mode, there is a possibility the devices on the | ||
341 | * bus will not be detected at all. This happens with PCIe switches. | ||
342 | */ | ||
343 | tmp = readl(pp->dbi_base + PCIE_RC_LCR); | ||
344 | tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK; | ||
345 | tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1; | ||
346 | writel(tmp, pp->dbi_base + PCIE_RC_LCR); | ||
347 | |||
348 | /* Start LTSSM. */ | ||
349 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, | ||
350 | IMX6Q_GPR12_PCIE_CTL_2, 1 << 10); | ||
351 | |||
352 | ret = imx6_pcie_wait_for_link(pp); | ||
353 | if (ret) | ||
354 | return ret; | ||
355 | |||
356 | /* Allow Gen2 mode after the link is up. */ | ||
357 | tmp = readl(pp->dbi_base + PCIE_RC_LCR); | ||
358 | tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK; | ||
359 | tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2; | ||
360 | writel(tmp, pp->dbi_base + PCIE_RC_LCR); | ||
361 | |||
362 | /* | ||
363 | * Start Directed Speed Change so the best possible speed both link | ||
364 | * partners support can be negotiated. | ||
365 | */ | ||
366 | tmp = readl(pp->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL); | ||
367 | tmp |= PORT_LOGIC_SPEED_CHANGE; | ||
368 | writel(tmp, pp->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL); | ||
369 | |||
370 | count = 200; | ||
371 | while (count--) { | ||
372 | tmp = readl(pp->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL); | ||
373 | /* Test if the speed change finished. */ | ||
374 | if (!(tmp & PORT_LOGIC_SPEED_CHANGE)) | ||
375 | break; | ||
376 | usleep_range(100, 1000); | ||
377 | } | ||
378 | |||
379 | /* Make sure link training is finished as well! */ | ||
380 | if (count) | ||
381 | ret = imx6_pcie_wait_for_link(pp); | ||
382 | else | ||
383 | ret = -EINVAL; | ||
384 | |||
385 | if (ret) { | ||
386 | dev_err(pp->dev, "Failed to bring link up!\n"); | ||
387 | } else { | ||
388 | tmp = readl(pp->dbi_base + 0x80); | ||
389 | dev_dbg(pp->dev, "Link up, Gen=%i\n", (tmp >> 16) & 0xf); | ||
390 | } | ||
391 | |||
392 | return ret; | ||
393 | } | ||
394 | |||
395 | static void imx6_pcie_host_init(struct pcie_port *pp) | ||
396 | { | ||
307 | imx6_pcie_assert_core_reset(pp); | 397 | imx6_pcie_assert_core_reset(pp); |
308 | 398 | ||
309 | imx6_pcie_init_phy(pp); | 399 | imx6_pcie_init_phy(pp); |
@@ -312,33 +402,41 @@ static void imx6_pcie_host_init(struct pcie_port *pp) | |||
312 | 402 | ||
313 | dw_pcie_setup_rc(pp); | 403 | dw_pcie_setup_rc(pp); |
314 | 404 | ||
315 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, | 405 | imx6_pcie_start_link(pp); |
316 | IMX6Q_GPR12_PCIE_CTL_2, 1 << 10); | 406 | } |
317 | 407 | ||
318 | while (!dw_pcie_link_up(pp)) { | 408 | static void imx6_pcie_reset_phy(struct pcie_port *pp) |
319 | usleep_range(100, 1000); | 409 | { |
320 | count++; | 410 | uint32_t temp; |
321 | if (count >= 200) { | 411 | |
322 | dev_err(pp->dev, "phy link never came up\n"); | 412 | pcie_phy_read(pp->dbi_base, PHY_RX_OVRD_IN_LO, &temp); |
323 | dev_dbg(pp->dev, | 413 | temp |= (PHY_RX_OVRD_IN_LO_RX_DATA_EN | |
324 | "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n", | 414 | PHY_RX_OVRD_IN_LO_RX_PLL_EN); |
325 | readl(pp->dbi_base + PCIE_PHY_DEBUG_R0), | 415 | pcie_phy_write(pp->dbi_base, PHY_RX_OVRD_IN_LO, temp); |
326 | readl(pp->dbi_base + PCIE_PHY_DEBUG_R1)); | 416 | |
327 | break; | 417 | usleep_range(2000, 3000); |
328 | } | ||
329 | } | ||
330 | 418 | ||
331 | return; | 419 | pcie_phy_read(pp->dbi_base, PHY_RX_OVRD_IN_LO, &temp); |
420 | temp &= ~(PHY_RX_OVRD_IN_LO_RX_DATA_EN | | ||
421 | PHY_RX_OVRD_IN_LO_RX_PLL_EN); | ||
422 | pcie_phy_write(pp->dbi_base, PHY_RX_OVRD_IN_LO, temp); | ||
332 | } | 423 | } |
333 | 424 | ||
334 | static int imx6_pcie_link_up(struct pcie_port *pp) | 425 | static int imx6_pcie_link_up(struct pcie_port *pp) |
335 | { | 426 | { |
336 | u32 rc, ltssm, rx_valid, temp; | 427 | u32 rc, ltssm, rx_valid; |
337 | 428 | ||
338 | /* link is debug bit 36, debug register 1 starts at bit 32 */ | 429 | /* |
339 | rc = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1) & (0x1 << (36 - 32)); | 430 | * Test if the PHY reports that the link is up and also that |
340 | if (rc) | 431 | * the link training finished. It might happen that the PHY |
341 | return -EAGAIN; | 432 | * reports the link is already up, but the link training bit |
433 | * is still set, so make sure to check the training is done | ||
434 | * as well here. | ||
435 | */ | ||
436 | rc = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1); | ||
437 | if ((rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP) && | ||
438 | !(rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING)) | ||
439 | return 1; | ||
342 | 440 | ||
343 | /* | 441 | /* |
344 | * From L0, initiate MAC entry to gen2 if EP/RC supports gen2. | 442 | * From L0, initiate MAC entry to gen2 if EP/RC supports gen2. |
@@ -358,21 +456,7 @@ static int imx6_pcie_link_up(struct pcie_port *pp) | |||
358 | 456 | ||
359 | dev_err(pp->dev, "transition to gen2 is stuck, reset PHY!\n"); | 457 | dev_err(pp->dev, "transition to gen2 is stuck, reset PHY!\n"); |
360 | 458 | ||
361 | pcie_phy_read(pp->dbi_base, | 459 | imx6_pcie_reset_phy(pp); |
362 | PHY_RX_OVRD_IN_LO, &temp); | ||
363 | temp |= (PHY_RX_OVRD_IN_LO_RX_DATA_EN | ||
364 | | PHY_RX_OVRD_IN_LO_RX_PLL_EN); | ||
365 | pcie_phy_write(pp->dbi_base, | ||
366 | PHY_RX_OVRD_IN_LO, temp); | ||
367 | |||
368 | usleep_range(2000, 3000); | ||
369 | |||
370 | pcie_phy_read(pp->dbi_base, | ||
371 | PHY_RX_OVRD_IN_LO, &temp); | ||
372 | temp &= ~(PHY_RX_OVRD_IN_LO_RX_DATA_EN | ||
373 | | PHY_RX_OVRD_IN_LO_RX_PLL_EN); | ||
374 | pcie_phy_write(pp->dbi_base, | ||
375 | PHY_RX_OVRD_IN_LO, temp); | ||
376 | 460 | ||
377 | return 0; | 461 | return 0; |
378 | } | 462 | } |
@@ -426,30 +510,19 @@ static int __init imx6_pcie_probe(struct platform_device *pdev) | |||
426 | "imprecise external abort"); | 510 | "imprecise external abort"); |
427 | 511 | ||
428 | dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 512 | dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
429 | if (!dbi_base) { | ||
430 | dev_err(&pdev->dev, "dbi_base memory resource not found\n"); | ||
431 | return -ENODEV; | ||
432 | } | ||
433 | |||
434 | pp->dbi_base = devm_ioremap_resource(&pdev->dev, dbi_base); | 513 | pp->dbi_base = devm_ioremap_resource(&pdev->dev, dbi_base); |
435 | if (IS_ERR(pp->dbi_base)) { | 514 | if (IS_ERR(pp->dbi_base)) |
436 | ret = PTR_ERR(pp->dbi_base); | 515 | return PTR_ERR(pp->dbi_base); |
437 | goto err; | ||
438 | } | ||
439 | 516 | ||
440 | /* Fetch GPIOs */ | 517 | /* Fetch GPIOs */ |
441 | imx6_pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); | 518 | imx6_pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); |
442 | if (!gpio_is_valid(imx6_pcie->reset_gpio)) { | 519 | if (gpio_is_valid(imx6_pcie->reset_gpio)) { |
443 | dev_err(&pdev->dev, "no reset-gpio defined\n"); | 520 | ret = devm_gpio_request_one(&pdev->dev, imx6_pcie->reset_gpio, |
444 | ret = -ENODEV; | 521 | GPIOF_OUT_INIT_LOW, "PCIe reset"); |
445 | } | 522 | if (ret) { |
446 | ret = devm_gpio_request_one(&pdev->dev, | 523 | dev_err(&pdev->dev, "unable to get reset gpio\n"); |
447 | imx6_pcie->reset_gpio, | 524 | return ret; |
448 | GPIOF_OUT_INIT_LOW, | 525 | } |
449 | "PCIe reset"); | ||
450 | if (ret) { | ||
451 | dev_err(&pdev->dev, "unable to get reset gpio\n"); | ||
452 | goto err; | ||
453 | } | 526 | } |
454 | 527 | ||
455 | imx6_pcie->power_on_gpio = of_get_named_gpio(np, "power-on-gpio", 0); | 528 | imx6_pcie->power_on_gpio = of_get_named_gpio(np, "power-on-gpio", 0); |
@@ -460,7 +533,7 @@ static int __init imx6_pcie_probe(struct platform_device *pdev) | |||
460 | "PCIe power enable"); | 533 | "PCIe power enable"); |
461 | if (ret) { | 534 | if (ret) { |
462 | dev_err(&pdev->dev, "unable to get power-on gpio\n"); | 535 | dev_err(&pdev->dev, "unable to get power-on gpio\n"); |
463 | goto err; | 536 | return ret; |
464 | } | 537 | } |
465 | } | 538 | } |
466 | 539 | ||
@@ -472,7 +545,7 @@ static int __init imx6_pcie_probe(struct platform_device *pdev) | |||
472 | "PCIe wake up"); | 545 | "PCIe wake up"); |
473 | if (ret) { | 546 | if (ret) { |
474 | dev_err(&pdev->dev, "unable to get wake-up gpio\n"); | 547 | dev_err(&pdev->dev, "unable to get wake-up gpio\n"); |
475 | goto err; | 548 | return ret; |
476 | } | 549 | } |
477 | } | 550 | } |
478 | 551 | ||
@@ -484,7 +557,7 @@ static int __init imx6_pcie_probe(struct platform_device *pdev) | |||
484 | "PCIe disable endpoint"); | 557 | "PCIe disable endpoint"); |
485 | if (ret) { | 558 | if (ret) { |
486 | dev_err(&pdev->dev, "unable to get disable-ep gpio\n"); | 559 | dev_err(&pdev->dev, "unable to get disable-ep gpio\n"); |
487 | goto err; | 560 | return ret; |
488 | } | 561 | } |
489 | } | 562 | } |
490 | 563 | ||
@@ -493,32 +566,28 @@ static int __init imx6_pcie_probe(struct platform_device *pdev) | |||
493 | if (IS_ERR(imx6_pcie->lvds_gate)) { | 566 | if (IS_ERR(imx6_pcie->lvds_gate)) { |
494 | dev_err(&pdev->dev, | 567 | dev_err(&pdev->dev, |
495 | "lvds_gate clock select missing or invalid\n"); | 568 | "lvds_gate clock select missing or invalid\n"); |
496 | ret = PTR_ERR(imx6_pcie->lvds_gate); | 569 | return PTR_ERR(imx6_pcie->lvds_gate); |
497 | goto err; | ||
498 | } | 570 | } |
499 | 571 | ||
500 | imx6_pcie->sata_ref_100m = devm_clk_get(&pdev->dev, "sata_ref_100m"); | 572 | imx6_pcie->sata_ref_100m = devm_clk_get(&pdev->dev, "sata_ref_100m"); |
501 | if (IS_ERR(imx6_pcie->sata_ref_100m)) { | 573 | if (IS_ERR(imx6_pcie->sata_ref_100m)) { |
502 | dev_err(&pdev->dev, | 574 | dev_err(&pdev->dev, |
503 | "sata_ref_100m clock source missing or invalid\n"); | 575 | "sata_ref_100m clock source missing or invalid\n"); |
504 | ret = PTR_ERR(imx6_pcie->sata_ref_100m); | 576 | return PTR_ERR(imx6_pcie->sata_ref_100m); |
505 | goto err; | ||
506 | } | 577 | } |
507 | 578 | ||
508 | imx6_pcie->pcie_ref_125m = devm_clk_get(&pdev->dev, "pcie_ref_125m"); | 579 | imx6_pcie->pcie_ref_125m = devm_clk_get(&pdev->dev, "pcie_ref_125m"); |
509 | if (IS_ERR(imx6_pcie->pcie_ref_125m)) { | 580 | if (IS_ERR(imx6_pcie->pcie_ref_125m)) { |
510 | dev_err(&pdev->dev, | 581 | dev_err(&pdev->dev, |
511 | "pcie_ref_125m clock source missing or invalid\n"); | 582 | "pcie_ref_125m clock source missing or invalid\n"); |
512 | ret = PTR_ERR(imx6_pcie->pcie_ref_125m); | 583 | return PTR_ERR(imx6_pcie->pcie_ref_125m); |
513 | goto err; | ||
514 | } | 584 | } |
515 | 585 | ||
516 | imx6_pcie->pcie_axi = devm_clk_get(&pdev->dev, "pcie_axi"); | 586 | imx6_pcie->pcie_axi = devm_clk_get(&pdev->dev, "pcie_axi"); |
517 | if (IS_ERR(imx6_pcie->pcie_axi)) { | 587 | if (IS_ERR(imx6_pcie->pcie_axi)) { |
518 | dev_err(&pdev->dev, | 588 | dev_err(&pdev->dev, |
519 | "pcie_axi clock source missing or invalid\n"); | 589 | "pcie_axi clock source missing or invalid\n"); |
520 | ret = PTR_ERR(imx6_pcie->pcie_axi); | 590 | return PTR_ERR(imx6_pcie->pcie_axi); |
521 | goto err; | ||
522 | } | 591 | } |
523 | 592 | ||
524 | /* Grab GPR config register range */ | 593 | /* Grab GPR config register range */ |
@@ -526,19 +595,15 @@ static int __init imx6_pcie_probe(struct platform_device *pdev) | |||
526 | syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr"); | 595 | syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr"); |
527 | if (IS_ERR(imx6_pcie->iomuxc_gpr)) { | 596 | if (IS_ERR(imx6_pcie->iomuxc_gpr)) { |
528 | dev_err(&pdev->dev, "unable to find iomuxc registers\n"); | 597 | dev_err(&pdev->dev, "unable to find iomuxc registers\n"); |
529 | ret = PTR_ERR(imx6_pcie->iomuxc_gpr); | 598 | return PTR_ERR(imx6_pcie->iomuxc_gpr); |
530 | goto err; | ||
531 | } | 599 | } |
532 | 600 | ||
533 | ret = imx6_add_pcie_port(pp, pdev); | 601 | ret = imx6_add_pcie_port(pp, pdev); |
534 | if (ret < 0) | 602 | if (ret < 0) |
535 | goto err; | 603 | return ret; |
536 | 604 | ||
537 | platform_set_drvdata(pdev, imx6_pcie); | 605 | platform_set_drvdata(pdev, imx6_pcie); |
538 | return 0; | 606 | return 0; |
539 | |||
540 | err: | ||
541 | return ret; | ||
542 | } | 607 | } |
543 | 608 | ||
544 | static const struct of_device_id imx6_pcie_of_match[] = { | 609 | static const struct of_device_id imx6_pcie_of_match[] = { |