From fbf0a7f44cdd4041b5a3e2b14deaa0adebaf40da Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Mon, 5 Aug 2019 12:54:01 +0200 Subject: [PATCH 01/18] drm/qxl: get vga ioports qxl has two modes: "native" (used by the drm driver) and "vga" (vga compatibility mode, typically used for boot display and firmware framebuffers). Accessing any vga ioport will switch the qxl device into vga mode. The qxl driver never does that, but other drivers accessing vga ports can trigger that too and therefore disturb qxl operation. So aquire the legacy vga ioports from vgaarb to avoid that. Reproducer: Boot kvm guest with both qxl and i915 vgpu, with qxl being first in pci scan order. v2: Skip this for secondary qxl cards which don't have vga mode in the first place (Frediano). Cc: Frediano Ziglio Signed-off-by: Gerd Hoffmann Reviewed-by: Dave Airlie Link: http://patchwork.freedesktop.org/patch/msgid/20190805105401.29874-1-kraxel@redhat.com --- drivers/gpu/drm/qxl/qxl_drv.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index f33e349c4ec5..952201c6d821 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -59,6 +59,11 @@ module_param_named(num_heads, qxl_num_crtc, int, 0400); static struct drm_driver qxl_driver; static struct pci_driver qxl_pci_driver; +static bool is_vga(struct pci_dev *pdev) +{ + return pdev->class == PCI_CLASS_DISPLAY_VGA << 8; +} + static int qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -83,9 +88,17 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) goto disable_pci; + if (is_vga(pdev)) { + ret = vga_get_interruptible(pdev, VGA_RSRC_LEGACY_IO); + if (ret) { + DRM_ERROR("can't get legacy vga ioports\n"); + goto disable_pci; + } + } + ret = qxl_device_init(qdev, &qxl_driver, pdev); if (ret) - goto disable_pci; + goto put_vga; ret = qxl_modeset_init(qdev); if (ret) @@ -105,6 +118,9 @@ modeset_cleanup: qxl_modeset_fini(qdev); unload: qxl_device_fini(qdev); +put_vga: + if (is_vga(pdev)) + vga_put(pdev, VGA_RSRC_LEGACY_IO); disable_pci: pci_disable_device(pdev); free_dev: @@ -122,6 +138,8 @@ qxl_pci_remove(struct pci_dev *pdev) qxl_modeset_fini(qdev); qxl_device_fini(qdev); + if (is_vga(pdev)) + vga_put(pdev, VGA_RSRC_LEGACY_IO); dev->dev_private = NULL; kfree(qdev); From 8090f7eb318d4241625449252db2741e7703e027 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 21 Aug 2019 21:32:26 +0300 Subject: [PATCH 02/18] drm/omap: Fix port lookup for SDI output When refactoring port lookup for DSS outputs, commit d17eb4537a7e ("drm/omap: Factor out common init/cleanup code for output devices") incorrectly hardcoded usage of DT port 0. This breaks operation for SDI (which uses the DT port 1) and DPI outputs other than DPI0 (which are not used in mainline DT sources). Fix this by using the port number from the output omap_dss_device of_ports field. Fixes: d17eb4537a7e ("drm/omap: Factor out common init/cleanup code for output devices") Signed-off-by: Laurent Pinchart Signed-off-by: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20190821183226.13784-1-laurent.pinchart@ideasonboard.com Tested-by: Aaro Koskinen --- drivers/gpu/drm/omapdrm/dss/output.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/omapdrm/dss/output.c b/drivers/gpu/drm/omapdrm/dss/output.c index de0f882f0f7b..14b41de44ebc 100644 --- a/drivers/gpu/drm/omapdrm/dss/output.c +++ b/drivers/gpu/drm/omapdrm/dss/output.c @@ -4,6 +4,7 @@ * Author: Archit Taneja */ +#include #include #include #include @@ -20,7 +21,8 @@ int omapdss_device_init_output(struct omap_dss_device *out) { struct device_node *remote_node; - remote_node = of_graph_get_remote_node(out->dev->of_node, 0, 0); + remote_node = of_graph_get_remote_node(out->dev->of_node, + ffs(out->of_ports) - 1, 0); if (!remote_node) { dev_dbg(out->dev, "failed to find video sink\n"); return 0; From 9b2a0a1ef66f96bf34921a3865581eca32ff05ec Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 21 Aug 2019 13:12:09 +0200 Subject: [PATCH 03/18] drm/virtio: use virtio_max_dma_size We must make sure our scatterlist segments are not too big, otherwise we might see swiotlb failures (happens with sev, also reproducable with swiotlb=force). Suggested-by: Laszlo Ersek Signed-off-by: Gerd Hoffmann Reviewed-by: Laszlo Ersek Link: http://patchwork.freedesktop.org/patch/msgid/20190821111210.27165-1-kraxel@redhat.com --- drivers/gpu/drm/virtio/virtgpu_object.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index b2da31310d24..09b526518f5a 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -204,6 +204,7 @@ int virtio_gpu_object_get_sg_table(struct virtio_gpu_device *qdev, .interruptible = false, .no_wait_gpu = false }; + size_t max_segment; /* wtf swapping */ if (bo->pages) @@ -215,8 +216,13 @@ int virtio_gpu_object_get_sg_table(struct virtio_gpu_device *qdev, if (!bo->pages) goto out; - ret = sg_alloc_table_from_pages(bo->pages, pages, nr_pages, 0, - nr_pages << PAGE_SHIFT, GFP_KERNEL); + max_segment = virtio_max_dma_size(qdev->vdev); + max_segment &= PAGE_MASK; + if (max_segment > SCATTERLIST_MAX_SEGMENT) + max_segment = SCATTERLIST_MAX_SEGMENT; + ret = __sg_alloc_table_from_pages(bo->pages, pages, nr_pages, 0, + nr_pages << PAGE_SHIFT, + max_segment, GFP_KERNEL); if (ret) goto out; return 0; From 8f6a79112a360ff05b8aa4a9be081d3eb9057077 Mon Sep 17 00:00:00 2001 From: "james qian wang (Arm Technology China)" Date: Mon, 19 Aug 2019 08:01:57 +0000 Subject: [PATCH 04/18] drm/komeda: Fix error: not allocating enough data 1592 vs 1584 The patch 5d51f6c0da1b: "drm/komeda: Add writeback support" from May 23, 2019, leads to the following static checker warning: drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c:151 komeda_wb_connector_add() error: not allocating enough data 1592 vs 1584 This is a typo which misuse "wb_conn" but which should be "kwb_conn" to allocate the memory. Reported-by: Dan Carpenter Signed-off-by: james qian wang (Arm Technology China) Reviewed-by: Ayan Kumar Halder Link: https://patchwork.freedesktop.org/patch/msgid/20190819080136.10190-1-james.qian.wang@arm.com --- drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c index 617e1f7b8472..2851cac94d86 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c @@ -148,7 +148,7 @@ static int komeda_wb_connector_add(struct komeda_kms_dev *kms, if (!kcrtc->master->wb_layer) return 0; - kwb_conn = kzalloc(sizeof(*wb_conn), GFP_KERNEL); + kwb_conn = kzalloc(sizeof(*kwb_conn), GFP_KERNEL); if (!kwb_conn) return -ENOMEM; From 61d05b184963523e50729af8466b72e9c8a4f8be Mon Sep 17 00:00:00 2001 From: "james qian wang (Arm Technology China)" Date: Mon, 12 Aug 2019 11:23:41 +0000 Subject: [PATCH 05/18] drm/komeda: Fix warning -Wunused-but-set-variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed two -Wunused-but-set-variable warnings: /arm/linux/display/aosp-4.14-drm-next/drivers/gpu/drm/arm/display/komeda/komeda_kms.c: In function ‘komeda_crtc_normalize_zpos’: /arm/linux/display/aosp-4.14-drm-next/drivers/gpu/drm/arm/display/komeda/komeda_kms.c:150:26: warning: variable ‘fb’ set but not used [-Wunused-but-set-variable] struct drm_framebuffer *fb; ^~ /arm/linux/display/aosp-4.14-drm-next/drivers/gpu/drm/arm/display/komeda/komeda_kms.c: In function ‘komeda_kms_check’: /arm/linux/display/aosp-4.14-drm-next/drivers/gpu/drm/arm/display/komeda/komeda_kms.c:209:25: warning: variable ‘old_crtc_st’ set but not used [-Wunused-but-set-variable] struct drm_crtc_state *old_crtc_st, *new_crtc_st; ^~~~~~~~~~~ Signed-off-by: james qian wang (Arm Technology China) Reviewed-by: Ayan Kumar Halder Link: https://patchwork.freedesktop.org/patch/msgid/20190812112322.15990-1-james.qian.wang@arm.com --- drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c index d50e75f0b2bd..1f0e3f4e8d74 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c @@ -147,7 +147,6 @@ static int komeda_crtc_normalize_zpos(struct drm_crtc *crtc, struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(crtc_st); struct komeda_plane_state *kplane_st; struct drm_plane_state *plane_st; - struct drm_framebuffer *fb; struct drm_plane *plane; struct list_head zorder_list; int order = 0, err; @@ -173,7 +172,6 @@ static int komeda_crtc_normalize_zpos(struct drm_crtc *crtc, list_for_each_entry(kplane_st, &zorder_list, zlist_node) { plane_st = &kplane_st->base; - fb = plane_st->fb; plane = plane_st->plane; plane_st->normalized_zpos = order++; @@ -206,7 +204,7 @@ static int komeda_kms_check(struct drm_device *dev, struct drm_atomic_state *state) { struct drm_crtc *crtc; - struct drm_crtc_state *old_crtc_st, *new_crtc_st; + struct drm_crtc_state *new_crtc_st; int i, err; err = drm_atomic_helper_check_modeset(dev, state); @@ -217,7 +215,7 @@ static int komeda_kms_check(struct drm_device *dev, * so need to add all affected_planes (even unchanged) to * drm_atomic_state. */ - for_each_oldnew_crtc_in_state(state, crtc, old_crtc_st, new_crtc_st, i) { + for_each_new_crtc_in_state(state, crtc, new_crtc_st, i) { err = drm_atomic_add_affected_planes(state, crtc); if (err) return err; From 95abcd33ad513faf9cf3f54a28fb4982407e5a92 Mon Sep 17 00:00:00 2001 From: "james qian wang (Arm Technology China)" Date: Tue, 13 Aug 2019 11:08:20 +0000 Subject: [PATCH 06/18] drm/komeda: Clean warning 'komeda_component_add' might be a candidate for 'gnu_printf' komeda/komeda_pipeline.c: In function 'komeda_component_add': komeda/komeda_pipeline.c:212:3: warning: function 'komeda_component_add' might be a candidate for 'gnu_printf' format attribute [-Wsuggest-attribute=format] vsnprintf(c->name, sizeof(c->name), name_fmt, args); ^~~~~~~~~ Signed-off-by: james qian wang (Arm Technology China) Reviewed-by: Ayan Kumar Halder Link: https://patchwork.freedesktop.org/patch/msgid/20190813110759.10425-1-james.qian.wang@arm.com --- drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h index a90bcbb3cb23..14b683164544 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h @@ -480,6 +480,7 @@ void komeda_pipeline_dump_register(struct komeda_pipeline *pipe, struct seq_file *sf); /* component APIs */ +extern __printf(10, 11) struct komeda_component * komeda_component_add(struct komeda_pipeline *pipe, size_t comp_sz, u32 id, u32 hw_id, From 51a44a28eefd0d4c1addeb23fc5a599ff1787dfd Mon Sep 17 00:00:00 2001 From: Mihail Atanassov Date: Tue, 20 Aug 2019 15:16:58 +0000 Subject: [PATCH 07/18] drm/komeda: Add missing of_node_get() call komeda_pipeline_destroy has the matching of_node_put(). Fixes: 29e56aec911dd ("drm/komeda: Add DT parsing") Signed-off-by: Mihail Atanassov Reviewed-by: Ayan Kumar Halder [Rebased on the latest drm-misc-fixes] Signed-off-by: Ayan Kumar Halder Link: https://patchwork.freedesktop.org/patch/325278/ Change-Id: I5fa2479d6cb3a77182f1a92833c1c0bca8668cb4 --- drivers/gpu/drm/arm/display/komeda/komeda_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c index a0eabc134dd6..9d4d5075cc64 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c @@ -127,7 +127,7 @@ static int komeda_parse_pipe_dt(struct komeda_dev *mdev, struct device_node *np) pipe->of_output_port = of_graph_get_port_by_id(np, KOMEDA_OF_PORT_OUTPUT); - pipe->of_node = np; + pipe->of_node = of_node_get(np); return 0; } From 42068e1ef961c719f967dbbb4ddcb394a0ba7917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 16 Aug 2019 14:56:35 +0200 Subject: [PATCH 08/18] drm/amdgpu: fix dma_fence_wait without reference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to grab a reference to the fence we wait for. Signed-off-by: Christian König Reviewed-by: Chunming Zhou Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 27 ++++++++++++++----------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index f539a2a92774..7398b4850649 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -534,21 +534,24 @@ int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx, struct drm_sched_entity *entity) { struct amdgpu_ctx_entity *centity = to_amdgpu_ctx_entity(entity); - unsigned idx = centity->sequence & (amdgpu_sched_jobs - 1); - struct dma_fence *other = centity->fences[idx]; + struct dma_fence *other; + unsigned idx; + long r; - if (other) { - signed long r; - r = dma_fence_wait(other, true); - if (r < 0) { - if (r != -ERESTARTSYS) - DRM_ERROR("Error (%ld) waiting for fence!\n", r); + spin_lock(&ctx->ring_lock); + idx = centity->sequence & (amdgpu_sched_jobs - 1); + other = dma_fence_get(centity->fences[idx]); + spin_unlock(&ctx->ring_lock); - return r; - } - } + if (!other) + return 0; - return 0; + r = dma_fence_wait(other, true); + if (r < 0 && r != -ERESTARTSYS) + DRM_ERROR("Error (%ld) waiting for fence!\n", r); + + dma_fence_put(other); + return r; } void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr) From 21649c0b6b7899f4fa3099c46d3d027f60b107ec Mon Sep 17 00:00:00 2001 From: Kent Russell Date: Thu, 22 Aug 2019 08:17:40 -0400 Subject: [PATCH 09/18] drm/powerplay: Fix Vega20 Average Power value v4 The SMU changed reading from CurrSocketPower to AverageSocketPower, so reflect this accordingly. This fixes the issue where Average Power Consumption was being reported as 0 from SMU 40.46-onward v2: Fixed headline prefix v3: Add check for SMU version for proper compatibility v4: Style fix Signed-off-by: Kent Russell Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c | 5 ++++- drivers/gpu/drm/amd/powerplay/vega20_ppt.c | 10 +++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c index f27c6fbb192e..e9de1c0a3b87 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c @@ -2101,7 +2101,10 @@ static int vega20_get_gpu_power(struct pp_hwmgr *hwmgr, if (ret) return ret; - *query = metrics_table.CurrSocketPower << 8; + if (hwmgr->smu_version < 0x282e00) + *query = metrics_table.CurrSocketPower << 8; + else + *query = metrics_table.AverageSocketPower << 8; return ret; } diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c index dd6fd1c8bf24..29b64ee53c29 100644 --- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c @@ -3050,6 +3050,7 @@ static int vega20_get_fan_speed_percent(struct smu_context *smu, static int vega20_get_gpu_power(struct smu_context *smu, uint32_t *value) { + uint32_t smu_version; int ret = 0; SmuMetrics_t metrics; @@ -3060,7 +3061,14 @@ static int vega20_get_gpu_power(struct smu_context *smu, uint32_t *value) if (ret) return ret; - *value = metrics.CurrSocketPower << 8; + ret = smu_get_smc_version(smu, NULL, &smu_version); + if (ret) + return ret; + + if (smu_version < 0x282e00) + *value = metrics.CurrSocketPower << 8; + else + *value = metrics.AverageSocketPower << 8; return 0; } From 23b7f6c41d4717b1638eca47e09d7e99fc7b9fd9 Mon Sep 17 00:00:00 2001 From: Kent Russell Date: Fri, 23 Aug 2019 09:13:18 -0400 Subject: [PATCH 10/18] drm/powerplay: Fix Vega20 power reading again For the 40.46 SMU release, they changed CurrSocketPower to AverageSocketPower, but this was changed back in 40.47 so just check if it's 40.46 and make the appropriate change Tested with 40.45, 40.46 and 40.47 successfully Signed-off-by: Kent Russell Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c | 7 ++++--- drivers/gpu/drm/amd/powerplay/vega20_ppt.c | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c index e9de1c0a3b87..81658dc8fafc 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c @@ -2101,10 +2101,11 @@ static int vega20_get_gpu_power(struct pp_hwmgr *hwmgr, if (ret) return ret; - if (hwmgr->smu_version < 0x282e00) - *query = metrics_table.CurrSocketPower << 8; - else + /* For the 40.46 release, they changed the value name */ + if (hwmgr->smu_version == 0x282e00) *query = metrics_table.AverageSocketPower << 8; + else + *query = metrics_table.CurrSocketPower << 8; return ret; } diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c index 29b64ee53c29..6a14497257e4 100644 --- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c @@ -3065,10 +3065,11 @@ static int vega20_get_gpu_power(struct smu_context *smu, uint32_t *value) if (ret) return ret; - if (smu_version < 0x282e00) - *value = metrics.CurrSocketPower << 8; - else + /* For the 40.46 release, they changed the value name */ + if (smu_version == 0x282e00) *value = metrics.AverageSocketPower << 8; + else + *value = metrics.CurrSocketPower << 8; return 0; } From ed5fa90660d63bcec4c3a62b03fed9427418b53d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 20 Aug 2019 19:16:57 +0300 Subject: [PATCH 11/18] drm/i915: Do not create a new max_bpc prop for MST connectors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We're not allowed to create new properties after device registration so for MST connectors we need to either create the max_bpc property earlier, or we reuse one we already have. Let's do the latter apporach since the corresponding SST connector already has the prop and its min/max are correct also for the MST connector. The problem was highlighted by commit 4f5368b5541a ("drm/kms: Catch mode_object lifetime errors") which results in the following spew: [ 1330.878941] WARNING: CPU: 2 PID: 1554 at drivers/gpu/drm/drm_mode_object.c:45 __drm_mode_object_add+0xa0/0xb0 [drm] ... [ 1330.879008] Call Trace: [ 1330.879023] drm_property_create+0xba/0x180 [drm] [ 1330.879036] drm_property_create_range+0x15/0x30 [drm] [ 1330.879048] drm_connector_attach_max_bpc_property+0x62/0x80 [drm] [ 1330.879086] intel_dp_add_mst_connector+0x11f/0x140 [i915] [ 1330.879094] drm_dp_add_port.isra.20+0x20b/0x440 [drm_kms_helper] ... Cc: stable@vger.kernel.org Cc: Lyude Paul Cc: sunpeng.li@amd.com Cc: Daniel Vetter Cc: Sean Paul Fixes: 5ca0ef8a56b8 ("drm/i915: Add max_bpc property for DP MST") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190820161657.9658-1-ville.syrjala@linux.intel.com Reviewed-by: José Roberto de Souza Reviewed-by: Lyude Paul (cherry picked from commit 1b9bd09630d4db4827cc04d358a41a16a6bc2cb0) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 60652ebbdf61..18e4cba76720 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -539,7 +539,15 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo intel_attach_force_audio_property(connector); intel_attach_broadcast_rgb_property(connector); - drm_connector_attach_max_bpc_property(connector, 6, 12); + + /* + * Reuse the prop from the SST connector because we're + * not allowed to create new props after device registration. + */ + connector->max_bpc_property = + intel_dp->attached_connector->base.max_bpc_property; + if (connector->max_bpc_property) + drm_connector_attach_max_bpc_property(connector, 6, 12); return connector; From 0a3dfbb5cd9033752639ef33e319c2f2863c713a Mon Sep 17 00:00:00 2001 From: Xiong Zhang Date: Tue, 20 Aug 2019 13:46:17 +0800 Subject: [PATCH 12/18] drm/i915: Don't deballoon unused ggtt drm_mm_node in linux guest The following call trace may exist in linux guest dmesg when guest i915 driver is unloaded. [ 90.776610] [drm:vgt_deballoon_space.isra.0 [i915]] deballoon space: range [0x0 - 0x0] 0 KiB. [ 90.776621] BUG: unable to handle kernel NULL pointer dereference at 00000000000000c0 [ 90.776691] IP: drm_mm_remove_node+0x4d/0x320 [drm] [ 90.776718] PGD 800000012c7d0067 P4D 800000012c7d0067 PUD 138e4c067 PMD 0 [ 90.777091] task: ffff9adab60f2f00 task.stack: ffffaf39c0fe0000 [ 90.777142] RIP: 0010:drm_mm_remove_node+0x4d/0x320 [drm] [ 90.777573] Call Trace: [ 90.777653] intel_vgt_deballoon+0x4c/0x60 [i915] [ 90.777729] i915_ggtt_cleanup_hw+0x121/0x190 [i915] [ 90.777792] i915_driver_unload+0x145/0x180 [i915] [ 90.777856] i915_pci_remove+0x15/0x20 [i915] [ 90.777890] pci_device_remove+0x3b/0xc0 [ 90.777916] device_release_driver_internal+0x157/0x220 [ 90.777945] driver_detach+0x39/0x70 [ 90.777967] bus_remove_driver+0x51/0xd0 [ 90.777990] pci_unregister_driver+0x23/0x90 [ 90.778019] SyS_delete_module+0x1da/0x240 [ 90.778045] entry_SYSCALL_64_fastpath+0x24/0x87 [ 90.778072] RIP: 0033:0x7f34312af067 [ 90.778092] RSP: 002b:00007ffdea3da0d8 EFLAGS: 00000206 [ 90.778297] RIP: drm_mm_remove_node+0x4d/0x320 [drm] RSP: ffffaf39c0fe3dc0 [ 90.778344] ---[ end trace f4b1bc8305fc59dd ]--- Four drm_mm_node are used to reserve guest ggtt space, but some of them may be skipped and not initialised due to space constraints in intel_vgt_balloon(). If drm_mm_remove_node() is called with uninitialized drm_mm_node, the above call trace occurs. This patch check drm_mm_node's validity before calling drm_mm_remove_node(). Fixes: ff8f797557c7("drm/i915: return the correct usable aperture size under gvt environment") Cc: stable@vger.kernel.org Signed-off-by: Xiong Zhang Acked-by: Zhenyu Wang Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/1566279978-9659-1-git-send-email-xiong.y.zhang@intel.com (cherry picked from commit 4776f3529d6b1e47f02904ad1d264d25ea22b27b) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_vgpu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c index 94d3992b599d..724627afdedc 100644 --- a/drivers/gpu/drm/i915/i915_vgpu.c +++ b/drivers/gpu/drm/i915/i915_vgpu.c @@ -101,6 +101,9 @@ static struct _balloon_info_ bl_info; static void vgt_deballoon_space(struct i915_ggtt *ggtt, struct drm_mm_node *node) { + if (!drm_mm_node_allocated(node)) + return; + DRM_DEBUG_DRIVER("deballoon space: range [0x%llx - 0x%llx] %llu KiB.\n", node->start, node->start + node->size, From 5b6eefd667847ca6bd6925f7bd1afcecc457c889 Mon Sep 17 00:00:00 2001 From: Manasi Navare Date: Wed, 21 Aug 2019 14:59:50 -0700 Subject: [PATCH 13/18] drm/i915/dp: Fix DSC enable code to use cpu_transcoder instead of encoder->type This patch fixes the intel_configure_pps_for_dsc_encoder() function to use cpu_transcoder instead of encoder->type to select the correct DSC registers that was wrongly used in the original patch for one DSC register isntance. Fixes: 7182414e2530 ("drm/i915/dp: Configure i915 Picture parameter Set registers during DSC enabling") Cc: Ville Syrjala Cc: Maarten Lankhorst Cc: Jani Nikula Cc: # v5.0+ Signed-off-by: Manasi Navare Reviewed-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20190821215950.24223-1-manasi.d.navare@intel.com (cherry picked from commit d4c61c4a16decd8ace8660f22c81609a539fccba) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_vdsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index ffec807b8960..f413904a3e96 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -541,7 +541,7 @@ static void intel_configure_pps_for_dsc_encoder(struct intel_encoder *encoder, pps_val |= DSC_PIC_HEIGHT(vdsc_cfg->pic_height) | DSC_PIC_WIDTH(vdsc_cfg->pic_width / num_vdsc_instances); DRM_INFO("PPS2 = 0x%08x\n", pps_val); - if (encoder->type == INTEL_OUTPUT_EDP) { + if (cpu_transcoder == TRANSCODER_EDP) { I915_WRITE(DSCA_PICTURE_PARAMETER_SET_2, pps_val); /* * If 2 VDSC instances are needed, configure PPS for second From 32f0a982650b123bdab36865617d3e03ebcacf3b Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Fri, 23 Aug 2019 16:52:51 -0400 Subject: [PATCH 14/18] drm/i915: Call dma_set_max_seg_size() in i915_driver_hw_probe() Currently, we don't call dma_set_max_seg_size() for i915 because we intentionally do not limit the segment length that the device supports. However, this results in a warning being emitted if we try to map anything larger than SZ_64K on a kernel with CONFIG_DMA_API_DEBUG_SG enabled: [ 7.751926] DMA-API: i915 0000:00:02.0: mapping sg segment longer than device claims to support [len=98304] [max=65536] [ 7.751934] WARNING: CPU: 5 PID: 474 at kernel/dma/debug.c:1220 debug_dma_map_sg+0x20f/0x340 This was originally brought up on https://bugs.freedesktop.org/show_bug.cgi?id=108517 , and the consensus there was it wasn't really useful to set a limit (and that dma-debug isn't really all that useful for i915 in the first place). Unfortunately though, CONFIG_DMA_API_DEBUG_SG is enabled in the debug configs for various distro kernels. Since a WARN_ON() will disable automatic problem reporting (and cause any CI with said option enabled to start complaining), we really should just fix the problem. Note that as me and Chris Wilson discussed, the other solution for this would be to make DMA-API not make such assumptions when a driver hasn't explicitly set a maximum segment size. But, taking a look at the commit which originally introduced this behavior, commit 78c47830a5cb ("dma-debug: check scatterlist segments"), there is an explicit mention of this assumption and how it applies to devices with no segment size: Conversely, devices which are less limited than the rather conservative defaults, or indeed have no limitations at all (e.g. GPUs with their own internal MMU), should be encouraged to set appropriate dma_parms, as they may get more efficient DMA mapping performance out of it. So unless there's any concerns (I'm open to discussion!), let's just follow suite and call dma_set_max_seg_size() with UINT_MAX as our limit to silence any warnings. Changes since v3: * Drop patch for enabling CONFIG_DMA_API_DEBUG_SG in CI. It looks like just turning it on causes the kernel to spit out bogus WARN_ONs() during some igt tests which would otherwise require teaching igt to disable the various DMA-API debugging options causing this. This is too much work to be worth it, since DMA-API debugging is useless for us. So, we'll just settle with this single patch to squelch WARN_ONs() during driver load for users that have CONFIG_DMA_API_DEBUG_SG turned on for some reason. * Move dma_set_max_seg_size() call into i915_driver_hw_probe() - Chris Wilson Signed-off-by: Lyude Paul Reviewed-by: Chris Wilson Cc: # v4.18+ Link: https://patchwork.freedesktop.org/patch/msgid/20190823205251.14298-1-lyude@redhat.com (cherry picked from commit acd674af95d3f627062007429b9c195c6b32361d) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_drv.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f62e3397d936..bac1ee94f63f 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1598,6 +1598,12 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) pci_set_master(pdev); + /* + * We don't have a max segment size, so set it to the max so sg's + * debugging layer doesn't complain + */ + dma_set_max_seg_size(&pdev->dev, UINT_MAX); + /* overlay on gen2 is broken and can't address above 1G */ if (IS_GEN(dev_priv, 2)) { ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(30)); From 83e09d5bddbee749fc83063890244397896a1971 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Mon, 19 Aug 2019 13:17:53 +0800 Subject: [PATCH 15/18] drm/amd/powerplay: correct Vega20 dpm level related settings Correct the settings for auto mode and skip the unnecessary settings for dcefclk and fclk. Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- .../drm/amd/powerplay/hwmgr/vega20_hwmgr.c | 60 +++++++++++++++++-- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c index 81658dc8fafc..90c4e87ac5ad 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c @@ -2353,12 +2353,16 @@ static int vega20_force_dpm_highest(struct pp_hwmgr *hwmgr) data->dpm_table.soc_table.dpm_state.soft_max_level = data->dpm_table.soc_table.dpm_levels[soft_level].value; - ret = vega20_upload_dpm_min_level(hwmgr, 0xFFFFFFFF); + ret = vega20_upload_dpm_min_level(hwmgr, FEATURE_DPM_GFXCLK_MASK | + FEATURE_DPM_UCLK_MASK | + FEATURE_DPM_SOCCLK_MASK); PP_ASSERT_WITH_CODE(!ret, "Failed to upload boot level to highest!", return ret); - ret = vega20_upload_dpm_max_level(hwmgr, 0xFFFFFFFF); + ret = vega20_upload_dpm_max_level(hwmgr, FEATURE_DPM_GFXCLK_MASK | + FEATURE_DPM_UCLK_MASK | + FEATURE_DPM_SOCCLK_MASK); PP_ASSERT_WITH_CODE(!ret, "Failed to upload dpm max level to highest!", return ret); @@ -2391,12 +2395,16 @@ static int vega20_force_dpm_lowest(struct pp_hwmgr *hwmgr) data->dpm_table.soc_table.dpm_state.soft_max_level = data->dpm_table.soc_table.dpm_levels[soft_level].value; - ret = vega20_upload_dpm_min_level(hwmgr, 0xFFFFFFFF); + ret = vega20_upload_dpm_min_level(hwmgr, FEATURE_DPM_GFXCLK_MASK | + FEATURE_DPM_UCLK_MASK | + FEATURE_DPM_SOCCLK_MASK); PP_ASSERT_WITH_CODE(!ret, "Failed to upload boot level to highest!", return ret); - ret = vega20_upload_dpm_max_level(hwmgr, 0xFFFFFFFF); + ret = vega20_upload_dpm_max_level(hwmgr, FEATURE_DPM_GFXCLK_MASK | + FEATURE_DPM_UCLK_MASK | + FEATURE_DPM_SOCCLK_MASK); PP_ASSERT_WITH_CODE(!ret, "Failed to upload dpm max level to highest!", return ret); @@ -2407,14 +2415,54 @@ static int vega20_force_dpm_lowest(struct pp_hwmgr *hwmgr) static int vega20_unforce_dpm_levels(struct pp_hwmgr *hwmgr) { + struct vega20_hwmgr *data = + (struct vega20_hwmgr *)(hwmgr->backend); + uint32_t soft_min_level, soft_max_level; int ret = 0; - ret = vega20_upload_dpm_min_level(hwmgr, 0xFFFFFFFF); + /* gfxclk soft min/max settings */ + soft_min_level = + vega20_find_lowest_dpm_level(&(data->dpm_table.gfx_table)); + soft_max_level = + vega20_find_highest_dpm_level(&(data->dpm_table.gfx_table)); + + data->dpm_table.gfx_table.dpm_state.soft_min_level = + data->dpm_table.gfx_table.dpm_levels[soft_min_level].value; + data->dpm_table.gfx_table.dpm_state.soft_max_level = + data->dpm_table.gfx_table.dpm_levels[soft_max_level].value; + + /* uclk soft min/max settings */ + soft_min_level = + vega20_find_lowest_dpm_level(&(data->dpm_table.mem_table)); + soft_max_level = + vega20_find_highest_dpm_level(&(data->dpm_table.mem_table)); + + data->dpm_table.mem_table.dpm_state.soft_min_level = + data->dpm_table.mem_table.dpm_levels[soft_min_level].value; + data->dpm_table.mem_table.dpm_state.soft_max_level = + data->dpm_table.mem_table.dpm_levels[soft_max_level].value; + + /* socclk soft min/max settings */ + soft_min_level = + vega20_find_lowest_dpm_level(&(data->dpm_table.soc_table)); + soft_max_level = + vega20_find_highest_dpm_level(&(data->dpm_table.soc_table)); + + data->dpm_table.soc_table.dpm_state.soft_min_level = + data->dpm_table.soc_table.dpm_levels[soft_min_level].value; + data->dpm_table.soc_table.dpm_state.soft_max_level = + data->dpm_table.soc_table.dpm_levels[soft_max_level].value; + + ret = vega20_upload_dpm_min_level(hwmgr, FEATURE_DPM_GFXCLK_MASK | + FEATURE_DPM_UCLK_MASK | + FEATURE_DPM_SOCCLK_MASK); PP_ASSERT_WITH_CODE(!ret, "Failed to upload DPM Bootup Levels!", return ret); - ret = vega20_upload_dpm_max_level(hwmgr, 0xFFFFFFFF); + ret = vega20_upload_dpm_max_level(hwmgr, FEATURE_DPM_GFXCLK_MASK | + FEATURE_DPM_UCLK_MASK | + FEATURE_DPM_SOCCLK_MASK); PP_ASSERT_WITH_CODE(!ret, "Failed to upload DPM Max Levels!", return ret); From 317a3aaef94d73ba6be88aea11b41bb631b2d581 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Tue, 27 Aug 2019 17:33:32 +0800 Subject: [PATCH 16/18] drm/amdgpu: Add APTX quirk for Dell Latitude 5495 Needs ATPX rather than _PR3 to really turn off the dGPU. This can save ~5W when dGPU is runtime-suspended. Signed-off-by: Kai-Heng Feng Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index 9b384a94d2f3..3e35a8f2c5e5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -574,6 +574,7 @@ static const struct amdgpu_px_quirk amdgpu_px_quirk_list[] = { { 0x1002, 0x6900, 0x1002, 0x0124, AMDGPU_PX_QUIRK_FORCE_ATPX }, { 0x1002, 0x6900, 0x1028, 0x0812, AMDGPU_PX_QUIRK_FORCE_ATPX }, { 0x1002, 0x6900, 0x1028, 0x0813, AMDGPU_PX_QUIRK_FORCE_ATPX }, + { 0x1002, 0x699f, 0x1028, 0x0814, AMDGPU_PX_QUIRK_FORCE_ATPX }, { 0x1002, 0x6900, 0x1025, 0x125A, AMDGPU_PX_QUIRK_FORCE_ATPX }, { 0x1002, 0x6900, 0x17AA, 0x3806, AMDGPU_PX_QUIRK_FORCE_ATPX }, { 0, 0, 0, 0, 0 }, From 41940ff50f6c347f3541163702566cd526200d98 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Tue, 27 Aug 2019 22:59:45 +0800 Subject: [PATCH 17/18] drm/amdgpu: fix GFXOFF on Picasso and Raven2 For picasso(adev->pdev->device == 0x15d8)&raven2(adev->rev_id >= 0x8), firmware is sufficient to support gfxoff. In commit 98f58ada2d37e, for picasso&raven2, return directly and cause gfxoff disabled. Fixes: 98f58ada2d37 ("drm/amdgpu/gfx9: update pg_flags after determining if gfx off is possible") Reviewed-by: Huang Rui Reviewed-by: Alex Deucher Signed-off-by: Aaron Liu Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index 4ea67f94cae2..c066e1d3f981 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -596,14 +596,14 @@ static void gfx_v9_0_check_if_need_gfxoff(struct amdgpu_device *adev) case CHIP_VEGA20: break; case CHIP_RAVEN: - if (adev->rev_id >= 0x8 || adev->pdev->device == 0x15d8) - break; - if ((adev->gfx.rlc_fw_version != 106 && - adev->gfx.rlc_fw_version < 531) || - (adev->gfx.rlc_fw_version == 53815) || - (adev->gfx.rlc_feature_version < 1) || - !adev->gfx.rlc.is_rlc_v2_1) + if (!(adev->rev_id >= 0x8 || adev->pdev->device == 0x15d8) + &&((adev->gfx.rlc_fw_version != 106 && + adev->gfx.rlc_fw_version < 531) || + (adev->gfx.rlc_fw_version == 53815) || + (adev->gfx.rlc_feature_version < 1) || + !adev->gfx.rlc.is_rlc_v2_1)) adev->pm.pp_feature &= ~PP_GFXOFF_MASK; + if (adev->pm.pp_feature & PP_GFXOFF_MASK) adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG | AMD_PG_SUPPORT_CP | From 6978bce054247e4cfccdf689ce263e076499f905 Mon Sep 17 00:00:00 2001 From: Ayan Kumar Halder Date: Wed, 28 Aug 2019 15:00:19 +0000 Subject: [PATCH 18/18] drm/komeda: Reordered the komeda's de-init functions The de-init routine should be doing the following in order:- 1. Unregister the drm device 2. Shut down the crtcs - failing to do this might cause a connector leakage See the 'commit 109c4d18e574 ("drm/arm/malidp: Ensure that the crtcs are shutdown before removing any encoder/connector")' 3. Disable the interrupts 4. Unbind the components 5. Free up DRM mode_config info Changes from v1:- 1. Re-ordered the header files inclusion 2. Rebased on top of the latest drm-misc-fixes Signed-off-by:. Ayan Kumar Halder Reviewed-by: Mihail Atanassov Reviewed-by: James Qian Wang (Arm Technology China) Link: https://patchwork.freedesktop.org/patch/327606/ --- .../gpu/drm/arm/display/komeda/komeda_kms.c | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c index 1f0e3f4e8d74..69d9e26c60c8 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c @@ -14,8 +14,8 @@ #include #include #include -#include #include +#include #include "komeda_dev.h" #include "komeda_framebuffer.h" @@ -306,11 +306,11 @@ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev) komeda_kms_irq_handler, IRQF_SHARED, drm->driver->name, drm); if (err) - goto cleanup_mode_config; + goto free_component_binding; err = mdev->funcs->enable_irq(mdev); if (err) - goto cleanup_mode_config; + goto free_component_binding; drm->irq_enabled = true; @@ -318,15 +318,21 @@ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev) err = drm_dev_register(drm, 0); if (err) - goto cleanup_mode_config; + goto free_interrupts; return kms; -cleanup_mode_config: +free_interrupts: drm_kms_helper_poll_fini(drm); drm->irq_enabled = false; + mdev->funcs->disable_irq(mdev); +free_component_binding: + component_unbind_all(mdev->dev, drm); +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); @@ -337,13 +343,14 @@ void komeda_kms_detach(struct komeda_kms_dev *kms) struct drm_device *drm = &kms->base; struct komeda_dev *mdev = drm->dev_private; - drm->irq_enabled = false; - mdev->funcs->disable_irq(mdev); drm_dev_unregister(drm); drm_kms_helper_poll_fini(drm); + drm_atomic_helper_shutdown(drm); + drm->irq_enabled = false; + mdev->funcs->disable_irq(mdev); component_unbind_all(mdev->dev, drm); - komeda_kms_cleanup_private_objs(kms); drm_mode_config_cleanup(drm); + komeda_kms_cleanup_private_objs(kms); drm->dev_private = NULL; drm_dev_put(drm); }