diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index c880fa271c02..714cb2f91a4d 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -1138,21 +1138,21 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ rv1106g-evb1-mcu-display-v20.dtb \ rv1106g-evb1-rgb-display-v11.dtb \ rv1106g-evb1-v10.dtb \ + rv1106g-evb1-v10-dual-cam.dtb \ + rv1106g-evb1-v10-facial-gate.dtb \ + rv1106g-evb1-v10-spi-nand.dtb \ + rv1106g-evb1-v10-spi-nor.dtb \ rv1106g-evb1-v11.dtb \ rv1106g-evb1-v11-4k.dtb \ rv1106g-evb1-v11-cvr.dtb \ rv1106g-evb1-v11-cvr-dual-cam.dtb \ - rv1106g-evb1-v11-spi-nand-cvr.dtb \ + rv1106g-evb1-v11-cvr-ext-dual-cam.dtb \ + rv1106g-evb1-v11-dual-cam.dtb \ + rv1106g-evb1-v11-facial-gate.dtb \ + rv1106g-evb1-v11-nofastae-spi-nand.dtb \ rv1106g-evb1-v11-sii902x-bt11202hdmi.dtb \ rv1106g-evb1-v11-sii902x-rgb2hdmi.dtb \ - rv1106g-evb1-v10-dual-cam.dtb \ - rv1106g-evb1-v11-dual-cam.dtb \ - rv1106g-evb1-v10-facial-gate.dtb \ - rv1106g-evb1-v11-facial-gate.dtb \ - rv1106g-evb1-v10-spi-nand.dtb \ - rv1106g-evb1-v10-spi-nor.dtb \ - rv1106g-evb1-v11-nofastae-spi-nand.dtb \ - rv1106g-evb1-v11-cvr-ext-dual-cam.dtb \ + rv1106g-evb1-v11-spi-nand-cvr.dtb \ rv1106g-evb2-v10.dtb \ rv1106g-evb2-v10-dual-camera.dtb \ rv1106g-evb2-v11-emmc.dtb \ diff --git a/arch/arm64/configs/rockchip_linux_defconfig b/arch/arm64/configs/rockchip_linux_defconfig index 9dbd820726d1..67f36e8b9884 100644 --- a/arch/arm64/configs/rockchip_linux_defconfig +++ b/arch/arm64/configs/rockchip_linux_defconfig @@ -25,6 +25,7 @@ CONFIG_BLK_DEV_INITRD=y CONFIG_EMBEDDED=y CONFIG_PROFILING=y CONFIG_ARCH_ROCKCHIP=y +# CONFIG_AMPERE_ERRATUM_AC03_CPU_38 is not set # CONFIG_ARM64_ERRATUM_826319 is not set # CONFIG_ARM64_ERRATUM_827319 is not set # CONFIG_ARM64_ERRATUM_824069 is not set @@ -32,6 +33,7 @@ CONFIG_ARCH_ROCKCHIP=y # CONFIG_ARM64_ERRATUM_832075 is not set # CONFIG_ARM64_ERRATUM_1418040 is not set # CONFIG_ARM64_ERRATUM_1165522 is not set +# CONFIG_ARM64_ERRATUM_2441007 is not set # CONFIG_ARM64_ERRATUM_1286807 is not set # CONFIG_ARM64_ERRATUM_1463225 is not set # CONFIG_ARM64_ERRATUM_1542419 is not set @@ -42,6 +44,7 @@ CONFIG_ARCH_ROCKCHIP=y # CONFIG_ARM64_ERRATUM_2054223 is not set # CONFIG_ARM64_ERRATUM_2067961 is not set # CONFIG_ARM64_ERRATUM_2441009 is not set +# CONFIG_ARM64_ERRATUM_2966298 is not set # CONFIG_CAVIUM_ERRATUM_22375 is not set # CONFIG_CAVIUM_ERRATUM_23154 is not set # CONFIG_CAVIUM_ERRATUM_27456 is not set @@ -57,7 +60,6 @@ CONFIG_ARCH_ROCKCHIP=y # CONFIG_SOCIONEXT_SYNQUACER_PREITS is not set CONFIG_SCHED_MC=y CONFIG_NR_CPUS=8 -CONFIG_HZ_300=y CONFIG_COMPAT=y CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c index afdcd5ad6fd4..f14c47ddcdff 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c @@ -1582,12 +1582,19 @@ static int dw_mipi_dsi2_host_attach(struct mipi_dsi_host *host, dsi2->format = device->format; dsi2->mode_flags = device->mode_flags; - return 0; + return component_add(dsi2->dev, &dw_mipi_dsi2_ops); } static int dw_mipi_dsi2_host_detach(struct mipi_dsi_host *host, struct mipi_dsi_device *device) { + struct dw_mipi_dsi2 *dsi2 = host_to_dsi2(host); + + if (dsi2->master) + return 0; + + component_del(dsi2->dev, &dw_mipi_dsi2_ops); + return 0; } @@ -1828,7 +1835,7 @@ static int dw_mipi_dsi2_probe(struct platform_device *pdev) return ret; } - return component_add(&pdev->dev, &dw_mipi_dsi2_ops); + return 0; } static int dw_mipi_dsi2_remove(struct platform_device *pdev) diff --git a/drivers/mfd/display-serdes/serdes-core.c b/drivers/mfd/display-serdes/serdes-core.c index ecf890cdda72..db6468788fe8 100644 --- a/drivers/mfd/display-serdes/serdes-core.c +++ b/drivers/mfd/display-serdes/serdes-core.c @@ -40,6 +40,10 @@ static const struct mfd_cell serdes_max96745_devs[] = { .name = "serdes-bridge", .of_compatible = "maxim,max96745-bridge", }, + { + .name = "serdes-bridge-split", + .of_compatible = "maxim,max96745-bridge-split", + }, }; static const struct mfd_cell serdes_max96755_devs[] = { diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 83a750678531..fa1206365709 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -2001,9 +2001,12 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) #endif serial8250_modem_status(up); #ifdef CONFIG_ARCH_ROCKCHIP - if ((!up->dma || (up->dma && (!up->dma->txchan || up->dma->tx_err))) && - ((iir & 0xf) == UART_IIR_THRI)) - serial8250_tx_chars(up); + if ((iir & 0xf) == UART_IIR_THRI) { + if (!up->dma || (up->dma && (!up->dma->txchan || up->dma->tx_err))) + serial8250_tx_chars(up); + else if (!up->dma->tx_running) + __stop_tx(up); + } #else if ((status & UART_LSR_THRE) && (up->ier & UART_IER_THRI)) { if (!up->dma || up->dma->tx_err) diff --git a/drivers/video/rockchip/mpp/mpp_av1dec.c b/drivers/video/rockchip/mpp/mpp_av1dec.c index 2d2055afc1a4..f64de732c716 100644 --- a/drivers/video/rockchip/mpp/mpp_av1dec.c +++ b/drivers/video/rockchip/mpp/mpp_av1dec.c @@ -1009,7 +1009,7 @@ static int av1dec_probe(struct platform_device *pdev) dec->reg_base[AV1DEC_CLASS_VCD] = mpp->reg_base; ret = devm_request_threaded_irq(dev, mpp->irq, mpp_dev_irq, - mpp_dev_isr_sched, + NULL, IRQF_SHARED, dev_name(dev), mpp); if (ret) { diff --git a/drivers/video/rockchip/mpp/mpp_common.c b/drivers/video/rockchip/mpp/mpp_common.c index 84c3502f9103..bfe7d9715088 100644 --- a/drivers/video/rockchip/mpp/mpp_common.c +++ b/drivers/video/rockchip/mpp/mpp_common.c @@ -517,9 +517,9 @@ void mpp_free_task(struct kref *ref) } session = task->session; - mpp_debug_func(DEBUG_TASK_INFO, "task %d:%d free state 0x%lx abort %d\n", - session->index, task->task_id, task->state, - atomic_read(&task->abort_request)); + mpp_debug_func(DEBUG_TASK_INFO, "session %d:%d task %d state 0x%lx abort %d\n", + session->device_type, session->index, task->task_index, + task->state, atomic_read(&task->abort_request)); mpp = mpp_get_task_used_device(task, session); if (mpp->dev_ops->free_task) @@ -532,62 +532,34 @@ void mpp_free_task(struct kref *ref) static void mpp_task_timeout_work(struct work_struct *work_s) { - struct mpp_dev *mpp; - struct mpp_session *session; struct mpp_task *task = container_of(to_delayed_work(work_s), struct mpp_task, timeout_work); + struct mpp_dev *mpp; + struct mpp_session *session = task->session; - if (test_and_set_bit(TASK_STATE_HANDLE, &task->state)) { - mpp_err("task has been handled\n"); - return; - } - - if (!task->session) { + if (!session) { mpp_err("task %p, task->session is null.\n", task); return; } - session = task->session; - mpp_err("task %d:%d:%d processing time out!\n", session->pid, - session->index, task->task_id); - - if (!session->mpp) { - mpp_err("session %d:%d, session mpp is null.\n", session->pid, - session->index); + mpp = mpp_get_task_used_device(task, session); + if (!mpp) { + mpp_err("session %d:%d mpp is null\n", session->device_type, session->index); return; } + disable_irq(mpp->irq); + if (test_and_set_bit(TASK_STATE_HANDLE, &task->state)) { + mpp_err("task has been handled\n"); + return; + } + mpp_err("session %d:%d task %d processing time out!\n", + session->device_type, session->index, task->task_index); mpp_task_dump_timing(task, ktime_us_delta(ktime_get(), task->on_create)); - - mpp = mpp_get_task_used_device(task, session); - - /* disable core irq */ - disable_irq(mpp->irq); - /* disable mmu irq */ - if (mpp->iommu_info && mpp->iommu_info->got_irq) - disable_irq(mpp->iommu_info->irq); - - /* hardware maybe dead, reset it */ - mpp_reset_up_read(mpp->reset_group); - mpp_dev_reset(mpp); - mpp_power_off(mpp); - - mpp_iommu_dev_deactivate(mpp->iommu_info, mpp); set_bit(TASK_STATE_TIMEOUT, &task->state); - set_bit(TASK_STATE_DONE, &task->state); - /* Wake up the GET thread */ - wake_up(&task->wait); - /* remove task from taskqueue running list */ - mpp_taskqueue_pop_running(mpp->queue, task); - - /* enable core irq */ enable_irq(mpp->irq); - /* enable mmu irq */ - if (mpp->iommu_info && mpp->iommu_info->got_irq) - enable_irq(mpp->iommu_info->irq); - mpp_taskqueue_trigger_work(mpp); } @@ -648,6 +620,9 @@ static int mpp_process_task_default(struct mpp_session *session, */ atomic_inc(&session->task_count); mpp_session_push_pending(session, task); + mpp_debug_func(DEBUG_TASK_INFO, "session %d:%d task %d state 0x%lx\n", + session->device_type, session->index, + task->task_index, task->state); return 0; } @@ -713,6 +688,9 @@ int mpp_dev_reset(struct mpp_dev *mpp) { dev_info(mpp->dev, "resetting...\n"); + disable_irq(mpp->irq); + if (mpp->iommu_info && mpp->iommu_info->got_irq) + disable_irq(mpp->iommu_info->irq); /* * before running, we have to switch grf ctrl bit to ensure * working in current hardware @@ -741,6 +719,10 @@ int mpp_dev_reset(struct mpp_dev *mpp) mpp_reset_up_write(mpp->reset_group); mpp_iommu_up_write(mpp->iommu_info); + enable_irq(mpp->irq); + if (mpp->iommu_info && mpp->iommu_info->got_irq) + enable_irq(mpp->iommu_info->irq); + dev_info(mpp->dev, "reset done\n"); return 0; @@ -780,6 +762,7 @@ static int mpp_task_run(struct mpp_dev *mpp, { int ret; u32 timing_en; + struct mpp_session *session = task->session; mpp_debug_enter(); @@ -820,8 +803,9 @@ static int mpp_task_run(struct mpp_dev *mpp, } mpp_power_on(mpp); - mpp_debug_func(DEBUG_TASK_INFO, "pid %d run %s\n", - task->session->pid, dev_name(mpp->dev)); + mpp_debug_func(DEBUG_TASK_INFO, "%s session %d:%d task %d state 0x%lx\n", + dev_name(mpp->dev), session->device_type, + session->index, task->task_index, task->state); if (mpp->auto_freq_en && mpp->hw_ops->set_freq) mpp->hw_ops->set_freq(mpp, task); @@ -835,6 +819,36 @@ static int mpp_task_run(struct mpp_dev *mpp, return 0; } +static void try_process_running_task(struct mpp_dev *mpp) +{ + struct mpp_task *mpp_task, *n; + struct mpp_taskqueue *queue = mpp->queue; + + /* try process running task */ + list_for_each_entry_safe(mpp_task, n, &queue->running_list, queue_link) { + mpp = mpp_get_task_used_device(mpp_task, mpp_task->session); + disable_irq(mpp->irq); + if (!test_bit(TASK_STATE_HANDLE, &mpp_task->state)) { + enable_irq(mpp->irq); + continue; + } + + /* process timeout task */ + if (test_bit(TASK_STATE_TIMEOUT, &mpp_task->state)) { + atomic_inc(&mpp->reset_request); + mpp_iommu_dev_deactivate(mpp->iommu_info, mpp); + } + + if (mpp->auto_freq_en && mpp->hw_ops->reduce_freq && + list_empty(&mpp->queue->pending_list)) + mpp->hw_ops->reduce_freq(mpp); + + if (mpp->dev_ops->isr) + mpp->dev_ops->isr(mpp); + enable_irq(mpp->irq); + } +} + static void mpp_task_worker_default(struct kthread_work *work_s) { struct mpp_task *task; @@ -843,6 +857,7 @@ static void mpp_task_worker_default(struct kthread_work *work_s) mpp_debug_enter(); + try_process_running_task(mpp); again: task = mpp_taskqueue_get_pending_task(queue); if (!task) @@ -2245,60 +2260,39 @@ irqreturn_t mpp_dev_irq(int irq, void *param) if (mpp->dev_ops->irq) irq_ret = mpp->dev_ops->irq(mpp); - if (task) { - if (irq_ret == IRQ_WAKE_THREAD) { - /* if wait or delayed work timeout, abort request will turn on, - * isr should not to response, and handle it in delayed work - */ - if (test_and_set_bit(TASK_STATE_HANDLE, &task->state)) { - mpp_err("error, task has been handled, irq_status %08x\n", - mpp->irq_status); - irq_ret = IRQ_HANDLED; - goto done; - } - if (timing_en) { - task->on_cancel_timeout = ktime_get(); - set_bit(TASK_TIMING_TO_CANCEL, &task->state); - } - cancel_delayed_work(&task->timeout_work); - /* normal condition, set state and wake up isr thread */ - set_bit(TASK_STATE_IRQ, &task->state); - } - - if (irq_ret == IRQ_WAKE_THREAD) - mpp_iommu_dev_deactivate(mpp->iommu_info, mpp); - } else { + if (!task) { mpp_debug(DEBUG_IRQ_CHECK, "error, task is null\n"); + irq_ret = IRQ_HANDLED; + goto done; } + + if (irq_ret == IRQ_WAKE_THREAD) { + /* if wait or delayed work timeout, abort request will turn on, + * isr should not to response, and handle it in delayed work + */ + if (test_and_set_bit(TASK_STATE_HANDLE, &task->state)) { + dev_err(mpp->dev, "error, task %d has been handled, irq_status %#x\n", + task->task_index, mpp->irq_status); + irq_ret = IRQ_HANDLED; + goto done; + } + if (timing_en) { + task->on_cancel_timeout = ktime_get(); + set_bit(TASK_TIMING_TO_CANCEL, &task->state); + } + cancel_delayed_work(&task->timeout_work); + /* normal condition, set state and wake up isr thread */ + set_bit(TASK_STATE_IRQ, &task->state); + task->irq_status = mpp->irq_status; + mpp_iommu_dev_deactivate(mpp->iommu_info, mpp); + irq_ret = IRQ_HANDLED; + mpp_taskqueue_trigger_work(mpp); + } + done: return irq_ret; } -irqreturn_t mpp_dev_isr_sched(int irq, void *param) -{ - irqreturn_t ret = IRQ_NONE; - struct mpp_dev *mpp = param; - struct mpp_task *task = mpp->cur_task; - - if (task && mpp->srv->timing_en) { - task->on_isr = ktime_get(); - set_bit(TASK_TIMING_ISR, &task->state); - } - - if (mpp->auto_freq_en && - mpp->hw_ops->reduce_freq && - list_empty(&mpp->queue->pending_list)) - mpp->hw_ops->reduce_freq(mpp); - - if (mpp->dev_ops->isr) - ret = mpp->dev_ops->isr(mpp); - - /* trigger current queue to run next task */ - mpp_taskqueue_trigger_work(mpp); - - return ret; -} - u32 mpp_get_grf(struct mpp_grf_info *grf_info) { u32 val = 0; @@ -2417,7 +2411,6 @@ void mpp_task_dump_timing(struct mpp_task *task, s64 time_diff) LOG_TIMING(state, TASK_TIMING_RUN_END, "run end", task->on_run_end, s); LOG_TIMING(state, TASK_TIMING_IRQ, "irq", task->on_irq, s); LOG_TIMING(state, TASK_TIMING_TO_CANCEL, "timeout cancel", task->on_cancel_timeout, s); - LOG_TIMING(state, TASK_TIMING_ISR, "isr", task->on_isr, s); LOG_TIMING(state, TASK_TIMING_FINISH, "finish", task->on_finish, s); } diff --git a/drivers/video/rockchip/mpp/mpp_common.h b/drivers/video/rockchip/mpp/mpp_common.h index 43b62e8e7df6..fdf893c790cc 100644 --- a/drivers/video/rockchip/mpp/mpp_common.h +++ b/drivers/video/rockchip/mpp/mpp_common.h @@ -395,8 +395,7 @@ enum mpp_task_state { TASK_TIMING_RUN_END = 21, TASK_TIMING_IRQ = 22, TASK_TIMING_TO_CANCEL = 23, - TASK_TIMING_ISR = 24, - TASK_TIMING_FINISH = 25, + TASK_TIMING_FINISH = 24, }; /* The context for the a task */ @@ -435,7 +434,6 @@ struct mpp_task { ktime_t on_run_end; ktime_t on_irq; ktime_t on_cancel_timeout; - ktime_t on_isr; ktime_t on_finish; /* hardware info for current task */ @@ -443,6 +441,7 @@ struct mpp_task { u32 task_index; u32 task_id; u32 *reg; + u32 irq_status; /* event for session wait thread */ wait_queue_head_t wait; @@ -660,7 +659,6 @@ int mpp_power_off(struct mpp_dev *mpp); int mpp_dev_reset(struct mpp_dev *mpp); irqreturn_t mpp_dev_irq(int irq, void *param); -irqreturn_t mpp_dev_isr_sched(int irq, void *param); struct reset_control *mpp_reset_control_get(struct mpp_dev *mpp, enum MPP_RESET_TYPE type, diff --git a/drivers/video/rockchip/mpp/mpp_iep2.c b/drivers/video/rockchip/mpp/mpp_iep2.c index 15c2d4f9bf0a..8e4a0050384e 100644 --- a/drivers/video/rockchip/mpp/mpp_iep2.c +++ b/drivers/video/rockchip/mpp/mpp_iep2.c @@ -1001,7 +1001,7 @@ static int iep2_probe(struct platform_device *pdev) ret = devm_request_threaded_irq(dev, mpp->irq, mpp_dev_irq, - mpp_dev_isr_sched, + NULL, IRQF_SHARED, dev_name(dev), mpp); if (ret) { diff --git a/drivers/video/rockchip/mpp/mpp_jpgdec.c b/drivers/video/rockchip/mpp/mpp_jpgdec.c index b88daee1c7e5..b9d415eda21f 100644 --- a/drivers/video/rockchip/mpp/mpp_jpgdec.c +++ b/drivers/video/rockchip/mpp/mpp_jpgdec.c @@ -617,7 +617,7 @@ static int jpgdec_probe(struct platform_device *pdev) ret = devm_request_threaded_irq(dev, mpp->irq, mpp_dev_irq, - mpp_dev_isr_sched, + NULL, IRQF_SHARED, dev_name(dev), mpp); if (ret) { diff --git a/drivers/video/rockchip/mpp/mpp_jpgenc.c b/drivers/video/rockchip/mpp/mpp_jpgenc.c index a494ab5e3aa3..62f8e2f2a37f 100644 --- a/drivers/video/rockchip/mpp/mpp_jpgenc.c +++ b/drivers/video/rockchip/mpp/mpp_jpgenc.c @@ -612,7 +612,7 @@ static int jpgenc_probe(struct platform_device *pdev) return -EINVAL; } - ret = devm_request_threaded_irq(dev, mpp->irq, mpp_dev_irq, mpp_dev_isr_sched, + ret = devm_request_threaded_irq(dev, mpp->irq, mpp_dev_irq, NULL, IRQF_SHARED, dev_name(dev), mpp); if (ret) { diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec.c b/drivers/video/rockchip/mpp/mpp_rkvdec.c index b060e12b20a8..d8628e0db099 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec.c @@ -1886,7 +1886,7 @@ static int rkvdec_probe(struct platform_device *pdev) ret = devm_request_threaded_irq(dev, mpp->irq, mpp_dev_irq, - mpp_dev_isr_sched, + NULL, IRQF_SHARED, dev_name(dev), mpp); if (ret) { diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2.c b/drivers/video/rockchip/mpp/mpp_rkvdec2.c index 7f6a4d89cd3a..20eda6bb693c 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2.c @@ -1879,6 +1879,7 @@ static int rkvdec2_probe_default(struct platform_device *pdev) struct rkvdec2_dev *dec = NULL; struct mpp_dev *mpp = NULL; const struct of_device_id *match = NULL; + irq_handler_t irq_proc = NULL; int ret = 0; dec = devm_kzalloc(dev, sizeof(*dec), GFP_KERNEL); @@ -1903,20 +1904,18 @@ static int rkvdec2_probe_default(struct platform_device *pdev) rkvdec2_alloc_rcbbuf(pdev, dec); rkvdec2_link_init(pdev, dec); + irq_proc = mpp_dev_irq; if (dec->link_dec && (mpp->task_capacity > 1)) { - ret = devm_request_threaded_irq(dev, mpp->irq, - rkvdec2_link_irq_proc, NULL, - IRQF_SHARED, dev_name(dev), mpp); + irq_proc = rkvdec2_link_irq_proc; mpp->dev_ops->process_task = rkvdec2_link_process_task; mpp->dev_ops->wait_result = rkvdec2_link_wait_result; mpp->dev_ops->task_worker = rkvdec2_link_worker; mpp->dev_ops->deinit = rkvdec2_link_session_deinit; kthread_init_work(&mpp->work, rkvdec2_link_worker); - } else { - ret = devm_request_threaded_irq(dev, mpp->irq, - mpp_dev_irq, mpp_dev_isr_sched, - IRQF_SHARED, dev_name(dev), mpp); } + + ret = devm_request_threaded_irq(dev, mpp->irq, irq_proc, NULL, + IRQF_SHARED, dev_name(dev), mpp); if (ret) { dev_err(dev, "register interrupter runtime failed\n"); return -EINVAL; diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c index 80aab857d783..5b7fd442d132 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c @@ -1631,9 +1631,6 @@ static int rkvdec2_soft_ccu_dequeue(struct mpp_taskqueue *queue) mpp_task->on_cancel_timeout = mpp_task->on_irq; set_bit(TASK_TIMING_TO_CANCEL, &mpp_task->state); - - mpp_task->on_isr = mpp_task->on_irq; - set_bit(TASK_TIMING_ISR, &mpp_task->state); } set_bit(TASK_STATE_HANDLE, &mpp_task->state); diff --git a/drivers/video/rockchip/mpp/mpp_rkvenc.c b/drivers/video/rockchip/mpp/mpp_rkvenc.c index 3e02712b0f60..f5bf49355165 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvenc.c +++ b/drivers/video/rockchip/mpp/mpp_rkvenc.c @@ -1420,7 +1420,7 @@ static int rkvenc_probe(struct platform_device *pdev) ret = devm_request_threaded_irq(dev, mpp->irq, mpp_dev_irq, - mpp_dev_isr_sched, + NULL, IRQF_SHARED, dev_name(dev), mpp); if (ret) { diff --git a/drivers/video/rockchip/mpp/mpp_rkvenc2.c b/drivers/video/rockchip/mpp/mpp_rkvenc2.c index df543a2b0efb..25c4d42539a7 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvenc2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvenc2.c @@ -2784,7 +2784,7 @@ static int rkvenc_core_probe(struct platform_device *pdev) ret = devm_request_threaded_irq(dev, mpp->irq, mpp_dev_irq, - mpp_dev_isr_sched, + NULL, IRQF_ONESHOT, dev_name(dev), mpp); if (ret) { @@ -2833,7 +2833,7 @@ static int rkvenc_probe_default(struct platform_device *pdev) ret = devm_request_threaded_irq(dev, mpp->irq, mpp_dev_irq, - mpp_dev_isr_sched, + NULL, IRQF_SHARED, dev_name(dev), mpp); if (ret) { diff --git a/drivers/video/rockchip/mpp/mpp_service.c b/drivers/video/rockchip/mpp/mpp_service.c index cc5968e1689e..e523fd125ed7 100644 --- a/drivers/video/rockchip/mpp/mpp_service.c +++ b/drivers/video/rockchip/mpp/mpp_service.c @@ -380,7 +380,7 @@ static int mpp_service_probe(struct platform_device *pdev) kthread_init_worker(&queue->worker); queue->kworker_task = kthread_run(kthread_worker_fn, &queue->worker, - "queue_work%d", i); + "mpp_worker_%d", i); srv->task_queues[i] = queue; } diff --git a/drivers/video/rockchip/mpp/mpp_vdpp.c b/drivers/video/rockchip/mpp/mpp_vdpp.c index ea6f51c28461..e24687c41a74 100644 --- a/drivers/video/rockchip/mpp/mpp_vdpp.c +++ b/drivers/video/rockchip/mpp/mpp_vdpp.c @@ -784,7 +784,7 @@ static int vdpp_probe(struct platform_device *pdev) /* get irq */ ret = devm_request_threaded_irq(dev, mpp->irq, mpp_dev_irq, - mpp_dev_isr_sched, + NULL, IRQF_SHARED, dev_name(dev), mpp); if (ret) { diff --git a/drivers/video/rockchip/mpp/mpp_vdpu1.c b/drivers/video/rockchip/mpp/mpp_vdpu1.c index 6ddf5dae73f3..e6a76d230d71 100644 --- a/drivers/video/rockchip/mpp/mpp_vdpu1.c +++ b/drivers/video/rockchip/mpp/mpp_vdpu1.c @@ -926,7 +926,7 @@ static int vdpu_probe(struct platform_device *pdev) ret = devm_request_threaded_irq(dev, mpp->irq, mpp_dev_irq, - mpp_dev_isr_sched, + NULL, IRQF_SHARED, dev_name(dev), mpp); if (ret) { diff --git a/drivers/video/rockchip/mpp/mpp_vdpu2.c b/drivers/video/rockchip/mpp/mpp_vdpu2.c index d5a6a3017208..0a165fa5d0f6 100644 --- a/drivers/video/rockchip/mpp/mpp_vdpu2.c +++ b/drivers/video/rockchip/mpp/mpp_vdpu2.c @@ -762,7 +762,7 @@ static int vdpu_probe(struct platform_device *pdev) ret = devm_request_threaded_irq(dev, mpp->irq, mpp_dev_irq, - mpp_dev_isr_sched, + NULL, IRQF_SHARED, dev_name(dev), mpp); if (ret) { diff --git a/drivers/video/rockchip/mpp/mpp_vepu1.c b/drivers/video/rockchip/mpp/mpp_vepu1.c index 18f685a2e948..4ebd0a57d74d 100644 --- a/drivers/video/rockchip/mpp/mpp_vepu1.c +++ b/drivers/video/rockchip/mpp/mpp_vepu1.c @@ -754,7 +754,7 @@ static int vepu_probe(struct platform_device *pdev) ret = devm_request_threaded_irq(dev, mpp->irq, mpp_dev_irq, - mpp_dev_isr_sched, + NULL, IRQF_SHARED, dev_name(dev), mpp); if (ret) { diff --git a/drivers/video/rockchip/mpp/mpp_vepu2.c b/drivers/video/rockchip/mpp/mpp_vepu2.c index fb5f5e5c28e3..05a5556e0f8d 100644 --- a/drivers/video/rockchip/mpp/mpp_vepu2.c +++ b/drivers/video/rockchip/mpp/mpp_vepu2.c @@ -1135,7 +1135,7 @@ static int vepu_core_probe(struct platform_device *pdev) ret = devm_request_threaded_irq(dev, mpp->irq, mpp_dev_irq, - mpp_dev_isr_sched, + NULL, IRQF_SHARED, dev_name(dev), mpp); if (ret) { @@ -1185,7 +1185,7 @@ static int vepu_probe_default(struct platform_device *pdev) ret = devm_request_threaded_irq(dev, mpp->irq, mpp_dev_irq, - mpp_dev_isr_sched, + NULL, IRQF_SHARED, dev_name(dev), mpp); if (ret) { diff --git a/drivers/video/rockchip/rga3/include/rga2_reg_info.h b/drivers/video/rockchip/rga3/include/rga2_reg_info.h index 07a1b29c50f9..90d18d443ce8 100644 --- a/drivers/video/rockchip/rga3/include/rga2_reg_info.h +++ b/drivers/video/rockchip/rga3/include/rga2_reg_info.h @@ -17,6 +17,7 @@ #define RGA2_MMU_CTRL0 0x014 #define RGA2_MMU_CMD_BASE 0x018 #define RGA2_STATUS2 0x01c +#define RGA2_WORK_CNT 0x020 #define RGA2_VERSION_NUM 0x028 #define RGA2_READ_LINE_CNT 0x030 #define RGA2_WRITE_LINE_CNT 0x034 diff --git a/drivers/video/rockchip/rga3/include/rga_drv.h b/drivers/video/rockchip/rga3/include/rga_drv.h index aa63b0bb00c4..890563febf4d 100644 --- a/drivers/video/rockchip/rga3/include/rga_drv.h +++ b/drivers/video/rockchip/rga3/include/rga_drv.h @@ -301,6 +301,8 @@ struct rga_job { uint32_t intr_status; uint32_t hw_status; uint32_t cmd_status; + + uint32_t work_cycle; }; struct rga_backend_ops { @@ -309,6 +311,7 @@ struct rga_backend_ops { int (*init_reg)(struct rga_job *job); void (*soft_reset)(struct rga_scheduler_t *scheduler); int (*read_back_reg)(struct rga_job *job, struct rga_scheduler_t *scheduler); + int (*read_status)(struct rga_job *job, struct rga_scheduler_t *scheduler); int (*irq)(struct rga_scheduler_t *scheduler); int (*isr_thread)(struct rga_job *job, struct rga_scheduler_t *scheduler); }; diff --git a/drivers/video/rockchip/rga3/rga2_reg_info.c b/drivers/video/rockchip/rga3/rga2_reg_info.c index a991bd35af06..0de469eb7eaa 100644 --- a/drivers/video/rockchip/rga3/rga2_reg_info.c +++ b/drivers/video/rockchip/rga3/rga2_reg_info.c @@ -2863,6 +2863,7 @@ static int rga2_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) int i; bool master_mode_en; uint32_t sys_ctrl; + unsigned long flags; ktime_t now = ktime_get(); /* @@ -2874,12 +2875,6 @@ static int rga2_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) else master_mode_en = false; - if (job->pre_intr_info.enable) - rga2_set_pre_intr_reg(job, scheduler); - - if (job->full_csc.flag) - rga2_set_reg_full_csc(job, scheduler); - if (DEBUGGER_EN(REG)) { uint32_t *p; @@ -2894,16 +2889,24 @@ static int rga2_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) p[2 + i * 4], p[3 + i * 4]); } - /* All CMD finish int */ - rga_write(rga_read(RGA2_INT, scheduler) | - m_RGA2_INT_ERROR_ENABLE_MASK | m_RGA2_INT_ALL_CMD_DONE_INT_EN, - RGA2_INT, scheduler); - /* sys_reg init */ sys_ctrl = m_RGA2_SYS_CTRL_AUTO_CKG | m_RGA2_SYS_CTRL_AUTO_RST | m_RGA2_SYS_CTRL_RST_PROTECT_P | m_RGA2_SYS_CTRL_DST_WR_OPT_DIS | m_RGA2_SYS_CTRL_SRC0YUV420SP_RD_OPT_DIS; + spin_lock_irqsave(&scheduler->irq_lock, flags); + + if (job->pre_intr_info.enable) + rga2_set_pre_intr_reg(job, scheduler); + + if (job->full_csc.flag) + rga2_set_reg_full_csc(job, scheduler); + + /* All CMD finish int */ + rga_write(rga_read(RGA2_INT, scheduler) | + m_RGA2_INT_ERROR_ENABLE_MASK | m_RGA2_INT_ALL_CMD_DONE_INT_EN, + RGA2_INT, scheduler); + if (master_mode_en) { /* master mode */ sys_ctrl |= s_RGA2_SYS_CTRL_CMD_MODE(1); @@ -2926,10 +2929,7 @@ static int rga2_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) rga_write(sys_ctrl, RGA2_SYS_CTRL, scheduler); } - if (DEBUGGER_EN(REG)) - pr_info("sys_ctrl = %x, int = %x\n", - rga_read(RGA2_SYS_CTRL, scheduler), - rga_read(RGA2_INT, scheduler)); + spin_unlock_irqrestore(&scheduler->irq_lock, flags); if (DEBUGGER_EN(TIME)) pr_info("request[%d], set register cost time %lld us\n", @@ -2988,6 +2988,16 @@ static int rga2_read_back_reg(struct rga_job *job, struct rga_scheduler_t *sched return 0; } +static int rga2_read_status(struct rga_job *job, struct rga_scheduler_t *scheduler) +{ + job->intr_status = rga_read(RGA2_INT, scheduler); + job->hw_status = rga_read(RGA2_STATUS2, scheduler); + job->cmd_status = rga_read(RGA2_STATUS1, scheduler); + job->work_cycle = rga_read(RGA2_WORK_CNT, scheduler); + + return 0; +} + static int rga2_irq(struct rga_scheduler_t *scheduler) { struct rga_job *job = scheduler->running_job; @@ -2999,13 +3009,12 @@ static int rga2_irq(struct rga_scheduler_t *scheduler) if (test_bit(RGA_JOB_STATE_INTR_ERR, &job->state)) return IRQ_WAKE_THREAD; - job->intr_status = rga_read(RGA2_INT, scheduler); - job->hw_status = rga_read(RGA2_STATUS2, scheduler); - job->cmd_status = rga_read(RGA2_STATUS1, scheduler); + scheduler->ops->read_status(job, scheduler); if (DEBUGGER_EN(INT_FLAG)) - pr_info("irq handler, INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x]\n", - job->intr_status, job->hw_status, job->cmd_status); + pr_info("irq handler, INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x], WORK_CYCLE[0x%x(%d)]\n", + job->intr_status, job->hw_status, job->cmd_status, + job->work_cycle, job->work_cycle); if (job->intr_status & (m_RGA2_INT_CUR_CMD_DONE_INT_FLAG | m_RGA2_INT_ALL_CMD_DONE_INT_FLAG)) { @@ -3013,8 +3022,10 @@ static int rga2_irq(struct rga_scheduler_t *scheduler) } else if (job->intr_status & m_RGA2_INT_ERROR_FLAG_MASK) { set_bit(RGA_JOB_STATE_INTR_ERR, &job->state); - pr_err("irq handler err! INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x]\n", - job->intr_status, job->hw_status, job->cmd_status); + pr_err("irq handler err! INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x], WORK_CYCLE[0x%x(%d)]\n", + job->intr_status, job->hw_status, job->cmd_status, + job->work_cycle, job->work_cycle); + scheduler->ops->soft_reset(scheduler); } @@ -3065,6 +3076,7 @@ const struct rga_backend_ops rga2_ops = { .init_reg = rga2_init_reg, .soft_reset = rga2_soft_reset, .read_back_reg = rga2_read_back_reg, + .read_status = rga2_read_status, .irq = rga2_irq, .isr_thread = rga2_isr_thread, }; diff --git a/drivers/video/rockchip/rga3/rga3_reg_info.c b/drivers/video/rockchip/rga3/rga3_reg_info.c index 1de0632187c3..a677fbc86a73 100644 --- a/drivers/video/rockchip/rga3/rga3_reg_info.c +++ b/drivers/video/rockchip/rga3/rga3_reg_info.c @@ -2225,6 +2225,7 @@ const struct rga_backend_ops rga3_ops = { .init_reg = rga3_init_reg, .soft_reset = rga3_soft_reset, .read_back_reg = NULL, + .read_status = NULL, .irq = rga3_irq, .isr_thread = rga3_isr_thread, }; diff --git a/drivers/video/rockchip/rga3/rga_job.c b/drivers/video/rockchip/rga3/rga_job.c index cfa913c3f69f..ae78578c3479 100644 --- a/drivers/video/rockchip/rga3/rga_job.c +++ b/drivers/video/rockchip/rga3/rga_job.c @@ -275,16 +275,46 @@ struct rga_job *rga_job_done(struct rga_scheduler_t *scheduler) rga_dump_job_image(job); if (DEBUGGER_EN(TIME)) - pr_info("request[%d], hardware[%s] cost time %lld us\n", + pr_info("request[%d], hardware[%s] cost time %lld us, work cycle %d\n", job->request_id, rga_get_core_name(scheduler->core), - ktime_us_delta(now, job->hw_running_time)); + ktime_us_delta(now, job->hw_running_time), + job->work_cycle); rga_mm_unmap_job_info(job); return job; } +static int rga_job_timeout_query_state(struct rga_job *job, int orig_ret) +{ + struct rga_scheduler_t *scheduler = job->scheduler; + + if (scheduler->ops->read_status) { + scheduler->ops->read_status(job, scheduler); + pr_err("request[%d] core[%d]: INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x], WORK_CYCLE[0x%x(%d)]\n", + job->request_id, scheduler->core, + job->intr_status, job->hw_status, job->cmd_status, + job->work_cycle, job->work_cycle); + } + + if (test_bit(RGA_JOB_STATE_DONE, &job->state) && + test_bit(RGA_JOB_STATE_FINISH, &job->state)) { + return orig_ret; + } else if (!test_bit(RGA_JOB_STATE_DONE, &job->state) && + test_bit(RGA_JOB_STATE_FINISH, &job->state)) { + pr_err("request[%d] job hardware has finished, but the software has timeout!\n", + job->request_id); + return -EBUSY; + } else if (!test_bit(RGA_JOB_STATE_DONE, &job->state) && + !test_bit(RGA_JOB_STATE_FINISH, &job->state)) { + pr_err("request[%d] job hardware has timeout.\n", job->request_id); + return -EBUSY; + } + + return orig_ret; +} + static void rga_job_scheduler_timeout_clean(struct rga_scheduler_t *scheduler) { unsigned long flags; @@ -299,6 +329,8 @@ static void rga_job_scheduler_timeout_clean(struct rga_scheduler_t *scheduler) job = scheduler->running_job; if (ktime_ms_delta(ktime_get(), job->hw_running_time) >= RGA_JOB_TIMEOUT_DELAY) { + job->ret = rga_job_timeout_query_state(job, job->ret); + scheduler->running_job = NULL; scheduler->status = RGA_SCHEDULER_ABORT; scheduler->ops->soft_reset(scheduler); @@ -306,8 +338,6 @@ static void rga_job_scheduler_timeout_clean(struct rga_scheduler_t *scheduler) spin_unlock_irqrestore(&scheduler->irq_lock, flags); rga_mm_unmap_job_info(job); - - job->ret = -EBUSY; rga_request_release_signal(scheduler, job); rga_power_disable(scheduler); @@ -766,23 +796,12 @@ static int rga_request_timeout_query_state(struct rga_request *request) if (scheduler->running_job) { job = scheduler->running_job; + if (request->id == job->request_id) { - if (test_bit(RGA_JOB_STATE_DONE, &job->state) && - test_bit(RGA_JOB_STATE_FINISH, &job->state)) { - spin_unlock_irqrestore(&scheduler->irq_lock, flags); - return request->ret; - } else if (!test_bit(RGA_JOB_STATE_DONE, &job->state) && - test_bit(RGA_JOB_STATE_FINISH, &job->state)) { - spin_unlock_irqrestore(&scheduler->irq_lock, flags); - pr_err("request[%d] hardware has finished, but the software has timeout!\n", - request->id); - return -EBUSY; - } else if (!test_bit(RGA_JOB_STATE_DONE, &job->state) && - !test_bit(RGA_JOB_STATE_FINISH, &job->state)) { - spin_unlock_irqrestore(&scheduler->irq_lock, flags); - pr_err("request[%d] hardware has timeout.\n", request->id); - return -EBUSY; - } + request->ret = rga_job_timeout_query_state(job, request->ret); + + spin_unlock_irqrestore(&scheduler->irq_lock, flags); + break; } }