.. | .. |
---|
34 | 34 | #include <linux/regmap.h> |
---|
35 | 35 | #include <linux/reset.h> |
---|
36 | 36 | #include <linux/resource.h> |
---|
| 37 | +#include <linux/rfkill-wlan.h> |
---|
37 | 38 | #include <linux/signal.h> |
---|
38 | 39 | #include <linux/types.h> |
---|
39 | 40 | #include <linux/uaccess.h> |
---|
.. | .. |
---|
53 | 54 | const char *id; |
---|
54 | 55 | struct reset_control *rst; |
---|
55 | 56 | }; |
---|
| 57 | + |
---|
| 58 | +#define RK_PCIE_DBG 0 |
---|
56 | 59 | |
---|
57 | 60 | #define PCIE_DMA_OFFSET 0x380000 |
---|
58 | 61 | |
---|
.. | .. |
---|
120 | 123 | #define PCIE_CLIENT_DBG_FIFO_STATUS 0x350 |
---|
121 | 124 | #define PCIE_CLIENT_DBG_TRANSITION_DATA 0xffff0000 |
---|
122 | 125 | #define PCIE_CLIENT_DBF_EN 0xffff0003 |
---|
123 | | -#define RK_PCIE_DBG 0 |
---|
124 | 126 | |
---|
125 | 127 | #define PCIE_PHY_LINKUP BIT(0) |
---|
126 | 128 | #define PCIE_DATA_LINKUP BIT(1) |
---|
.. | .. |
---|
147 | 149 | unsigned int clk_cnt; |
---|
148 | 150 | struct reset_bulk_data *rsts; |
---|
149 | 151 | struct gpio_desc *rst_gpio; |
---|
| 152 | + struct gpio_desc *prsnt_gpio; |
---|
150 | 153 | phys_addr_t mem_start; |
---|
151 | 154 | size_t mem_size; |
---|
152 | 155 | struct pcie_port pp; |
---|
.. | .. |
---|
154 | 157 | struct regmap *pmu_grf; |
---|
155 | 158 | struct dma_trx_obj *dma_obj; |
---|
156 | 159 | bool in_suspend; |
---|
| 160 | + bool skip_scan_in_resume; |
---|
157 | 161 | bool is_rk1808; |
---|
158 | 162 | bool is_signal_test; |
---|
159 | 163 | bool bifurcation; |
---|
.. | .. |
---|
161 | 165 | struct irq_domain *irq_domain; |
---|
162 | 166 | raw_spinlock_t intx_lock; |
---|
163 | 167 | struct dentry *debugfs; |
---|
| 168 | + u32 msi_vector_num; |
---|
164 | 169 | }; |
---|
165 | 170 | |
---|
166 | 171 | struct rk_pcie_of_data { |
---|
167 | 172 | enum rk_pcie_device_mode mode; |
---|
| 173 | + u32 msi_vector_num; |
---|
168 | 174 | }; |
---|
169 | 175 | |
---|
170 | 176 | #define to_rk_pcie(x) dev_get_drvdata((x)->dev) |
---|
.. | .. |
---|
410 | 416 | return 1; |
---|
411 | 417 | } else { |
---|
412 | 418 | val = rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS); |
---|
413 | | - if ((val & (RDLH_LINKUP | SMLH_LINKUP)) == 0x30000 && |
---|
414 | | - (val & GENMASK(5, 0)) == 0x11) |
---|
| 419 | + if ((val & (RDLH_LINKUP | SMLH_LINKUP)) == 0x30000) |
---|
415 | 420 | return 1; |
---|
416 | 421 | } |
---|
417 | 422 | |
---|
.. | .. |
---|
453 | 458 | |
---|
454 | 459 | static int rk_pcie_establish_link(struct dw_pcie *pci) |
---|
455 | 460 | { |
---|
456 | | - int retries; |
---|
| 461 | + int retries, power; |
---|
457 | 462 | struct rk_pcie *rk_pcie = to_rk_pcie(pci); |
---|
| 463 | + bool std_rc = rk_pcie->mode == RK_PCIE_RC_TYPE && !rk_pcie->dma_obj; |
---|
458 | 464 | |
---|
459 | | - if (dw_pcie_link_up(pci)) { |
---|
| 465 | + /* |
---|
| 466 | + * For standard RC, even if the link has been setup by firmware, |
---|
| 467 | + * we still need to reset link as we need to remove all resource info |
---|
| 468 | + * from devices, for instance BAR, as it wasn't assigned by kernel. |
---|
| 469 | + */ |
---|
| 470 | + if (dw_pcie_link_up(pci) && !std_rc) { |
---|
460 | 471 | dev_err(pci->dev, "link is already up\n"); |
---|
461 | 472 | return 0; |
---|
462 | 473 | } |
---|
.. | .. |
---|
472 | 483 | rk_pcie_enable_ltssm(rk_pcie); |
---|
473 | 484 | |
---|
474 | 485 | /* |
---|
| 486 | + * In resume routine, function devices' resume function must be late after |
---|
| 487 | + * controllers'. Some devices, such as Wi-Fi, need special IO setting before |
---|
| 488 | + * finishing training. So there must be timeout here. These kinds of devices |
---|
| 489 | + * need rescan devices by its driver when used. So no need to waste time waiting |
---|
| 490 | + * for training pass. |
---|
| 491 | + */ |
---|
| 492 | + if (rk_pcie->in_suspend && rk_pcie->skip_scan_in_resume) { |
---|
| 493 | + rfkill_get_wifi_power_state(&power); |
---|
| 494 | + if (!power) { |
---|
| 495 | + gpiod_set_value_cansleep(rk_pcie->rst_gpio, 1); |
---|
| 496 | + return 0; |
---|
| 497 | + } |
---|
| 498 | + } |
---|
| 499 | + |
---|
| 500 | + /* |
---|
475 | 501 | * PCIe requires the refclk to be stable for 100µs prior to releasing |
---|
476 | 502 | * PERST and T_PVPERL (Power stable to PERST# inactive) should be a |
---|
477 | 503 | * minimum of 100ms. See table 2-4 in section 2.6.2 AC, the PCI Express |
---|
.. | .. |
---|
480 | 506 | */ |
---|
481 | 507 | msleep(1000); |
---|
482 | 508 | gpiod_set_value_cansleep(rk_pcie->rst_gpio, 1); |
---|
| 509 | + |
---|
| 510 | + /* |
---|
| 511 | + * Add this 1ms delay because we observe link is always up stably after it and |
---|
| 512 | + * could help us save 20ms for scanning devices. |
---|
| 513 | + */ |
---|
| 514 | + usleep_range(1000, 1100); |
---|
483 | 515 | |
---|
484 | 516 | for (retries = 0; retries < 10; retries++) { |
---|
485 | 517 | if (dw_pcie_link_up(pci)) { |
---|
.. | .. |
---|
516 | 548 | return -EINVAL; |
---|
517 | 549 | } |
---|
518 | 550 | |
---|
519 | | - rk_pcie->dma_obj = pcie_dw_dmatest_register(rk_pcie->pci, true); |
---|
| 551 | + rk_pcie->dma_obj = pcie_dw_dmatest_register(rk_pcie->pci->dev, true); |
---|
520 | 552 | if (IS_ERR(rk_pcie->dma_obj)) { |
---|
521 | 553 | dev_err(rk_pcie->pci->dev, "failed to prepare dmatest\n"); |
---|
522 | 554 | return -EINVAL; |
---|
.. | .. |
---|
675 | 707 | return 0; |
---|
676 | 708 | } |
---|
677 | 709 | |
---|
| 710 | +static void rk_pcie_msi_set_num_vectors(struct pcie_port *pp) |
---|
| 711 | +{ |
---|
| 712 | + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
---|
| 713 | + struct rk_pcie *rk_pcie = to_rk_pcie(pci); |
---|
| 714 | + |
---|
| 715 | + pp->num_vectors = rk_pcie->msi_vector_num; |
---|
| 716 | +} |
---|
| 717 | + |
---|
678 | 718 | static int rk_pcie_host_init(struct pcie_port *pp) |
---|
679 | 719 | { |
---|
680 | 720 | int ret; |
---|
.. | .. |
---|
707 | 747 | if (pp->msi_irq < 0) { |
---|
708 | 748 | dev_info(dev, "use outband MSI support"); |
---|
709 | 749 | rk_pcie_host_ops.msi_host_init = rk_pcie_msi_host_init; |
---|
| 750 | + } else { |
---|
| 751 | + dev_info(dev, "max MSI vector is %d\n", rk_pcie->msi_vector_num); |
---|
| 752 | + rk_pcie_host_ops.set_num_vectors = rk_pcie_msi_set_num_vectors; |
---|
710 | 753 | } |
---|
711 | 754 | } |
---|
712 | 755 | |
---|
.. | .. |
---|
864 | 907 | dev_err(&pdev->dev, "invalid reset-gpios property in node\n"); |
---|
865 | 908 | return PTR_ERR(rk_pcie->rst_gpio); |
---|
866 | 909 | } |
---|
| 910 | + |
---|
| 911 | + rk_pcie->prsnt_gpio = devm_gpiod_get_optional(&pdev->dev, "prsnt", GPIOD_IN); |
---|
| 912 | + if (IS_ERR_OR_NULL(rk_pcie->prsnt_gpio)) |
---|
| 913 | + dev_info(&pdev->dev, "invalid prsnt-gpios property in node\n"); |
---|
867 | 914 | |
---|
868 | 915 | return 0; |
---|
869 | 916 | } |
---|
.. | .. |
---|
1149 | 1196 | .mode = RK_PCIE_EP_TYPE, |
---|
1150 | 1197 | }; |
---|
1151 | 1198 | |
---|
| 1199 | +static const struct rk_pcie_of_data rk3528_pcie_rc_of_data = { |
---|
| 1200 | + .mode = RK_PCIE_RC_TYPE, |
---|
| 1201 | + .msi_vector_num = 8, |
---|
| 1202 | +}; |
---|
| 1203 | + |
---|
1152 | 1204 | static const struct of_device_id rk_pcie_of_match[] = { |
---|
1153 | 1205 | { |
---|
1154 | 1206 | .compatible = "rockchip,rk1808-pcie", |
---|
.. | .. |
---|
1157 | 1209 | { |
---|
1158 | 1210 | .compatible = "rockchip,rk1808-pcie-ep", |
---|
1159 | 1211 | .data = &rk_pcie_ep_of_data, |
---|
| 1212 | + }, |
---|
| 1213 | + { |
---|
| 1214 | + .compatible = "rockchip,rk3528-pcie", |
---|
| 1215 | + .data = &rk3528_pcie_rc_of_data, |
---|
1160 | 1216 | }, |
---|
1161 | 1217 | { |
---|
1162 | 1218 | .compatible = "rockchip,rk3568-pcie", |
---|
.. | .. |
---|
1529 | 1585 | enum rk_pcie_device_mode mode; |
---|
1530 | 1586 | struct device_node *np = pdev->dev.of_node; |
---|
1531 | 1587 | struct platform_driver *drv = to_platform_driver(dev->driver); |
---|
1532 | | - u32 val; |
---|
| 1588 | + u32 val = 0; |
---|
1533 | 1589 | int irq; |
---|
1534 | 1590 | |
---|
1535 | 1591 | match = of_match_device(rk_pcie_of_match, dev); |
---|
1536 | | - if (!match) |
---|
1537 | | - return -EINVAL; |
---|
| 1592 | + if (!match) { |
---|
| 1593 | + ret = -EINVAL; |
---|
| 1594 | + goto release_driver; |
---|
| 1595 | + } |
---|
1538 | 1596 | |
---|
1539 | 1597 | data = (struct rk_pcie_of_data *)match->data; |
---|
1540 | 1598 | mode = (enum rk_pcie_device_mode)data->mode; |
---|
1541 | 1599 | |
---|
1542 | 1600 | rk_pcie = devm_kzalloc(dev, sizeof(*rk_pcie), GFP_KERNEL); |
---|
1543 | | - if (!rk_pcie) |
---|
1544 | | - return -ENOMEM; |
---|
| 1601 | + if (!rk_pcie) { |
---|
| 1602 | + ret = -ENOMEM; |
---|
| 1603 | + goto release_driver; |
---|
| 1604 | + } |
---|
1545 | 1605 | |
---|
1546 | 1606 | pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); |
---|
1547 | | - if (!pci) |
---|
1548 | | - return -ENOMEM; |
---|
| 1607 | + if (!pci) { |
---|
| 1608 | + ret = -ENOMEM; |
---|
| 1609 | + goto release_driver; |
---|
| 1610 | + } |
---|
1549 | 1611 | |
---|
1550 | 1612 | pci->dev = dev; |
---|
1551 | 1613 | pci->ops = &dw_pcie_ops; |
---|
1552 | 1614 | |
---|
1553 | 1615 | rk_pcie->mode = mode; |
---|
| 1616 | + rk_pcie->msi_vector_num = data->msi_vector_num; |
---|
1554 | 1617 | rk_pcie->pci = pci; |
---|
1555 | 1618 | |
---|
1556 | 1619 | if (of_device_is_compatible(np, "rockchip,rk1808-pcie") || |
---|
.. | .. |
---|
1565 | 1628 | ret = rk_pcie_resource_get(pdev, rk_pcie); |
---|
1566 | 1629 | if (ret) { |
---|
1567 | 1630 | dev_err(dev, "resource init failed\n"); |
---|
1568 | | - return ret; |
---|
| 1631 | + goto release_driver; |
---|
1569 | 1632 | } |
---|
1570 | 1633 | |
---|
| 1634 | + if (!IS_ERR_OR_NULL(rk_pcie->prsnt_gpio)) { |
---|
| 1635 | + if (!gpiod_get_value(rk_pcie->prsnt_gpio)) { |
---|
| 1636 | + ret = -ENODEV; |
---|
| 1637 | + goto release_driver; |
---|
| 1638 | + } |
---|
| 1639 | + } |
---|
| 1640 | + |
---|
| 1641 | +retry_regulator: |
---|
1571 | 1642 | /* DON'T MOVE ME: must be enable before phy init */ |
---|
1572 | 1643 | rk_pcie->vpcie3v3 = devm_regulator_get_optional(dev, "vpcie3v3"); |
---|
1573 | 1644 | if (IS_ERR(rk_pcie->vpcie3v3)) { |
---|
1574 | | - if (PTR_ERR(rk_pcie->vpcie3v3) != -ENODEV) |
---|
1575 | | - return PTR_ERR(rk_pcie->vpcie3v3); |
---|
| 1645 | + if (PTR_ERR(rk_pcie->vpcie3v3) != -ENODEV) { |
---|
| 1646 | + if (IS_ENABLED(CONFIG_PCIE_RK_THREADED_INIT)) { |
---|
| 1647 | + /* Deferred but in threaded context for most 10s */ |
---|
| 1648 | + msleep(20); |
---|
| 1649 | + if (++val < 500) |
---|
| 1650 | + goto retry_regulator; |
---|
| 1651 | + } |
---|
| 1652 | + |
---|
| 1653 | + ret = PTR_ERR(rk_pcie->vpcie3v3); |
---|
| 1654 | + goto release_driver; |
---|
| 1655 | + } |
---|
| 1656 | + |
---|
1576 | 1657 | dev_info(dev, "no vpcie3v3 regulator found\n"); |
---|
1577 | 1658 | } |
---|
1578 | 1659 | |
---|
1579 | 1660 | ret = rk_pcie_enable_power(rk_pcie); |
---|
1580 | 1661 | if (ret) |
---|
1581 | | - return ret; |
---|
| 1662 | + goto release_driver; |
---|
1582 | 1663 | |
---|
1583 | 1664 | ret = rk_pcie_phy_init(rk_pcie); |
---|
1584 | 1665 | if (ret) { |
---|
.. | .. |
---|
1589 | 1670 | ret = rk_pcie_reset_control_release(rk_pcie); |
---|
1590 | 1671 | if (ret) { |
---|
1591 | 1672 | dev_err(dev, "reset control init failed\n"); |
---|
1592 | | - goto disable_vpcie3v3; |
---|
| 1673 | + goto disable_phy; |
---|
1593 | 1674 | } |
---|
1594 | 1675 | |
---|
1595 | 1676 | ret = rk_pcie_request_sys_irq(rk_pcie, pdev); |
---|
1596 | 1677 | if (ret) { |
---|
1597 | 1678 | dev_err(dev, "pcie irq init failed\n"); |
---|
1598 | | - goto disable_vpcie3v3; |
---|
| 1679 | + goto disable_phy; |
---|
1599 | 1680 | } |
---|
1600 | 1681 | |
---|
1601 | 1682 | platform_set_drvdata(pdev, rk_pcie); |
---|
.. | .. |
---|
1603 | 1684 | ret = rk_pcie_clk_init(rk_pcie); |
---|
1604 | 1685 | if (ret) { |
---|
1605 | 1686 | dev_err(dev, "clock init failed\n"); |
---|
1606 | | - goto disable_vpcie3v3; |
---|
| 1687 | + goto disable_phy; |
---|
1607 | 1688 | } |
---|
1608 | 1689 | |
---|
1609 | 1690 | dw_pcie_dbi_ro_wr_en(pci); |
---|
.. | .. |
---|
1626 | 1707 | /* Unmask all legacy interrupt from INTA~INTD */ |
---|
1627 | 1708 | rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK_LEGACY, |
---|
1628 | 1709 | UNMASK_ALL_LEGACY_INT); |
---|
| 1710 | + } else { |
---|
| 1711 | + dev_info(dev, "missing legacy IRQ resource\n"); |
---|
1629 | 1712 | } |
---|
1630 | | - |
---|
1631 | | - dev_info(dev, "missing legacy IRQ resource\n"); |
---|
1632 | 1713 | } |
---|
1633 | 1714 | |
---|
1634 | 1715 | /* Set PCIe mode */ |
---|
.. | .. |
---|
1649 | 1730 | dw_pcie_writel_dbi(pci, PCIE_CAP_LINK_CONTROL2_LINK_STATUS, val); |
---|
1650 | 1731 | rk_pcie->is_signal_test = true; |
---|
1651 | 1732 | } |
---|
| 1733 | + |
---|
| 1734 | + /* Skip waiting for training to pass in system PM routine */ |
---|
| 1735 | + if (device_property_read_bool(dev, "rockchip,skip-scan-in-resume")) |
---|
| 1736 | + rk_pcie->skip_scan_in_resume = true; |
---|
1652 | 1737 | |
---|
1653 | 1738 | switch (rk_pcie->mode) { |
---|
1654 | 1739 | case RK_PCIE_RC_TYPE: |
---|
.. | .. |
---|
1709 | 1794 | remove_irq_domain: |
---|
1710 | 1795 | if (rk_pcie->irq_domain) |
---|
1711 | 1796 | irq_domain_remove(rk_pcie->irq_domain); |
---|
| 1797 | +disable_phy: |
---|
| 1798 | + phy_power_off(rk_pcie->phy); |
---|
| 1799 | + phy_exit(rk_pcie->phy); |
---|
1712 | 1800 | deinit_clk: |
---|
1713 | 1801 | rk_pcie_clk_deinit(rk_pcie); |
---|
1714 | 1802 | disable_vpcie3v3: |
---|
1715 | 1803 | rk_pcie_disable_power(rk_pcie); |
---|
| 1804 | + |
---|
| 1805 | +release_driver: |
---|
| 1806 | + if (IS_ENABLED(CONFIG_PCIE_RK_THREADED_INIT)) |
---|
| 1807 | + device_release_driver(dev); |
---|
1716 | 1808 | |
---|
1717 | 1809 | return ret; |
---|
1718 | 1810 | } |
---|
1719 | 1811 | |
---|
1720 | 1812 | static int rk_pcie_probe(struct platform_device *pdev) |
---|
1721 | 1813 | { |
---|
1722 | | - struct task_struct *tsk; |
---|
| 1814 | + if (IS_ENABLED(CONFIG_PCIE_RK_THREADED_INIT)) { |
---|
| 1815 | + struct task_struct *tsk; |
---|
1723 | 1816 | |
---|
1724 | | - tsk = kthread_run(rk_pcie_really_probe, pdev, "rk-pcie"); |
---|
1725 | | - if (IS_ERR(tsk)) { |
---|
1726 | | - dev_err(&pdev->dev, "start rk-pcie thread failed\n"); |
---|
1727 | | - return PTR_ERR(tsk); |
---|
| 1817 | + tsk = kthread_run(rk_pcie_really_probe, pdev, "rk-pcie"); |
---|
| 1818 | + if (IS_ERR(tsk)) { |
---|
| 1819 | + dev_err(&pdev->dev, "start rk-pcie thread failed\n"); |
---|
| 1820 | + return PTR_ERR(tsk); |
---|
| 1821 | + } |
---|
| 1822 | + |
---|
| 1823 | + return 0; |
---|
1728 | 1824 | } |
---|
1729 | | - return 0; |
---|
| 1825 | + |
---|
| 1826 | + return rk_pcie_really_probe(pdev); |
---|
1730 | 1827 | } |
---|
1731 | 1828 | |
---|
1732 | 1829 | static int __maybe_unused rockchip_dw_pcie_suspend(struct device *dev) |
---|
.. | .. |
---|
1749 | 1846 | |
---|
1750 | 1847 | gpiod_set_value_cansleep(rk_pcie->rst_gpio, 0); |
---|
1751 | 1848 | ret = rk_pcie_disable_power(rk_pcie); |
---|
1752 | | - |
---|
1753 | | - if (rk_pcie->pci->pp.msi_irq > 0) |
---|
1754 | | - dw_pcie_free_msi(&rk_pcie->pci->pp); |
---|
1755 | 1849 | |
---|
1756 | 1850 | return ret; |
---|
1757 | 1851 | } |
---|
.. | .. |
---|
1811 | 1905 | goto err; |
---|
1812 | 1906 | } |
---|
1813 | 1907 | |
---|
1814 | | - if (rk_pcie->pci->pp.msi_irq > 0) |
---|
1815 | | - dw_pcie_msi_init(&rk_pcie->pci->pp); |
---|
1816 | | - |
---|
1817 | 1908 | if (std_rc) |
---|
1818 | 1909 | goto std_rc_done; |
---|
1819 | 1910 | |
---|
.. | .. |
---|
1836 | 1927 | goto err; |
---|
1837 | 1928 | } |
---|
1838 | 1929 | |
---|
| 1930 | + if (rk_pcie->pci->pp.msi_irq > 0) |
---|
| 1931 | + dw_pcie_msi_init(&rk_pcie->pci->pp); |
---|
| 1932 | + |
---|
1839 | 1933 | return 0; |
---|
1840 | 1934 | err: |
---|
1841 | 1935 | rk_pcie_disable_power(rk_pcie); |
---|