hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/drivers/pci/controller/dwc/pcie-dw-ep-rockchip.c
....@@ -10,7 +10,6 @@
1010
1111 #include <linux/clk.h>
1212 #include <linux/gpio/consumer.h>
13
-#include <linux/iopoll.h>
1413 #include <linux/miscdevice.h>
1514 #include <linux/mfd/syscon.h>
1615 #include <linux/module.h>
....@@ -95,11 +94,13 @@
9594 #define PCIE_ELBI_LOCAL_BASE 0x200e00
9695
9796 #define PCIE_ELBI_APP_ELBI_INT_GEN0 0x0
98
-#define PCIE_ELBI_APP_ELBI_INT_GEN0_SIGIO BIT(0)
97
+#define PCIE_ELBI_APP_ELBI_INT_GEN0_IRQ_USER BIT(0)
9998
10099 #define PCIE_ELBI_APP_ELBI_INT_GEN1 0x4
101100
102101 #define PCIE_ELBI_LOCAL_ENABLE_OFF 0x8
102
+
103
+#define PCIE_ELBI_USER_DATA_OFF 0x10
103104
104105 #define PCIE_DIRECT_SPEED_CHANGE BIT(17)
105106
....@@ -132,12 +133,14 @@
132133 u32 ib_target_size[PCIE_BAR_MAX_NUM];
133134 void *ib_target_base[PCIE_BAR_MAX_NUM];
134135 struct dma_trx_obj *dma_obj;
135
- struct fasync_struct *async;
136136 phys_addr_t dbi_base_physical;
137137 struct pcie_ep_obj_info *obj_info;
138138 enum pcie_ep_mmap_resource cur_mmap_res;
139139 struct workqueue_struct *hot_rst_wq;
140140 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;
141144 };
142145
143146 struct rockchip_pcie_misc_dev {
....@@ -207,7 +210,6 @@
207210 struct device_node *np = dev->of_node;
208211 void *addr;
209212 struct resource *dbi_base;
210
- struct resource *apb_base;
211213 struct device_node *mem;
212214 struct resource reg;
213215 char name[8];
....@@ -223,17 +225,14 @@
223225 rockchip->pci.dbi_base = devm_ioremap_resource(dev, dbi_base);
224226 if (IS_ERR(rockchip->pci.dbi_base))
225227 return PTR_ERR(rockchip->pci.dbi_base);
228
+ rockchip->pci.atu_base = rockchip->pci.dbi_base + DEFAULT_DBI_ATU_OFFSET;
226229 rockchip->dbi_base_physical = dbi_base->start;
227230
228
- apb_base = platform_get_resource_byname(pdev, IORESOURCE_MEM,
229
- "pcie-apb");
230
- if (!apb_base) {
231
+ rockchip->apb_base = devm_platform_ioremap_resource_byname(pdev, "pcie-apb");
232
+ if (!rockchip->apb_base) {
231233 dev_err(dev, "get pcie-apb failed\n");
232234 return -ENODEV;
233235 }
234
- rockchip->apb_base = devm_ioremap_resource(dev, apb_base);
235
- if (IS_ERR(rockchip->apb_base))
236
- return PTR_ERR(rockchip->apb_base);
237236
238237 rockchip->rst_gpio = devm_gpiod_get_optional(dev, "reset",
239238 GPIOD_OUT_HIGH);
....@@ -533,18 +532,18 @@
533532
534533 /* Resize BAR0 4M 32bits, BAR2 64M 64bits-pref, BAR4 1MB 32bits */
535534 bar = BAR_0;
536
- dw_pcie_writel_dbi(pci, resbar_base + 0x4 + bar * 0x8, 0xfffff0);
535
+ dw_pcie_writel_dbi(pci, resbar_base + 0x4 + bar * 0x8, 0x40);
537536 dw_pcie_writel_dbi(pci, resbar_base + 0x8 + bar * 0x8, 0x2c0);
538537 rockchip_pcie_ep_set_bar_flag(rockchip, bar, PCI_BASE_ADDRESS_MEM_TYPE_32);
539538
540539 bar = BAR_2;
541
- dw_pcie_writel_dbi(pci, resbar_base + 0x4 + bar * 0x8, 0xfffff0);
540
+ dw_pcie_writel_dbi(pci, resbar_base + 0x4 + bar * 0x8, 0x400);
542541 dw_pcie_writel_dbi(pci, resbar_base + 0x8 + bar * 0x8, 0x6c0);
543542 rockchip_pcie_ep_set_bar_flag(rockchip, bar,
544543 PCI_BASE_ADDRESS_MEM_PREFETCH | PCI_BASE_ADDRESS_MEM_TYPE_64);
545544
546545 bar = BAR_4;
547
- dw_pcie_writel_dbi(pci, resbar_base + 0x4 + bar * 0x8, 0xfffff0);
546
+ dw_pcie_writel_dbi(pci, resbar_base + 0x4 + bar * 0x8, 0x10);
548547 dw_pcie_writel_dbi(pci, resbar_base + 0x8 + bar * 0x8, 0xc0);
549548 rockchip_pcie_ep_set_bar_flag(rockchip, bar, PCI_BASE_ADDRESS_MEM_TYPE_32);
550549
....@@ -580,7 +579,7 @@
580579
581580 as_type = DW_PCIE_AS_MEM;
582581
583
- ret = dw_pcie_prog_inbound_atu(pci, free_win, bar, cpu_addr, as_type);
582
+ ret = dw_pcie_prog_inbound_atu(pci, 0, free_win, bar, cpu_addr, as_type);
584583 if (ret < 0) {
585584 dev_err(pci->dev, "Failed to program IB window\n");
586585 return ret;
....@@ -647,6 +646,49 @@
647646 rockchip_pcie_writel_apb(rockchip, BIT(interrupt_num), PCIE_CLIENT_MSI_GEN_CON);
648647 }
649648
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
+
650692 static irqreturn_t rockchip_pcie_sys_irq_handler(int irq, void *arg)
651693 {
652694 struct rockchip_pcie *rockchip = arg;
....@@ -656,14 +698,19 @@
656698 union int_status wr_status, rd_status;
657699 union int_clear clears;
658700 u32 reg, mask;
659
- bool sigio = false;
660701
661702 /* ELBI helper, only check the valid bits, and discard the rest interrupts */
662703 elbi_reg = dw_pcie_readl_dbi(pci, PCIE_ELBI_LOCAL_BASE + PCIE_ELBI_APP_ELBI_INT_GEN0);
663
- if (elbi_reg & PCIE_ELBI_APP_ELBI_INT_GEN0_SIGIO) {
664
- sigio = true;
665
- rockchip->obj_info->irq_type_ep = OBJ_IRQ_ELBI;
704
+ if (elbi_reg & PCIE_ELBI_APP_ELBI_INT_GEN0_IRQ_USER) {
666705 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
+ }
667714 goto out;
668715 }
669716
....@@ -716,15 +763,9 @@
716763 rockchip->obj_info->irq_type_ep = OBJ_IRQ_DMA;
717764 rockchip->obj_info->dma_status_ep.wr |= wr_status.asdword;
718765 rockchip->obj_info->dma_status_ep.rd |= rd_status.asdword;
719
- sigio = true;
720766 }
721767
722768 out:
723
- if (sigio) {
724
- dev_dbg(rockchip->pci.dev, "SIGIO\n");
725
- kill_fasync(&rockchip->async, SIGIO, POLL_IN);
726
- }
727
-
728769 reg = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_INTR_STATUS_MISC);
729770 if (reg & BIT(2))
730771 queue_work(rockchip->hot_rst_wq, &rockchip->hot_rst_work);
....@@ -949,13 +990,6 @@
949990 .link_up = rockchip_pcie_link_up,
950991 };
951992
952
-static int pcie_ep_fasync(int fd, struct file *file, int mode)
953
-{
954
- struct rockchip_pcie *rockchip = (struct rockchip_pcie *)file->private_data;
955
-
956
- return fasync_helper(fd, file, mode, &rockchip->async);
957
-}
958
-
959993 static int pcie_ep_open(struct inode *inode, struct file *file)
960994 {
961995 struct miscdevice *miscdev = file->private_data;
....@@ -967,35 +1001,16 @@
9671001 return 0;
9681002 }
9691003
970
-static int pcie_ep_release(struct inode *inode, struct file *file)
971
-{
972
- return pcie_ep_fasync(-1, file, 0);
973
-}
974
-
9751004 static long pcie_ep_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
9761005 {
9771006 struct rockchip_pcie *rockchip = (struct rockchip_pcie *)file->private_data;
978
- struct pcie_ep_user_data msg;
9791007 struct pcie_ep_dma_cache_cfg cfg;
9801008 void __user *uarg = (void __user *)arg;
981
- int i, ret;
1009
+ struct pcie_ep_obj_poll_virtual_id_cfg poll_cfg;
9821010 enum pcie_ep_mmap_resource mmap_res;
1011
+ int ret, index;
9831012
9841013 switch (cmd) {
985
- case PCIE_DMA_GET_ELBI_DATA:
986
- for (i = 4; i <= 6; i++)
987
- msg.elbi_app_user[i - 4] = dw_pcie_readl_dbi(&rockchip->pci,
988
- PCIE_ELBI_LOCAL_BASE + i * 4);
989
- for (i = 8; i <= 15; i++)
990
- msg.elbi_app_user[i - 5] = dw_pcie_readl_dbi(&rockchip->pci,
991
- PCIE_ELBI_LOCAL_BASE + i * 4);
992
-
993
- ret = copy_to_user(uarg, &msg, sizeof(msg));
994
- if (ret) {
995
- dev_err(rockchip->pci.dev, "failed to get elbi data\n");
996
- return -EFAULT;
997
- }
998
- break;
9991014 case PCIE_DMA_CACHE_INVALIDE:
10001015 ret = copy_from_user(&cfg, uarg, sizeof(cfg));
10011016 if (ret) {
....@@ -1018,18 +1033,8 @@
10181033 dw_pcie_writel_dbi(&rockchip->pci, PCIE_DMA_OFFSET + PCIE_DMA_RD_INT_MASK,
10191034 0xffffffff);
10201035 break;
1021
- case PCIE_DMA_RAISE_MSI_OBJ_IRQ_USER:
1022
- rockchip->obj_info->irq_type_rc = OBJ_IRQ_USER;
1036
+ case PCIE_EP_RAISE_MSI:
10231037 rockchip_pcie_raise_msi_irq(rockchip, PCIe_CLIENT_MSI_OBJ_IRQ);
1024
- break;
1025
- case PCIE_EP_GET_USER_INFO:
1026
- msg.bar0_phys_addr = rockchip->ib_target_address[0];
1027
-
1028
- ret = copy_to_user(uarg, &msg, sizeof(msg));
1029
- if (ret) {
1030
- dev_err(rockchip->pci.dev, "failed to get elbi data\n");
1031
- return -EFAULT;
1032
- }
10331038 break;
10341039 case PCIE_EP_SET_MMAP_RESOURCE:
10351040 ret = copy_from_user(&mmap_res, uarg, sizeof(mmap_res));
....@@ -1044,6 +1049,34 @@
10441049 }
10451050
10461051 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;
10471080 break;
10481081 default:
10491082 break;
....@@ -1105,9 +1138,7 @@
11051138 static const struct file_operations pcie_ep_ops = {
11061139 .owner = THIS_MODULE,
11071140 .open = pcie_ep_open,
1108
- .release = pcie_ep_release,
11091141 .unlocked_ioctl = pcie_ep_ioctl,
1110
- .fasync = pcie_ep_fasync,
11111142 .mmap = pcie_ep_mmap,
11121143 };
11131144
....@@ -1270,12 +1301,14 @@
12701301 rockchip->dma_obj->config_dma_func = rockchip_pcie_config_dma_dwc;
12711302 rockchip->dma_obj->get_dma_status = rockchip_pcie_get_dma_status;
12721303 }
1304
+ mutex_init(&rockchip->file_mutex);
12731305
12741306 /* Enable client ELBI interrupt */
12751307 rockchip_pcie_writel_apb(rockchip, 0x80000000, PCIE_CLIENT_INTR_MASK);
12761308 /* Enable ELBI interrupt */
12771309 rockchip_pcie_local_elbi_enable(rockchip);
12781310
1311
+ init_waitqueue_head(&rockchip->wq_head);
12791312 ret = rockchip_pcie_request_sys_irq(rockchip, pdev);
12801313 if (ret)
12811314 goto deinit_phy;