From d420d65bec8435e3e1198fbb7aaf3af04d10111b Mon Sep 17 00:00:00 2001 From: Zhibin Huang Date: Mon, 29 Apr 2024 09:28:16 +0800 Subject: [PATCH 01/11] drm/rockchip: dsi2: optimize drive probe process Put "component_add" in the attach call so that dsi host and dsi device (panel or bridge) can be regarded as a component as a whole. dsi calls "mipi_dsi_host_register" so that the panel executes the probe process or the bridge successfully executes "mipi_dsi_device_register_full" during the probe process. The panel or bridge triggers "component_add" by calling mipi_dsi_attach after the probe is successful. Through the above modifications, you can avoid dsi defer probe infinitely due to panel configuration errors. Type: Fix Redmine ID: N/A Associated modifications: N/A Test: N/A Signed-off-by: Zhibin Huang Change-Id: Ic8782e9902a6133990fca728ab12e530e50b6d68 --- drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) 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) From 4938e4ee1b60cfa972aafa896e3ebc0fcf222a60 Mon Sep 17 00:00:00 2001 From: Yandong Lin Date: Sun, 8 Oct 2023 10:07:23 +0800 Subject: [PATCH 02/11] video: rockchip: mpp: optimize the schedule of enc/dec Remove the isr thread to reduce one thread schedule. Signed-off-by: Yandong Lin Change-Id: I4721fc6066c8580e5955f8c79025e46b96c82d85 --- drivers/video/rockchip/mpp/mpp_av1dec.c | 2 +- drivers/video/rockchip/mpp/mpp_common.c | 183 +++++++++--------- drivers/video/rockchip/mpp/mpp_common.h | 6 +- drivers/video/rockchip/mpp/mpp_iep2.c | 2 +- drivers/video/rockchip/mpp/mpp_jpgdec.c | 2 +- drivers/video/rockchip/mpp/mpp_jpgenc.c | 2 +- drivers/video/rockchip/mpp/mpp_rkvdec.c | 2 +- drivers/video/rockchip/mpp/mpp_rkvdec2.c | 13 +- drivers/video/rockchip/mpp/mpp_rkvdec2_link.c | 3 - drivers/video/rockchip/mpp/mpp_rkvenc.c | 2 +- drivers/video/rockchip/mpp/mpp_rkvenc2.c | 4 +- drivers/video/rockchip/mpp/mpp_service.c | 2 +- drivers/video/rockchip/mpp/mpp_vdpp.c | 2 +- drivers/video/rockchip/mpp/mpp_vdpu1.c | 2 +- drivers/video/rockchip/mpp/mpp_vdpu2.c | 2 +- drivers/video/rockchip/mpp/mpp_vepu1.c | 2 +- drivers/video/rockchip/mpp/mpp_vepu2.c | 4 +- 17 files changed, 111 insertions(+), 124 deletions(-) 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) { From 13f5c96469301c077ec0d39d0ab6e87ece13eb54 Mon Sep 17 00:00:00 2001 From: Tao Huang Date: Fri, 24 May 2024 10:00:55 +0800 Subject: [PATCH 03/11] ARM: dts: rockchip: Sort dtb entries in Makefile Signed-off-by: Tao Huang Change-Id: Idde8ca2faf4faf1767c4b140a920af68a5e1ebf4 --- arch/arm/boot/dts/Makefile | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) 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 \ From c6a0b5d0c797a2a5b09613f5b9942f1f468f4ece Mon Sep 17 00:00:00 2001 From: Tao Huang Date: Fri, 24 May 2024 11:04:55 +0800 Subject: [PATCH 04/11] arm64: rockchip_linux_defconfig: Disable AMPERE/A520 erratum -CONFIG_AMPERE_ERRATUM_AC03_CPU_38 -CONFIG_ARM64_ERRATUM_2966298 Signed-off-by: Tao Huang Change-Id: Iac5a07f0190dac519f7ab4570b0de7963be0c90c --- arch/arm64/configs/rockchip_linux_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/configs/rockchip_linux_defconfig b/arch/arm64/configs/rockchip_linux_defconfig index 9dbd820726d1..2cc2abee29fe 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 @@ -42,6 +43,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 From d60dbd00ed1d922676b72355009982ad68c6a3f0 Mon Sep 17 00:00:00 2001 From: Yu Qiaowei Date: Thu, 9 May 2024 09:54:45 +0800 Subject: [PATCH 05/11] video: rockchip: rga3: support querying hardware work cycle Signed-off-by: Yu Qiaowei Change-Id: I7884f17590ed8a11134664897534eb0cc911275d --- .../rockchip/rga3/include/rga2_reg_info.h | 1 + drivers/video/rockchip/rga3/include/rga_drv.h | 3 +++ drivers/video/rockchip/rga3/rga2_reg_info.c | 26 ++++++++++++++----- drivers/video/rockchip/rga3/rga3_reg_info.c | 1 + drivers/video/rockchip/rga3/rga_job.c | 14 ++++++++-- 5 files changed, 36 insertions(+), 9 deletions(-) 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..153051a31124 100644 --- a/drivers/video/rockchip/rga3/rga2_reg_info.c +++ b/drivers/video/rockchip/rga3/rga2_reg_info.c @@ -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..7e9b425cec95 100644 --- a/drivers/video/rockchip/rga3/rga_job.c +++ b/drivers/video/rockchip/rga3/rga_job.c @@ -275,10 +275,11 @@ 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); @@ -766,7 +767,16 @@ 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 (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", + 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)) { spin_unlock_irqrestore(&scheduler->irq_lock, flags); From 4f91478b80bb25e5587eae48f02c2aaa880f353f Mon Sep 17 00:00:00 2001 From: Yu Qiaowei Date: Wed, 22 May 2024 15:13:14 +0800 Subject: [PATCH 06/11] video: rockchip: rga3: query job state when clearinga timeout job Signed-off-by: Yu Qiaowei Change-Id: Ia78895878e5ed2a0658e827ec16ffd3314235edb --- drivers/video/rockchip/rga3/rga_job.c | 59 +++++++++++++++------------ 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/drivers/video/rockchip/rga3/rga_job.c b/drivers/video/rockchip/rga3/rga_job.c index 7e9b425cec95..ae78578c3479 100644 --- a/drivers/video/rockchip/rga3/rga_job.c +++ b/drivers/video/rockchip/rga3/rga_job.c @@ -286,6 +286,35 @@ struct rga_job *rga_job_done(struct rga_scheduler_t *scheduler) 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; @@ -300,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); @@ -307,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); @@ -769,30 +798,10 @@ static int rga_request_timeout_query_state(struct rga_request *request) job = scheduler->running_job; if (request->id == job->request_id) { - 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", - request->id, scheduler->core, - job->intr_status, job->hw_status, job->cmd_status, - job->work_cycle, job->work_cycle); - } + request->ret = rga_job_timeout_query_state(job, request->ret); - 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; - } + spin_unlock_irqrestore(&scheduler->irq_lock, flags); + break; } } From 171188308c6b3bc1f25e32068fd4e942b3ccb00d Mon Sep 17 00:00:00 2001 From: Yu Qiaowei Date: Wed, 22 May 2024 15:18:52 +0800 Subject: [PATCH 07/11] video: rockchip: rga3: scheduler needs to be locked when operating registers Signed-off-by: Yu Qiaowei Change-Id: I729f1e0dac96022ffe01b3367a964d61e4e739e1 --- drivers/video/rockchip/rga3/rga2_reg_info.c | 30 ++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/video/rockchip/rga3/rga2_reg_info.c b/drivers/video/rockchip/rga3/rga2_reg_info.c index 153051a31124..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", From 9fbcb7ca5ba5862d1c597ae52ed331c406071403 Mon Sep 17 00:00:00 2001 From: Huibin Hong Date: Tue, 21 May 2024 11:11:53 +0800 Subject: [PATCH 08/11] serial: 8250_port: fix dma tx issue on rockchip Fixes: e8ffbb71f783 ("serial: 8250: use THRE & __stop_tx also with DMA") Change-Id: I8c30f0413a3ff7f9f36ee089ee1be5f3f4a0d045 Signed-off-by: Huibin Hong --- drivers/tty/serial/8250/8250_port.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 4a9a8c081c92..c79a29bf4c76 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) From 74ff804ebab9761e0b195536de6a35d3bec9aa77 Mon Sep 17 00:00:00 2001 From: Tao Huang Date: Fri, 24 May 2024 11:08:11 +0800 Subject: [PATCH 09/11] arm64: rockchip_linux_defconfig: Disable CPU errata 2441007 (Cortex-A55) According to ANDROID commit a9567a35d0b8 ("ANDROID: arm64: Disable workaround for CPU errata 2441007 and 2441009"): CPU errata 2441007 (Cortex-A55) and 2441009 (Cortex-A510) are categorised as "rare" by Arm and consequently the workaround is not intended to be deployed in practice as the issue is not expected to occur in real-world environments. Given that the cost of the workaround, which issues additional broadcast TLB invalidation requests, has been shown to impact kswapd significantly on Pixel devices, disable the workaround following Arm's recommendation. Signed-off-by: Tao Huang Change-Id: I794d048a094714c1370752bfaa47bee2afd57d53 --- arch/arm64/configs/rockchip_linux_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/rockchip_linux_defconfig b/arch/arm64/configs/rockchip_linux_defconfig index 2cc2abee29fe..61cef7c55425 100644 --- a/arch/arm64/configs/rockchip_linux_defconfig +++ b/arch/arm64/configs/rockchip_linux_defconfig @@ -33,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 From 70fde854eacfe3898e70b6459afbf7a973e8add5 Mon Sep 17 00:00:00 2001 From: Tao Huang Date: Fri, 24 May 2024 11:14:23 +0800 Subject: [PATCH 10/11] arm64: rockchip_linux_defconfig: Use CONFIG_HZ_250 Which is default. Signed-off-by: Tao Huang Change-Id: Ib6cd6ea9a22e238ff9b97d69f93a4ce50b4b4331 --- arch/arm64/configs/rockchip_linux_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/configs/rockchip_linux_defconfig b/arch/arm64/configs/rockchip_linux_defconfig index 61cef7c55425..67f36e8b9884 100644 --- a/arch/arm64/configs/rockchip_linux_defconfig +++ b/arch/arm64/configs/rockchip_linux_defconfig @@ -60,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 From a72be40c93bd82f7ddc24a54a935d017b16453b5 Mon Sep 17 00:00:00 2001 From: Luo Wei Date: Fri, 26 Apr 2024 11:59:44 +0800 Subject: [PATCH 11/11] mfd: display-serdes: add max96745 bridge split support Signed-off-by: Luo Wei Change-Id: I038592b035a9623962e7f129881ec197261e4c22 --- drivers/mfd/display-serdes/serdes-core.c | 4 ++++ 1 file changed, 4 insertions(+) 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[] = {