hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/video/rockchip/mpp/mpp_vepu2.c
....@@ -22,6 +22,7 @@
2222 #include <linux/proc_fs.h>
2323 #include <linux/nospec.h>
2424 #include <soc/rockchip/pm_domains.h>
25
+#include <soc/rockchip/rockchip_iommu.h>
2526
2627 #include "mpp_debug.h"
2728 #include "mpp_common.h"
....@@ -882,6 +883,48 @@
882883 return 0;
883884 }
884885
886
+static int vepu2_iommu_fault_handle(struct iommu_domain *iommu, struct device *iommu_dev,
887
+ unsigned long iova, int status, void *arg)
888
+{
889
+ struct mpp_dev *mpp = (struct mpp_dev *)arg;
890
+ struct mpp_task *mpp_task;
891
+ struct vepu_dev *enc = to_vepu_dev(mpp);
892
+ struct vepu_ccu *ccu = enc->ccu;
893
+
894
+ dev_err(iommu_dev, "fault addr 0x%08lx status %x arg %p\n",
895
+ iova, status, arg);
896
+
897
+ if (ccu) {
898
+ int i;
899
+ struct mpp_dev *core;
900
+
901
+ for (i = 0; i < ccu->core_num; i++) {
902
+ core = ccu->cores[i];
903
+ if (core->iommu_info && (&core->iommu_info->pdev->dev == iommu_dev)) {
904
+ mpp = core;
905
+ break;
906
+ }
907
+ }
908
+ }
909
+
910
+ if (!mpp) {
911
+ dev_err(iommu_dev, "pagefault without device to handle\n");
912
+ return 0;
913
+ }
914
+ mpp_task = mpp->cur_task;
915
+ if (mpp_task)
916
+ mpp_task_dump_mem_region(mpp, mpp_task);
917
+
918
+ mpp_task_dump_hw_reg(mpp);
919
+ /*
920
+ * Mask iommu irq, in order for iommu not repeatedly trigger pagefault.
921
+ * Until the pagefault task finish by hw timeout.
922
+ */
923
+ rockchip_iommu_mask_irq(mpp->dev);
924
+
925
+ return 0;
926
+}
927
+
885928 static struct mpp_hw_ops vepu_v2_hw_ops = {
886929 .init = vepu_init,
887930 .clk_on = vepu_clk_on,
....@@ -1100,6 +1143,7 @@
11001143 return -EINVAL;
11011144 }
11021145
1146
+ mpp->fault_handler = vepu2_iommu_fault_handle;
11031147 mpp->session_max_buffers = VEPU2_SESSION_MAX_BUFFERS;
11041148 vepu_procfs_init(mpp);
11051149 vepu_procfs_ccu_init(mpp);
....@@ -1149,6 +1193,7 @@
11491193 return -EINVAL;
11501194 }
11511195
1196
+ mpp->fault_handler = vepu2_iommu_fault_handle;
11521197 mpp->session_max_buffers = VEPU2_SESSION_MAX_BUFFERS;
11531198 vepu_procfs_init(mpp);
11541199 /* register current device to mpp service */