From 7d07b3ae8ddad407913c5301877e694430a3263f Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 23 Nov 2023 08:24:31 +0000
Subject: [PATCH] add build kerneldeb
---
kernel/drivers/video/rockchip/mpp/mpp_iep2.c | 105 +++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 91 insertions(+), 14 deletions(-)
diff --git a/kernel/drivers/video/rockchip/mpp/mpp_iep2.c b/kernel/drivers/video/rockchip/mpp/mpp_iep2.c
index 92ec40e..e8e2183 100644
--- a/kernel/drivers/video/rockchip/mpp/mpp_iep2.c
+++ b/kernel/drivers/video/rockchip/mpp/mpp_iep2.c
@@ -20,6 +20,8 @@
#include <linux/regmap.h>
#include <linux/pm_runtime.h>
#include <linux/proc_fs.h>
+#include <linux/mfd/syscon.h>
+#include <linux/rockchip/cpu.h>
#include <soc/rockchip/pm_domains.h>
#include "rockchip_iep2_regs.h"
@@ -389,12 +391,13 @@
| IEP2_REG_DIL_OSD_EN
| IEP2_REG_DIL_PD_EN
| IEP2_REG_DIL_FF_EN
- | IEP2_REG_DIL_MD_PRE_EN
| IEP2_REG_DIL_FIELD_ORDER(cfg->dil_field_order)
| IEP2_REG_DIL_OUT_MODE(cfg->dil_out_mode)
| IEP2_REG_DIL_MODE(cfg->dil_mode);
if (cfg->roi_en)
reg |= IEP2_REG_DIL_ROI_EN;
+ if (cfg->md_lambda < 8)
+ reg |= IEP2_REG_DIL_MD_PRE_EN;
mpp_write_relaxed(mpp, IEP2_REG_DIL_CONFIG0, reg);
if (cfg->dil_mode != ROCKCHIP_IEP2_DIL_MODE_PD) {
@@ -437,6 +440,9 @@
mpp_write_relaxed(mpp, IEP2_REG_SRC_ADDR_NXTUV, bot->cbcr);
mpp_write_relaxed(mpp, IEP2_REG_SRC_ADDR_NXTV, bot->cr);
}
+
+ reg = IEP2_REG_TIMEOUT_CFG_EN | 0x3ffffff;
+ mpp_write_relaxed(mpp, IEP2_REG_TIMEOUT_CFG, reg);
mpp_write_relaxed(mpp, IEP2_REG_SRC_ADDR_PREY, cfg->src[2].y);
mpp_write_relaxed(mpp, IEP2_REG_SRC_ADDR_PREUV, cfg->src[2].cbcr);
@@ -580,6 +586,7 @@
struct mpp_task *mpp_task)
{
struct iep_task *task = NULL;
+ u32 timing_en = mpp->srv->timing_en;
mpp_debug_enter();
@@ -598,12 +605,20 @@
mpp_write_relaxed(mpp, IEP2_REG_INT_EN,
IEP2_REG_FRM_DONE_EN
| IEP2_REG_OSD_MAX_EN
- | IEP2_REG_BUS_ERROR_EN);
+ | IEP2_REG_BUS_ERROR_EN
+ | IEP2_REG_TIMEOUT_EN);
+
+ /* flush tlb before starting hardware */
+ mpp_iommu_flush_tlb(mpp->iommu_info);
+
+ mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY);
/* Last, flush the registers */
wmb();
/* start iep2 */
mpp_write(mpp, IEP2_REG_FRM_START, 1);
+
+ mpp_task_run_end(mpp_task, timing_en);
mpp_debug_leave();
@@ -612,6 +627,10 @@
static int iep2_irq(struct mpp_dev *mpp)
{
+ u32 work_mode = mpp_read(mpp, IEP2_REG_WORK_MODE);
+
+ if (work_mode && !(work_mode & IEP2_REG_IEP2_MODE))
+ return IRQ_NONE;
mpp->irq_status = mpp_read(mpp, IEP2_REG_INT_STS);
mpp_write(mpp, IEP2_REG_INT_CLR, 0xffffffff);
@@ -640,7 +659,8 @@
mpp_debug(DEBUG_IRQ_STATUS, "irq_status: %08x\n",
task->irq_status);
- if (IEP2_REG_RO_BUS_ERROR_STS(task->irq_status))
+ if (IEP2_REG_RO_BUS_ERROR_STS(task->irq_status) ||
+ IEP2_REG_RO_TIMEOUT_STS(task->irq_status))
atomic_inc(&mpp->reset_request);
mpp_task_finish(mpp_task->session, mpp_task);
@@ -769,6 +789,10 @@
iep->procfs = NULL;
return -EIO;
}
+
+ /* for common mpp_dev options */
+ mpp_procfs_create_common(iep->procfs, mpp);
+
mpp_procfs_create_u32("aclk", 0644,
iep->procfs, &iep->aclk_info.debug_rate_hz);
mpp_procfs_create_u32("session_buffers", 0644,
@@ -870,17 +894,29 @@
{
struct iep2_dev *iep = to_iep2_dev(mpp);
- if (iep->rst_a && iep->rst_h && iep->rst_s) {
- /* Don't skip this or iommu won't work after reset */
- rockchip_pmu_idle_request(mpp->dev, true);
- mpp_safe_reset(iep->rst_a);
- mpp_safe_reset(iep->rst_h);
- mpp_safe_reset(iep->rst_s);
- udelay(5);
- mpp_safe_unreset(iep->rst_a);
- mpp_safe_unreset(iep->rst_h);
- mpp_safe_unreset(iep->rst_s);
- rockchip_pmu_idle_request(mpp->dev, false);
+ int ret = 0;
+ u32 rst_status = 0;
+
+ /* soft rest first */
+ mpp_write(mpp, IEP2_REG_IEP_CONFIG0, IEP2_REG_ACLK_SRESET_P);
+ ret = readl_relaxed_poll_timeout(mpp->reg_base + IEP2_REG_STATUS,
+ rst_status,
+ rst_status & IEP2_REG_ARST_FINISH_DONE,
+ 0, 5);
+ if (ret) {
+ mpp_err("soft reset timeout, use cru reset\n");
+ if (iep->rst_a && iep->rst_h && iep->rst_s) {
+ /* Don't skip this or iommu won't work after reset */
+ mpp_pmu_idle_request(mpp, true);
+ mpp_safe_reset(iep->rst_a);
+ mpp_safe_reset(iep->rst_h);
+ mpp_safe_reset(iep->rst_s);
+ udelay(5);
+ mpp_safe_unreset(iep->rst_a);
+ mpp_safe_unreset(iep->rst_h);
+ mpp_safe_unreset(iep->rst_s);
+ mpp_pmu_idle_request(mpp, false);
+ }
}
return 0;
@@ -1008,12 +1044,53 @@
dev_err(dev, "wait total running time out\n");
}
+static int iep2_runtime_suspend(struct device *dev)
+{
+ struct mpp_dev *mpp = dev_get_drvdata(dev);
+ struct mpp_grf_info *info = mpp->grf_info;
+ struct mpp_taskqueue *queue = mpp->queue;
+
+ if (cpu_is_rk3528() && info && info->mem_offset) {
+ mutex_lock(&queue->ref_lock);
+ if (!atomic_dec_if_positive(&queue->runtime_cnt)) {
+ regmap_write(info->grf, info->mem_offset,
+ info->val_mem_off);
+ }
+ mutex_unlock(&queue->ref_lock);
+ }
+
+ return 0;
+}
+
+static int iep2_runtime_resume(struct device *dev)
+{
+ struct mpp_dev *mpp = dev_get_drvdata(dev);
+ struct mpp_grf_info *info = mpp->grf_info;
+ struct mpp_taskqueue *queue = mpp->queue;
+
+ if (cpu_is_rk3528() && info && info->mem_offset) {
+ mutex_lock(&queue->ref_lock);
+ regmap_write(info->grf, info->mem_offset,
+ info->val_mem_on);
+ atomic_inc(&queue->runtime_cnt);
+ mutex_unlock(&queue->ref_lock);
+ }
+
+ return 0;
+}
+
+static const struct dev_pm_ops iep2_pm_ops = {
+ .runtime_suspend = iep2_runtime_suspend,
+ .runtime_resume = iep2_runtime_resume,
+};
+
struct platform_driver rockchip_iep2_driver = {
.probe = iep2_probe,
.remove = iep2_remove,
.shutdown = iep2_shutdown,
.driver = {
.name = IEP2_DRIVER_NAME,
+ .pm = &iep2_pm_ops,
.of_match_table = of_match_ptr(mpp_iep2_match),
},
};
--
Gitblit v1.6.2