From 0d8657dd3056063fb115946b10157477b5c70451 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 20 Nov 2023 09:09:45 +0000
Subject: [PATCH] enable lvds 1280x800
---
kernel/drivers/video/rockchip/mpp/mpp_rkvdec2.c | 81 +++++++++++++++++++++++++++++++++++++---
1 files changed, 75 insertions(+), 6 deletions(-)
diff --git a/kernel/drivers/video/rockchip/mpp/mpp_rkvdec2.c b/kernel/drivers/video/rockchip/mpp/mpp_rkvdec2.c
index f6d605d..61364f2 100644
--- a/kernel/drivers/video/rockchip/mpp/mpp_rkvdec2.c
+++ b/kernel/drivers/video/rockchip/mpp/mpp_rkvdec2.c
@@ -17,8 +17,10 @@
#include <linux/devfreq_cooling.h>
#include <soc/rockchip/rockchip_ipa.h>
+#include <soc/rockchip/rockchip_dmc.h>
#include <soc/rockchip/rockchip_opp_select.h>
#include <soc/rockchip/rockchip_system_monitor.h>
+#include <soc/rockchip/rockchip_iommu.h>
#ifdef CONFIG_PM_DEVFREQ
#include "../../../devfreq/governor.h"
@@ -304,6 +306,7 @@
static int rkvdec2_run(struct mpp_dev *mpp, struct mpp_task *mpp_task)
{
struct rkvdec2_task *task = to_rkvdec2_task(mpp_task);
+ u32 timing_en = mpp->srv->timing_en;
u32 reg_en = mpp_task->hw_info->reg_en;
/* set cache size */
u32 reg = RKVDEC_CACHE_PERMIT_CACHEABLE_ACCESS |
@@ -332,12 +335,20 @@
e = s + req->size / sizeof(u32);
mpp_write_req(mpp, task->reg, s, e, reg_en);
}
+
+ /* flush tlb before starting hardware */
+ mpp_iommu_flush_tlb(mpp->iommu_info);
+
/* init current task */
mpp->cur_task = mpp_task;
- mpp_time_record(mpp_task);
+
+ mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY);
+
/* Flush the register before the start the device */
wmb();
mpp_write(mpp, RKVDEC_REG_START_EN_BASE, task->reg[reg_en] | RKVDEC_START_EN);
+
+ mpp_task_run_end(mpp_task, timing_en);
mpp_debug_leave();
@@ -381,13 +392,15 @@
u32 err_mask;
struct rkvdec2_task *task = NULL;
struct mpp_task *mpp_task = mpp->cur_task;
+ struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp);
/* FIXME use a spin lock here */
if (!mpp_task) {
dev_err(mpp->dev, "no current task\n");
return IRQ_HANDLED;
}
- mpp_time_diff(mpp_task);
+ mpp_task->hw_cycles = mpp_read(mpp, RKVDEC_PERF_WORKING_CNT);
+ mpp_time_diff_with_hw_time(mpp_task, dec->core_clk_info.real_rate_hz);
mpp->cur_task = NULL;
task = to_rkvdec2_task(mpp_task);
task->irq_status = mpp->irq_status;
@@ -552,6 +565,16 @@
}
}
} break;
+ case MPP_CMD_SET_ERR_REF_HACK: {
+ struct rkvdec2_dev *dec = to_rkvdec2_dev(session->mpp);
+ u32 err_ref_hack_en = 0;
+
+ if (copy_from_user(&err_ref_hack_en, req->data, sizeof(u32))) {
+ mpp_err("copy_from_user failed\n");
+ return -EINVAL;
+ }
+ dec->err_ref_hack = err_ref_hack_en;
+ } break;
default: {
mpp_err("unknown mpp ioctl cmd %x\n", req->cmd);
} break;
@@ -617,6 +640,10 @@
dec->procfs = NULL;
return -EIO;
}
+
+ /* for common mpp_dev options */
+ mpp_procfs_create_common(dec->procfs, mpp);
+
mpp_procfs_create_u32("aclk", 0644,
dec->procfs, &dec->aclk_info.debug_rate_hz);
mpp_procfs_create_u32("clk_core", 0644,
@@ -1067,17 +1094,41 @@
return 0;
}
+static int rkvdec2_soft_reset(struct mpp_dev *mpp)
+{
+ int ret = 0;
+
+ /*
+ * for rk3528 and rk3562
+ * use mmu reset instead of rkvdec soft reset
+ * rkvdec will reset together when rkvdec_mmu force reset
+ */
+ ret = rockchip_iommu_force_reset(mpp->dev);
+ if (ret)
+ mpp_err("soft mmu reset fail, ret %d\n", ret);
+ mpp_write(mpp, RKVDEC_REG_INT_EN, 0);
+
+ return ret;
+
+}
+
static int rkvdec2_reset(struct mpp_dev *mpp)
{
struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp);
+ int ret = 0;
mpp_debug_enter();
#ifdef CONFIG_PM_DEVFREQ
if (dec->devfreq)
mutex_lock(&dec->devfreq->lock);
#endif
- if (dec->rst_a && dec->rst_h) {
- rockchip_pmu_idle_request(mpp->dev, true);
+ /* safe reset first*/
+ ret = rkvdec2_soft_reset(mpp);
+
+ /* cru reset */
+ if (ret && dec->rst_a && dec->rst_h) {
+ mpp_err("soft reset timeout, use cru reset\n");
+ mpp_pmu_idle_request(mpp, true);
mpp_safe_reset(dec->rst_niu_a);
mpp_safe_reset(dec->rst_niu_h);
mpp_safe_reset(dec->rst_a);
@@ -1093,12 +1144,30 @@
mpp_safe_unreset(dec->rst_core);
mpp_safe_unreset(dec->rst_cabac);
mpp_safe_unreset(dec->rst_hevc_cabac);
- rockchip_pmu_idle_request(mpp->dev, false);
+ mpp_pmu_idle_request(mpp, false);
}
#ifdef CONFIG_PM_DEVFREQ
if (dec->devfreq)
mutex_unlock(&dec->devfreq->lock);
#endif
+ mpp_debug_leave();
+
+ return 0;
+}
+
+static int rkvdec2_sip_reset(struct mpp_dev *mpp)
+{
+ mpp_debug_enter();
+
+ if (IS_REACHABLE(CONFIG_ROCKCHIP_SIP)) {
+ /* sip reset */
+ rockchip_dmcfreq_lock();
+ sip_smc_vpu_reset(0, 0, 0);
+ rockchip_dmcfreq_unlock();
+ } else {
+ rkvdec2_reset(mpp);
+ }
+
mpp_debug_leave();
return 0;
@@ -1120,7 +1189,7 @@
.clk_off = rkvdec2_clk_off,
.get_freq = rkvdec2_get_freq,
.set_freq = rkvdec2_set_freq,
- .reset = rkvdec2_reset,
+ .reset = rkvdec2_sip_reset,
};
static struct mpp_dev_ops rkvdec_v2_dev_ops = {
--
Gitblit v1.6.2