From e3e12f52b214121840b44c91de5b3e5af5d3eb84 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 06 Nov 2023 03:04:41 +0000 Subject: [PATCH] rk3568 rt init --- kernel/drivers/video/rockchip/mpp/mpp_vdpu1.c | 82 ++++++++++++++++++++++++++++++++++++++-- 1 files changed, 77 insertions(+), 5 deletions(-) diff --git a/kernel/drivers/video/rockchip/mpp/mpp_vdpu1.c b/kernel/drivers/video/rockchip/mpp/mpp_vdpu1.c index a14f102..537c6a2 100644 --- a/kernel/drivers/video/rockchip/mpp/mpp_vdpu1.c +++ b/kernel/drivers/video/rockchip/mpp/mpp_vdpu1.c @@ -20,6 +20,8 @@ #include <linux/uaccess.h> #include <linux/regmap.h> #include <linux/proc_fs.h> +#include <linux/mfd/syscon.h> +#include <linux/rockchip/cpu.h> #include <soc/rockchip/pm_domains.h> #include "mpp_debug.h" @@ -57,6 +59,9 @@ /* NOTE: Don't enable it or decoding AVC would meet problem at rk3288 */ #define VDPU1_REG_DEC_EN 0x008 #define VDPU1_CLOCK_GATE_EN BIT(10) + +#define VDPU1_REG_SOFT_RESET 0x194 +#define VDPU1_REG_SOFT_RESET_INDEX (101) #define VDPU1_REG_SYS_CTRL 0x00c #define VDPU1_REG_SYS_CTRL_INDEX (3) @@ -387,6 +392,7 @@ u32 i; u32 reg_en; struct vdpu_task *task = to_vdpu_task(mpp_task); + u32 timing_en = mpp->srv->timing_en; mpp_debug_enter(); @@ -401,12 +407,21 @@ 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_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY); + /* Flush the register before the start the device */ wmb(); mpp_write(mpp, VDPU1_REG_DEC_INT_EN, task->reg[reg_en] | VDPU1_DEC_START); + + mpp_task_run_end(mpp_task, timing_en); mpp_debug_leave(); @@ -503,6 +518,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("session_buffers", 0644, @@ -663,21 +682,35 @@ return IRQ_HANDLED; } +static int vdpu_soft_reset(struct mpp_dev *mpp) +{ + u32 val; + + mpp_write(mpp, VDPU1_REG_SOFT_RESET, 1); + udelay(2); + val = mpp_read(mpp, VDPU1_REG_SOFT_RESET); + + return val; +} + static int vdpu_reset(struct mpp_dev *mpp) { struct vdpu_dev *dec = to_vdpu_dev(mpp); + u32 ret = 0; - if (dec->rst_a && dec->rst_h) { + /* soft reset first */ + ret = vdpu_soft_reset(mpp); + if (ret && dec->rst_a && dec->rst_h) { mpp_debug(DEBUG_RESET, "reset in\n"); /* Don't skip this or iommu won't work after reset */ - rockchip_pmu_idle_request(mpp->dev, true); + mpp_pmu_idle_request(mpp, true); mpp_safe_reset(dec->rst_a); mpp_safe_reset(dec->rst_h); udelay(5); mpp_safe_unreset(dec->rst_a); mpp_safe_unreset(dec->rst_h); - rockchip_pmu_idle_request(mpp->dev, false); + mpp_pmu_idle_request(mpp, false); mpp_debug(DEBUG_RESET, "reset out\n"); } @@ -774,12 +807,10 @@ .data = &vdpu_3368_data, }, #endif -#ifdef CONFIG_CPU_RK3328 { .compatible = "rockchip,avs-plus-decoder", .data = &avsd_plus_data, }, -#endif {}, }; @@ -864,12 +895,53 @@ dev_err(dev, "wait total running time out\n"); } +static int vdpu_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 vdpu_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 vdpu_pm_ops = { + .runtime_suspend = vdpu_runtime_suspend, + .runtime_resume = vdpu_runtime_resume, +}; + struct platform_driver rockchip_vdpu1_driver = { .probe = vdpu_probe, .remove = vdpu_remove, .shutdown = vdpu_shutdown, .driver = { .name = VDPU1_DRIVER_NAME, + .pm = &vdpu_pm_ops, .of_match_table = of_match_ptr(mpp_vdpu1_dt_match), }, }; -- Gitblit v1.6.2