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_iep2.c | 95 ++++++++++++++++++++++++++++------------------- 1 files changed, 56 insertions(+), 39 deletions(-) diff --git a/kernel/drivers/video/rockchip/mpp/mpp_iep2.c b/kernel/drivers/video/rockchip/mpp/mpp_iep2.c index 92ec40e..8d19269 100644 --- a/kernel/drivers/video/rockchip/mpp/mpp_iep2.c +++ b/kernel/drivers/video/rockchip/mpp/mpp_iep2.c @@ -266,8 +266,8 @@ mem_region = mpp_task_attach_fd(&task->mpp_task, usr_fd); if (IS_ERR(mem_region)) { - mpp_debug(DEBUG_IOMMU, "reg[%3d]: %08x failed\n", - iep2_addr_rnum[i], paddr[i]); + mpp_err("reg[%03d]: %08x failed\n", + iep2_addr_rnum[i], paddr[i]); return PTR_ERR(mem_region); } @@ -389,12 +389,13 @@ | IEP2_REG_DIL_OSD_EN | IEP2_REG_DIL_PD_EN | IEP2_REG_DIL_FF_EN - | IEP2_REG_DIL_MD_PRE_EN | IEP2_REG_DIL_FIELD_ORDER(cfg->dil_field_order) | IEP2_REG_DIL_OUT_MODE(cfg->dil_out_mode) | IEP2_REG_DIL_MODE(cfg->dil_mode); if (cfg->roi_en) reg |= IEP2_REG_DIL_ROI_EN; + if (cfg->md_lambda < 8) + reg |= IEP2_REG_DIL_MD_PRE_EN; mpp_write_relaxed(mpp, IEP2_REG_DIL_CONFIG0, reg); if (cfg->dil_mode != ROCKCHIP_IEP2_DIL_MODE_PD) { @@ -437,6 +438,9 @@ mpp_write_relaxed(mpp, IEP2_REG_SRC_ADDR_NXTUV, bot->cbcr); mpp_write_relaxed(mpp, IEP2_REG_SRC_ADDR_NXTV, bot->cr); } + + reg = IEP2_REG_TIMEOUT_CFG_EN | 0x3ffffff; + mpp_write_relaxed(mpp, IEP2_REG_TIMEOUT_CFG, reg); mpp_write_relaxed(mpp, IEP2_REG_SRC_ADDR_PREY, cfg->src[2].y); mpp_write_relaxed(mpp, IEP2_REG_SRC_ADDR_PREUV, cfg->src[2].cbcr); @@ -580,6 +584,7 @@ struct mpp_task *mpp_task) { struct iep_task *task = NULL; + u32 timing_en = mpp->srv->timing_en; mpp_debug_enter(); @@ -598,12 +603,20 @@ mpp_write_relaxed(mpp, IEP2_REG_INT_EN, IEP2_REG_FRM_DONE_EN | IEP2_REG_OSD_MAX_EN - | IEP2_REG_BUS_ERROR_EN); + | IEP2_REG_BUS_ERROR_EN + | IEP2_REG_TIMEOUT_EN); + + /* flush tlb before starting hardware */ + mpp_iommu_flush_tlb(mpp->iommu_info); + + mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY); /* Last, flush the registers */ wmb(); /* start iep2 */ mpp_write(mpp, IEP2_REG_FRM_START, 1); + + mpp_task_run_end(mpp_task, timing_en); mpp_debug_leave(); @@ -612,6 +625,10 @@ static int iep2_irq(struct mpp_dev *mpp) { + u32 work_mode = mpp_read(mpp, IEP2_REG_WORK_MODE); + + if (work_mode && !(work_mode & IEP2_REG_IEP2_MODE)) + return IRQ_NONE; mpp->irq_status = mpp_read(mpp, IEP2_REG_INT_STS); mpp_write(mpp, IEP2_REG_INT_CLR, 0xffffffff); @@ -640,7 +657,8 @@ mpp_debug(DEBUG_IRQ_STATUS, "irq_status: %08x\n", task->irq_status); - if (IEP2_REG_RO_BUS_ERROR_STS(task->irq_status)) + if (IEP2_REG_RO_BUS_ERROR_STS(task->irq_status) || + IEP2_REG_RO_TIMEOUT_STS(task->irq_status)) atomic_inc(&mpp->reset_request); mpp_task_finish(mpp_task->session, mpp_task); @@ -769,6 +787,10 @@ iep->procfs = NULL; return -EIO; } + + /* for common mpp_dev options */ + mpp_procfs_create_common(iep->procfs, mpp); + mpp_procfs_create_u32("aclk", 0644, iep->procfs, &iep->aclk_info.debug_rate_hz); mpp_procfs_create_u32("session_buffers", 0644, @@ -870,17 +892,29 @@ { struct iep2_dev *iep = to_iep2_dev(mpp); - if (iep->rst_a && iep->rst_h && iep->rst_s) { - /* Don't skip this or iommu won't work after reset */ - rockchip_pmu_idle_request(mpp->dev, true); - mpp_safe_reset(iep->rst_a); - mpp_safe_reset(iep->rst_h); - mpp_safe_reset(iep->rst_s); - udelay(5); - mpp_safe_unreset(iep->rst_a); - mpp_safe_unreset(iep->rst_h); - mpp_safe_unreset(iep->rst_s); - rockchip_pmu_idle_request(mpp->dev, false); + int ret = 0; + u32 rst_status = 0; + + /* soft rest first */ + mpp_write(mpp, IEP2_REG_IEP_CONFIG0, IEP2_REG_ACLK_SRESET_P); + ret = readl_relaxed_poll_timeout(mpp->reg_base + IEP2_REG_STATUS, + rst_status, + rst_status & IEP2_REG_ARST_FINISH_DONE, + 0, 5); + if (ret) { + mpp_err("soft reset timeout, use cru reset\n"); + if (iep->rst_a && iep->rst_h && iep->rst_s) { + /* Don't skip this or iommu won't work after reset */ + mpp_pmu_idle_request(mpp, true); + mpp_safe_reset(iep->rst_a); + mpp_safe_reset(iep->rst_h); + mpp_safe_reset(iep->rst_s); + udelay(5); + mpp_safe_unreset(iep->rst_a); + mpp_safe_unreset(iep->rst_h); + mpp_safe_unreset(iep->rst_s); + mpp_pmu_idle_request(mpp, false); + } } return 0; @@ -943,7 +977,7 @@ return -ENOMEM; mpp = &iep->mpp; - platform_set_drvdata(pdev, iep); + platform_set_drvdata(pdev, mpp); if (pdev->dev.of_node) { match = of_match_node(mpp_iep2_match, pdev->dev.of_node); @@ -979,39 +1013,22 @@ static int iep2_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct iep2_dev *iep = platform_get_drvdata(pdev); + struct mpp_dev *mpp = dev_get_drvdata(dev); + struct iep2_dev *iep = to_iep2_dev(mpp); dma_free_coherent(dev, iep->roi.size, iep->roi.vaddr, iep->roi.iova); dev_info(dev, "remove device\n"); - mpp_dev_remove(&iep->mpp); - iep2_procfs_remove(&iep->mpp); + mpp_dev_remove(mpp); + iep2_procfs_remove(mpp); return 0; -} - -static void iep2_shutdown(struct platform_device *pdev) -{ - int ret; - int val; - struct device *dev = &pdev->dev; - struct iep2_dev *iep = platform_get_drvdata(pdev); - struct mpp_dev *mpp = &iep->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_iep2_driver = { .probe = iep2_probe, .remove = iep2_remove, - .shutdown = iep2_shutdown, + .shutdown = mpp_dev_shutdown, .driver = { .name = IEP2_DRIVER_NAME, .of_match_table = of_match_ptr(mpp_iep2_match), -- Gitblit v1.6.2