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_rkvenc2.c | 86 +++++++++++++++++++++++++++++++++++++++---- 1 files changed, 78 insertions(+), 8 deletions(-) diff --git a/kernel/drivers/video/rockchip/mpp/mpp_rkvenc2.c b/kernel/drivers/video/rockchip/mpp/mpp_rkvenc2.c index 90cdc13..7d2d7ae 100644 --- a/kernel/drivers/video/rockchip/mpp/mpp_rkvenc2.c +++ b/kernel/drivers/video/rockchip/mpp/mpp_rkvenc2.c @@ -28,6 +28,8 @@ #include <linux/nospec.h> #include <linux/workqueue.h> #include <linux/dma-iommu.h> +#include <linux/mfd/syscon.h> +#include <linux/rockchip/cpu.h> #include <soc/rockchip/pm_domains.h> #include <soc/rockchip/rockchip_ipa.h> #include <soc/rockchip/rockchip_opp_select.h> @@ -41,6 +43,7 @@ #define RKVENC_SESSION_MAX_BUFFERS 40 #define RKVENC_MAX_CORE_NUM 4 +#define RKVENC_SCLR_DONE_STA BIT(2) #define to_rkvenc_info(info) \ container_of(info, struct rkvenc_hw_info, hw) @@ -187,6 +190,7 @@ dma_addr_t sram_iova; u32 sram_enabled; struct page *rcb_page; + struct regmap *grf; }; @@ -699,6 +703,7 @@ struct rkvenc_dev *enc = to_rkvenc_dev(mpp); struct rkvenc_task *task = to_rkvenc_task(mpp_task); struct rkvenc_hw_info *hw = enc->hw_info; + u32 timing_en = mpp->srv->timing_en; mpp_debug_enter(); @@ -735,11 +740,20 @@ } } + /* 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, enc->hw_info->enc_start_base, start_val); + + mpp_task_run_end(mpp_task, timing_en); mpp_debug_leave(); @@ -793,6 +807,7 @@ if (mpp_debug_unlikely(DEBUG_DUMP_ERR_REG)) mpp_task_dump_hw_reg(mpp, mpp_task); } + mpp_task_finish(mpp_task->session, mpp_task); mpp_debug_leave(); @@ -1031,6 +1046,10 @@ enc->procfs = NULL; return -EIO; } + + /* for common mpp_dev options */ + mpp_procfs_create_common(enc->procfs, mpp); + /* for debug */ mpp_procfs_create_u32("aclk", 0644, enc->procfs, &enc->aclk_info.debug_rate_hz); @@ -1063,7 +1082,7 @@ struct rkvenc_dev *enc = to_rkvenc_dev(mpp); int ret = 0; - mpp->grf_info = &mpp->srv->grf_infos[MPP_DRIVER_RKVENC]; + mpp->grf_info = &mpp->srv->grf_infos[MPP_DRIVER_RKVENC2]; /* Get clock info from dtsi */ ret = mpp_get_clk_info(mpp, &enc->aclk_info, "aclk_vcodec"); @@ -1097,23 +1116,41 @@ return 0; } -static int rkvenc_reset(struct mpp_dev *mpp) +static int rkvenc_soft_reset(struct mpp_dev *mpp) { struct rkvenc_dev *enc = to_rkvenc_dev(mpp); struct rkvenc_hw_info *hw = enc->hw_info; - - mpp_debug_enter(); + u32 rst_status = 0; + int ret = 0; /* safe reset */ mpp_write(mpp, hw->int_mask_base, 0x3FF); mpp_write(mpp, hw->enc_clr_base, 0x1); - udelay(5); + ret = readl_relaxed_poll_timeout(mpp->reg_base + hw->int_sta_base, + rst_status, + rst_status & RKVENC_SCLR_DONE_STA, + 0, 5); mpp_write(mpp, hw->int_clr_base, 0xffffffff); mpp_write(mpp, hw->int_sta_base, 0); + return ret; + +} + +static int rkvenc_reset(struct mpp_dev *mpp) +{ + struct rkvenc_dev *enc = to_rkvenc_dev(mpp); + int ret = 0; + + mpp_debug_enter(); + + /* safe reset first*/ + ret = rkvenc_soft_reset(mpp); + /* cru reset */ - if (enc->rst_a && enc->rst_h && enc->rst_core) { - rockchip_pmu_idle_request(mpp->dev, true); + if (ret && enc->rst_a && enc->rst_h && enc->rst_core) { + mpp_err("soft reset timeout, use cru reset\n"); + mpp_pmu_idle_request(mpp, true); mpp_safe_reset(enc->rst_a); mpp_safe_reset(enc->rst_h); mpp_safe_reset(enc->rst_core); @@ -1121,7 +1158,7 @@ mpp_safe_unreset(enc->rst_a); mpp_safe_unreset(enc->rst_h); mpp_safe_unreset(enc->rst_core); - rockchip_pmu_idle_request(mpp->dev, false); + mpp_pmu_idle_request(mpp, false); } mpp_debug_leave(); @@ -1338,6 +1375,7 @@ } mpp->session_max_buffers = RKVENC_SESSION_MAX_BUFFERS; enc->hw_info = to_rkvenc_info(mpp->var->hw_info); + rkvenc_procfs_init(mpp); mpp_dev_register_srv(mpp, mpp->srv); @@ -1416,12 +1454,44 @@ dev_info(dev, "shutdown success\n"); } +static int rkvenc_runtime_suspend(struct device *dev) +{ + struct mpp_dev *mpp = dev_get_drvdata(dev); + struct mpp_grf_info *info = mpp->grf_info; + + if (cpu_is_rk3528() && info && info->mem_offset) + regmap_write(info->grf, + info->mem_offset, + info->val_mem_off); + + return 0; +} + +static int rkvenc_runtime_resume(struct device *dev) +{ + struct mpp_dev *mpp = dev_get_drvdata(dev); + struct mpp_grf_info *info = mpp->grf_info; + + if (cpu_is_rk3528() && info && info->mem_offset) + regmap_write(info->grf, + info->mem_offset, + info->val_mem_on); + + return 0; +} + +static const struct dev_pm_ops rkvenc_pm_ops = { + .runtime_suspend = rkvenc_runtime_suspend, + .runtime_resume = rkvenc_runtime_resume, +}; + struct platform_driver rockchip_rkvenc2_driver = { .probe = rkvenc_probe, .remove = rkvenc_remove, .shutdown = rkvenc_shutdown, .driver = { .name = RKVENC_DRIVER_NAME, + .pm = &rkvenc_pm_ops, .of_match_table = of_match_ptr(mpp_rkvenc_dt_match), }, }; -- Gitblit v1.6.2