Merge commit 'a72be40c93bd82f7ddc24a54a935d017b16453b5'

* commit 'a72be40c93bd82f7ddc24a54a935d017b16453b5':
  mfd: display-serdes: add max96745 bridge split support
  arm64: rockchip_linux_defconfig: Use CONFIG_HZ_250
  arm64: rockchip_linux_defconfig: Disable CPU errata 2441007 (Cortex-A55)
  serial: 8250_port: fix dma tx issue on rockchip
  video: rockchip: rga3: scheduler needs to be locked when operating registers
  video: rockchip: rga3: query job state when clearinga timeout job
  video: rockchip: rga3: support querying hardware work cycle
  arm64: rockchip_linux_defconfig: Disable AMPERE/A520 erratum
  ARM: dts: rockchip: Sort dtb entries in Makefile
  video: rockchip: mpp: optimize the schedule of enc/dec
  drm/rockchip: dsi2: optimize drive probe process

Change-Id: I84f64cb3f5c978fdaf3ce313a445fd551c960f3a
This commit is contained in:
Tao Huang
2024-05-24 19:48:08 +08:00
27 changed files with 220 additions and 181 deletions

View File

@@ -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 \

View File

@@ -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

View File

@@ -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)

View File

@@ -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[] = {

View File

@@ -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)

View File

@@ -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) {

View File

@@ -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);
}

View File

@@ -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,

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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

View File

@@ -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);
};

View File

@@ -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,
};

View File

@@ -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,
};

View File

@@ -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;
}
}