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_vdpu2.c | 96 +++++++++++++++++++++++++++++++++-------------- 1 files changed, 67 insertions(+), 29 deletions(-) diff --git a/kernel/drivers/video/rockchip/mpp/mpp_vdpu2.c b/kernel/drivers/video/rockchip/mpp/mpp_vdpu2.c index f697033..d5a6a30 100644 --- a/kernel/drivers/video/rockchip/mpp/mpp_vdpu2.c +++ b/kernel/drivers/video/rockchip/mpp/mpp_vdpu2.c @@ -69,6 +69,9 @@ #define VDPU2_DEC_CLOCK_GATE_EN BIT(4) #define VDPU2_DEC_START BIT(0) +#define VDPU2_REG_SOFT_RESET 0x0e8 +#define VDPU2_REG_SOFT_RESET_INDEX (58) + #define VDPU2_REG_DIR_MV_BASE 0x0f8 #define VDPU2_REG_DIR_MV_BASE_INDEX (62) @@ -224,8 +227,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[%3d]: %08x fd %d attach failed\n", + idx, task->reg[idx], fd); return -EFAULT; + } iova = mem_region->iova; mpp_debug(DEBUG_IOMMU, "DMV[%3d]: %3d => %pad + offset %10d\n", @@ -340,6 +346,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(); @@ -354,16 +361,32 @@ 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 registers */ wmb(); mpp_write(mpp, VDPU2_REG_DEC_EN, task->reg[reg_en] | VDPU2_DEC_START); + mpp_task_run_end(mpp_task, timing_en); + mpp_debug_leave(); return 0; +} + +static int vdpu_px30_run(struct mpp_dev *mpp, + struct mpp_task *mpp_task) +{ + mpp_iommu_flush_tlb(mpp->iommu_info); + return vdpu_run(mpp, mpp_task); } static int vdpu_finish(struct mpp_dev *mpp, @@ -456,6 +479,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, @@ -596,21 +623,39 @@ return IRQ_HANDLED; } +static int vdpu_soft_reset(struct mpp_dev *mpp) +{ + u32 val; + u32 ret; + + mpp_write(mpp, VDPU2_REG_SOFT_RESET, 1); + ret = readl_relaxed_poll_timeout(mpp->reg_base + VDPU2_REG_SOFT_RESET, + val, !val, 0, 5); + return ret; +} + static int vdpu_reset(struct mpp_dev *mpp) { struct vdpu_dev *dec = to_vdpu_dev(mpp); + u32 ret = 0; mpp_write(mpp, VDPU2_REG_DEC_EN, 0); mpp_write(mpp, VDPU2_REG_DEC_INT, 0); - if (dec->rst_a && dec->rst_h) { + + /* soft reset first */ + ret = vdpu_soft_reset(mpp); + if (ret && dec->rst_a && dec->rst_h) { /* Don't skip this or iommu won't work after reset */ - rockchip_pmu_idle_request(mpp->dev, true); + mpp_err("soft reset failed, use cru reset!\n"); + mpp_debug(DEBUG_RESET, "reset in\n"); + 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"); } return 0; @@ -645,6 +690,16 @@ .free_task = vdpu_free_task, }; +static struct mpp_dev_ops vdpu_px30_dev_ops = { + .alloc_task = vdpu_alloc_task, + .run = vdpu_px30_run, + .irq = vdpu_irq, + .isr = vdpu_isr, + .finish = vdpu_finish, + .result = vdpu_result, + .free_task = vdpu_free_task, +}; + static const struct mpp_dev_var vdpu_v2_data = { .device_type = MPP_DEVICE_VDPU2, .hw_info = &vdpu_v2_hw_info, @@ -658,7 +713,7 @@ .hw_info = &vdpu_v2_hw_info, .trans_info = vdpu_v2_trans, .hw_ops = &vdpu_px30_hw_ops, - .dev_ops = &vdpu_v2_dev_ops, + .dev_ops = &vdpu_px30_dev_ops, }; static const struct of_device_id mpp_vdpu2_dt_match[] = { @@ -687,15 +742,16 @@ 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_vdpu2_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); @@ -731,37 +787,19 @@ 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"); } struct platform_driver rockchip_vdpu2_driver = { .probe = vdpu_probe, .remove = vdpu_remove, - .shutdown = vdpu_shutdown, + .shutdown = mpp_dev_shutdown, .driver = { .name = VDPU2_DRIVER_NAME, .of_match_table = of_match_ptr(mpp_vdpu2_dt_match), -- Gitblit v1.6.2