From 973a5909e99d0301a8832ca0cf07f9be01c4e97a Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Thu, 23 Apr 2020 12:42:24 -0400 Subject: [PATCH 001/109] Revert "drm/dp_mst: Remove single tx msg restriction." This reverts commit 6bb0942e8f46863a745489cce27efe5be2a3885e. Unfortunately it would appear that the rumors we've heard of sideband message interleaving not being very well supported are true. On the Lenovo ThinkPad Thunderbolt 3 dock that I have, interleaved messages appear to just get dropped: [drm:drm_dp_mst_wait_tx_reply [drm_kms_helper]] timedout msg send 00000000571ddfd0 2 1 [dp_mst] txmsg cur_offset=2 cur_len=2 seqno=1 state=SENT path_msg=1 dst=00 [dp_mst] type=ENUM_PATH_RESOURCES contents: [dp_mst] port=2 DP descriptor for this hub: OUI 90-cc-24 dev-ID SYNA3 HW-rev 1.0 SW-rev 3.12 quirks 0x0008 It would seem like as well that this is a somewhat well known issue in the field. From section 5.4.2 of the DisplayPort 2.0 specification: There are MST Sink/Branch devices in the field that do not handle interleaved message transactions. To facilitate message transaction handling by downstream devices, an MST Source device shall generate message transactions in an atomic manner (i.e., the MST Source device shall not concurrently interleave multiple message transactions). Therefore, an MST Source device shall clear the Message_Sequence_No value in the Sideband_MSG_Header to 0. MST Source devices that support field policy updates by way of software should update the policy to forego the generation of interleaved message transactions. This is a bit disappointing, as features like HDCP require that we send a sideband request every ~2 seconds for each active stream. However, there isn't really anything in the specification that allows us to accurately probe for interleaved messages. If it ends up being that we -really- need this in the future, we might be able to whitelist hubs where interleaving is known to work-or maybe try some sort of heuristics. But for now, let's just play it safe and not use it. Signed-off-by: Lyude Paul Fixes: 6bb0942e8f46 ("drm/dp_mst: Remove single tx msg restriction.") Cc: Wayne Lin Cc: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20200423164225.680178-1-lyude@redhat.com Reviewed-by: Sean Paul --- drivers/gpu/drm/drm_dp_mst_topology.c | 14 ++++++++++++-- include/drm/drm_dp_mst_helper.h | 5 +++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 13213c4b77d1..d2c19791b2b6 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -1205,6 +1205,8 @@ static int drm_dp_mst_wait_tx_reply(struct drm_dp_mst_branch *mstb, txmsg->state == DRM_DP_SIDEBAND_TX_SENT) { mstb->tx_slots[txmsg->seqno] = NULL; } + mgr->is_waiting_for_dwn_reply = false; + } out: if (unlikely(ret == -EIO) && drm_debug_enabled(DRM_UT_DP)) { @@ -1214,6 +1216,7 @@ out: } mutex_unlock(&mgr->qlock); + drm_dp_mst_kick_tx(mgr); return ret; } @@ -2789,9 +2792,11 @@ static void process_single_down_tx_qlock(struct drm_dp_mst_topology_mgr *mgr) ret = process_single_tx_qlock(mgr, txmsg, false); if (ret == 1) { /* txmsg is sent it should be in the slots now */ + mgr->is_waiting_for_dwn_reply = true; list_del(&txmsg->next); } else if (ret) { DRM_DEBUG_KMS("failed to send msg in q %d\n", ret); + mgr->is_waiting_for_dwn_reply = false; list_del(&txmsg->next); if (txmsg->seqno != -1) txmsg->dst->tx_slots[txmsg->seqno] = NULL; @@ -2831,7 +2836,8 @@ static void drm_dp_queue_down_tx(struct drm_dp_mst_topology_mgr *mgr, drm_dp_mst_dump_sideband_msg_tx(&p, txmsg); } - if (list_is_singular(&mgr->tx_msg_downq)) + if (list_is_singular(&mgr->tx_msg_downq) && + !mgr->is_waiting_for_dwn_reply) process_single_down_tx_qlock(mgr); mutex_unlock(&mgr->qlock); } @@ -3823,6 +3829,7 @@ static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr) mutex_lock(&mgr->qlock); txmsg->state = DRM_DP_SIDEBAND_TX_RX; mstb->tx_slots[seqno] = NULL; + mgr->is_waiting_for_dwn_reply = false; mutex_unlock(&mgr->qlock); wake_up_all(&mgr->tx_waitq); @@ -3830,6 +3837,9 @@ static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr) return 0; out_clear_reply: + mutex_lock(&mgr->qlock); + mgr->is_waiting_for_dwn_reply = false; + mutex_unlock(&mgr->qlock); if (msg) memset(msg, 0, sizeof(struct drm_dp_sideband_msg_rx)); out: @@ -4682,7 +4692,7 @@ static void drm_dp_tx_work(struct work_struct *work) struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, tx_work); mutex_lock(&mgr->qlock); - if (!list_empty(&mgr->tx_msg_downq)) + if (!list_empty(&mgr->tx_msg_downq) && !mgr->is_waiting_for_dwn_reply) process_single_down_tx_qlock(mgr); mutex_unlock(&mgr->qlock); } diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index 2d7c26592c05..96bcf33c03d3 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -592,6 +592,11 @@ struct drm_dp_mst_topology_mgr { */ bool payload_id_table_cleared : 1; + /** + * @is_waiting_for_dwn_reply: whether we're waiting for a down reply. + */ + bool is_waiting_for_dwn_reply : 1; + /** * @mst_primary: Pointer to the primary/first branch device. */ From 21d81f888299715ce6e1f0a04506aeb7c6012660 Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Tue, 21 Apr 2020 23:51:36 +0100 Subject: [PATCH 002/109] drm/lima: Clean up IRQ warnings Use the optional form of platform_get_irq() for blocks that legitimately may not be present, to avoid getting an annoying barrage of spurious warnings for non-existent PPs on configurations like Mali-450 MP2. Signed-off-by: Robin Murphy Signed-off-by: Qiang Yu Link: https://patchwork.freedesktop.org/patch/msgid/de475904091400ef6c123285f221094654d96d35.1587509150.git.robin.murphy@arm.com --- drivers/gpu/drm/lima/lima_device.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c index 247f51fd40a2..c334d297796a 100644 --- a/drivers/gpu/drm/lima/lima_device.c +++ b/drivers/gpu/drm/lima/lima_device.c @@ -171,8 +171,10 @@ static void lima_regulator_fini(struct lima_device *dev) static int lima_init_ip(struct lima_device *dev, int index) { + struct platform_device *pdev = to_platform_device(dev->dev); struct lima_ip_desc *desc = lima_ip_desc + index; struct lima_ip *ip = dev->ip + index; + const char *irq_name = desc->irq_name; int offset = desc->offset[dev->id]; bool must = desc->must_have[dev->id]; int err; @@ -183,8 +185,9 @@ static int lima_init_ip(struct lima_device *dev, int index) ip->dev = dev; ip->id = index; ip->iomem = dev->iomem + offset; - if (desc->irq_name) { - err = platform_get_irq_byname(dev->pdev, desc->irq_name); + if (irq_name) { + err = must ? platform_get_irq_byname(pdev, irq_name) : + platform_get_irq_byname_optional(pdev, irq_name); if (err < 0) goto out; ip->irq = err; From 2ce216edf2c661fd9d2f5e19ce72fd80c25abc64 Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Tue, 21 Apr 2020 23:51:37 +0100 Subject: [PATCH 003/109] drm/lima: Clean up redundant pdev pointer There's no point explicitly tracking the platform device when it can be trivially derived from the regular device pointer in the couple of places it's ever used. Signed-off-by: Robin Murphy Signed-off-by: Qiang Yu Link: https://patchwork.freedesktop.org/patch/msgid/8d9073cc91c10fc70910587fd1794e0e8f32b467.1587509150.git.robin.murphy@arm.com --- drivers/gpu/drm/lima/lima_devfreq.c | 7 +++---- drivers/gpu/drm/lima/lima_device.c | 5 ++--- drivers/gpu/drm/lima/lima_device.h | 1 - drivers/gpu/drm/lima/lima_drv.c | 1 - 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/lima/lima_devfreq.c b/drivers/gpu/drm/lima/lima_devfreq.c index 8c4d21d07529..1d479b5924fe 100644 --- a/drivers/gpu/drm/lima/lima_devfreq.c +++ b/drivers/gpu/drm/lima/lima_devfreq.c @@ -101,13 +101,12 @@ void lima_devfreq_fini(struct lima_device *ldev) } if (devfreq->devfreq) { - devm_devfreq_remove_device(&ldev->pdev->dev, - devfreq->devfreq); + devm_devfreq_remove_device(ldev->dev, devfreq->devfreq); devfreq->devfreq = NULL; } if (devfreq->opp_of_table_added) { - dev_pm_opp_of_remove_table(&ldev->pdev->dev); + dev_pm_opp_of_remove_table(ldev->dev); devfreq->opp_of_table_added = false; } @@ -125,7 +124,7 @@ void lima_devfreq_fini(struct lima_device *ldev) int lima_devfreq_init(struct lima_device *ldev) { struct thermal_cooling_device *cooling; - struct device *dev = &ldev->pdev->dev; + struct device *dev = ldev->dev; struct opp_table *opp_table; struct devfreq *devfreq; struct lima_devfreq *ldevfreq = &ldev->devfreq; diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c index c334d297796a..29285dedd124 100644 --- a/drivers/gpu/drm/lima/lima_device.c +++ b/drivers/gpu/drm/lima/lima_device.c @@ -297,8 +297,8 @@ static void lima_fini_pp_pipe(struct lima_device *dev) int lima_device_init(struct lima_device *ldev) { + struct platform_device *pdev = to_platform_device(ldev->dev); int err, i; - struct resource *res; dma_set_coherent_mask(ldev->dev, DMA_BIT_MASK(32)); @@ -329,8 +329,7 @@ int lima_device_init(struct lima_device *ldev) } else ldev->va_end = LIMA_VA_RESERVE_END; - res = platform_get_resource(ldev->pdev, IORESOURCE_MEM, 0); - ldev->iomem = devm_ioremap_resource(ldev->dev, res); + ldev->iomem = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(ldev->iomem)) { dev_err(ldev->dev, "fail to ioremap iomem\n"); err = PTR_ERR(ldev->iomem); diff --git a/drivers/gpu/drm/lima/lima_device.h b/drivers/gpu/drm/lima/lima_device.h index 06fd9636dd72..99b1fb147dad 100644 --- a/drivers/gpu/drm/lima/lima_device.h +++ b/drivers/gpu/drm/lima/lima_device.h @@ -76,7 +76,6 @@ enum lima_pipe_id { struct lima_device { struct device *dev; struct drm_device *ddev; - struct platform_device *pdev; enum lima_gpu_id id; u32 gp_version; diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c index bbbdc8455e2f..4e5dd75822c0 100644 --- a/drivers/gpu/drm/lima/lima_drv.c +++ b/drivers/gpu/drm/lima/lima_drv.c @@ -380,7 +380,6 @@ static int lima_pdev_probe(struct platform_device *pdev) goto err_out0; } - ldev->pdev = pdev; ldev->dev = &pdev->dev; ldev->id = (enum lima_gpu_id)of_device_get_match_data(&pdev->dev); From 4eda21d61904f75cda7635b3c225b7141c2ef20c Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Tue, 21 Apr 2020 21:35:42 +0800 Subject: [PATCH 004/109] drm/lima: use module_platform_driver helper Simplify module init/exit with module_platform_driver. Tested-by: Bhushan Shah Reviewed-by: Vasily Khoruzhick Signed-off-by: Qiang Yu Link: https://patchwork.freedesktop.org/patch/msgid/20200421133551.31481-2-yuq825@gmail.com --- drivers/gpu/drm/lima/lima_drv.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c index 4e5dd75822c0..3d63d496cfc2 100644 --- a/drivers/gpu/drm/lima/lima_drv.c +++ b/drivers/gpu/drm/lima/lima_drv.c @@ -460,17 +460,7 @@ static struct platform_driver lima_platform_driver = { }, }; -static int __init lima_init(void) -{ - return platform_driver_register(&lima_platform_driver); -} -module_init(lima_init); - -static void __exit lima_exit(void) -{ - platform_driver_unregister(&lima_platform_driver); -} -module_exit(lima_exit); +module_platform_driver(lima_platform_driver); MODULE_AUTHOR("Lima Project Developers"); MODULE_DESCRIPTION("Lima DRM Driver"); From d04f2a8e5b190c277663865311ecd6a393abf3b9 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Tue, 21 Apr 2020 21:35:43 +0800 Subject: [PATCH 005/109] drm/lima: print process name and pid when task error When error task list is full, print the process info where the error task come from for debug usage. Tested-by: Bhushan Shah Reviewed-by: Vasily Khoruzhick Signed-off-by: Qiang Yu Link: https://patchwork.freedesktop.org/patch/msgid/20200421133551.31481-3-yuq825@gmail.com --- drivers/gpu/drm/lima/lima_sched.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c index a2db1c937424..387f9439450a 100644 --- a/drivers/gpu/drm/lima/lima_sched.c +++ b/drivers/gpu/drm/lima/lima_sched.c @@ -285,7 +285,8 @@ static void lima_sched_build_error_task_list(struct lima_sched_task *task) mutex_lock(&dev->error_task_list_lock); if (dev->dump.num_tasks >= lima_max_error_tasks) { - dev_info(dev->dev, "fail to save task state: error task list is full\n"); + dev_info(dev->dev, "fail to save task state from %s pid %d: " + "error task list is full\n", ctx->pname, ctx->pid); goto out; } From 24943269e51bb6fd2810e71597b675878369e06b Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Tue, 21 Apr 2020 21:35:44 +0800 Subject: [PATCH 006/109] drm/lima: check vm != NULL in lima_vm_put No need to handle this check before calling lima_vm_put. Tested-by: Bhushan Shah Reviewed-by: Vasily Khoruzhick Signed-off-by: Qiang Yu Link: https://patchwork.freedesktop.org/patch/msgid/20200421133551.31481-4-yuq825@gmail.com --- drivers/gpu/drm/lima/lima_sched.c | 7 ++----- drivers/gpu/drm/lima/lima_vm.h | 3 ++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c index 387f9439450a..3ac5797e31fc 100644 --- a/drivers/gpu/drm/lima/lima_sched.c +++ b/drivers/gpu/drm/lima/lima_sched.c @@ -252,8 +252,7 @@ static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job) lima_mmu_switch_vm(pipe->mmu[i], vm); } - if (last_vm) - lima_vm_put(last_vm); + lima_vm_put(last_vm); trace_lima_task_run(task); @@ -416,9 +415,7 @@ static void lima_sched_timedout_job(struct drm_sched_job *job) lima_mmu_page_fault_resume(pipe->mmu[i]); } - if (pipe->current_vm) - lima_vm_put(pipe->current_vm); - + lima_vm_put(pipe->current_vm); pipe->current_vm = NULL; pipe->current_task = NULL; diff --git a/drivers/gpu/drm/lima/lima_vm.h b/drivers/gpu/drm/lima/lima_vm.h index 22aeec77d84d..3a7c74822d8b 100644 --- a/drivers/gpu/drm/lima/lima_vm.h +++ b/drivers/gpu/drm/lima/lima_vm.h @@ -54,7 +54,8 @@ static inline struct lima_vm *lima_vm_get(struct lima_vm *vm) static inline void lima_vm_put(struct lima_vm *vm) { - kref_put(&vm->refcount, lima_vm_release); + if (vm) + kref_put(&vm->refcount, lima_vm_release); } void lima_vm_print(struct lima_vm *vm); From 4eb70cd3f284e200c9e526bdd60ed720d5ab9e5c Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Tue, 21 Apr 2020 21:35:45 +0800 Subject: [PATCH 007/109] drm/lima: always set page directory when switch vm We need to flush TLB anyway before every task start, and the page directory will be set to empty vm after suspend/resume, so always set it to the task vm even no ctx switch happens. Tested-by: Bhushan Shah Reviewed-by: Vasily Khoruzhick Signed-off-by: Qiang Yu Link: https://patchwork.freedesktop.org/patch/msgid/20200421133551.31481-5-yuq825@gmail.com --- drivers/gpu/drm/lima/lima_mmu.c | 3 +-- drivers/gpu/drm/lima/lima_sched.c | 14 ++++---------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/lima/lima_mmu.c b/drivers/gpu/drm/lima/lima_mmu.c index f79d2af427e7..c26b751b0f9d 100644 --- a/drivers/gpu/drm/lima/lima_mmu.c +++ b/drivers/gpu/drm/lima/lima_mmu.c @@ -113,8 +113,7 @@ void lima_mmu_switch_vm(struct lima_ip *ip, struct lima_vm *vm) LIMA_MMU_STATUS, v, v & LIMA_MMU_STATUS_STALL_ACTIVE); - if (vm) - mmu_write(LIMA_MMU_DTE_ADDR, vm->pd.dma); + mmu_write(LIMA_MMU_DTE_ADDR, vm->pd.dma); /* flush the TLB */ mmu_write(LIMA_MMU_COMMAND, LIMA_MMU_COMMAND_ZAP_CACHE); diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c index 3ac5797e31fc..eb46db0717cd 100644 --- a/drivers/gpu/drm/lima/lima_sched.c +++ b/drivers/gpu/drm/lima/lima_sched.c @@ -200,7 +200,6 @@ static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job) struct lima_sched_pipe *pipe = to_lima_pipe(job->sched); struct lima_fence *fence; struct dma_fence *ret; - struct lima_vm *vm = NULL, *last_vm = NULL; int i; /* after GPU reset */ @@ -239,21 +238,16 @@ static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job) for (i = 0; i < pipe->num_l2_cache; i++) lima_l2_cache_flush(pipe->l2_cache[i]); - if (task->vm != pipe->current_vm) { - vm = lima_vm_get(task->vm); - last_vm = pipe->current_vm; - pipe->current_vm = task->vm; - } + lima_vm_put(pipe->current_vm); + pipe->current_vm = lima_vm_get(task->vm); if (pipe->bcast_mmu) - lima_mmu_switch_vm(pipe->bcast_mmu, vm); + lima_mmu_switch_vm(pipe->bcast_mmu, pipe->current_vm); else { for (i = 0; i < pipe->num_mmu; i++) - lima_mmu_switch_vm(pipe->mmu[i], vm); + lima_mmu_switch_vm(pipe->mmu[i], pipe->current_vm); } - lima_vm_put(last_vm); - trace_lima_task_run(task); pipe->error = false; From 4836cf044d74eb70bb28d3460d8c82e4aaf56d65 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Tue, 21 Apr 2020 21:35:46 +0800 Subject: [PATCH 008/109] drm/lima: add lima_devfreq_resume/suspend Used for device resume/suspend in the following commits. Tested-by: Bhushan Shah Reviewed-by: Vasily Khoruzhick Signed-off-by: Qiang Yu Link: https://patchwork.freedesktop.org/patch/msgid/20200421133551.31481-6-yuq825@gmail.com --- drivers/gpu/drm/lima/lima_devfreq.c | 24 ++++++++++++++++++++++++ drivers/gpu/drm/lima/lima_devfreq.h | 3 +++ 2 files changed, 27 insertions(+) diff --git a/drivers/gpu/drm/lima/lima_devfreq.c b/drivers/gpu/drm/lima/lima_devfreq.c index 1d479b5924fe..bbe02817721b 100644 --- a/drivers/gpu/drm/lima/lima_devfreq.c +++ b/drivers/gpu/drm/lima/lima_devfreq.c @@ -231,3 +231,27 @@ void lima_devfreq_record_idle(struct lima_devfreq *devfreq) spin_unlock_irqrestore(&devfreq->lock, irqflags); } + +int lima_devfreq_resume(struct lima_devfreq *devfreq) +{ + unsigned long irqflags; + + if (!devfreq->devfreq) + return 0; + + spin_lock_irqsave(&devfreq->lock, irqflags); + + lima_devfreq_reset(devfreq); + + spin_unlock_irqrestore(&devfreq->lock, irqflags); + + return devfreq_resume_device(devfreq->devfreq); +} + +int lima_devfreq_suspend(struct lima_devfreq *devfreq) +{ + if (!devfreq->devfreq) + return 0; + + return devfreq_suspend_device(devfreq->devfreq); +} diff --git a/drivers/gpu/drm/lima/lima_devfreq.h b/drivers/gpu/drm/lima/lima_devfreq.h index 8d71ba9fb22a..5eed2975a375 100644 --- a/drivers/gpu/drm/lima/lima_devfreq.h +++ b/drivers/gpu/drm/lima/lima_devfreq.h @@ -38,4 +38,7 @@ void lima_devfreq_fini(struct lima_device *ldev); void lima_devfreq_record_busy(struct lima_devfreq *devfreq); void lima_devfreq_record_idle(struct lima_devfreq *devfreq); +int lima_devfreq_resume(struct lima_devfreq *devfreq); +int lima_devfreq_suspend(struct lima_devfreq *devfreq); + #endif From 9f5072a191a141dcc919125986ea22bf05d598a7 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Tue, 21 Apr 2020 21:35:47 +0800 Subject: [PATCH 009/109] drm/lima: power down ip blocks when pmu exit Prepare resume/suspend PM. v2: Fix lima_pmu_wait_cmd timeout when mali400 case. Tested-by: Bhushan Shah Reviewed-by: Vasily Khoruzhick Signed-off-by: Qiang Yu Link: https://patchwork.freedesktop.org/patch/msgid/20200421133551.31481-7-yuq825@gmail.com --- drivers/gpu/drm/lima/lima_device.h | 2 ++ drivers/gpu/drm/lima/lima_pmu.c | 53 +++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/lima/lima_device.h b/drivers/gpu/drm/lima/lima_device.h index 99b1fb147dad..9cd2718079bd 100644 --- a/drivers/gpu/drm/lima/lima_device.h +++ b/drivers/gpu/drm/lima/lima_device.h @@ -64,6 +64,8 @@ struct lima_ip { bool async_reset; /* l2 cache */ spinlock_t lock; + /* pmu */ + u32 mask; } data; }; diff --git a/drivers/gpu/drm/lima/lima_pmu.c b/drivers/gpu/drm/lima/lima_pmu.c index 571f6d661581..d476569f2043 100644 --- a/drivers/gpu/drm/lima/lima_pmu.c +++ b/drivers/gpu/drm/lima/lima_pmu.c @@ -21,7 +21,7 @@ static int lima_pmu_wait_cmd(struct lima_ip *ip) v, v & LIMA_PMU_INT_CMD_MASK, 100, 100000); if (err) { - dev_err(dev->dev, "timeout wait pmd cmd\n"); + dev_err(dev->dev, "timeout wait pmu cmd\n"); return err; } @@ -29,6 +29,40 @@ static int lima_pmu_wait_cmd(struct lima_ip *ip) return 0; } +static u32 lima_pmu_get_ip_mask(struct lima_ip *ip) +{ + struct lima_device *dev = ip->dev; + u32 ret = 0; + int i; + + ret |= LIMA_PMU_POWER_GP0_MASK; + + if (dev->id == lima_gpu_mali400) { + ret |= LIMA_PMU_POWER_L2_MASK; + for (i = 0; i < 4; i++) { + if (dev->ip[lima_ip_pp0 + i].present) + ret |= LIMA_PMU_POWER_PP_MASK(i); + } + } else { + if (dev->ip[lima_ip_pp0].present) + ret |= LIMA450_PMU_POWER_PP0_MASK; + for (i = lima_ip_pp1; i <= lima_ip_pp3; i++) { + if (dev->ip[i].present) { + ret |= LIMA450_PMU_POWER_PP13_MASK; + break; + } + } + for (i = lima_ip_pp4; i <= lima_ip_pp7; i++) { + if (dev->ip[i].present) { + ret |= LIMA450_PMU_POWER_PP47_MASK; + break; + } + } + } + + return ret; +} + int lima_pmu_init(struct lima_ip *ip) { int err; @@ -56,5 +90,22 @@ int lima_pmu_init(struct lima_ip *ip) void lima_pmu_fini(struct lima_ip *ip) { + u32 stat; + if (!ip->data.mask) + ip->data.mask = lima_pmu_get_ip_mask(ip); + + stat = ~pmu_read(LIMA_PMU_STATUS) & ip->data.mask; + if (stat) { + pmu_write(LIMA_PMU_POWER_DOWN, stat); + + /* Don't wait for interrupt on Mali400 if all domains are + * powered off because the HW won't generate an interrupt + * in this case. + */ + if (ip->dev->id == lima_gpu_mali400) + pmu_write(LIMA_PMU_INT_CLEAR, LIMA_PMU_INT_CMD_MASK); + else + lima_pmu_wait_cmd(ip); + } } From 3446d7e9883d70882568b0f7b6549835d51a8bc7 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Tue, 21 Apr 2020 21:35:48 +0800 Subject: [PATCH 010/109] drm/lima: add resume/suspend callback for each ip For called when PM do resume/suspend. Tested-by: Bhushan Shah Reviewed-by: Vasily Khoruzhick Signed-off-by: Qiang Yu Link: https://patchwork.freedesktop.org/patch/msgid/20200421133551.31481-8-yuq825@gmail.com --- drivers/gpu/drm/lima/lima_bcast.c | 25 ++++++++++++--- drivers/gpu/drm/lima/lima_bcast.h | 2 ++ drivers/gpu/drm/lima/lima_device.c | 4 +++ drivers/gpu/drm/lima/lima_device.h | 2 +- drivers/gpu/drm/lima/lima_dlbu.c | 17 +++++++++- drivers/gpu/drm/lima/lima_dlbu.h | 2 ++ drivers/gpu/drm/lima/lima_gp.c | 21 +++++++++++-- drivers/gpu/drm/lima/lima_gp.h | 2 ++ drivers/gpu/drm/lima/lima_l2_cache.c | 38 +++++++++++++++++------ drivers/gpu/drm/lima/lima_l2_cache.h | 2 ++ drivers/gpu/drm/lima/lima_mmu.c | 46 ++++++++++++++++++++-------- drivers/gpu/drm/lima/lima_mmu.h | 2 ++ drivers/gpu/drm/lima/lima_pmu.c | 24 +++++++++++++-- drivers/gpu/drm/lima/lima_pmu.h | 2 ++ drivers/gpu/drm/lima/lima_pp.c | 31 +++++++++++++++++-- drivers/gpu/drm/lima/lima_pp.h | 4 +++ 16 files changed, 187 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/lima/lima_bcast.c b/drivers/gpu/drm/lima/lima_bcast.c index 288398027bfa..fbc43f243c54 100644 --- a/drivers/gpu/drm/lima/lima_bcast.c +++ b/drivers/gpu/drm/lima/lima_bcast.c @@ -26,18 +26,33 @@ void lima_bcast_enable(struct lima_device *dev, int num_pp) bcast_write(LIMA_BCAST_BROADCAST_MASK, mask); } +static int lima_bcast_hw_init(struct lima_ip *ip) +{ + bcast_write(LIMA_BCAST_BROADCAST_MASK, ip->data.mask << 16); + bcast_write(LIMA_BCAST_INTERRUPT_MASK, ip->data.mask); + return 0; +} + +int lima_bcast_resume(struct lima_ip *ip) +{ + return lima_bcast_hw_init(ip); +} + +void lima_bcast_suspend(struct lima_ip *ip) +{ + +} + int lima_bcast_init(struct lima_ip *ip) { - int i, mask = 0; + int i; for (i = lima_ip_pp0; i <= lima_ip_pp7; i++) { if (ip->dev->ip[i].present) - mask |= 1 << (i - lima_ip_pp0); + ip->data.mask |= 1 << (i - lima_ip_pp0); } - bcast_write(LIMA_BCAST_BROADCAST_MASK, mask << 16); - bcast_write(LIMA_BCAST_INTERRUPT_MASK, mask); - return 0; + return lima_bcast_hw_init(ip); } void lima_bcast_fini(struct lima_ip *ip) diff --git a/drivers/gpu/drm/lima/lima_bcast.h b/drivers/gpu/drm/lima/lima_bcast.h index c47e58563d0a..465ee587bceb 100644 --- a/drivers/gpu/drm/lima/lima_bcast.h +++ b/drivers/gpu/drm/lima/lima_bcast.h @@ -6,6 +6,8 @@ struct lima_ip; +int lima_bcast_resume(struct lima_ip *ip); +void lima_bcast_suspend(struct lima_ip *ip); int lima_bcast_init(struct lima_ip *ip); void lima_bcast_fini(struct lima_ip *ip); diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c index 29285dedd124..a2d4ec75b3b3 100644 --- a/drivers/gpu/drm/lima/lima_device.c +++ b/drivers/gpu/drm/lima/lima_device.c @@ -25,6 +25,8 @@ struct lima_ip_desc { int (*init)(struct lima_ip *ip); void (*fini)(struct lima_ip *ip); + int (*resume)(struct lima_ip *ip); + void (*suspend)(struct lima_ip *ip); }; #define LIMA_IP_DESC(ipname, mst0, mst1, off0, off1, func, irq) \ @@ -41,6 +43,8 @@ struct lima_ip_desc { }, \ .init = lima_##func##_init, \ .fini = lima_##func##_fini, \ + .resume = lima_##func##_resume, \ + .suspend = lima_##func##_suspend, \ } static struct lima_ip_desc lima_ip_desc[lima_ip_num] = { diff --git a/drivers/gpu/drm/lima/lima_device.h b/drivers/gpu/drm/lima/lima_device.h index 9cd2718079bd..d9df1b45dfa9 100644 --- a/drivers/gpu/drm/lima/lima_device.h +++ b/drivers/gpu/drm/lima/lima_device.h @@ -64,7 +64,7 @@ struct lima_ip { bool async_reset; /* l2 cache */ spinlock_t lock; - /* pmu */ + /* pmu/bcast */ u32 mask; } data; }; diff --git a/drivers/gpu/drm/lima/lima_dlbu.c b/drivers/gpu/drm/lima/lima_dlbu.c index 8399ceffb94b..c1d5ea35daa7 100644 --- a/drivers/gpu/drm/lima/lima_dlbu.c +++ b/drivers/gpu/drm/lima/lima_dlbu.c @@ -42,7 +42,7 @@ void lima_dlbu_set_reg(struct lima_ip *ip, u32 *reg) dlbu_write(LIMA_DLBU_START_TILE_POS, reg[3]); } -int lima_dlbu_init(struct lima_ip *ip) +static int lima_dlbu_hw_init(struct lima_ip *ip) { struct lima_device *dev = ip->dev; @@ -52,6 +52,21 @@ int lima_dlbu_init(struct lima_ip *ip) return 0; } +int lima_dlbu_resume(struct lima_ip *ip) +{ + return lima_dlbu_hw_init(ip); +} + +void lima_dlbu_suspend(struct lima_ip *ip) +{ + +} + +int lima_dlbu_init(struct lima_ip *ip) +{ + return lima_dlbu_hw_init(ip); +} + void lima_dlbu_fini(struct lima_ip *ip) { diff --git a/drivers/gpu/drm/lima/lima_dlbu.h b/drivers/gpu/drm/lima/lima_dlbu.h index 16f877984466..be71daaaee89 100644 --- a/drivers/gpu/drm/lima/lima_dlbu.h +++ b/drivers/gpu/drm/lima/lima_dlbu.h @@ -12,6 +12,8 @@ void lima_dlbu_disable(struct lima_device *dev); void lima_dlbu_set_reg(struct lima_ip *ip, u32 *reg); +int lima_dlbu_resume(struct lima_ip *ip); +void lima_dlbu_suspend(struct lima_ip *ip); int lima_dlbu_init(struct lima_ip *ip); void lima_dlbu_fini(struct lima_ip *ip); diff --git a/drivers/gpu/drm/lima/lima_gp.c b/drivers/gpu/drm/lima/lima_gp.c index d8841c870d90..8dd501b7a3d0 100644 --- a/drivers/gpu/drm/lima/lima_gp.c +++ b/drivers/gpu/drm/lima/lima_gp.c @@ -274,6 +274,23 @@ static void lima_gp_print_version(struct lima_ip *ip) static struct kmem_cache *lima_gp_task_slab; static int lima_gp_task_slab_refcnt; +static int lima_gp_hw_init(struct lima_ip *ip) +{ + ip->data.async_reset = false; + lima_gp_soft_reset_async(ip); + return lima_gp_soft_reset_async_wait(ip); +} + +int lima_gp_resume(struct lima_ip *ip) +{ + return lima_gp_hw_init(ip); +} + +void lima_gp_suspend(struct lima_ip *ip) +{ + +} + int lima_gp_init(struct lima_ip *ip) { struct lima_device *dev = ip->dev; @@ -281,9 +298,7 @@ int lima_gp_init(struct lima_ip *ip) lima_gp_print_version(ip); - ip->data.async_reset = false; - lima_gp_soft_reset_async(ip); - err = lima_gp_soft_reset_async_wait(ip); + err = lima_gp_hw_init(ip); if (err) return err; diff --git a/drivers/gpu/drm/lima/lima_gp.h b/drivers/gpu/drm/lima/lima_gp.h index 516e5c1babbb..02ec9af78a51 100644 --- a/drivers/gpu/drm/lima/lima_gp.h +++ b/drivers/gpu/drm/lima/lima_gp.h @@ -7,6 +7,8 @@ struct lima_ip; struct lima_device; +int lima_gp_resume(struct lima_ip *ip); +void lima_gp_suspend(struct lima_ip *ip); int lima_gp_init(struct lima_ip *ip); void lima_gp_fini(struct lima_ip *ip); diff --git a/drivers/gpu/drm/lima/lima_l2_cache.c b/drivers/gpu/drm/lima/lima_l2_cache.c index 6873a7af5a5c..c4080a02957b 100644 --- a/drivers/gpu/drm/lima/lima_l2_cache.c +++ b/drivers/gpu/drm/lima/lima_l2_cache.c @@ -38,9 +38,35 @@ int lima_l2_cache_flush(struct lima_ip *ip) return ret; } +static int lima_l2_cache_hw_init(struct lima_ip *ip) +{ + int err; + + err = lima_l2_cache_flush(ip); + if (err) + return err; + + l2_cache_write(LIMA_L2_CACHE_ENABLE, + LIMA_L2_CACHE_ENABLE_ACCESS | + LIMA_L2_CACHE_ENABLE_READ_ALLOCATE); + l2_cache_write(LIMA_L2_CACHE_MAX_READS, 0x1c); + + return 0; +} + +int lima_l2_cache_resume(struct lima_ip *ip) +{ + return lima_l2_cache_hw_init(ip); +} + +void lima_l2_cache_suspend(struct lima_ip *ip) +{ + +} + int lima_l2_cache_init(struct lima_ip *ip) { - int i, err; + int i; u32 size; struct lima_device *dev = ip->dev; @@ -63,15 +89,7 @@ int lima_l2_cache_init(struct lima_ip *ip) 1 << (size & 0xff), 1 << ((size >> 24) & 0xff)); - err = lima_l2_cache_flush(ip); - if (err) - return err; - - l2_cache_write(LIMA_L2_CACHE_ENABLE, - LIMA_L2_CACHE_ENABLE_ACCESS|LIMA_L2_CACHE_ENABLE_READ_ALLOCATE); - l2_cache_write(LIMA_L2_CACHE_MAX_READS, 0x1c); - - return 0; + return lima_l2_cache_hw_init(ip); } void lima_l2_cache_fini(struct lima_ip *ip) diff --git a/drivers/gpu/drm/lima/lima_l2_cache.h b/drivers/gpu/drm/lima/lima_l2_cache.h index c63fb676ff14..1aeeefd53fb9 100644 --- a/drivers/gpu/drm/lima/lima_l2_cache.h +++ b/drivers/gpu/drm/lima/lima_l2_cache.h @@ -6,6 +6,8 @@ struct lima_ip; +int lima_l2_cache_resume(struct lima_ip *ip); +void lima_l2_cache_suspend(struct lima_ip *ip); int lima_l2_cache_init(struct lima_ip *ip); void lima_l2_cache_fini(struct lima_ip *ip); diff --git a/drivers/gpu/drm/lima/lima_mmu.c b/drivers/gpu/drm/lima/lima_mmu.c index c26b751b0f9d..a1ae6c252dc2 100644 --- a/drivers/gpu/drm/lima/lima_mmu.c +++ b/drivers/gpu/drm/lima/lima_mmu.c @@ -59,12 +59,44 @@ static irqreturn_t lima_mmu_irq_handler(int irq, void *data) return IRQ_HANDLED; } -int lima_mmu_init(struct lima_ip *ip) +static int lima_mmu_hw_init(struct lima_ip *ip) { struct lima_device *dev = ip->dev; int err; u32 v; + mmu_write(LIMA_MMU_COMMAND, LIMA_MMU_COMMAND_HARD_RESET); + err = lima_mmu_send_command(LIMA_MMU_COMMAND_HARD_RESET, + LIMA_MMU_DTE_ADDR, v, v == 0); + if (err) + return err; + + mmu_write(LIMA_MMU_INT_MASK, + LIMA_MMU_INT_PAGE_FAULT | LIMA_MMU_INT_READ_BUS_ERROR); + mmu_write(LIMA_MMU_DTE_ADDR, dev->empty_vm->pd.dma); + return lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_PAGING, + LIMA_MMU_STATUS, v, + v & LIMA_MMU_STATUS_PAGING_ENABLED); +} + +int lima_mmu_resume(struct lima_ip *ip) +{ + if (ip->id == lima_ip_ppmmu_bcast) + return 0; + + return lima_mmu_hw_init(ip); +} + +void lima_mmu_suspend(struct lima_ip *ip) +{ + +} + +int lima_mmu_init(struct lima_ip *ip) +{ + struct lima_device *dev = ip->dev; + int err; + if (ip->id == lima_ip_ppmmu_bcast) return 0; @@ -74,12 +106,6 @@ int lima_mmu_init(struct lima_ip *ip) return -EIO; } - mmu_write(LIMA_MMU_COMMAND, LIMA_MMU_COMMAND_HARD_RESET); - err = lima_mmu_send_command(LIMA_MMU_COMMAND_HARD_RESET, - LIMA_MMU_DTE_ADDR, v, v == 0); - if (err) - return err; - err = devm_request_irq(dev->dev, ip->irq, lima_mmu_irq_handler, IRQF_SHARED, lima_ip_name(ip), ip); if (err) { @@ -87,11 +113,7 @@ int lima_mmu_init(struct lima_ip *ip) return err; } - mmu_write(LIMA_MMU_INT_MASK, LIMA_MMU_INT_PAGE_FAULT | LIMA_MMU_INT_READ_BUS_ERROR); - mmu_write(LIMA_MMU_DTE_ADDR, dev->empty_vm->pd.dma); - return lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_PAGING, - LIMA_MMU_STATUS, v, - v & LIMA_MMU_STATUS_PAGING_ENABLED); + return lima_mmu_hw_init(ip); } void lima_mmu_fini(struct lima_ip *ip) diff --git a/drivers/gpu/drm/lima/lima_mmu.h b/drivers/gpu/drm/lima/lima_mmu.h index 4f8ccbebcba1..f0c97ac75ea0 100644 --- a/drivers/gpu/drm/lima/lima_mmu.h +++ b/drivers/gpu/drm/lima/lima_mmu.h @@ -7,6 +7,8 @@ struct lima_ip; struct lima_vm; +int lima_mmu_resume(struct lima_ip *ip); +void lima_mmu_suspend(struct lima_ip *ip); int lima_mmu_init(struct lima_ip *ip); void lima_mmu_fini(struct lima_ip *ip); diff --git a/drivers/gpu/drm/lima/lima_pmu.c b/drivers/gpu/drm/lima/lima_pmu.c index d476569f2043..e397e1146e96 100644 --- a/drivers/gpu/drm/lima/lima_pmu.c +++ b/drivers/gpu/drm/lima/lima_pmu.c @@ -63,7 +63,7 @@ static u32 lima_pmu_get_ip_mask(struct lima_ip *ip) return ret; } -int lima_pmu_init(struct lima_ip *ip) +static int lima_pmu_hw_init(struct lima_ip *ip) { int err; u32 stat; @@ -88,7 +88,7 @@ int lima_pmu_init(struct lima_ip *ip) return 0; } -void lima_pmu_fini(struct lima_ip *ip) +static void lima_pmu_hw_fini(struct lima_ip *ip) { u32 stat; @@ -109,3 +109,23 @@ void lima_pmu_fini(struct lima_ip *ip) lima_pmu_wait_cmd(ip); } } + +int lima_pmu_resume(struct lima_ip *ip) +{ + return lima_pmu_hw_init(ip); +} + +void lima_pmu_suspend(struct lima_ip *ip) +{ + lima_pmu_hw_fini(ip); +} + +int lima_pmu_init(struct lima_ip *ip) +{ + return lima_pmu_hw_init(ip); +} + +void lima_pmu_fini(struct lima_ip *ip) +{ + lima_pmu_hw_fini(ip); +} diff --git a/drivers/gpu/drm/lima/lima_pmu.h b/drivers/gpu/drm/lima/lima_pmu.h index a2a18775eb07..652dc7af3047 100644 --- a/drivers/gpu/drm/lima/lima_pmu.h +++ b/drivers/gpu/drm/lima/lima_pmu.h @@ -6,6 +6,8 @@ struct lima_ip; +int lima_pmu_resume(struct lima_ip *ip); +void lima_pmu_suspend(struct lima_ip *ip); int lima_pmu_init(struct lima_ip *ip); void lima_pmu_fini(struct lima_ip *ip); diff --git a/drivers/gpu/drm/lima/lima_pp.c b/drivers/gpu/drm/lima/lima_pp.c index 8fef224b93c8..33f01383409c 100644 --- a/drivers/gpu/drm/lima/lima_pp.c +++ b/drivers/gpu/drm/lima/lima_pp.c @@ -223,6 +223,23 @@ static void lima_pp_print_version(struct lima_ip *ip) lima_ip_name(ip), name, major, minor); } +static int lima_pp_hw_init(struct lima_ip *ip) +{ + ip->data.async_reset = false; + lima_pp_soft_reset_async(ip); + return lima_pp_soft_reset_async_wait(ip); +} + +int lima_pp_resume(struct lima_ip *ip) +{ + return lima_pp_hw_init(ip); +} + +void lima_pp_suspend(struct lima_ip *ip) +{ + +} + int lima_pp_init(struct lima_ip *ip) { struct lima_device *dev = ip->dev; @@ -230,9 +247,7 @@ int lima_pp_init(struct lima_ip *ip) lima_pp_print_version(ip); - ip->data.async_reset = false; - lima_pp_soft_reset_async(ip); - err = lima_pp_soft_reset_async_wait(ip); + err = lima_pp_hw_init(ip); if (err) return err; @@ -254,6 +269,16 @@ void lima_pp_fini(struct lima_ip *ip) } +int lima_pp_bcast_resume(struct lima_ip *ip) +{ + return 0; +} + +void lima_pp_bcast_suspend(struct lima_ip *ip) +{ + +} + int lima_pp_bcast_init(struct lima_ip *ip) { struct lima_device *dev = ip->dev; diff --git a/drivers/gpu/drm/lima/lima_pp.h b/drivers/gpu/drm/lima/lima_pp.h index bf60c77b2633..16ec96de15a9 100644 --- a/drivers/gpu/drm/lima/lima_pp.h +++ b/drivers/gpu/drm/lima/lima_pp.h @@ -7,9 +7,13 @@ struct lima_ip; struct lima_device; +int lima_pp_resume(struct lima_ip *ip); +void lima_pp_suspend(struct lima_ip *ip); int lima_pp_init(struct lima_ip *ip); void lima_pp_fini(struct lima_ip *ip); +int lima_pp_bcast_resume(struct lima_ip *ip); +void lima_pp_bcast_suspend(struct lima_ip *ip); int lima_pp_bcast_init(struct lima_ip *ip); void lima_pp_bcast_fini(struct lima_ip *ip); From 7a475eb470ac482306c9281b2faadf2cbfb6b84c Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Tue, 21 Apr 2020 21:35:49 +0800 Subject: [PATCH 011/109] drm/lima: separate clk/regulator enable/disable function For being used by both device init/fini and suspend/resume. Tested-by: Bhushan Shah Reviewed-by: Vasily Khoruzhick Signed-off-by: Qiang Yu Link: https://patchwork.freedesktop.org/patch/msgid/20200421133551.31481-9-yuq825@gmail.com --- drivers/gpu/drm/lima/lima_device.c | 105 +++++++++++++++++++---------- 1 file changed, 68 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c index a2d4ec75b3b3..1d9b7f415da1 100644 --- a/drivers/gpu/drm/lima/lima_device.c +++ b/drivers/gpu/drm/lima/lima_device.c @@ -81,26 +81,10 @@ const char *lima_ip_name(struct lima_ip *ip) return lima_ip_desc[ip->id].name; } -static int lima_clk_init(struct lima_device *dev) +static int lima_clk_enable(struct lima_device *dev) { int err; - dev->clk_bus = devm_clk_get(dev->dev, "bus"); - if (IS_ERR(dev->clk_bus)) { - err = PTR_ERR(dev->clk_bus); - if (err != -EPROBE_DEFER) - dev_err(dev->dev, "get bus clk failed %d\n", err); - return err; - } - - dev->clk_gpu = devm_clk_get(dev->dev, "core"); - if (IS_ERR(dev->clk_gpu)) { - err = PTR_ERR(dev->clk_gpu); - if (err != -EPROBE_DEFER) - dev_err(dev->dev, "get core clk failed %d\n", err); - return err; - } - err = clk_prepare_enable(dev->clk_bus); if (err) return err; @@ -109,15 +93,7 @@ static int lima_clk_init(struct lima_device *dev) if (err) goto error_out0; - dev->reset = devm_reset_control_array_get_optional_shared(dev->dev); - - if (IS_ERR(dev->reset)) { - err = PTR_ERR(dev->reset); - if (err != -EPROBE_DEFER) - dev_err(dev->dev, "get reset controller failed %d\n", - err); - goto error_out1; - } else if (dev->reset != NULL) { + if (dev->reset) { err = reset_control_deassert(dev->reset); if (err) { dev_err(dev->dev, @@ -135,14 +111,76 @@ error_out0: return err; } -static void lima_clk_fini(struct lima_device *dev) +static void lima_clk_disable(struct lima_device *dev) { - if (dev->reset != NULL) + if (dev->reset) reset_control_assert(dev->reset); clk_disable_unprepare(dev->clk_gpu); clk_disable_unprepare(dev->clk_bus); } +static int lima_clk_init(struct lima_device *dev) +{ + int err; + + dev->clk_bus = devm_clk_get(dev->dev, "bus"); + if (IS_ERR(dev->clk_bus)) { + err = PTR_ERR(dev->clk_bus); + if (err != -EPROBE_DEFER) + dev_err(dev->dev, "get bus clk failed %d\n", err); + dev->clk_bus = NULL; + return err; + } + + dev->clk_gpu = devm_clk_get(dev->dev, "core"); + if (IS_ERR(dev->clk_gpu)) { + err = PTR_ERR(dev->clk_gpu); + if (err != -EPROBE_DEFER) + dev_err(dev->dev, "get core clk failed %d\n", err); + dev->clk_gpu = NULL; + return err; + } + + dev->reset = devm_reset_control_array_get_optional_shared(dev->dev); + if (IS_ERR(dev->reset)) { + err = PTR_ERR(dev->reset); + if (err != -EPROBE_DEFER) + dev_err(dev->dev, "get reset controller failed %d\n", + err); + dev->reset = NULL; + return err; + } + + return lima_clk_enable(dev); +} + +static void lima_clk_fini(struct lima_device *dev) +{ + lima_clk_disable(dev); +} + +static int lima_regulator_enable(struct lima_device *dev) +{ + int ret; + + if (!dev->regulator) + return 0; + + ret = regulator_enable(dev->regulator); + if (ret < 0) { + dev_err(dev->dev, "failed to enable regulator: %d\n", ret); + return ret; + } + + return 0; +} + +static void lima_regulator_disable(struct lima_device *dev) +{ + if (dev->regulator) + regulator_disable(dev->regulator); +} + static int lima_regulator_init(struct lima_device *dev) { int ret; @@ -158,19 +196,12 @@ static int lima_regulator_init(struct lima_device *dev) return ret; } - ret = regulator_enable(dev->regulator); - if (ret < 0) { - dev_err(dev->dev, "failed to enable regulator: %d\n", ret); - return ret; - } - - return 0; + return lima_regulator_enable(dev); } static void lima_regulator_fini(struct lima_device *dev) { - if (dev->regulator) - regulator_disable(dev->regulator); + lima_regulator_disable(dev); } static int lima_init_ip(struct lima_device *dev, int index) From 63945d51490f16aede6d635e785faf56521e5e4a Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Tue, 21 Apr 2020 21:35:50 +0800 Subject: [PATCH 012/109] drm/lima: add pm resume/suspend ops Add driver pm system and runtime hardware resume/suspend ops. Note this won't enable runtime pm of the device yet. v2: Do clock and power gating when suspend/resume. Tested-by: Bhushan Shah Reviewed-by: Vasily Khoruzhick Signed-off-by: Qiang Yu Link: https://patchwork.freedesktop.org/patch/msgid/20200421133551.31481-10-yuq825@gmail.com --- drivers/gpu/drm/lima/lima_device.c | 90 ++++++++++++++++++++++++++++++ drivers/gpu/drm/lima/lima_device.h | 3 + drivers/gpu/drm/lima/lima_drv.c | 7 +++ 3 files changed, 100 insertions(+) diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c index 1d9b7f415da1..65fdca366e41 100644 --- a/drivers/gpu/drm/lima/lima_device.c +++ b/drivers/gpu/drm/lima/lima_device.c @@ -247,6 +247,27 @@ static void lima_fini_ip(struct lima_device *ldev, int index) desc->fini(ip); } +static int lima_resume_ip(struct lima_device *ldev, int index) +{ + struct lima_ip_desc *desc = lima_ip_desc + index; + struct lima_ip *ip = ldev->ip + index; + int ret = 0; + + if (ip->present) + ret = desc->resume(ip); + + return ret; +} + +static void lima_suspend_ip(struct lima_device *ldev, int index) +{ + struct lima_ip_desc *desc = lima_ip_desc + index; + struct lima_ip *ip = ldev->ip + index; + + if (ip->present) + desc->suspend(ip); +} + static int lima_init_gp_pipe(struct lima_device *dev) { struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp; @@ -441,3 +462,72 @@ void lima_device_fini(struct lima_device *ldev) lima_clk_fini(ldev); } + +int lima_device_resume(struct device *dev) +{ + struct lima_device *ldev = dev_get_drvdata(dev); + int i, err; + + err = lima_clk_enable(ldev); + if (err) { + dev_err(dev, "resume clk fail %d\n", err); + return err; + } + + err = lima_regulator_enable(ldev); + if (err) { + dev_err(dev, "resume regulator fail %d\n", err); + goto err_out0; + } + + for (i = 0; i < lima_ip_num; i++) { + err = lima_resume_ip(ldev, i); + if (err) { + dev_err(dev, "resume ip %d fail\n", i); + goto err_out1; + } + } + + err = lima_devfreq_resume(&ldev->devfreq); + if (err) { + dev_err(dev, "devfreq resume fail\n"); + goto err_out1; + } + + return 0; + +err_out1: + while (--i >= 0) + lima_suspend_ip(ldev, i); + lima_regulator_disable(ldev); +err_out0: + lima_clk_disable(ldev); + return err; +} + +int lima_device_suspend(struct device *dev) +{ + struct lima_device *ldev = dev_get_drvdata(dev); + int i, err; + + /* check any task running */ + for (i = 0; i < lima_pipe_num; i++) { + if (atomic_read(&ldev->pipe[i].base.hw_rq_count)) + return -EBUSY; + } + + err = lima_devfreq_suspend(&ldev->devfreq); + if (err) { + dev_err(dev, "devfreq suspend fail\n"); + return err; + } + + for (i = lima_ip_num - 1; i >= 0; i--) + lima_suspend_ip(ldev, i); + + lima_regulator_disable(ldev); + + lima_clk_disable(ldev); + + return 0; +} diff --git a/drivers/gpu/drm/lima/lima_device.h b/drivers/gpu/drm/lima/lima_device.h index d9df1b45dfa9..41b9d7b4bcc7 100644 --- a/drivers/gpu/drm/lima/lima_device.h +++ b/drivers/gpu/drm/lima/lima_device.h @@ -140,4 +140,7 @@ static inline int lima_poll_timeout(struct lima_ip *ip, lima_poll_func_t func, return 0; } +int lima_device_suspend(struct device *dev); +int lima_device_resume(struct device *dev); + #endif diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c index 3d63d496cfc2..f3fe0a2f764b 100644 --- a/drivers/gpu/drm/lima/lima_drv.c +++ b/drivers/gpu/drm/lima/lima_drv.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -451,11 +452,17 @@ static const struct of_device_id dt_match[] = { }; MODULE_DEVICE_TABLE(of, dt_match); +static const struct dev_pm_ops lima_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) + SET_RUNTIME_PM_OPS(lima_device_suspend, lima_device_resume, NULL) +}; + static struct platform_driver lima_platform_driver = { .probe = lima_pdev_probe, .remove = lima_pdev_remove, .driver = { .name = "lima", + .pm = &lima_pm_ops, .of_match_table = dt_match, }, }; From 50de2e9ebbc08e1ca27f9b3f0471d92abaaf834a Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Tue, 21 Apr 2020 21:35:51 +0800 Subject: [PATCH 013/109] drm/lima: enable runtime pm Enable runtime pm by default so GPU suspend when idle for 200ms. This value can be changed by autosuspend_delay_ms in device's power sysfs dir. On Allwinner H3 lima_device_resume takes ~40us and lima_device_suspend takes ~20us. Tested-by: Bhushan Shah Reviewed-by: Vasily Khoruzhick Signed-off-by: Qiang Yu Link: https://patchwork.freedesktop.org/patch/msgid/20200421133551.31481-11-yuq825@gmail.com --- drivers/gpu/drm/lima/lima_drv.c | 21 ++++++++++++---- drivers/gpu/drm/lima/lima_sched.c | 41 +++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c index f3fe0a2f764b..a831565af813 100644 --- a/drivers/gpu/drm/lima/lima_drv.c +++ b/drivers/gpu/drm/lima/lima_drv.c @@ -404,6 +404,12 @@ static int lima_pdev_probe(struct platform_device *pdev) goto err_out2; } + pm_runtime_set_active(ldev->dev); + pm_runtime_mark_last_busy(ldev->dev); + pm_runtime_set_autosuspend_delay(ldev->dev, 200); + pm_runtime_use_autosuspend(ldev->dev); + pm_runtime_enable(ldev->dev); + /* * Register the DRM device with the core and the connectors with * sysfs. @@ -412,17 +418,16 @@ static int lima_pdev_probe(struct platform_device *pdev) if (err < 0) goto err_out3; - platform_set_drvdata(pdev, ldev); - if (sysfs_create_bin_file(&ldev->dev->kobj, &lima_error_state_attr)) dev_warn(ldev->dev, "fail to create error state sysfs\n"); return 0; err_out3: - lima_device_fini(ldev); -err_out2: + pm_runtime_disable(ldev->dev); lima_devfreq_fini(ldev); +err_out2: + lima_device_fini(ldev); err_out1: drm_dev_put(ddev); err_out0: @@ -436,10 +441,16 @@ static int lima_pdev_remove(struct platform_device *pdev) struct drm_device *ddev = ldev->ddev; sysfs_remove_bin_file(&ldev->dev->kobj, &lima_error_state_attr); - platform_set_drvdata(pdev, NULL); + drm_dev_unregister(ddev); + + /* stop autosuspend to make sure device is in active state */ + pm_runtime_set_autosuspend_delay(ldev->dev, -1); + pm_runtime_disable(ldev->dev); + lima_devfreq_fini(ldev); lima_device_fini(ldev); + drm_dev_put(ddev); lima_sched_slab_fini(); return 0; diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c index eb46db0717cd..e6cefda00279 100644 --- a/drivers/gpu/drm/lima/lima_sched.c +++ b/drivers/gpu/drm/lima/lima_sched.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "lima_devfreq.h" #include "lima_drv.h" @@ -194,13 +195,36 @@ static struct dma_fence *lima_sched_dependency(struct drm_sched_job *job, return NULL; } +static int lima_pm_busy(struct lima_device *ldev) +{ + int ret; + + /* resume GPU if it has been suspended by runtime PM */ + ret = pm_runtime_get_sync(ldev->dev); + if (ret < 0) + return ret; + + lima_devfreq_record_busy(&ldev->devfreq); + return 0; +} + +static void lima_pm_idle(struct lima_device *ldev) +{ + lima_devfreq_record_idle(&ldev->devfreq); + + /* GPU can do auto runtime suspend */ + pm_runtime_mark_last_busy(ldev->dev); + pm_runtime_put_autosuspend(ldev->dev); +} + static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job) { struct lima_sched_task *task = to_lima_task(job); struct lima_sched_pipe *pipe = to_lima_pipe(job->sched); + struct lima_device *ldev = pipe->ldev; struct lima_fence *fence; struct dma_fence *ret; - int i; + int i, err; /* after GPU reset */ if (job->s_fence->finished.error < 0) @@ -209,6 +233,13 @@ static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job) fence = lima_fence_create(pipe); if (!fence) return NULL; + + err = lima_pm_busy(ldev); + if (err < 0) { + dma_fence_put(&fence->base); + return NULL; + } + task->fence = &fence->base; /* for caller usage of the fence, otherwise irq handler @@ -216,8 +247,6 @@ static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job) */ ret = dma_fence_get(task->fence); - lima_devfreq_record_busy(&pipe->ldev->devfreq); - pipe->current_task = task; /* this is needed for MMU to work correctly, otherwise GP/PP @@ -388,6 +417,7 @@ static void lima_sched_timedout_job(struct drm_sched_job *job) { struct lima_sched_pipe *pipe = to_lima_pipe(job->sched); struct lima_sched_task *task = to_lima_task(job); + struct lima_device *ldev = pipe->ldev; if (!pipe->error) DRM_ERROR("lima job timeout\n"); @@ -413,7 +443,7 @@ static void lima_sched_timedout_job(struct drm_sched_job *job) pipe->current_vm = NULL; pipe->current_task = NULL; - lima_devfreq_record_idle(&pipe->ldev->devfreq); + lima_pm_idle(ldev); drm_sched_resubmit_jobs(&pipe->base); drm_sched_start(&pipe->base, true); @@ -485,6 +515,7 @@ void lima_sched_pipe_fini(struct lima_sched_pipe *pipe) void lima_sched_pipe_task_done(struct lima_sched_pipe *pipe) { struct lima_sched_task *task = pipe->current_task; + struct lima_device *ldev = pipe->ldev; if (pipe->error) { if (task && task->recoverable) @@ -495,6 +526,6 @@ void lima_sched_pipe_task_done(struct lima_sched_pipe *pipe) pipe->task_fini(pipe); dma_fence_signal(task->fence); - lima_devfreq_record_idle(&pipe->ldev->devfreq); + lima_pm_idle(ldev); } } From 2f7b832fc9920b444c7a0c36005369147b9a003b Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Wed, 15 Apr 2020 19:27:23 +0200 Subject: [PATCH 014/109] drm/panel: simple: Add support for AUO G190EAN01 panel Add timings for the G190EAN01 dual channel LVDS panel. Signed-off-by: Sebastian Reichel Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200415172725.84257-2-sebastian.reichel@collabora.com --- .../bindings/display/panel/panel-simple.yaml | 2 ++ drivers/gpu/drm/panel/panel-simple.c | 33 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml index 989cb3ca6d58..a1daae98784e 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -57,6 +57,8 @@ properties: - auo,g133han01 # AU Optronics Corporation 18.5" FHD (1920x1080) TFT LCD panel - auo,g185han01 + # AU Optronics Corporation 19.0" (1280x1024) TFT LCD panel + - auo,g190ean01 # AU Optronics Corporation 31.5" FHD (1920x1080) TFT LCD panel - auo,p320hvn03 # AU Optronics Corporation 21.5" FHD (1920x1080) color TFT LCD panel diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 003b54ea90d5..cef344ada3b2 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -922,6 +922,36 @@ static const struct panel_desc auo_g185han01 = { .connector_type = DRM_MODE_CONNECTOR_LVDS, }; +static const struct display_timing auo_g190ean01_timings = { + .pixelclock = { 90000000, 108000000, 135000000 }, + .hactive = { 1280, 1280, 1280 }, + .hfront_porch = { 126, 184, 1266 }, + .hback_porch = { 84, 122, 844 }, + .hsync_len = { 70, 102, 704 }, + .vactive = { 1024, 1024, 1024 }, + .vfront_porch = { 4, 26, 76 }, + .vback_porch = { 2, 8, 25 }, + .vsync_len = { 2, 8, 25 }, +}; + +static const struct panel_desc auo_g190ean01 = { + .timings = &auo_g190ean01_timings, + .num_timings = 1, + .bpc = 8, + .size = { + .width = 376, + .height = 301, + }, + .delay = { + .prepare = 50, + .enable = 200, + .disable = 110, + .unprepare = 1000, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, +}; + static const struct display_timing auo_p320hvn03_timings = { .pixelclock = { 106000000, 148500000, 164000000 }, .hactive = { 1920, 1920, 1920 }, @@ -3486,6 +3516,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "auo,g185han01", .data = &auo_g185han01, + }, { + .compatible = "auo,g190ean01", + .data = &auo_g190ean01, }, { .compatible = "auo,p320hvn03", .data = &auo_p320hvn03, From d9ccd1f28246ff76d02a28ef745302b1954fa07e Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Wed, 15 Apr 2020 19:27:24 +0200 Subject: [PATCH 015/109] drm/panel: simple: Add support for AUO G156XTN01.0 panel Add timings for the AUO G156XTN01.0 panel. Signed-off-by: Sebastian Reichel Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200415172725.84257-3-sebastian.reichel@collabora.com --- .../bindings/display/panel/panel-simple.yaml | 2 ++ drivers/gpu/drm/panel/panel-simple.c | 28 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml index a1daae98784e..cc360deb7472 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -55,6 +55,8 @@ properties: - auo,g104sn02 # AU Optronics Corporation 13.3" FHD (1920x1080) TFT LCD panel - auo,g133han01 + # AU Optronics Corporation 15.6" (1366x768) TFT LCD panel + - auo,g156xtn01 # AU Optronics Corporation 18.5" FHD (1920x1080) TFT LCD panel - auo,g185han01 # AU Optronics Corporation 19.0" (1280x1024) TFT LCD panel diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index cef344ada3b2..33b8d0edb175 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -892,6 +892,31 @@ static const struct panel_desc auo_g133han01 = { .connector_type = DRM_MODE_CONNECTOR_LVDS, }; +static const struct drm_display_mode auo_g156xtn01_mode = { + .clock = 76000, + .hdisplay = 1366, + .hsync_start = 1366 + 33, + .hsync_end = 1366 + 33 + 67, + .htotal = 1560, + .vdisplay = 768, + .vsync_start = 768 + 4, + .vsync_end = 768 + 4 + 4, + .vtotal = 806, + .vrefresh = 60, +}; + +static const struct panel_desc auo_g156xtn01 = { + .modes = &auo_g156xtn01_mode, + .num_modes = 1, + .bpc = 8, + .size = { + .width = 344, + .height = 194, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, +}; + static const struct display_timing auo_g185han01_timings = { .pixelclock = { 120000000, 144000000, 175000000 }, .hactive = { 1920, 1920, 1920 }, @@ -3513,6 +3538,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "auo,g133han01", .data = &auo_g133han01, + }, { + .compatible = "auo,g156xtn01", + .data = &auo_g156xtn01, }, { .compatible = "auo,g185han01", .data = &auo_g185han01, From 03e909acd95afe5077e61fd2a9968000c329f7db Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Wed, 15 Apr 2020 19:27:25 +0200 Subject: [PATCH 016/109] drm/panel: simple: Add support for AUO G121EAN01.4 panel Add timings for the AUO G121EAN01.4 panel. Signed-off-by: Sebastian Reichel Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200415172725.84257-4-sebastian.reichel@collabora.com --- .../bindings/display/panel/panel-simple.yaml | 2 ++ drivers/gpu/drm/panel/panel-simple.c | 28 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml index cc360deb7472..8b356d04cd3c 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -53,6 +53,8 @@ properties: - auo,g101evn010 # AU Optronics Corporation 10.4" (800x600) color TFT LCD panel - auo,g104sn02 + # AU Optronics Corporation 12.1" (1280x800) TFT LCD panel + - auo,g121ean01 # AU Optronics Corporation 13.3" FHD (1920x1080) TFT LCD panel - auo,g133han01 # AU Optronics Corporation 15.6" (1366x768) TFT LCD panel diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 33b8d0edb175..17d22c5a0fc2 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -862,6 +862,31 @@ static const struct panel_desc auo_g104sn02 = { }, }; +static const struct drm_display_mode auo_g121ean01_mode = { + .clock = 66700, + .hdisplay = 1280, + .hsync_start = 1280 + 58, + .hsync_end = 1280 + 58 + 8, + .htotal = 1280 + 58 + 8 + 70, + .vdisplay = 800, + .vsync_start = 800 + 6, + .vsync_end = 800 + 6 + 4, + .vtotal = 800 + 6 + 4 + 10, + .vrefresh = 60, +}; + +static const struct panel_desc auo_g121ean01 = { + .modes = &auo_g121ean01_mode, + .num_modes = 1, + .bpc = 8, + .size = { + .width = 261, + .height = 163, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, +}; + static const struct display_timing auo_g133han01_timings = { .pixelclock = { 134000000, 141200000, 149000000 }, .hactive = { 1920, 1920, 1920 }, @@ -3535,6 +3560,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "auo,g104sn02", .data = &auo_g104sn02, + }, { + .compatible = "auo,g121ean01", + .data = &auo_g121ean01, }, { .compatible = "auo,g133han01", .data = &auo_g133han01, From a29b57e9df22d1b8bf3a7a8e5a2011a4ea44a967 Mon Sep 17 00:00:00 2001 From: Zheng Bin Date: Fri, 24 Apr 2020 16:02:24 +0800 Subject: [PATCH 017/109] drm/panel: ili9322: Remove unneeded semicolon Fixes coccicheck warning: drivers/gpu/drm/panel/panel-ilitek-ili9322.c:382:2-3: Unneeded semicolon drivers/gpu/drm/panel/panel-ilitek-ili9322.c:391:2-3: Unneeded semicolon Reported-by: Hulk Robot Signed-off-by: Zheng Bin Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200424080224.30763-1-zhengbin13@huawei.com --- drivers/gpu/drm/panel/panel-ilitek-ili9322.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9322.c b/drivers/gpu/drm/panel/panel-ilitek-ili9322.c index 09935520e606..873b1c7059bd 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9322.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9322.c @@ -379,7 +379,7 @@ static int ili9322_init(struct drm_panel *panel, struct ili9322 *ili) "can't set up VCOM amplitude (%d)\n", ret); return ret; } - }; + } if (ili->vcom_high != U8_MAX) { ret = regmap_write(ili->regmap, ILI9322_VCOM_HIGH, @@ -388,7 +388,7 @@ static int ili9322_init(struct drm_panel *panel, struct ili9322 *ili) dev_err(ili->dev, "can't set up VCOM high (%d)\n", ret); return ret; } - }; + } /* Set up gamma correction */ for (i = 0; i < ARRAY_SIZE(ili->gamma); i++) { From d53139b37f1037033c47cc552f2e6ce745c6a159 Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Thu, 16 Apr 2020 18:44:03 +0200 Subject: [PATCH 018/109] drm: panel: Set connector type for LP120UP1 The LP120UP1 is a eDP panel, set the connector type accordingly. Signed-off-by: Enric Balletbo i Serra Reviewed-by: Laurent Pinchart Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200416164404.2418426-1-enric.balletbo@collabora.com --- drivers/gpu/drm/panel/panel-simple.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 17d22c5a0fc2..efbe2764688d 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -2248,6 +2248,7 @@ static const struct panel_desc lg_lp120up1 = { .width = 267, .height = 183, }, + .connector_type = DRM_MODE_CONNECTOR_eDP, }; static const struct drm_display_mode lg_lp129qe_mode = { From 4606ed7ede0c1f8616c7d30cbf72230314888653 Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Thu, 16 Apr 2020 18:44:04 +0200 Subject: [PATCH 019/109] drm/bridge: ps8640: Let panel to set the connector type The panel connector type should be set by the panel not the bridge, so remove the connector_type assignment. Signed-off-by: Enric Balletbo i Serra Reviewed-by: Laurent Pinchart Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200416164404.2418426-2-enric.balletbo@collabora.com --- drivers/gpu/drm/bridge/parade-ps8640.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c b/drivers/gpu/drm/bridge/parade-ps8640.c index d3a53442d449..4b099196afeb 100644 --- a/drivers/gpu/drm/bridge/parade-ps8640.c +++ b/drivers/gpu/drm/bridge/parade-ps8640.c @@ -268,8 +268,6 @@ static int ps8640_probe(struct i2c_client *client) if (!panel) return -ENODEV; - panel->connector_type = DRM_MODE_CONNECTOR_eDP; - ps_bridge->panel_bridge = devm_drm_panel_bridge_add(dev, panel); if (IS_ERR(ps_bridge->panel_bridge)) return PTR_ERR(ps_bridge->panel_bridge); From 30be3031087139061de4421bf52015931eaab569 Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Thu, 16 Apr 2020 23:06:54 +0200 Subject: [PATCH 020/109] drm/bridge: panel: Return always an error pointer in drm_panel_bridge_add() Since commit 89958b7cd955 ("drm/bridge: panel: Infer connector type from panel by default"), drm_panel_bridge_add() and their variants can return NULL and an error pointer. This is fine but none of the actual users of the API are checking for the NULL value. Instead of change all the users, seems reasonable to return an error pointer instead. So change the returned value for those functions when the connector type is unknown. Suggested-by: Laurent Pinchart Signed-off-by: Enric Balletbo i Serra Reviewed-by: Laurent Pinchart Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200416210654.2468805-1-enric.balletbo@collabora.com --- drivers/gpu/drm/bridge/panel.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c index e933f1c47f5d..1e63ed6b18aa 100644 --- a/drivers/gpu/drm/bridge/panel.c +++ b/drivers/gpu/drm/bridge/panel.c @@ -166,7 +166,7 @@ static const struct drm_bridge_funcs panel_bridge_bridge_funcs = { * * The connector type is set to @panel->connector_type, which must be set to a * known type. Calling this function with a panel whose connector type is - * DRM_MODE_CONNECTOR_Unknown will return NULL. + * DRM_MODE_CONNECTOR_Unknown will return ERR_PTR(-EINVAL). * * See devm_drm_panel_bridge_add() for an automatically managed version of this * function. @@ -174,7 +174,7 @@ static const struct drm_bridge_funcs panel_bridge_bridge_funcs = { struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel) { if (WARN_ON(panel->connector_type == DRM_MODE_CONNECTOR_Unknown)) - return NULL; + return ERR_PTR(-EINVAL); return drm_panel_bridge_add_typed(panel, panel->connector_type); } @@ -265,7 +265,7 @@ struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev, struct drm_panel *panel) { if (WARN_ON(panel->connector_type == DRM_MODE_CONNECTOR_Unknown)) - return NULL; + return ERR_PTR(-EINVAL); return devm_drm_panel_bridge_add_typed(dev, panel, panel->connector_type); From 232f23e8cd97cc27e91a6e0f9cd055248abd329b Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 17 Apr 2020 08:53:28 +0200 Subject: [PATCH 021/109] dt-bindings: panel: Document some missing compatible strings Add missing compatible strings for the Panasonic and Chunghwa panels found on NVIDIA Dalmore and Cardhu boards. Signed-off-by: Thierry Reding Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200417065328.1578603-1-thierry.reding@gmail.com --- .../devicetree/bindings/display/panel/panel-simple-dsi.yaml | 2 ++ .../devicetree/bindings/display/panel/panel-simple.yaml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml index 423532f57e89..16778ce782fc 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml @@ -42,6 +42,8 @@ properties: # One Stop Displays OSD101T2587-53TS 10.1" 1920x1200 panel - osddisplays,osd101t2587-53ts # Panasonic 10" WUXGA TFT LCD panel + - panasonic,vvx10f004b00 + # Panasonic 10" WUXGA TFT LCD panel - panasonic,vvx10f034n00 reg: diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml index 8b356d04cd3c..6d2776d454f3 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -84,6 +84,8 @@ properties: # Chunghwa Picture Tubes Ltd. 10.1" WXGA TFT LCD panel - chunghwa,claa101wa01a # Chunghwa Picture Tubes Ltd. 10.1" WXGA TFT LCD panel + - chunghwa,claa101wb01 + # Chunghwa Picture Tubes Ltd. 10.1" WXGA TFT LCD panel - chunghwa,claa101wb03 # DataImage, Inc. 7" WVGA (800x480) TFT LCD panel with 24-bit parallel interface. - dataimage,scf0700c48ggu18 From 3d930aacd637cca551f216c61b2e1c455db58eb0 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Fri, 17 Apr 2020 18:14:01 +0800 Subject: [PATCH 022/109] drm/panel: remove set but not used variable 'config' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/gpu/drm/panel/panel-truly-nt35597.c:493:31: warning: variable ‘config’ set but not used [-Wunused-but-set-variable] const struct nt35597_config *config; ^~~~~~ Signed-off-by: YueHaibing Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200417101401.19388-1-yuehaibing@huawei.com --- drivers/gpu/drm/panel/panel-truly-nt35597.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-truly-nt35597.c b/drivers/gpu/drm/panel/panel-truly-nt35597.c index 012ca62bf30e..f0ad6081570f 100644 --- a/drivers/gpu/drm/panel/panel-truly-nt35597.c +++ b/drivers/gpu/drm/panel/panel-truly-nt35597.c @@ -490,9 +490,7 @@ static int truly_nt35597_panel_add(struct truly_nt35597 *ctx) { struct device *dev = ctx->dev; int ret, i; - const struct nt35597_config *config; - config = ctx->config; for (i = 0; i < ARRAY_SIZE(ctx->supplies); i++) ctx->supplies[i].supply = regulator_names[i]; From bc7f0b6d4ae41875557eeaa1ebd5d8ac1a8f3657 Mon Sep 17 00:00:00 2001 From: Souptick Joarder Date: Mon, 20 Apr 2020 23:57:24 +0530 Subject: [PATCH 023/109] video/fbdev/riva: Remove dead code These are dead code since 3.15. These can be removed forever if no plan to use it further. Signed-off-by: Souptick Joarder Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/1587407244-32574-1-git-send-email-jrdr.linux@gmail.com --- drivers/video/fbdev/riva/riva_hw.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/drivers/video/fbdev/riva/riva_hw.c b/drivers/video/fbdev/riva/riva_hw.c index 0601c13f2105..08c9ee46978e 100644 --- a/drivers/video/fbdev/riva/riva_hw.c +++ b/drivers/video/fbdev/riva/riva_hw.c @@ -1343,24 +1343,6 @@ int CalcStateExt /* * Load fixed function state and pre-calculated/stored state. */ -#if 0 -#define LOAD_FIXED_STATE(tbl,dev) \ - for (i = 0; i < sizeof(tbl##Table##dev)/8; i++) \ - chip->dev[tbl##Table##dev[i][0]] = tbl##Table##dev[i][1] -#define LOAD_FIXED_STATE_8BPP(tbl,dev) \ - for (i = 0; i < sizeof(tbl##Table##dev##_8BPP)/8; i++) \ - chip->dev[tbl##Table##dev##_8BPP[i][0]] = tbl##Table##dev##_8BPP[i][1] -#define LOAD_FIXED_STATE_15BPP(tbl,dev) \ - for (i = 0; i < sizeof(tbl##Table##dev##_15BPP)/8; i++) \ - chip->dev[tbl##Table##dev##_15BPP[i][0]] = tbl##Table##dev##_15BPP[i][1] -#define LOAD_FIXED_STATE_16BPP(tbl,dev) \ - for (i = 0; i < sizeof(tbl##Table##dev##_16BPP)/8; i++) \ - chip->dev[tbl##Table##dev##_16BPP[i][0]] = tbl##Table##dev##_16BPP[i][1] -#define LOAD_FIXED_STATE_32BPP(tbl,dev) \ - for (i = 0; i < sizeof(tbl##Table##dev##_32BPP)/8; i++) \ - chip->dev[tbl##Table##dev##_32BPP[i][0]] = tbl##Table##dev##_32BPP[i][1] -#endif - #define LOAD_FIXED_STATE(tbl,dev) \ for (i = 0; i < sizeof(tbl##Table##dev)/8; i++) \ NV_WR32(&chip->dev[tbl##Table##dev[i][0]], 0, tbl##Table##dev[i][1]) From 1a8afd1ef47c1fa4425b685d7dd3bcffe56209c3 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Mon, 20 Apr 2020 14:57:41 -0700 Subject: [PATCH 024/109] dt-bindings: display: simple: Add BOE NV133FHM-N61 Add the BOE NV133FHM-N61 13.3" FHD (1920x1080) TFT LCD Panel to the compatible list of panel-simple. Signed-off-by: Bjorn Andersson Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200420215742.1927498-1-bjorn.andersson@linaro.org --- .../devicetree/bindings/display/panel/panel-simple.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml index 6d2776d454f3..1e2abe5b0dce 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -73,6 +73,8 @@ properties: - boe,hv070wsa-100 # BOE OPTOELECTRONICS TECHNOLOGY 10.1" WXGA TFT LCD panel - boe,nv101wxmn51 + # BOE NV133FHM-N61 13.3" FHD (1920x1080) TFT LCD Panel + - boe,nv133fhm-n61 # BOE NV140FHM-N49 14.0" FHD a-Si FT panel - boe,nv140fhmn49 # CDTech(H.K.) Electronics Limited 4.3" 480x272 color TFT-LCD panel From b0c664cc80e8780fdc06cf2e1281d7fcc1ab536f Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Mon, 20 Apr 2020 14:57:42 -0700 Subject: [PATCH 025/109] panel: simple: Add BOE NV133FHM-N61 The BOE NV133FHM-N61 panel is a 13.3" 1920x1080 eDP panel, add support for it in panel-simple. Signed-off-by: Bjorn Andersson Signed-off-by: Sam Ravnborg [add boe_nv133fhm_n61_modes in alphabetical order] Link: https://patchwork.freedesktop.org/patch/msgid/20200420215742.1927498-2-bjorn.andersson@linaro.org --- drivers/gpu/drm/panel/panel-simple.c | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index efbe2764688d..00bfbc08f0ba 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -1172,6 +1172,36 @@ static const struct panel_desc boe_nv101wxmn51 = { }, }; +static const struct drm_display_mode boe_nv133fhm_n61_modes = { + .clock = 147840, + .hdisplay = 1920, + .hsync_start = 1920 + 48, + .hsync_end = 1920 + 48 + 32, + .htotal = 1920 + 48 + 32 + 200, + .vdisplay = 1080, + .vsync_start = 1080 + 3, + .vsync_end = 1080 + 3 + 6, + .vtotal = 1080 + 3 + 6 + 31, + .vrefresh = 60, +}; + +static const struct panel_desc boe_nv133fhm_n61 = { + .modes = &boe_nv133fhm_n61_modes, + .num_modes = 1, + .bpc = 8, + .size = { + .width = 300, + .height = 187, + }, + .delay = { + .hpd_absent_delay = 200, + .unprepare = 500, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X24, + .bus_flags = DRM_BUS_FLAG_DATA_MSB_TO_LSB, + .connector_type = DRM_MODE_CONNECTOR_eDP, +}; + static const struct drm_display_mode boe_nv140fhmn49_modes[] = { { .clock = 148500, @@ -3594,6 +3624,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "boe,nv101wxmn51", .data = &boe_nv101wxmn51, + }, { + .compatible = "boe,nv133fhm-n61", + .data = &boe_nv133fhm_n61, }, { .compatible = "boe,nv140fhmn49", .data = &boe_nv140fhmn49, From d08ffbeaa100100767ff6bd922a7b6448cb3c372 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Mon, 20 Apr 2020 14:57:27 -0700 Subject: [PATCH 026/109] dt-bindings: display: simple: Add IVO M133NWF4 R0 Define the vendor prefix for InfoVision Optoelectronics and add their M133NWF4 R0 13.3" FHD (1920x1080) TFT LCD panel to the compatible list of panel-simple. Signed-off-by: Bjorn Andersson Acked-by: Rob Herring [vendor-prefix] Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200420215728.1927434-1-bjorn.andersson@linaro.org --- .../devicetree/bindings/display/panel/panel-simple.yaml | 2 ++ Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml index 1e2abe5b0dce..fdd74d07f645 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -133,6 +133,8 @@ properties: - hannstar,hsd100pxn1 # Hitachi Ltd. Corporation 9" WVGA (800x480) TFT LCD panel - hit,tx23d38vm0caa + # InfoVision Optoelectronics M133NWF4 R0 13.3" FHD (1920x1080) TFT LCD panel + - ivo,m133nwf4-r0 # Innolux AT043TN24 4.3" WQVGA TFT LCD panel - innolux,at043tn24 # Innolux AT070TN92 7.0" WQVGA TFT LCD panel diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index d3891386d671..31012f91fb9a 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -463,6 +463,8 @@ patternProperties: description: Infineon Technologies "^inforce,.*": description: Inforce Computing + "^ivo,.*": + description: InfoVision Optoelectronics Kunshan Co. Ltd. "^ingenic,.*": description: Ingenic Semiconductor "^innolux,.*": From e1ca5184625d06b116816830333e745af00b26a6 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Mon, 20 Apr 2020 14:57:28 -0700 Subject: [PATCH 027/109] panel: simple: Add Ivo M133NWF4 R0 The InfoVision Optoelectronics M133NWF4 R0 panel is a 13.3" 1920x1080 eDP panel, add support for it in panel-simple. Signed-off-by: Bjorn Andersson Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200420215728.1927434-2-bjorn.andersson@linaro.org --- drivers/gpu/drm/panel/panel-simple.c | 34 ++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 00bfbc08f0ba..5e56c68fbd3e 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -2090,6 +2090,37 @@ static const struct panel_desc innolux_zj070na_01p = { }, }; +static const struct drm_display_mode ivo_m133nwf4_r0_mode = { + .clock = 138778, + .hdisplay = 1920, + .hsync_start = 1920 + 24, + .hsync_end = 1920 + 24 + 48, + .htotal = 1920 + 24 + 48 + 88, + .vdisplay = 1080, + .vsync_start = 1080 + 3, + .vsync_end = 1080 + 3 + 12, + .vtotal = 1080 + 3 + 12 + 17, + .vrefresh = 60, + .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, +}; + +static const struct panel_desc ivo_m133nwf4_r0 = { + .modes = &ivo_m133nwf4_r0_mode, + .num_modes = 1, + .bpc = 8, + .size = { + .width = 294, + .height = 165, + }, + .delay = { + .hpd_absent_delay = 200, + .unprepare = 500, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X24, + .bus_flags = DRM_BUS_FLAG_DATA_MSB_TO_LSB, + .connector_type = DRM_MODE_CONNECTOR_eDP, +}; + static const struct display_timing koe_tx14d24vm1bpa_timing = { .pixelclock = { 5580000, 5850000, 6200000 }, .hactive = { 320, 320, 320 }, @@ -3735,6 +3766,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "innolux,zj070na-01p", .data = &innolux_zj070na_01p, + }, { + .compatible = "ivo,m133nwf4-r0", + .data = &ivo_m133nwf4_r0, }, { .compatible = "koe,tx14d24vm1bpa", .data = &koe_tx14d24vm1bpa, From b430ff7ef8b016abcd8ebf8991920deb8750e351 Mon Sep 17 00:00:00 2001 From: Yannick Fertre Date: Fri, 28 Feb 2020 09:07:38 +0100 Subject: [PATCH 028/109] drm/stm: ltdc: check number of endpoints Number of endpoints could exceed the fix value MAX_ENDPOINTS(2). Instead of increase simply this value, the number of endpoint could be read from device tree. Load sequence has been a little rework to take care of several panel or bridge which can be connected/disconnected or enable/disable. Signed-off-by: Yannick Fertre Signed-off-by: Benjamin Gaignard Link: https://patchwork.freedesktop.org/patch/msgid/1582877258-1112-1-git-send-email-yannick.fertre@st.com --- drivers/gpu/drm/stm/ltdc.c | 102 +++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c index df585fe64f61..f894968d6e45 100644 --- a/drivers/gpu/drm/stm/ltdc.c +++ b/drivers/gpu/drm/stm/ltdc.c @@ -42,8 +42,6 @@ #define MAX_IRQ 4 -#define MAX_ENDPOINTS 2 - #define HWVER_10200 0x010200 #define HWVER_10300 0x010300 #define HWVER_20101 0x020101 @@ -1201,36 +1199,20 @@ int ltdc_load(struct drm_device *ddev) struct ltdc_device *ldev = ddev->dev_private; struct device *dev = ddev->dev; struct device_node *np = dev->of_node; - struct drm_bridge *bridge[MAX_ENDPOINTS] = {NULL}; - struct drm_panel *panel[MAX_ENDPOINTS] = {NULL}; + struct drm_bridge *bridge; + struct drm_panel *panel; struct drm_crtc *crtc; struct reset_control *rstc; struct resource *res; - int irq, ret, i, endpoint_not_ready = -ENODEV; + int irq, i, nb_endpoints; + int ret = -ENODEV; DRM_DEBUG_DRIVER("\n"); - /* Get endpoints if any */ - for (i = 0; i < MAX_ENDPOINTS; i++) { - ret = drm_of_find_panel_or_bridge(np, 0, i, &panel[i], - &bridge[i]); - - /* - * If at least one endpoint is -EPROBE_DEFER, defer probing, - * else if at least one endpoint is ready, continue probing. - */ - if (ret == -EPROBE_DEFER) - return ret; - else if (!ret) - endpoint_not_ready = 0; - } - - if (endpoint_not_ready) - return endpoint_not_ready; - - rstc = devm_reset_control_get_exclusive(dev, NULL); - - mutex_init(&ldev->err_lock); + /* Get number of endpoints */ + nb_endpoints = of_graph_get_endpoint_count(np); + if (!nb_endpoints) + return -ENODEV; ldev->pixel_clk = devm_clk_get(dev, "lcd"); if (IS_ERR(ldev->pixel_clk)) { @@ -1244,6 +1226,43 @@ int ltdc_load(struct drm_device *ddev) return -ENODEV; } + /* Get endpoints if any */ + for (i = 0; i < nb_endpoints; i++) { + ret = drm_of_find_panel_or_bridge(np, 0, i, &panel, &bridge); + + /* + * If at least one endpoint is -ENODEV, continue probing, + * else if at least one endpoint returned an error + * (ie -EPROBE_DEFER) then stop probing. + */ + if (ret == -ENODEV) + continue; + else if (ret) + goto err; + + if (panel) { + bridge = drm_panel_bridge_add_typed(panel, + DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(bridge)) { + DRM_ERROR("panel-bridge endpoint %d\n", i); + ret = PTR_ERR(bridge); + goto err; + } + } + + if (bridge) { + ret = ltdc_encoder_init(ddev, bridge); + if (ret) { + DRM_ERROR("init encoder endpoint %d\n", i); + goto err; + } + } + } + + rstc = devm_reset_control_get_exclusive(dev, NULL); + + mutex_init(&ldev->err_lock); + if (!IS_ERR(rstc)) { reset_control_assert(rstc); usleep_range(10, 20); @@ -1285,27 +1304,7 @@ int ltdc_load(struct drm_device *ddev) DRM_ERROR("Failed to register LTDC interrupt\n"); goto err; } - } - /* Add endpoints panels or bridges if any */ - for (i = 0; i < MAX_ENDPOINTS; i++) { - if (panel[i]) { - bridge[i] = drm_panel_bridge_add_typed(panel[i], - DRM_MODE_CONNECTOR_DPI); - if (IS_ERR(bridge[i])) { - DRM_ERROR("panel-bridge endpoint %d\n", i); - ret = PTR_ERR(bridge[i]); - goto err; - } - } - - if (bridge[i]) { - ret = ltdc_encoder_init(ddev, bridge[i]); - if (ret) { - DRM_ERROR("init encoder endpoint %d\n", i); - goto err; - } - } } crtc = devm_kzalloc(dev, sizeof(*crtc), GFP_KERNEL); @@ -1340,8 +1339,8 @@ int ltdc_load(struct drm_device *ddev) return 0; err: - for (i = 0; i < MAX_ENDPOINTS; i++) - drm_panel_bridge_remove(bridge[i]); + for (i = 0; i < nb_endpoints; i++) + drm_of_panel_bridge_remove(ddev->dev->of_node, 0, i); clk_disable_unprepare(ldev->pixel_clk); @@ -1350,11 +1349,14 @@ err: void ltdc_unload(struct drm_device *ddev) { - int i; + struct device *dev = ddev->dev; + int nb_endpoints, i; DRM_DEBUG_DRIVER("\n"); - for (i = 0; i < MAX_ENDPOINTS; i++) + nb_endpoints = of_graph_get_endpoint_count(dev->of_node); + + for (i = 0; i < nb_endpoints; i++) drm_of_panel_bridge_remove(ddev->dev->of_node, 0, i); pm_runtime_disable(ddev->dev); From 7c49abb4c2f8853520abc05b7f7e8b751fbb3086 Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Sun, 26 Apr 2020 18:16:53 +0200 Subject: [PATCH 029/109] drm/rockchip: cdn-dp-core: Make cdn_dp_core_suspend/resume static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes the following warning detected when running make with W=1 drivers/gpu/drm/rockchip//cdn-dp-core.c:1112:5: warning: no previous prototype for ‘cdn_dp_suspend’ [-Wmissing-prototypes] drivers/gpu/drm/rockchip//cdn-dp-core.c:1126:5: warning: no previous prototype for ‘cdn_dp_resume’ [-Wmissing-prototypes] Signed-off-by: Enric Balletbo i Serra Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/20200426161653.7710-1-enric.balletbo@collabora.com --- drivers/gpu/drm/rockchip/cdn-dp-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c index 06f85138b51b..c634b95b50f7 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c @@ -1106,7 +1106,7 @@ static const struct component_ops cdn_dp_component_ops = { .unbind = cdn_dp_unbind, }; -int cdn_dp_suspend(struct device *dev) +static int cdn_dp_suspend(struct device *dev) { struct cdn_dp_device *dp = dev_get_drvdata(dev); int ret = 0; @@ -1120,7 +1120,7 @@ int cdn_dp_suspend(struct device *dev) return ret; } -int cdn_dp_resume(struct device *dev) +static int cdn_dp_resume(struct device *dev) { struct cdn_dp_device *dp = dev_get_drvdata(dev); From 611e22b1d9f61a8742c99433de9ff40795574c61 Mon Sep 17 00:00:00 2001 From: Zheng Bin Date: Fri, 24 Apr 2020 15:44:10 +0800 Subject: [PATCH 030/109] drm/rockchip: Remove unneeded semicolon Fixes coccicheck warning: drivers/gpu/drm/rockchip/cdn-dp-reg.c:604:2-3: Unneeded semicolon drivers/gpu/drm/rockchip/cdn-dp-reg.c:622:2-3: Unneeded semicolon drivers/gpu/drm/rockchip/cdn-dp-reg.c:703:2-3: Unneeded semicolon Reported-by: Hulk Robot Signed-off-by: Zheng Bin Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/20200424074410.1070-1-zhengbin13@huawei.com --- drivers/gpu/drm/rockchip/cdn-dp-reg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.c b/drivers/gpu/drm/rockchip/cdn-dp-reg.c index 7361c07cb4a7..9d2163ef4d6e 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c @@ -601,7 +601,7 @@ static int cdn_dp_get_msa_misc(struct video_info *video, case YCBCR_4_2_0: val[0] = 5; break; - }; + } switch (video->color_depth) { case 6: @@ -619,7 +619,7 @@ static int cdn_dp_get_msa_misc(struct video_info *video, case 16: val[1] = 4; break; - }; + } msa_misc = 2 * val[0] + 32 * val[1] + ((video->color_fmt == Y_ONLY) ? (1 << 14) : 0); @@ -700,7 +700,7 @@ int cdn_dp_config_video(struct cdn_dp_device *dp) case 16: val = BCS_16; break; - }; + } val += video->color_fmt << 8; ret = cdn_dp_reg_write(dp, DP_FRAMER_PXL_REPR, val); From d308a881a5917bdb46472c861a1dabe54b46c423 Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Fri, 24 Apr 2020 14:13:08 -0400 Subject: [PATCH 031/109] drm/dp_mst: Kill the second sideband tx slot, save the world While we support using both tx slots for sideband transmissions, it appears that DisplayPort devices in the field didn't end up doing a very good job of supporting it. From section 5.2.1 of the DP 2.0 specification: There are MST Sink/Branch devices in the field that do not handle interleaved message transactions. To facilitate message transaction handling by downstream devices, an MST Source device shall generate message transactions in an atomic manner (i.e., the MST Source device shall not concurrently interleave multiple message transactions). Therefore, an MST Source device shall clear the Message_Sequence_No value in the Sideband_MSG_Header to 0. This might come as a bit of a surprise since the vast majority of hubs will support using both tx slots even if they don't support interleaved message transactions, and we've also been using both tx slots since MST was introduced into the kernel. However, there is one device we've had trouble getting working consistently with MST for so long that we actually assumed it was just broken: the infamous Dell P2415Qb. Previously this monitor would appear to work sometimes, but in most situations would end up timing out LINK_ADDRESS messages almost at random until you power cycled the whole display. After reading section 5.2.1 in the DP 2.0 spec, some closer investigation into this infamous display revealed it was only ever timing out on sideband messages in the second TX slot. Sure enough, avoiding the second TX slot has suddenly made this monitor function perfectly for the first time in five years. And since they explicitly mention this in the specification, I doubt this is the only monitor out there with this issue. This might even explain explain the seemingly harmless garbage sideband responses we would occasionally see with MST hubs! So - rewrite our sideband TX handlers to only support one TX slot. In order to simplify our sideband handling now that we don't support transmitting to multiple MSTBs at once, we also move all state tracking for down replies from mstbs to the topology manager. Signed-off-by: Lyude Paul Fixes: ad7f8a1f9ced ("drm/helper: add Displayport multi-stream helper (v0.6)") Cc: Sean Paul Cc: "Lin, Wayne" Cc: # v3.17+ Reviewed-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20200424181308.770749-1-lyude@redhat.com --- drivers/gpu/drm/drm_dp_mst_topology.c | 149 ++++++++------------------ include/drm/drm_dp_mst_helper.h | 29 ++--- 2 files changed, 50 insertions(+), 128 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index d2c19791b2b6..b90cca361afe 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -1197,16 +1197,8 @@ static int drm_dp_mst_wait_tx_reply(struct drm_dp_mst_branch *mstb, /* remove from q */ if (txmsg->state == DRM_DP_SIDEBAND_TX_QUEUED || - txmsg->state == DRM_DP_SIDEBAND_TX_START_SEND) { + txmsg->state == DRM_DP_SIDEBAND_TX_START_SEND) list_del(&txmsg->next); - } - - if (txmsg->state == DRM_DP_SIDEBAND_TX_START_SEND || - txmsg->state == DRM_DP_SIDEBAND_TX_SENT) { - mstb->tx_slots[txmsg->seqno] = NULL; - } - mgr->is_waiting_for_dwn_reply = false; - } out: if (unlikely(ret == -EIO) && drm_debug_enabled(DRM_UT_DP)) { @@ -2685,22 +2677,6 @@ static int set_hdr_from_dst_qlock(struct drm_dp_sideband_msg_hdr *hdr, struct drm_dp_mst_branch *mstb = txmsg->dst; u8 req_type; - /* both msg slots are full */ - if (txmsg->seqno == -1) { - if (mstb->tx_slots[0] && mstb->tx_slots[1]) { - DRM_DEBUG_KMS("%s: failed to find slot\n", __func__); - return -EAGAIN; - } - if (mstb->tx_slots[0] == NULL && mstb->tx_slots[1] == NULL) { - txmsg->seqno = mstb->last_seqno; - mstb->last_seqno ^= 1; - } else if (mstb->tx_slots[0] == NULL) - txmsg->seqno = 0; - else - txmsg->seqno = 1; - mstb->tx_slots[txmsg->seqno] = txmsg; - } - req_type = txmsg->msg[0] & 0x7f; if (req_type == DP_CONNECTION_STATUS_NOTIFY || req_type == DP_RESOURCE_STATUS_NOTIFY) @@ -2712,7 +2688,7 @@ static int set_hdr_from_dst_qlock(struct drm_dp_sideband_msg_hdr *hdr, hdr->lcr = mstb->lct - 1; if (mstb->lct > 1) memcpy(hdr->rad, mstb->rad, mstb->lct / 2); - hdr->seqno = txmsg->seqno; + return 0; } /* @@ -2727,15 +2703,15 @@ static int process_single_tx_qlock(struct drm_dp_mst_topology_mgr *mgr, int len, space, idx, tosend; int ret; + if (txmsg->state == DRM_DP_SIDEBAND_TX_SENT) + return 0; + memset(&hdr, 0, sizeof(struct drm_dp_sideband_msg_hdr)); - if (txmsg->state == DRM_DP_SIDEBAND_TX_QUEUED) { - txmsg->seqno = -1; + if (txmsg->state == DRM_DP_SIDEBAND_TX_QUEUED) txmsg->state = DRM_DP_SIDEBAND_TX_START_SEND; - } - /* make hdr from dst mst - for replies use seqno - otherwise assign one */ + /* make hdr from dst mst */ ret = set_hdr_from_dst_qlock(&hdr, txmsg); if (ret < 0) return ret; @@ -2788,42 +2764,17 @@ static void process_single_down_tx_qlock(struct drm_dp_mst_topology_mgr *mgr) if (list_empty(&mgr->tx_msg_downq)) return; - txmsg = list_first_entry(&mgr->tx_msg_downq, struct drm_dp_sideband_msg_tx, next); + txmsg = list_first_entry(&mgr->tx_msg_downq, + struct drm_dp_sideband_msg_tx, next); ret = process_single_tx_qlock(mgr, txmsg, false); - if (ret == 1) { - /* txmsg is sent it should be in the slots now */ - mgr->is_waiting_for_dwn_reply = true; - list_del(&txmsg->next); - } else if (ret) { + if (ret < 0) { DRM_DEBUG_KMS("failed to send msg in q %d\n", ret); - mgr->is_waiting_for_dwn_reply = false; list_del(&txmsg->next); - if (txmsg->seqno != -1) - txmsg->dst->tx_slots[txmsg->seqno] = NULL; txmsg->state = DRM_DP_SIDEBAND_TX_TIMEOUT; wake_up_all(&mgr->tx_waitq); } } -/* called holding qlock */ -static void process_single_up_tx_qlock(struct drm_dp_mst_topology_mgr *mgr, - struct drm_dp_sideband_msg_tx *txmsg) -{ - int ret; - - /* construct a chunk from the first msg in the tx_msg queue */ - ret = process_single_tx_qlock(mgr, txmsg, true); - - if (ret != 1) - DRM_DEBUG_KMS("failed to send msg in q %d\n", ret); - - if (txmsg->seqno != -1) { - WARN_ON((unsigned int)txmsg->seqno > - ARRAY_SIZE(txmsg->dst->tx_slots)); - txmsg->dst->tx_slots[txmsg->seqno] = NULL; - } -} - static void drm_dp_queue_down_tx(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_sideband_msg_tx *txmsg) { @@ -2836,8 +2787,7 @@ static void drm_dp_queue_down_tx(struct drm_dp_mst_topology_mgr *mgr, drm_dp_mst_dump_sideband_msg_tx(&p, txmsg); } - if (list_is_singular(&mgr->tx_msg_downq) && - !mgr->is_waiting_for_dwn_reply) + if (list_is_singular(&mgr->tx_msg_downq)) process_single_down_tx_qlock(mgr); mutex_unlock(&mgr->qlock); } @@ -3457,7 +3407,7 @@ static int drm_dp_encode_up_ack_reply(struct drm_dp_sideband_msg_tx *msg, u8 req static int drm_dp_send_up_ack_reply(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_branch *mstb, - int req_type, int seqno, bool broadcast) + int req_type, bool broadcast) { struct drm_dp_sideband_msg_tx *txmsg; @@ -3466,13 +3416,11 @@ static int drm_dp_send_up_ack_reply(struct drm_dp_mst_topology_mgr *mgr, return -ENOMEM; txmsg->dst = mstb; - txmsg->seqno = seqno; drm_dp_encode_up_ack_reply(txmsg, req_type); mutex_lock(&mgr->qlock); - - process_single_up_tx_qlock(mgr, txmsg); - + /* construct a chunk from the first msg in the tx_msg queue */ + process_single_tx_qlock(mgr, txmsg, true); mutex_unlock(&mgr->qlock); kfree(txmsg); @@ -3697,8 +3645,9 @@ out_fail: } EXPORT_SYMBOL(drm_dp_mst_topology_mgr_resume); -static bool drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up, - struct drm_dp_mst_branch **mstb, int *seqno) +static bool +drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up, + struct drm_dp_mst_branch **mstb) { int len; u8 replyblock[32]; @@ -3706,13 +3655,13 @@ static bool drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up, int ret; u8 hdrlen; struct drm_dp_sideband_msg_hdr hdr; - struct drm_dp_sideband_msg_rx *msg; + struct drm_dp_sideband_msg_rx *msg = + up ? &mgr->up_req_recv : &mgr->down_rep_recv; int basereg = up ? DP_SIDEBAND_MSG_UP_REQ_BASE : DP_SIDEBAND_MSG_DOWN_REP_BASE; if (!up) *mstb = NULL; - *seqno = -1; len = min(mgr->max_dpcd_transaction_bytes, 16); ret = drm_dp_dpcd_read(mgr->aux, basereg, replyblock, len); @@ -3729,11 +3678,7 @@ static bool drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up, return false; } - *seqno = hdr.seqno; - - if (up) { - msg = &mgr->up_req_recv; - } else { + if (!up) { /* Caller is responsible for giving back this reference */ *mstb = drm_dp_get_mst_branch_device(mgr, hdr.lct, hdr.rad); if (!*mstb) { @@ -3741,7 +3686,6 @@ static bool drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up, hdr.lct); return false; } - msg = &(*mstb)->down_rep_recv[hdr.seqno]; } if (!drm_dp_sideband_msg_set_header(msg, &hdr, hdrlen)) { @@ -3785,13 +3729,10 @@ static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr) { struct drm_dp_sideband_msg_tx *txmsg; struct drm_dp_mst_branch *mstb = NULL; - struct drm_dp_sideband_msg_rx *msg = NULL; - int seqno = -1; + struct drm_dp_sideband_msg_rx *msg = &mgr->down_rep_recv; - if (!drm_dp_get_one_sb_msg(mgr, false, &mstb, &seqno)) - goto out_clear_reply; - - msg = &mstb->down_rep_recv[seqno]; + if (!drm_dp_get_one_sb_msg(mgr, false, &mstb)) + goto out; /* Multi-packet message transmission, don't clear the reply */ if (!msg->have_eomt) @@ -3799,11 +3740,12 @@ static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr) /* find the message */ mutex_lock(&mgr->qlock); - txmsg = mstb->tx_slots[seqno]; - /* remove from slots */ + txmsg = list_first_entry_or_null(&mgr->tx_msg_downq, + struct drm_dp_sideband_msg_tx, next); mutex_unlock(&mgr->qlock); - if (!txmsg) { + /* Were we actually expecting a response, and from this mstb? */ + if (!txmsg || txmsg->dst != mstb) { struct drm_dp_sideband_msg_hdr *hdr; hdr = &msg->initial_hdr; DRM_DEBUG_KMS("Got MST reply with no msg %p %d %d %02x %02x\n", @@ -3828,8 +3770,7 @@ static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr) mutex_lock(&mgr->qlock); txmsg->state = DRM_DP_SIDEBAND_TX_RX; - mstb->tx_slots[seqno] = NULL; - mgr->is_waiting_for_dwn_reply = false; + list_del(&txmsg->next); mutex_unlock(&mgr->qlock); wake_up_all(&mgr->tx_waitq); @@ -3837,11 +3778,7 @@ static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr) return 0; out_clear_reply: - mutex_lock(&mgr->qlock); - mgr->is_waiting_for_dwn_reply = false; - mutex_unlock(&mgr->qlock); - if (msg) - memset(msg, 0, sizeof(struct drm_dp_sideband_msg_rx)); + memset(msg, 0, sizeof(struct drm_dp_sideband_msg_rx)); out: if (mstb) drm_dp_mst_topology_put_mstb(mstb); @@ -3921,9 +3858,8 @@ static void drm_dp_mst_up_req_work(struct work_struct *work) static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr) { struct drm_dp_pending_up_req *up_req; - int seqno; - if (!drm_dp_get_one_sb_msg(mgr, true, NULL, &seqno)) + if (!drm_dp_get_one_sb_msg(mgr, true, NULL)) goto out; if (!mgr->up_req_recv.have_eomt) @@ -3947,7 +3883,7 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr) } drm_dp_send_up_ack_reply(mgr, mgr->mst_primary, up_req->msg.req_type, - seqno, false); + false); if (up_req->msg.req_type == DP_CONNECTION_STATUS_NOTIFY) { const struct drm_dp_connection_status_notify *conn_stat = @@ -4692,7 +4628,7 @@ static void drm_dp_tx_work(struct work_struct *work) struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, tx_work); mutex_lock(&mgr->qlock); - if (!list_empty(&mgr->tx_msg_downq) && !mgr->is_waiting_for_dwn_reply) + if (!list_empty(&mgr->tx_msg_downq)) process_single_down_tx_qlock(mgr); mutex_unlock(&mgr->qlock); } @@ -4713,26 +4649,25 @@ static inline void drm_dp_delayed_destroy_mstb(struct drm_dp_mst_branch *mstb) { struct drm_dp_mst_topology_mgr *mgr = mstb->mgr; - struct drm_dp_mst_port *port, *tmp; + struct drm_dp_mst_port *port, *port_tmp; + struct drm_dp_sideband_msg_tx *txmsg, *txmsg_tmp; bool wake_tx = false; mutex_lock(&mgr->lock); - list_for_each_entry_safe(port, tmp, &mstb->ports, next) { + list_for_each_entry_safe(port, port_tmp, &mstb->ports, next) { list_del(&port->next); drm_dp_mst_topology_put_port(port); } mutex_unlock(&mgr->lock); - /* drop any tx slots msg */ + /* drop any tx slot msg */ mutex_lock(&mstb->mgr->qlock); - if (mstb->tx_slots[0]) { - mstb->tx_slots[0]->state = DRM_DP_SIDEBAND_TX_TIMEOUT; - mstb->tx_slots[0] = NULL; - wake_tx = true; - } - if (mstb->tx_slots[1]) { - mstb->tx_slots[1]->state = DRM_DP_SIDEBAND_TX_TIMEOUT; - mstb->tx_slots[1] = NULL; + list_for_each_entry_safe(txmsg, txmsg_tmp, &mgr->tx_msg_downq, next) { + if (txmsg->dst != mstb) + continue; + + txmsg->state = DRM_DP_SIDEBAND_TX_TIMEOUT; + list_del(&txmsg->next); wake_tx = true; } mutex_unlock(&mstb->mgr->qlock); diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index 96bcf33c03d3..9e1ffcd7cb68 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -194,11 +194,8 @@ struct drm_dp_sideband_msg_rx { * @rad: Relative Address to talk to this branch device. * @lct: Link count total to talk to this branch device. * @num_ports: number of ports on the branch. - * @msg_slots: one bit per transmitted msg slot. * @port_parent: pointer to the port parent, NULL if toplevel. * @mgr: topology manager for this branch device. - * @tx_slots: transmission slots for this device. - * @last_seqno: last sequence number used to talk to this. * @link_address_sent: if a link address message has been sent to this device yet. * @guid: guid for DP 1.2 branch device. port under this branch can be * identified by port #. @@ -239,7 +236,6 @@ struct drm_dp_mst_branch { u8 lct; int num_ports; - int msg_slots; /** * @ports: the list of ports on this branch device. This should be * considered protected for reading by &drm_dp_mst_topology_mgr.lock. @@ -252,20 +248,11 @@ struct drm_dp_mst_branch { */ struct list_head ports; - /* list of tx ops queue for this port */ struct drm_dp_mst_port *port_parent; struct drm_dp_mst_topology_mgr *mgr; - /* slots are protected by mstb->mgr->qlock */ - struct drm_dp_sideband_msg_tx *tx_slots[2]; - int last_seqno; bool link_address_sent; - /** - * @down_rep_recv: Message receiver state for down replies. - */ - struct drm_dp_sideband_msg_rx down_rep_recv[2]; - /* global unique identifier to identify branch devices */ u8 guid[16]; }; @@ -567,6 +554,12 @@ struct drm_dp_mst_topology_mgr { */ struct drm_dp_sideband_msg_rx up_req_recv; + /** + * @down_rep_recv: Message receiver state for replies to down + * requests. + */ + struct drm_dp_sideband_msg_rx down_rep_recv; + /** * @lock: protects @mst_state, @mst_primary, @dpcd, and * @payload_id_table_cleared. @@ -592,11 +585,6 @@ struct drm_dp_mst_topology_mgr { */ bool payload_id_table_cleared : 1; - /** - * @is_waiting_for_dwn_reply: whether we're waiting for a down reply. - */ - bool is_waiting_for_dwn_reply : 1; - /** * @mst_primary: Pointer to the primary/first branch device. */ @@ -621,13 +609,12 @@ struct drm_dp_mst_topology_mgr { const struct drm_private_state_funcs *funcs; /** - * @qlock: protects @tx_msg_downq, the &drm_dp_mst_branch.txslost and - * &drm_dp_sideband_msg_tx.state once they are queued + * @qlock: protects @tx_msg_downq and &drm_dp_sideband_msg_tx.state */ struct mutex qlock; /** - * @tx_msg_downq: List of pending down replies. + * @tx_msg_downq: List of pending down requests */ struct list_head tx_msg_downq; From 439c2787532ff6ecfa7917ad100df923da58c103 Mon Sep 17 00:00:00 2001 From: Zheng Bin Date: Fri, 24 Apr 2020 15:49:49 +0800 Subject: [PATCH 032/109] drm/meson: Remove unneeded semicolon Fixes coccicheck warning: drivers/gpu/drm/meson/meson_plane.c:226:3-4: Unneeded semicolon Reported-by: Hulk Robot Signed-off-by: Zheng Bin Reviewed-by: Neil Armstrong Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20200424074949.12309-1-zhengbin13@huawei.com --- drivers/gpu/drm/meson/meson_plane.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c index d5cbc47835bf..35338ed18209 100644 --- a/drivers/gpu/drm/meson/meson_plane.c +++ b/drivers/gpu/drm/meson/meson_plane.c @@ -223,7 +223,7 @@ static void meson_plane_atomic_update(struct drm_plane *plane, priv->viu.osd1_blk0_cfg[0] |= OSD_BLK_MODE_16 | OSD_COLOR_MATRIX_16_RGB565; break; - }; + } } switch (fb->format->format) { From 44dd0eef4a24bc4020f6c7b7aa855e341eb4bad2 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Wed, 15 Apr 2020 21:21:05 +0800 Subject: [PATCH 033/109] drm/omap: venc: remove unused variable 'venc_config_pal_bdghi' drivers/gpu/drm/omapdrm/dss/venc.c:211:33: warning: 'venc_config_pal_bdghi' defined but not used [-Wunused-const-variable=] static const struct venc_config venc_config_pal_bdghi = { ^~~~~~~~~~~~~~~~~~~~~ It is never used, remove it. Reported-by: Hulk Robot Signed-off-by: YueHaibing Signed-off-by: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20200415132105.43636-1-yuehaibing@huawei.com --- drivers/gpu/drm/omapdrm/dss/venc.c | 43 ------------------------------ 1 file changed, 43 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c index 766553bb2f87..9701843ccf09 100644 --- a/drivers/gpu/drm/omapdrm/dss/venc.c +++ b/drivers/gpu/drm/omapdrm/dss/venc.c @@ -208,49 +208,6 @@ static const struct venc_config venc_config_ntsc_trm = { .gen_ctrl = 0x00F90000, }; -static const struct venc_config venc_config_pal_bdghi = { - .f_control = 0, - .vidout_ctrl = 0, - .sync_ctrl = 0, - .hfltr_ctrl = 0, - .x_color = 0, - .line21 = 0, - .ln_sel = 21, - .htrigger_vtrigger = 0, - .tvdetgp_int_start_stop_x = 0x00140001, - .tvdetgp_int_start_stop_y = 0x00010001, - .gen_ctrl = 0x00FB0000, - - .llen = 864-1, - .flens = 625-1, - .cc_carr_wss_carr = 0x2F7625ED, - .c_phase = 0xDF, - .gain_u = 0x111, - .gain_v = 0x181, - .gain_y = 0x140, - .black_level = 0x3e, - .blank_level = 0x3e, - .m_control = 0<<2 | 1<<1, - .bstamp_wss_data = 0x42, - .s_carr = 0x2a098acb, - .l21__wc_ctl = 0<<13 | 0x16<<8 | 0<<0, - .savid__eavid = 0x06A70108, - .flen__fal = 23<<16 | 624<<0, - .lal__phase_reset = 2<<17 | 310<<0, - .hs_int_start_stop_x = 0x00920358, - .hs_ext_start_stop_x = 0x000F035F, - .vs_int_start_x = 0x1a7<<16, - .vs_int_stop_x__vs_int_start_y = 0x000601A7, - .vs_int_stop_y__vs_ext_start_x = 0x01AF0036, - .vs_ext_stop_x__vs_ext_start_y = 0x27101af, - .vs_ext_stop_y = 0x05, - .avid_start_stop_x = 0x03530082, - .avid_start_stop_y = 0x0270002E, - .fid_int_start_x__fid_int_start_y = 0x0005008A, - .fid_int_offset_y__fid_ext_start_x = 0x002E0138, - .fid_ext_start_y__fid_ext_offset_y = 0x01380005, -}; - enum venc_videomode { VENC_MODE_UNKNOWN, VENC_MODE_PAL, From b0b5849e0cc0195604c0945c9adb7c2570621a51 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:36 +0200 Subject: [PATCH 034/109] drm: Add devm_drm_dev_alloc macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new macro helper to combine the usual init sequence in drivers, consisting of a kzalloc + devm_drm_dev_init + drmm_add_final_kfree triplet. This allows us to remove the rather unsightly drmm_add_final_kfree from all currently merged drivers. The kerneldoc is only added for this new function. Existing kerneldoc and examples will be udated at the very end, since once all drivers are converted over to devm_drm_dev_alloc we can unexport a lot of interim functions and make the documentation for driver authors a lot cleaner and less confusing. There will be only one true way to initialize a drm_device at the end of this, which is going to be devm_drm_dev_alloc. v2: - Actually explain what this is for in the commit message (Sam) - Fix checkpatch issues (Sam) Acked-by: Noralf Trønnes Cc: Noralf Trønnes Reviewed-by: Thomas Zimmermann Reviewed-by: Sam Ravnborg Cc: Sam Ravnborg Cc: Paul Kocialkowski Cc: Laurent Pinchart Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-2-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_drv.c | 23 +++++++++++++++++++++++ include/drm/drm_drv.h | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index c15c9b4540e1..bc38322f306e 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -739,6 +739,29 @@ int devm_drm_dev_init(struct device *parent, } EXPORT_SYMBOL(devm_drm_dev_init); +void *__devm_drm_dev_alloc(struct device *parent, struct drm_driver *driver, + size_t size, size_t offset) +{ + void *container; + struct drm_device *drm; + int ret; + + container = kzalloc(size, GFP_KERNEL); + if (!container) + return ERR_PTR(-ENOMEM); + + drm = container + offset; + ret = devm_drm_dev_init(parent, drm, driver); + if (ret) { + kfree(container); + return ERR_PTR(ret); + } + drmm_add_final_kfree(drm, container); + + return container; +} +EXPORT_SYMBOL(__devm_drm_dev_alloc); + /** * drm_dev_alloc - Allocate new DRM device * @driver: DRM driver to allocate device for diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index e0ea577559ff..6d457652f199 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -623,6 +623,39 @@ int devm_drm_dev_init(struct device *parent, struct drm_device *dev, struct drm_driver *driver); +void *__devm_drm_dev_alloc(struct device *parent, struct drm_driver *driver, + size_t size, size_t offset); + +/** + * devm_drm_dev_alloc - Resource managed allocation of a &drm_device instance + * @parent: Parent device object + * @driver: DRM driver + * @type: the type of the struct which contains struct &drm_device + * @member: the name of the &drm_device within @type. + * + * This allocates and initialize a new DRM device. No device registration is done. + * Call drm_dev_register() to advertice the device to user space and register it + * with other core subsystems. This should be done last in the device + * initialization sequence to make sure userspace can't access an inconsistent + * state. + * + * The initial ref-count of the object is 1. Use drm_dev_get() and + * drm_dev_put() to take and drop further ref-counts. + * + * It is recommended that drivers embed &struct drm_device into their own device + * structure. + * + * Note that this manages the lifetime of the resulting &drm_device + * automatically using devres. The DRM device initialized with this function is + * automatically put on driver detach using drm_dev_put(). + * + * RETURNS: + * Pointer to new DRM device, or ERR_PTR on failure. + */ +#define devm_drm_dev_alloc(parent, driver, type, member) \ + ((type *) __devm_drm_dev_alloc(parent, driver, sizeof(type), \ + offsetof(type, member))) + struct drm_device *drm_dev_alloc(struct drm_driver *driver, struct device *parent); int drm_dev_register(struct drm_device *dev, unsigned long flags); From 2de955d072e4ceb1ac11cd735a485f2bdf523c89 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:37 +0200 Subject: [PATCH 035/109] drm/vboxvideo: drop DRM_MTRR_WC #define Doesn't apply to upstream kernels since a rather long time. Reviewed-by: Hans de Goede Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: Hans de Goede Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-3-daniel.vetter@ffwll.ch --- drivers/gpu/drm/vboxvideo/vbox_ttm.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/gpu/drm/vboxvideo/vbox_ttm.c b/drivers/gpu/drm/vboxvideo/vbox_ttm.c index 976423d0c3cc..f5a06675da43 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_ttm.c +++ b/drivers/gpu/drm/vboxvideo/vbox_ttm.c @@ -24,25 +24,13 @@ int vbox_mm_init(struct vbox_private *vbox) return ret; } -#ifdef DRM_MTRR_WC - vbox->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 0), - pci_resource_len(dev->pdev, 0), - DRM_MTRR_WC); -#else vbox->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0), pci_resource_len(dev->pdev, 0)); -#endif return 0; } void vbox_mm_fini(struct vbox_private *vbox) { -#ifdef DRM_MTRR_WC - drm_mtrr_del(vbox->fb_mtrr, - pci_resource_start(vbox->ddev.pdev, 0), - pci_resource_len(vbox->ddev.pdev, 0), DRM_MTRR_WC); -#else arch_phys_wc_del(vbox->fb_mtrr); -#endif drm_vram_helper_release_mm(&vbox->ddev); } From 35b24eed48ed42b2d3802647f2b54f7befe63396 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:38 +0200 Subject: [PATCH 036/109] drm/vboxvideo: Use devm_drm_dev_alloc Straightforward conversion. Reviewed-by: Hans de Goede Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: Hans de Goede Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-4-daniel.vetter@ffwll.ch --- drivers/gpu/drm/vboxvideo/vbox_drv.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c index 282348e071fe..7dd25c7a3768 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c @@ -46,25 +46,19 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) return ret; - vbox = kzalloc(sizeof(*vbox), GFP_KERNEL); - if (!vbox) - return -ENOMEM; - - ret = drm_dev_init(&vbox->ddev, &driver, &pdev->dev); - if (ret) { - kfree(vbox); - return ret; - } + vbox = devm_drm_dev_alloc(&pdev->dev, &driver, + struct vbox_private, ddev); + if (IS_ERR(vbox)) + return PTR_ERR(vbox); vbox->ddev.pdev = pdev; vbox->ddev.dev_private = vbox; pci_set_drvdata(pdev, vbox); - drmm_add_final_kfree(&vbox->ddev, vbox); mutex_init(&vbox->hw_mutex); ret = pci_enable_device(pdev); if (ret) - goto err_dev_put; + return ret; ret = vbox_hw_init(vbox); if (ret) @@ -100,8 +94,6 @@ err_hw_fini: vbox_hw_fini(vbox); err_pci_disable: pci_disable_device(pdev); -err_dev_put: - drm_dev_put(&vbox->ddev); return ret; } @@ -114,7 +106,6 @@ static void vbox_pci_remove(struct pci_dev *pdev) vbox_mode_fini(vbox); vbox_mm_fini(vbox); vbox_hw_fini(vbox); - drm_dev_put(&vbox->ddev); } #ifdef CONFIG_PM_SLEEP From dd9a68935f93e95a9f9f231e4b2853b897162c85 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:39 +0200 Subject: [PATCH 037/109] drm/vboxvideo: Stop using drm_device->dev_private We use the baseclass pattern here, so lets to the proper (and more typesafe) upcasting. Acked-by: Sam Ravnborg Acked-by: Thomas Zimmermann Reviewed-by: Hans de Goede Signed-off-by: Daniel Vetter Cc: Hans de Goede Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-5-daniel.vetter@ffwll.ch --- drivers/gpu/drm/vboxvideo/vbox_drv.c | 1 - drivers/gpu/drm/vboxvideo/vbox_drv.h | 1 + drivers/gpu/drm/vboxvideo/vbox_irq.c | 2 +- drivers/gpu/drm/vboxvideo/vbox_mode.c | 10 +++++----- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c index 7dd25c7a3768..cfa4639c5142 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c @@ -52,7 +52,6 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return PTR_ERR(vbox); vbox->ddev.pdev = pdev; - vbox->ddev.dev_private = vbox; pci_set_drvdata(pdev, vbox); mutex_init(&vbox->hw_mutex); diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.h b/drivers/gpu/drm/vboxvideo/vbox_drv.h index 87421903816c..ac7c2effc46f 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.h +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.h @@ -127,6 +127,7 @@ struct vbox_encoder { #define to_vbox_crtc(x) container_of(x, struct vbox_crtc, base) #define to_vbox_connector(x) container_of(x, struct vbox_connector, base) #define to_vbox_encoder(x) container_of(x, struct vbox_encoder, base) +#define to_vbox_dev(x) container_of(x, struct vbox_private, ddev) bool vbox_check_supported(u16 id); int vbox_hw_init(struct vbox_private *vbox); diff --git a/drivers/gpu/drm/vboxvideo/vbox_irq.c b/drivers/gpu/drm/vboxvideo/vbox_irq.c index 16a1e29f5292..631657fa554f 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_irq.c +++ b/drivers/gpu/drm/vboxvideo/vbox_irq.c @@ -34,7 +34,7 @@ void vbox_report_hotplug(struct vbox_private *vbox) irqreturn_t vbox_irq_handler(int irq, void *arg) { struct drm_device *dev = (struct drm_device *)arg; - struct vbox_private *vbox = (struct vbox_private *)dev->dev_private; + struct vbox_private *vbox = to_vbox_dev(dev); u32 host_flags = vbox_get_flags(vbox); if (!(host_flags & HGSMIHOSTFLAGS_IRQ)) diff --git a/drivers/gpu/drm/vboxvideo/vbox_mode.c b/drivers/gpu/drm/vboxvideo/vbox_mode.c index 0883a435e62b..d9a5af62af89 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_mode.c +++ b/drivers/gpu/drm/vboxvideo/vbox_mode.c @@ -36,7 +36,7 @@ static void vbox_do_modeset(struct drm_crtc *crtc) u16 flags; s32 x_offset, y_offset; - vbox = crtc->dev->dev_private; + vbox = to_vbox_dev(crtc->dev); width = vbox_crtc->width ? vbox_crtc->width : 640; height = vbox_crtc->height ? vbox_crtc->height : 480; bpp = fb ? fb->format->cpp[0] * 8 : 32; @@ -77,7 +77,7 @@ static void vbox_do_modeset(struct drm_crtc *crtc) static int vbox_set_view(struct drm_crtc *crtc) { struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc); - struct vbox_private *vbox = crtc->dev->dev_private; + struct vbox_private *vbox = to_vbox_dev(crtc->dev); struct vbva_infoview *p; /* @@ -174,7 +174,7 @@ static void vbox_crtc_set_base_and_mode(struct drm_crtc *crtc, int x, int y) { struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(fb->obj[0]); - struct vbox_private *vbox = crtc->dev->dev_private; + struct vbox_private *vbox = to_vbox_dev(crtc->dev); struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc); bool needs_modeset = drm_atomic_crtc_needs_modeset(crtc->state); @@ -272,7 +272,7 @@ static void vbox_primary_atomic_update(struct drm_plane *plane, { struct drm_crtc *crtc = plane->state->crtc; struct drm_framebuffer *fb = plane->state->fb; - struct vbox_private *vbox = fb->dev->dev_private; + struct vbox_private *vbox = to_vbox_dev(fb->dev); struct drm_mode_rect *clips; uint32_t num_clips, i; @@ -704,7 +704,7 @@ static int vbox_get_modes(struct drm_connector *connector) int preferred_width, preferred_height; vbox_connector = to_vbox_connector(connector); - vbox = connector->dev->dev_private; + vbox = to_vbox_dev(connector->dev); hgsmi_report_flags_location(vbox->guest_pool, GUEST_HEAP_OFFSET(vbox) + HOST_FLAGS_OFFSET); From 8558de401b5fbbfb1df96d6986bba3c79cd47401 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:40 +0200 Subject: [PATCH 038/109] drm/vboxvideo: use managed pci functions Allows us to drop the cleanup code on the floor. Sam noticed in his review: > With this change we avoid calling pci_disable_device() > twise in case vbox_mm_init() fails. > Once in vbox_hw_fini() and once in the error path. v2: Include Sam's review remarks v3: Fix typo in commit summary (Thomas Zimmermann) Acked-by: Sam Ravnborg Reviewed-by: Hans de Goede Signed-off-by: Daniel Vetter Cc: Hans de Goede Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-6-daniel.vetter@ffwll.ch --- drivers/gpu/drm/vboxvideo/vbox_drv.c | 6 ++---- drivers/gpu/drm/vboxvideo/vbox_main.c | 7 +------ 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c index cfa4639c5142..cf2e3e6a2388 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c @@ -55,13 +55,13 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, vbox); mutex_init(&vbox->hw_mutex); - ret = pci_enable_device(pdev); + ret = pcim_enable_device(pdev); if (ret) return ret; ret = vbox_hw_init(vbox); if (ret) - goto err_pci_disable; + return ret; ret = vbox_mm_init(vbox); if (ret) @@ -91,8 +91,6 @@ err_mm_fini: vbox_mm_fini(vbox); err_hw_fini: vbox_hw_fini(vbox); -err_pci_disable: - pci_disable_device(pdev); return ret; } diff --git a/drivers/gpu/drm/vboxvideo/vbox_main.c b/drivers/gpu/drm/vboxvideo/vbox_main.c index 9dcab115a261..1336ab9795fc 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_main.c +++ b/drivers/gpu/drm/vboxvideo/vbox_main.c @@ -71,8 +71,6 @@ static void vbox_accel_fini(struct vbox_private *vbox) for (i = 0; i < vbox->num_crtcs; ++i) vbva_disable(&vbox->vbva_info[i], vbox->guest_pool, i); - - pci_iounmap(vbox->ddev.pdev, vbox->vbva_buffers); } /* Do we support the 4.3 plus mode hint reporting interface? */ @@ -125,7 +123,7 @@ int vbox_hw_init(struct vbox_private *vbox) /* Create guest-heap mem-pool use 2^4 = 16 byte chunks */ vbox->guest_pool = gen_pool_create(4, -1); if (!vbox->guest_pool) - goto err_unmap_guest_heap; + return -ENOMEM; ret = gen_pool_add_virt(vbox->guest_pool, (unsigned long)vbox->guest_heap, @@ -168,8 +166,6 @@ int vbox_hw_init(struct vbox_private *vbox) err_destroy_guest_pool: gen_pool_destroy(vbox->guest_pool); -err_unmap_guest_heap: - pci_iounmap(vbox->ddev.pdev, vbox->guest_heap); return ret; } @@ -177,5 +173,4 @@ void vbox_hw_fini(struct vbox_private *vbox) { vbox_accel_fini(vbox); gen_pool_destroy(vbox->guest_pool); - pci_iounmap(vbox->ddev.pdev, vbox->guest_heap); } From 4cc9b565454bb2cf5d27d58485816570f18f5a5a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:41 +0200 Subject: [PATCH 039/109] drm/vboxvideo: Use devm_gen_pool_create Aside from deleting all the cleanup code we're now also setting a name for the pool Acked-by: Sam Ravnborg Reviewed-by: Hans de Goede Signed-off-by: Daniel Vetter Cc: Hans de Goede Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-7-daniel.vetter@ffwll.ch --- drivers/gpu/drm/vboxvideo/vbox_main.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/vboxvideo/vbox_main.c b/drivers/gpu/drm/vboxvideo/vbox_main.c index 1336ab9795fc..d68d9bad7674 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_main.c +++ b/drivers/gpu/drm/vboxvideo/vbox_main.c @@ -121,7 +121,8 @@ int vbox_hw_init(struct vbox_private *vbox) return -ENOMEM; /* Create guest-heap mem-pool use 2^4 = 16 byte chunks */ - vbox->guest_pool = gen_pool_create(4, -1); + vbox->guest_pool = devm_gen_pool_create(vbox->ddev.dev, 4, -1, + "vboxvideo-accel"); if (!vbox->guest_pool) return -ENOMEM; @@ -130,12 +131,12 @@ int vbox_hw_init(struct vbox_private *vbox) GUEST_HEAP_OFFSET(vbox), GUEST_HEAP_USABLE_SIZE, -1); if (ret) - goto err_destroy_guest_pool; + return ret; ret = hgsmi_test_query_conf(vbox->guest_pool); if (ret) { DRM_ERROR("vboxvideo: hgsmi_test_query_conf failed\n"); - goto err_destroy_guest_pool; + return ret; } /* Reduce available VRAM size to reflect the guest heap. */ @@ -147,30 +148,23 @@ int vbox_hw_init(struct vbox_private *vbox) if (!have_hgsmi_mode_hints(vbox)) { ret = -ENOTSUPP; - goto err_destroy_guest_pool; + return ret; } vbox->last_mode_hints = devm_kcalloc(vbox->ddev.dev, vbox->num_crtcs, sizeof(struct vbva_modehint), GFP_KERNEL); - if (!vbox->last_mode_hints) { - ret = -ENOMEM; - goto err_destroy_guest_pool; - } + if (!vbox->last_mode_hints) + return -ENOMEM; ret = vbox_accel_init(vbox); if (ret) - goto err_destroy_guest_pool; + return ret; return 0; - -err_destroy_guest_pool: - gen_pool_destroy(vbox->guest_pool); - return ret; } void vbox_hw_fini(struct vbox_private *vbox) { vbox_accel_fini(vbox); - gen_pool_destroy(vbox->guest_pool); } From af25c16bd1c6e7e73d67271c0fe6e0d5078759f1 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:42 +0200 Subject: [PATCH 040/109] drm/v3d: Don't set drm_device->dev_private And switch the helper over to container_of, which is a bunch faster than chasing a pointer. Plus allows gcc to see through this maze. Acked-by: Eric Anholt Signed-off-by: Daniel Vetter Cc: Eric Anholt Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-8-daniel.vetter@ffwll.ch --- drivers/gpu/drm/v3d/v3d_drv.c | 1 - drivers/gpu/drm/v3d/v3d_drv.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index 8d0c0daaac81..ead62a15d48f 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -265,7 +265,6 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, drm); - drm->dev_private = v3d; drmm_add_final_kfree(drm, v3d); ret = map_regs(v3d, &v3d->hub_regs, "hub"); diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h index e0775c884553..112d80aed5f6 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h @@ -121,7 +121,7 @@ struct v3d_dev { static inline struct v3d_dev * to_v3d_dev(struct drm_device *dev) { - return (struct v3d_dev *)dev->dev_private; + return container_of(dev, struct v3d_dev, drm); } static inline bool From 235b7e7d7eee3797a354ef5e923d58a477d1cb82 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:43 +0200 Subject: [PATCH 041/109] drm/v3d: Use devm_drm_dev_alloc Also allows us to simplify the unroll code since the drm_dev_put disappears. Acked-by: Eric Anholt Signed-off-by: Daniel Vetter Cc: Eric Anholt Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-9-daniel.vetter@ffwll.ch --- drivers/gpu/drm/v3d/v3d_drv.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index ead62a15d48f..f57d408ef371 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -251,29 +251,23 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) u32 ident1; - v3d = kzalloc(sizeof(*v3d), GFP_KERNEL); - if (!v3d) - return -ENOMEM; + v3d = devm_drm_dev_alloc(dev, &v3d_drm_driver, struct v3d_dev, drm); + if (IS_ERR(v3d)) + return PTR_ERR(v3d); + v3d->dev = dev; v3d->pdev = pdev; drm = &v3d->drm; - ret = drm_dev_init(&v3d->drm, &v3d_drm_driver, dev); - if (ret) { - kfree(v3d); - return ret; - } - platform_set_drvdata(pdev, drm); - drmm_add_final_kfree(drm, v3d); ret = map_regs(v3d, &v3d->hub_regs, "hub"); if (ret) - goto dev_destroy; + return ret; ret = map_regs(v3d, &v3d->core_regs[0], "core0"); if (ret) - goto dev_destroy; + return ret; mmu_debug = V3D_READ(V3D_MMU_DEBUG_INFO); dev->coherent_dma_mask = @@ -291,29 +285,28 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) ret = PTR_ERR(v3d->reset); if (ret == -EPROBE_DEFER) - goto dev_destroy; + return ret; v3d->reset = NULL; ret = map_regs(v3d, &v3d->bridge_regs, "bridge"); if (ret) { dev_err(dev, "Failed to get reset control or bridge regs\n"); - goto dev_destroy; + return ret; } } if (v3d->ver < 41) { ret = map_regs(v3d, &v3d->gca_regs, "gca"); if (ret) - goto dev_destroy; + return ret; } v3d->mmu_scratch = dma_alloc_wc(dev, 4096, &v3d->mmu_scratch_paddr, GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO); if (!v3d->mmu_scratch) { dev_err(dev, "Failed to allocate MMU scratch page\n"); - ret = -ENOMEM; - goto dev_destroy; + return -ENOMEM; } pm_runtime_use_autosuspend(dev); @@ -340,8 +333,6 @@ gem_destroy: v3d_gem_destroy(drm); dma_free: dma_free_wc(dev, 4096, v3d->mmu_scratch, v3d->mmu_scratch_paddr); -dev_destroy: - drm_dev_put(drm); return ret; } @@ -354,8 +345,6 @@ static int v3d_platform_drm_remove(struct platform_device *pdev) v3d_gem_destroy(drm); - drm_dev_put(drm); - dma_free_wc(v3d->dev, 4096, v3d->mmu_scratch, v3d->mmu_scratch_paddr); return 0; From bc662528e29ae751e0d43c18c9e4cd71a20ef0d4 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:44 +0200 Subject: [PATCH 042/109] drm/v3d: Delete v3d_dev->dev We already have it in v3d_dev->drm.dev with zero additional pointer chasing. Personally I don't like duplicated pointers like this because: - reviewers need to check whether the pointer is for the same or different objects if there's multiple - compilers have an easier time too But also a bit a bikeshed, so feel free to ignore. Acked-by: Eric Anholt Signed-off-by: Daniel Vetter Cc: Eric Anholt Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-10-daniel.vetter@ffwll.ch --- drivers/gpu/drm/v3d/v3d_debugfs.c | 12 ++++++------ drivers/gpu/drm/v3d/v3d_drv.c | 12 ++++++------ drivers/gpu/drm/v3d/v3d_drv.h | 2 -- drivers/gpu/drm/v3d/v3d_gem.c | 17 +++++++++-------- drivers/gpu/drm/v3d/v3d_irq.c | 12 ++++++------ drivers/gpu/drm/v3d/v3d_mmu.c | 10 +++++----- drivers/gpu/drm/v3d/v3d_sched.c | 10 +++++----- 7 files changed, 37 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/v3d/v3d_debugfs.c b/drivers/gpu/drm/v3d/v3d_debugfs.c index 2b0ea5f8febd..e76b24bb8828 100644 --- a/drivers/gpu/drm/v3d/v3d_debugfs.c +++ b/drivers/gpu/drm/v3d/v3d_debugfs.c @@ -132,7 +132,7 @@ static int v3d_v3d_debugfs_ident(struct seq_file *m, void *unused) u32 ident0, ident1, ident2, ident3, cores; int ret, core; - ret = pm_runtime_get_sync(v3d->dev); + ret = pm_runtime_get_sync(v3d->drm.dev); if (ret < 0) return ret; @@ -187,8 +187,8 @@ static int v3d_v3d_debugfs_ident(struct seq_file *m, void *unused) (misccfg & V3D_MISCCFG_OVRTMUOUT) != 0); } - pm_runtime_mark_last_busy(v3d->dev); - pm_runtime_put_autosuspend(v3d->dev); + pm_runtime_mark_last_busy(v3d->drm.dev); + pm_runtime_put_autosuspend(v3d->drm.dev); return 0; } @@ -219,7 +219,7 @@ static int v3d_measure_clock(struct seq_file *m, void *unused) int measure_ms = 1000; int ret; - ret = pm_runtime_get_sync(v3d->dev); + ret = pm_runtime_get_sync(v3d->drm.dev); if (ret < 0) return ret; @@ -245,8 +245,8 @@ static int v3d_measure_clock(struct seq_file *m, void *unused) cycles / (measure_ms * 1000), (cycles / (measure_ms * 100)) % 10); - pm_runtime_mark_last_busy(v3d->dev); - pm_runtime_put_autosuspend(v3d->dev); + pm_runtime_mark_last_busy(v3d->drm.dev); + pm_runtime_put_autosuspend(v3d->drm.dev); return 0; } diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index f57d408ef371..37cb880f2826 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -105,7 +105,7 @@ static int v3d_get_param_ioctl(struct drm_device *dev, void *data, if (args->value != 0) return -EINVAL; - ret = pm_runtime_get_sync(v3d->dev); + ret = pm_runtime_get_sync(v3d->drm.dev); if (ret < 0) return ret; if (args->param >= DRM_V3D_PARAM_V3D_CORE0_IDENT0 && @@ -114,8 +114,8 @@ static int v3d_get_param_ioctl(struct drm_device *dev, void *data, } else { args->value = V3D_READ(offset); } - pm_runtime_mark_last_busy(v3d->dev); - pm_runtime_put_autosuspend(v3d->dev); + pm_runtime_mark_last_busy(v3d->drm.dev); + pm_runtime_put_autosuspend(v3d->drm.dev); return 0; } @@ -237,7 +237,7 @@ map_regs(struct v3d_dev *v3d, void __iomem **regs, const char *name) struct resource *res = platform_get_resource_byname(v3d->pdev, IORESOURCE_MEM, name); - *regs = devm_ioremap_resource(v3d->dev, res); + *regs = devm_ioremap_resource(v3d->drm.dev, res); return PTR_ERR_OR_ZERO(*regs); } @@ -255,7 +255,6 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) if (IS_ERR(v3d)) return PTR_ERR(v3d); - v3d->dev = dev; v3d->pdev = pdev; drm = &v3d->drm; @@ -345,7 +344,8 @@ static int v3d_platform_drm_remove(struct platform_device *pdev) v3d_gem_destroy(drm); - dma_free_wc(v3d->dev, 4096, v3d->mmu_scratch, v3d->mmu_scratch_paddr); + dma_free_wc(v3d->drm.dev, 4096, v3d->mmu_scratch, + v3d->mmu_scratch_paddr); return 0; } diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h index 112d80aed5f6..4d2d1f2fe1af 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h @@ -14,7 +14,6 @@ #include "uapi/drm/v3d_drm.h" struct clk; -struct device; struct platform_device; struct reset_control; @@ -47,7 +46,6 @@ struct v3d_dev { int ver; bool single_irq_line; - struct device *dev; struct platform_device *pdev; void __iomem *hub_regs; void __iomem *core_regs[3]; diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c index 549dde83408b..09a7639cf161 100644 --- a/drivers/gpu/drm/v3d/v3d_gem.c +++ b/drivers/gpu/drm/v3d/v3d_gem.c @@ -370,8 +370,8 @@ v3d_job_free(struct kref *ref) dma_fence_put(job->irq_fence); dma_fence_put(job->done_fence); - pm_runtime_mark_last_busy(job->v3d->dev); - pm_runtime_put_autosuspend(job->v3d->dev); + pm_runtime_mark_last_busy(job->v3d->drm.dev); + pm_runtime_put_autosuspend(job->v3d->drm.dev); kfree(job); } @@ -439,7 +439,7 @@ v3d_job_init(struct v3d_dev *v3d, struct drm_file *file_priv, job->v3d = v3d; job->free = free; - ret = pm_runtime_get_sync(v3d->dev); + ret = pm_runtime_get_sync(v3d->drm.dev); if (ret < 0) return ret; @@ -458,7 +458,7 @@ v3d_job_init(struct v3d_dev *v3d, struct drm_file *file_priv, return 0; fail: xa_destroy(&job->deps); - pm_runtime_put_autosuspend(v3d->dev); + pm_runtime_put_autosuspend(v3d->drm.dev); return ret; } @@ -886,12 +886,12 @@ v3d_gem_init(struct drm_device *dev) */ drm_mm_init(&v3d->mm, 1, pt_size / sizeof(u32) - 1); - v3d->pt = dma_alloc_wc(v3d->dev, pt_size, + v3d->pt = dma_alloc_wc(v3d->drm.dev, pt_size, &v3d->pt_paddr, GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO); if (!v3d->pt) { drm_mm_takedown(&v3d->mm); - dev_err(v3d->dev, + dev_err(v3d->drm.dev, "Failed to allocate page tables. " "Please ensure you have CMA enabled.\n"); return -ENOMEM; @@ -903,7 +903,7 @@ v3d_gem_init(struct drm_device *dev) ret = v3d_sched_init(v3d); if (ret) { drm_mm_takedown(&v3d->mm); - dma_free_coherent(v3d->dev, 4096 * 1024, (void *)v3d->pt, + dma_free_coherent(v3d->drm.dev, 4096 * 1024, (void *)v3d->pt, v3d->pt_paddr); } @@ -925,5 +925,6 @@ v3d_gem_destroy(struct drm_device *dev) drm_mm_takedown(&v3d->mm); - dma_free_coherent(v3d->dev, 4096 * 1024, (void *)v3d->pt, v3d->pt_paddr); + dma_free_coherent(v3d->drm.dev, 4096 * 1024, (void *)v3d->pt, + v3d->pt_paddr); } diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c index 662e67279a7b..f4ce6d057c90 100644 --- a/drivers/gpu/drm/v3d/v3d_irq.c +++ b/drivers/gpu/drm/v3d/v3d_irq.c @@ -128,7 +128,7 @@ v3d_irq(int irq, void *arg) * always-allowed mode. */ if (intsts & V3D_INT_GMPV) - dev_err(v3d->dev, "GMP violation\n"); + dev_err(v3d->drm.dev, "GMP violation\n"); /* V3D 4.2 wires the hub and core IRQs together, so if we & * didn't see the common one then check hub for MMU IRQs. @@ -189,7 +189,7 @@ v3d_hub_irq(int irq, void *arg) client = v3d41_axi_ids[axi_id]; } - dev_err(v3d->dev, "MMU error from client %s (%d) at 0x%llx%s%s%s\n", + dev_err(v3d->drm.dev, "MMU error from client %s (%d) at 0x%llx%s%s%s\n", client, axi_id, (long long)vio_addr, ((intsts & V3D_HUB_INT_MMU_WRV) ? ", write violation" : ""), @@ -221,12 +221,12 @@ v3d_irq_init(struct v3d_dev *v3d) if (irq1 == -EPROBE_DEFER) return irq1; if (irq1 > 0) { - ret = devm_request_irq(v3d->dev, irq1, + ret = devm_request_irq(v3d->drm.dev, irq1, v3d_irq, IRQF_SHARED, "v3d_core0", v3d); if (ret) goto fail; - ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0), + ret = devm_request_irq(v3d->drm.dev, platform_get_irq(v3d->pdev, 0), v3d_hub_irq, IRQF_SHARED, "v3d_hub", v3d); if (ret) @@ -234,7 +234,7 @@ v3d_irq_init(struct v3d_dev *v3d) } else { v3d->single_irq_line = true; - ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0), + ret = devm_request_irq(v3d->drm.dev, platform_get_irq(v3d->pdev, 0), v3d_irq, IRQF_SHARED, "v3d", v3d); if (ret) @@ -246,7 +246,7 @@ v3d_irq_init(struct v3d_dev *v3d) fail: if (ret != -EPROBE_DEFER) - dev_err(v3d->dev, "IRQ setup failed: %d\n", ret); + dev_err(v3d->drm.dev, "IRQ setup failed: %d\n", ret); return ret; } diff --git a/drivers/gpu/drm/v3d/v3d_mmu.c b/drivers/gpu/drm/v3d/v3d_mmu.c index 395e81d97163..3b81ea28c0bb 100644 --- a/drivers/gpu/drm/v3d/v3d_mmu.c +++ b/drivers/gpu/drm/v3d/v3d_mmu.c @@ -40,7 +40,7 @@ static int v3d_mmu_flush_all(struct v3d_dev *v3d) ret = wait_for(!(V3D_READ(V3D_MMU_CTL) & V3D_MMU_CTL_TLB_CLEARING), 100); if (ret) - dev_err(v3d->dev, "TLB clear wait idle pre-wait failed\n"); + dev_err(v3d->drm.dev, "TLB clear wait idle pre-wait failed\n"); V3D_WRITE(V3D_MMU_CTL, V3D_READ(V3D_MMU_CTL) | V3D_MMU_CTL_TLB_CLEAR); @@ -52,14 +52,14 @@ static int v3d_mmu_flush_all(struct v3d_dev *v3d) ret = wait_for(!(V3D_READ(V3D_MMU_CTL) & V3D_MMU_CTL_TLB_CLEARING), 100); if (ret) { - dev_err(v3d->dev, "TLB clear wait idle failed\n"); + dev_err(v3d->drm.dev, "TLB clear wait idle failed\n"); return ret; } ret = wait_for(!(V3D_READ(V3D_MMUC_CONTROL) & V3D_MMUC_CONTROL_FLUSHING), 100); if (ret) - dev_err(v3d->dev, "MMUC flush wait idle failed\n"); + dev_err(v3d->drm.dev, "MMUC flush wait idle failed\n"); return ret; } @@ -109,7 +109,7 @@ void v3d_mmu_insert_ptes(struct v3d_bo *bo) shmem_obj->base.size >> V3D_MMU_PAGE_SHIFT); if (v3d_mmu_flush_all(v3d)) - dev_err(v3d->dev, "MMU flush timeout\n"); + dev_err(v3d->drm.dev, "MMU flush timeout\n"); } void v3d_mmu_remove_ptes(struct v3d_bo *bo) @@ -122,5 +122,5 @@ void v3d_mmu_remove_ptes(struct v3d_bo *bo) v3d->pt[page] = 0; if (v3d_mmu_flush_all(v3d)) - dev_err(v3d->dev, "MMU flush timeout\n"); + dev_err(v3d->drm.dev, "MMU flush timeout\n"); } diff --git a/drivers/gpu/drm/v3d/v3d_sched.c b/drivers/gpu/drm/v3d/v3d_sched.c index 8c2df6d95283..0747614a78f0 100644 --- a/drivers/gpu/drm/v3d/v3d_sched.c +++ b/drivers/gpu/drm/v3d/v3d_sched.c @@ -403,7 +403,7 @@ v3d_sched_init(struct v3d_dev *v3d) msecs_to_jiffies(hang_limit_ms), "v3d_bin"); if (ret) { - dev_err(v3d->dev, "Failed to create bin scheduler: %d.", ret); + dev_err(v3d->drm.dev, "Failed to create bin scheduler: %d.", ret); return ret; } @@ -413,7 +413,7 @@ v3d_sched_init(struct v3d_dev *v3d) msecs_to_jiffies(hang_limit_ms), "v3d_render"); if (ret) { - dev_err(v3d->dev, "Failed to create render scheduler: %d.", + dev_err(v3d->drm.dev, "Failed to create render scheduler: %d.", ret); v3d_sched_fini(v3d); return ret; @@ -425,7 +425,7 @@ v3d_sched_init(struct v3d_dev *v3d) msecs_to_jiffies(hang_limit_ms), "v3d_tfu"); if (ret) { - dev_err(v3d->dev, "Failed to create TFU scheduler: %d.", + dev_err(v3d->drm.dev, "Failed to create TFU scheduler: %d.", ret); v3d_sched_fini(v3d); return ret; @@ -438,7 +438,7 @@ v3d_sched_init(struct v3d_dev *v3d) msecs_to_jiffies(hang_limit_ms), "v3d_csd"); if (ret) { - dev_err(v3d->dev, "Failed to create CSD scheduler: %d.", + dev_err(v3d->drm.dev, "Failed to create CSD scheduler: %d.", ret); v3d_sched_fini(v3d); return ret; @@ -450,7 +450,7 @@ v3d_sched_init(struct v3d_dev *v3d) msecs_to_jiffies(hang_limit_ms), "v3d_cache_clean"); if (ret) { - dev_err(v3d->dev, "Failed to create CACHE_CLEAN scheduler: %d.", + dev_err(v3d->drm.dev, "Failed to create CACHE_CLEAN scheduler: %d.", ret); v3d_sched_fini(v3d); return ret; From 0df3ac7657c92756a26c164133380edbce672f7a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:45 +0200 Subject: [PATCH 043/109] drm/v3d: Delete v3d_dev->pdev We already have it in v3d_dev->drm.dev with zero additional pointer chasing. Personally I don't like duplicated pointers like this because: - reviewers need to check whether the pointer is for the same or different objects if there's multiple - compilers have an easier time too To avoid having to pull in some big headers I implemented the casting function as a macro instead of a static inline. Typechecking thanks to container_of still assured. But also a bit a bikeshed, so feel free to ignore. v2: More parens for v3d_to_pdev macro (checkpatch) Acked-by: Eric Anholt Signed-off-by: Daniel Vetter Cc: Eric Anholt Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-11-daniel.vetter@ffwll.ch --- drivers/gpu/drm/v3d/v3d_drv.c | 3 +-- drivers/gpu/drm/v3d/v3d_drv.h | 3 ++- drivers/gpu/drm/v3d/v3d_irq.c | 8 +++++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index 37cb880f2826..82a7dfdd14c2 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -235,7 +235,7 @@ static int map_regs(struct v3d_dev *v3d, void __iomem **regs, const char *name) { struct resource *res = - platform_get_resource_byname(v3d->pdev, IORESOURCE_MEM, name); + platform_get_resource_byname(v3d_to_pdev(v3d), IORESOURCE_MEM, name); *regs = devm_ioremap_resource(v3d->drm.dev, res); return PTR_ERR_OR_ZERO(*regs); @@ -255,7 +255,6 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) if (IS_ERR(v3d)) return PTR_ERR(v3d); - v3d->pdev = pdev; drm = &v3d->drm; platform_set_drvdata(pdev, drm); diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h index 4d2d1f2fe1af..8a390738d65b 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h @@ -46,7 +46,6 @@ struct v3d_dev { int ver; bool single_irq_line; - struct platform_device *pdev; void __iomem *hub_regs; void __iomem *core_regs[3]; void __iomem *bridge_regs; @@ -128,6 +127,8 @@ v3d_has_csd(struct v3d_dev *v3d) return v3d->ver >= 41; } +#define v3d_to_pdev(v3d) to_platform_device((v3d)->drm.dev) + /* The per-fd struct, which tracks the MMU mappings. */ struct v3d_file_priv { struct v3d_dev *v3d; diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c index f4ce6d057c90..51b65263c657 100644 --- a/drivers/gpu/drm/v3d/v3d_irq.c +++ b/drivers/gpu/drm/v3d/v3d_irq.c @@ -217,7 +217,7 @@ v3d_irq_init(struct v3d_dev *v3d) V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS); V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS); - irq1 = platform_get_irq(v3d->pdev, 1); + irq1 = platform_get_irq(v3d_to_pdev(v3d), 1); if (irq1 == -EPROBE_DEFER) return irq1; if (irq1 > 0) { @@ -226,7 +226,8 @@ v3d_irq_init(struct v3d_dev *v3d) "v3d_core0", v3d); if (ret) goto fail; - ret = devm_request_irq(v3d->drm.dev, platform_get_irq(v3d->pdev, 0), + ret = devm_request_irq(v3d->drm.dev, + platform_get_irq(v3d_to_pdev(v3d), 0), v3d_hub_irq, IRQF_SHARED, "v3d_hub", v3d); if (ret) @@ -234,7 +235,8 @@ v3d_irq_init(struct v3d_dev *v3d) } else { v3d->single_irq_line = true; - ret = devm_request_irq(v3d->drm.dev, platform_get_irq(v3d->pdev, 0), + ret = devm_request_irq(v3d->drm.dev, + platform_get_irq(v3d_to_pdev(v3d), 0), v3d_irq, IRQF_SHARED, "v3d", v3d); if (ret) From 50b9bbecaa5bdb78aaa51a39a01242016ed96314 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:46 +0200 Subject: [PATCH 044/109] drm/udl: Use devm_drm_dev_alloc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With Thomas' patch to clean up fbdev init this is a rather standard conversion to the new wrapper macro. v2: Rebase on top of Thomas' patches to remove the return value from drm_fbdev_generic_setup() v3: Update commit message to reflect the reality of the rebased patch (Sam) Reviewed-by: Thomas Zimmermann Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: Noralf Trønnes Cc: Dave Airlie Cc: Sean Paul Cc: Thomas Zimmermann Cc: Daniel Vetter Cc: Emil Velikov Cc: Sam Ravnborg Cc: Thomas Gleixner Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-12-daniel.vetter@ffwll.ch --- drivers/gpu/drm/udl/udl_drv.c | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 9cc6d075cb40..523f60e02a85 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -57,27 +57,20 @@ static struct udl_device *udl_driver_create(struct usb_interface *interface) struct udl_device *udl; int r; - udl = kzalloc(sizeof(*udl), GFP_KERNEL); - if (!udl) - return ERR_PTR(-ENOMEM); - - r = drm_dev_init(&udl->drm, &driver, &interface->dev); - if (r) { - kfree(udl); - return ERR_PTR(r); - } + udl = devm_drm_dev_alloc(&interface->dev, &driver, + struct udl_device, drm); + if (IS_ERR(udl)) + return udl; udl->udev = udev; udl->drm.dev_private = udl; - drmm_add_final_kfree(&udl->drm, udl); r = udl_init(udl); - if (r) { - drm_dev_put(&udl->drm); + if (r) return ERR_PTR(r); - } usb_set_intfdata(interface, udl); + return udl; } @@ -93,17 +86,13 @@ static int udl_usb_probe(struct usb_interface *interface, r = drm_dev_register(&udl->drm, 0); if (r) - goto err_free; + return r; DRM_INFO("Initialized udl on minor %d\n", udl->drm.primary->index); drm_fbdev_generic_setup(&udl->drm, 0); return 0; - -err_free: - drm_dev_put(&udl->drm); - return r; } static void udl_usb_disconnect(struct usb_interface *interface) @@ -113,7 +102,6 @@ static void udl_usb_disconnect(struct usb_interface *interface) drm_kms_helper_poll_fini(dev); udl_drop_usb(dev); drm_dev_unplug(dev); - drm_dev_put(dev); } /* From 6ae355a260d25d2bd465f89d1668300aaa9fec4c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:47 +0200 Subject: [PATCH 045/109] drm/udl: don't set drm_device->dev_private MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We're mostly there already, just a handful of places that didn't use the to_udl container_of cast. To make sure no new appear, don't set ->dev_private. Reviewed-by: Thomas Zimmermann Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: Dave Airlie Cc: Sean Paul Cc: Emil Velikov Cc: Thomas Zimmermann Cc: Daniel Vetter Cc: Alexios Zavras Cc: Laurent Pinchart Cc: Thomas Gleixner Cc: "José Roberto de Souza" Cc: Sam Ravnborg Cc: Gerd Hoffmann Cc: Allison Randal Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-13-daniel.vetter@ffwll.ch --- drivers/gpu/drm/udl/udl_connector.c | 4 ++-- drivers/gpu/drm/udl/udl_drv.c | 1 - drivers/gpu/drm/udl/udl_modeset.c | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c index 0afdfb0d1fe1..cdc1c42e1669 100644 --- a/drivers/gpu/drm/udl/udl_connector.c +++ b/drivers/gpu/drm/udl/udl_connector.c @@ -59,7 +59,7 @@ static int udl_get_modes(struct drm_connector *connector) static enum drm_mode_status udl_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - struct udl_device *udl = connector->dev->dev_private; + struct udl_device *udl = to_udl(connector->dev); if (!udl->sku_pixel_limit) return 0; @@ -72,7 +72,7 @@ static enum drm_mode_status udl_mode_valid(struct drm_connector *connector, static enum drm_connector_status udl_detect(struct drm_connector *connector, bool force) { - struct udl_device *udl = connector->dev->dev_private; + struct udl_device *udl = to_udl(connector->dev); struct udl_drm_connector *udl_connector = container_of(connector, struct udl_drm_connector, diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 523f60e02a85..d1aa50fd6d65 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -63,7 +63,6 @@ static struct udl_device *udl_driver_create(struct usb_interface *interface) return udl; udl->udev = udev; - udl->drm.dev_private = udl; r = udl_init(udl); if (r) diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index 8cad01f3d163..99518a826435 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c @@ -215,7 +215,7 @@ static char *udl_dummy_render(char *wrptr) static int udl_crtc_write_mode_to_hw(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct udl_device *udl = dev->dev_private; + struct udl_device *udl = to_udl(dev); struct urb *urb; char *buf; int retval; @@ -369,7 +369,7 @@ udl_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe, struct drm_crtc *crtc = &pipe->crtc; struct drm_device *dev = crtc->dev; struct drm_framebuffer *fb = plane_state->fb; - struct udl_device *udl = dev->dev_private; + struct udl_device *udl = to_udl(dev); struct drm_display_mode *mode = &crtc_state->mode; char *buf; char *wrptr; @@ -464,7 +464,7 @@ static const struct drm_mode_config_funcs udl_mode_funcs = { int udl_modeset_init(struct drm_device *dev) { size_t format_count = ARRAY_SIZE(udl_simple_display_pipe_formats); - struct udl_device *udl = dev->dev_private; + struct udl_device *udl = to_udl(dev); struct drm_connector *connector; int ret; From 14877bc715973d145d977e6054d5d2b6468ff460 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:48 +0200 Subject: [PATCH 046/109] drm/st7735r: Use devm_drm_dev_alloc Already using devm_drm_dev_init, so very simple replacment. Aside: There was an oddity in the old code, we allocated priv but in the error path we've freed priv->dbidev ... Acked-by: David Lechner Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: David Lechner Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-14-daniel.vetter@ffwll.ch --- drivers/gpu/drm/tiny/st7735r.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/tiny/st7735r.c b/drivers/gpu/drm/tiny/st7735r.c index c2c7dc0224dd..0af1b15efdf8 100644 --- a/drivers/gpu/drm/tiny/st7735r.c +++ b/drivers/gpu/drm/tiny/st7735r.c @@ -195,21 +195,16 @@ static int st7735r_probe(struct spi_device *spi) if (!cfg) cfg = (void *)spi_get_device_id(spi)->driver_data; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; + priv = devm_drm_dev_alloc(dev, &st7735r_driver, + struct st7735r_priv, dbidev.drm); + if (IS_ERR(priv)) + return PTR_ERR(priv); dbidev = &priv->dbidev; priv->cfg = cfg; dbi = &dbidev->dbi; drm = &dbidev->drm; - ret = devm_drm_dev_init(dev, drm, &st7735r_driver); - if (ret) { - kfree(dbidev); - return ret; - } - drmm_add_final_kfree(drm, dbidev); dbi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(dbi->reset)) { From e20b873802b6a8c8c65cd85ecf79a3615f3a0a5c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:49 +0200 Subject: [PATCH 047/109] drm/st7586: Use devm_drm_dev_alloc Already using devm_drm_dev_init, so very simple replacment. Acked-by: David Lechner Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: David Lechner Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-15-daniel.vetter@ffwll.ch --- drivers/gpu/drm/tiny/st7586.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/tiny/st7586.c b/drivers/gpu/drm/tiny/st7586.c index c3295c717ba6..2a1fae422f7a 100644 --- a/drivers/gpu/drm/tiny/st7586.c +++ b/drivers/gpu/drm/tiny/st7586.c @@ -317,18 +317,13 @@ static int st7586_probe(struct spi_device *spi) size_t bufsize; int ret; - dbidev = kzalloc(sizeof(*dbidev), GFP_KERNEL); - if (!dbidev) - return -ENOMEM; + dbidev = devm_drm_dev_alloc(dev, &st7586_driver, + struct mipi_dbi_dev, drm); + if (IS_ERR(dbidev)) + return PTR_ERR(dbidev); dbi = &dbidev->dbi; drm = &dbidev->drm; - ret = devm_drm_dev_init(dev, drm, &st7586_driver); - if (ret) { - kfree(dbidev); - return ret; - } - drmm_add_final_kfree(drm, dbidev); bufsize = (st7586_mode.vdisplay + 2) / 3 * st7586_mode.hdisplay; From 98904f3d2d92f4a3c3101dcaaa09eb5377f38ce8 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:50 +0200 Subject: [PATCH 048/109] drm/repaper: Use devm_drm_dev_alloc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Already using devm_drm_dev_init, so very simple replacment. Acked-by: Noralf Trønnes Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: "Noralf Trønnes" Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-16-daniel.vetter@ffwll.ch --- drivers/gpu/drm/tiny/repaper.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c index 862c3ee6055d..1c0e7169545b 100644 --- a/drivers/gpu/drm/tiny/repaper.c +++ b/drivers/gpu/drm/tiny/repaper.c @@ -1002,19 +1002,13 @@ static int repaper_probe(struct spi_device *spi) } } - epd = kzalloc(sizeof(*epd), GFP_KERNEL); - if (!epd) - return -ENOMEM; + epd = devm_drm_dev_alloc(dev, &repaper_driver, + struct repaper_epd, drm); + if (IS_ERR(epd)) + return PTR_ERR(epd); drm = &epd->drm; - ret = devm_drm_dev_init(dev, drm, &repaper_driver); - if (ret) { - kfree(epd); - return ret; - } - drmm_add_final_kfree(drm, epd); - ret = drmm_mode_config_init(drm); if (ret) return ret; From 35d8ef4ba24d2f8e4e69e8b6cf482658d128b2fb Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:51 +0200 Subject: [PATCH 049/109] drm/mi0283qt: Use devm_drm_dev_alloc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Already using devm_drm_dev_init, so very simple replacment. Acked-by: Noralf Trønnes Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: "Noralf Trønnes" Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-17-daniel.vetter@ffwll.ch --- drivers/gpu/drm/tiny/mi0283qt.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/tiny/mi0283qt.c b/drivers/gpu/drm/tiny/mi0283qt.c index decaf57053ff..08ac549ab0f7 100644 --- a/drivers/gpu/drm/tiny/mi0283qt.c +++ b/drivers/gpu/drm/tiny/mi0283qt.c @@ -187,18 +187,13 @@ static int mi0283qt_probe(struct spi_device *spi) u32 rotation = 0; int ret; - dbidev = kzalloc(sizeof(*dbidev), GFP_KERNEL); - if (!dbidev) - return -ENOMEM; + dbidev = devm_drm_dev_alloc(dev, &mi0283qt_driver, + struct mipi_dbi_dev, drm); + if (IS_ERR(dbidev)) + return PTR_ERR(dbidev); dbi = &dbidev->dbi; drm = &dbidev->drm; - ret = devm_drm_dev_init(dev, drm, &mi0283qt_driver); - if (ret) { - kfree(dbidev); - return ret; - } - drmm_add_final_kfree(drm, dbidev); dbi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(dbi->reset)) { From 3d49ea22946b9bee9c9344c2adc9857f2a3dc831 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:52 +0200 Subject: [PATCH 050/109] drm/ili9486: Use devm_drm_dev_alloc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Already using devm_drm_dev_init, so very simple replacment. Acked-by: Noralf Trønnes Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: Kamlesh Gurudasani Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-18-daniel.vetter@ffwll.ch --- drivers/gpu/drm/tiny/ili9486.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/tiny/ili9486.c b/drivers/gpu/drm/tiny/ili9486.c index c4079bf9e2c8..2702ea557d29 100644 --- a/drivers/gpu/drm/tiny/ili9486.c +++ b/drivers/gpu/drm/tiny/ili9486.c @@ -197,18 +197,13 @@ static int ili9486_probe(struct spi_device *spi) u32 rotation = 0; int ret; - dbidev = kzalloc(sizeof(*dbidev), GFP_KERNEL); - if (!dbidev) - return -ENOMEM; + dbidev = devm_drm_dev_alloc(dev, &ili9486_driver, + struct mipi_dbi_dev, drm); + if (IS_ERR(dbidev)) + return PTR_ERR(dbidev); dbi = &dbidev->dbi; drm = &dbidev->drm; - ret = devm_drm_dev_init(dev, drm, &ili9486_driver); - if (ret) { - kfree(dbidev); - return ret; - } - drmm_add_final_kfree(drm, dbidev); dbi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(dbi->reset)) { From 5301e305c682a879666371cdcddf37bbce2ef77e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:53 +0200 Subject: [PATCH 051/109] drm/ili9341: Use devm_drm_dev_alloc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Already using devm_drm_dev_init, so very simple replacment. Acked-by: David Lechner Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: "Noralf Trønnes" Cc: Sam Ravnborg Cc: Daniel Vetter Cc: Eric Anholt Cc: David Lechner Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-19-daniel.vetter@ffwll.ch --- drivers/gpu/drm/tiny/ili9341.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/tiny/ili9341.c b/drivers/gpu/drm/tiny/ili9341.c index e152de369019..bb819f45a5d3 100644 --- a/drivers/gpu/drm/tiny/ili9341.c +++ b/drivers/gpu/drm/tiny/ili9341.c @@ -183,18 +183,13 @@ static int ili9341_probe(struct spi_device *spi) u32 rotation = 0; int ret; - dbidev = kzalloc(sizeof(*dbidev), GFP_KERNEL); - if (!dbidev) - return -ENOMEM; + dbidev = devm_drm_dev_alloc(dev, &ili9341_driver, + struct mipi_dbi_dev, drm); + if (IS_ERR(dbidev)) + return PTR_ERR(dbidev); dbi = &dbidev->dbi; drm = &dbidev->drm; - ret = devm_drm_dev_init(dev, drm, &ili9341_driver); - if (ret) { - kfree(dbidev); - return ret; - } - drmm_add_final_kfree(drm, dbidev); dbi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(dbi->reset)) { From 4c99859f3bf9e40e7859878b697adb8581cb6ac0 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:54 +0200 Subject: [PATCH 052/109] drm/ili9225: Use devm_drm_dev_alloc Already using devm_drm_dev_init, so very simple replacment. Acked-by: David Lechner Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: David Lechner Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-20-daniel.vetter@ffwll.ch --- drivers/gpu/drm/tiny/ili9225.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/tiny/ili9225.c b/drivers/gpu/drm/tiny/ili9225.c index 118477af4491..d1a5ab6747d5 100644 --- a/drivers/gpu/drm/tiny/ili9225.c +++ b/drivers/gpu/drm/tiny/ili9225.c @@ -376,18 +376,13 @@ static int ili9225_probe(struct spi_device *spi) u32 rotation = 0; int ret; - dbidev = kzalloc(sizeof(*dbidev), GFP_KERNEL); - if (!dbidev) - return -ENOMEM; + dbidev = devm_drm_dev_alloc(dev, &ili9225_driver, + struct mipi_dbi_dev, drm); + if (IS_ERR(dbidev)) + return PTR_ERR(dbidev); dbi = &dbidev->dbi; drm = &dbidev->drm; - ret = devm_drm_dev_init(dev, drm, &ili9225_driver); - if (ret) { - kfree(dbidev); - return ret; - } - drmm_add_final_kfree(drm, dbidev); dbi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(dbi->reset)) { From f3eb15bb796dcd7dd5171736a475ee6248d96918 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:55 +0200 Subject: [PATCH 053/109] drm/hx8357d: Use devm_drm_dev_alloc Already using devm_drm_dev_init, so very simple replacment. Acked-by: Eric Anholt Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: Eric Anholt Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-21-daniel.vetter@ffwll.ch --- drivers/gpu/drm/tiny/hx8357d.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/tiny/hx8357d.c b/drivers/gpu/drm/tiny/hx8357d.c index af7f3d10aac3..b4bc358a3269 100644 --- a/drivers/gpu/drm/tiny/hx8357d.c +++ b/drivers/gpu/drm/tiny/hx8357d.c @@ -226,17 +226,12 @@ static int hx8357d_probe(struct spi_device *spi) u32 rotation = 0; int ret; - dbidev = kzalloc(sizeof(*dbidev), GFP_KERNEL); - if (!dbidev) - return -ENOMEM; + dbidev = devm_drm_dev_alloc(dev, &hx8357d_driver, + struct mipi_dbi_dev, drm); + if (IS_ERR(dbidev)) + return PTR_ERR(dbidev); drm = &dbidev->drm; - ret = devm_drm_dev_init(dev, drm, &hx8357d_driver); - if (ret) { - kfree(dbidev); - return ret; - } - drmm_add_final_kfree(drm, dbidev); dc = devm_gpiod_get(dev, "dc", GPIOD_OUT_LOW); if (IS_ERR(dc)) { From 9213142d6b8c9065323d4c1e221751a22e4935cc Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:56 +0200 Subject: [PATCH 054/109] drm/gm12u320: Use devm_drm_dev_alloc Already using devm_drm_dev_init, so very simple replacment. Acked-by: Sam Ravnborg Reviewed-by: Hans de Goede Signed-off-by: Daniel Vetter Cc: Hans de Goede Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-22-daniel.vetter@ffwll.ch --- drivers/gpu/drm/tiny/gm12u320.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c index 6f0ea2827d62..907739a67bf6 100644 --- a/drivers/gpu/drm/tiny/gm12u320.c +++ b/drivers/gpu/drm/tiny/gm12u320.c @@ -631,22 +631,17 @@ static int gm12u320_usb_probe(struct usb_interface *interface, if (interface->cur_altsetting->desc.bInterfaceNumber != 0) return -ENODEV; - gm12u320 = kzalloc(sizeof(*gm12u320), GFP_KERNEL); - if (gm12u320 == NULL) - return -ENOMEM; + gm12u320 = devm_drm_dev_alloc(&interface->dev, &gm12u320_drm_driver, + struct gm12u320_device, dev); + if (IS_ERR(gm12u320)) + return PTR_ERR(gm12u320); gm12u320->udev = interface_to_usbdev(interface); INIT_DELAYED_WORK(&gm12u320->fb_update.work, gm12u320_fb_update_work); mutex_init(&gm12u320->fb_update.lock); dev = &gm12u320->dev; - ret = devm_drm_dev_init(&interface->dev, dev, &gm12u320_drm_driver); - if (ret) { - kfree(gm12u320); - return ret; - } dev->dev_private = gm12u320; - drmm_add_final_kfree(dev, gm12u320); ret = drmm_mode_config_init(dev); if (ret) From 7ced4801d26746df3211d9ebf4b6b70daa7dffec Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:57 +0200 Subject: [PATCH 055/109] drm/gm12u320: Don't use drm_device->dev_private Upcasting using a container_of macro is more typesafe, faster and easier for the compiler to optimize. Acked-by: Sam Ravnborg Reviewed-by: Hans de Goede Signed-off-by: Daniel Vetter Cc: Hans de Goede Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-23-daniel.vetter@ffwll.ch --- drivers/gpu/drm/tiny/gm12u320.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c index 907739a67bf6..cc397671f689 100644 --- a/drivers/gpu/drm/tiny/gm12u320.c +++ b/drivers/gpu/drm/tiny/gm12u320.c @@ -98,6 +98,8 @@ struct gm12u320_device { } fb_update; }; +#define to_gm12u320(__dev) container_of(__dev, struct gm12u320_device, dev) + static const char cmd_data[CMD_SIZE] = { 0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x68, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, @@ -408,7 +410,7 @@ err: static void gm12u320_fb_mark_dirty(struct drm_framebuffer *fb, struct drm_rect *dirty) { - struct gm12u320_device *gm12u320 = fb->dev->dev_private; + struct gm12u320_device *gm12u320 = to_gm12u320(fb->dev); struct drm_framebuffer *old_fb = NULL; bool wakeup = false; @@ -558,7 +560,7 @@ static void gm12u320_pipe_enable(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state) { struct drm_rect rect = { 0, 0, GM12U320_USER_WIDTH, GM12U320_HEIGHT }; - struct gm12u320_device *gm12u320 = pipe->crtc.dev->dev_private; + struct gm12u320_device *gm12u320 = to_gm12u320(pipe->crtc.dev); gm12u320->fb_update.draw_status_timeout = FIRST_FRAME_TIMEOUT; gm12u320_fb_mark_dirty(plane_state->fb, &rect); @@ -566,7 +568,7 @@ static void gm12u320_pipe_enable(struct drm_simple_display_pipe *pipe, static void gm12u320_pipe_disable(struct drm_simple_display_pipe *pipe) { - struct gm12u320_device *gm12u320 = pipe->crtc.dev->dev_private; + struct gm12u320_device *gm12u320 = to_gm12u320(pipe->crtc.dev); gm12u320_stop_fb_update(gm12u320); } @@ -641,7 +643,6 @@ static int gm12u320_usb_probe(struct usb_interface *interface, mutex_init(&gm12u320->fb_update.lock); dev = &gm12u320->dev; - dev->dev_private = gm12u320; ret = drmm_mode_config_init(dev); if (ret) @@ -706,7 +707,7 @@ static __maybe_unused int gm12u320_suspend(struct usb_interface *interface, static __maybe_unused int gm12u320_resume(struct usb_interface *interface) { struct drm_device *dev = usb_get_intfdata(interface); - struct gm12u320_device *gm12u320 = dev->dev_private; + struct gm12u320_device *gm12u320 = to_gm12u320(dev); gm12u320_set_ecomode(gm12u320); From b3b134007e2c795f78bb34bc92ee68608cb92b04 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:58 +0200 Subject: [PATCH 056/109] drm/tidss: Use devm_drm_dev_alloc Already using devm_drm_dev_init, so very simple replacment. Tested-by: Jyri Sarha Acked-by: Sam Ravnborg Reviewed-by: Tomi Valkeinen Signed-off-by: Daniel Vetter Cc: Jyri Sarha Cc: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-24-daniel.vetter@ffwll.ch --- drivers/gpu/drm/tidss/tidss_drv.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c index ad449d104306..7d4465d58be8 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.c +++ b/drivers/gpu/drm/tidss/tidss_drv.c @@ -135,20 +135,13 @@ static int tidss_probe(struct platform_device *pdev) dev_dbg(dev, "%s\n", __func__); - /* Can't use devm_* since drm_device's lifetime may exceed dev's */ - tidss = kzalloc(sizeof(*tidss), GFP_KERNEL); - if (!tidss) - return -ENOMEM; + tidss = devm_drm_dev_alloc(&pdev->dev, &tidss_driver, + struct tidss_device, ddev); + if (IS_ERR(tidss)) + return PTR_ERR(tidss); ddev = &tidss->ddev; - ret = devm_drm_dev_init(&pdev->dev, ddev, &tidss_driver); - if (ret) { - kfree(ddev); - return ret; - } - drmm_add_final_kfree(ddev, tidss); - tidss->dev = dev; tidss->feat = of_device_get_match_data(dev); From 02bb1317d5e4002e65a3debfb27ae2a1bfd0a3c2 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:39:59 +0200 Subject: [PATCH 057/109] drm/tidss: Don't use drm_device->dev_private Upcasting using a container_of macro is more typesafe, faster and easier for the compiler to optimize. Tested-by: Jyri Sarha Acked-by: Sam Ravnborg Reviewed-by: Tomi Valkeinen Signed-off-by: Daniel Vetter Cc: Jyri Sarha Cc: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-25-daniel.vetter@ffwll.ch --- drivers/gpu/drm/tidss/tidss_crtc.c | 16 ++++++++-------- drivers/gpu/drm/tidss/tidss_drv.c | 2 -- drivers/gpu/drm/tidss/tidss_drv.h | 2 ++ drivers/gpu/drm/tidss/tidss_irq.c | 12 ++++++------ drivers/gpu/drm/tidss/tidss_kms.c | 2 +- drivers/gpu/drm/tidss/tidss_plane.c | 6 +++--- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tidss_crtc.c index d4ce9bab8c7e..2396262c09e4 100644 --- a/drivers/gpu/drm/tidss/tidss_crtc.c +++ b/drivers/gpu/drm/tidss/tidss_crtc.c @@ -24,7 +24,7 @@ static void tidss_crtc_finish_page_flip(struct tidss_crtc *tcrtc) { struct drm_device *ddev = tcrtc->crtc.dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); struct drm_pending_vblank_event *event; unsigned long flags; bool busy; @@ -88,7 +88,7 @@ static int tidss_crtc_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { struct drm_device *ddev = crtc->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); struct dispc_device *dispc = tidss->dispc; struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); u32 hw_videoport = tcrtc->hw_videoport; @@ -165,7 +165,7 @@ static void tidss_crtc_atomic_flush(struct drm_crtc *crtc, { struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); struct drm_device *ddev = crtc->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); unsigned long flags; dev_dbg(ddev->dev, @@ -216,7 +216,7 @@ static void tidss_crtc_atomic_enable(struct drm_crtc *crtc, { struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); struct drm_device *ddev = crtc->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); const struct drm_display_mode *mode = &crtc->state->adjusted_mode; unsigned long flags; int r; @@ -259,7 +259,7 @@ static void tidss_crtc_atomic_disable(struct drm_crtc *crtc, { struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); struct drm_device *ddev = crtc->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); unsigned long flags; dev_dbg(ddev->dev, "%s, event %p\n", __func__, crtc->state->event); @@ -295,7 +295,7 @@ enum drm_mode_status tidss_crtc_mode_valid(struct drm_crtc *crtc, { struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); struct drm_device *ddev = crtc->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); return dispc_vp_mode_valid(tidss->dispc, tcrtc->hw_videoport, mode); } @@ -314,7 +314,7 @@ static const struct drm_crtc_helper_funcs tidss_crtc_helper_funcs = { static int tidss_crtc_enable_vblank(struct drm_crtc *crtc) { struct drm_device *ddev = crtc->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); dev_dbg(ddev->dev, "%s\n", __func__); @@ -328,7 +328,7 @@ static int tidss_crtc_enable_vblank(struct drm_crtc *crtc) static void tidss_crtc_disable_vblank(struct drm_crtc *crtc) { struct drm_device *ddev = crtc->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); dev_dbg(ddev->dev, "%s\n", __func__); diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c index 7d4465d58be8..99edc66ebdef 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.c +++ b/drivers/gpu/drm/tidss/tidss_drv.c @@ -147,8 +147,6 @@ static int tidss_probe(struct platform_device *pdev) platform_set_drvdata(pdev, tidss); - ddev->dev_private = tidss; - ret = dispc_init(tidss); if (ret) { dev_err(dev, "failed to initialize dispc: %d\n", ret); diff --git a/drivers/gpu/drm/tidss/tidss_drv.h b/drivers/gpu/drm/tidss/tidss_drv.h index e2aa6436ad18..b23cd95c8d78 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.h +++ b/drivers/gpu/drm/tidss/tidss_drv.h @@ -33,6 +33,8 @@ struct tidss_device { struct drm_atomic_state *saved_state; }; +#define to_tidss(__dev) container_of(__dev, struct tidss_device, ddev) + int tidss_runtime_get(struct tidss_device *tidss); void tidss_runtime_put(struct tidss_device *tidss); diff --git a/drivers/gpu/drm/tidss/tidss_irq.c b/drivers/gpu/drm/tidss/tidss_irq.c index 612c046738e5..1b80f2d62e0a 100644 --- a/drivers/gpu/drm/tidss/tidss_irq.c +++ b/drivers/gpu/drm/tidss/tidss_irq.c @@ -23,7 +23,7 @@ static void tidss_irq_update(struct tidss_device *tidss) void tidss_irq_enable_vblank(struct drm_crtc *crtc) { struct drm_device *ddev = crtc->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); u32 hw_videoport = tcrtc->hw_videoport; unsigned long flags; @@ -38,7 +38,7 @@ void tidss_irq_enable_vblank(struct drm_crtc *crtc) void tidss_irq_disable_vblank(struct drm_crtc *crtc) { struct drm_device *ddev = crtc->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); u32 hw_videoport = tcrtc->hw_videoport; unsigned long flags; @@ -53,7 +53,7 @@ void tidss_irq_disable_vblank(struct drm_crtc *crtc) irqreturn_t tidss_irq_handler(int irq, void *arg) { struct drm_device *ddev = (struct drm_device *)arg; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); unsigned int id; dispc_irq_t irqstatus; @@ -95,7 +95,7 @@ void tidss_irq_resume(struct tidss_device *tidss) void tidss_irq_preinstall(struct drm_device *ddev) { - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); spin_lock_init(&tidss->wait_lock); @@ -109,7 +109,7 @@ void tidss_irq_preinstall(struct drm_device *ddev) int tidss_irq_postinstall(struct drm_device *ddev) { - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); unsigned long flags; unsigned int i; @@ -138,7 +138,7 @@ int tidss_irq_postinstall(struct drm_device *ddev) void tidss_irq_uninstall(struct drm_device *ddev) { - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); tidss_runtime_get(tidss); dispc_set_irqenable(tidss->dispc, 0); diff --git a/drivers/gpu/drm/tidss/tidss_kms.c b/drivers/gpu/drm/tidss/tidss_kms.c index 4bd339a467a4..4b99e9fa84a5 100644 --- a/drivers/gpu/drm/tidss/tidss_kms.c +++ b/drivers/gpu/drm/tidss/tidss_kms.c @@ -25,7 +25,7 @@ static void tidss_atomic_commit_tail(struct drm_atomic_state *old_state) { struct drm_device *ddev = old_state->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); dev_dbg(ddev->dev, "%s\n", __func__); diff --git a/drivers/gpu/drm/tidss/tidss_plane.c b/drivers/gpu/drm/tidss/tidss_plane.c index ff99b2dd4a17..23bb3e59504b 100644 --- a/drivers/gpu/drm/tidss/tidss_plane.c +++ b/drivers/gpu/drm/tidss/tidss_plane.c @@ -22,7 +22,7 @@ static int tidss_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { struct drm_device *ddev = plane->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); struct tidss_plane *tplane = to_tidss_plane(plane); const struct drm_format_info *finfo; struct drm_crtc_state *crtc_state; @@ -101,7 +101,7 @@ static void tidss_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { struct drm_device *ddev = plane->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); struct tidss_plane *tplane = to_tidss_plane(plane); struct drm_plane_state *state = plane->state; u32 hw_videoport; @@ -133,7 +133,7 @@ static void tidss_plane_atomic_disable(struct drm_plane *plane, struct drm_plane_state *old_state) { struct drm_device *ddev = plane->dev; - struct tidss_device *tidss = ddev->dev_private; + struct tidss_device *tidss = to_tidss(ddev); struct tidss_plane *tplane = to_tidss_plane(plane); dev_dbg(ddev->dev, "%s\n", __func__); From 3927037003f97fc0e57a6804e95bb186e3d22194 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:40:00 +0200 Subject: [PATCH 058/109] drm/tidss: Delete tidss->saved_state Not used anymore since the switch to suspend/resume helpers. Tested-by: Jyri Sarha Acked-by: Sam Ravnborg Reviewed-by: Tomi Valkeinen Signed-off-by: Daniel Vetter Cc: Jyri Sarha Cc: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-26-daniel.vetter@ffwll.ch --- drivers/gpu/drm/tidss/tidss_drv.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_drv.h b/drivers/gpu/drm/tidss/tidss_drv.h index b23cd95c8d78..3b0a3d87b7c4 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.h +++ b/drivers/gpu/drm/tidss/tidss_drv.h @@ -29,8 +29,6 @@ struct tidss_device { spinlock_t wait_lock; /* protects the irq masks */ dispc_irq_t irq_mask; /* enabled irqs in addition to wait_list */ - - struct drm_atomic_state *saved_state; }; #define to_tidss(__dev) container_of(__dev, struct tidss_device, ddev) From 6ff71edfcb0be37c803da51e1b893809ead22203 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:40:03 +0200 Subject: [PATCH 059/109] drm/mcde: Use devm_drm_dev_alloc Already using devm_drm_dev_init, so very simple replacment. v2: Move misplaced double-assignement to next patch (Sam) Acked-by: Sam Ravnborg Reviewed-by: Linus Walleij Signed-off-by: Daniel Vetter Cc: Linus Walleij Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-29-daniel.vetter@ffwll.ch --- drivers/gpu/drm/mcde/mcde_drv.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c index 88cc6b4a7a64..22003478db2c 100644 --- a/drivers/gpu/drm/mcde/mcde_drv.c +++ b/drivers/gpu/drm/mcde/mcde_drv.c @@ -307,19 +307,12 @@ static int mcde_probe(struct platform_device *pdev) int ret; int i; - mcde = kzalloc(sizeof(*mcde), GFP_KERNEL); - if (!mcde) - return -ENOMEM; - mcde->dev = dev; - - ret = devm_drm_dev_init(dev, &mcde->drm, &mcde_drm_driver); - if (ret) { - kfree(mcde); - return ret; - } + mcde = devm_drm_dev_alloc(dev, &mcde_drm_driver, struct mcde, drm); + if (IS_ERR(mcde)) + return PTR_ERR(mcde); drm = &mcde->drm; drm->dev_private = mcde; - drmm_add_final_kfree(drm, mcde); + mcde->dev = dev; platform_set_drvdata(pdev, drm); /* Enable continuous updates: this is what Linux' framebuffer expects */ From fd7ee85cfe7bad518da9dd17dd6ee44199e20833 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:40:04 +0200 Subject: [PATCH 060/109] drm/mcde: Don't use drm_device->dev_private Upcasting using a container_of macro is more typesafe, faster and easier for the compiler to optimize. v2: Move misplaced removal of double-assignment to this patch (Sam) Reviewed-by: Linus Walleij (v1) Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: Linus Walleij Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-30-daniel.vetter@ffwll.ch --- drivers/gpu/drm/mcde/mcde_display.c | 10 +++++----- drivers/gpu/drm/mcde/mcde_drm.h | 2 ++ drivers/gpu/drm/mcde/mcde_drv.c | 6 ++---- drivers/gpu/drm/mcde/mcde_dsi.c | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/mcde/mcde_display.c b/drivers/gpu/drm/mcde/mcde_display.c index e59907e68854..04e1d38d41f7 100644 --- a/drivers/gpu/drm/mcde/mcde_display.c +++ b/drivers/gpu/drm/mcde/mcde_display.c @@ -948,7 +948,7 @@ static void mcde_display_disable(struct drm_simple_display_pipe *pipe) { struct drm_crtc *crtc = &pipe->crtc; struct drm_device *drm = crtc->dev; - struct mcde *mcde = drm->dev_private; + struct mcde *mcde = to_mcde(drm); struct drm_pending_vblank_event *event; drm_crtc_vblank_off(crtc); @@ -1020,7 +1020,7 @@ static void mcde_display_update(struct drm_simple_display_pipe *pipe, { struct drm_crtc *crtc = &pipe->crtc; struct drm_device *drm = crtc->dev; - struct mcde *mcde = drm->dev_private; + struct mcde *mcde = to_mcde(drm); struct drm_pending_vblank_event *event = crtc->state->event; struct drm_plane *plane = &pipe->plane; struct drm_plane_state *pstate = plane->state; @@ -1078,7 +1078,7 @@ static int mcde_display_enable_vblank(struct drm_simple_display_pipe *pipe) { struct drm_crtc *crtc = &pipe->crtc; struct drm_device *drm = crtc->dev; - struct mcde *mcde = drm->dev_private; + struct mcde *mcde = to_mcde(drm); u32 val; /* Enable all VBLANK IRQs */ @@ -1097,7 +1097,7 @@ static void mcde_display_disable_vblank(struct drm_simple_display_pipe *pipe) { struct drm_crtc *crtc = &pipe->crtc; struct drm_device *drm = crtc->dev; - struct mcde *mcde = drm->dev_private; + struct mcde *mcde = to_mcde(drm); /* Disable all VBLANK IRQs */ writel(0, mcde->regs + MCDE_IMSCPP); @@ -1117,7 +1117,7 @@ static struct drm_simple_display_pipe_funcs mcde_display_funcs = { int mcde_display_init(struct drm_device *drm) { - struct mcde *mcde = drm->dev_private; + struct mcde *mcde = to_mcde(drm); int ret; static const u32 formats[] = { DRM_FORMAT_ARGB8888, diff --git a/drivers/gpu/drm/mcde/mcde_drm.h b/drivers/gpu/drm/mcde/mcde_drm.h index 80edd6628979..679c2c4e6d9d 100644 --- a/drivers/gpu/drm/mcde/mcde_drm.h +++ b/drivers/gpu/drm/mcde/mcde_drm.h @@ -34,6 +34,8 @@ struct mcde { struct regulator *vana; }; +#define to_mcde(dev) container_of(dev, struct mcde, drm) + bool mcde_dsi_irq(struct mipi_dsi_device *mdsi); void mcde_dsi_te_request(struct mipi_dsi_device *mdsi); extern struct platform_driver mcde_dsi_driver; diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c index 22003478db2c..84f3e2dbd77b 100644 --- a/drivers/gpu/drm/mcde/mcde_drv.c +++ b/drivers/gpu/drm/mcde/mcde_drv.c @@ -164,7 +164,7 @@ static irqreturn_t mcde_irq(int irq, void *data) static int mcde_modeset_init(struct drm_device *drm) { struct drm_mode_config *mode_config; - struct mcde *mcde = drm->dev_private; + struct mcde *mcde = to_mcde(drm); int ret; if (!mcde->bridge) { @@ -311,13 +311,11 @@ static int mcde_probe(struct platform_device *pdev) if (IS_ERR(mcde)) return PTR_ERR(mcde); drm = &mcde->drm; - drm->dev_private = mcde; mcde->dev = dev; platform_set_drvdata(pdev, drm); /* Enable continuous updates: this is what Linux' framebuffer expects */ mcde->oneshot_mode = false; - drm->dev_private = mcde; /* First obtain and turn on the main power */ mcde->epod = devm_regulator_get(dev, "epod"); @@ -487,7 +485,7 @@ regulator_epod_off: static int mcde_remove(struct platform_device *pdev) { struct drm_device *drm = platform_get_drvdata(pdev); - struct mcde *mcde = drm->dev_private; + struct mcde *mcde = to_mcde(drm); component_master_del(&pdev->dev, &mcde_drm_comp_ops); clk_disable_unprepare(mcde->mcde_clk); diff --git a/drivers/gpu/drm/mcde/mcde_dsi.c b/drivers/gpu/drm/mcde/mcde_dsi.c index 7af5ebb0c436..1baa2324cdb9 100644 --- a/drivers/gpu/drm/mcde/mcde_dsi.c +++ b/drivers/gpu/drm/mcde/mcde_dsi.c @@ -1020,7 +1020,7 @@ static int mcde_dsi_bind(struct device *dev, struct device *master, void *data) { struct drm_device *drm = data; - struct mcde *mcde = drm->dev_private; + struct mcde *mcde = to_mcde(drm); struct mcde_dsi *d = dev_get_drvdata(dev); struct device_node *child; struct drm_panel *panel = NULL; From 37d8d81f019ac1bdfb2f7668f783604604782868 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:40:05 +0200 Subject: [PATCH 061/109] drm/ingenic: Use devm_drm_dev_alloc Already using devm_drm_dev_init, so very simple replacment. Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: Paul Cercueil Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-31-daniel.vetter@ffwll.ch --- drivers/gpu/drm/ingenic/ingenic-drm.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c index 24cc3587cea5..2dd1f3020fcb 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm.c @@ -611,9 +611,10 @@ static int ingenic_drm_probe(struct platform_device *pdev) return -EINVAL; } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; + priv = devm_drm_dev_alloc(dev, &ingenic_drm_driver_data, + struct ingenic_drm, drm); + if (IS_ERR(priv)) + return PTR_ERR(priv); priv->soc_info = soc_info; priv->dev = dev; @@ -622,13 +623,6 @@ static int ingenic_drm_probe(struct platform_device *pdev) platform_set_drvdata(pdev, priv); - ret = devm_drm_dev_init(dev, drm, &ingenic_drm_driver_data); - if (ret) { - kfree(priv); - return ret; - } - drmm_add_final_kfree(drm, priv); - ret = drmm_mode_config_init(drm); if (ret) return ret; From b8d91c0a770e2c6608a3cacc82f3674d9745c90e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:40:06 +0200 Subject: [PATCH 062/109] drm/ingenic: Don't set drm_device->dev_private Entirely not used, just copypasta. Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: Paul Cercueil Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-32-daniel.vetter@ffwll.ch --- drivers/gpu/drm/ingenic/ingenic-drm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c index 2dd1f3020fcb..632d72177123 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm.c @@ -619,7 +619,6 @@ static int ingenic_drm_probe(struct platform_device *pdev) priv->soc_info = soc_info; priv->dev = dev; drm = &priv->drm; - drm->dev_private = priv; platform_set_drvdata(pdev, priv); From 843ef624a491fabc3f0829c341a33fc4cc008000 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:40:07 +0200 Subject: [PATCH 063/109] drm/komeda: use devm_drm_dev_alloc Komeda uses the component framework, which does open/close a new devres group around all the bind callbacks. Which means we can use devm_ functions for managing the drm_device cleanup, with leaking stuff in case of deferred probes or other reasons to unbind components, or the component_master. Also note that this fixes a double-free in the probe unroll code, bot drm_dev_put and kfree(kms) result in the kms allocation getting freed. Aside: komeda_bind could be cleaned up a lot, devm_kfree is a bit redundant. Plus I'm not clear on why there's suballocations for mdrv->mdev and mdrv->kms. Plus I'm not sure the lifetimes are correct with all that devm_kzalloc usage ... That structure layout is also the reason why komeda still uses drm_device->dev_private and can't easily be replaced with a proper container_of upcasting. I'm pretty sure that there's endless amounts of hotunplug/hotremove bugs in there with all the unprotected dereferencing of drm_device->dev_private. Reviewed-by: James Qian Wang Signed-off-by: Daniel Vetter Cc: "James (Qian) Wang" Cc: Liviu Dudau Cc: Mihail Atanassov Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-33-daniel.vetter@ffwll.ch --- drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c index 16dfd5cdb66c..6b85d5f4caa8 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c @@ -261,18 +261,16 @@ static void komeda_kms_mode_config_init(struct komeda_kms_dev *kms, struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev) { - struct komeda_kms_dev *kms = kzalloc(sizeof(*kms), GFP_KERNEL); + struct komeda_kms_dev *kms; struct drm_device *drm; int err; - if (!kms) - return ERR_PTR(-ENOMEM); + kms = devm_drm_dev_alloc(mdev->dev, &komeda_kms_driver, + struct komeda_kms_dev, base); + if (IS_ERR(kms)) + return kms; drm = &kms->base; - err = drm_dev_init(drm, &komeda_kms_driver, mdev->dev); - if (err) - goto free_kms; - drmm_add_final_kfree(drm, kms); drm->dev_private = mdev; @@ -329,9 +327,6 @@ cleanup_mode_config: drm_mode_config_cleanup(drm); komeda_kms_cleanup_private_objs(kms); drm->dev_private = NULL; - drm_dev_put(drm); -free_kms: - kfree(kms); return ERR_PTR(err); } @@ -348,5 +343,4 @@ void komeda_kms_detach(struct komeda_kms_dev *kms) drm_mode_config_cleanup(drm); komeda_kms_cleanup_private_objs(kms); drm->dev_private = NULL; - drm_dev_put(drm); } From 9bb2e63705a1a1cacd05b094b7fd9a1b28fa00f2 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:40:10 +0200 Subject: [PATCH 064/109] drm/cirrus: Use devm_drm_dev_alloc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Already using devm_drm_dev_init, so very simple replacment. Acked-by: Noralf Trønnes Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: Dave Airlie Cc: Gerd Hoffmann Cc: Daniel Vetter Cc: Sam Ravnborg Cc: "Noralf Trønnes" Cc: Rob Herring Cc: Thomas Zimmermann Cc: virtualization@lists.linux-foundation.org Cc: Emil Velikov Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-36-daniel.vetter@ffwll.ch --- drivers/gpu/drm/cirrus/cirrus.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/cirrus/cirrus.c b/drivers/gpu/drm/cirrus/cirrus.c index a36269717c3b..4b65637147ba 100644 --- a/drivers/gpu/drm/cirrus/cirrus.c +++ b/drivers/gpu/drm/cirrus/cirrus.c @@ -567,18 +567,13 @@ static int cirrus_pci_probe(struct pci_dev *pdev, return ret; ret = -ENOMEM; - cirrus = kzalloc(sizeof(*cirrus), GFP_KERNEL); - if (cirrus == NULL) - return ret; + cirrus = devm_drm_dev_alloc(&pdev->dev, &cirrus_driver, + struct cirrus_device, dev); + if (IS_ERR(cirrus)) + return PTR_ERR(cirrus); dev = &cirrus->dev; - ret = devm_drm_dev_init(&pdev->dev, dev, &cirrus_driver); - if (ret) { - kfree(cirrus); - return ret; - } dev->dev_private = cirrus; - drmm_add_final_kfree(dev, cirrus); cirrus->vram = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); From 0c7890dc1e539c2c5357a6591c5ed1a4ed3c8d02 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:40:11 +0200 Subject: [PATCH 065/109] drm/cirrus: Don't use drm_device->dev_private MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upcasting using a container_of macro is more typesafe, faster and easier for the compiler to optimize. Acked-by: Eric Anholt Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: Dave Airlie Cc: Gerd Hoffmann Cc: Daniel Vetter Cc: "Noralf Trønnes" Cc: Sam Ravnborg Cc: Eric Anholt Cc: Thomas Zimmermann Cc: virtualization@lists.linux-foundation.org Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-37-daniel.vetter@ffwll.ch --- drivers/gpu/drm/cirrus/cirrus.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/cirrus/cirrus.c b/drivers/gpu/drm/cirrus/cirrus.c index 4b65637147ba..744a8e337e41 100644 --- a/drivers/gpu/drm/cirrus/cirrus.c +++ b/drivers/gpu/drm/cirrus/cirrus.c @@ -59,6 +59,8 @@ struct cirrus_device { void __iomem *mmio; }; +#define to_cirrus(_dev) container_of(_dev, struct cirrus_device, dev) + /* ------------------------------------------------------------------ */ /* * The meat of this driver. The core passes us a mode and we have to program @@ -311,7 +313,7 @@ static int cirrus_mode_set(struct cirrus_device *cirrus, static int cirrus_fb_blit_rect(struct drm_framebuffer *fb, struct drm_rect *rect) { - struct cirrus_device *cirrus = fb->dev->dev_private; + struct cirrus_device *cirrus = to_cirrus(fb->dev); void *vmap; int idx, ret; @@ -436,7 +438,7 @@ static void cirrus_pipe_enable(struct drm_simple_display_pipe *pipe, struct drm_crtc_state *crtc_state, struct drm_plane_state *plane_state) { - struct cirrus_device *cirrus = pipe->crtc.dev->dev_private; + struct cirrus_device *cirrus = to_cirrus(pipe->crtc.dev); cirrus_mode_set(cirrus, &crtc_state->mode, plane_state->fb); cirrus_fb_blit_fullscreen(plane_state->fb); @@ -445,7 +447,7 @@ static void cirrus_pipe_enable(struct drm_simple_display_pipe *pipe, static void cirrus_pipe_update(struct drm_simple_display_pipe *pipe, struct drm_plane_state *old_state) { - struct cirrus_device *cirrus = pipe->crtc.dev->dev_private; + struct cirrus_device *cirrus = to_cirrus(pipe->crtc.dev); struct drm_plane_state *state = pipe->plane.state; struct drm_crtc *crtc = &pipe->crtc; struct drm_rect rect; @@ -573,7 +575,6 @@ static int cirrus_pci_probe(struct pci_dev *pdev, return PTR_ERR(cirrus); dev = &cirrus->dev; - dev->dev_private = cirrus; cirrus->vram = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); From b0548a245dd30bf448e2d4fc88edcb66d4fa668f Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:40:12 +0200 Subject: [PATCH 066/109] drm/cirrus: Move to drm/tiny Because it is. Huge congrats to everyone who made this kind of refactoring happen! Acked-by: Gerd Hoffmann Reviewed-by: Thomas Zimmermann Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: Dave Airlie Cc: Gerd Hoffmann Cc: virtualization@lists.linux-foundation.org Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-38-daniel.vetter@ffwll.ch --- MAINTAINERS | 2 +- drivers/gpu/drm/Kconfig | 2 -- drivers/gpu/drm/Makefile | 1 - drivers/gpu/drm/cirrus/Kconfig | 19 ------------------- drivers/gpu/drm/cirrus/Makefile | 2 -- drivers/gpu/drm/tiny/Kconfig | 19 +++++++++++++++++++ drivers/gpu/drm/tiny/Makefile | 1 + drivers/gpu/drm/{cirrus => tiny}/cirrus.c | 0 8 files changed, 21 insertions(+), 25 deletions(-) delete mode 100644 drivers/gpu/drm/cirrus/Kconfig delete mode 100644 drivers/gpu/drm/cirrus/Makefile rename drivers/gpu/drm/{cirrus => tiny}/cirrus.c (100%) diff --git a/MAINTAINERS b/MAINTAINERS index ad29107786fe..4e4883dfdd55 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5422,7 +5422,7 @@ L: virtualization@lists.linux-foundation.org S: Obsolete W: https://www.kraxel.org/blog/2014/10/qemu-using-cirrus-considered-harmful/ T: git git://anongit.freedesktop.org/drm/drm-misc -F: drivers/gpu/drm/cirrus/ +F: drivers/gpu/drm/tiny/cirrus.c DRM DRIVER FOR QXL VIRTUAL GPU M: Dave Airlie diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 43594978958e..4f4e7fa001c1 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -310,8 +310,6 @@ source "drivers/gpu/drm/ast/Kconfig" source "drivers/gpu/drm/mgag200/Kconfig" -source "drivers/gpu/drm/cirrus/Kconfig" - source "drivers/gpu/drm/armada/Kconfig" source "drivers/gpu/drm/atmel-hlcdc/Kconfig" diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index f34d08c83485..2c0e5a7e5953 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -74,7 +74,6 @@ obj-$(CONFIG_DRM_I915) += i915/ obj-$(CONFIG_DRM_MGAG200) += mgag200/ obj-$(CONFIG_DRM_V3D) += v3d/ obj-$(CONFIG_DRM_VC4) += vc4/ -obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus/ obj-$(CONFIG_DRM_SIS) += sis/ obj-$(CONFIG_DRM_SAVAGE)+= savage/ obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/ diff --git a/drivers/gpu/drm/cirrus/Kconfig b/drivers/gpu/drm/cirrus/Kconfig deleted file mode 100644 index c6bbd988b0e5..000000000000 --- a/drivers/gpu/drm/cirrus/Kconfig +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -config DRM_CIRRUS_QEMU - tristate "Cirrus driver for QEMU emulated device" - depends on DRM && PCI && MMU - select DRM_KMS_HELPER - select DRM_GEM_SHMEM_HELPER - help - This is a KMS driver for emulated cirrus device in qemu. - It is *NOT* intended for real cirrus devices. This requires - the modesetting userspace X.org driver. - - Cirrus is obsolete, the hardware was designed in the 90ies - and can't keep up with todays needs. More background: - https://www.kraxel.org/blog/2014/10/qemu-using-cirrus-considered-harmful/ - - Better alternatives are: - - stdvga (DRM_BOCHS, qemu -vga std, default in qemu 2.2+) - - qxl (DRM_QXL, qemu -vga qxl, works best with spice) - - virtio (DRM_VIRTIO_GPU), qemu -vga virtio) diff --git a/drivers/gpu/drm/cirrus/Makefile b/drivers/gpu/drm/cirrus/Makefile deleted file mode 100644 index 0c1ed3f99725..000000000000 --- a/drivers/gpu/drm/cirrus/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus.o diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 4160e74e4751..2b6414f0fa75 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -1,5 +1,24 @@ # SPDX-License-Identifier: GPL-2.0-only +config DRM_CIRRUS_QEMU + tristate "Cirrus driver for QEMU emulated device" + depends on DRM && PCI && MMU + select DRM_KMS_HELPER + select DRM_GEM_SHMEM_HELPER + help + This is a KMS driver for emulated cirrus device in qemu. + It is *NOT* intended for real cirrus devices. This requires + the modesetting userspace X.org driver. + + Cirrus is obsolete, the hardware was designed in the 90ies + and can't keep up with todays needs. More background: + https://www.kraxel.org/blog/2014/10/qemu-using-cirrus-considered-harmful/ + + Better alternatives are: + - stdvga (DRM_BOCHS, qemu -vga std, default in qemu 2.2+) + - qxl (DRM_QXL, qemu -vga qxl, works best with spice) + - virtio (DRM_VIRTIO_GPU), qemu -vga virtio) + config DRM_GM12U320 tristate "GM12U320 driver for USB projectors" depends on DRM && USB diff --git a/drivers/gpu/drm/tiny/Makefile b/drivers/gpu/drm/tiny/Makefile index c96ceee71453..6ae4e9e5a35f 100644 --- a/drivers/gpu/drm/tiny/Makefile +++ b/drivers/gpu/drm/tiny/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus.o obj-$(CONFIG_DRM_GM12U320) += gm12u320.o obj-$(CONFIG_TINYDRM_HX8357D) += hx8357d.o obj-$(CONFIG_TINYDRM_ILI9225) += ili9225.o diff --git a/drivers/gpu/drm/cirrus/cirrus.c b/drivers/gpu/drm/tiny/cirrus.c similarity index 100% rename from drivers/gpu/drm/cirrus/cirrus.c rename to drivers/gpu/drm/tiny/cirrus.c From e95d2f40124992fb60a150e297b6fe96cc4ac741 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:40:29 +0200 Subject: [PATCH 067/109] drm/aspeed: Drop aspeed_gfx->fbdev No longer used since the conversion to generic fbdev. Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: Joel Stanley Cc: Andrew Jeffery Cc: linux-aspeed@lists.ozlabs.org Cc: linux-arm-kernel@lists.infradead.org Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-55-daniel.vetter@ffwll.ch --- drivers/gpu/drm/aspeed/aspeed_gfx.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx.h b/drivers/gpu/drm/aspeed/aspeed_gfx.h index a10358bb61ec..adc02940de6f 100644 --- a/drivers/gpu/drm/aspeed/aspeed_gfx.h +++ b/drivers/gpu/drm/aspeed/aspeed_gfx.h @@ -12,7 +12,6 @@ struct aspeed_gfx { struct drm_simple_display_pipe pipe; struct drm_connector connector; - struct drm_fbdev_cma *fbdev; }; int aspeed_gfx_create_pipe(struct drm_device *drm); From cd8294540776f7986b7cf658a3579d576853610c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:40:30 +0200 Subject: [PATCH 068/109] drm/aspeed: Use devm_drm_dev_alloc As usual, we can drop the drm_dev_put() and need to embed the drm_device. Since it's so few, also go right ahead and leave drm_device->dev_private set to NULL, so that we always use the container_of() upcast, which is faster anyway. Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: Joel Stanley Cc: Andrew Jeffery Cc: linux-aspeed@lists.ozlabs.org Cc: linux-arm-kernel@lists.infradead.org Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-56-daniel.vetter@ffwll.ch --- drivers/gpu/drm/aspeed/aspeed_gfx.h | 2 ++ drivers/gpu/drm/aspeed/aspeed_gfx_crtc.c | 2 +- drivers/gpu/drm/aspeed/aspeed_gfx_drv.c | 31 +++++++++--------------- drivers/gpu/drm/aspeed/aspeed_gfx_out.c | 2 +- 4 files changed, 15 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx.h b/drivers/gpu/drm/aspeed/aspeed_gfx.h index adc02940de6f..e7ca95827ae8 100644 --- a/drivers/gpu/drm/aspeed/aspeed_gfx.h +++ b/drivers/gpu/drm/aspeed/aspeed_gfx.h @@ -5,6 +5,7 @@ #include struct aspeed_gfx { + struct drm_device drm; void __iomem *base; struct clk *clk; struct reset_control *rst; @@ -13,6 +14,7 @@ struct aspeed_gfx { struct drm_simple_display_pipe pipe; struct drm_connector connector; }; +#define to_aspeed_gfx(x) container_of(x, struct aspeed_gfx, drm) int aspeed_gfx_create_pipe(struct drm_device *drm); int aspeed_gfx_create_output(struct drm_device *drm); diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_crtc.c b/drivers/gpu/drm/aspeed/aspeed_gfx_crtc.c index 2184b8be6fd4..e54686c31a90 100644 --- a/drivers/gpu/drm/aspeed/aspeed_gfx_crtc.c +++ b/drivers/gpu/drm/aspeed/aspeed_gfx_crtc.c @@ -231,7 +231,7 @@ static const uint32_t aspeed_gfx_formats[] = { int aspeed_gfx_create_pipe(struct drm_device *drm) { - struct aspeed_gfx *priv = drm->dev_private; + struct aspeed_gfx *priv = to_aspeed_gfx(drm); return drm_simple_display_pipe_init(drm, &priv->pipe, &aspeed_gfx_funcs, aspeed_gfx_formats, diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c index ada2f6aca906..6b27242b9ee3 100644 --- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c +++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c @@ -77,7 +77,7 @@ static void aspeed_gfx_setup_mode_config(struct drm_device *drm) static irqreturn_t aspeed_gfx_irq_handler(int irq, void *data) { struct drm_device *drm = data; - struct aspeed_gfx *priv = drm->dev_private; + struct aspeed_gfx *priv = to_aspeed_gfx(drm); u32 reg; reg = readl(priv->base + CRT_CTRL1); @@ -96,15 +96,10 @@ static irqreturn_t aspeed_gfx_irq_handler(int irq, void *data) static int aspeed_gfx_load(struct drm_device *drm) { struct platform_device *pdev = to_platform_device(drm->dev); - struct aspeed_gfx *priv; + struct aspeed_gfx *priv = to_aspeed_gfx(drm); struct resource *res; int ret; - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - drm->dev_private = priv; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->base = devm_ioremap_resource(drm->dev, res); if (IS_ERR(priv->base)) @@ -187,8 +182,6 @@ static void aspeed_gfx_unload(struct drm_device *drm) { drm_kms_helper_poll_fini(drm); drm_mode_config_cleanup(drm); - - drm->dev_private = NULL; } DEFINE_DRM_GEM_CMA_FOPS(fops); @@ -216,27 +209,26 @@ static const struct of_device_id aspeed_gfx_match[] = { static int aspeed_gfx_probe(struct platform_device *pdev) { - struct drm_device *drm; + struct aspeed_gfx *priv; int ret; - drm = drm_dev_alloc(&aspeed_gfx_driver, &pdev->dev); - if (IS_ERR(drm)) - return PTR_ERR(drm); + priv = devm_drm_dev_alloc(&pdev->dev, &aspeed_gfx_driver, + struct aspeed_gfx, drm); + if (IS_ERR(priv)) + return PTR_ERR(priv); - ret = aspeed_gfx_load(drm); + ret = aspeed_gfx_load(&priv->drm); if (ret) - goto err_free; + return ret; - ret = drm_dev_register(drm, 0); + ret = drm_dev_register(&priv->drm, 0); if (ret) goto err_unload; return 0; err_unload: - aspeed_gfx_unload(drm); -err_free: - drm_dev_put(drm); + aspeed_gfx_unload(&priv->drm); return ret; } @@ -247,7 +239,6 @@ static int aspeed_gfx_remove(struct platform_device *pdev) drm_dev_unregister(drm); aspeed_gfx_unload(drm); - drm_dev_put(drm); return 0; } diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_out.c b/drivers/gpu/drm/aspeed/aspeed_gfx_out.c index 67ee5fa10055..6759cb88415a 100644 --- a/drivers/gpu/drm/aspeed/aspeed_gfx_out.c +++ b/drivers/gpu/drm/aspeed/aspeed_gfx_out.c @@ -28,7 +28,7 @@ static const struct drm_connector_funcs aspeed_gfx_connector_funcs = { int aspeed_gfx_create_output(struct drm_device *drm) { - struct aspeed_gfx *priv = drm->dev_private; + struct aspeed_gfx *priv = to_aspeed_gfx(drm); int ret; priv->connector.dpms = DRM_MODE_DPMS_OFF; From a7aed875e3fa184c96a2af8c1d86d4e2882e969c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:40:33 +0200 Subject: [PATCH 069/109] drm/ast: Drop explicit connector register/unregister This is only needed for hotpluggable connectors set up after drm_dev_register(). Reviewed-by: Thomas Zimemrmann Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: Dave Airlie Cc: Thomas Zimmermann Cc: Gerd Hoffmann Cc: Daniel Vetter Cc: Sam Ravnborg Cc: Emil Velikov Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-59-daniel.vetter@ffwll.ch --- drivers/gpu/drm/ast/ast_mode.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 7a9f20a2fd30..d2ab81f9c498 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -1080,7 +1080,6 @@ static void ast_connector_destroy(struct drm_connector *connector) { struct ast_connector *ast_connector = to_ast_connector(connector); ast_i2c_destroy(ast_connector->i2c); - drm_connector_unregister(connector); drm_connector_cleanup(connector); kfree(connector); } @@ -1123,8 +1122,6 @@ static int ast_connector_init(struct drm_device *dev) connector->interlace_allowed = 0; connector->doublescan_allowed = 0; - drm_connector_register(connector); - connector->polled = DRM_CONNECTOR_POLL_CONNECT; encoder = list_first_entry(&dev->mode_config.encoder_list, struct drm_encoder, head); From d83949492427e1c9584c8db91c5d2a26747e7e73 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:40:34 +0200 Subject: [PATCH 070/109] drm/bochs: Remove explicit drm_connector_register This is leftovers from the old drm_driver->load callback upside-down issues. It doesn't do anything for not-hotplugged connectors since drm_dev_register takes care of that. Acked-by: Gerd Hoffmann Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: Gerd Hoffmann Cc: virtualization@lists.linux-foundation.org Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-60-daniel.vetter@ffwll.ch --- drivers/gpu/drm/bochs/bochs_kms.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index 7f4bcfad87e9..05d8373888e8 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -104,7 +104,6 @@ static void bochs_connector_init(struct drm_device *dev) DRM_MODE_CONNECTOR_VIRTUAL); drm_connector_helper_add(connector, &bochs_connector_connector_helper_funcs); - drm_connector_register(connector); bochs_hw_load_edid(bochs); if (bochs->edid) { From 87189b78959c10c454477cce5cb9836c2ee5c730 Mon Sep 17 00:00:00 2001 From: Kenny Levinsen Date: Fri, 24 Apr 2020 16:51:03 +0200 Subject: [PATCH 071/109] drm: make drm_file use keyed wakeups Some processes, such as systemd, are only polling for EPOLLERR|EPOLLHUP. As drm_file uses unkeyed wakeups, such a poll receives many spurious wakeups from uninteresting events. Use keyed wakeups to allow the wakeup target to more efficiently discard these uninteresting events. Signed-off-by: Kenny Levinsen Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20200424145103.3048-1-kl@kl.wtf --- drivers/gpu/drm/drm_file.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index eb009d3ab48f..7194e67e78bd 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -613,7 +613,8 @@ put_back_event: file_priv->event_space -= length; list_add(&e->link, &file_priv->event_list); spin_unlock_irq(&dev->event_lock); - wake_up_interruptible(&file_priv->event_wait); + wake_up_interruptible_poll(&file_priv->event_wait, + EPOLLIN | EPOLLRDNORM); break; } @@ -809,7 +810,8 @@ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e) list_del(&e->pending_link); list_add_tail(&e->link, &e->file_priv->event_list); - wake_up_interruptible(&e->file_priv->event_wait); + wake_up_interruptible_poll(&e->file_priv->event_wait, + EPOLLIN | EPOLLRDNORM); } EXPORT_SYMBOL(drm_send_event_locked); From a9b0b24a6fff2d269eb966d7e4eca498bf9f0bba Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:40:01 +0200 Subject: [PATCH 072/109] drm/qxl: Use devm_drm_dev_alloc Also need to remove the drm_dev_put from the remove hook. Acked-by: Gerd Hoffmann Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: Dave Airlie Cc: Gerd Hoffmann Cc: virtualization@lists.linux-foundation.org Cc: spice-devel@lists.freedesktop.org Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-27-daniel.vetter@ffwll.ch --- drivers/gpu/drm/qxl/qxl_drv.c | 15 ++++++++------- drivers/gpu/drm/qxl/qxl_drv.h | 3 +-- drivers/gpu/drm/qxl/qxl_kms.c | 12 +----------- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index 09102e2efabc..6b4ae4c5fb76 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -81,13 +81,16 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return -EINVAL; /* TODO: ENODEV ? */ } - qdev = kzalloc(sizeof(struct qxl_device), GFP_KERNEL); - if (!qdev) + qdev = devm_drm_dev_alloc(&pdev->dev, &qxl_driver, + struct qxl_device, ddev); + if (IS_ERR(qdev)) { + pr_err("Unable to init drm dev"); return -ENOMEM; + } ret = pci_enable_device(pdev); if (ret) - goto free_dev; + return ret; ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, "qxl"); if (ret) @@ -101,7 +104,7 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } } - ret = qxl_device_init(qdev, &qxl_driver, pdev); + ret = qxl_device_init(qdev, pdev); if (ret) goto put_vga; @@ -128,8 +131,7 @@ put_vga: vga_put(pdev, VGA_RSRC_LEGACY_IO); disable_pci: pci_disable_device(pdev); -free_dev: - kfree(qdev); + return ret; } @@ -155,7 +157,6 @@ qxl_pci_remove(struct pci_dev *pdev) drm_atomic_helper_shutdown(dev); if (is_vga(pdev)) vga_put(pdev, VGA_RSRC_LEGACY_IO); - drm_dev_put(dev); } DEFINE_DRM_GEM_FOPS(qxl_fops); diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 435126facc9b..86ac191d9205 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -276,8 +276,7 @@ struct qxl_device { extern const struct drm_ioctl_desc qxl_ioctls[]; extern int qxl_max_ioctl; -int qxl_device_init(struct qxl_device *qdev, struct drm_driver *drv, - struct pci_dev *pdev); +int qxl_device_init(struct qxl_device *qdev, struct pci_dev *pdev); void qxl_device_fini(struct qxl_device *qdev); int qxl_modeset_init(struct qxl_device *qdev); diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c index 9eed1a375f24..91a34dd835d7 100644 --- a/drivers/gpu/drm/qxl/qxl_kms.c +++ b/drivers/gpu/drm/qxl/qxl_kms.c @@ -108,21 +108,13 @@ static void qxl_gc_work(struct work_struct *work) } int qxl_device_init(struct qxl_device *qdev, - struct drm_driver *drv, struct pci_dev *pdev) { int r, sb; - r = drm_dev_init(&qdev->ddev, drv, &pdev->dev); - if (r) { - pr_err("Unable to init drm dev"); - goto error; - } - qdev->ddev.pdev = pdev; pci_set_drvdata(pdev, &qdev->ddev); qdev->ddev.dev_private = qdev; - drmm_add_final_kfree(&qdev->ddev, qdev); mutex_init(&qdev->gem.mutex); mutex_init(&qdev->update_area_mutex); @@ -138,8 +130,7 @@ int qxl_device_init(struct qxl_device *qdev, qdev->vram_mapping = io_mapping_create_wc(qdev->vram_base, pci_resource_len(pdev, 0)); if (!qdev->vram_mapping) { pr_err("Unable to create vram_mapping"); - r = -ENOMEM; - goto error; + return -ENOMEM; } if (pci_resource_len(pdev, 4) > 0) { @@ -293,7 +284,6 @@ surface_mapping_free: io_mapping_free(qdev->surface_mapping); vram_mapping_free: io_mapping_free(qdev->vram_mapping); -error: return r; } From e304f8a0513b830be37b3f5059c3d8fcaacda4b7 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:40:02 +0200 Subject: [PATCH 073/109] drm/qxl: Don't use drm_device->dev_private Upcasting using a container_of macro is more typesafe, faster and easier for the compiler to optimize. Acked-by: Gerd Hoffmann Acked-by: Sam Ravnborg Signed-off-by: Daniel Vetter Cc: Dave Airlie Cc: Gerd Hoffmann Cc: virtualization@lists.linux-foundation.org Cc: spice-devel@lists.freedesktop.org Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-28-daniel.vetter@ffwll.ch --- drivers/gpu/drm/qxl/qxl_debugfs.c | 7 +++---- drivers/gpu/drm/qxl/qxl_display.c | 32 +++++++++++++++---------------- drivers/gpu/drm/qxl/qxl_drv.c | 8 ++++---- drivers/gpu/drm/qxl/qxl_drv.h | 4 ++-- drivers/gpu/drm/qxl/qxl_dumb.c | 2 +- drivers/gpu/drm/qxl/qxl_gem.c | 2 +- drivers/gpu/drm/qxl/qxl_ioctl.c | 14 +++++++------- drivers/gpu/drm/qxl/qxl_irq.c | 2 +- drivers/gpu/drm/qxl/qxl_kms.c | 1 - drivers/gpu/drm/qxl/qxl_object.c | 2 +- drivers/gpu/drm/qxl/qxl_release.c | 2 +- drivers/gpu/drm/qxl/qxl_ttm.c | 2 +- 12 files changed, 38 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_debugfs.c b/drivers/gpu/drm/qxl/qxl_debugfs.c index 88123047fdd4..524d35b648d8 100644 --- a/drivers/gpu/drm/qxl/qxl_debugfs.c +++ b/drivers/gpu/drm/qxl/qxl_debugfs.c @@ -39,7 +39,7 @@ static int qxl_debugfs_irq_received(struct seq_file *m, void *data) { struct drm_info_node *node = (struct drm_info_node *) m->private; - struct qxl_device *qdev = node->minor->dev->dev_private; + struct qxl_device *qdev = to_qxl(node->minor->dev); seq_printf(m, "%d\n", atomic_read(&qdev->irq_received)); seq_printf(m, "%d\n", atomic_read(&qdev->irq_received_display)); @@ -53,7 +53,7 @@ static int qxl_debugfs_buffers_info(struct seq_file *m, void *data) { struct drm_info_node *node = (struct drm_info_node *) m->private; - struct qxl_device *qdev = node->minor->dev->dev_private; + struct qxl_device *qdev = to_qxl(node->minor->dev); struct qxl_bo *bo; list_for_each_entry(bo, &qdev->gem.objects, list) { @@ -83,8 +83,7 @@ void qxl_debugfs_init(struct drm_minor *minor) { #if defined(CONFIG_DEBUG_FS) - struct qxl_device *dev = - (struct qxl_device *) minor->dev->dev_private; + struct qxl_device *dev = to_qxl(minor->dev); drm_debugfs_create_files(qxl_debugfs_list, QXL_DEBUGFS_ENTRIES, minor->debugfs_root, minor); diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 09583a08e141..1082cd5d2fd4 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -221,7 +221,7 @@ static int qxl_add_mode(struct drm_connector *connector, bool preferred) { struct drm_device *dev = connector->dev; - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct drm_display_mode *mode = NULL; int rc; @@ -242,7 +242,7 @@ static int qxl_add_mode(struct drm_connector *connector, static int qxl_add_monitors_config_modes(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct qxl_output *output = drm_connector_to_qxl_output(connector); int h = output->index; struct qxl_head *head; @@ -310,7 +310,7 @@ static void qxl_crtc_update_monitors_config(struct drm_crtc *crtc, const char *reason) { struct drm_device *dev = crtc->dev; - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct qxl_crtc *qcrtc = to_qxl_crtc(crtc); struct qxl_head head; int oldcount, i = qcrtc->index; @@ -400,7 +400,7 @@ static int qxl_framebuffer_surface_dirty(struct drm_framebuffer *fb, unsigned int num_clips) { /* TODO: vmwgfx where this was cribbed from had locking. Why? */ - struct qxl_device *qdev = fb->dev->dev_private; + struct qxl_device *qdev = to_qxl(fb->dev); struct drm_clip_rect norect; struct qxl_bo *qobj; bool is_primary; @@ -462,7 +462,7 @@ static const struct drm_crtc_helper_funcs qxl_crtc_helper_funcs = { static int qxl_primary_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { - struct qxl_device *qdev = plane->dev->dev_private; + struct qxl_device *qdev = to_qxl(plane->dev); struct qxl_bo *bo; if (!state->crtc || !state->fb) @@ -476,7 +476,7 @@ static int qxl_primary_atomic_check(struct drm_plane *plane, static int qxl_primary_apply_cursor(struct drm_plane *plane) { struct drm_device *dev = plane->dev; - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct drm_framebuffer *fb = plane->state->fb; struct qxl_crtc *qcrtc = to_qxl_crtc(plane->state->crtc); struct qxl_cursor_cmd *cmd; @@ -523,7 +523,7 @@ out_free_release: static void qxl_primary_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { - struct qxl_device *qdev = plane->dev->dev_private; + struct qxl_device *qdev = to_qxl(plane->dev); struct qxl_bo *bo = gem_to_qxl_bo(plane->state->fb->obj[0]); struct qxl_bo *primary; struct drm_clip_rect norect = { @@ -554,7 +554,7 @@ static void qxl_primary_atomic_update(struct drm_plane *plane, static void qxl_primary_atomic_disable(struct drm_plane *plane, struct drm_plane_state *old_state) { - struct qxl_device *qdev = plane->dev->dev_private; + struct qxl_device *qdev = to_qxl(plane->dev); if (old_state->fb) { struct qxl_bo *bo = gem_to_qxl_bo(old_state->fb->obj[0]); @@ -570,7 +570,7 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { struct drm_device *dev = plane->dev; - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct drm_framebuffer *fb = plane->state->fb; struct qxl_crtc *qcrtc = to_qxl_crtc(plane->state->crtc); struct qxl_release *release; @@ -679,7 +679,7 @@ out_free_release: static void qxl_cursor_atomic_disable(struct drm_plane *plane, struct drm_plane_state *old_state) { - struct qxl_device *qdev = plane->dev->dev_private; + struct qxl_device *qdev = to_qxl(plane->dev); struct qxl_release *release; struct qxl_cursor_cmd *cmd; int ret; @@ -762,7 +762,7 @@ static void qxl_calc_dumb_shadow(struct qxl_device *qdev, static int qxl_plane_prepare_fb(struct drm_plane *plane, struct drm_plane_state *new_state) { - struct qxl_device *qdev = plane->dev->dev_private; + struct qxl_device *qdev = to_qxl(plane->dev); struct drm_gem_object *obj; struct qxl_bo *user_bo; struct qxl_surface surf; @@ -923,7 +923,7 @@ static int qdev_crtc_init(struct drm_device *dev, int crtc_id) { struct qxl_crtc *qxl_crtc; struct drm_plane *primary, *cursor; - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); int r; qxl_crtc = kzalloc(sizeof(struct qxl_crtc), GFP_KERNEL); @@ -965,7 +965,7 @@ free_mem: static int qxl_conn_get_modes(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct qxl_output *output = drm_connector_to_qxl_output(connector); unsigned int pwidth = 1024; unsigned int pheight = 768; @@ -991,7 +991,7 @@ static enum drm_mode_status qxl_conn_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { struct drm_device *ddev = connector->dev; - struct qxl_device *qdev = ddev->dev_private; + struct qxl_device *qdev = to_qxl(ddev); if (qxl_check_mode(qdev, mode->hdisplay, mode->vdisplay) != 0) return MODE_BAD; @@ -1021,7 +1021,7 @@ static enum drm_connector_status qxl_conn_detect( struct qxl_output *output = drm_connector_to_qxl_output(connector); struct drm_device *ddev = connector->dev; - struct qxl_device *qdev = ddev->dev_private; + struct qxl_device *qdev = to_qxl(ddev); bool connected = false; /* The first monitor is always connected */ @@ -1071,7 +1071,7 @@ static int qxl_mode_create_hotplug_mode_update_property(struct qxl_device *qdev) static int qdev_output_init(struct drm_device *dev, int num_output) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct qxl_output *qxl_output; struct drm_connector *connector; struct drm_encoder *encoder; diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index 6b4ae4c5fb76..13872b882775 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -137,7 +137,7 @@ disable_pci: static void qxl_drm_release(struct drm_device *dev) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); /* * TODO: qxl_device_fini() call should be in qxl_pci_remove(), @@ -164,7 +164,7 @@ DEFINE_DRM_GEM_FOPS(qxl_fops); static int qxl_drm_freeze(struct drm_device *dev) { struct pci_dev *pdev = dev->pdev; - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); int ret; ret = drm_mode_config_helper_suspend(dev); @@ -186,7 +186,7 @@ static int qxl_drm_freeze(struct drm_device *dev) static int qxl_drm_resume(struct drm_device *dev, bool thaw) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); qdev->ram_header->int_mask = QXL_INTERRUPT_MASK; if (!thaw) { @@ -245,7 +245,7 @@ static int qxl_pm_restore(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); - struct qxl_device *qdev = drm_dev->dev_private; + struct qxl_device *qdev = to_qxl(drm_dev); qxl_io_reset(qdev); return qxl_drm_resume(drm_dev, false); diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 86ac191d9205..31e35f787df2 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -192,8 +192,6 @@ struct qxl_debugfs { int qxl_debugfs_fence_init(struct qxl_device *rdev); -struct qxl_device; - struct qxl_device { struct drm_device ddev; @@ -273,6 +271,8 @@ struct qxl_device { int monitors_config_height; }; +#define to_qxl(dev) container_of(dev, struct qxl_device, ddev) + extern const struct drm_ioctl_desc qxl_ioctls[]; extern int qxl_max_ioctl; diff --git a/drivers/gpu/drm/qxl/qxl_dumb.c b/drivers/gpu/drm/qxl/qxl_dumb.c index 272d19b677d8..24e903383aa1 100644 --- a/drivers/gpu/drm/qxl/qxl_dumb.c +++ b/drivers/gpu/drm/qxl/qxl_dumb.c @@ -32,7 +32,7 @@ int qxl_mode_dumb_create(struct drm_file *file_priv, struct drm_device *dev, struct drm_mode_create_dumb *args) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct qxl_bo *qobj; uint32_t handle; int r; diff --git a/drivers/gpu/drm/qxl/qxl_gem.c b/drivers/gpu/drm/qxl/qxl_gem.c index 69f37db1027a..5ff6fa9b799c 100644 --- a/drivers/gpu/drm/qxl/qxl_gem.c +++ b/drivers/gpu/drm/qxl/qxl_gem.c @@ -34,7 +34,7 @@ void qxl_gem_object_free(struct drm_gem_object *gobj) struct qxl_device *qdev; struct ttm_buffer_object *tbo; - qdev = (struct qxl_device *)gobj->dev->dev_private; + qdev = to_qxl(gobj->dev); qxl_surface_evict(qdev, qobj, false); diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c index 8117a45b3610..d9a583966949 100644 --- a/drivers/gpu/drm/qxl/qxl_ioctl.c +++ b/drivers/gpu/drm/qxl/qxl_ioctl.c @@ -36,7 +36,7 @@ static int qxl_alloc_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct drm_qxl_alloc *qxl_alloc = data; int ret; struct qxl_bo *qobj; @@ -64,7 +64,7 @@ static int qxl_alloc_ioctl(struct drm_device *dev, void *data, static int qxl_map_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct drm_qxl_map *qxl_map = data; return qxl_mode_dumb_mmap(file_priv, &qdev->ddev, qxl_map->handle, @@ -279,7 +279,7 @@ out_free_reloc: static int qxl_execbuffer_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct drm_qxl_execbuffer *execbuffer = data; struct drm_qxl_command user_cmd; int cmd_num; @@ -304,7 +304,7 @@ static int qxl_execbuffer_ioctl(struct drm_device *dev, void *data, static int qxl_update_area_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct drm_qxl_update_area *update_area = data; struct qxl_rect area = {.left = update_area->left, .top = update_area->top, @@ -354,7 +354,7 @@ out: static int qxl_getparam_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct drm_qxl_getparam *param = data; switch (param->param) { @@ -373,7 +373,7 @@ static int qxl_getparam_ioctl(struct drm_device *dev, void *data, static int qxl_clientcap_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct drm_qxl_clientcap *param = data; int byte, idx; @@ -394,7 +394,7 @@ static int qxl_clientcap_ioctl(struct drm_device *dev, void *data, static int qxl_alloc_surf_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { - struct qxl_device *qdev = dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); struct drm_qxl_alloc_surf *param = data; struct qxl_bo *qobj; int handle; diff --git a/drivers/gpu/drm/qxl/qxl_irq.c b/drivers/gpu/drm/qxl/qxl_irq.c index 8435af108632..1ba5a702d763 100644 --- a/drivers/gpu/drm/qxl/qxl_irq.c +++ b/drivers/gpu/drm/qxl/qxl_irq.c @@ -32,7 +32,7 @@ irqreturn_t qxl_irq_handler(int irq, void *arg) { struct drm_device *dev = (struct drm_device *) arg; - struct qxl_device *qdev = (struct qxl_device *)dev->dev_private; + struct qxl_device *qdev = to_qxl(dev); uint32_t pending; pending = xchg(&qdev->ram_header->int_pending, 0); diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c index 91a34dd835d7..a6d873052cd4 100644 --- a/drivers/gpu/drm/qxl/qxl_kms.c +++ b/drivers/gpu/drm/qxl/qxl_kms.c @@ -114,7 +114,6 @@ int qxl_device_init(struct qxl_device *qdev, qdev->ddev.pdev = pdev; pci_set_drvdata(pdev, &qdev->ddev); - qdev->ddev.dev_private = qdev; mutex_init(&qdev->gem.mutex); mutex_init(&qdev->update_area_mutex); diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c index ab72dc3476e9..edc8a9916872 100644 --- a/drivers/gpu/drm/qxl/qxl_object.c +++ b/drivers/gpu/drm/qxl/qxl_object.c @@ -33,7 +33,7 @@ static void qxl_ttm_bo_destroy(struct ttm_buffer_object *tbo) struct qxl_device *qdev; bo = to_qxl_bo(tbo); - qdev = (struct qxl_device *)bo->tbo.base.dev->dev_private; + qdev = to_qxl(bo->tbo.base.dev); qxl_surface_evict(qdev, bo, false); WARN_ON_ONCE(bo->map_count > 0); diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index 2feca734c7b1..4fae3e393da1 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c @@ -243,7 +243,7 @@ static int qxl_release_validate_bo(struct qxl_bo *bo) return ret; /* allocate a surface for reserved + validated buffers */ - ret = qxl_bo_check_id(bo->tbo.base.dev->dev_private, bo); + ret = qxl_bo_check_id(to_qxl(bo->tbo.base.dev), bo); if (ret) return ret; return 0; diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index 93a2eb14844b..f09a712b1ed2 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c @@ -243,7 +243,7 @@ static void qxl_bo_move_notify(struct ttm_buffer_object *bo, if (!qxl_ttm_bo_is_qxl_bo(bo)) return; qbo = to_qxl_bo(bo); - qdev = qbo->tbo.base.dev->dev_private; + qdev = to_qxl(qbo->tbo.base.dev); if (bo->mem.mem_type == TTM_PL_PRIV && qbo->surface_id) qxl_surface_evict(qdev, qbo, new_mem ? true : false); From 274ed9e9eabd23984ac03a8cebf5ce206c0b60bf Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 15 Apr 2020 09:40:13 +0200 Subject: [PATCH 074/109] drm/i915: Use devm_drm_dev_alloc Luckily we're already well set up in the main driver, with drm_dev_put() being the last thing in both the unload error case and the pci remove function. Acked-by: Jani Nikula Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-39-daniel.vetter@ffwll.ch --- drivers/gpu/drm/i915/i915_drv.c | 17 ++++------------- drivers/gpu/drm/i915/i915_pci.c | 2 -- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 2b5f13ca5ec4..43b4146c25f3 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -877,19 +877,11 @@ i915_driver_create(struct pci_dev *pdev, const struct pci_device_id *ent) (struct intel_device_info *)ent->driver_data; struct intel_device_info *device_info; struct drm_i915_private *i915; - int err; - i915 = kzalloc(sizeof(*i915), GFP_KERNEL); - if (!i915) - return ERR_PTR(-ENOMEM); - - err = drm_dev_init(&i915->drm, &driver, &pdev->dev); - if (err) { - kfree(i915); - return ERR_PTR(err); - } - - drmm_add_final_kfree(&i915->drm, i915); + i915 = devm_drm_dev_alloc(&pdev->dev, &driver, + struct drm_i915_private, drm); + if (IS_ERR(i915)) + return i915; i915->drm.pdev = pdev; pci_set_drvdata(pdev, i915); @@ -1006,7 +998,6 @@ out_pci_disable: pci_disable_device(pdev); out_fini: i915_probe_error(i915, "Device initialization failed (%d)\n", ret); - drm_dev_put(&i915->drm); return ret; } diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 2c80a0194c80..0f8b439d6fd5 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -920,8 +920,6 @@ static void i915_pci_remove(struct pci_dev *pdev) i915_driver_remove(i915); pci_set_drvdata(pdev, NULL); - - drm_dev_put(&i915->drm); } /* is device_id present in comma separated list of ids */ From 66ddc1e94114d0271910ed31af6c301a281c9260 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 3 Apr 2020 17:06:08 -0600 Subject: [PATCH 075/109] drm: pl111: Fix module autoloading Add a missing MODULE_DEVICE_TABLE entry to fix module autoloading. Cc: Eric Anholt Cc: dri-devel@lists.freedesktop.org Acked-by: Sam Ravnborg Reviewed-by: Linus Walleij Signed-off-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/20200409013947.12667-2-robh@kernel.org --- drivers/gpu/drm/pl111/pl111_drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c index f9ca0f3edbbb..da0c39dae874 100644 --- a/drivers/gpu/drm/pl111/pl111_drv.c +++ b/drivers/gpu/drm/pl111/pl111_drv.c @@ -444,6 +444,7 @@ static const struct amba_id pl111_id_table[] = { }, {0, 0}, }; +MODULE_DEVICE_TABLE(amba, pl111_id_table); static struct amba_driver pl111_amba_driver __maybe_unused = { .drv = { From cbcab504ceecc0b27ab829cbbcd5cad1c17b3975 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 2 Apr 2020 11:34:25 -0600 Subject: [PATCH 076/109] drm: pl111: Simplify vexpress init The init VExpress variants currently instantiates a 'muxfpga' driver for the sole purpose of getting a regmap for it. There's no reason to instantiate a driver and doing so just complicates things. The muxfpga driver also isn't unregistered properly on module unload. Let's just simplify all this this by just calling devm_regmap_init_vexpress_config() directly. Cc: Eric Anholt Cc: dri-devel@lists.freedesktop.org Acked-by: Sam Ravnborg Reviewed-by: Linus Walleij Signed-off-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/20200409013947.12667-3-robh@kernel.org --- drivers/gpu/drm/pl111/pl111_versatile.c | 21 +++---------- drivers/gpu/drm/pl111/pl111_vexpress.c | 42 ------------------------- drivers/gpu/drm/pl111/pl111_vexpress.h | 7 ----- 3 files changed, 4 insertions(+), 66 deletions(-) diff --git a/drivers/gpu/drm/pl111/pl111_versatile.c b/drivers/gpu/drm/pl111/pl111_versatile.c index 4f325c410b5d..f891f9bf3a93 100644 --- a/drivers/gpu/drm/pl111/pl111_versatile.c +++ b/drivers/gpu/drm/pl111/pl111_versatile.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "pl111_versatile.h" #include "pl111_vexpress.h" @@ -391,17 +392,8 @@ int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv) } /* Versatile Express special handling */ - if (versatile_clcd_type == VEXPRESS_CLCD_V2M) { + if (IS_ENABLED(CONFIG_VEXPRESS_CONFIG) && versatile_clcd_type == VEXPRESS_CLCD_V2M) { struct platform_device *pdev; - - /* Registers a driver for the muxfpga */ - ret = vexpress_muxfpga_init(); - if (ret) { - dev_err(dev, "unable to initialize muxfpga driver\n"); - of_node_put(np); - return ret; - } - /* Call into deep Vexpress configuration API */ pdev = of_find_device_by_node(np); if (!pdev) { @@ -409,13 +401,8 @@ int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv) of_node_put(np); return -EPROBE_DEFER; } - map = dev_get_drvdata(&pdev->dev); - if (!map) { - dev_err(dev, "sysreg has not yet probed\n"); - platform_device_put(pdev); - of_node_put(np); - return -EPROBE_DEFER; - } + map = devm_regmap_init_vexpress_config(&pdev->dev); + platform_device_put(pdev); } else { map = syscon_node_to_regmap(np); } diff --git a/drivers/gpu/drm/pl111/pl111_vexpress.c b/drivers/gpu/drm/pl111/pl111_vexpress.c index 350570fe06b5..37ed3f1da820 100644 --- a/drivers/gpu/drm/pl111/pl111_vexpress.c +++ b/drivers/gpu/drm/pl111/pl111_vexpress.c @@ -94,45 +94,3 @@ int pl111_vexpress_clcd_init(struct device *dev, return 0; } - -/* - * This sets up the regmap pointer that will then be retrieved by - * the detection code in pl111_versatile.c and passed in to the - * pl111_vexpress_clcd_init() function above. - */ -static int vexpress_muxfpga_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct regmap *map; - - map = devm_regmap_init_vexpress_config(&pdev->dev); - if (IS_ERR(map)) - return PTR_ERR(map); - dev_set_drvdata(dev, map); - - return 0; -} - -static const struct of_device_id vexpress_muxfpga_match[] = { - { .compatible = "arm,vexpress-muxfpga", }, - {} -}; - -static struct platform_driver vexpress_muxfpga_driver = { - .driver = { - .name = "vexpress-muxfpga", - .of_match_table = of_match_ptr(vexpress_muxfpga_match), - }, - .probe = vexpress_muxfpga_probe, -}; - -int vexpress_muxfpga_init(void) -{ - int ret; - - ret = platform_driver_register(&vexpress_muxfpga_driver); - /* -EBUSY just means this driver is already registered */ - if (ret == -EBUSY) - ret = 0; - return ret; -} diff --git a/drivers/gpu/drm/pl111/pl111_vexpress.h b/drivers/gpu/drm/pl111/pl111_vexpress.h index 5d3681bb4c00..bb54864ca91e 100644 --- a/drivers/gpu/drm/pl111/pl111_vexpress.h +++ b/drivers/gpu/drm/pl111/pl111_vexpress.h @@ -10,8 +10,6 @@ int pl111_vexpress_clcd_init(struct device *dev, struct pl111_drm_dev_private *priv, struct regmap *map); -int vexpress_muxfpga_init(void); - #else static inline int pl111_vexpress_clcd_init(struct device *dev, @@ -21,9 +19,4 @@ static inline int pl111_vexpress_clcd_init(struct device *dev, return -ENODEV; } -static inline int vexpress_muxfpga_init(void) -{ - return 0; -} - #endif From 826fc86b59034b0913976a0ff5901de82a4b66e8 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Sun, 5 Apr 2020 11:14:52 -0600 Subject: [PATCH 077/109] drm: pl111: Move VExpress setup into versatile init Since the VExpress setup in pl111_vexpress.c is now just a single function call, let's move it into pl111_versatile.c and we can further simplify pl111_versatile_init() by moving the other pieces for VExpress into pl111_vexpress_clcd_init(). Cc: Eric Anholt Cc: dri-devel@lists.freedesktop.org Acked-by: Sam Ravnborg Reviewed-by: Linus Walleij Signed-off-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/20200409013947.12667-4-robh@kernel.org --- drivers/gpu/drm/pl111/Makefile | 1 - drivers/gpu/drm/pl111/pl111_versatile.c | 133 +++++++++++++++++++----- drivers/gpu/drm/pl111/pl111_vexpress.c | 96 ----------------- drivers/gpu/drm/pl111/pl111_vexpress.h | 22 ---- 4 files changed, 108 insertions(+), 144 deletions(-) delete mode 100644 drivers/gpu/drm/pl111/pl111_vexpress.c delete mode 100644 drivers/gpu/drm/pl111/pl111_vexpress.h diff --git a/drivers/gpu/drm/pl111/Makefile b/drivers/gpu/drm/pl111/Makefile index 0c70f0e91d21..67d430d433e0 100644 --- a/drivers/gpu/drm/pl111/Makefile +++ b/drivers/gpu/drm/pl111/Makefile @@ -3,7 +3,6 @@ pl111_drm-y += pl111_display.o \ pl111_versatile.o \ pl111_drv.o -pl111_drm-$(CONFIG_ARCH_VEXPRESS) += pl111_vexpress.o pl111_drm-$(CONFIG_ARCH_NOMADIK) += pl111_nomadik.o pl111_drm-$(CONFIG_DEBUG_FS) += pl111_debugfs.o diff --git a/drivers/gpu/drm/pl111/pl111_versatile.c b/drivers/gpu/drm/pl111/pl111_versatile.c index f891f9bf3a93..64f01a4e6767 100644 --- a/drivers/gpu/drm/pl111/pl111_versatile.c +++ b/drivers/gpu/drm/pl111/pl111_versatile.c @@ -11,7 +11,6 @@ #include #include "pl111_versatile.h" -#include "pl111_vexpress.h" #include "pl111_drm.h" static struct regmap *versatile_syscon_map; @@ -362,13 +361,110 @@ static const struct pl111_variant_data pl111_vexpress = { .broken_clockdivider = true, }; +#define VEXPRESS_FPGAMUX_MOTHERBOARD 0x00 +#define VEXPRESS_FPGAMUX_DAUGHTERBOARD_1 0x01 +#define VEXPRESS_FPGAMUX_DAUGHTERBOARD_2 0x02 + +static int pl111_vexpress_clcd_init(struct device *dev, struct device_node *np, + struct pl111_drm_dev_private *priv) +{ + struct platform_device *pdev; + struct device_node *root; + struct device_node *child; + struct device_node *ct_clcd = NULL; + struct regmap *map; + bool has_coretile_clcd = false; + bool has_coretile_hdlcd = false; + bool mux_motherboard = true; + u32 val; + int ret; + + if (!IS_ENABLED(CONFIG_VEXPRESS_CONFIG)) + return -ENODEV; + + /* + * Check if we have a CLCD or HDLCD on the core tile by checking if a + * CLCD or HDLCD is available in the root of the device tree. + */ + root = of_find_node_by_path("/"); + if (!root) + return -EINVAL; + + for_each_available_child_of_node(root, child) { + if (of_device_is_compatible(child, "arm,pl111")) { + has_coretile_clcd = true; + ct_clcd = child; + break; + } + if (of_device_is_compatible(child, "arm,hdlcd")) { + has_coretile_hdlcd = true; + of_node_put(child); + break; + } + } + + of_node_put(root); + + /* + * If there is a coretile HDLCD and it has a driver, + * do not mux the CLCD on the motherboard to the DVI. + */ + if (has_coretile_hdlcd && IS_ENABLED(CONFIG_DRM_HDLCD)) + mux_motherboard = false; + + /* + * On the Vexpress CA9 we let the CLCD on the coretile + * take precedence, so also in this case do not mux the + * motherboard to the DVI. + */ + if (has_coretile_clcd) + mux_motherboard = false; + + if (mux_motherboard) { + dev_info(dev, "DVI muxed to motherboard CLCD\n"); + val = VEXPRESS_FPGAMUX_MOTHERBOARD; + } else if (ct_clcd == dev->of_node) { + dev_info(dev, + "DVI muxed to daughterboard 1 (core tile) CLCD\n"); + val = VEXPRESS_FPGAMUX_DAUGHTERBOARD_1; + } else { + dev_info(dev, "core tile graphics present\n"); + dev_info(dev, "this device will be deactivated\n"); + return -ENODEV; + } + + /* Call into deep Vexpress configuration API */ + pdev = of_find_device_by_node(np); + if (!pdev) { + dev_err(dev, "can't find the sysreg device, deferring\n"); + return -EPROBE_DEFER; + } + + map = devm_regmap_init_vexpress_config(&pdev->dev); + if (IS_ERR(map)) { + platform_device_put(pdev); + return PTR_ERR(map); + } + + ret = regmap_write(map, 0, val); + platform_device_put(pdev); + if (ret) { + dev_err(dev, "error setting DVI muxmode\n"); + return -ENODEV; + } + + priv->variant = &pl111_vexpress; + dev_info(dev, "initializing Versatile Express PL111\n"); + + return 0; +} + int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv) { const struct of_device_id *clcd_id; enum versatile_clcd versatile_clcd_type; struct device_node *np; struct regmap *map; - int ret; np = of_find_matching_node_and_match(NULL, versatile_clcd_of_match, &clcd_id); @@ -379,6 +475,15 @@ int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv) versatile_clcd_type = (enum versatile_clcd)clcd_id->data; + /* Versatile Express special handling */ + if (versatile_clcd_type == VEXPRESS_CLCD_V2M) { + int ret = pl111_vexpress_clcd_init(dev, np, priv); + of_node_put(np); + if (ret) + dev_err(dev, "Versatile Express init failed - %d", ret); + return ret; + } + /* * On the Integrator, check if we should use the IM-PD1 instead, * if we find it, it will take precedence. This is on the Integrator/AP @@ -391,23 +496,8 @@ int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv) versatile_clcd_type = (enum versatile_clcd)clcd_id->data; } - /* Versatile Express special handling */ - if (IS_ENABLED(CONFIG_VEXPRESS_CONFIG) && versatile_clcd_type == VEXPRESS_CLCD_V2M) { - struct platform_device *pdev; - /* Call into deep Vexpress configuration API */ - pdev = of_find_device_by_node(np); - if (!pdev) { - dev_err(dev, "can't find the sysreg device, deferring\n"); - of_node_put(np); - return -EPROBE_DEFER; - } - map = devm_regmap_init_vexpress_config(&pdev->dev); - platform_device_put(pdev); - } else { - map = syscon_node_to_regmap(np); - } + map = syscon_node_to_regmap(np); of_node_put(np); - if (IS_ERR(map)) { dev_err(dev, "no Versatile syscon regmap\n"); return PTR_ERR(map); @@ -453,13 +543,6 @@ int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv) priv->variant_display_disable = pl111_realview_clcd_disable; dev_info(dev, "set up callbacks for RealView PL111\n"); break; - case VEXPRESS_CLCD_V2M: - priv->variant = &pl111_vexpress; - dev_info(dev, "initializing Versatile Express PL111\n"); - ret = pl111_vexpress_clcd_init(dev, priv, map); - if (ret) - return ret; - break; default: dev_info(dev, "unknown Versatile system controller\n"); break; diff --git a/drivers/gpu/drm/pl111/pl111_vexpress.c b/drivers/gpu/drm/pl111/pl111_vexpress.c deleted file mode 100644 index 37ed3f1da820..000000000000 --- a/drivers/gpu/drm/pl111/pl111_vexpress.c +++ /dev/null @@ -1,96 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Versatile Express PL111 handling - * Copyright (C) 2018 Linus Walleij - * - * This module binds to the "arm,vexpress-muxfpga" device on the - * Versatile Express configuration bus and sets up which CLCD instance - * gets muxed out on the DVI bridge. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "pl111_drm.h" -#include "pl111_vexpress.h" - -#define VEXPRESS_FPGAMUX_MOTHERBOARD 0x00 -#define VEXPRESS_FPGAMUX_DAUGHTERBOARD_1 0x01 -#define VEXPRESS_FPGAMUX_DAUGHTERBOARD_2 0x02 - -int pl111_vexpress_clcd_init(struct device *dev, - struct pl111_drm_dev_private *priv, - struct regmap *map) -{ - struct device_node *root; - struct device_node *child; - struct device_node *ct_clcd = NULL; - bool has_coretile_clcd = false; - bool has_coretile_hdlcd = false; - bool mux_motherboard = true; - u32 val; - int ret; - - /* - * Check if we have a CLCD or HDLCD on the core tile by checking if a - * CLCD or HDLCD is available in the root of the device tree. - */ - root = of_find_node_by_path("/"); - if (!root) - return -EINVAL; - - for_each_available_child_of_node(root, child) { - if (of_device_is_compatible(child, "arm,pl111")) { - has_coretile_clcd = true; - ct_clcd = child; - break; - } - if (of_device_is_compatible(child, "arm,hdlcd")) { - has_coretile_hdlcd = true; - of_node_put(child); - break; - } - } - - of_node_put(root); - - /* - * If there is a coretile HDLCD and it has a driver, - * do not mux the CLCD on the motherboard to the DVI. - */ - if (has_coretile_hdlcd && IS_ENABLED(CONFIG_DRM_HDLCD)) - mux_motherboard = false; - - /* - * On the Vexpress CA9 we let the CLCD on the coretile - * take precedence, so also in this case do not mux the - * motherboard to the DVI. - */ - if (has_coretile_clcd) - mux_motherboard = false; - - if (mux_motherboard) { - dev_info(dev, "DVI muxed to motherboard CLCD\n"); - val = VEXPRESS_FPGAMUX_MOTHERBOARD; - } else if (ct_clcd == dev->of_node) { - dev_info(dev, - "DVI muxed to daughterboard 1 (core tile) CLCD\n"); - val = VEXPRESS_FPGAMUX_DAUGHTERBOARD_1; - } else { - dev_info(dev, "core tile graphics present\n"); - dev_info(dev, "this device will be deactivated\n"); - return -ENODEV; - } - - ret = regmap_write(map, 0, val); - if (ret) { - dev_err(dev, "error setting DVI muxmode\n"); - return -ENODEV; - } - - return 0; -} diff --git a/drivers/gpu/drm/pl111/pl111_vexpress.h b/drivers/gpu/drm/pl111/pl111_vexpress.h deleted file mode 100644 index bb54864ca91e..000000000000 --- a/drivers/gpu/drm/pl111/pl111_vexpress.h +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -struct device; -struct pl111_drm_dev_private; -struct regmap; - -#ifdef CONFIG_ARCH_VEXPRESS - -int pl111_vexpress_clcd_init(struct device *dev, - struct pl111_drm_dev_private *priv, - struct regmap *map); - -#else - -static inline int pl111_vexpress_clcd_init(struct device *dev, - struct pl111_drm_dev_private *priv, - struct regmap *map) -{ - return -ENODEV; -} - -#endif From 839b480dd11144f258d0b1babf33cc7c604adeb4 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 23 Apr 2020 09:40:03 +0200 Subject: [PATCH 078/109] MAINTAINERS: Restore alphabetical sorting MAINTAINERS got sorted in commit 4400b7d68f6e ("MAINTAINERS: sort entries by entry name") Merging from drm-next into drm-misc-next duplicated some of the entries by restoring old, unsorted sections. Restore the sorted list by removing the duplicates. Signed-off-by: Thomas Zimmermann Fixes: 08d99b2c23df ("Merge drm/drm-next into drm-misc-next") Acked-by: Sam Ravnborg Cc: Thomas Zimmermann Cc: Mauro Carvalho Chehab Cc: Rob Herring Cc: "David S. Miller" Cc: Greg Kroah-Hartman Cc: Neil Armstrong Cc: Laurent Pinchart Cc: Jernej Skrabec Cc: Jonas Karlman Cc: Douglas Anderson Cc: Jerome Brunet Cc: Dariusz Marcinkiewicz Cc: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200423074003.9637-1-tzimmermann@suse.de --- MAINTAINERS | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 4e4883dfdd55..938316092634 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5047,24 +5047,6 @@ F: Documentation/driver-api/dma-buf.rst K: \bdma_(?:buf|fence|resv)\b T: git git://anongit.freedesktop.org/drm/drm-misc -DMA-BUF HEAPS FRAMEWORK -M: Sumit Semwal -R: Andrew F. Davis -R: Benjamin Gaignard -R: Liam Mark -R: Laura Abbott -R: Brian Starkey -R: John Stultz -S: Maintained -L: linux-media@vger.kernel.org -L: dri-devel@lists.freedesktop.org -L: linaro-mm-sig@lists.linaro.org (moderated for non-subscribers) -F: include/uapi/linux/dma-heap.h -F: include/linux/dma-heap.h -F: drivers/dma-buf/dma-heap.c -F: drivers/dma-buf/heaps/* -T: git git://anongit.freedesktop.org/drm/drm-misc - DMA GENERIC OFFLOAD ENGINE SUBSYSTEM M: Vinod Koul L: dmaengine@vger.kernel.org @@ -5276,11 +5258,6 @@ S: Maintained F: drivers/gpu/drm/panel/panel-arm-versatile.c F: Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.yaml -DRM DRIVER FOR AST SERVER GRAPHICS CHIPS -M: Dave Airlie -S: Odd Fixes -F: drivers/gpu/drm/ast/ - DRM DRIVER FOR ASPEED BMC GFX M: Joel Stanley L: linux-aspeed@lists.ozlabs.org @@ -5468,12 +5445,6 @@ S: Orphan / Obsolete F: drivers/gpu/drm/sis/ F: include/uapi/drm/sis_drm.h -DRM DRIVER FOR SITRONIX ST7701 PANELS -M: Jagan Teki -S: Maintained -F: drivers/gpu/drm/panel/panel-sitronix-st7701.c -F: Documentation/devicetree/bindings/display/panel/sitronix,st7701.yaml - DRM DRIVER FOR SITRONIX ST7586 PANELS M: David Lechner S: Maintained From 58911c240783e0d1e7d457832416eb3347b8abbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 28 Apr 2020 20:19:25 +0300 Subject: [PATCH 079/109] drm: Nuke mode->hsync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's just calculate the hsync rate on demand. No point in wasting space storing it and risking the cached value getting out of sync with reality. v2: Move drm_mode_hsync() next to its only users Drop the TODO Reviewed-by: Sam Ravnborg Reviewed-by: Emil Velikov #v1 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20200428171940.19552-2-ville.syrjala@linux.intel.com --- Documentation/gpu/todo.rst | 12 --------- drivers/gpu/drm/drm_edid.c | 8 ++++++ drivers/gpu/drm/drm_modes.c | 26 -------------------- drivers/gpu/drm/i915/display/intel_display.c | 1 - include/drm/drm_modes.h | 11 --------- 5 files changed, 8 insertions(+), 50 deletions(-) diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 439656f55c5d..658b52f7ffc6 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -347,18 +347,6 @@ Contact: Sean Paul Level: Starter -Remove drm_display_mode.hsync ------------------------------ - -We have drm_mode_hsync() to calculate this from hsync_start/end, since drivers -shouldn't/don't use this, remove this member to avoid any temptations to use it -in the future. If there is any debug code using drm_display_mode.hsync, convert -it to use drm_mode_hsync() instead. - -Contact: Sean Paul - -Level: Starter - connector register/unregister fixes ----------------------------------- diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 43b6ca364daa..3bd95c4b02eb 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -2380,6 +2380,14 @@ bad_std_timing(u8 a, u8 b) (a == 0x20 && b == 0x20); } +static int drm_mode_hsync(const struct drm_display_mode *mode) +{ + if (mode->htotal <= 0) + return 0; + + return DIV_ROUND_CLOSEST(mode->clock, mode->htotal); +} + /** * drm_mode_std - convert standard mode info (width, height, refresh) into mode * @connector: connector of for the EDID block diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index d4d64518e11b..fec1c33b3045 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -747,32 +747,6 @@ void drm_mode_set_name(struct drm_display_mode *mode) } EXPORT_SYMBOL(drm_mode_set_name); -/** - * drm_mode_hsync - get the hsync of a mode - * @mode: mode - * - * Returns: - * @modes's hsync rate in kHz, rounded to the nearest integer. Calculates the - * value first if it is not yet set. - */ -int drm_mode_hsync(const struct drm_display_mode *mode) -{ - unsigned int calc_val; - - if (mode->hsync) - return mode->hsync; - - if (mode->htotal <= 0) - return 0; - - calc_val = (mode->clock * 1000) / mode->htotal; /* hsync in Hz */ - calc_val += 500; /* round to 1000Hz */ - calc_val /= 1000; /* truncate to kHz */ - - return calc_val; -} -EXPORT_SYMBOL(drm_mode_hsync); - /** * drm_mode_vrefresh - get the vrefresh of a mode * @mode: mode diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 346846609f45..ec7e943fd877 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8891,7 +8891,6 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode, mode->clock = pipe_config->hw.adjusted_mode.crtc_clock; - mode->hsync = drm_mode_hsync(mode); mode->vrefresh = drm_mode_vrefresh(mode); drm_mode_set_name(mode); } diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h index 99134d4f35eb..730fc31de4fb 100644 --- a/include/drm/drm_modes.h +++ b/include/drm/drm_modes.h @@ -390,16 +390,6 @@ struct drm_display_mode { */ int vrefresh; - /** - * @hsync: - * - * Horizontal refresh rate, for debug output in human readable form. Not - * used in a functional way. - * - * This value is in kHz. - */ - int hsync; - /** * @picture_aspect_ratio: * @@ -493,7 +483,6 @@ int of_get_drm_display_mode(struct device_node *np, int index); void drm_mode_set_name(struct drm_display_mode *mode); -int drm_mode_hsync(const struct drm_display_mode *mode); int drm_mode_vrefresh(const struct drm_display_mode *mode); void drm_mode_get_hv_timing(const struct drm_display_mode *mode, int *hdisplay, int *vdisplay); From 6d4f3e2bfc4968eba13ea41bd3040ed76733324b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 29 Apr 2020 12:48:24 +0200 Subject: [PATCH 080/109] video: fbdev: controlfb: fix build for COMPILE_TEST=y && PPC_PMAC=y && PPC32=n powerpc allyesconfig fails like this: drivers/video/fbdev/controlfb.c: In function 'controlfb_mmap': drivers/video/fbdev/controlfb.c:756:23: error: implicit declaration of function 'pgprot_cached_wthru'; did you mean 'pgprot_cached'? [-Werror=implicit-function-declaration] 756 | vma->vm_page_prot = pgprot_cached_wthru(vma->vm_page_prot); | ^~~~~~~~~~~~~~~~~~~ | pgprot_cached drivers/video/fbdev/controlfb.c:756:23: error: incompatible types when assigning to type 'pgprot_t' {aka 'struct '} from type 'int' Fix it by adding missing PPC32 dependency. Fixes: a07a63b0e24d ("video: fbdev: controlfb: add COMPILE_TEST support") Reported-by: Stephen Rothwell Reported-by: kbuild test robot Cc: Sam Ravnborg Cc: Daniel Vetter Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/fe520316-3863-e6c4-9581-5d709f49e906@samsung.com --- drivers/video/fbdev/controlfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/controlfb.c b/drivers/video/fbdev/controlfb.c index 52170ed20e74..9c4f1be856ec 100644 --- a/drivers/video/fbdev/controlfb.c +++ b/drivers/video/fbdev/controlfb.c @@ -55,7 +55,7 @@ #include "macmodes.h" #include "controlfb.h" -#ifndef CONFIG_PPC_PMAC +#if !defined(CONFIG_PPC_PMAC) || !defined(CONFIG_PPC32) #define invalid_vram_cache(addr) #undef in_8 #undef out_8 From 78b0d99a68ecdc84728c99f4fef71942e9ecf35a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 28 Apr 2020 23:53:54 +0200 Subject: [PATCH 081/109] drm/bridge: fix stack usage warning on old gcc Some older versions of gcc badly optimize code that passes an inline function argument into another function by reference, causing huge stack usage: drivers/gpu/drm/bridge/tc358768.c: In function 'tc358768_bridge_pre_enable': drivers/gpu/drm/bridge/tc358768.c:840:1: error: the frame size of 2256 bytes is larger than 2048 bytes [-Werror=frame-larger-than=] Use a temporary variable as a workaround and add a comment pointing to the gcc bug. Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver") Signed-off-by: Arnd Bergmann Reviewed-by: Tomi Valkeinen Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200428215408.4111675-1-arnd@arndb.de --- drivers/gpu/drm/bridge/tc358768.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index 1b39e8d37834..6650fe4cfc20 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -178,6 +178,8 @@ static int tc358768_clear_error(struct tc358768_priv *priv) static void tc358768_write(struct tc358768_priv *priv, u32 reg, u32 val) { + /* work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ + int tmpval = val; size_t count = 2; if (priv->error) @@ -187,7 +189,7 @@ static void tc358768_write(struct tc358768_priv *priv, u32 reg, u32 val) if (reg < 0x100 || reg >= 0x600) count = 1; - priv->error = regmap_bulk_write(priv->regmap, reg, &val, count); + priv->error = regmap_bulk_write(priv->regmap, reg, &tmpval, count); } static void tc358768_read(struct tc358768_priv *priv, u32 reg, u32 *val) From ef54569966f7b3090a6f1e4bd61db7f2ff2a62f9 Mon Sep 17 00:00:00 2001 From: Jason Yan Date: Wed, 29 Apr 2020 22:10:10 +0800 Subject: [PATCH 082/109] drm/ast: remove duplicate assignment of ast_crtc_funcs member The struct member 'set_config' was assigned twice: static const struct drm_crtc_funcs ast_crtc_funcs = { .reset = ast_crtc_reset, .set_config = drm_crtc_helper_set_config, ...... .set_config = drm_atomic_helper_set_config, ...... }; Since the second one is which we use now in fact, we can remove the first one. This fixes the following coccicheck warning: drivers/gpu/drm/ast/ast_mode.c:932:50-51: set_config: first occurrence line 934, second occurrence line 937 Signed-off-by: Jason Yan Signed-off-by: Thomas Zimmermann Reviewed-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20200429141010.8445-1-yanaijie@huawei.com --- drivers/gpu/drm/ast/ast_mode.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index d2ab81f9c498..7062bcd78740 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -931,7 +931,6 @@ static void ast_crtc_atomic_destroy_state(struct drm_crtc *crtc, static const struct drm_crtc_funcs ast_crtc_funcs = { .reset = ast_crtc_reset, - .set_config = drm_crtc_helper_set_config, .gamma_set = drm_atomic_helper_legacy_gamma_set, .destroy = ast_crtc_destroy, .set_config = drm_atomic_helper_set_config, From 7837300c250cdda06bf82177fa4f1a512d290ee0 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Wed, 29 Apr 2020 14:41:42 -0400 Subject: [PATCH 083/109] drm: Correct DP DSC macro typo In the file drm_dp_helper.h we have a macro named DP_DSC_THROUGHPUT_MODE_{0,1}_UPSUPPORTED, the correct name should be DP_DSC_THROUGHPUT_MODE_{0,1}_UNSUPPORTED. This commits adjusts this typo in the header file and in other places that attempt to access this macro. Reviewed-by: Harry Wentland Signed-off-by: Rodrigo Siqueira Signed-off-by: Alex Deucher Link: https://patchwork.freedesktop.org/patch/msgid/20200429184142.1867987-1-Rodrigo.Siqueira@amd.com --- drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c | 2 +- include/drm/drm_dp_helper.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c index 87d682d25278..0ea6662a1563 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c +++ b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c @@ -129,7 +129,7 @@ static bool dsc_line_buff_depth_from_dpcd(int dpcd_line_buff_bit_depth, int *lin static bool dsc_throughput_from_dpcd(int dpcd_throughput, int *throughput) { switch (dpcd_throughput) { - case DP_DSC_THROUGHPUT_MODE_0_UPSUPPORTED: + case DP_DSC_THROUGHPUT_MODE_0_UNSUPPORTED: *throughput = 0; break; case DP_DSC_THROUGHPUT_MODE_0_170: diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index e22cf5b2f174..09e674c228b9 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -292,7 +292,7 @@ #define DP_DSC_PEAK_THROUGHPUT 0x06B # define DP_DSC_THROUGHPUT_MODE_0_MASK (0xf << 0) # define DP_DSC_THROUGHPUT_MODE_0_SHIFT 0 -# define DP_DSC_THROUGHPUT_MODE_0_UPSUPPORTED 0 +# define DP_DSC_THROUGHPUT_MODE_0_UNSUPPORTED 0 # define DP_DSC_THROUGHPUT_MODE_0_340 (1 << 0) # define DP_DSC_THROUGHPUT_MODE_0_400 (2 << 0) # define DP_DSC_THROUGHPUT_MODE_0_450 (3 << 0) @@ -310,7 +310,7 @@ # define DP_DSC_THROUGHPUT_MODE_0_170 (15 << 0) /* 1.4a */ # define DP_DSC_THROUGHPUT_MODE_1_MASK (0xf << 4) # define DP_DSC_THROUGHPUT_MODE_1_SHIFT 4 -# define DP_DSC_THROUGHPUT_MODE_1_UPSUPPORTED 0 +# define DP_DSC_THROUGHPUT_MODE_1_UNSUPPORTED 0 # define DP_DSC_THROUGHPUT_MODE_1_340 (1 << 4) # define DP_DSC_THROUGHPUT_MODE_1_400 (2 << 4) # define DP_DSC_THROUGHPUT_MODE_1_450 (3 << 4) From 5213a8db23f1768c974b41c15df9d1570f5f5147 Mon Sep 17 00:00:00 2001 From: allen Date: Mon, 27 Apr 2020 17:16:52 +0800 Subject: [PATCH 084/109] dt-bindings: fix vendor prefix for ITE Tech. Inc. ITE Tech. Inc. (abbreviated as ITE ) is a professional fabless IC design house. ITE's core technology includes PC and NB Controller chips, Super I/O, High Speed Serial Interface, Video Codec, Touch Sensing, Surveillance, OFDM, Sensor Fusion, and so on. Our official name is "ITE Tech. Inc.", so change "ITE," to "ITE.". more information on: http://www.ite.com.tw/ Signed-off-by: Allen Chen Acked-by: Rob Herring Fixes: 17ff9478ffa3 ("dt-bindings: Add ITE Tech prefix") Cc: Marek Vasut Cc: devicetree@vger.kernel.org Cc: Allen Chen Signed-off-by: Sam Ravnborg [added fixes tag and updated subject] Link: https://patchwork.freedesktop.org/patch/msgid/1587979103-5630-2-git-send-email-allen.chen@ite.com.tw --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 31012f91fb9a..a129db1701e5 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -490,7 +490,7 @@ patternProperties: "^issi,.*": description: Integrated Silicon Solutions Inc. "^ite,.*": - description: ITE Tech, Inc. + description: ITE Tech. Inc. "^itead,.*": description: ITEAD Intelligent Systems Co.Ltd "^iwave,.*": From 5e6ed29d72d28ff7cd92ebf5711aac6a613ef01e Mon Sep 17 00:00:00 2001 From: allen Date: Mon, 27 Apr 2020 17:16:53 +0800 Subject: [PATCH 085/109] dt-bindings: Add binding for IT6505. Add a DT binding documentation for IT6505. Acked-by: Sam Ravnborg Signed-off-by: Allen Chen Signed-off-by: Pi-Hsun Shih Signed-off-by: Sam Ravnborg [fixed example to use i2c] Link: https://patchwork.freedesktop.org/patch/msgid/1587979103-5630-3-git-send-email-allen.chen@ite.com.tw --- .../bindings/display/bridge/ite,it6505.yaml | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml diff --git a/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml b/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml new file mode 100644 index 000000000000..2c500166c65d --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml @@ -0,0 +1,91 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/bridge/ite,it6505.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ITE it6505 Device Tree Bindings + +maintainers: + - Allen Chen + +description: | + The IT6505 is a high-performance DisplayPort 1.1a transmitter, + fully compliant with DisplayPort 1.1a, HDCP 1.3 specifications. + The IT6505 supports color depth of up to 36 bits (12 bits/color) + and ensures robust transmission of high-quality uncompressed video + content, along with uncompressed and compressed digital audio content. + + Aside from the various video output formats supported, the IT6505 + also encodes and transmits up to 8 channels of I2S digital audio, + with sampling rate up to 192kHz and sample size up to 24 bits. + In addition, an S/PDIF input port takes in compressed audio of up to + 192kHz frame rate. + + Each IT6505 chip comes preprogrammed with an unique HDCP key, + in compliance with the HDCP 1.3 standard so as to provide secure + transmission of high-definition content. Users of the IT6505 need not + purchase any HDCP keys or ROMs. + +properties: + compatible: + const: ite,it6505 + + ovdd-supply: + maxItems: 1 + description: I/O voltage + + pwr18-supply: + maxItems: 1 + description: core voltage + + interrupts: + maxItems: 1 + description: interrupt specifier of INT pin + + reset-gpios: + maxItems: 1 + description: gpio specifier of RESET pin + + extcon: + maxItems: 1 + description: extcon specifier for the Power Delivery + + port: + type: object + description: A port node pointing to DPI host port node + +required: + - compatible + - ovdd-supply + - pwr18-supply + - interrupts + - reset-gpios + - extcon + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + dp-bridge@5c { + compatible = "ite,it6505"; + interrupts = <152 IRQ_TYPE_EDGE_FALLING 152 0>; + reg = <0x5c>; + pinctrl-names = "default"; + pinctrl-0 = <&it6505_pins>; + ovdd-supply = <&mt6358_vsim1_reg>; + pwr18-supply = <&it6505_pp18_reg>; + reset-gpios = <&pio 179 1>; + extcon = <&usbc_extcon>; + + port { + it6505_in: endpoint { + remote-endpoint = <&dpi_out>; + }; + }; + }; + }; From 27a46fb732c6af68ef7458e75768ea5608e8ef9c Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 17 Apr 2020 14:40:43 +0300 Subject: [PATCH 086/109] drm/panel: panel-simple: fix AUO G101EVN010 connector/panel type The AUO G101EVN010 is a 18-bit LVDS panel, not a parallel panel, as indicated by the current bus_format. Fix the bus_format to MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, and also set the connector_type to LVDS. Signed-off-by: Tomi Valkeinen Signed-off-by: Sam Ravnborg [updated patch subject] Link: https://patchwork.freedesktop.org/patch/msgid/20200417114043.25381-1-tomi.valkeinen@ti.com --- drivers/gpu/drm/panel/panel-simple.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 5e56c68fbd3e..d6c29543e510 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -836,7 +836,8 @@ static const struct panel_desc auo_g101evn010 = { .width = 216, .height = 135, }, - .bus_format = MEDIA_BUS_FMT_RGB666_1X18, + .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct drm_display_mode auo_g104sn02_mode = { From 1f52bab3c9bffeb945c3453f26155fb75f851935 Mon Sep 17 00:00:00 2001 From: Adrian Ratiu Date: Thu, 23 Apr 2020 13:00:58 +0300 Subject: [PATCH 087/109] dt-bindings: display: dw_mipi_dsi.txt: convert to yaml This converts the Synopsis MIPI DSI binding documentation to yaml and should be quite straightforward. I've added a missing ref clk and also added Philippe as maintainer b/c he's the original txt author following the algorithm provided in Message-ID 20200420175909.GA5810@ravnborg.org. Cc: Philippe CORNU Cc: devicetree@vger.kernel.org Suggested-by: Laurent Pinchart Reviewed-by: Rob Herring Signed-off-by: Adrian Ratiu Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200423100058.1734009-1-adrian.ratiu@collabora.com --- .../bindings/display/bridge/dw_mipi_dsi.txt | 32 --------- .../display/bridge/snps,dw-mipi-dsi.yaml | 68 +++++++++++++++++++ 2 files changed, 68 insertions(+), 32 deletions(-) delete mode 100644 Documentation/devicetree/bindings/display/bridge/dw_mipi_dsi.txt create mode 100644 Documentation/devicetree/bindings/display/bridge/snps,dw-mipi-dsi.yaml diff --git a/Documentation/devicetree/bindings/display/bridge/dw_mipi_dsi.txt b/Documentation/devicetree/bindings/display/bridge/dw_mipi_dsi.txt deleted file mode 100644 index b13adf30b8d3..000000000000 --- a/Documentation/devicetree/bindings/display/bridge/dw_mipi_dsi.txt +++ /dev/null @@ -1,32 +0,0 @@ -Synopsys DesignWare MIPI DSI host controller -============================================ - -This document defines device tree properties for the Synopsys DesignWare MIPI -DSI host controller. It doesn't constitue a device tree binding specification -by itself but is meant to be referenced by platform-specific device tree -bindings. - -When referenced from platform device tree bindings the properties defined in -this document are defined as follows. The platform device tree bindings are -responsible for defining whether each optional property is used or not. - -- reg: Memory mapped base address and length of the DesignWare MIPI DSI - host controller registers. (mandatory) - -- clocks: References to all the clocks specified in the clock-names property - as specified in [1]. (mandatory) - -- clock-names: - - "pclk" is the peripheral clock for either AHB and APB. (mandatory) - - "px_clk" is the pixel clock for the DPI/RGB input. (optional) - -- resets: References to all the resets specified in the reset-names property - as specified in [2]. (optional) - -- reset-names: string reset name, must be "apb" if used. (optional) - -- panel or bridge node: see [3]. (mandatory) - -[1] Documentation/devicetree/bindings/clock/clock-bindings.txt -[2] Documentation/devicetree/bindings/reset/reset.txt -[3] Documentation/devicetree/bindings/display/mipi-dsi-bus.txt diff --git a/Documentation/devicetree/bindings/display/bridge/snps,dw-mipi-dsi.yaml b/Documentation/devicetree/bindings/display/bridge/snps,dw-mipi-dsi.yaml new file mode 100644 index 000000000000..012aa8e7cb8c --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/snps,dw-mipi-dsi.yaml @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/bridge/snps,dw-mipi-dsi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Synopsys DesignWare MIPI DSI host controller + +maintainers: + - Philippe CORNU + +description: | + This document defines device tree properties for the Synopsys DesignWare MIPI + DSI host controller. It doesn't constitue a device tree binding specification + by itself but is meant to be referenced by platform-specific device tree + bindings. + + When referenced from platform device tree bindings the properties defined in + this document are defined as follows. The platform device tree bindings are + responsible for defining whether each property is required or optional. + +allOf: + - $ref: ../dsi-controller.yaml# + +properties: + reg: + maxItems: 1 + + clocks: + items: + - description: Module clock + - description: DSI bus clock for either AHB and APB + - description: Pixel clock for the DPI/RGB input + minItems: 2 + + clock-names: + items: + - const: ref + - const: pclk + - const: px_clk + minItems: 2 + + resets: + maxItems: 1 + + reset-names: + const: apb + + ports: + type: object + + properties: + port@0: + type: object + description: Input node to receive pixel data. + port@1: + type: object + description: DSI output node to panel. + + required: + - port@0 + - port@1 + +required: + - clock-names + - clocks + - ports + - reg From 42470eec8552e51e98fe89742bd95cc732aac28f Mon Sep 17 00:00:00 2001 From: David Lu Date: Tue, 28 Apr 2020 14:45:21 +0800 Subject: [PATCH 088/109] drm/panel: boe-tv101wum-n16: fine tune clock fix boe_tv105wum_nw0 display shift. Signed-off-by: David Lu Fixes: 963518c12431 ("drm/panel: support for boe,tv105wum-nw0 dsi video mode panel") Cc: David Lu Cc: Nicolas Boichat Cc: Sam Ravnborg Cc: Thierry Reding Cc: dri-devel@lists.freedesktop.org Signed-off-by: Sam Ravnborg [added fixes tag] Link: https://patchwork.freedesktop.org/patch/msgid/20200428064521.21511-1-david.lu@bitland.com.cn --- drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c index f89861c8598a..46fe1805c588 100644 --- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c +++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c @@ -697,15 +697,15 @@ static const struct panel_desc auo_b101uan08_3_desc = { }; static const struct drm_display_mode boe_tv105wum_nw0_default_mode = { - .clock = 159260, + .clock = 159916, .hdisplay = 1200, .hsync_start = 1200 + 80, .hsync_end = 1200 + 80 + 24, .htotal = 1200 + 80 + 24 + 60, .vdisplay = 1920, - .vsync_start = 1920 + 10, - .vsync_end = 1920 + 10 + 2, - .vtotal = 1920 + 10 + 2 + 14, + .vsync_start = 1920 + 20, + .vsync_end = 1920 + 20 + 4, + .vtotal = 1920 + 20 + 4 + 10, .vrefresh = 60, .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, }; From 9cd39de4db54062ad60f8004362c293c0c950456 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 17 Apr 2020 14:41:51 +0300 Subject: [PATCH 089/109] drm/omap: change default signal polarities and drives If the given videomode does not specify DISPLAY_FLAG_* for the specific signal property, the driver used a default value. These defaults were never thought through, as the expectation was that all the DISPLAY_FLAGS are always set explicitly. With DRM bridge and panel drivers this is not the case, and while that issue should be resolved in the future, it's still good to have sane signal defaults. This patch changes the defaults to what the hardware has as reset defaults. Also, based on my experience, I think they make sense and are more likely correct than the defaults without this patch. Signed-off-by: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20200417114151.25843-1-tomi.valkeinen@ti.com Reviewed-by: Laurent Pinchart --- drivers/gpu/drm/omapdrm/dss/dispc.c | 33 ++++++----------------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index dbb90f2d2ccd..6639ee9b05d3 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c @@ -3137,33 +3137,12 @@ static void _dispc_mgr_set_lcd_timings(struct dispc_device *dispc, dispc_write_reg(dispc, DISPC_TIMING_H(channel), timing_h); dispc_write_reg(dispc, DISPC_TIMING_V(channel), timing_v); - if (vm->flags & DISPLAY_FLAGS_VSYNC_HIGH) - vs = false; - else - vs = true; - - if (vm->flags & DISPLAY_FLAGS_HSYNC_HIGH) - hs = false; - else - hs = true; - - if (vm->flags & DISPLAY_FLAGS_DE_HIGH) - de = false; - else - de = true; - - if (vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE) - ipc = false; - else - ipc = true; - - /* always use the 'rf' setting */ - onoff = true; - - if (vm->flags & DISPLAY_FLAGS_SYNC_POSEDGE) - rf = true; - else - rf = false; + vs = !!(vm->flags & DISPLAY_FLAGS_VSYNC_LOW); + hs = !!(vm->flags & DISPLAY_FLAGS_HSYNC_LOW); + de = !!(vm->flags & DISPLAY_FLAGS_DE_LOW); + ipc = !!(vm->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE); + onoff = true; /* always use the 'rf' setting */ + rf = !!(vm->flags & DISPLAY_FLAGS_SYNC_POSEDGE); l = FLD_VAL(onoff, 17, 17) | FLD_VAL(rf, 16, 16) | From a8d9d7da1546349f18eb2d6b6b3a04bdeb38719d Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 29 Apr 2020 15:10:22 +0300 Subject: [PATCH 090/109] drm/tidss: remove AM65x PG1 YUV erratum code AM65x PG1 has a HW issue with YUV pixel formats, resulting in wrong colors on the screen. This issue is fixed in PG2 hardware. The driver currently has code to hide YUV pixel formats from the userspace. To support PG2, we would need to add code to detect the SoC version and hide the YUV formats based on that. However, as PG1 will be phased out and PG2 will be the main platform, a much simpler solution is just to drop the code in question. The downside is that the users will be able to use YUV formats on PG1, getting wrong colors on the screen. On the other hand, that may also be a plus, as the same applications will now work on PG1 and PG2, even if the colors are wrong on PG1. Signed-off-by: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20200429121022.3871-1-tomi.valkeinen@ti.com Reviewed-by: Jyri Sarha --- drivers/gpu/drm/tidss/tidss_dispc.c | 11 ++--------- drivers/gpu/drm/tidss/tidss_dispc.h | 6 ------ 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c index 29f42768e294..629dd06393f6 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.c +++ b/drivers/gpu/drm/tidss/tidss_dispc.c @@ -181,10 +181,6 @@ const struct dispc_features dispc_am65x_feats = { .vid_name = { "vid", "vidl1" }, .vid_lite = { false, true, }, .vid_order = { 1, 0 }, - - .errata = { - .i2000 = true, - }, }; static const u16 tidss_j721e_common_regs[DISPC_COMMON_REG_TABLE_LEN] = { @@ -2674,12 +2670,9 @@ int dispc_init(struct tidss_device *tidss) return -ENOMEM; num_fourccs = 0; - for (i = 0; i < ARRAY_SIZE(dispc_color_formats); ++i) { - if (feat->errata.i2000 && - dispc_fourcc_is_yuv(dispc_color_formats[i].fourcc)) - continue; + for (i = 0; i < ARRAY_SIZE(dispc_color_formats); ++i) dispc->fourccs[num_fourccs++] = dispc_color_formats[i].fourcc; - } + dispc->num_fourccs = num_fourccs; dispc->tidss = tidss; dispc->dev = dev; diff --git a/drivers/gpu/drm/tidss/tidss_dispc.h b/drivers/gpu/drm/tidss/tidss_dispc.h index a4a68249e44b..902e612ff7ac 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.h +++ b/drivers/gpu/drm/tidss/tidss_dispc.h @@ -46,10 +46,6 @@ struct dispc_features_scaling { u32 xinc_max; }; -struct dispc_errata { - bool i2000; /* DSS Does Not Support YUV Pixel Data Formats */ -}; - enum dispc_vp_bus_type { DISPC_VP_DPI, /* DPI output */ DISPC_VP_OLDI, /* OLDI (LVDS) output */ @@ -83,8 +79,6 @@ struct dispc_features { const char *vid_name[TIDSS_MAX_PLANES]; /* Should match dt reg names */ bool vid_lite[TIDSS_MAX_PLANES]; u32 vid_order[TIDSS_MAX_PLANES]; - - struct dispc_errata errata; }; extern const struct dispc_features dispc_k2g_feats; From 647f0d0ac1a6c5a8635464f1120e2cb5368a37cb Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Fri, 24 Apr 2020 23:35:37 +0200 Subject: [PATCH 091/109] dt-bindings: Add vendor prefix for Chrontel, Inc. Chrontel makes encoders for video displays and perhaps other stuff. Their web site is http://www.chrontel.com/. Signed-off-by: Lubomir Rintel Acked-by: Rob Herring Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20200424213539.93157-2-lkundrak@v3.sk --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index a129db1701e5..05a98c26828d 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -187,6 +187,8 @@ patternProperties: description: ChipOne "^chipspark,.*": description: ChipSPARK + "^chrontel,.*": + description: Chrontel, Inc. "^chrp,.*": description: Common Hardware Reference Platform "^chunghwa,.*": From a7e73070afe62bc6c88560f10a189d43a215aed2 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Fri, 24 Apr 2020 23:35:38 +0200 Subject: [PATCH 092/109] dt-bindings: display: Add Chrontel CH7033 Video Encoder binding Add binding document for the Chrontel CH7033 VGA/DVI/HDMI Encoder. Signed-off-by: Lubomir Rintel Reviewed-by: Rob Herring Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20200424213539.93157-3-lkundrak@v3.sk --- .../display/bridge/chrontel,ch7033.yaml | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/chrontel,ch7033.yaml diff --git a/Documentation/devicetree/bindings/display/bridge/chrontel,ch7033.yaml b/Documentation/devicetree/bindings/display/bridge/chrontel,ch7033.yaml new file mode 100644 index 000000000000..9f38f55fc990 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/chrontel,ch7033.yaml @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) 2019,2020 Lubomir Rintel +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/bridge/chrontel,ch7033.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Chrontel CH7033 Video Encoder Device Tree Bindings + +maintainers: + - Lubomir Rintel + +properties: + compatible: + const: chrontel,ch7033 + + reg: + maxItems: 1 + description: I2C address of the device + + ports: + type: object + + properties: + port@0: + type: object + description: | + Video port for RGB input. + + port@1: + type: object + description: | + DVI port, should be connected to a node compatible with the + dvi-connector binding. + + required: + - port@0 + - port@1 + +required: + - compatible + - reg + - ports + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + vga-dvi-encoder@76 { + compatible = "chrontel,ch7033"; + reg = <0x76>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + endpoint { + remote-endpoint = <&lcd0_rgb_out>; + }; + }; + + port@1 { + reg = <1>; + endpoint { + remote-endpoint = <&dvi_in>; + }; + }; + + }; + }; + }; From e7f12054a1b9cbf6b4923427dec5eeb32f7ac388 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Fri, 24 Apr 2020 23:35:39 +0200 Subject: [PATCH 093/109] drm/bridge: chrontel-ch7033: Add a new driver This is a driver for video encoder with VGA and DVI/HDMI outputs. There is no documentation for the chip -- the operation was guessed from what was sniffed on a Dell Wyse 3020 ThinOS terminal, the register names come from the ch7035 driver in Mediatek's GPL code dump. Only bare minimum is implemented -- no fancy stuff, such as scaling. That would only worsen our misery. We don't load the firmware and we don't need to even bother enabling the MCU. There are probably no distributable firmware images anyway. Tested with a handful of monitors ranging from 1024x768@75 to 1400x1050@60, with VGA as well as DVI. Signed-off-by: Lubomir Rintel Acked-by: Sam Ravnborg Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20200424213539.93157-4-lkundrak@v3.sk --- drivers/gpu/drm/bridge/Kconfig | 10 + drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/chrontel-ch7033.c | 620 +++++++++++++++++++++++ 3 files changed, 631 insertions(+) create mode 100644 drivers/gpu/drm/bridge/chrontel-ch7033.c diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 6ec945f837b8..04f876e985de 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -27,6 +27,16 @@ config DRM_CDNS_DSI Support Cadence DPI to DSI bridge. This is an internal bridge and is meant to be directly embedded in a SoC. +config DRM_CHRONTEL_CH7033 + tristate "Chrontel CH7033 Video Encoder" + depends on OF + select DRM_KMS_HELPER + help + Enable support for the Chrontel CH7033 VGA/DVI/HDMI Encoder, as + found in the Dell Wyse 3020 thin client. + + If in doubt, say "N". + config DRM_DISPLAY_CONNECTOR tristate "Display connector support" depends on OF diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index b04ac2dfa22c..d63d4b7e4347 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o +obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o obj-$(CONFIG_DRM_DISPLAY_CONNECTOR) += display-connector.o obj-$(CONFIG_DRM_LVDS_CODEC) += lvds-codec.o obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v3-fw.o diff --git a/drivers/gpu/drm/bridge/chrontel-ch7033.c b/drivers/gpu/drm/bridge/chrontel-ch7033.c new file mode 100644 index 000000000000..f8675d82974b --- /dev/null +++ b/drivers/gpu/drm/bridge/chrontel-ch7033.c @@ -0,0 +1,620 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Chrontel CH7033 Video Encoder Driver + * + * Copyright (C) 2019,2020 Lubomir Rintel + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* Page 0, Register 0x07 */ +enum { + DRI_PD = BIT(3), + IO_PD = BIT(5), +}; + +/* Page 0, Register 0x08 */ +enum { + DRI_PDDRI = GENMASK(7, 4), + PDDAC = GENMASK(3, 1), + PANEN = BIT(0), +}; + +/* Page 0, Register 0x09 */ +enum { + DPD = BIT(7), + GCKOFF = BIT(6), + TV_BP = BIT(5), + SCLPD = BIT(4), + SDPD = BIT(3), + VGA_PD = BIT(2), + HDBKPD = BIT(1), + HDMI_PD = BIT(0), +}; + +/* Page 0, Register 0x0a */ +enum { + MEMINIT = BIT(7), + MEMIDLE = BIT(6), + MEMPD = BIT(5), + STOP = BIT(4), + LVDS_PD = BIT(3), + HD_DVIB = BIT(2), + HDCP_PD = BIT(1), + MCU_PD = BIT(0), +}; + +/* Page 0, Register 0x18 */ +enum { + IDF = GENMASK(7, 4), + INTEN = BIT(3), + SWAP = GENMASK(2, 0), +}; + +enum { + BYTE_SWAP_RGB = 0, + BYTE_SWAP_RBG = 1, + BYTE_SWAP_GRB = 2, + BYTE_SWAP_GBR = 3, + BYTE_SWAP_BRG = 4, + BYTE_SWAP_BGR = 5, +}; + +/* Page 0, Register 0x19 */ +enum { + HPO_I = BIT(5), + VPO_I = BIT(4), + DEPO_I = BIT(3), + CRYS_EN = BIT(2), + GCLKFREQ = GENMASK(2, 0), +}; + +/* Page 0, Register 0x2e */ +enum { + HFLIP = BIT(7), + VFLIP = BIT(6), + DEPO_O = BIT(5), + HPO_O = BIT(4), + VPO_O = BIT(3), + TE = GENMASK(2, 0), +}; + +/* Page 0, Register 0x2b */ +enum { + SWAPS = GENMASK(7, 4), + VFMT = GENMASK(3, 0), +}; + +/* Page 0, Register 0x54 */ +enum { + COMP_BP = BIT(7), + DAC_EN_T = BIT(6), + HWO_HDMI_HI = GENMASK(5, 3), + HOO_HDMI_HI = GENMASK(2, 0), +}; + +/* Page 0, Register 0x57 */ +enum { + FLDSEN = BIT(7), + VWO_HDMI_HI = GENMASK(5, 3), + VOO_HDMI_HI = GENMASK(2, 0), +}; + +/* Page 0, Register 0x7e */ +enum { + HDMI_LVDS_SEL = BIT(7), + DE_GEN = BIT(6), + PWM_INDEX_HI = BIT(5), + USE_DE = BIT(4), + R_INT = GENMASK(3, 0), +}; + +/* Page 1, Register 0x07 */ +enum { + BPCKSEL = BIT(7), + DRI_CMFB_EN = BIT(6), + CEC_PUEN = BIT(5), + CEC_T = BIT(3), + CKINV = BIT(2), + CK_TVINV = BIT(1), + DRI_CKS2 = BIT(0), +}; + +/* Page 1, Register 0x08 */ +enum { + DACG = BIT(6), + DACKTST = BIT(5), + DEDGEB = BIT(4), + SYO = BIT(3), + DRI_IT_LVDS = GENMASK(2, 1), + DISPON = BIT(0), +}; + +/* Page 1, Register 0x0c */ +enum { + DRI_PLL_CP = GENMASK(7, 6), + DRI_PLL_DIVSEL = BIT(5), + DRI_PLL_N1_1 = BIT(4), + DRI_PLL_N1_0 = BIT(3), + DRI_PLL_N3_1 = BIT(2), + DRI_PLL_N3_0 = BIT(1), + DRI_PLL_CKTSTEN = BIT(0), +}; + +/* Page 1, Register 0x6b */ +enum { + VCO3CS = GENMASK(7, 6), + ICPGBK2_0 = GENMASK(5, 3), + DRI_VCO357SC = BIT(2), + PDPLL2 = BIT(1), + DRI_PD_SER = BIT(0), +}; + +/* Page 1, Register 0x6c */ +enum { + PLL2N11 = GENMASK(7, 4), + PLL2N5_4 = BIT(3), + PLL2N5_TOP = BIT(2), + DRI_PLL_PD = BIT(1), + PD_I2CM = BIT(0), +}; + +/* Page 3, Register 0x28 */ +enum { + DIFF_EN = GENMASK(7, 6), + CORREC_EN = GENMASK(5, 4), + VGACLK_BP = BIT(3), + HM_LV_SEL = BIT(2), + HD_VGA_SEL = BIT(1), +}; + +/* Page 3, Register 0x2a */ +enum { + LVDSCLK_BP = BIT(7), + HDTVCLK_BP = BIT(6), + HDMICLK_BP = BIT(5), + HDTV_BP = BIT(4), + HDMI_BP = BIT(3), + THRWL = GENMASK(2, 0), +}; + +/* Page 4, Register 0x52 */ +enum { + PGM_ARSTB = BIT(7), + MCU_ARSTB = BIT(6), + MCU_RETB = BIT(2), + RESETIB = BIT(1), + RESETDB = BIT(0), +}; + +struct ch7033_priv { + struct regmap *regmap; + struct drm_bridge *next_bridge; + struct drm_bridge bridge; + struct drm_connector connector; +}; + +#define conn_to_ch7033_priv(x) \ + container_of(x, struct ch7033_priv, connector) +#define bridge_to_ch7033_priv(x) \ + container_of(x, struct ch7033_priv, bridge) + + +static enum drm_connector_status ch7033_connector_detect( + struct drm_connector *connector, bool force) +{ + struct ch7033_priv *priv = conn_to_ch7033_priv(connector); + + return drm_bridge_detect(priv->next_bridge); +} + +static const struct drm_connector_funcs ch7033_connector_funcs = { + .reset = drm_atomic_helper_connector_reset, + .fill_modes = drm_helper_probe_single_connector_modes, + .detect = ch7033_connector_detect, + .destroy = drm_connector_cleanup, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static int ch7033_connector_get_modes(struct drm_connector *connector) +{ + struct ch7033_priv *priv = conn_to_ch7033_priv(connector); + struct edid *edid; + int ret; + + edid = drm_bridge_get_edid(priv->next_bridge, connector); + drm_connector_update_edid_property(connector, edid); + if (edid) { + ret = drm_add_edid_modes(connector, edid); + kfree(edid); + } else { + ret = drm_add_modes_noedid(connector, 1920, 1080); + drm_set_preferred_mode(connector, 1024, 768); + } + + return ret; +} + +static struct drm_encoder *ch7033_connector_best_encoder( + struct drm_connector *connector) +{ + struct ch7033_priv *priv = conn_to_ch7033_priv(connector); + + return priv->bridge.encoder; +} + +static const struct drm_connector_helper_funcs ch7033_connector_helper_funcs = { + .get_modes = ch7033_connector_get_modes, + .best_encoder = ch7033_connector_best_encoder, +}; + +static void ch7033_hpd_event(void *arg, enum drm_connector_status status) +{ + struct ch7033_priv *priv = arg; + + if (priv->bridge.dev) + drm_helper_hpd_irq_event(priv->connector.dev); +} + +static int ch7033_bridge_attach(struct drm_bridge *bridge, + enum drm_bridge_attach_flags flags) +{ + struct ch7033_priv *priv = bridge_to_ch7033_priv(bridge); + struct drm_connector *connector = &priv->connector; + int ret; + + ret = drm_bridge_attach(bridge->encoder, priv->next_bridge, bridge, + DRM_BRIDGE_ATTACH_NO_CONNECTOR); + if (ret) + return ret; + + if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) + return 0; + + if (priv->next_bridge->ops & DRM_BRIDGE_OP_DETECT) { + connector->polled = DRM_CONNECTOR_POLL_HPD; + } else { + connector->polled = DRM_CONNECTOR_POLL_CONNECT | + DRM_CONNECTOR_POLL_DISCONNECT; + } + + if (priv->next_bridge->ops & DRM_BRIDGE_OP_HPD) { + drm_bridge_hpd_enable(priv->next_bridge, ch7033_hpd_event, + priv); + } + + drm_connector_helper_add(connector, + &ch7033_connector_helper_funcs); + ret = drm_connector_init_with_ddc(bridge->dev, &priv->connector, + &ch7033_connector_funcs, + priv->next_bridge->type, + priv->next_bridge->ddc); + if (ret) { + DRM_ERROR("Failed to initialize connector\n"); + return ret; + } + + return drm_connector_attach_encoder(&priv->connector, bridge->encoder); +} + +static void ch7033_bridge_detach(struct drm_bridge *bridge) +{ + struct ch7033_priv *priv = bridge_to_ch7033_priv(bridge); + + if (priv->next_bridge->ops & DRM_BRIDGE_OP_HPD) + drm_bridge_hpd_disable(priv->next_bridge); + drm_connector_cleanup(&priv->connector); +} + +static enum drm_mode_status ch7033_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_mode *mode) +{ + if (mode->clock > 165000) + return MODE_CLOCK_HIGH; + if (mode->hdisplay >= 1920) + return MODE_BAD_HVALUE; + if (mode->vdisplay >= 1080) + return MODE_BAD_VVALUE; + return MODE_OK; +} + +static void ch7033_bridge_disable(struct drm_bridge *bridge) +{ + struct ch7033_priv *priv = bridge_to_ch7033_priv(bridge); + + regmap_write(priv->regmap, 0x03, 0x04); + regmap_update_bits(priv->regmap, 0x52, RESETDB, 0x00); +} + +static void ch7033_bridge_enable(struct drm_bridge *bridge) +{ + struct ch7033_priv *priv = bridge_to_ch7033_priv(bridge); + + regmap_write(priv->regmap, 0x03, 0x04); + regmap_update_bits(priv->regmap, 0x52, RESETDB, RESETDB); +} + +static void ch7033_bridge_mode_set(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + const struct drm_display_mode *adjusted_mode) +{ + struct ch7033_priv *priv = bridge_to_ch7033_priv(bridge); + int hbporch = mode->hsync_start - mode->hdisplay; + int hsynclen = mode->hsync_end - mode->hsync_start; + int vbporch = mode->vsync_start - mode->vdisplay; + int vsynclen = mode->vsync_end - mode->vsync_start; + + /* + * Page 4 + */ + regmap_write(priv->regmap, 0x03, 0x04); + + /* Turn everything off to set all the registers to their defaults. */ + regmap_write(priv->regmap, 0x52, 0x00); + /* Bring I/O block up. */ + regmap_write(priv->regmap, 0x52, RESETIB); + + /* + * Page 0 + */ + regmap_write(priv->regmap, 0x03, 0x00); + + /* Bring up parts we need from the power down. */ + regmap_update_bits(priv->regmap, 0x07, DRI_PD | IO_PD, 0); + regmap_update_bits(priv->regmap, 0x08, DRI_PDDRI | PDDAC | PANEN, 0); + regmap_update_bits(priv->regmap, 0x09, DPD | GCKOFF | + HDMI_PD | VGA_PD, 0); + regmap_update_bits(priv->regmap, 0x0a, HD_DVIB, 0); + + /* Horizontal input timing. */ + regmap_write(priv->regmap, 0x0b, (mode->htotal >> 8) << 3 | + (mode->hdisplay >> 8)); + regmap_write(priv->regmap, 0x0c, mode->hdisplay); + regmap_write(priv->regmap, 0x0d, mode->htotal); + regmap_write(priv->regmap, 0x0e, (hsynclen >> 8) << 3 | + (hbporch >> 8)); + regmap_write(priv->regmap, 0x0f, hbporch); + regmap_write(priv->regmap, 0x10, hsynclen); + + /* Vertical input timing. */ + regmap_write(priv->regmap, 0x11, (mode->vtotal >> 8) << 3 | + (mode->vdisplay >> 8)); + regmap_write(priv->regmap, 0x12, mode->vdisplay); + regmap_write(priv->regmap, 0x13, mode->vtotal); + regmap_write(priv->regmap, 0x14, ((vsynclen >> 8) << 3) | + (vbporch >> 8)); + regmap_write(priv->regmap, 0x15, vbporch); + regmap_write(priv->regmap, 0x16, vsynclen); + + /* Input color swap. */ + regmap_update_bits(priv->regmap, 0x18, SWAP, BYTE_SWAP_BGR); + + /* Input clock and sync polarity. */ + regmap_update_bits(priv->regmap, 0x19, 0x1, mode->clock >> 16); + regmap_update_bits(priv->regmap, 0x19, HPO_I | VPO_I | GCLKFREQ, + (mode->flags & DRM_MODE_FLAG_PHSYNC) ? HPO_I : 0 | + (mode->flags & DRM_MODE_FLAG_PVSYNC) ? VPO_I : 0 | + mode->clock >> 16); + regmap_write(priv->regmap, 0x1a, mode->clock >> 8); + regmap_write(priv->regmap, 0x1b, mode->clock); + + /* Horizontal output timing. */ + regmap_write(priv->regmap, 0x1f, (mode->htotal >> 8) << 3 | + (mode->hdisplay >> 8)); + regmap_write(priv->regmap, 0x20, mode->hdisplay); + regmap_write(priv->regmap, 0x21, mode->htotal); + + /* Vertical output timing. */ + regmap_write(priv->regmap, 0x25, (mode->vtotal >> 8) << 3 | + (mode->vdisplay >> 8)); + regmap_write(priv->regmap, 0x26, mode->vdisplay); + regmap_write(priv->regmap, 0x27, mode->vtotal); + + /* VGA channel bypass */ + regmap_update_bits(priv->regmap, 0x2b, VFMT, 9); + + /* Output sync polarity. */ + regmap_update_bits(priv->regmap, 0x2e, HPO_O | VPO_O, + (mode->flags & DRM_MODE_FLAG_PHSYNC) ? HPO_O : 0 | + (mode->flags & DRM_MODE_FLAG_PVSYNC) ? VPO_O : 0); + + /* HDMI horizontal output timing. */ + regmap_update_bits(priv->regmap, 0x54, HWO_HDMI_HI | HOO_HDMI_HI, + (hsynclen >> 8) << 3 | + (hbporch >> 8)); + regmap_write(priv->regmap, 0x55, hbporch); + regmap_write(priv->regmap, 0x56, hsynclen); + + /* HDMI vertical output timing. */ + regmap_update_bits(priv->regmap, 0x57, VWO_HDMI_HI | VOO_HDMI_HI, + (vsynclen >> 8) << 3 | + (vbporch >> 8)); + regmap_write(priv->regmap, 0x58, vbporch); + regmap_write(priv->regmap, 0x59, vsynclen); + + /* Pick HDMI, not LVDS. */ + regmap_update_bits(priv->regmap, 0x7e, HDMI_LVDS_SEL, HDMI_LVDS_SEL); + + /* + * Page 1 + */ + regmap_write(priv->regmap, 0x03, 0x01); + + /* No idea what these do, but VGA is wobbly and blinky without them. */ + regmap_update_bits(priv->regmap, 0x07, CKINV, CKINV); + regmap_update_bits(priv->regmap, 0x08, DISPON, DISPON); + + /* DRI PLL */ + regmap_update_bits(priv->regmap, 0x0c, DRI_PLL_DIVSEL, DRI_PLL_DIVSEL); + if (mode->clock <= 40000) { + regmap_update_bits(priv->regmap, 0x0c, DRI_PLL_N1_1 | + DRI_PLL_N1_0 | + DRI_PLL_N3_1 | + DRI_PLL_N3_0, + 0); + } else if (mode->clock < 80000) { + regmap_update_bits(priv->regmap, 0x0c, DRI_PLL_N1_1 | + DRI_PLL_N1_0 | + DRI_PLL_N3_1 | + DRI_PLL_N3_0, + DRI_PLL_N3_0 | + DRI_PLL_N1_0); + } else { + regmap_update_bits(priv->regmap, 0x0c, DRI_PLL_N1_1 | + DRI_PLL_N1_0 | + DRI_PLL_N3_1 | + DRI_PLL_N3_0, + DRI_PLL_N3_1 | + DRI_PLL_N1_1); + } + + /* This seems to be color calibration for VGA. */ + regmap_write(priv->regmap, 0x64, 0x29); /* LSB Blue */ + regmap_write(priv->regmap, 0x65, 0x29); /* LSB Green */ + regmap_write(priv->regmap, 0x66, 0x29); /* LSB Red */ + regmap_write(priv->regmap, 0x67, 0x00); /* MSB Blue */ + regmap_write(priv->regmap, 0x68, 0x00); /* MSB Green */ + regmap_write(priv->regmap, 0x69, 0x00); /* MSB Red */ + + regmap_update_bits(priv->regmap, 0x6b, DRI_PD_SER, 0x00); + regmap_update_bits(priv->regmap, 0x6c, DRI_PLL_PD, 0x00); + + /* + * Page 3 + */ + regmap_write(priv->regmap, 0x03, 0x03); + + /* More bypasses and apparently another HDMI/LVDS selector. */ + regmap_update_bits(priv->regmap, 0x28, VGACLK_BP | HM_LV_SEL, + VGACLK_BP | HM_LV_SEL); + regmap_update_bits(priv->regmap, 0x2a, HDMICLK_BP | HDMI_BP, + HDMICLK_BP | HDMI_BP); + + /* + * Page 4 + */ + regmap_write(priv->regmap, 0x03, 0x04); + + /* Output clock. */ + regmap_write(priv->regmap, 0x10, mode->clock >> 16); + regmap_write(priv->regmap, 0x11, mode->clock >> 8); + regmap_write(priv->regmap, 0x12, mode->clock); +} + +static const struct drm_bridge_funcs ch7033_bridge_funcs = { + .attach = ch7033_bridge_attach, + .detach = ch7033_bridge_detach, + .mode_valid = ch7033_bridge_mode_valid, + .disable = ch7033_bridge_disable, + .enable = ch7033_bridge_enable, + .mode_set = ch7033_bridge_mode_set, +}; + +static const struct regmap_config ch7033_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0x7f, +}; + +static int ch7033_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device *dev = &client->dev; + struct ch7033_priv *priv; + unsigned int val; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + dev_set_drvdata(dev, priv); + + ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1, NULL, + &priv->next_bridge); + if (ret) + return ret; + + priv->regmap = devm_regmap_init_i2c(client, &ch7033_regmap_config); + if (IS_ERR(priv->regmap)) { + dev_err(&client->dev, "regmap init failed\n"); + return PTR_ERR(priv->regmap); + } + + ret = regmap_read(priv->regmap, 0x00, &val); + if (ret < 0) { + dev_err(&client->dev, "error reading the model id: %d\n", ret); + return ret; + } + if ((val & 0xf7) != 0x56) { + dev_err(&client->dev, "the device is not a ch7033\n"); + return -ENODEV; + } + + regmap_write(priv->regmap, 0x03, 0x04); + ret = regmap_read(priv->regmap, 0x51, &val); + if (ret < 0) { + dev_err(&client->dev, "error reading the model id: %d\n", ret); + return ret; + } + if ((val & 0x0f) != 3) { + dev_err(&client->dev, "unknown revision %u\n", val); + return -ENODEV; + } + + INIT_LIST_HEAD(&priv->bridge.list); + priv->bridge.funcs = &ch7033_bridge_funcs; + priv->bridge.of_node = dev->of_node; + drm_bridge_add(&priv->bridge); + + dev_info(dev, "Chrontel CH7033 Video Encoder\n"); + return 0; +} + +static int ch7033_remove(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct ch7033_priv *priv = dev_get_drvdata(dev); + + drm_bridge_remove(&priv->bridge); + + return 0; +} + +static const struct of_device_id ch7033_dt_ids[] = { + { .compatible = "chrontel,ch7033", }, + { } +}; +MODULE_DEVICE_TABLE(of, ch7033_dt_ids); + +static const struct i2c_device_id ch7033_ids[] = { + { "ch7033", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ch7033_ids); + +static struct i2c_driver ch7033_driver = { + .probe = ch7033_probe, + .remove = ch7033_remove, + .driver = { + .name = "ch7033", + .of_match_table = of_match_ptr(ch7033_dt_ids), + }, + .id_table = ch7033_ids, +}; + +module_i2c_driver(ch7033_driver); + +MODULE_AUTHOR("Lubomir Rintel "); +MODULE_DESCRIPTION("Chrontel CH7033 Video Encoder Driver"); +MODULE_LICENSE("GPL v2"); From 8976eeee8de05f11eb424882a57084880b677525 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 28 Apr 2020 11:21:47 +0200 Subject: [PATCH 094/109] drm/meson: add mode selection limits against specific SoC revisions The Amlogic S805X/Y uses the same die as the S905X, but with more limited graphics capabilities. This adds a soc version detection adding specific limitations on the HDMI mode selections. Here, we limit to HDMI 1.2a max HDMI PHY clock frequency. Changes sinces v1: - Moved frequency check in the vclk code, and also checks DMT modes Signed-off-by: Neil Armstrong Acked-by: Martin Blumenstingl [narmstrong: fixed commit message with HDMI 1.2a instead of HDMI 1.3a] Link: https://patchwork.freedesktop.org/patch/msgid/20200428092147.13698-1-narmstrong@baylibre.com --- drivers/gpu/drm/meson/meson_drv.c | 29 ++++++++++++++++++++++++++- drivers/gpu/drm/meson/meson_drv.h | 6 ++++++ drivers/gpu/drm/meson/meson_dw_hdmi.c | 2 +- drivers/gpu/drm/meson/meson_vclk.c | 16 ++++++++++++++- drivers/gpu/drm/meson/meson_vclk.h | 3 ++- 5 files changed, 52 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 6f29fab79952..621f6de0f076 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -183,6 +184,24 @@ static void meson_remove_framebuffers(void) kfree(ap); } +struct meson_drm_soc_attr { + struct meson_drm_soc_limits limits; + const struct soc_device_attribute *attrs; +}; + +static const struct meson_drm_soc_attr meson_drm_soc_attrs[] = { + /* S805X/S805Y HDMI PLL won't lock for HDMI PHY freq > 1,65GHz */ + { + .limits = { + .max_hdmi_phy_freq = 1650000, + }, + .attrs = (const struct soc_device_attribute []) { + { .soc_id = "GXL (S805*)", }, + { /* sentinel */ }, + } + }, +}; + static int meson_drv_bind_master(struct device *dev, bool has_components) { struct platform_device *pdev = to_platform_device(dev); @@ -191,7 +210,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) struct drm_device *drm; struct resource *res; void __iomem *regs; - int ret; + int ret, i; /* Checks if an output connector is available */ if (!meson_vpu_has_available_connectors(dev)) { @@ -281,6 +300,14 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) if (ret) goto free_drm; + /* Assign limits per soc revision/package */ + for (i = 0 ; i < ARRAY_SIZE(meson_drm_soc_attrs) ; ++i) { + if (soc_device_match(meson_drm_soc_attrs[i].attrs)) { + priv->limits = &meson_drm_soc_attrs[i].limits; + break; + } + } + /* Remove early framebuffers (ie. simplefb) */ meson_remove_framebuffers(); diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h index 04fdf3826643..5b23704a80d6 100644 --- a/drivers/gpu/drm/meson/meson_drv.h +++ b/drivers/gpu/drm/meson/meson_drv.h @@ -30,6 +30,10 @@ struct meson_drm_match_data { struct meson_afbcd_ops *afbcd_ops; }; +struct meson_drm_soc_limits { + unsigned int max_hdmi_phy_freq; +}; + struct meson_drm { struct device *dev; enum vpu_compatible compat; @@ -48,6 +52,8 @@ struct meson_drm { struct drm_plane *primary_plane; struct drm_plane *overlay_plane; + const struct meson_drm_soc_limits *limits; + /* Components Data */ struct { bool osd1_enabled; diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index e8c94915a4fc..5be963e9db05 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -695,7 +695,7 @@ dw_hdmi_mode_valid(struct drm_connector *connector, dev_dbg(connector->dev->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n", __func__, phy_freq, vclk_freq, venc_freq, hdmi_freq); - return meson_vclk_vic_supported_freq(phy_freq, vclk_freq); + return meson_vclk_vic_supported_freq(priv, phy_freq, vclk_freq); } /* Encoder */ diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c index fdf26dac9fa8..0eb86943a358 100644 --- a/drivers/gpu/drm/meson/meson_vclk.c +++ b/drivers/gpu/drm/meson/meson_vclk.c @@ -725,6 +725,13 @@ meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq) /* In DMT mode, path after PLL is always /10 */ freq *= 10; + /* Check against soc revision/package limits */ + if (priv->limits) { + if (priv->limits->max_hdmi_phy_freq && + freq > priv->limits->max_hdmi_phy_freq) + return MODE_CLOCK_HIGH; + } + if (meson_hdmi_pll_find_params(priv, freq, &m, &frac, &od)) return MODE_OK; @@ -762,7 +769,7 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv, } enum drm_mode_status -meson_vclk_vic_supported_freq(unsigned int phy_freq, +meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq, unsigned int vclk_freq) { int i; @@ -770,6 +777,13 @@ meson_vclk_vic_supported_freq(unsigned int phy_freq, DRM_DEBUG_DRIVER("phy_freq = %d vclk_freq = %d\n", phy_freq, vclk_freq); + /* Check against soc revision/package limits */ + if (priv->limits) { + if (priv->limits->max_hdmi_phy_freq && + phy_freq > priv->limits->max_hdmi_phy_freq) + return MODE_CLOCK_HIGH; + } + for (i = 0 ; params[i].pixel_freq ; ++i) { DRM_DEBUG_DRIVER("i = %d pixel_freq = %d alt = %d\n", i, params[i].pixel_freq, diff --git a/drivers/gpu/drm/meson/meson_vclk.h b/drivers/gpu/drm/meson/meson_vclk.h index aed0ab2efa71..60617aaf18dd 100644 --- a/drivers/gpu/drm/meson/meson_vclk.h +++ b/drivers/gpu/drm/meson/meson_vclk.h @@ -25,7 +25,8 @@ enum { enum drm_mode_status meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq); enum drm_mode_status -meson_vclk_vic_supported_freq(unsigned int phy_freq, unsigned int vclk_freq); +meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq, + unsigned int vclk_freq); void meson_vclk_setup(struct meson_drm *priv, unsigned int target, unsigned int phy_freq, unsigned int vclk_freq, From 9bcaa3fe58ab7559e71df798bcff6e0795158695 Mon Sep 17 00:00:00 2001 From: Michal Orzel Date: Tue, 28 Apr 2020 19:10:04 +0200 Subject: [PATCH 095/109] drm: Replace drm_modeset_lock/unlock_all with DRM_MODESET_LOCK_ALL_* helpers As suggested by the TODO list for the kernel DRM subsystem, replace the deprecated functions that take/drop modeset locks with new helpers. Signed-off-by: Michal Orzel Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/1588093804-30446-1-git-send-email-michalorzel.eng@gmail.com --- drivers/gpu/drm/drm_mode_object.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c index 35c2719407a8..901b078abf40 100644 --- a/drivers/gpu/drm/drm_mode_object.c +++ b/drivers/gpu/drm/drm_mode_object.c @@ -402,12 +402,13 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data, { struct drm_mode_obj_get_properties *arg = data; struct drm_mode_object *obj; + struct drm_modeset_acquire_ctx ctx; int ret = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EOPNOTSUPP; - drm_modeset_lock_all(dev); + DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type); if (!obj) { @@ -427,7 +428,7 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data, out_unref: drm_mode_object_put(obj); out: - drm_modeset_unlock_all(dev); + DRM_MODESET_LOCK_ALL_END(ctx, ret); return ret; } @@ -449,12 +450,13 @@ static int set_property_legacy(struct drm_mode_object *obj, { struct drm_device *dev = prop->dev; struct drm_mode_object *ref; + struct drm_modeset_acquire_ctx ctx; int ret = -EINVAL; if (!drm_property_change_valid_get(prop, prop_value, &ref)) return -EINVAL; - drm_modeset_lock_all(dev); + DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); switch (obj->type) { case DRM_MODE_OBJECT_CONNECTOR: ret = drm_connector_set_obj_prop(obj, prop, prop_value); @@ -468,7 +470,7 @@ static int set_property_legacy(struct drm_mode_object *obj, break; } drm_property_change_valid_put(prop, ref); - drm_modeset_unlock_all(dev); + DRM_MODESET_LOCK_ALL_END(ctx, ret); return ret; } From ca96088aa0de3400048093adb2fa13eb10569023 Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Thu, 30 Apr 2020 17:33:46 +0200 Subject: [PATCH 096/109] drm/client: Dual licence the header in GPL-2 and MIT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Source file was dual licenced but the header was omitted, fix that. Contributors for this file are: Daniel Vetter Matt Roper Maxime Ripard Noralf Trønnes Thomas Zimmermann Acked-by: Noralf Trønnes Acked-by: Matt Roper Acked-by: Daniel Vetter Acked-by: Maxime Ripard Acked-by: Thomas Zimmermann Signed-off-by: Emmanuel Vadot Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20200430153347.85323-1-manu@FreeBSD.org --- include/drm/drm_client.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index 7402f852d3c4..eb259c2547af 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0 or MIT */ #ifndef _DRM_CLIENT_H_ #define _DRM_CLIENT_H_ From b7301fd812a3b103df422826c830dc9a979b2908 Mon Sep 17 00:00:00 2001 From: Maya Rashish Date: Wed, 8 Apr 2020 22:14:42 +0000 Subject: [PATCH 097/109] drm/ttm: Remove reference to the mem_glob member MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was removed in: Author: Christian König Date: Wed Sep 25 11:38:50 2019 +0200 drm/ttm: remove pointers to globals Signed-off-by: Maya Rashish Reviewed-by: Christian König Link: https://patchwork.freedesktop.org/patch/360750/ Signed-off-by: Christian König --- include/drm/ttm/ttm_bo_driver.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index c9e0fd09f4b2..54a527aa79cc 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -390,7 +390,6 @@ struct ttm_bo_driver { /** * struct ttm_bo_global - Buffer object driver global data. * - * @mem_glob: Pointer to a struct ttm_mem_global object for accounting. * @dummy_read_page: Pointer to a dummy page used for mapping requests * of unpopulated pages. * @shrink: A shrink callback object used for buffer object swap. From 0cdea4455acd350a7f62406478e3d6d1f764cef9 Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Mon, 4 May 2020 17:40:35 +0200 Subject: [PATCH 098/109] drm/mm: optimize rb_hole_addr rbtree search MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Userspace can severely fragment rb_hole_addr rbtree by manipulating alignment while allocating buffers. Fragmented rb_hole_addr rbtree would result in large delays while allocating buffer object for a userspace application. It takes long time to find suitable hole because if we fail to find a suitable hole in the first attempt then we look for neighbouring nodes using rb_prev()/rb_next(). Traversing rbtree using rb_prev()/rb_next() can take really long time if the tree is fragmented. This patch improves searches in fragmented rb_hole_addr rbtree by modifying it to an augmented rbtree which will store an extra field in drm_mm_node, subtree_max_hole. Each drm_mm_node now stores maximum hole size for its subtree in drm_mm_node->subtree_max_hole. Using drm_mm_node->subtree_max_hole, it is possible to eliminate a complete subtree if that subtree is unable to serve a request hence reducing number of rb_prev()/rb_next() used. With this patch applied, 1 million bo allocs on amdgpu took ~8 sec, compared to 50k bo allocs which took 28 sec without it. partial test code: int test_fragmentation(void) { int i = 0; uint32_t minor_version; uint32_t major_version; struct amdgpu_bo_alloc_request request = {}; amdgpu_bo_handle vram_handle[MAX_ALLOC] = {}; amdgpu_device_handle device_handle; request.alloc_size = 4096; request.phys_alignment = 8192; request.preferred_heap = AMDGPU_GEM_DOMAIN_VRAM; int fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC); amdgpu_device_initialize(fd, &major_version, &minor_version, &device_handle); for (i = 0; i < MAX_ALLOC; i++) { amdgpu_bo_alloc(device_handle, &request, &vram_handle[i]); } for (i = 0; i < MAX_ALLOC; i++) amdgpu_bo_free(vram_handle[i]); return 0; } v2: Use RB_DECLARE_CALLBACKS_MAX to maintain subtree_max_hole v3: insert_hole_addr() should be static a function fix return value of next_hole_high_addr()/next_hole_low_addr() Reported-by: kbuild test robot v4: Fix commit message. Signed-off-by: Nirmoy Das Reviewed-by: Chris Wilson Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/364341/ Signed-off-by: Christian König --- drivers/gpu/drm/drm_mm.c | 133 +++++++++++++++++++++++++++++++++------ include/drm/drm_mm.h | 1 + 2 files changed, 115 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 8981abe8b7c9..f4ca1ff80af9 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -212,20 +212,6 @@ static void drm_mm_interval_tree_add_node(struct drm_mm_node *hole_node, &drm_mm_interval_tree_augment); } -#define RB_INSERT(root, member, expr) do { \ - struct rb_node **link = &root.rb_node, *rb = NULL; \ - u64 x = expr(node); \ - while (*link) { \ - rb = *link; \ - if (x < expr(rb_entry(rb, struct drm_mm_node, member))) \ - link = &rb->rb_left; \ - else \ - link = &rb->rb_right; \ - } \ - rb_link_node(&node->member, rb, link); \ - rb_insert_color(&node->member, &root); \ -} while (0) - #define HOLE_SIZE(NODE) ((NODE)->hole_size) #define HOLE_ADDR(NODE) (__drm_mm_hole_node_start(NODE)) @@ -255,16 +241,42 @@ static void insert_hole_size(struct rb_root_cached *root, rb_insert_color_cached(&node->rb_hole_size, root, first); } +RB_DECLARE_CALLBACKS_MAX(static, augment_callbacks, + struct drm_mm_node, rb_hole_addr, + u64, subtree_max_hole, HOLE_SIZE) + +static void insert_hole_addr(struct rb_root *root, struct drm_mm_node *node) +{ + struct rb_node **link = &root->rb_node, *rb_parent = NULL; + u64 start = HOLE_ADDR(node), subtree_max_hole = node->subtree_max_hole; + struct drm_mm_node *parent; + + while (*link) { + rb_parent = *link; + parent = rb_entry(rb_parent, struct drm_mm_node, rb_hole_addr); + if (parent->subtree_max_hole < subtree_max_hole) + parent->subtree_max_hole = subtree_max_hole; + if (start < HOLE_ADDR(parent)) + link = &parent->rb_hole_addr.rb_left; + else + link = &parent->rb_hole_addr.rb_right; + } + + rb_link_node(&node->rb_hole_addr, rb_parent, link); + rb_insert_augmented(&node->rb_hole_addr, root, &augment_callbacks); +} + static void add_hole(struct drm_mm_node *node) { struct drm_mm *mm = node->mm; node->hole_size = __drm_mm_hole_node_end(node) - __drm_mm_hole_node_start(node); + node->subtree_max_hole = node->hole_size; DRM_MM_BUG_ON(!drm_mm_hole_follows(node)); insert_hole_size(&mm->holes_size, node); - RB_INSERT(mm->holes_addr, rb_hole_addr, HOLE_ADDR); + insert_hole_addr(&mm->holes_addr, node); list_add(&node->hole_stack, &mm->hole_stack); } @@ -275,8 +287,10 @@ static void rm_hole(struct drm_mm_node *node) list_del(&node->hole_stack); rb_erase_cached(&node->rb_hole_size, &node->mm->holes_size); - rb_erase(&node->rb_hole_addr, &node->mm->holes_addr); + rb_erase_augmented(&node->rb_hole_addr, &node->mm->holes_addr, + &augment_callbacks); node->hole_size = 0; + node->subtree_max_hole = 0; DRM_MM_BUG_ON(drm_mm_hole_follows(node)); } @@ -361,9 +375,90 @@ first_hole(struct drm_mm *mm, } } +/** + * next_hole_high_addr - returns next hole for a DRM_MM_INSERT_HIGH mode request + * @entry: previously selected drm_mm_node + * @size: size of the a hole needed for the request + * + * This function will verify whether left subtree of @entry has hole big enough + * to fit the requtested size. If so, it will return previous node of @entry or + * else it will return parent node of @entry + * + * It will also skip the complete left subtree if subtree_max_hole of that + * subtree is same as the subtree_max_hole of the @entry. + * + * Returns: + * previous node of @entry if left subtree of @entry can serve the request or + * else return parent of @entry + */ +static struct drm_mm_node * +next_hole_high_addr(struct drm_mm_node *entry, u64 size) +{ + struct rb_node *rb_node, *left_rb_node, *parent_rb_node; + struct drm_mm_node *left_node; + + if (!entry) + return NULL; + + rb_node = &entry->rb_hole_addr; + if (rb_node->rb_left) { + left_rb_node = rb_node->rb_left; + parent_rb_node = rb_parent(rb_node); + left_node = rb_entry(left_rb_node, + struct drm_mm_node, rb_hole_addr); + if ((left_node->subtree_max_hole < size || + entry->size == entry->subtree_max_hole) && + parent_rb_node && parent_rb_node->rb_left != rb_node) + return rb_hole_addr_to_node(parent_rb_node); + } + + return rb_hole_addr_to_node(rb_prev(rb_node)); +} + +/** + * next_hole_low_addr - returns next hole for a DRM_MM_INSERT_LOW mode request + * @entry: previously selected drm_mm_node + * @size: size of the a hole needed for the request + * + * This function will verify whether right subtree of @entry has hole big enough + * to fit the requtested size. If so, it will return next node of @entry or + * else it will return parent node of @entry + * + * It will also skip the complete right subtree if subtree_max_hole of that + * subtree is same as the subtree_max_hole of the @entry. + * + * Returns: + * next node of @entry if right subtree of @entry can serve the request or + * else return parent of @entry + */ +static struct drm_mm_node * +next_hole_low_addr(struct drm_mm_node *entry, u64 size) +{ + struct rb_node *rb_node, *right_rb_node, *parent_rb_node; + struct drm_mm_node *right_node; + + if (!entry) + return NULL; + + rb_node = &entry->rb_hole_addr; + if (rb_node->rb_right) { + right_rb_node = rb_node->rb_right; + parent_rb_node = rb_parent(rb_node); + right_node = rb_entry(right_rb_node, + struct drm_mm_node, rb_hole_addr); + if ((right_node->subtree_max_hole < size || + entry->size == entry->subtree_max_hole) && + parent_rb_node && parent_rb_node->rb_right != rb_node) + return rb_hole_addr_to_node(parent_rb_node); + } + + return rb_hole_addr_to_node(rb_next(rb_node)); +} + static struct drm_mm_node * next_hole(struct drm_mm *mm, struct drm_mm_node *node, + u64 size, enum drm_mm_insert_mode mode) { switch (mode) { @@ -372,10 +467,10 @@ next_hole(struct drm_mm *mm, return rb_hole_size_to_node(rb_prev(&node->rb_hole_size)); case DRM_MM_INSERT_LOW: - return rb_hole_addr_to_node(rb_next(&node->rb_hole_addr)); + return next_hole_low_addr(node, size); case DRM_MM_INSERT_HIGH: - return rb_hole_addr_to_node(rb_prev(&node->rb_hole_addr)); + return next_hole_high_addr(node, size); case DRM_MM_INSERT_EVICT: node = list_next_entry(node, hole_stack); @@ -489,7 +584,7 @@ int drm_mm_insert_node_in_range(struct drm_mm * const mm, remainder_mask = is_power_of_2(alignment) ? alignment - 1 : 0; for (hole = first_hole(mm, range_start, range_end, size, mode); hole; - hole = once ? NULL : next_hole(mm, hole, mode)) { + hole = once ? NULL : next_hole(mm, hole, size, mode)) { u64 hole_start = __drm_mm_hole_node_start(hole); u64 hole_end = hole_start + hole->hole_size; u64 adj_start, adj_end; diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index ee8b0e80ca90..a01bc6fac83c 100644 --- a/include/drm/drm_mm.h +++ b/include/drm/drm_mm.h @@ -168,6 +168,7 @@ struct drm_mm_node { struct rb_node rb_hole_addr; u64 __subtree_last; u64 hole_size; + u64 subtree_max_hole; unsigned long flags; #define DRM_MM_NODE_ALLOCATED_BIT 0 #define DRM_MM_NODE_SCANNED_BIT 1 From 13e9bd05b3d549ecd5d6103ebc74671889aff314 Mon Sep 17 00:00:00 2001 From: Jason Yan Date: Wed, 22 Apr 2020 15:18:26 +0800 Subject: [PATCH 099/109] video: fbdev: i810: use true,false for bool variables Fix the following coccicheck warning: drivers/video/fbdev/i810/i810_main.c:1969:3-7: WARNING: Assignment of 0/1 to bool variable drivers/video/fbdev/i810/i810_main.c:1971:3-8: WARNING: Assignment of 0/1 to bool variable drivers/video/fbdev/i810/i810_main.c:1973:3-9: WARNING: Assignment of 0/1 to bool variable drivers/video/fbdev/i810/i810_main.c:1975:3-7: WARNING: Assignment of 0/1 to bool variable drivers/video/fbdev/i810/i810_main.c:2001:3-9: WARNING: Assignment of 0/1 to bool variable Signed-off-by: Jason Yan Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200422071826.49038-1-yanaijie@huawei.com --- drivers/video/fbdev/i810/i810_main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/video/fbdev/i810/i810_main.c b/drivers/video/fbdev/i810/i810_main.c index aa7583d963ac..13bbf7fe13bf 100644 --- a/drivers/video/fbdev/i810/i810_main.c +++ b/drivers/video/fbdev/i810/i810_main.c @@ -1966,13 +1966,13 @@ static int i810fb_setup(char *options) while ((this_opt = strsep(&options, ",")) != NULL) { if (!strncmp(this_opt, "mtrr", 4)) - mtrr = 1; + mtrr = true; else if (!strncmp(this_opt, "accel", 5)) - accel = 1; + accel = true; else if (!strncmp(this_opt, "extvga", 6)) - extvga = 1; + extvga = true; else if (!strncmp(this_opt, "sync", 4)) - sync = 1; + sync = true; else if (!strncmp(this_opt, "vram:", 5)) vram = (simple_strtoul(this_opt+5, NULL, 0)); else if (!strncmp(this_opt, "voffset:", 8)) @@ -1998,7 +1998,7 @@ static int i810fb_setup(char *options) else if (!strncmp(this_opt, "vsync2:", 7)) vsync2 = simple_strtoul(this_opt+7, NULL, 0); else if (!strncmp(this_opt, "dcolor", 6)) - dcolor = 1; + dcolor = true; else if (!strncmp(this_opt, "ddc3", 4)) ddc3 = true; else From 7022537b58d82d3db30bc99664d8de5f45ec29aa Mon Sep 17 00:00:00 2001 From: Jason Yan Date: Wed, 22 Apr 2020 15:18:36 +0800 Subject: [PATCH 100/109] video: udlfb: use true,false for bool variables Fix the following coccicheck warning: drivers/video/fbdev/udlfb.c:67:12-19: WARNING: Assignment of 0/1 to bool variable drivers/video/fbdev/udlfb.c:68:12-20: WARNING: Assignment of 0/1 to bool variable drivers/video/fbdev/udlfb.c:69:12-18: WARNING: Assignment of 0/1 to bool variable Signed-off-by: Jason Yan Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200422071836.49123-1-yanaijie@huawei.com --- drivers/video/fbdev/udlfb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c index 07905d385949..5b014b479f83 100644 --- a/drivers/video/fbdev/udlfb.c +++ b/drivers/video/fbdev/udlfb.c @@ -64,9 +64,9 @@ static const struct usb_device_id id_table[] = { MODULE_DEVICE_TABLE(usb, id_table); /* module options */ -static bool console = 1; /* Allow fbcon to open framebuffer */ -static bool fb_defio = 1; /* Detect mmap writes using page faults */ -static bool shadow = 1; /* Optionally disable shadow framebuffer */ +static bool console = true; /* Allow fbcon to open framebuffer */ +static bool fb_defio = true; /* Detect mmap writes using page faults */ +static bool shadow = true; /* Optionally disable shadow framebuffer */ static int pixel_limit; /* Optionally force a pixel resolution limit */ struct dlfb_deferred_free { From dbc7ece12a38889ceb3d7f99dad269822f6bd34e Mon Sep 17 00:00:00 2001 From: Jason Yan Date: Wed, 22 Apr 2020 15:18:45 +0800 Subject: [PATCH 101/109] video: uvesafb: use true,false for bool variables Fix the following coccicheck warning: drivers/video/fbdev/uvesafb.c:48:12-17: WARNING: Assignment of 0/1 to bool variable drivers/video/fbdev/uvesafb.c:1827:3-13: WARNING: Assignment of 0/1 to bool variable drivers/video/fbdev/uvesafb.c:1829:3-13: WARNING: Assignment of 0/1 to bool variable drivers/video/fbdev/uvesafb.c:1835:3-9: WARNING: Assignment of 0/1 to bool variable drivers/video/fbdev/uvesafb.c:1837:3-9: WARNING: Assignment of 0/1 to bool variable drivers/video/fbdev/uvesafb.c:1839:3-8: WARNING: Assignment of 0/1 to bool variable Signed-off-by: Jason Yan Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200422071845.403-1-yanaijie@huawei.com --- drivers/video/fbdev/uvesafb.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c index 1b385cf76110..bee29aadc646 100644 --- a/drivers/video/fbdev/uvesafb.c +++ b/drivers/video/fbdev/uvesafb.c @@ -45,7 +45,7 @@ static const struct fb_fix_screeninfo uvesafb_fix = { }; static int mtrr = 3; /* enable mtrr by default */ -static bool blank = 1; /* enable blanking by default */ +static bool blank = true; /* enable blanking by default */ static int ypan = 1; /* 0: scroll, 1: ypan, 2: ywrap */ static bool pmi_setpal = true; /* use PMI for palette changes */ static bool nocrtc; /* ignore CRTC settings */ @@ -1824,19 +1824,19 @@ static int uvesafb_setup(char *options) else if (!strcmp(this_opt, "ywrap")) ypan = 2; else if (!strcmp(this_opt, "vgapal")) - pmi_setpal = 0; + pmi_setpal = false; else if (!strcmp(this_opt, "pmipal")) - pmi_setpal = 1; + pmi_setpal = true; else if (!strncmp(this_opt, "mtrr:", 5)) mtrr = simple_strtoul(this_opt+5, NULL, 0); else if (!strcmp(this_opt, "nomtrr")) mtrr = 0; else if (!strcmp(this_opt, "nocrtc")) - nocrtc = 1; + nocrtc = true; else if (!strcmp(this_opt, "noedid")) - noedid = 1; + noedid = true; else if (!strcmp(this_opt, "noblank")) - blank = 0; + blank = true; else if (!strncmp(this_opt, "vtotal:", 7)) vram_total = simple_strtoul(this_opt + 7, NULL, 0); else if (!strncmp(this_opt, "vremap:", 7)) From d163a95cf00130d8d980cbf16675337caeb9cdad Mon Sep 17 00:00:00 2001 From: Jason Yan Date: Wed, 22 Apr 2020 15:18:54 +0800 Subject: [PATCH 102/109] fbdev: aty: use true, false for bool variables in atyfb_base.c Fix the following coccicheck warning: drivers/video/fbdev/aty/atyfb_base.c:3822:3-10: WARNING: Assignment of 0/1 to bool variable drivers/video/fbdev/aty/atyfb_base.c:3824:3-9: WARNING: Assignment of 0/1 to bool variable Signed-off-by: Jason Yan Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200422071854.513-1-yanaijie@huawei.com --- drivers/video/fbdev/aty/atyfb_base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c index 49d192869cf5..b0ac895e5ac9 100644 --- a/drivers/video/fbdev/aty/atyfb_base.c +++ b/drivers/video/fbdev/aty/atyfb_base.c @@ -3819,9 +3819,9 @@ static int __init atyfb_setup(char *options) while ((this_opt = strsep(&options, ",")) != NULL) { if (!strncmp(this_opt, "noaccel", 7)) { - noaccel = 1; + noaccel = true; } else if (!strncmp(this_opt, "nomtrr", 6)) { - nomtrr = 1; + nomtrr = true; } else if (!strncmp(this_opt, "vram:", 5)) vram = simple_strtoul(this_opt + 5, NULL, 0); else if (!strncmp(this_opt, "pll:", 4)) From 18722d48a6bb9c2e8d046214c0a5fd19d0a7c9f6 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Wed, 6 May 2020 20:19:02 +0200 Subject: [PATCH 103/109] video: fbdev: w100fb: Fix a potential double free. Some memory is vmalloc'ed in the 'w100fb_save_vidmem' function and freed in the 'w100fb_restore_vidmem' function. (these functions are called respectively from the 'suspend' and the 'resume' functions) However, it is also freed in the 'remove' function. In order to avoid a potential double free, set the corresponding pointer to NULL once freed in the 'w100fb_restore_vidmem' function. Fixes: aac51f09d96a ("[PATCH] w100fb: Rewrite for platform independence") Cc: Richard Purdie Cc: Antonino Daplas Cc: Bartlomiej Zolnierkiewicz Cc: # v2.6.14+ Signed-off-by: Christophe JAILLET Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200506181902.193290-1-christophe.jaillet@wanadoo.fr --- drivers/video/fbdev/w100fb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/video/fbdev/w100fb.c b/drivers/video/fbdev/w100fb.c index 2d6e2738b792..d96ab28f8ce4 100644 --- a/drivers/video/fbdev/w100fb.c +++ b/drivers/video/fbdev/w100fb.c @@ -588,6 +588,7 @@ static void w100fb_restore_vidmem(struct w100fb_par *par) memsize=par->mach->mem->size; memcpy_toio(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), par->saved_extmem, memsize); vfree(par->saved_extmem); + par->saved_extmem = NULL; } if (par->saved_intmem) { memsize=MEM_INT_SIZE; @@ -596,6 +597,7 @@ static void w100fb_restore_vidmem(struct w100fb_par *par) else memcpy_toio(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), par->saved_intmem, memsize); vfree(par->saved_intmem); + par->saved_intmem = NULL; } } From 10a14c3224a45b951f529925b757392aa2d2dcc9 Mon Sep 17 00:00:00 2001 From: Harigovindan P Date: Wed, 29 Apr 2020 11:15:15 +0530 Subject: [PATCH 104/109] dt-bindings: documenting compatible string vendor "visionox" Documenting compatible string vendor "visionox" in vendor-prefix yaml file. Signed-off-by: Harigovindan P Acked-by: Rob Herring Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200429054515.4976-2-harigovi@codeaurora.org --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 05a98c26828d..7a39732c582d 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -1043,6 +1043,8 @@ patternProperties: description: Tronsmart "^truly,.*": description: Truly Semiconductors Limited + "^visionox,.*": + description: Visionox "^tsd,.*": description: Theobroma Systems Design und Consulting GmbH "^tyan,.*": From c7f66d32dd431cc30139324a7e0956f641dc6ff0 Mon Sep 17 00:00:00 2001 From: Harigovindan P Date: Wed, 29 Apr 2020 11:15:14 +0530 Subject: [PATCH 105/109] drm/panel: add support for rm69299 visionox panel Add support for Visionox rm69299 panel. Signed-off-by: Harigovindan P Reviewed-by: Matthias Kaehlcke Signed-off-by: Sam Ravnborg [fix checkpatch warnings, added sentinel ] Link: https://patchwork.freedesktop.org/patch/msgid/20200421045508.21137-2-harigovi@codeaurora.org --- drivers/gpu/drm/panel/Kconfig | 8 + drivers/gpu/drm/panel/Makefile | 1 + .../gpu/drm/panel/panel-visionox-rm69299.c | 302 ++++++++++++++++++ 3 files changed, 311 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-visionox-rm69299.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index d56258b9fcaf..4b6131f5893d 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -444,6 +444,14 @@ config DRM_PANEL_TRULY_NT35597_WQXGA Say Y here if you want to enable support for Truly NT35597 WQXGA Dual DSI Video Mode panel +config DRM_PANEL_VISIONOX_RM69299 + tristate "Visionox RM69299" + depends on OF + depends on DRM_MIPI_DSI + help + Say Y here if you want to enable support for Visionox + RM69299 DSI Video Mode panel. + config DRM_PANEL_XINPENG_XPP055C272 tristate "Xinpeng XPP055C272 panel driver" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 2335a1e32ae0..8eac3e6fa82c 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -47,4 +47,5 @@ obj-$(CONFIG_DRM_PANEL_TPO_TD028TTEC1) += panel-tpo-td028ttec1.o obj-$(CONFIG_DRM_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o obj-$(CONFIG_DRM_PANEL_TPO_TPG110) += panel-tpo-tpg110.o obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o +obj-$(CONFIG_DRM_PANEL_VISIONOX_RM69299) += panel-visionox-rm69299.o obj-$(CONFIG_DRM_PANEL_XINPENG_XPP055C272) += panel-xinpeng-xpp055c272.o diff --git a/drivers/gpu/drm/panel/panel-visionox-rm69299.c b/drivers/gpu/drm/panel/panel-visionox-rm69299.c new file mode 100644 index 000000000000..25fe8b0bb040 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-visionox-rm69299.c @@ -0,0 +1,302 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include + +#include