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_rkvdec.c | 154 ++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 120 insertions(+), 34 deletions(-) diff --git a/kernel/drivers/video/rockchip/mpp/mpp_rkvdec.c b/kernel/drivers/video/rockchip/mpp/mpp_rkvdec.c index 89ec8a9..4310a09 100644 --- a/kernel/drivers/video/rockchip/mpp/mpp_rkvdec.c +++ b/kernel/drivers/video/rockchip/mpp/mpp_rkvdec.c @@ -36,6 +36,7 @@ #include "mpp_debug.h" #include "mpp_common.h" #include "mpp_iommu.h" +#include <soc/rockchip/rockchip_iommu.h> #include "hack/mpp_hack_px30.h" @@ -593,6 +594,7 @@ mem_region = mpp_task_attach_fd(&task->mpp_task, scaling_fd); if (IS_ERR(mem_region)) { + mpp_err("scaling list fd %d attach failed\n", scaling_fd); ret = PTR_ERR(mem_region); goto done; } @@ -727,8 +729,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); return -EFAULT; + } iova = mem_region->iova; task->reg[idx] = iova + offset; @@ -887,6 +892,7 @@ int i; u32 reg_en; struct rkvdec_task *task = NULL; + u32 timing_en = mpp->srv->timing_en; mpp_debug_enter(); @@ -918,10 +924,13 @@ } /* 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, RKVDEC_REG_INT_EN, task->reg[reg_en] | RKVDEC_DEC_START); + + mpp_task_run_end(mpp_task, timing_en); } break; default: break; @@ -969,6 +978,13 @@ if (task->link_mode == RKVDEC_MODE_ONEFRAME) mpp_iommu_flush_tlb(mpp->iommu_info); + return rkvdec_run(mpp, mpp_task); +} + +static int rkvdec_px30_run(struct mpp_dev *mpp, + struct mpp_task *mpp_task) +{ + mpp_iommu_flush_tlb(mpp->iommu_info); return rkvdec_run(mpp, mpp_task); } @@ -1265,6 +1281,13 @@ return px30_workaround_combo_init(mpp); } +static int rkvdec_3036_init(struct mpp_dev *mpp) +{ + rkvdec_init(mpp); + set_bit(mpp->var->device_type, &mpp->queue->dev_active_flags); + return 0; +} + static int rkvdec_3328_iommu_hdl(struct iommu_domain *iommu, struct device *iommu_dev, unsigned long iova, @@ -1315,7 +1338,7 @@ struct rkvdec_dev *dec = to_rkvdec_dev(mpp); mutex_init(&dec->set_clk_lock); - dec->parent_devfreq = devfreq_get_devfreq_by_phandle(mpp->dev, 0); + dec->parent_devfreq = devfreq_get_devfreq_by_phandle(mpp->dev, "rkvdec_devfreq", 0); if (IS_ERR_OR_NULL(dec->parent_devfreq)) { if (PTR_ERR(dec->parent_devfreq) == -EPROBE_DEFER) { dev_warn(mpp->dev, "parent devfreq is not ready, retry\n"); @@ -1406,7 +1429,7 @@ goto done; } dec->aux_iova = -1; - mpp->iommu_info->hdl = rkvdec_3328_iommu_hdl; + mpp->fault_handler = rkvdec_3328_iommu_hdl; ret = rkvdec_devfreq_init(mpp); done: @@ -1514,6 +1537,52 @@ dec->grf_changed = mpp_grf_is_changed(mpp->grf_info); mpp_set_grf(mpp->grf_info); + + return 0; +} + +static int rkvdec_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; } @@ -1658,18 +1727,18 @@ static int rkvdec_sip_reset(struct mpp_dev *mpp) { - struct rkvdec_dev *dec = to_rkvdec_dev(mpp); + if (IS_REACHABLE(CONFIG_ROCKCHIP_SIP)) { + /* The reset flow in arm trustzone firmware */ + struct rkvdec_dev *dec = to_rkvdec_dev(mpp); -/* The reset flow in arm trustzone firmware */ -#if IS_ENABLED(CONFIG_ROCKCHIP_SIP) - mutex_lock(&dec->sip_reset_lock); - sip_smc_vpu_reset(0, 0, 0); - mutex_unlock(&dec->sip_reset_lock); + mutex_lock(&dec->sip_reset_lock); + sip_smc_vpu_reset(0, 0, 0); + mutex_unlock(&dec->sip_reset_lock); - return 0; -#else - return rkvdec_reset(mpp); -#endif + return 0; + } else { + return rkvdec_reset(mpp); + } } static struct mpp_hw_ops rkvdec_v1_hw_ops = { @@ -1691,6 +1760,17 @@ .reduce_freq = rkvdec_reduce_freq, .reset = rkvdec_reset, .set_grf = px30_workaround_combo_switch_grf, +}; + +static struct mpp_hw_ops rkvdec_3036_hw_ops = { + .init = rkvdec_3036_init, + .clk_on = rkvdec_clk_on, + .clk_off = rkvdec_clk_off, + .get_freq = rkvdec_get_freq, + .set_freq = rkvdec_set_freq, + .reduce_freq = rkvdec_reduce_freq, + .reset = rkvdec_reset, + .set_grf = rkvdec_3036_set_grf, }; static struct mpp_hw_ops rkvdec_3399_hw_ops = { @@ -1717,6 +1797,16 @@ static struct mpp_dev_ops rkvdec_v1_dev_ops = { .alloc_task = rkvdec_alloc_task, .run = rkvdec_run, + .irq = rkvdec_irq, + .isr = rkvdec_isr, + .finish = rkvdec_finish, + .result = rkvdec_result, + .free_task = rkvdec_free_task, +}; + +static struct mpp_dev_ops rkvdec_px30_dev_ops = { + .alloc_task = rkvdec_alloc_task, + .run = rkvdec_px30_run, .irq = rkvdec_irq, .isr = rkvdec_isr, .finish = rkvdec_finish, @@ -1773,6 +1863,14 @@ .dev_ops = &rkvdec_v1_dev_ops, }; +static const struct mpp_dev_var rk_hevcdec_3036_data = { + .device_type = MPP_DEVICE_HEVC_DEC, + .hw_info = &rk_hevcdec_hw_info, + .trans_info = rk_hevcdec_trans, + .hw_ops = &rkvdec_3036_hw_ops, + .dev_ops = &rkvdec_v1_dev_ops, +}; + static const struct mpp_dev_var rk_hevcdec_3368_data = { .device_type = MPP_DEVICE_HEVC_DEC, .hw_info = &rk_hevcdec_hw_info, @@ -1786,7 +1884,7 @@ .hw_info = &rk_hevcdec_hw_info, .trans_info = rk_hevcdec_trans, .hw_ops = &rkvdec_px30_hw_ops, - .dev_ops = &rkvdec_v1_dev_ops, + .dev_ops = &rkvdec_px30_dev_ops, }; static const struct mpp_dev_var rkvdec_v1_data = { @@ -1830,6 +1928,12 @@ { .compatible = "rockchip,hevc-decoder-px30", .data = &rk_hevcdec_px30_data, + }, +#endif +#ifdef CONFIG_CPU_RK3036 + { + .compatible = "rockchip,hevc-decoder-rk3036", + .data = &rk_hevcdec_3036_data, }, #endif #ifdef CONFIG_CPU_RK3368 @@ -1877,7 +1981,7 @@ return -ENOMEM; mpp = &dec->mpp; - platform_set_drvdata(pdev, dec); + platform_set_drvdata(pdev, mpp); if (pdev->dev.of_node) { match = of_match_node(mpp_rkvdec_dt_match, @@ -1923,28 +2027,10 @@ return 0; } -static void rkvdec_shutdown(struct platform_device *pdev) -{ - int ret; - int val; - struct device *dev = &pdev->dev; - struct rkvdec_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"); -} - struct platform_driver rockchip_rkvdec_driver = { .probe = rkvdec_probe, .remove = rkvdec_remove, - .shutdown = rkvdec_shutdown, + .shutdown = mpp_dev_shutdown, .driver = { .name = RKVDEC_DRIVER_NAME, .of_match_table = of_match_ptr(mpp_rkvdec_dt_match), -- Gitblit v1.6.2