hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/pci/controller/dwc/pcie-dw-ep-rockchip.c
....@@ -81,6 +81,10 @@
8181 #define PCIE_CLIENT_HOT_RESET_CTRL 0x180
8282 #define PCIE_CLIENT_LTSSM_STATUS 0x300
8383 #define PCIE_CLIENT_INTR_MASK 0x24
84
+#define PCIE_LTSSM_APP_DLY1_EN BIT(0)
85
+#define PCIE_LTSSM_APP_DLY2_EN BIT(1)
86
+#define PCIE_LTSSM_APP_DLY1_DONE BIT(2)
87
+#define PCIE_LTSSM_APP_DLY2_DONE BIT(3)
8488 #define PCIE_LTSSM_ENABLE_ENHANCE BIT(4)
8589 #define PCIE_CLIENT_MSI_GEN_CON 0x38
8690
....@@ -106,6 +110,7 @@
106110 #define PCIE_EP_OBJ_INFO_DRV_VERSION 0x00000001
107111
108112 #define PCIE_BAR_MAX_NUM 6
113
+#define PCIE_HOTRESET_TMOUT_US 10000
109114
110115 struct rockchip_pcie {
111116 struct dw_pcie pci;
....@@ -130,6 +135,8 @@
130135 phys_addr_t dbi_base_physical;
131136 struct pcie_ep_obj_info *obj_info;
132137 enum pcie_ep_mmap_resource cur_mmap_res;
138
+ struct workqueue_struct *hot_rst_wq;
139
+ struct work_struct hot_rst_work;
133140 };
134141
135142 struct rockchip_pcie_misc_dev {
....@@ -586,7 +593,8 @@
586593
587594 /* LTSSM EN ctrl mode */
588595 val = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_HOT_RESET_CTRL);
589
- val |= PCIE_LTSSM_ENABLE_ENHANCE | (PCIE_LTSSM_ENABLE_ENHANCE << 16);
596
+ val |= (PCIE_LTSSM_ENABLE_ENHANCE | PCIE_LTSSM_APP_DLY2_EN) |
597
+ ((PCIE_LTSSM_ENABLE_ENHANCE | PCIE_LTSSM_APP_DLY2_EN) << 16);
590598 rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_HOT_RESET_CTRL);
591599 }
592600
....@@ -642,7 +650,7 @@
642650 u32 chn;
643651 union int_status wr_status, rd_status;
644652 union int_clear clears;
645
- u32 reg, val, mask;
653
+ u32 reg, mask;
646654 bool sigio = false;
647655
648656 /* ELBI helper, only check the valid bits, and discard the rest interrupts */
....@@ -713,14 +721,8 @@
713721 }
714722
715723 reg = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_INTR_STATUS_MISC);
716
- if (reg & BIT(2)) {
717
- /* Setup command register */
718
- val = dw_pcie_readl_dbi(pci, PCI_COMMAND);
719
- val &= 0xffff0000;
720
- val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
721
- PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
722
- dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
723
- }
724
+ if (reg & BIT(2))
725
+ queue_work(rockchip->hot_rst_wq, &rockchip->hot_rst_work);
724726
725727 rockchip_pcie_writel_apb(rockchip, reg, PCIE_CLIENT_INTR_STATUS_MISC);
726728
....@@ -868,6 +870,23 @@
868870 table->weilo.weight0 = 0x0;
869871 table->start.stop = 0x0;
870872 table->start.chnl = table->chn;
873
+}
874
+
875
+static void rockchip_pcie_hot_rst_work(struct work_struct *work)
876
+{
877
+ struct rockchip_pcie *rockchip = container_of(work, struct rockchip_pcie, hot_rst_work);
878
+ u32 status;
879
+ int ret;
880
+
881
+ if (rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_HOT_RESET_CTRL) & PCIE_LTSSM_APP_DLY2_EN) {
882
+ ret = readl_poll_timeout(rockchip->apb_base + PCIE_CLIENT_LTSSM_STATUS,
883
+ status, ((status & 0x3F) == 0), 100, PCIE_HOTRESET_TMOUT_US);
884
+ if (ret)
885
+ dev_err(rockchip->pci.dev, "wait for detect quiet failed!\n");
886
+
887
+ rockchip_pcie_writel_apb(rockchip, (PCIE_LTSSM_APP_DLY2_DONE) | ((PCIE_LTSSM_APP_DLY2_DONE) << 16),
888
+ PCIE_CLIENT_HOT_RESET_CTRL);
889
+ }
871890 }
872891
873892 static int rockchip_pcie_get_dma_status(struct dma_trx_obj *obj, u8 chn, enum dma_dir dir)
....@@ -1121,6 +1140,7 @@
11211140 struct rockchip_pcie *rockchip;
11221141 int ret;
11231142 int retry, i;
1143
+ u32 reg;
11241144
11251145 rockchip = devm_kzalloc(dev, sizeof(*rockchip), GFP_KERNEL);
11261146 if (!rockchip)
....@@ -1182,6 +1202,26 @@
11821202 rockchip_pcie_start_link(&rockchip->pci);
11831203 rockchip_pcie_devmode_update(rockchip, RKEP_MODE_KERNEL, RKEP_SMODE_LNKRDY);
11841204
1205
+ rockchip->hot_rst_wq = create_singlethread_workqueue("rkep_hot_rst_wq");
1206
+ if (!rockchip->hot_rst_wq) {
1207
+ dev_err(dev, "failed to create hot_rst workqueue\n");
1208
+ ret = -ENOMEM;
1209
+ goto deinit_phy;
1210
+ }
1211
+ INIT_WORK(&rockchip->hot_rst_work, rockchip_pcie_hot_rst_work);
1212
+
1213
+ reg = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_INTR_STATUS_MISC);
1214
+ if ((reg & BIT(2)) &&
1215
+ (rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_HOT_RESET_CTRL) & PCIE_LTSSM_APP_DLY2_EN)) {
1216
+ rockchip_pcie_writel_apb(rockchip, PCIE_LTSSM_APP_DLY2_DONE | (PCIE_LTSSM_APP_DLY2_DONE << 16),
1217
+ PCIE_CLIENT_HOT_RESET_CTRL);
1218
+ dev_info(dev, "hot reset ever\n");
1219
+ }
1220
+ rockchip_pcie_writel_apb(rockchip, reg, PCIE_CLIENT_INTR_STATUS_MISC);
1221
+
1222
+ /* Enable client reset or link down interrupt */
1223
+ rockchip_pcie_writel_apb(rockchip, 0x40000, PCIE_CLIENT_INTR_MASK);
1224
+
11851225 for (retry = 0; retry < 10000; retry++) {
11861226 if (dw_pcie_link_up(&rockchip->pci)) {
11871227 /*