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_vdpp.c | 70 +++++++++++++++++++++++++++++++++-- 1 files changed, 66 insertions(+), 4 deletions(-) diff --git a/kernel/drivers/video/rockchip/mpp/mpp_vdpp.c b/kernel/drivers/video/rockchip/mpp/mpp_vdpp.c index 9369615..43a7cb0 100644 --- a/kernel/drivers/video/rockchip/mpp/mpp_vdpp.c +++ b/kernel/drivers/video/rockchip/mpp/mpp_vdpp.c @@ -18,6 +18,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" @@ -27,6 +29,8 @@ #define VDPP_DRIVER_NAME "mpp_vdpp" #define VDPP_SESSION_MAX_BUFFERS 15 +#define VDPP_REG_WORK_MODE 0x0008 +#define VDPP_REG_VDPP_MODE BIT(1) #define to_vdpp_info(info) \ container_of(info, struct vdpp_hw_info, hw) @@ -87,6 +91,7 @@ struct reset_control *rst_s; /* for zme */ void __iomem *zme_base; + struct regmap *grf; }; static struct vdpp_hw_info vdpp_v1_hw_info = { @@ -332,6 +337,9 @@ } } + /* flush tlb before starting hardware */ + mpp_iommu_flush_tlb(mpp->iommu_info); + /* init current task */ mpp->cur_task = mpp_task; /* Flush the register before the start the device */ @@ -474,6 +482,8 @@ int ret; struct vdpp_dev *vdpp = to_vdpp_dev(mpp); + mpp->grf_info = &mpp->srv->grf_infos[MPP_DRIVER_VDPP]; + /* Get clock info from dtsi */ ret = mpp_get_clk_info(mpp, &vdpp->aclk_info, "aclk"); if (ret) @@ -546,12 +556,18 @@ { struct vdpp_dev *vdpp = to_vdpp_dev(mpp); struct vdpp_hw_info *hw_info = vdpp->hw_info; + u32 work_mode = mpp_read(mpp, VDPP_REG_WORK_MODE); + if (!(work_mode & VDPP_REG_VDPP_MODE)) + return IRQ_NONE; mpp->irq_status = mpp_read(mpp, hw_info->int_sta_base); if (!(mpp->irq_status & hw_info->int_mask)) return IRQ_NONE; mpp_write(mpp, hw_info->int_en_base, 0); mpp_write(mpp, hw_info->int_clr_base, mpp->irq_status); + + /* ensure hardware is being off status */ + mpp_write(mpp, hw_info->start_base, 0); return IRQ_WAKE_THREAD; } @@ -590,7 +606,7 @@ 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(vdpp->rst_a); mpp_safe_reset(vdpp->rst_h); mpp_safe_reset(vdpp->rst_s); @@ -598,7 +614,7 @@ mpp_safe_unreset(vdpp->rst_a); mpp_safe_unreset(vdpp->rst_h); mpp_safe_unreset(vdpp->rst_s); - rockchip_pmu_idle_request(mpp->dev, false); + mpp_pmu_idle_request(mpp, false); mpp_debug(DEBUG_RESET, "reset out\n"); } @@ -617,14 +633,18 @@ mpp_write(mpp, hw_info->cfg_base, hw_info->bit_rst_en); ret = readl_relaxed_poll_timeout(mpp->reg_base + hw_info->rst_sta_base, rst_status, - !(rst_status & hw_info->bit_rst_done), - 0, 2); + rst_status & hw_info->bit_rst_done, + 0, 5); if (ret) { mpp_err("soft reset timeout, use cru reset\n"); return _vdpp_reset(mpp, vdpp); } mpp_write(mpp, hw_info->rst_sta_base, 0); + + /* ensure hardware is being off status */ + mpp_write(mpp, hw_info->start_base, 0); + return 0; } @@ -710,6 +730,7 @@ dev_err(dev, "register interrupter runtime failed\n"); return -EINVAL; } + mpp->session_max_buffers = VDPP_SESSION_MAX_BUFFERS; vdpp->hw_info = to_vdpp_info(mpp->var->hw_info); vdpp_procfs_init(mpp); @@ -751,12 +772,53 @@ dev_err(dev, "wait total running time out\n"); } +static int vdpp_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 vdpp_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 vdpp_pm_ops = { + .runtime_suspend = vdpp_runtime_suspend, + .runtime_resume = vdpp_runtime_resume, +}; + struct platform_driver rockchip_vdpp_driver = { .probe = vdpp_probe, .remove = vdpp_remove, .shutdown = vdpp_shutdown, .driver = { .name = VDPP_DRIVER_NAME, + .pm = &vdpp_pm_ops, .of_match_table = of_match_ptr(mpp_vdpp_dt_match), }, }; -- Gitblit v1.6.2