From 15ade055295d13f95d49e3d99b09f3bbfb4a43e7 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 06 Nov 2023 07:25:24 +0000 Subject: [PATCH] add at24 driver --- 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