hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
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
....@@ -90,11 +94,13 @@
9094 #define PCIE_ELBI_LOCAL_BASE 0x200e00
9195
9296 #define PCIE_ELBI_APP_ELBI_INT_GEN0 0x0
93
-#define PCIE_ELBI_APP_ELBI_INT_GEN0_SIGIO BIT(0)
97
+#define PCIE_ELBI_APP_ELBI_INT_GEN0_IRQ_USER BIT(0)
9498
9599 #define PCIE_ELBI_APP_ELBI_INT_GEN1 0x4
96100
97101 #define PCIE_ELBI_LOCAL_ENABLE_OFF 0x8
102
+
103
+#define PCIE_ELBI_USER_DATA_OFF 0x10
98104
99105 #define PCIE_DIRECT_SPEED_CHANGE BIT(17)
100106
....@@ -106,6 +112,7 @@
106112 #define PCIE_EP_OBJ_INFO_DRV_VERSION 0x00000001
107113
108114 #define PCIE_BAR_MAX_NUM 6
115
+#define PCIE_HOTRESET_TMOUT_US 10000
109116
110117 struct rockchip_pcie {
111118 struct dw_pcie pci;
....@@ -126,10 +133,14 @@
126133 u32 ib_target_size[PCIE_BAR_MAX_NUM];
127134 void *ib_target_base[PCIE_BAR_MAX_NUM];
128135 struct dma_trx_obj *dma_obj;
129
- struct fasync_struct *async;
130136 phys_addr_t dbi_base_physical;
131137 struct pcie_ep_obj_info *obj_info;
132138 enum pcie_ep_mmap_resource cur_mmap_res;
139
+ struct workqueue_struct *hot_rst_wq;
140
+ struct work_struct hot_rst_work;
141
+ struct mutex file_mutex;
142
+ DECLARE_BITMAP(virtual_id_irq_bitmap, RKEP_EP_VIRTUAL_ID_MAX);
143
+ wait_queue_head_t wq_head;
133144 };
134145
135146 struct rockchip_pcie_misc_dev {
....@@ -521,18 +532,18 @@
521532
522533 /* Resize BAR0 4M 32bits, BAR2 64M 64bits-pref, BAR4 1MB 32bits */
523534 bar = BAR_0;
524
- dw_pcie_writel_dbi(pci, resbar_base + 0x4 + bar * 0x8, 0xfffff0);
535
+ dw_pcie_writel_dbi(pci, resbar_base + 0x4 + bar * 0x8, 0x40);
525536 dw_pcie_writel_dbi(pci, resbar_base + 0x8 + bar * 0x8, 0x2c0);
526537 rockchip_pcie_ep_set_bar_flag(rockchip, bar, PCI_BASE_ADDRESS_MEM_TYPE_32);
527538
528539 bar = BAR_2;
529
- dw_pcie_writel_dbi(pci, resbar_base + 0x4 + bar * 0x8, 0xfffff0);
540
+ dw_pcie_writel_dbi(pci, resbar_base + 0x4 + bar * 0x8, 0x400);
530541 dw_pcie_writel_dbi(pci, resbar_base + 0x8 + bar * 0x8, 0x6c0);
531542 rockchip_pcie_ep_set_bar_flag(rockchip, bar,
532543 PCI_BASE_ADDRESS_MEM_PREFETCH | PCI_BASE_ADDRESS_MEM_TYPE_64);
533544
534545 bar = BAR_4;
535
- dw_pcie_writel_dbi(pci, resbar_base + 0x4 + bar * 0x8, 0xfffff0);
546
+ dw_pcie_writel_dbi(pci, resbar_base + 0x4 + bar * 0x8, 0x10);
536547 dw_pcie_writel_dbi(pci, resbar_base + 0x8 + bar * 0x8, 0xc0);
537548 rockchip_pcie_ep_set_bar_flag(rockchip, bar, PCI_BASE_ADDRESS_MEM_TYPE_32);
538549
....@@ -586,7 +597,8 @@
586597
587598 /* LTSSM EN ctrl mode */
588599 val = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_HOT_RESET_CTRL);
589
- val |= PCIE_LTSSM_ENABLE_ENHANCE | (PCIE_LTSSM_ENABLE_ENHANCE << 16);
600
+ val |= (PCIE_LTSSM_ENABLE_ENHANCE | PCIE_LTSSM_APP_DLY2_EN) |
601
+ ((PCIE_LTSSM_ENABLE_ENHANCE | PCIE_LTSSM_APP_DLY2_EN) << 16);
590602 rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_HOT_RESET_CTRL);
591603 }
592604
....@@ -634,6 +646,49 @@
634646 rockchip_pcie_writel_apb(rockchip, BIT(interrupt_num), PCIE_CLIENT_MSI_GEN_CON);
635647 }
636648
649
+static int rockchip_pcie_raise_irq_user(struct rockchip_pcie *rockchip, u32 index)
650
+{
651
+ if (index >= RKEP_EP_VIRTUAL_ID_MAX) {
652
+ dev_err(rockchip->pci.dev, "raise irq_user, virtual id %d out of range\n", index);
653
+
654
+ return -EINVAL;
655
+ }
656
+
657
+ mutex_lock(&rockchip->file_mutex);
658
+ rockchip->obj_info->irq_type_rc = OBJ_IRQ_USER;
659
+ rockchip->obj_info->irq_user_data_rc = index;
660
+ rockchip_pcie_raise_msi_irq(rockchip, PCIe_CLIENT_MSI_OBJ_IRQ);
661
+ mutex_unlock(&rockchip->file_mutex);
662
+
663
+ return 0;
664
+}
665
+
666
+static int rockchip_pcie_poll_irq_user(struct rockchip_pcie *rockchip, struct pcie_ep_obj_poll_virtual_id_cfg *cfg)
667
+{
668
+ u32 index = cfg->virtual_id;
669
+
670
+ if (index >= RKEP_EP_VIRTUAL_ID_MAX) {
671
+ dev_err(rockchip->pci.dev, "poll irq_user, virtual id %d out of range\n", index);
672
+
673
+ return -EINVAL;
674
+ }
675
+
676
+ cfg->poll_status = NSIGPOLL;
677
+ if (cfg->sync)
678
+ wait_event_interruptible(rockchip->wq_head,
679
+ test_bit(index, rockchip->virtual_id_irq_bitmap));
680
+ else
681
+ wait_event_interruptible_timeout(rockchip->wq_head,
682
+ test_bit(index, rockchip->virtual_id_irq_bitmap),
683
+ cfg->timeout_ms);
684
+ if (test_and_clear_bit(index, rockchip->virtual_id_irq_bitmap))
685
+ cfg->poll_status = POLL_IN;
686
+
687
+ dev_dbg(rockchip->pci.dev, "poll virtual id %d, ret=%d\n", index, cfg->poll_status);
688
+
689
+ return 0;
690
+}
691
+
637692 static irqreturn_t rockchip_pcie_sys_irq_handler(int irq, void *arg)
638693 {
639694 struct rockchip_pcie *rockchip = arg;
....@@ -642,15 +697,20 @@
642697 u32 chn;
643698 union int_status wr_status, rd_status;
644699 union int_clear clears;
645
- u32 reg, val, mask;
646
- bool sigio = false;
700
+ u32 reg, mask;
647701
648702 /* ELBI helper, only check the valid bits, and discard the rest interrupts */
649703 elbi_reg = dw_pcie_readl_dbi(pci, PCIE_ELBI_LOCAL_BASE + PCIE_ELBI_APP_ELBI_INT_GEN0);
650
- if (elbi_reg & PCIE_ELBI_APP_ELBI_INT_GEN0_SIGIO) {
651
- sigio = true;
652
- rockchip->obj_info->irq_type_ep = OBJ_IRQ_ELBI;
704
+ if (elbi_reg & PCIE_ELBI_APP_ELBI_INT_GEN0_IRQ_USER) {
653705 rockchip_pcie_elbi_clear(rockchip);
706
+
707
+ if (rockchip->obj_info->irq_type_ep == OBJ_IRQ_USER) {
708
+ reg = rockchip->obj_info->irq_user_data_ep;
709
+ if (reg < RKEP_EP_VIRTUAL_ID_MAX) {
710
+ set_bit(reg, rockchip->virtual_id_irq_bitmap);
711
+ wake_up_interruptible(&rockchip->wq_head);
712
+ }
713
+ }
654714 goto out;
655715 }
656716
....@@ -703,24 +763,12 @@
703763 rockchip->obj_info->irq_type_ep = OBJ_IRQ_DMA;
704764 rockchip->obj_info->dma_status_ep.wr |= wr_status.asdword;
705765 rockchip->obj_info->dma_status_ep.rd |= rd_status.asdword;
706
- sigio = true;
707766 }
708767
709768 out:
710
- if (sigio) {
711
- dev_dbg(rockchip->pci.dev, "SIGIO\n");
712
- kill_fasync(&rockchip->async, SIGIO, POLL_IN);
713
- }
714
-
715769 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
- }
770
+ if (reg & BIT(2))
771
+ queue_work(rockchip->hot_rst_wq, &rockchip->hot_rst_work);
724772
725773 rockchip_pcie_writel_apb(rockchip, reg, PCIE_CLIENT_INTR_STATUS_MISC);
726774
....@@ -870,6 +918,23 @@
870918 table->start.chnl = table->chn;
871919 }
872920
921
+static void rockchip_pcie_hot_rst_work(struct work_struct *work)
922
+{
923
+ struct rockchip_pcie *rockchip = container_of(work, struct rockchip_pcie, hot_rst_work);
924
+ u32 status;
925
+ int ret;
926
+
927
+ if (rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_HOT_RESET_CTRL) & PCIE_LTSSM_APP_DLY2_EN) {
928
+ ret = readl_poll_timeout(rockchip->apb_base + PCIE_CLIENT_LTSSM_STATUS,
929
+ status, ((status & 0x3F) == 0), 100, PCIE_HOTRESET_TMOUT_US);
930
+ if (ret)
931
+ dev_err(rockchip->pci.dev, "wait for detect quiet failed!\n");
932
+
933
+ rockchip_pcie_writel_apb(rockchip, (PCIE_LTSSM_APP_DLY2_DONE) | ((PCIE_LTSSM_APP_DLY2_DONE) << 16),
934
+ PCIE_CLIENT_HOT_RESET_CTRL);
935
+ }
936
+}
937
+
873938 static int rockchip_pcie_get_dma_status(struct dma_trx_obj *obj, u8 chn, enum dma_dir dir)
874939 {
875940 struct rockchip_pcie *rockchip = dev_get_drvdata(obj->dev);
....@@ -925,13 +990,6 @@
925990 .link_up = rockchip_pcie_link_up,
926991 };
927992
928
-static int pcie_ep_fasync(int fd, struct file *file, int mode)
929
-{
930
- struct rockchip_pcie *rockchip = (struct rockchip_pcie *)file->private_data;
931
-
932
- return fasync_helper(fd, file, mode, &rockchip->async);
933
-}
934
-
935993 static int pcie_ep_open(struct inode *inode, struct file *file)
936994 {
937995 struct miscdevice *miscdev = file->private_data;
....@@ -943,35 +1001,16 @@
9431001 return 0;
9441002 }
9451003
946
-static int pcie_ep_release(struct inode *inode, struct file *file)
947
-{
948
- return pcie_ep_fasync(-1, file, 0);
949
-}
950
-
9511004 static long pcie_ep_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
9521005 {
9531006 struct rockchip_pcie *rockchip = (struct rockchip_pcie *)file->private_data;
954
- struct pcie_ep_user_data msg;
9551007 struct pcie_ep_dma_cache_cfg cfg;
9561008 void __user *uarg = (void __user *)arg;
957
- int i, ret;
1009
+ struct pcie_ep_obj_poll_virtual_id_cfg poll_cfg;
9581010 enum pcie_ep_mmap_resource mmap_res;
1011
+ int ret, index;
9591012
9601013 switch (cmd) {
961
- case PCIE_DMA_GET_ELBI_DATA:
962
- for (i = 4; i <= 6; i++)
963
- msg.elbi_app_user[i - 4] = dw_pcie_readl_dbi(&rockchip->pci,
964
- PCIE_ELBI_LOCAL_BASE + i * 4);
965
- for (i = 8; i <= 15; i++)
966
- msg.elbi_app_user[i - 5] = dw_pcie_readl_dbi(&rockchip->pci,
967
- PCIE_ELBI_LOCAL_BASE + i * 4);
968
-
969
- ret = copy_to_user(uarg, &msg, sizeof(msg));
970
- if (ret) {
971
- dev_err(rockchip->pci.dev, "failed to get elbi data\n");
972
- return -EFAULT;
973
- }
974
- break;
9751014 case PCIE_DMA_CACHE_INVALIDE:
9761015 ret = copy_from_user(&cfg, uarg, sizeof(cfg));
9771016 if (ret) {
....@@ -994,18 +1033,8 @@
9941033 dw_pcie_writel_dbi(&rockchip->pci, PCIE_DMA_OFFSET + PCIE_DMA_RD_INT_MASK,
9951034 0xffffffff);
9961035 break;
997
- case PCIE_DMA_RAISE_MSI_OBJ_IRQ_USER:
998
- rockchip->obj_info->irq_type_rc = OBJ_IRQ_USER;
1036
+ case PCIE_EP_RAISE_MSI:
9991037 rockchip_pcie_raise_msi_irq(rockchip, PCIe_CLIENT_MSI_OBJ_IRQ);
1000
- break;
1001
- case PCIE_EP_GET_USER_INFO:
1002
- msg.bar0_phys_addr = rockchip->ib_target_address[0];
1003
-
1004
- ret = copy_to_user(uarg, &msg, sizeof(msg));
1005
- if (ret) {
1006
- dev_err(rockchip->pci.dev, "failed to get elbi data\n");
1007
- return -EFAULT;
1008
- }
10091038 break;
10101039 case PCIE_EP_SET_MMAP_RESOURCE:
10111040 ret = copy_from_user(&mmap_res, uarg, sizeof(mmap_res));
....@@ -1020,6 +1049,34 @@
10201049 }
10211050
10221051 rockchip->cur_mmap_res = mmap_res;
1052
+ break;
1053
+ case PCIE_EP_RAISE_IRQ_USER:
1054
+ ret = copy_from_user(&index, uarg, sizeof(index));
1055
+ if (ret) {
1056
+ dev_err(rockchip->pci.dev,
1057
+ "failed to get raise irq data copy from userspace\n");
1058
+ return -EFAULT;
1059
+ }
1060
+
1061
+ ret = rockchip_pcie_raise_irq_user(rockchip, index);
1062
+ if (ret < 0)
1063
+ return -EFAULT;
1064
+ break;
1065
+ case PCIE_EP_POLL_IRQ_USER:
1066
+ ret = copy_from_user(&poll_cfg, uarg, sizeof(poll_cfg));
1067
+ if (ret) {
1068
+ dev_err(rockchip->pci.dev,
1069
+ "failed to get poll irq data copy from userspace\n");
1070
+
1071
+ return -EFAULT;
1072
+ }
1073
+
1074
+ ret = rockchip_pcie_poll_irq_user(rockchip, &poll_cfg);
1075
+ if (ret < 0)
1076
+ return -EFAULT;
1077
+
1078
+ if (copy_to_user(uarg, &poll_cfg, sizeof(poll_cfg)))
1079
+ return -EFAULT;
10231080 break;
10241081 default:
10251082 break;
....@@ -1081,9 +1138,7 @@
10811138 static const struct file_operations pcie_ep_ops = {
10821139 .owner = THIS_MODULE,
10831140 .open = pcie_ep_open,
1084
- .release = pcie_ep_release,
10851141 .unlocked_ioctl = pcie_ep_ioctl,
1086
- .fasync = pcie_ep_fasync,
10871142 .mmap = pcie_ep_mmap,
10881143 };
10891144
....@@ -1121,6 +1176,7 @@
11211176 struct rockchip_pcie *rockchip;
11221177 int ret;
11231178 int retry, i;
1179
+ u32 reg;
11241180
11251181 rockchip = devm_kzalloc(dev, sizeof(*rockchip), GFP_KERNEL);
11261182 if (!rockchip)
....@@ -1182,6 +1238,26 @@
11821238 rockchip_pcie_start_link(&rockchip->pci);
11831239 rockchip_pcie_devmode_update(rockchip, RKEP_MODE_KERNEL, RKEP_SMODE_LNKRDY);
11841240
1241
+ rockchip->hot_rst_wq = create_singlethread_workqueue("rkep_hot_rst_wq");
1242
+ if (!rockchip->hot_rst_wq) {
1243
+ dev_err(dev, "failed to create hot_rst workqueue\n");
1244
+ ret = -ENOMEM;
1245
+ goto deinit_phy;
1246
+ }
1247
+ INIT_WORK(&rockchip->hot_rst_work, rockchip_pcie_hot_rst_work);
1248
+
1249
+ reg = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_INTR_STATUS_MISC);
1250
+ if ((reg & BIT(2)) &&
1251
+ (rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_HOT_RESET_CTRL) & PCIE_LTSSM_APP_DLY2_EN)) {
1252
+ rockchip_pcie_writel_apb(rockchip, PCIE_LTSSM_APP_DLY2_DONE | (PCIE_LTSSM_APP_DLY2_DONE << 16),
1253
+ PCIE_CLIENT_HOT_RESET_CTRL);
1254
+ dev_info(dev, "hot reset ever\n");
1255
+ }
1256
+ rockchip_pcie_writel_apb(rockchip, reg, PCIE_CLIENT_INTR_STATUS_MISC);
1257
+
1258
+ /* Enable client reset or link down interrupt */
1259
+ rockchip_pcie_writel_apb(rockchip, 0x40000, PCIE_CLIENT_INTR_MASK);
1260
+
11851261 for (retry = 0; retry < 10000; retry++) {
11861262 if (dw_pcie_link_up(&rockchip->pci)) {
11871263 /*
....@@ -1225,12 +1301,14 @@
12251301 rockchip->dma_obj->config_dma_func = rockchip_pcie_config_dma_dwc;
12261302 rockchip->dma_obj->get_dma_status = rockchip_pcie_get_dma_status;
12271303 }
1304
+ mutex_init(&rockchip->file_mutex);
12281305
12291306 /* Enable client ELBI interrupt */
12301307 rockchip_pcie_writel_apb(rockchip, 0x80000000, PCIE_CLIENT_INTR_MASK);
12311308 /* Enable ELBI interrupt */
12321309 rockchip_pcie_local_elbi_enable(rockchip);
12331310
1311
+ init_waitqueue_head(&rockchip->wq_head);
12341312 ret = rockchip_pcie_request_sys_irq(rockchip, pdev);
12351313 if (ret)
12361314 goto deinit_phy;