From: Jared Baldridge jrb@expunge.us
[ Upstream commit 81ad7f9f78e4ff80e95be8282423f511b84f1166 ]
The OneGX1 Pro has a fairly unique combination of generic strings, but we additionally match on the BIOS date just to be safe.
Signed-off-by: Jared Baldridge jrb@expunge.us Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/41288ccb-1012-486b-81c1-a24c31... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_panel_orientation_quirks.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c index 58f5dc2f6dd5..f6bdec7fa925 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -84,6 +84,13 @@ static const struct drm_dmi_panel_orientation_data itworks_tw891 = { .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, };
+static const struct drm_dmi_panel_orientation_data onegx1_pro = { + .width = 1200, + .height = 1920, + .bios_dates = (const char * const []){ "12/17/2020", NULL }, + .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, +}; + static const struct drm_dmi_panel_orientation_data lcd720x1280_rightside_up = { .width = 720, .height = 1280, @@ -211,6 +218,13 @@ static const struct dmi_system_id orientation_data[] = { DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"), }, .driver_data = (void *)&lcd1200x1920_rightside_up, + }, { /* OneGX1 Pro */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SYSTEM_MANUFACTURER"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SYSTEM_PRODUCT_NAME"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Default string"), + }, + .driver_data = (void *)&onegx1_pro, }, { /* VIOS LTH17 */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"),
From: Tong Zhang ztong0001@gmail.com
[ Upstream commit b91907a6241193465ca92e357adf16822242296d ]
if qxl_device_init() fail, drm device will not be registered, in this case, do not run qxl_drm_release()
[ 5.258534] ================================================================== [ 5.258931] BUG: KASAN: user-memory-access in qxl_destroy_monitors_object+0x42/0xa0 [qxl] [ 5.259388] Write of size 8 at addr 00000000000014dc by task modprobe/95 [ 5.259754] [ 5.259842] CPU: 0 PID: 95 Comm: modprobe Not tainted 5.11.0-rc6-00007-g88bb507a74ea #62 [ 5.260309] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-48-gd9c812dda54 [ 5.260917] Call Trace: [ 5.261056] dump_stack+0x7d/0xa3 [ 5.261245] kasan_report.cold+0x10c/0x10e [ 5.261475] ? qxl_destroy_monitors_object+0x42/0xa0 [qxl] [ 5.261789] check_memory_region+0x17c/0x1e0 [ 5.262029] qxl_destroy_monitors_object+0x42/0xa0 [qxl] [ 5.262332] qxl_modeset_fini+0x9/0x20 [qxl] [ 5.262595] qxl_drm_release+0x22/0x30 [qxl] [ 5.262841] drm_dev_release+0x32/0x50 [ 5.263047] release_nodes+0x39e/0x410 [ 5.263253] ? devres_release+0x40/0x40 [ 5.263462] really_probe+0x2ea/0x420 [ 5.263664] driver_probe_device+0x6d/0xd0 [ 5.263888] device_driver_attach+0x82/0x90 [ 5.264116] ? device_driver_attach+0x90/0x90 [ 5.264353] __driver_attach+0x60/0x100 [ 5.264563] ? device_driver_attach+0x90/0x90 [ 5.264801] bus_for_each_dev+0xe1/0x140 [ 5.265014] ? subsys_dev_iter_exit+0x10/0x10 [ 5.265251] ? klist_node_init+0x61/0x80 [ 5.265464] bus_add_driver+0x254/0x2a0 [ 5.265673] driver_register+0xd3/0x150 [ 5.265882] ? 0xffffffffc0048000 [ 5.266064] do_one_initcall+0x84/0x250 [ 5.266274] ? trace_event_raw_event_initcall_finish+0x150/0x150 [ 5.266596] ? unpoison_range+0xf/0x30 [ 5.266801] ? ____kasan_kmalloc.constprop.0+0x84/0xa0 [ 5.267082] ? unpoison_range+0xf/0x30 [ 5.267287] ? unpoison_range+0xf/0x30 [ 5.267491] do_init_module+0xf8/0x350 [ 5.267697] load_module+0x3fe6/0x4340 [ 5.267902] ? vm_unmap_ram+0x1d0/0x1d0 [ 5.268115] ? module_frob_arch_sections+0x20/0x20 [ 5.268375] ? __do_sys_finit_module+0x108/0x170 [ 5.268624] __do_sys_finit_module+0x108/0x170 [ 5.268865] ? __ia32_sys_init_module+0x40/0x40 [ 5.269111] ? file_open_root+0x200/0x200 [ 5.269330] ? do_sys_open+0x85/0xe0 [ 5.269527] ? filp_open+0x50/0x50 [ 5.269714] ? exit_to_user_mode_prepare+0xfc/0x130 [ 5.269978] do_syscall_64+0x33/0x40 [ 5.270176] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 5.270450] RIP: 0033:0x7fa3f685bcf7 [ 5.270646] Code: 48 89 57 30 48 8b 04 24 48 89 47 38 e9 1d a0 02 00 48 89 f8 48 89 f7 48 89 d1 [ 5.271634] RSP: 002b:00007ffca83048d8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 [ 5.272037] RAX: ffffffffffffffda RBX: 0000000001e94a70 RCX: 00007fa3f685bcf7 [ 5.272416] RDX: 0000000000000000 RSI: 0000000001e939e0 RDI: 0000000000000003 [ 5.272794] RBP: 0000000000000003 R08: 0000000000000000 R09: 0000000000000001 [ 5.273171] R10: 00007fa3f68bf300 R11: 0000000000000246 R12: 0000000001e939e0 [ 5.273550] R13: 0000000000000000 R14: 0000000001e93bd0 R15: 0000000000000001 [ 5.273928] ==================================================================
Signed-off-by: Tong Zhang ztong0001@gmail.com Link: http://patchwork.freedesktop.org/patch/msgid/20210203040727.868921-1-ztong00... Signed-off-by: Gerd Hoffmann kraxel@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/qxl/qxl_drv.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index 6e7f16f4cec7..41cdf9d1e59d 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -144,6 +144,8 @@ static void qxl_drm_release(struct drm_device *dev) * reodering qxl_modeset_fini() + qxl_device_fini() calls is * non-trivial though. */ + if (!dev->registered) + return; qxl_modeset_fini(qdev); qxl_device_fini(qdev); }
From: Gerd Hoffmann kraxel@redhat.com
[ Upstream commit 4ca77c513537700d3fae69030879f781dde1904c ]
In case we have a shadow surface on shutdown release it so it doesn't leak.
Signed-off-by: Gerd Hoffmann kraxel@redhat.com Acked-by: Thomas Zimmermann tzimmermann@suse.de Link: http://patchwork.freedesktop.org/patch/msgid/20210204145712.1531203-6-kraxel... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/qxl/qxl_display.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 862ef59d4d03..1f0802f5d84e 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -1224,6 +1224,10 @@ int qxl_modeset_init(struct qxl_device *qdev)
void qxl_modeset_fini(struct qxl_device *qdev) { + if (qdev->dumb_shadow_bo) { + drm_gem_object_put(&qdev->dumb_shadow_bo->tbo.base); + qdev->dumb_shadow_bo = NULL; + } qxl_destroy_monitors_object(qdev); drm_mode_config_cleanup(&qdev->ddev); }
From: Thomas Zimmermann tzimmermann@suse.de
[ Upstream commit ee4a92d690f30f3793df942939726bec0338e65b ]
Use AST_MAX_HWC_HEIGHT for setting offset_y in the cursor plane's atomic_check. The code used AST_MAX_HWC_WIDTH instead. This worked because both constants has the same value.
Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Acked-by: Gerd Hoffmann kraxel@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20210209134632.12157-3-tzimmer... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/ast/ast_mode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 0a1e1cf57e19..a3c2f76668ab 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -688,7 +688,7 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane, unsigned int offset_x, offset_y;
offset_x = AST_MAX_HWC_WIDTH - fb->width; - offset_y = AST_MAX_HWC_WIDTH - fb->height; + offset_y = AST_MAX_HWC_HEIGHT - fb->height;
if (state->fb != old_state->fb) { /* A new cursor image was installed. */
From: Martin Leung martin.leung@amd.com
[ Upstream commit efe213e5a57e0cd92fa4f328dc1963d330549982 ]
[Why] Hardware team remeasured, need to update timings to increase latency slightly and avoid intermittent underflows.
[How] sr exit latency update.
Signed-off-by: Martin Leung martin.leung@amd.com Reviewed-by: Alvin Lee Alvin.Lee2@amd.com Acked-by: Qingqing Zhuo Qingqing.Zhuo@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c index 2455d210ccf6..8465cae180da 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -180,7 +180,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_0_soc = { }, .min_dcfclk = 500.0, /* TODO: set this to actual min DCFCLK */ .num_states = 1, - .sr_exit_time_us = 12, + .sr_exit_time_us = 15.5, .sr_enter_plus_exit_time_us = 20, .urgent_latency_us = 4.0, .urgent_latency_pixel_data_only_us = 4.0,
From: Tong Zhang ztong0001@gmail.com
[ Upstream commit dc739820ff90acccd013f6bb420222978a982791 ]
a connector is leaked upon module unload, it seems that we should do similar to sample driver as suggested in drm_drv.c.
Adding drm_atomic_helper_shutdown() in ast_pci_remove to prevent leaking.
[ 153.822134] WARNING: CPU: 0 PID: 173 at drivers/gpu/drm/drm_mode_config.c:504 drm_mode_config_cle0 [ 153.822698] Modules linked in: ast(-) drm_vram_helper drm_ttm_helper ttm [last unloaded: ttm] [ 153.823197] CPU: 0 PID: 173 Comm: modprobe Tainted: G W 5.11.0-03615-g55f62bc873474 [ 153.823708] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-48-gd9c812dda519-4 [ 153.824333] RIP: 0010:drm_mode_config_cleanup+0x418/0x470 [ 153.824637] Code: 0c 00 00 00 00 48 8b 84 24 a8 00 00 00 65 48 33 04 25 28 00 00 00 75 65 48 81 c0 [ 153.825668] RSP: 0018:ffff888103c9fb70 EFLAGS: 00010212 [ 153.825962] RAX: ffff888102b0d100 RBX: ffff888102b0c298 RCX: ffffffff818d8b2b [ 153.826356] RDX: dffffc0000000000 RSI: 000000007fffffff RDI: ffff888102b0c298 [ 153.826748] RBP: ffff888103c9fba0 R08: 0000000000000001 R09: ffffed1020561857 [ 153.827146] R10: ffff888102b0c2b7 R11: ffffed1020561856 R12: ffff888102b0c000 [ 153.827538] R13: ffff888102b0c2d8 R14: ffff888102b0c2d8 R15: 1ffff11020793f70 [ 153.827935] FS: 00007f24bff456a0(0000) GS:ffff88815b400000(0000) knlGS:0000000000000000 [ 153.828380] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 153.828697] CR2: 0000000001c39018 CR3: 0000000103c90000 CR4: 00000000000006f0 [ 153.829096] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 153.829486] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 153.829883] Call Trace: [ 153.830024] ? drmm_mode_config_init+0x930/0x930 [ 153.830281] ? cpumask_next+0x16/0x20 [ 153.830488] ? mnt_get_count+0x66/0x80 [ 153.830699] ? drm_mode_config_cleanup+0x470/0x470 [ 153.830972] drm_managed_release+0xed/0x1c0 [ 153.831208] drm_dev_release+0x3a/0x50 [ 153.831420] release_nodes+0x39e/0x410 [ 153.831631] ? devres_release+0x40/0x40 [ 153.831852] device_release_driver_internal+0x158/0x270 [ 153.832143] driver_detach+0x76/0xe0 [ 153.832344] bus_remove_driver+0x7e/0x100 [ 153.832568] pci_unregister_driver+0x28/0xf0 [ 153.832821] __x64_sys_delete_module+0x268/0x300 [ 153.833086] ? __ia32_sys_delete_module+0x300/0x300 [ 153.833357] ? call_rcu+0x372/0x4f0 [ 153.833553] ? fpregs_assert_state_consistent+0x4d/0x60 [ 153.833840] ? exit_to_user_mode_prepare+0x2f/0x130 [ 153.834118] do_syscall_64+0x33/0x40 [ 153.834317] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 153.834597] RIP: 0033:0x7f24bfec7cf7 [ 153.834797] Code: 48 89 57 30 48 8b 04 24 48 89 47 38 e9 1d a0 02 00 48 89 f8 48 89 f7 48 89 d6 41 [ 153.835812] RSP: 002b:00007fff72e6cb58 EFLAGS: 00000202 ORIG_RAX: 00000000000000b0 [ 153.836234] RAX: ffffffffffffffda RBX: 00007f24bff45690 RCX: 00007f24bfec7cf7 [ 153.836623] RDX: 00000000ffffffff RSI: 0000000000000080 RDI: 0000000001c2fb10 [ 153.837018] RBP: 0000000001c2fac0 R08: 2f2f2f2f2f2f2f2f R09: 0000000001c2fac0 [ 153.837408] R10: fefefefefefefeff R11: 0000000000000202 R12: 0000000001c2fac0 [ 153.837798] R13: 0000000001c2f9d0 R14: 0000000000000000 R15: 0000000000000001 [ 153.838194] ---[ end trace b92031513bbe596c ]--- [ 153.838441] [drm:drm_mode_config_cleanup] *ERROR* connector VGA-1 leaked!
Signed-off-by: Tong Zhang ztong0001@gmail.com Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Link: https://patchwork.freedesktop.org/patch/msgid/20210222023322.984885-1-ztong0... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/ast/ast_drv.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index f0b4af1c390a..59d2466d40c6 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -30,6 +30,7 @@ #include <linux/module.h> #include <linux/pci.h>
+#include <drm/drm_atomic_helper.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_drv.h> #include <drm/drm_fb_helper.h> @@ -138,6 +139,7 @@ static void ast_pci_remove(struct pci_dev *pdev) struct drm_device *dev = pci_get_drvdata(pdev);
drm_dev_unregister(dev); + drm_atomic_helper_shutdown(dev); }
static int ast_drm_freeze(struct drm_device *dev)
From: Eryk Brol eryk.brol@amd.com
[ Upstream commit 349a19b2f1b01e713268c7de9944ad669ccdf369 ]
[why] This check for ASIC revision is no longer useful and causes lightup issues after a topology change in MST DSC scenario. In this case, DSC configs should be recalculated for the new topology. This check prevented that from happening on certain ASICs that do, in fact, support DSC.
[how] Change the ASIC revision to instead check if DSC is supported.
Signed-off-by: Eryk Brol eryk.brol@amd.com Acked-by: Bindu Ramamurthy bindu.r@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index c07737c45677..830d302be045 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -8659,7 +8659,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, }
#if defined(CONFIG_DRM_AMD_DC_DCN) - if (adev->asic_type >= CHIP_NAVI10) { + if (dc_resource_is_dsc_encoding_supported(dc)) { for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { if (drm_atomic_crtc_needs_modeset(new_crtc_state)) { ret = add_affected_mst_dsc_crtcs(state, crtc);
From: Aric Cyr aric.cyr@amd.com
[ Upstream commit 6ad98e8aeb0106f453bb154933e8355849244990 ]
[Why] There is a window of time where we optimize bandwidth due to no streams enabled will enable PSTATE changing but HUBPs are not disabled yet. This results in underflow counter increasing in some hotplug scenarios.
[How] Set the optimize-bandwidth flag for later processing once all the HUBPs are properly disabled.
Signed-off-by: Aric Cyr aric.cyr@amd.com Acked-by: Bindu Ramamurthy bindu.r@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index ffb21196bf59..921c4ca6e902 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -2345,7 +2345,8 @@ static void commit_planes_do_stream_update(struct dc *dc, if (pipe_ctx->stream_res.audio && !dc->debug.az_endpoint_mute_only) pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
- dc->hwss.optimize_bandwidth(dc, dc->current_state); + dc->optimized_required = true; + } else { if (dc->optimize_seamless_boot_streams == 0) dc->hwss.prepare_bandwidth(dc, dc->current_state);
From: Xiaogang Chen xiaogang.chen@amd.com
[ Upstream commit b6f91fc183f758461b9462cc93e673adbbf95c2d ]
amdgpu DM handles INTERRUPT_LOW_IRQ_CONTEXT interrupt(hpd, hpd_rx) by using work queue and uses single work_struct. If new interrupt is recevied before the previous handler finished, new interrupts(same type) will be discarded and driver just sends "amdgpu_dm_irq_schedule_work FAILED" message out. If some important hpd, hpd_rx related interrupts are missed by driver the hot (un)plug devices may cause system hang or instability, such as issues with system resume from S3 sleep with mst device connected.
This patch dynamically allocates new amdgpu_dm_irq_handler_data for new interrupts if previous INTERRUPT_LOW_IRQ_CONTEXT interrupt work has not been handled. So the new interrupt works can be queued to the same workqueue_struct, instead of discard the new interrupts. All allocated amdgpu_dm_irq_handler_data are put into a single linked list and will be reused after.
Signed-off-by: Xiaogang Chen xiaogang.chen@amd.com Reviewed-by: Aurabindo Pillai aurabindo.pillai@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 14 +-- .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 115 ++++++++++++------ 2 files changed, 80 insertions(+), 49 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index a8a0e8cb1a11..1df7f1b18049 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -68,18 +68,6 @@ struct common_irq_params { enum dc_irq_source irq_src; };
-/** - * struct irq_list_head - Linked-list for low context IRQ handlers. - * - * @head: The list_head within &struct handler_data - * @work: A work_struct containing the deferred handler work - */ -struct irq_list_head { - struct list_head head; - /* In case this interrupt needs post-processing, 'work' will be queued*/ - struct work_struct work; -}; - /** * struct dm_compressor_info - Buffer info used by frame buffer compression * @cpu_addr: MMIO cpu addr @@ -270,7 +258,7 @@ struct amdgpu_display_manager { * Note that handlers are called in the same order as they were * registered (FIFO). */ - struct irq_list_head irq_handler_list_low_tab[DAL_IRQ_SOURCES_NUMBER]; + struct list_head irq_handler_list_low_tab[DAL_IRQ_SOURCES_NUMBER];
/** * @irq_handler_list_high_tab: diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c index 357778556b06..281b274e2b9b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c @@ -82,6 +82,7 @@ struct amdgpu_dm_irq_handler_data { struct amdgpu_display_manager *dm; /* DAL irq source which registered for this interrupt. */ enum dc_irq_source irq_source; + struct work_struct work; };
#define DM_IRQ_TABLE_LOCK(adev, flags) \ @@ -111,20 +112,10 @@ static void init_handler_common_data(struct amdgpu_dm_irq_handler_data *hcd, */ static void dm_irq_work_func(struct work_struct *work) { - struct irq_list_head *irq_list_head = - container_of(work, struct irq_list_head, work); - struct list_head *handler_list = &irq_list_head->head; - struct amdgpu_dm_irq_handler_data *handler_data; - - list_for_each_entry(handler_data, handler_list, list) { - DRM_DEBUG_KMS("DM_IRQ: work_func: for dal_src=%d\n", - handler_data->irq_source); + struct amdgpu_dm_irq_handler_data *handler_data = + container_of(work, struct amdgpu_dm_irq_handler_data, work);
- DRM_DEBUG_KMS("DM_IRQ: schedule_work: for dal_src=%d\n", - handler_data->irq_source); - - handler_data->handler(handler_data->handler_arg); - } + handler_data->handler(handler_data->handler_arg);
/* Call a DAL subcomponent which registered for interrupt notification * at INTERRUPT_LOW_IRQ_CONTEXT. @@ -156,7 +147,7 @@ static struct list_head *remove_irq_handler(struct amdgpu_device *adev, break; case INTERRUPT_LOW_IRQ_CONTEXT: default: - hnd_list = &adev->dm.irq_handler_list_low_tab[irq_source].head; + hnd_list = &adev->dm.irq_handler_list_low_tab[irq_source]; break; }
@@ -287,7 +278,8 @@ void *amdgpu_dm_irq_register_interrupt(struct amdgpu_device *adev, break; case INTERRUPT_LOW_IRQ_CONTEXT: default: - hnd_list = &adev->dm.irq_handler_list_low_tab[irq_source].head; + hnd_list = &adev->dm.irq_handler_list_low_tab[irq_source]; + INIT_WORK(&handler_data->work, dm_irq_work_func); break; }
@@ -369,7 +361,7 @@ void amdgpu_dm_irq_unregister_interrupt(struct amdgpu_device *adev, int amdgpu_dm_irq_init(struct amdgpu_device *adev) { int src; - struct irq_list_head *lh; + struct list_head *lh;
DRM_DEBUG_KMS("DM_IRQ\n");
@@ -378,9 +370,7 @@ int amdgpu_dm_irq_init(struct amdgpu_device *adev) for (src = 0; src < DAL_IRQ_SOURCES_NUMBER; src++) { /* low context handler list init */ lh = &adev->dm.irq_handler_list_low_tab[src]; - INIT_LIST_HEAD(&lh->head); - INIT_WORK(&lh->work, dm_irq_work_func); - + INIT_LIST_HEAD(lh); /* high context handler init */ INIT_LIST_HEAD(&adev->dm.irq_handler_list_high_tab[src]); } @@ -397,8 +387,11 @@ int amdgpu_dm_irq_init(struct amdgpu_device *adev) void amdgpu_dm_irq_fini(struct amdgpu_device *adev) { int src; - struct irq_list_head *lh; + struct list_head *lh; + struct list_head *entry, *tmp; + struct amdgpu_dm_irq_handler_data *handler; unsigned long irq_table_flags; + DRM_DEBUG_KMS("DM_IRQ: releasing resources.\n"); for (src = 0; src < DAL_IRQ_SOURCES_NUMBER; src++) { DM_IRQ_TABLE_LOCK(adev, irq_table_flags); @@ -407,7 +400,16 @@ void amdgpu_dm_irq_fini(struct amdgpu_device *adev) * (because no code can schedule a new one). */ lh = &adev->dm.irq_handler_list_low_tab[src]; DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags); - flush_work(&lh->work); + + if (!list_empty(lh)) { + list_for_each_safe(entry, tmp, lh) { + handler = list_entry( + entry, + struct amdgpu_dm_irq_handler_data, + list); + flush_work(&handler->work); + } + } } }
@@ -417,6 +419,8 @@ int amdgpu_dm_irq_suspend(struct amdgpu_device *adev) struct list_head *hnd_list_h; struct list_head *hnd_list_l; unsigned long irq_table_flags; + struct list_head *entry, *tmp; + struct amdgpu_dm_irq_handler_data *handler;
DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
@@ -427,14 +431,22 @@ int amdgpu_dm_irq_suspend(struct amdgpu_device *adev) * will be disabled from manage_dm_interrupts on disable CRTC. */ for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6RX; src++) { - hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head; + hnd_list_l = &adev->dm.irq_handler_list_low_tab[src]; hnd_list_h = &adev->dm.irq_handler_list_high_tab[src]; if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h)) dc_interrupt_set(adev->dm.dc, src, false);
DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags); - flush_work(&adev->dm.irq_handler_list_low_tab[src].work);
+ if (!list_empty(hnd_list_l)) { + list_for_each_safe (entry, tmp, hnd_list_l) { + handler = list_entry( + entry, + struct amdgpu_dm_irq_handler_data, + list); + flush_work(&handler->work); + } + } DM_IRQ_TABLE_LOCK(adev, irq_table_flags); }
@@ -454,7 +466,7 @@ int amdgpu_dm_irq_resume_early(struct amdgpu_device *adev)
/* re-enable short pulse interrupts HW interrupt */ for (src = DC_IRQ_SOURCE_HPD1RX; src <= DC_IRQ_SOURCE_HPD6RX; src++) { - hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head; + hnd_list_l = &adev->dm.irq_handler_list_low_tab[src]; hnd_list_h = &adev->dm.irq_handler_list_high_tab[src]; if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h)) dc_interrupt_set(adev->dm.dc, src, true); @@ -480,7 +492,7 @@ int amdgpu_dm_irq_resume_late(struct amdgpu_device *adev) * will be enabled from manage_dm_interrupts on enable CRTC. */ for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6; src++) { - hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head; + hnd_list_l = &adev->dm.irq_handler_list_low_tab[src]; hnd_list_h = &adev->dm.irq_handler_list_high_tab[src]; if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h)) dc_interrupt_set(adev->dm.dc, src, true); @@ -497,22 +509,53 @@ int amdgpu_dm_irq_resume_late(struct amdgpu_device *adev) static void amdgpu_dm_irq_schedule_work(struct amdgpu_device *adev, enum dc_irq_source irq_source) { - unsigned long irq_table_flags; - struct work_struct *work = NULL; + struct list_head *handler_list = &adev->dm.irq_handler_list_low_tab[irq_source]; + struct amdgpu_dm_irq_handler_data *handler_data; + bool work_queued = false;
- DM_IRQ_TABLE_LOCK(adev, irq_table_flags); + if (list_empty(handler_list)) + return;
- if (!list_empty(&adev->dm.irq_handler_list_low_tab[irq_source].head)) - work = &adev->dm.irq_handler_list_low_tab[irq_source].work; + list_for_each_entry (handler_data, handler_list, list) { + if (!queue_work(system_highpri_wq, &handler_data->work)) { + continue; + } else { + work_queued = true; + break; + } + }
- DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags); + if (!work_queued) { + struct amdgpu_dm_irq_handler_data *handler_data_add; + /*get the amdgpu_dm_irq_handler_data of first item pointed by handler_list*/ + handler_data = container_of(handler_list->next, struct amdgpu_dm_irq_handler_data, list);
- if (work) { - if (!schedule_work(work)) - DRM_INFO("amdgpu_dm_irq_schedule_work FAILED src %d\n", - irq_source); - } + /*allocate a new amdgpu_dm_irq_handler_data*/ + handler_data_add = kzalloc(sizeof(*handler_data), GFP_KERNEL); + if (!handler_data_add) { + DRM_ERROR("DM_IRQ: failed to allocate irq handler!\n"); + return; + } + + /*copy new amdgpu_dm_irq_handler_data members from handler_data*/ + handler_data_add->handler = handler_data->handler; + handler_data_add->handler_arg = handler_data->handler_arg; + handler_data_add->dm = handler_data->dm; + handler_data_add->irq_source = irq_source;
+ list_add_tail(&handler_data_add->list, handler_list); + + INIT_WORK(&handler_data_add->work, dm_irq_work_func); + + if (queue_work(system_highpri_wq, &handler_data_add->work)) + DRM_DEBUG("Queued work for handling interrupt from " + "display for IRQ source %d\n", + irq_source); + else + DRM_ERROR("Failed to queue work for handling interrupt " + "from display for IRQ source %d\n", + irq_source); + } }
/*
From: Lee Jones lee.jones@linaro.org
[ Upstream commit 89adc10178fd6cb68c8ef1905d269070a4d3bd64 ]
Fixes the following W=1 kernel build warning(s):
In file included from drivers/gpu/drm/amd/amdgpu/../display/dc/dce112/dce112_resource.c:59: drivers/gpu/drm/amd/amdgpu/../include/asic_reg/dce/dce_11_2_sh_mask.h:10014:58: warning: initialized field overwritten [-Woverride-init] drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:214:16: note: in expansion of macro ‘AUX_SW_DATA__AUX_SW_AUTOINCREMENT_DISABLE__SHIFT’ drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:127:2: note: in expansion of macro ‘AUX_SF’ drivers/gpu/drm/amd/amdgpu/../display/dc/dce112/dce112_resource.c:177:2: note: in expansion of macro ‘DCE_AUX_MASK_SH_LIST’ drivers/gpu/drm/amd/amdgpu/../include/asic_reg/dce/dce_11_2_sh_mask.h:10014:58: note: (near initialization for ‘aux_shift.AUX_SW_AUTOINCREMENT_DISABLE’) drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:214:16: note: in expansion of macro ‘AUX_SW_DATA__AUX_SW_AUTOINCREMENT_DISABLE__SHIFT’ drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:127:2: note: in expansion of macro ‘AUX_SF’ drivers/gpu/drm/amd/amdgpu/../display/dc/dce112/dce112_resource.c:177:2: note: in expansion of macro ‘DCE_AUX_MASK_SH_LIST’ drivers/gpu/drm/amd/amdgpu/../include/asic_reg/dce/dce_11_2_sh_mask.h:10013:56: warning: initialized field overwritten [-Woverride-init] drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:214:16: note: in expansion of macro ‘AUX_SW_DATA__AUX_SW_AUTOINCREMENT_DISABLE_MASK’ drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:127:2: note: in expansion of macro ‘AUX_SF’ drivers/gpu/drm/amd/amdgpu/../display/dc/dce112/dce112_resource.c:181:2: note: in expansion of macro ‘DCE_AUX_MASK_SH_LIST’ drivers/gpu/drm/amd/amdgpu/../include/asic_reg/dce/dce_11_2_sh_mask.h:10013:56: note: (near initialization for ‘aux_mask.AUX_SW_AUTOINCREMENT_DISABLE’) drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:214:16: note: in expansion of macro ‘AUX_SW_DATA__AUX_SW_AUTOINCREMENT_DISABLE_MASK’ drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:127:2: note: in expansion of macro ‘AUX_SF’
Cc: Harry Wentland harry.wentland@amd.com Cc: Leo Li sunpeng.li@amd.com Cc: Alex Deucher alexander.deucher@amd.com Cc: "Christian König" christian.koenig@amd.com Cc: David Airlie airlied@linux.ie Cc: Daniel Vetter daniel@ffwll.ch Cc: amd-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dce/dce_aux.h | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h index 382465862f29..f72f02e016ae 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h @@ -99,7 +99,6 @@ struct dce110_aux_registers { AUX_SF(AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\ AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ AUX_SF(AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\ - AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ AUX_SF(AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\ AUX_SF(AUX_SW_DATA, AUX_SW_DATA, mask_sh),\ AUX_SF(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\
From: Emily Deng Emily.Deng@amd.com
[ Upstream commit bb0cd09be45ea457f25fdcbcb3d6cf2230f26c46 ]
When unloading driver after killing some applications, it will hit sdma flush tlb job timeout which is called by ttm_bo_delay_delete. So to avoid the job submit after fence driver fini, call ttm_bo_lock_delayed_workqueue before fence driver fini. And also put drm_sched_fini before waiting fence.
Signed-off-by: Emily Deng Emily.Deng@amd.com Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 76d10f1c579b..7f2689d4b86d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3551,6 +3551,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev) { dev_info(adev->dev, "amdgpu: finishing device.\n"); flush_delayed_work(&adev->delayed_init_work); + ttm_bo_lock_delayed_workqueue(&adev->mman.bdev); adev->shutdown = true;
kfree(adev->pci_state); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index fe2d495d08ab..d07c458c0bed 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -532,6 +532,8 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev)
if (!ring || !ring->fence_drv.initialized) continue; + if (!ring->no_scheduler) + drm_sched_fini(&ring->sched); r = amdgpu_fence_wait_empty(ring); if (r) { /* no need to trigger GPU reset as we are unloading */ @@ -540,8 +542,7 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev) if (ring->fence_drv.irq_src) amdgpu_irq_put(adev, ring->fence_drv.irq_src, ring->fence_drv.irq_type); - if (!ring->no_scheduler) - drm_sched_fini(&ring->sched); + del_timer_sync(&ring->fence_drv.fallback_timer); for (j = 0; j <= ring->fence_drv.num_fences_mask; ++j) dma_fence_put(ring->fence_drv.fences[j]);
From: Obeida Shamoun oshmoun100@googlemail.com
[ Upstream commit cdfd4c689e2a52c313b35ddfc1852ff274f91acb ]
WLED3_SINK_REG_SYNC is, as the name implies, a sink register offset. Therefore, use the sink address as base instead of the ctrl address.
This fixes the sync toggle on wled4, which can be observed by the fact that adjusting brightness now works.
It has no effect on wled3 because sink and ctrl base addresses are the same. This allows adjusting the brightness without having to disable then reenable the module.
Signed-off-by: Obeida Shamoun oshmoun100@googlemail.com Signed-off-by: Konrad Dybcio konrad.dybcio@somainline.org Signed-off-by: Marijn Suijten marijn.suijten@somainline.org Reviewed-by: Daniel Thompson daniel.thompson@linaro.org Acked-by: Kiran Gunda kgunda@codeaurora.org Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/video/backlight/qcom-wled.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/backlight/qcom-wled.c b/drivers/video/backlight/qcom-wled.c index 3bc7800eb0a9..83a187fdaa1d 100644 --- a/drivers/video/backlight/qcom-wled.c +++ b/drivers/video/backlight/qcom-wled.c @@ -336,13 +336,13 @@ static int wled3_sync_toggle(struct wled *wled) unsigned int mask = GENMASK(wled->max_string_count - 1, 0);
rc = regmap_update_bits(wled->regmap, - wled->ctrl_addr + WLED3_SINK_REG_SYNC, + wled->sink_addr + WLED3_SINK_REG_SYNC, mask, mask); if (rc < 0) return rc;
rc = regmap_update_bits(wled->regmap, - wled->ctrl_addr + WLED3_SINK_REG_SYNC, + wled->sink_addr + WLED3_SINK_REG_SYNC, mask, WLED3_SINK_REG_SYNC_CLEAR);
return rc;
From: Kiran Gunda kgunda@codeaurora.org
[ Upstream commit 4d6e9cdff7fbb6bef3e5559596fab3eeffaf95ca ]
Currently, for WLED5, the FSC (Full scale current) setting is not updated properly due to driver toggling the wrong register after an FSC update.
On WLED5 we should only toggle the MOD_SYNC bit after a brightness update. For an FSC update we need to toggle the SYNC bits instead.
Fix it by adopting the common wled3_sync_toggle() for WLED5 and introducing new code to the brightness update path to compensate.
Signed-off-by: Kiran Gunda kgunda@codeaurora.org Reviewed-by: Daniel Thompson daniel.thompson@linaro.org Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/video/backlight/qcom-wled.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/drivers/video/backlight/qcom-wled.c b/drivers/video/backlight/qcom-wled.c index 83a187fdaa1d..cd11c5776438 100644 --- a/drivers/video/backlight/qcom-wled.c +++ b/drivers/video/backlight/qcom-wled.c @@ -348,7 +348,7 @@ static int wled3_sync_toggle(struct wled *wled) return rc; }
-static int wled5_sync_toggle(struct wled *wled) +static int wled5_mod_sync_toggle(struct wled *wled) { int rc; u8 val; @@ -445,10 +445,23 @@ static int wled_update_status(struct backlight_device *bl) goto unlock_mutex; }
- rc = wled->wled_sync_toggle(wled); - if (rc < 0) { - dev_err(wled->dev, "wled sync failed rc:%d\n", rc); - goto unlock_mutex; + if (wled->version < 5) { + rc = wled->wled_sync_toggle(wled); + if (rc < 0) { + dev_err(wled->dev, "wled sync failed rc:%d\n", rc); + goto unlock_mutex; + } + } else { + /* + * For WLED5 toggling the MOD_SYNC_BIT updates the + * brightness + */ + rc = wled5_mod_sync_toggle(wled); + if (rc < 0) { + dev_err(wled->dev, "wled mod sync failed rc:%d\n", + rc); + goto unlock_mutex; + } } }
@@ -1459,7 +1472,7 @@ static int wled_configure(struct wled *wled) size = ARRAY_SIZE(wled5_opts); *cfg = wled5_config_defaults; wled->wled_set_brightness = wled5_set_brightness; - wled->wled_sync_toggle = wled5_sync_toggle; + wled->wled_sync_toggle = wled3_sync_toggle; wled->wled_cabc_config = wled5_cabc_config; wled->wled_ovp_delay = wled5_ovp_delay; wled->wled_auto_detection_required =
From: Lyude Paul lyude@redhat.com
[ Upstream commit 9962849d0871f5e53d0e3b3d84561f8f2847fbf4 ]
Since encoder mappings for connectors are exposed to userspace, we should be attaching the encoder before exposing the connector to userspace. Just a drive-by fix for an issue I noticed while fixing up usages of drm_dp_aux_init()/drm_dp_aux_register() across the tree.
Signed-off-by: Lyude Paul lyude@redhat.com Reviewed-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20210219215326.2227596-9-lyude... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c index 81debd02c169..fbfe0cc89ba4 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c +++ b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c @@ -924,12 +924,6 @@ static int anx78xx_bridge_attach(struct drm_bridge *bridge, drm_connector_helper_add(&anx78xx->connector, &anx78xx_connector_helper_funcs);
- err = drm_connector_register(&anx78xx->connector); - if (err) { - DRM_ERROR("Failed to register connector: %d\n", err); - return err; - } - anx78xx->connector.polled = DRM_CONNECTOR_POLL_HPD;
err = drm_connector_attach_encoder(&anx78xx->connector, @@ -939,6 +933,12 @@ static int anx78xx_bridge_attach(struct drm_bridge *bridge, return err; }
+ err = drm_connector_register(&anx78xx->connector); + if (err) { + DRM_ERROR("Failed to register connector: %d\n", err); + return err; + } + return 0; }
From: Lyude Paul lyude@redhat.com
[ Upstream commit 212ee8db84600f7b279b8645c62a112bff310995 ]
Just another issue I noticed while correcting usages of drm_dp_aux_init()/drm_dp_aux_register() around the tree. If any of the steps in anx78xx_bridge_attach() fail, we end up leaking resources. So, let's fix that (and fix leaking a DP AUX adapter in the process) by unrolling on errors.
Signed-off-by: Lyude Paul lyude@redhat.com Reviewed-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20210219215326.2227596-10-lyud... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c index fbfe0cc89ba4..bcc778f680a8 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c +++ b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c @@ -918,7 +918,7 @@ static int anx78xx_bridge_attach(struct drm_bridge *bridge, DRM_MODE_CONNECTOR_DisplayPort); if (err) { DRM_ERROR("Failed to initialize connector: %d\n", err); - return err; + goto aux_unregister; }
drm_connector_helper_add(&anx78xx->connector, @@ -930,16 +930,21 @@ static int anx78xx_bridge_attach(struct drm_bridge *bridge, bridge->encoder); if (err) { DRM_ERROR("Failed to link up connector to encoder: %d\n", err); - return err; + goto connector_cleanup; }
err = drm_connector_register(&anx78xx->connector); if (err) { DRM_ERROR("Failed to register connector: %d\n", err); - return err; + goto connector_cleanup; }
return 0; +connector_cleanup: + drm_connector_cleanup(&anx78xx->connector); +aux_unregister: + drm_dp_aux_unregister(&anx78xx->aux); + return err; }
static enum drm_mode_status
From: Jonathan Kim jonathan.kim@amd.com
[ Upstream commit 4ac5617c4b7d0f0a8f879997f8ceaa14636d7554 ]
The psp supplies the link type in the upper 2 bits of the psp xgmi node information num_hops field. With a new link type, Aldebaran has these bits set to a non-zero value (1 = xGMI3) so the KFD topology will report the incorrect IO link weights without proper masking. The actual number of hops is located in the 3 least significant bits of this field so mask if off accordingly before passing it to the KFD.
Signed-off-by: Jonathan Kim jonathan.kim@amd.com Reviewed-by: Amber Lin amber.lin@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c index 1162913c8bf4..0526dec1d736 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c @@ -465,15 +465,22 @@ int amdgpu_xgmi_update_topology(struct amdgpu_hive_info *hive, struct amdgpu_dev }
+/* + * NOTE psp_xgmi_node_info.num_hops layout is as follows: + * num_hops[7:6] = link type (0 = xGMI2, 1 = xGMI3, 2/3 = reserved) + * num_hops[5:3] = reserved + * num_hops[2:0] = number of hops + */ int amdgpu_xgmi_get_hops_count(struct amdgpu_device *adev, struct amdgpu_device *peer_adev) { struct psp_xgmi_topology_info *top = &adev->psp.xgmi_context.top_info; + uint8_t num_hops_mask = 0x7; int i;
for (i = 0 ; i < top->num_nodes; ++i) if (top->nodes[i].node_id == peer_adev->gmc.xgmi.node_id) - return top->nodes[i].num_hops; + return top->nodes[i].num_hops & num_hops_mask; return -EINVAL; }
From: Anson Jacob Anson.Jacob@amd.com
[ Upstream commit 50e2fc36e72d4ad672032ebf646cecb48656efe0 ]
If get_num_sdma_queues or get_num_xgmi_sdma_queues is 0, we end up doing a shift operation where the number of bits shifted equals number of bits in the operand. This behaviour is undefined.
Set num_sdma_queues or num_xgmi_sdma_queues to ULLONG_MAX, if the count is >= number of bits in the operand.
Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1472
Reported-by: Lyude Paul lyude@redhat.com Signed-off-by: Anson Jacob Anson.Jacob@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com Reviewed-by: Felix Kuehling Felix.Kuehling@amd.com Tested-by: Lyude Paul lyude@redhat.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../drm/amd/amdkfd/kfd_device_queue_manager.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 8e5cfb1f8a51..6ea8a4b6efde 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -1128,6 +1128,9 @@ static int set_sched_resources(struct device_queue_manager *dqm)
static int initialize_cpsch(struct device_queue_manager *dqm) { + uint64_t num_sdma_queues; + uint64_t num_xgmi_sdma_queues; + pr_debug("num of pipes: %d\n", get_pipes_per_mec(dqm));
mutex_init(&dqm->lock_hidden); @@ -1136,8 +1139,18 @@ static int initialize_cpsch(struct device_queue_manager *dqm) dqm->active_cp_queue_count = 0; dqm->gws_queue_count = 0; dqm->active_runlist = false; - dqm->sdma_bitmap = ~0ULL >> (64 - get_num_sdma_queues(dqm)); - dqm->xgmi_sdma_bitmap = ~0ULL >> (64 - get_num_xgmi_sdma_queues(dqm)); + + num_sdma_queues = get_num_sdma_queues(dqm); + if (num_sdma_queues >= BITS_PER_TYPE(dqm->sdma_bitmap)) + dqm->sdma_bitmap = ULLONG_MAX; + else + dqm->sdma_bitmap = (BIT_ULL(num_sdma_queues) - 1); + + num_xgmi_sdma_queues = get_num_xgmi_sdma_queues(dqm); + if (num_xgmi_sdma_queues >= BITS_PER_TYPE(dqm->xgmi_sdma_bitmap)) + dqm->xgmi_sdma_bitmap = ULLONG_MAX; + else + dqm->xgmi_sdma_bitmap = (BIT_ULL(num_xgmi_sdma_queues) - 1);
INIT_WORK(&dqm->hw_exception_work, kfd_process_hw_exception);
From: shaoyunl shaoyun.liu@amd.com
[ Upstream commit c8941550aa66b2a90f4b32c45d59e8571e33336e ]
This recent change introduce SDMA interrupt info printing with irq->process function. These functions do not require a set function to enable/disable the irq
Signed-off-by: shaoyunl shaoyun.liu@amd.com Reviewed-by: Hawking Zhang Hawking.Zhang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 300ac73b4738..2f70fdd6104f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -499,7 +499,7 @@ void amdgpu_irq_gpu_reset_resume_helper(struct amdgpu_device *adev) for (j = 0; j < AMDGPU_MAX_IRQ_SRC_ID; ++j) { struct amdgpu_irq_src *src = adev->irq.client[i].sources[j];
- if (!src) + if (!src || !src->funcs || !src->funcs->set) continue; for (k = 0; k < src->num_types; k++) amdgpu_irq_update(adev, src, k);
From: Kenneth Feng kenneth.feng@amd.com
[ Upstream commit 0979d43259e13846d86ba17e451e17fec185d240 ]
Workload number mapped to the correct one. This issue is only on vega10.
Signed-off-by: Kenneth Feng kenneth.feng@amd.com Reviewed-by: Kevin Wang kevin1.wang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c index ed4eafc744d3..132c269c7c89 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c @@ -5159,7 +5159,7 @@ static int vega10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui
out: smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetWorkloadMask, - 1 << power_profile_mode, + (!power_profile_mode) ? 0 : 1 << (power_profile_mode - 1), NULL); hwmgr->power_profile_mode = power_profile_mode;
From: Anson Jacob Anson.Jacob@amd.com
[ Upstream commit 6a30a92997eee49554f72b462dce90abe54a496f ]
[Why] dc_cursor_position do not initialise position.translate_by_source when crtc or plane->state->fb is NULL. UBSAN caught this error in dce110_set_cursor_position, as the value was garbage.
[How] Initialise dc_cursor_position structure elements to 0 in handle_cursor_update before calling get_cursor_position.
Tested-by: Daniel Wheeler daniel.wheeler@amd.com Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1471 Reported-by: Lyude Paul lyude@redhat.com Signed-off-by: Anson Jacob Anson.Jacob@amd.com Reviewed-by: Aurabindo Jayamohanan Pillai Aurabindo.Pillai@amd.com Acked-by: Solomon Chiu solomon.chiu@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 830d302be045..12a4f0675fb0 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6800,10 +6800,6 @@ static int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc, int x, y; int xorigin = 0, yorigin = 0;
- position->enable = false; - position->x = 0; - position->y = 0; - if (!crtc || !plane->state->fb) return 0;
@@ -6850,7 +6846,7 @@ static void handle_cursor_update(struct drm_plane *plane, struct dm_crtc_state *crtc_state = crtc ? to_dm_crtc_state(crtc->state) : NULL; struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); uint64_t address = afb ? afb->address : 0; - struct dc_cursor_position position; + struct dc_cursor_position position = {0}; struct dc_cursor_attributes attributes; int ret;
From: Aric Cyr aric.cyr@amd.com
[ Upstream commit 4710430a779e6077d81218ac768787545bff8c49 ]
[Why] When unplugging a display, the underflow counter can be seen to increase because PSTATE switch is allowed even when some planes are not blanked.
[How] Check that all planes are not active instead of all streams before allowing PSTATE change.
Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Aric Cyr aric.cyr@amd.com Acked-by: Solomon Chiu solomon.chiu@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c index 95d883482227..cab47bb21172 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c @@ -240,6 +240,7 @@ static void dcn3_update_clocks(struct clk_mgr *clk_mgr_base, bool force_reset = false; bool update_uclk = false; bool p_state_change_support; + int total_plane_count;
if (dc->work_arounds.skip_clock_update || !clk_mgr->smu_present) return; @@ -280,7 +281,8 @@ static void dcn3_update_clocks(struct clk_mgr *clk_mgr_base, clk_mgr_base->clks.socclk_khz = new_clocks->socclk_khz;
clk_mgr_base->clks.prev_p_state_change_support = clk_mgr_base->clks.p_state_change_support; - p_state_change_support = new_clocks->p_state_change_support || (display_count == 0); + total_plane_count = clk_mgr_helper_get_active_plane_cnt(dc, context); + p_state_change_support = new_clocks->p_state_change_support || (total_plane_count == 0); if (should_update_pstate_support(safe_to_lower, p_state_change_support, clk_mgr_base->clks.p_state_change_support)) { clk_mgr_base->clks.p_state_change_support = p_state_change_support;
From: Dmytro Laktyushkin Dmytro.Laktyushkin@amd.com
[ Upstream commit 8ee0fea4baf90e43efe2275de208a7809f9985bc ]
Incorrect variable used, missing initialization during validation.
Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Dmytro Laktyushkin Dmytro.Laktyushkin@amd.com Reviewed-by: Eric Bernstein Eric.Bernstein@amd.com Acked-by: Solomon Chiu solomon.chiu@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c | 1 + drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c | 1 + 2 files changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c index 45f028986a8d..b3f0476899d3 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c @@ -3437,6 +3437,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l mode_lib->vba.DCCEnabledInAnyPlane = true; } } + mode_lib->vba.UrgentLatency = mode_lib->vba.UrgentLatencyPixelDataOnly; for (i = 0; i <= mode_lib->vba.soc.num_states; i++) { locals->FabricAndDRAMBandwidthPerState[i] = dml_min( mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c index 80170f9721ce..1bcda7eba4a6 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c @@ -3510,6 +3510,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode mode_lib->vba.DCCEnabledInAnyPlane = true; } } + mode_lib->vba.UrgentLatency = mode_lib->vba.UrgentLatencyPixelDataOnly; for (i = 0; i <= mode_lib->vba.soc.num_states; i++) { locals->FabricAndDRAMBandwidthPerState[i] = dml_min( mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels
From: Dmitry Vyukov dvyukov@google.com
[ Upstream commit b4142fc4d52d051d4d8df1fb6c569e5b445d369e ]
vkms_vblank_simulate() uses WARN_ON for timing-dependent condition (timer overrun). This is a mis-use of WARN_ON, WARN_ON must be used to denote kernel bugs. Use pr_warn() instead.
Signed-off-by: Dmitry Vyukov dvyukov@google.com Reported-by: syzbot+4fc21a003c8332eb0bdd@syzkaller.appspotmail.com Cc: Rodrigo Siqueira rodrigosiqueiramelo@gmail.com Cc: Melissa Wen melissa.srw@gmail.com Cc: Haneen Mohammed hamohammed.sa@gmail.com Cc: Daniel Vetter daniel@ffwll.ch Cc: David Airlie airlied@linux.ie Cc: dri-devel@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org Acked-by: Melissa Wen melissa.srw@gmail.com Signed-off-by: Melissa Wen melissa.srw@gmail.com Link: https://patchwork.freedesktop.org/patch/msgid/20210320132840.1315853-1-dvyuk... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vkms/vkms_crtc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index 09c012d54d58..1ae5cd47d954 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -18,7 +18,8 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer, output->period_ns); - WARN_ON(ret_overrun != 1); + if (ret_overrun != 1) + pr_warn("%s: vblank timer overrun\n", __func__);
spin_lock(&output->lock); ret = drm_crtc_handle_vblank(crtc);
dri-devel@lists.freedesktop.org