.. | .. |
---|
8 | 8 | * Author: Simon Xue <xxm@rock-chips.com> |
---|
9 | 9 | */ |
---|
10 | 10 | |
---|
| 11 | +#include <dt-bindings/phy/phy.h> |
---|
11 | 12 | #include <linux/clk.h> |
---|
12 | 13 | #include <linux/delay.h> |
---|
13 | 14 | #include <linux/fs.h> |
---|
.. | .. |
---|
115 | 116 | #define PME_TURN_OFF (BIT(4) | BIT(20)) |
---|
116 | 117 | #define PCIE_CLIENT_GENERAL_DEBUG 0x104 |
---|
117 | 118 | #define PCIE_CLIENT_HOT_RESET_CTRL 0x180 |
---|
| 119 | +#define PCIE_LTSSM_APP_DLY1_EN BIT(0) |
---|
| 120 | +#define PCIE_LTSSM_APP_DLY2_EN BIT(1) |
---|
| 121 | +#define PCIE_LTSSM_APP_DLY1_DONE BIT(2) |
---|
| 122 | +#define PCIE_LTSSM_APP_DLY2_DONE BIT(3) |
---|
118 | 123 | #define PCIE_LTSSM_ENABLE_ENHANCE BIT(4) |
---|
119 | 124 | #define PCIE_CLIENT_LTSSM_STATUS 0x300 |
---|
120 | 125 | #define SMLH_LINKUP BIT(16) |
---|
.. | .. |
---|
137 | 142 | |
---|
138 | 143 | #define PCIE_PL_ORDER_RULE_CTRL_OFF 0x8B4 |
---|
139 | 144 | #define RK_PCIE_L2_TMOUT_US 5000 |
---|
| 145 | +#define RK_PCIE_HOTRESET_TMOUT_US 10000 |
---|
| 146 | +#define RK_PCIE_ENUM_HW_RETRYIES 2 |
---|
140 | 147 | |
---|
141 | 148 | enum rk_pcie_ltssm_code { |
---|
142 | 149 | S_L0 = 0x11, |
---|
.. | .. |
---|
185 | 192 | u32 l1ss_ctl1; |
---|
186 | 193 | struct dentry *debugfs; |
---|
187 | 194 | u32 msi_vector_num; |
---|
| 195 | + struct workqueue_struct *hot_rst_wq; |
---|
| 196 | + struct work_struct hot_rst_work; |
---|
| 197 | + u32 comp_prst[2]; |
---|
| 198 | + u32 intx; |
---|
188 | 199 | }; |
---|
189 | 200 | |
---|
190 | 201 | struct rk_pcie_of_data { |
---|
.. | .. |
---|
193 | 204 | }; |
---|
194 | 205 | |
---|
195 | 206 | #define to_rk_pcie(x) dev_get_drvdata((x)->dev) |
---|
| 207 | +static int rk_pcie_disable_power(struct rk_pcie *rk_pcie); |
---|
| 208 | +static int rk_pcie_enable_power(struct rk_pcie *rk_pcie); |
---|
196 | 209 | |
---|
197 | 210 | static int rk_pcie_read(void __iomem *addr, int size, u32 *val) |
---|
198 | 211 | { |
---|
.. | .. |
---|
693 | 706 | rk_pcie_writel_apb(rk_pcie, 0x0, 0xC000C); |
---|
694 | 707 | } |
---|
695 | 708 | |
---|
696 | | -static int rk_pcie_link_up(struct dw_pcie *pci) |
---|
697 | | -{ |
---|
698 | | - struct rk_pcie *rk_pcie = to_rk_pcie(pci); |
---|
699 | | - u32 val; |
---|
700 | | - |
---|
701 | | - if (rk_pcie->is_rk1808) { |
---|
702 | | - val = rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_GENERAL_DEBUG); |
---|
703 | | - if ((val & (PCIE_PHY_LINKUP | PCIE_DATA_LINKUP)) == 0x3) |
---|
704 | | - return 1; |
---|
705 | | - } else { |
---|
706 | | - val = rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS); |
---|
707 | | - if ((val & (RDLH_LINKUP | SMLH_LINKUP)) == 0x30000) |
---|
708 | | - return 1; |
---|
709 | | - } |
---|
710 | | - |
---|
711 | | - return 0; |
---|
712 | | -} |
---|
713 | | - |
---|
714 | 709 | static void rk_pcie_enable_debug(struct rk_pcie *rk_pcie) |
---|
715 | 710 | { |
---|
716 | 711 | if (!IS_ENABLED(CONFIG_DEBUG_FS)) |
---|
.. | .. |
---|
749 | 744 | int retries, power; |
---|
750 | 745 | struct rk_pcie *rk_pcie = to_rk_pcie(pci); |
---|
751 | 746 | bool std_rc = rk_pcie->mode == RK_PCIE_RC_TYPE && !rk_pcie->dma_obj; |
---|
| 747 | + int hw_retries = 0; |
---|
| 748 | + u32 ltssm; |
---|
752 | 749 | |
---|
753 | 750 | /* |
---|
754 | 751 | * For standard RC, even if the link has been setup by firmware, |
---|
.. | .. |
---|
760 | 757 | return 0; |
---|
761 | 758 | } |
---|
762 | 759 | |
---|
763 | | - /* Rest the device */ |
---|
764 | | - gpiod_set_value_cansleep(rk_pcie->rst_gpio, 0); |
---|
| 760 | + for (hw_retries = 0; hw_retries < RK_PCIE_ENUM_HW_RETRYIES; hw_retries++) { |
---|
| 761 | + /* Rest the device */ |
---|
| 762 | + gpiod_set_value_cansleep(rk_pcie->rst_gpio, 0); |
---|
765 | 763 | |
---|
766 | | - rk_pcie_disable_ltssm(rk_pcie); |
---|
767 | | - rk_pcie_link_status_clear(rk_pcie); |
---|
768 | | - rk_pcie_enable_debug(rk_pcie); |
---|
| 764 | + rk_pcie_disable_ltssm(rk_pcie); |
---|
| 765 | + rk_pcie_link_status_clear(rk_pcie); |
---|
| 766 | + rk_pcie_enable_debug(rk_pcie); |
---|
769 | 767 | |
---|
770 | | - /* Enable client reset or link down interrupt */ |
---|
771 | | - rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK, 0x40000); |
---|
| 768 | + /* Enable client reset or link down interrupt */ |
---|
| 769 | + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK, 0x40000); |
---|
772 | 770 | |
---|
773 | | - /* Enable LTSSM */ |
---|
774 | | - rk_pcie_enable_ltssm(rk_pcie); |
---|
| 771 | + /* Enable LTSSM */ |
---|
| 772 | + rk_pcie_enable_ltssm(rk_pcie); |
---|
775 | 773 | |
---|
776 | | - /* |
---|
777 | | - * In resume routine, function devices' resume function must be late after |
---|
778 | | - * controllers'. Some devices, such as Wi-Fi, need special IO setting before |
---|
779 | | - * finishing training. So there must be timeout here. These kinds of devices |
---|
780 | | - * need rescan devices by its driver when used. So no need to waste time waiting |
---|
781 | | - * for training pass. |
---|
782 | | - */ |
---|
783 | | - if (rk_pcie->in_suspend && rk_pcie->skip_scan_in_resume) { |
---|
784 | | - rfkill_get_wifi_power_state(&power); |
---|
785 | | - if (!power) { |
---|
786 | | - gpiod_set_value_cansleep(rk_pcie->rst_gpio, 1); |
---|
787 | | - return 0; |
---|
788 | | - } |
---|
789 | | - } |
---|
790 | | - |
---|
791 | | - /* |
---|
792 | | - * PCIe requires the refclk to be stable for 100µs prior to releasing |
---|
793 | | - * PERST and T_PVPERL (Power stable to PERST# inactive) should be a |
---|
794 | | - * minimum of 100ms. See table 2-4 in section 2.6.2 AC, the PCI Express |
---|
795 | | - * Card Electromechanical Specification 3.0. So 100ms in total is the min |
---|
796 | | - * requuirement here. We add a 200ms by default for sake of hoping everthings |
---|
797 | | - * work fine. If it doesn't, please add more in DT node by add rockchip,perst-inactive-ms. |
---|
798 | | - */ |
---|
799 | | - msleep(rk_pcie->perst_inactive_ms); |
---|
800 | | - gpiod_set_value_cansleep(rk_pcie->rst_gpio, 1); |
---|
801 | | - |
---|
802 | | - /* |
---|
803 | | - * Add this 1ms delay because we observe link is always up stably after it and |
---|
804 | | - * could help us save 20ms for scanning devices. |
---|
805 | | - */ |
---|
806 | | - usleep_range(1000, 1100); |
---|
807 | | - |
---|
808 | | - for (retries = 0; retries < 100; retries++) { |
---|
809 | | - if (dw_pcie_link_up(pci)) { |
---|
810 | | - /* |
---|
811 | | - * We may be here in case of L0 in Gen1. But if EP is capable |
---|
812 | | - * of Gen2 or Gen3, Gen switch may happen just in this time, but |
---|
813 | | - * we keep on accessing devices in unstable link status. Given |
---|
814 | | - * that LTSSM max timeout is 24ms per period, we can wait a bit |
---|
815 | | - * more for Gen switch. |
---|
816 | | - */ |
---|
817 | | - msleep(50); |
---|
818 | | - /* In case link drop after linkup, double check it */ |
---|
819 | | - if (dw_pcie_link_up(pci)) { |
---|
820 | | - dev_info(pci->dev, "PCIe Link up, LTSSM is 0x%x\n", |
---|
821 | | - rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS)); |
---|
822 | | - rk_pcie_debug_dump(rk_pcie); |
---|
| 774 | + /* |
---|
| 775 | + * In resume routine, function devices' resume function must be late after |
---|
| 776 | + * controllers'. Some devices, such as Wi-Fi, need special IO setting before |
---|
| 777 | + * finishing training. So there must be timeout here. These kinds of devices |
---|
| 778 | + * need rescan devices by its driver when used. So no need to waste time waiting |
---|
| 779 | + * for training pass. |
---|
| 780 | + */ |
---|
| 781 | + if (rk_pcie->in_suspend && rk_pcie->skip_scan_in_resume) { |
---|
| 782 | + rfkill_get_wifi_power_state(&power); |
---|
| 783 | + if (!power) { |
---|
| 784 | + gpiod_set_value_cansleep(rk_pcie->rst_gpio, 1); |
---|
823 | 785 | return 0; |
---|
824 | 786 | } |
---|
825 | 787 | } |
---|
826 | 788 | |
---|
827 | | - dev_info_ratelimited(pci->dev, "PCIe Linking... LTSSM is 0x%x\n", |
---|
828 | | - rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS)); |
---|
829 | | - rk_pcie_debug_dump(rk_pcie); |
---|
830 | | - msleep(20); |
---|
831 | | - } |
---|
| 789 | + /* |
---|
| 790 | + * PCIe requires the refclk to be stable for 100µs prior to releasing |
---|
| 791 | + * PERST and T_PVPERL (Power stable to PERST# inactive) should be a |
---|
| 792 | + * minimum of 100ms. See table 2-4 in section 2.6.2 AC, the PCI Express |
---|
| 793 | + * Card Electromechanical Specification 3.0. So 100ms in total is the min |
---|
| 794 | + * requuirement here. We add a 200ms by default for sake of hoping everthings |
---|
| 795 | + * work fine. If it doesn't, please add more in DT node by add rockchip,perst-inactive-ms. |
---|
| 796 | + */ |
---|
| 797 | + msleep(rk_pcie->perst_inactive_ms); |
---|
| 798 | + gpiod_set_value_cansleep(rk_pcie->rst_gpio, 1); |
---|
832 | 799 | |
---|
833 | | - dev_err(pci->dev, "PCIe Link Fail\n"); |
---|
| 800 | + /* |
---|
| 801 | + * Add this 1ms delay because we observe link is always up stably after it and |
---|
| 802 | + * could help us save 20ms for scanning devices. |
---|
| 803 | + */ |
---|
| 804 | + usleep_range(1000, 1100); |
---|
| 805 | + |
---|
| 806 | + for (retries = 0; retries < 100; retries++) { |
---|
| 807 | + if (dw_pcie_link_up(pci)) { |
---|
| 808 | + /* |
---|
| 809 | + * We may be here in case of L0 in Gen1. But if EP is capable |
---|
| 810 | + * of Gen2 or Gen3, Gen switch may happen just in this time, but |
---|
| 811 | + * we keep on accessing devices in unstable link status. Given |
---|
| 812 | + * that LTSSM max timeout is 24ms per period, we can wait a bit |
---|
| 813 | + * more for Gen switch. |
---|
| 814 | + */ |
---|
| 815 | + msleep(50); |
---|
| 816 | + /* In case link drop after linkup, double check it */ |
---|
| 817 | + if (dw_pcie_link_up(pci)) { |
---|
| 818 | + dev_info(pci->dev, "PCIe Link up, LTSSM is 0x%x\n", |
---|
| 819 | + rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS)); |
---|
| 820 | + rk_pcie_debug_dump(rk_pcie); |
---|
| 821 | + return 0; |
---|
| 822 | + } |
---|
| 823 | + } |
---|
| 824 | + |
---|
| 825 | + dev_info_ratelimited(pci->dev, "PCIe Linking... LTSSM is 0x%x\n", |
---|
| 826 | + rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS)); |
---|
| 827 | + rk_pcie_debug_dump(rk_pcie); |
---|
| 828 | + msleep(20); |
---|
| 829 | + } |
---|
| 830 | + |
---|
| 831 | + /* |
---|
| 832 | + * In response to the situation where PCIe peripherals cannot be |
---|
| 833 | + * enumerated due tosignal abnormalities, reset PERST# and reset |
---|
| 834 | + * the peripheral power supply, then restart the enumeration. |
---|
| 835 | + */ |
---|
| 836 | + ltssm = rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS); |
---|
| 837 | + dev_err(pci->dev, "PCIe Link Fail, LTSSM is 0x%x, hw_retries=%d\n", ltssm, hw_retries); |
---|
| 838 | + if (ltssm >= 3 && !rk_pcie->is_signal_test) { |
---|
| 839 | + rk_pcie_disable_power(rk_pcie); |
---|
| 840 | + msleep(1000); |
---|
| 841 | + rk_pcie_enable_power(rk_pcie); |
---|
| 842 | + } else { |
---|
| 843 | + break; |
---|
| 844 | + } |
---|
| 845 | + } |
---|
834 | 846 | |
---|
835 | 847 | return rk_pcie->is_signal_test == true ? 0 : -EINVAL; |
---|
836 | 848 | } |
---|
.. | .. |
---|
1119 | 1131 | |
---|
1120 | 1132 | dw_pcie_setup_rc(pp); |
---|
1121 | 1133 | |
---|
| 1134 | + /* Disable BAR0 BAR1 */ |
---|
| 1135 | + dw_pcie_writel_dbi2(pci, PCI_BASE_ADDRESS_0, 0x0); |
---|
| 1136 | + dw_pcie_writel_dbi2(pci, PCI_BASE_ADDRESS_1, 0x0); |
---|
| 1137 | + |
---|
1122 | 1138 | ret = rk_pcie_establish_link(pci); |
---|
1123 | 1139 | |
---|
1124 | 1140 | if (pp->msi_irq > 0) |
---|
.. | .. |
---|
1190 | 1206 | return ret; |
---|
1191 | 1207 | } |
---|
1192 | 1208 | |
---|
1193 | | - rk_pcie->pci->dbi_base2 = rk_pcie->pci->dbi_base + PCIE_TYPE0_HDR_DBI2_OFFSET; |
---|
1194 | 1209 | rk_pcie->pci->atu_base = rk_pcie->pci->dbi_base + DEFAULT_DBI_ATU_OFFSET; |
---|
1195 | 1210 | rk_pcie->pci->iatu_unroll_enabled = rk_pcie_iatu_unroll_enabled(rk_pcie->pci); |
---|
1196 | 1211 | |
---|
.. | .. |
---|
1250 | 1265 | return PTR_ERR(rk_pcie->dbi_base); |
---|
1251 | 1266 | |
---|
1252 | 1267 | rk_pcie->pci->dbi_base = rk_pcie->dbi_base; |
---|
| 1268 | + rk_pcie->pci->dbi_base2 = rk_pcie->pci->dbi_base + PCIE_TYPE0_HDR_DBI2_OFFSET; |
---|
1253 | 1269 | |
---|
1254 | 1270 | apb_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
---|
1255 | 1271 | "pcie-apb"); |
---|
.. | .. |
---|
1434 | 1450 | table->start.chnl = table->chn; |
---|
1435 | 1451 | } |
---|
1436 | 1452 | |
---|
| 1453 | +static void rk_pcie_hot_rst_work(struct work_struct *work) |
---|
| 1454 | +{ |
---|
| 1455 | + struct rk_pcie *rk_pcie = container_of(work, struct rk_pcie, hot_rst_work); |
---|
| 1456 | + u32 val, status; |
---|
| 1457 | + int ret; |
---|
| 1458 | + |
---|
| 1459 | + /* Setup command register */ |
---|
| 1460 | + val = dw_pcie_readl_dbi(rk_pcie->pci, PCI_COMMAND); |
---|
| 1461 | + val &= 0xffff0000; |
---|
| 1462 | + val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | |
---|
| 1463 | + PCI_COMMAND_MASTER | PCI_COMMAND_SERR; |
---|
| 1464 | + dw_pcie_writel_dbi(rk_pcie->pci, PCI_COMMAND, val); |
---|
| 1465 | + |
---|
| 1466 | + if (rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_HOT_RESET_CTRL) & PCIE_LTSSM_APP_DLY2_EN) { |
---|
| 1467 | + ret = readl_poll_timeout(rk_pcie->apb_base + PCIE_CLIENT_LTSSM_STATUS, |
---|
| 1468 | + status, ((status & 0x3F) == 0), 100, RK_PCIE_HOTRESET_TMOUT_US); |
---|
| 1469 | + if (ret) |
---|
| 1470 | + dev_err(rk_pcie->pci->dev, "wait for detect quiet failed!\n"); |
---|
| 1471 | + |
---|
| 1472 | + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_HOT_RESET_CTRL, |
---|
| 1473 | + (PCIE_LTSSM_APP_DLY2_DONE) | ((PCIE_LTSSM_APP_DLY2_DONE) << 16)); |
---|
| 1474 | + } |
---|
| 1475 | +} |
---|
| 1476 | + |
---|
1437 | 1477 | static irqreturn_t rk_pcie_sys_irq_handler(int irq, void *arg) |
---|
1438 | 1478 | { |
---|
1439 | 1479 | struct rk_pcie *rk_pcie = arg; |
---|
1440 | 1480 | u32 chn; |
---|
1441 | 1481 | union int_status status; |
---|
1442 | 1482 | union int_clear clears; |
---|
1443 | | - u32 reg, val; |
---|
| 1483 | + u32 reg; |
---|
1444 | 1484 | |
---|
1445 | 1485 | status.asdword = dw_pcie_readl_dbi(rk_pcie->pci, PCIE_DMA_OFFSET + |
---|
1446 | 1486 | PCIE_DMA_WR_INT_STATUS); |
---|
.. | .. |
---|
1481 | 1521 | } |
---|
1482 | 1522 | |
---|
1483 | 1523 | reg = rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_INTR_STATUS_MISC); |
---|
1484 | | - if (reg & BIT(2)) { |
---|
1485 | | - /* Setup command register */ |
---|
1486 | | - val = dw_pcie_readl_dbi(rk_pcie->pci, PCI_COMMAND); |
---|
1487 | | - val &= 0xffff0000; |
---|
1488 | | - val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | |
---|
1489 | | - PCI_COMMAND_MASTER | PCI_COMMAND_SERR; |
---|
1490 | | - dw_pcie_writel_dbi(rk_pcie->pci, PCI_COMMAND, val); |
---|
1491 | | - } |
---|
| 1524 | + if (reg & BIT(2)) |
---|
| 1525 | + queue_work(rk_pcie->hot_rst_wq, &rk_pcie->hot_rst_work); |
---|
1492 | 1526 | |
---|
1493 | 1527 | rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_STATUS_MISC, reg); |
---|
1494 | 1528 | |
---|
.. | .. |
---|
1570 | 1604 | |
---|
1571 | 1605 | static const struct dw_pcie_ops dw_pcie_ops = { |
---|
1572 | 1606 | .start_link = rk_pcie_establish_link, |
---|
1573 | | - .link_up = rk_pcie_link_up, |
---|
1574 | 1607 | }; |
---|
1575 | 1608 | |
---|
1576 | 1609 | static int rk1808_pcie_fixup(struct rk_pcie *rk_pcie, struct device_node *np) |
---|
.. | .. |
---|
1612 | 1645 | |
---|
1613 | 1646 | /* LTSSM EN ctrl mode */ |
---|
1614 | 1647 | val = rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_HOT_RESET_CTRL); |
---|
1615 | | - val |= PCIE_LTSSM_ENABLE_ENHANCE | (PCIE_LTSSM_ENABLE_ENHANCE << 16); |
---|
| 1648 | + val |= (PCIE_LTSSM_ENABLE_ENHANCE | PCIE_LTSSM_APP_DLY2_EN) |
---|
| 1649 | + | ((PCIE_LTSSM_APP_DLY2_EN | PCIE_LTSSM_ENABLE_ENHANCE) << 16); |
---|
1616 | 1650 | rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_HOT_RESET_CTRL, val); |
---|
1617 | 1651 | } |
---|
1618 | 1652 | |
---|
.. | .. |
---|
1650 | 1684 | static int rk_pcie_intx_map(struct irq_domain *domain, unsigned int irq, |
---|
1651 | 1685 | irq_hw_number_t hwirq) |
---|
1652 | 1686 | { |
---|
1653 | | - irq_set_chip_and_handler(irq, &rk_pcie_legacy_irq_chip, handle_simple_irq); |
---|
| 1687 | + irq_set_chip_and_handler(irq, &rk_pcie_legacy_irq_chip, handle_level_irq); |
---|
1654 | 1688 | irq_set_chip_data(irq, domain->host_data); |
---|
1655 | 1689 | |
---|
1656 | 1690 | return 0; |
---|
.. | .. |
---|
1956 | 1990 | |
---|
1957 | 1991 | if (!IS_ERR_OR_NULL(rk_pcie->prsnt_gpio)) { |
---|
1958 | 1992 | if (!gpiod_get_value(rk_pcie->prsnt_gpio)) { |
---|
| 1993 | + dev_info(dev, "device isn't present\n"); |
---|
1959 | 1994 | ret = -ENODEV; |
---|
1960 | 1995 | goto release_driver; |
---|
1961 | 1996 | } |
---|
.. | .. |
---|
2051 | 2086 | rk_pcie->is_signal_test = true; |
---|
2052 | 2087 | } |
---|
2053 | 2088 | |
---|
2054 | | - /* Force into compliance mode */ |
---|
2055 | | - if (device_property_read_bool(dev, "rockchip,compliance-mode")) { |
---|
2056 | | - val = dw_pcie_readl_dbi(pci, PCIE_CAP_LINK_CONTROL2_LINK_STATUS); |
---|
2057 | | - val |= BIT(4); |
---|
2058 | | - dw_pcie_writel_dbi(pci, PCIE_CAP_LINK_CONTROL2_LINK_STATUS, val); |
---|
| 2089 | + /* |
---|
| 2090 | + * Force into compliance mode |
---|
| 2091 | + * comp_prst is a two dimensional array of which the first element |
---|
| 2092 | + * stands for speed mode, and the second one is preset value encoding: |
---|
| 2093 | + * [0] 0->SMA tool control the signal switch, 1/2/3 is for manual Gen setting |
---|
| 2094 | + * [1] transmitter setting for manual Gen setting, valid only if [0] isn't zero. |
---|
| 2095 | + */ |
---|
| 2096 | + if (!device_property_read_u32_array(dev, "rockchip,compliance-mode", |
---|
| 2097 | + rk_pcie->comp_prst, 2)) { |
---|
| 2098 | + BUG_ON(rk_pcie->comp_prst[0] > 3 || rk_pcie->comp_prst[1] > 10); |
---|
| 2099 | + if (!rk_pcie->comp_prst[0]) { |
---|
| 2100 | + dev_info(dev, "Auto compliance mode for SMA tool.\n"); |
---|
| 2101 | + } else { |
---|
| 2102 | + dev_info(dev, "compliance mode for soldered board Gen%d, P%d.\n", |
---|
| 2103 | + rk_pcie->comp_prst[0], rk_pcie->comp_prst[1]); |
---|
| 2104 | + val = dw_pcie_readl_dbi(pci, PCIE_CAP_LINK_CONTROL2_LINK_STATUS); |
---|
| 2105 | + val |= BIT(4) | rk_pcie->comp_prst[0] | (rk_pcie->comp_prst[1] << 12); |
---|
| 2106 | + dw_pcie_writel_dbi(pci, PCIE_CAP_LINK_CONTROL2_LINK_STATUS, val); |
---|
| 2107 | + } |
---|
2059 | 2108 | rk_pcie->is_signal_test = true; |
---|
2060 | 2109 | } |
---|
2061 | 2110 | |
---|
2062 | 2111 | /* Skip waiting for training to pass in system PM routine */ |
---|
2063 | 2112 | if (device_property_read_bool(dev, "rockchip,skip-scan-in-resume")) |
---|
2064 | 2113 | rk_pcie->skip_scan_in_resume = true; |
---|
| 2114 | + |
---|
| 2115 | + rk_pcie->hot_rst_wq = create_singlethread_workqueue("rk_pcie_hot_rst_wq"); |
---|
| 2116 | + if (!rk_pcie->hot_rst_wq) { |
---|
| 2117 | + dev_err(dev, "failed to create hot_rst workqueue\n"); |
---|
| 2118 | + ret = -ENOMEM; |
---|
| 2119 | + goto remove_irq_domain; |
---|
| 2120 | + } |
---|
| 2121 | + INIT_WORK(&rk_pcie->hot_rst_work, rk_pcie_hot_rst_work); |
---|
2065 | 2122 | |
---|
2066 | 2123 | switch (rk_pcie->mode) { |
---|
2067 | 2124 | case RK_PCIE_RC_TYPE: |
---|
.. | .. |
---|
2076 | 2133 | return 0; |
---|
2077 | 2134 | |
---|
2078 | 2135 | if (ret) |
---|
2079 | | - goto remove_irq_domain; |
---|
| 2136 | + goto remove_rst_wq; |
---|
2080 | 2137 | |
---|
2081 | 2138 | ret = rk_pcie_init_dma_trx(rk_pcie); |
---|
2082 | 2139 | if (ret) { |
---|
2083 | 2140 | dev_err(dev, "failed to add dma extension\n"); |
---|
2084 | | - goto remove_irq_domain; |
---|
| 2141 | + goto remove_rst_wq; |
---|
2085 | 2142 | } |
---|
2086 | 2143 | |
---|
2087 | 2144 | if (rk_pcie->dma_obj) { |
---|
.. | .. |
---|
2093 | 2150 | /* hold link reset grant after link-up */ |
---|
2094 | 2151 | ret = rk_pcie_reset_grant_ctrl(rk_pcie, false); |
---|
2095 | 2152 | if (ret) |
---|
2096 | | - goto remove_irq_domain; |
---|
| 2153 | + goto remove_rst_wq; |
---|
2097 | 2154 | } |
---|
2098 | 2155 | |
---|
2099 | 2156 | dw_pcie_dbi_ro_wr_dis(pci); |
---|
.. | .. |
---|
2121 | 2178 | |
---|
2122 | 2179 | return 0; |
---|
2123 | 2180 | |
---|
| 2181 | +remove_rst_wq: |
---|
| 2182 | + destroy_workqueue(rk_pcie->hot_rst_wq); |
---|
2124 | 2183 | remove_irq_domain: |
---|
2125 | 2184 | if (rk_pcie->irq_domain) |
---|
2126 | 2185 | irq_domain_remove(rk_pcie->irq_domain); |
---|
.. | .. |
---|
2298 | 2357 | no_l2: |
---|
2299 | 2358 | rk_pcie_disable_ltssm(rk_pcie); |
---|
2300 | 2359 | |
---|
| 2360 | + ret = phy_validate(rk_pcie->phy, PHY_TYPE_PCIE, 0, NULL); |
---|
| 2361 | + if (ret && ret != -EOPNOTSUPP) { |
---|
| 2362 | + dev_err(dev, "PHY is reused by other controller, check the dts!\n"); |
---|
| 2363 | + return ret; |
---|
| 2364 | + } |
---|
| 2365 | + |
---|
2301 | 2366 | /* make sure assert phy success */ |
---|
2302 | 2367 | usleep_range(200, 300); |
---|
2303 | 2368 | |
---|
2304 | 2369 | phy_power_off(rk_pcie->phy); |
---|
2305 | 2370 | phy_exit(rk_pcie->phy); |
---|
| 2371 | + |
---|
| 2372 | + rk_pcie->intx = rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_INTR_MASK_LEGACY); |
---|
2306 | 2373 | |
---|
2307 | 2374 | clk_bulk_disable_unprepare(rk_pcie->clk_cnt, rk_pcie->clks); |
---|
2308 | 2375 | |
---|
.. | .. |
---|
2368 | 2435 | if (std_rc) |
---|
2369 | 2436 | dw_pcie_setup_rc(&rk_pcie->pci->pp); |
---|
2370 | 2437 | |
---|
| 2438 | + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK_LEGACY, |
---|
| 2439 | + rk_pcie->intx | 0xffff0000); |
---|
| 2440 | + |
---|
2371 | 2441 | ret = rk_pcie_establish_link(rk_pcie->pci); |
---|
2372 | 2442 | if (ret) { |
---|
2373 | 2443 | dev_err(dev, "failed to establish pcie link\n"); |
---|