From 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 13 May 2024 10:30:14 +0000
Subject: [PATCH] modify sin led gpio
---
kernel/drivers/video/rockchip/mpp/mpp_vepu2.c | 83 +++++++++++++++++++++++++++++++----------
1 files changed, 63 insertions(+), 20 deletions(-)
diff --git a/kernel/drivers/video/rockchip/mpp/mpp_vepu2.c b/kernel/drivers/video/rockchip/mpp/mpp_vepu2.c
index 12aef5e..fb5f5e5 100644
--- a/kernel/drivers/video/rockchip/mpp/mpp_vepu2.c
+++ b/kernel/drivers/video/rockchip/mpp/mpp_vepu2.c
@@ -22,6 +22,7 @@
#include <linux/proc_fs.h>
#include <linux/nospec.h>
#include <soc/rockchip/pm_domains.h>
+#include <soc/rockchip/rockchip_iommu.h>
#include "mpp_debug.h"
#include "mpp_common.h"
@@ -314,43 +315,40 @@
static void *vepu_prepare(struct mpp_dev *mpp, struct mpp_task *mpp_task)
{
- struct mpp_taskqueue *queue = mpp->queue;
struct vepu_dev *enc = to_vepu_dev(mpp);
struct vepu_ccu *ccu = enc->ccu;
unsigned long core_idle;
unsigned long flags;
- u32 core_id_max;
s32 core_id;
u32 i;
spin_lock_irqsave(&ccu->lock, flags);
- core_idle = queue->core_idle;
- core_id_max = queue->core_id_max;
+ core_idle = ccu->core_idle;
- for (i = 0; i <= core_id_max; i++) {
- struct mpp_dev *mpp = queue->cores[i];
+ for (i = 0; i < ccu->core_num; i++) {
+ struct mpp_dev *mpp = ccu->cores[i];
if (mpp && mpp->disable)
- clear_bit(i, &core_idle);
+ clear_bit(mpp->core_id, &core_idle);
}
- core_id = find_first_bit(&ccu->core_idle, ccu->core_num);
- core_id = array_index_nospec(core_id, MPP_MAX_CORE_NUM);
- if (core_id >= core_id_max + 1 || !queue->cores[core_id]) {
+ core_id = find_first_bit(&core_idle, ccu->core_num);
+ if (core_id >= ARRAY_SIZE(ccu->cores)) {
mpp_task = NULL;
mpp_dbg_core("core %d all busy %lx\n", core_id, ccu->core_idle);
- } else {
- unsigned long core_idle = ccu->core_idle;
-
- clear_bit(core_id, &ccu->core_idle);
- mpp_task->mpp = ccu->cores[core_id];
- mpp_task->core_id = core_id;
-
- mpp_dbg_core("core cnt %d core %d set idle %lx -> %lx\n",
- ccu->core_num, core_id, core_idle, ccu->core_idle);
+ goto done;
}
+ core_id = array_index_nospec(core_id, MPP_MAX_CORE_NUM);
+ clear_bit(core_id, &ccu->core_idle);
+ mpp_task->mpp = ccu->cores[core_id];
+ mpp_task->core_id = core_id;
+
+ mpp_dbg_core("core cnt %d core %d set idle %lx -> %lx\n",
+ ccu->core_num, core_id, core_idle, ccu->core_idle);
+
+done:
spin_unlock_irqrestore(&ccu->lock, flags);
return mpp_task;
@@ -885,6 +883,48 @@
return 0;
}
+static int vepu2_iommu_fault_handle(struct iommu_domain *iommu, struct device *iommu_dev,
+ unsigned long iova, int status, void *arg)
+{
+ struct mpp_dev *mpp = (struct mpp_dev *)arg;
+ struct mpp_task *mpp_task;
+ struct vepu_dev *enc = to_vepu_dev(mpp);
+ struct vepu_ccu *ccu = enc->ccu;
+
+ dev_err(iommu_dev, "fault addr 0x%08lx status %x arg %p\n",
+ iova, status, arg);
+
+ if (ccu) {
+ int i;
+ struct mpp_dev *core;
+
+ for (i = 0; i < ccu->core_num; i++) {
+ core = ccu->cores[i];
+ if (core->iommu_info && (&core->iommu_info->pdev->dev == iommu_dev)) {
+ mpp = core;
+ break;
+ }
+ }
+ }
+
+ if (!mpp) {
+ dev_err(iommu_dev, "pagefault without device to handle\n");
+ return 0;
+ }
+ mpp_task = mpp->cur_task;
+ if (mpp_task)
+ mpp_task_dump_mem_region(mpp, mpp_task);
+
+ mpp_task_dump_hw_reg(mpp);
+ /*
+ * Mask iommu irq, in order for iommu not repeatedly trigger pagefault.
+ * Until the pagefault task finish by hw timeout.
+ */
+ rockchip_iommu_mask_irq(mpp->dev);
+
+ return 0;
+}
+
static struct mpp_hw_ops vepu_v2_hw_ops = {
.init = vepu_init,
.clk_on = vepu_clk_on,
@@ -1050,7 +1090,8 @@
ccu_info = ccu->main_core->iommu_info;
cur_info = enc->mpp.iommu_info;
- cur_info->domain = ccu_info->domain;
+ if (cur_info)
+ cur_info->domain = ccu_info->domain;
mpp_iommu_attach(cur_info);
}
enc->ccu = ccu;
@@ -1102,6 +1143,7 @@
return -EINVAL;
}
+ mpp->fault_handler = vepu2_iommu_fault_handle;
mpp->session_max_buffers = VEPU2_SESSION_MAX_BUFFERS;
vepu_procfs_init(mpp);
vepu_procfs_ccu_init(mpp);
@@ -1151,6 +1193,7 @@
return -EINVAL;
}
+ mpp->fault_handler = vepu2_iommu_fault_handle;
mpp->session_max_buffers = VEPU2_SESSION_MAX_BUFFERS;
vepu_procfs_init(mpp);
/* register current device to mpp service */
--
Gitblit v1.6.2