From 9370bb92b2d16684ee45cf24e879c93c509162da Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Thu, 19 Dec 2024 01:47:39 +0000 Subject: [PATCH] add wifi6 8852be driver --- kernel/drivers/video/rockchip/mpp/mpp_vdpu1.c | 166 +++++++++++++++++++++++++++++++----------------------- 1 files changed, 95 insertions(+), 71 deletions(-) diff --git a/kernel/drivers/video/rockchip/mpp/mpp_vdpu1.c b/kernel/drivers/video/rockchip/mpp/mpp_vdpu1.c index 537c6a2..6ddf5da 100644 --- a/kernel/drivers/video/rockchip/mpp/mpp_vdpu1.c +++ b/kernel/drivers/video/rockchip/mpp/mpp_vdpu1.c @@ -20,13 +20,12 @@ #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" #include "mpp_common.h" #include "mpp_iommu.h" +#include <soc/rockchip/rockchip_iommu.h> #define VDPU1_DRIVER_NAME "mpp_vdpu1" @@ -268,8 +267,11 @@ offset = task->reg[idx] >> 10 << 4; } mem_region = mpp_task_attach_fd(&task->mpp_task, fd); - if (IS_ERR(mem_region)) + if (IS_ERR(mem_region)) { + mpp_err("reg[%03d]: %08x fd %d attach failed\n", + idx, task->reg[idx], fd); goto fail; + } iova = mem_region->iova; mpp_debug(DEBUG_IOMMU, "DMV[%3d]: %3d => %pad + offset %10d\n", @@ -569,6 +571,13 @@ return 0; } +static int vdpu_3036_init(struct mpp_dev *mpp) +{ + vdpu_init(mpp); + set_bit(mpp->var->device_type, &mpp->queue->dev_active_flags); + return 0; +} + static int vdpu_clk_on(struct mpp_dev *mpp) { struct vdpu_dev *dec = to_vdpu_dev(mpp); @@ -685,12 +694,13 @@ static int vdpu_soft_reset(struct mpp_dev *mpp) { u32 val; + u32 ret; mpp_write(mpp, VDPU1_REG_SOFT_RESET, 1); - udelay(2); - val = mpp_read(mpp, VDPU1_REG_SOFT_RESET); + ret = readl_relaxed_poll_timeout(mpp->reg_base + VDPU1_REG_SOFT_RESET, + val, !val, 0, 5); - return val; + return ret; } static int vdpu_reset(struct mpp_dev *mpp) @@ -701,6 +711,7 @@ /* soft reset first */ ret = vdpu_soft_reset(mpp); if (ret && dec->rst_a && dec->rst_h) { + mpp_err("soft reset failed, use cru reset!\n"); mpp_debug(DEBUG_RESET, "reset in\n"); /* Don't skip this or iommu won't work after reset */ @@ -719,6 +730,51 @@ return 0; } +static int vdpu_3036_set_grf(struct mpp_dev *mpp) +{ + int grf_changed; + struct mpp_dev *loop = NULL, *n; + struct mpp_taskqueue *queue = mpp->queue; + bool pd_is_on; + + grf_changed = mpp_grf_is_changed(mpp->grf_info); + if (grf_changed) { + + /* + * in this case, devices share the queue also share the same pd&clk, + * so use mpp->dev's pd to control all the process is okay + */ + pd_is_on = rockchip_pmu_pd_is_on(mpp->dev); + if (!pd_is_on) + rockchip_pmu_pd_on(mpp->dev); + mpp->hw_ops->clk_on(mpp); + + list_for_each_entry_safe(loop, n, &queue->dev_list, queue_link) { + if (test_bit(loop->var->device_type, &queue->dev_active_flags)) { + mpp_set_grf(loop->grf_info); + if (loop->hw_ops->clk_on) + loop->hw_ops->clk_on(loop); + if (loop->hw_ops->reset) + loop->hw_ops->reset(loop); + rockchip_iommu_disable(loop->dev); + if (loop->hw_ops->clk_off) + loop->hw_ops->clk_off(loop); + clear_bit(loop->var->device_type, &queue->dev_active_flags); + } + } + + mpp_set_grf(mpp->grf_info); + rockchip_iommu_enable(mpp->dev); + set_bit(mpp->var->device_type, &queue->dev_active_flags); + + mpp->hw_ops->clk_off(mpp); + if (!pd_is_on) + rockchip_pmu_pd_off(mpp->dev); + } + + return 0; +} + static struct mpp_hw_ops vdpu_v1_hw_ops = { .init = vdpu_init, .clk_on = vdpu_clk_on, @@ -726,6 +782,17 @@ .set_freq = vdpu_set_freq, .reduce_freq = vdpu_reduce_freq, .reset = vdpu_reset, + .set_grf = vdpu_3036_set_grf, +}; + +static struct mpp_hw_ops vdpu_3036_hw_ops = { + .init = vdpu_3036_init, + .clk_on = vdpu_clk_on, + .clk_off = vdpu_clk_off, + .set_freq = vdpu_set_freq, + .reduce_freq = vdpu_reduce_freq, + .reset = vdpu_reset, + .set_grf = vdpu_3036_set_grf, }; static struct mpp_hw_ops vdpu_3288_hw_ops = { @@ -766,6 +833,14 @@ .dev_ops = &vdpu_v1_dev_ops, }; +static const struct mpp_dev_var vdpu_3036_data = { + .device_type = MPP_DEVICE_VDPU1, + .hw_info = &vdpu_v1_hw_info, + .trans_info = vdpu_v1_trans, + .hw_ops = &vdpu_3036_hw_ops, + .dev_ops = &vdpu_v1_dev_ops, +}; + static const struct mpp_dev_var vdpu_3288_data = { .device_type = MPP_DEVICE_VDPU1, .hw_info = &vdpu_v1_hw_info, @@ -801,6 +876,12 @@ .data = &vdpu_3288_data, }, #endif +#ifdef CONFIG_CPU_RK3036 + { + .compatible = "rockchip,vpu-decoder-rk3036", + .data = &vdpu_3036_data, + }, +#endif #ifdef CONFIG_CPU_RK3368 { .compatible = "rockchip,vpu-decoder-rk3368", @@ -826,13 +907,15 @@ dec = devm_kzalloc(dev, sizeof(struct vdpu_dev), GFP_KERNEL); if (!dec) return -ENOMEM; - platform_set_drvdata(pdev, dec); - mpp = &dec->mpp; + platform_set_drvdata(pdev, mpp); + if (pdev->dev.of_node) { match = of_match_node(mpp_vdpu1_dt_match, pdev->dev.of_node); if (match) mpp->var = (struct mpp_dev_var *)match->data; + + mpp->core_id = of_alias_get_id(pdev->dev.of_node, "vdpu"); } ret = mpp_dev_probe(mpp, pdev); @@ -868,80 +951,21 @@ static int vdpu_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct vdpu_dev *dec = platform_get_drvdata(pdev); + struct mpp_dev *mpp = dev_get_drvdata(dev); dev_info(dev, "remove device\n"); - mpp_dev_remove(&dec->mpp); - vdpu_procfs_remove(&dec->mpp); + mpp_dev_remove(mpp); + vdpu_procfs_remove(mpp); return 0; } - -static void vdpu_shutdown(struct platform_device *pdev) -{ - int ret; - int val; - struct device *dev = &pdev->dev; - struct vdpu_dev *dec = platform_get_drvdata(pdev); - struct mpp_dev *mpp = &dec->mpp; - - dev_info(dev, "shutdown device\n"); - - atomic_inc(&mpp->srv->shutdown_request); - ret = readx_poll_timeout(atomic_read, - &mpp->task_count, - val, val == 0, 20000, 200000); - if (ret == -ETIMEDOUT) - 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, + .shutdown = mpp_dev_shutdown, .driver = { .name = VDPU1_DRIVER_NAME, - .pm = &vdpu_pm_ops, .of_match_table = of_match_ptr(mpp_vdpu1_dt_match), }, }; -- Gitblit v1.6.2