| .. | .. |
|---|
| 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"); |
|---|