From: Greg Kroah-Hartman Date: Fri, 12 Mar 2021 13:39:13 +0000 (+0100) Subject: 5.10-stable patches X-Git-Tag: v4.4.262~88 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bf8622d3cdac61e681f297de8cdeb2ea5b1744f5;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: drm-amd-display-add-a-backlight-module-option.patch drm-amd-display-fix-nested-fpu-context-in-dcn21_validate_bandwidth.patch drm-amd-pm-bug-fix-for-pcie-dpm.patch drm-amdgpu-display-don-t-assert-in-set-backlight-function.patch drm-amdgpu-display-handle-aux-backlight-in-backlight_get_brightness.patch drm-amdgpu-display-simplify-backlight-setting.patch drm-amdgpu-display-use-gfp_atomic-in-dcn21_validate_bandwidth_fp.patch drm-compat-clear-bounce-structures.patch drm-shmem-helper-check-for-purged-buffers-in-fault-handler.patch drm-shmem-helper-don-t-remove-the-offset-in-vm_area_struct-pgoff.patch drm-use-usb-controller-s-dma-mask-when-importing-dmabufs.patch --- diff --git a/queue-5.10/drm-amd-display-add-a-backlight-module-option.patch b/queue-5.10/drm-amd-display-add-a-backlight-module-option.patch new file mode 100644 index 00000000000..54e44305b44 --- /dev/null +++ b/queue-5.10/drm-amd-display-add-a-backlight-module-option.patch @@ -0,0 +1,68 @@ +From 7a46f05e5e163c00e41892e671294286e53fe15c Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Wed, 3 Feb 2021 13:42:41 +0100 +Subject: drm/amd/display: Add a backlight module option + +From: Takashi Iwai + +commit 7a46f05e5e163c00e41892e671294286e53fe15c upstream. + +There seem devices that don't work with the aux channel backlight +control. For allowing such users to test with the other backlight +control method, provide a new module option, aux_backlight, to specify +enabling or disabling the aux backport support explicitly. As +default, the aux support is detected by the hardware capability. + +v2: make the backlight option generic in case we add future +backlight types (Alex) + +BugLink: https://bugzilla.opensuse.org/show_bug.cgi?id=1180749 +BugLink: https://gitlab.freedesktop.org/drm/amd/-/issues/1438 +Reviewed-by: Nicholas Kazlauskas +Signed-off-by: Takashi Iwai +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 ++++ + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +++++ + 3 files changed, 10 insertions(+) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +@@ -178,6 +178,7 @@ extern uint amdgpu_smu_memory_pool_size; + extern uint amdgpu_dc_feature_mask; + extern uint amdgpu_dc_debug_mask; + extern uint amdgpu_dm_abm_level; ++extern int amdgpu_backlight; + extern struct amdgpu_mgpu_info mgpu_info; + extern int amdgpu_ras_enable; + extern uint amdgpu_ras_mask; +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -768,6 +768,10 @@ uint amdgpu_dm_abm_level = 0; + MODULE_PARM_DESC(abmlevel, "ABM level (0 = off (default), 1-4 = backlight reduction level) "); + module_param_named(abmlevel, amdgpu_dm_abm_level, uint, 0444); + ++int amdgpu_backlight = -1; ++MODULE_PARM_DESC(backlight, "Backlight control (0 = pwm, 1 = aux, -1 auto (default))"); ++module_param_named(backlight, amdgpu_backlight, bint, 0444); ++ + /** + * DOC: tmz (int) + * Trusted Memory Zone (TMZ) is a method to protect data being written +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -2140,6 +2140,11 @@ static void update_connector_ext_caps(st + caps->ext_caps->bits.hdr_aux_backlight_control == 1) + caps->aux_support = true; + ++ if (amdgpu_backlight == 0) ++ caps->aux_support = false; ++ else if (amdgpu_backlight == 1) ++ caps->aux_support = true; ++ + /* From the specification (CTA-861-G), for calculating the maximum + * luminance we need to use: + * Luminance = 50*2**(CV/32) diff --git a/queue-5.10/drm-amd-display-fix-nested-fpu-context-in-dcn21_validate_bandwidth.patch b/queue-5.10/drm-amd-display-fix-nested-fpu-context-in-dcn21_validate_bandwidth.patch new file mode 100644 index 00000000000..4a18b81f5c3 --- /dev/null +++ b/queue-5.10/drm-amd-display-fix-nested-fpu-context-in-dcn21_validate_bandwidth.patch @@ -0,0 +1,60 @@ +From 15e8b95d5f7509e0b09289be8c422c459c9f0412 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Holger=20Hoffst=C3=A4tte?= +Date: Fri, 5 Mar 2021 12:39:21 +0100 +Subject: drm/amd/display: Fix nested FPU context in dcn21_validate_bandwidth() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Holger Hoffstätte + +commit 15e8b95d5f7509e0b09289be8c422c459c9f0412 upstream. + +Commit 41401ac67791 added FPU wrappers to dcn21_validate_bandwidth(), +which was correct. Unfortunately a nested function alredy contained +DC_FP_START()/DC_FP_END() calls, which results in nested FPU context +enter/exit and complaints by kernel_fpu_begin_mask(). +This can be observed e.g. with 5.10.20, which backported 41401ac67791 +and now emits the following warning on boot: + +WARNING: CPU: 6 PID: 858 at arch/x86/kernel/fpu/core.c:129 kernel_fpu_begin_mask+0xa5/0xc0 +Call Trace: + dcn21_calculate_wm+0x47/0xa90 [amdgpu] + dcn21_validate_bandwidth_fp+0x15d/0x2b0 [amdgpu] + dcn21_validate_bandwidth+0x29/0x40 [amdgpu] + dc_validate_global_state+0x3c7/0x4c0 [amdgpu] + +The warning is emitted due to the additional DC_FP_START/END calls in +patch_bounding_box(), which is inlined into dcn21_calculate_wm(), +its only caller. Removing the calls brings the code in line with +dcn20 and makes the warning disappear. + +Fixes: 41401ac67791 ("drm/amd/display: Add FPU wrappers to dcn21_validate_bandwidth()") +Signed-off-by: Holger Hoffstätte +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c | 4 ---- + 1 file changed, 4 deletions(-) + +--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +@@ -1058,8 +1058,6 @@ static void patch_bounding_box(struct dc + { + int i; + +- DC_FP_START(); +- + if (dc->bb_overrides.sr_exit_time_ns) { + for (i = 0; i < WM_SET_COUNT; i++) { + dc->clk_mgr->bw_params->wm_table.entries[i].sr_exit_time_us = +@@ -1084,8 +1082,6 @@ static void patch_bounding_box(struct dc + dc->bb_overrides.dram_clock_change_latency_ns / 1000.0; + } + } +- +- DC_FP_END(); + } + + void dcn21_calculate_wm( diff --git a/queue-5.10/drm-amd-pm-bug-fix-for-pcie-dpm.patch b/queue-5.10/drm-amd-pm-bug-fix-for-pcie-dpm.patch new file mode 100644 index 00000000000..ff007d15b38 --- /dev/null +++ b/queue-5.10/drm-amd-pm-bug-fix-for-pcie-dpm.patch @@ -0,0 +1,258 @@ +From 50ceb1fe7acd50831180f4b5597bf7b39e8059c8 Mon Sep 17 00:00:00 2001 +From: Kenneth Feng +Date: Tue, 9 Mar 2021 21:10:16 +0800 +Subject: drm/amd/pm: bug fix for pcie dpm + +From: Kenneth Feng + +commit 50ceb1fe7acd50831180f4b5597bf7b39e8059c8 upstream. + +Currently the pcie dpm has two problems. +1. Only the high dpm level speed/width can be overrided +if the requested values are out of the pcie capability. +2. The high dpm level is always overrided though sometimes +it's not necesarry. + +Signed-off-by: Kenneth Feng +Reviewed-by: Alex Deucher +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 48 +++++++++++++ + drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c | 66 ++++++++++++++++++ + drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c | 48 +++++++------ + 3 files changed, 141 insertions(+), 21 deletions(-) + +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +@@ -1506,6 +1506,48 @@ static int vega10_populate_single_lclk_l + return 0; + } + ++static int vega10_override_pcie_parameters(struct pp_hwmgr *hwmgr) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); ++ struct vega10_hwmgr *data = ++ (struct vega10_hwmgr *)(hwmgr->backend); ++ uint32_t pcie_gen = 0, pcie_width = 0; ++ PPTable_t *pp_table = &(data->smc_state_table.pp_table); ++ int i; ++ ++ if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) ++ pcie_gen = 3; ++ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) ++ pcie_gen = 2; ++ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) ++ pcie_gen = 1; ++ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1) ++ pcie_gen = 0; ++ ++ if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16) ++ pcie_width = 6; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12) ++ pcie_width = 5; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8) ++ pcie_width = 4; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4) ++ pcie_width = 3; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2) ++ pcie_width = 2; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1) ++ pcie_width = 1; ++ ++ for (i = 0; i < NUM_LINK_LEVELS; i++) { ++ if (pp_table->PcieGenSpeed[i] > pcie_gen) ++ pp_table->PcieGenSpeed[i] = pcie_gen; ++ ++ if (pp_table->PcieLaneCount[i] > pcie_width) ++ pp_table->PcieLaneCount[i] = pcie_width; ++ } ++ ++ return 0; ++} ++ + static int vega10_populate_smc_link_levels(struct pp_hwmgr *hwmgr) + { + int result = -1; +@@ -2557,6 +2599,11 @@ static int vega10_init_smc_table(struct + "Failed to initialize Link Level!", + return result); + ++ result = vega10_override_pcie_parameters(hwmgr); ++ PP_ASSERT_WITH_CODE(!result, ++ "Failed to override pcie parameters!", ++ return result); ++ + result = vega10_populate_all_graphic_levels(hwmgr); + PP_ASSERT_WITH_CODE(!result, + "Failed to initialize Graphics Level!", +@@ -2923,6 +2970,7 @@ static int vega10_start_dpm(struct pp_hw + return 0; + } + ++ + static int vega10_enable_disable_PCC_limit_feature(struct pp_hwmgr *hwmgr, bool enable) + { + struct vega10_hwmgr *data = hwmgr->backend; +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c +@@ -481,6 +481,67 @@ static void vega12_init_dpm_state(struct + dpm_state->hard_max_level = 0xffff; + } + ++static int vega12_override_pcie_parameters(struct pp_hwmgr *hwmgr) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); ++ struct vega12_hwmgr *data = ++ (struct vega12_hwmgr *)(hwmgr->backend); ++ uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg, pcie_gen_arg, pcie_width_arg; ++ PPTable_t *pp_table = &(data->smc_state_table.pp_table); ++ int i; ++ int ret; ++ ++ if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) ++ pcie_gen = 3; ++ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) ++ pcie_gen = 2; ++ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) ++ pcie_gen = 1; ++ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1) ++ pcie_gen = 0; ++ ++ if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16) ++ pcie_width = 6; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12) ++ pcie_width = 5; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8) ++ pcie_width = 4; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4) ++ pcie_width = 3; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2) ++ pcie_width = 2; ++ else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1) ++ pcie_width = 1; ++ ++ /* Bit 31:16: LCLK DPM level. 0 is DPM0, and 1 is DPM1 ++ * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4 ++ * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 ++ */ ++ for (i = 0; i < NUM_LINK_LEVELS; i++) { ++ pcie_gen_arg = (pp_table->PcieGenSpeed[i] > pcie_gen) ? pcie_gen : ++ pp_table->PcieGenSpeed[i]; ++ pcie_width_arg = (pp_table->PcieLaneCount[i] > pcie_width) ? pcie_width : ++ pp_table->PcieLaneCount[i]; ++ ++ if (pcie_gen_arg != pp_table->PcieGenSpeed[i] || pcie_width_arg != ++ pp_table->PcieLaneCount[i]) { ++ smu_pcie_arg = (i << 16) | (pcie_gen_arg << 8) | pcie_width_arg; ++ ret = smum_send_msg_to_smc_with_parameter(hwmgr, ++ PPSMC_MSG_OverridePcieParameters, smu_pcie_arg, ++ NULL); ++ PP_ASSERT_WITH_CODE(!ret, ++ "[OverridePcieParameters] Attempt to override pcie params failed!", ++ return ret); ++ } ++ ++ /* update the pptable */ ++ pp_table->PcieGenSpeed[i] = pcie_gen_arg; ++ pp_table->PcieLaneCount[i] = pcie_width_arg; ++ } ++ ++ return 0; ++} ++ + static int vega12_get_number_of_dpm_level(struct pp_hwmgr *hwmgr, + PPCLK_e clk_id, uint32_t *num_of_levels) + { +@@ -969,6 +1030,11 @@ static int vega12_enable_dpm_tasks(struc + "Failed to enable all smu features!", + return result); + ++ result = vega12_override_pcie_parameters(hwmgr); ++ PP_ASSERT_WITH_CODE(!result, ++ "[EnableDPMTasks] Failed to override pcie parameters!", ++ return result); ++ + tmp_result = vega12_power_control_set_level(hwmgr); + PP_ASSERT_WITH_CODE(!tmp_result, + "Failed to power control set level!", +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +@@ -832,7 +832,9 @@ static int vega20_override_pcie_paramete + struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); + struct vega20_hwmgr *data = + (struct vega20_hwmgr *)(hwmgr->backend); +- uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg; ++ uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg, pcie_gen_arg, pcie_width_arg; ++ PPTable_t *pp_table = &(data->smc_state_table.pp_table); ++ int i; + int ret; + + if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) +@@ -861,17 +863,27 @@ static int vega20_override_pcie_paramete + * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4 + * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 + */ +- smu_pcie_arg = (1 << 16) | (pcie_gen << 8) | pcie_width; +- ret = smum_send_msg_to_smc_with_parameter(hwmgr, +- PPSMC_MSG_OverridePcieParameters, smu_pcie_arg, +- NULL); +- PP_ASSERT_WITH_CODE(!ret, +- "[OverridePcieParameters] Attempt to override pcie params failed!", +- return ret); ++ for (i = 0; i < NUM_LINK_LEVELS; i++) { ++ pcie_gen_arg = (pp_table->PcieGenSpeed[i] > pcie_gen) ? pcie_gen : ++ pp_table->PcieGenSpeed[i]; ++ pcie_width_arg = (pp_table->PcieLaneCount[i] > pcie_width) ? pcie_width : ++ pp_table->PcieLaneCount[i]; ++ ++ if (pcie_gen_arg != pp_table->PcieGenSpeed[i] || pcie_width_arg != ++ pp_table->PcieLaneCount[i]) { ++ smu_pcie_arg = (i << 16) | (pcie_gen_arg << 8) | pcie_width_arg; ++ ret = smum_send_msg_to_smc_with_parameter(hwmgr, ++ PPSMC_MSG_OverridePcieParameters, smu_pcie_arg, ++ NULL); ++ PP_ASSERT_WITH_CODE(!ret, ++ "[OverridePcieParameters] Attempt to override pcie params failed!", ++ return ret); ++ } + +- data->pcie_parameters_override = true; +- data->pcie_gen_level1 = pcie_gen; +- data->pcie_width_level1 = pcie_width; ++ /* update the pptable */ ++ pp_table->PcieGenSpeed[i] = pcie_gen_arg; ++ pp_table->PcieLaneCount[i] = pcie_width_arg; ++ } + + return 0; + } +@@ -3320,9 +3332,7 @@ static int vega20_print_clock_levels(str + data->od8_settings.od8_settings_array; + OverDriveTable_t *od_table = + &(data->smc_state_table.overdrive_table); +- struct phm_ppt_v3_information *pptable_information = +- (struct phm_ppt_v3_information *)hwmgr->pptable; +- PPTable_t *pptable = (PPTable_t *)pptable_information->smc_pptable; ++ PPTable_t *pptable = &(data->smc_state_table.pp_table); + struct pp_clock_levels_with_latency clocks; + struct vega20_single_dpm_table *fclk_dpm_table = + &(data->dpm_table.fclk_table); +@@ -3421,13 +3431,9 @@ static int vega20_print_clock_levels(str + current_lane_width = + vega20_get_current_pcie_link_width_level(hwmgr); + for (i = 0; i < NUM_LINK_LEVELS; i++) { +- if (i == 1 && data->pcie_parameters_override) { +- gen_speed = data->pcie_gen_level1; +- lane_width = data->pcie_width_level1; +- } else { +- gen_speed = pptable->PcieGenSpeed[i]; +- lane_width = pptable->PcieLaneCount[i]; +- } ++ gen_speed = pptable->PcieGenSpeed[i]; ++ lane_width = pptable->PcieLaneCount[i]; ++ + size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i, + (gen_speed == 0) ? "2.5GT/s," : + (gen_speed == 1) ? "5.0GT/s," : diff --git a/queue-5.10/drm-amdgpu-display-don-t-assert-in-set-backlight-function.patch b/queue-5.10/drm-amdgpu-display-don-t-assert-in-set-backlight-function.patch new file mode 100644 index 00000000000..8630b0ed00b --- /dev/null +++ b/queue-5.10/drm-amdgpu-display-don-t-assert-in-set-backlight-function.patch @@ -0,0 +1,29 @@ +From dfd8b7fbd985ec1cf76fe10f2875a50b10833740 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Thu, 10 Dec 2020 01:20:08 -0500 +Subject: drm/amdgpu/display: don't assert in set backlight function + +From: Alex Deucher + +commit dfd8b7fbd985ec1cf76fe10f2875a50b10833740 upstream. + +It just spams the logs. + +Reviewed-by: Nicholas Kazlauskas +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/display/dc/core/dc_link.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c +@@ -2555,7 +2555,6 @@ bool dc_link_set_backlight_level(const s + if (pipe_ctx->plane_state == NULL) + frame_ramp = 0; + } else { +- ASSERT(false); + return false; + } + diff --git a/queue-5.10/drm-amdgpu-display-handle-aux-backlight-in-backlight_get_brightness.patch b/queue-5.10/drm-amdgpu-display-handle-aux-backlight-in-backlight_get_brightness.patch new file mode 100644 index 00000000000..49d88c75759 --- /dev/null +++ b/queue-5.10/drm-amdgpu-display-handle-aux-backlight-in-backlight_get_brightness.patch @@ -0,0 +1,53 @@ +From 0ad3e64eb46d8c47de3af552e282894e3893e973 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Thu, 10 Dec 2020 01:45:12 -0500 +Subject: drm/amdgpu/display: handle aux backlight in backlight_get_brightness + +From: Alex Deucher + +commit 0ad3e64eb46d8c47de3af552e282894e3893e973 upstream. + +Need to fetch it via aux. + +Reviewed-by: Nicholas Kazlauskas +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 24 ++++++++++++++++++---- + 1 file changed, 20 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -3116,11 +3116,27 @@ static int amdgpu_dm_backlight_update_st + static int amdgpu_dm_backlight_get_brightness(struct backlight_device *bd) + { + struct amdgpu_display_manager *dm = bl_get_data(bd); +- int ret = dc_link_get_backlight_level(dm->backlight_link); ++ struct amdgpu_dm_backlight_caps caps; + +- if (ret == DC_ERROR_UNEXPECTED) +- return bd->props.brightness; +- return convert_brightness_to_user(&dm->backlight_caps, ret); ++ amdgpu_dm_update_backlight_caps(dm); ++ caps = dm->backlight_caps; ++ ++ if (caps.aux_support) { ++ struct dc_link *link = (struct dc_link *)dm->backlight_link; ++ u32 avg, peak; ++ bool rc; ++ ++ rc = dc_link_get_backlight_level_nits(link, &avg, &peak); ++ if (!rc) ++ return bd->props.brightness; ++ return convert_brightness_to_user(&caps, avg); ++ } else { ++ int ret = dc_link_get_backlight_level(dm->backlight_link); ++ ++ if (ret == DC_ERROR_UNEXPECTED) ++ return bd->props.brightness; ++ return convert_brightness_to_user(&caps, ret); ++ } + } + + static const struct backlight_ops amdgpu_dm_backlight_ops = { diff --git a/queue-5.10/drm-amdgpu-display-simplify-backlight-setting.patch b/queue-5.10/drm-amdgpu-display-simplify-backlight-setting.patch new file mode 100644 index 00000000000..7cf0297e133 --- /dev/null +++ b/queue-5.10/drm-amdgpu-display-simplify-backlight-setting.patch @@ -0,0 +1,55 @@ +From a2f8d988698d7d3645b045f4940415b045140b81 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Thu, 10 Dec 2020 01:18:40 -0500 +Subject: drm/amdgpu/display: simplify backlight setting + +From: Alex Deucher + +commit a2f8d988698d7d3645b045f4940415b045140b81 upstream. + +Avoid the extra wrapper function. + +Reviewed-by: Nicholas Kazlauskas +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 20 ++++---------------- + 1 file changed, 4 insertions(+), 16 deletions(-) + +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -3043,19 +3043,6 @@ static void amdgpu_dm_update_backlight_c + #endif + } + +-static int set_backlight_via_aux(struct dc_link *link, uint32_t brightness) +-{ +- bool rc; +- +- if (!link) +- return 1; +- +- rc = dc_link_set_backlight_level_nits(link, true, brightness, +- AUX_BL_DEFAULT_TRANSITION_TIME_MS); +- +- return rc ? 0 : 1; +-} +- + static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps, + unsigned *min, unsigned *max) + { +@@ -3118,9 +3105,10 @@ static int amdgpu_dm_backlight_update_st + brightness = convert_brightness_from_user(&caps, bd->props.brightness); + // Change brightness based on AUX property + if (caps.aux_support) +- return set_backlight_via_aux(link, brightness); +- +- rc = dc_link_set_backlight_level(dm->backlight_link, brightness, 0); ++ rc = dc_link_set_backlight_level_nits(link, true, brightness, ++ AUX_BL_DEFAULT_TRANSITION_TIME_MS); ++ else ++ rc = dc_link_set_backlight_level(dm->backlight_link, brightness, 0); + + return rc ? 0 : 1; + } diff --git a/queue-5.10/drm-amdgpu-display-use-gfp_atomic-in-dcn21_validate_bandwidth_fp.patch b/queue-5.10/drm-amdgpu-display-use-gfp_atomic-in-dcn21_validate_bandwidth_fp.patch new file mode 100644 index 00000000000..3897778cb93 --- /dev/null +++ b/queue-5.10/drm-amdgpu-display-use-gfp_atomic-in-dcn21_validate_bandwidth_fp.patch @@ -0,0 +1,37 @@ +From 680174cfd1e1cea70a8f30ccb44d8fbdf996018e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Holger=20Hoffst=C3=A4tte?= +Date: Fri, 5 Mar 2021 15:23:18 +0100 +Subject: drm/amdgpu/display: use GFP_ATOMIC in dcn21_validate_bandwidth_fp() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Holger Hoffstätte + +commit 680174cfd1e1cea70a8f30ccb44d8fbdf996018e upstream. + +After fixing nested FPU contexts caused by 41401ac67791 we're still seeing +complaints about spurious kernel_fpu_end(). As it turns out this was +already fixed for dcn20 in commit f41ed88cbd ("drm/amdgpu/display: +use GFP_ATOMIC in dcn20_validate_bandwidth_internal") but never moved +forward to dcn21. + +Signed-off-by: Holger Hoffstätte +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +@@ -1183,7 +1183,7 @@ static noinline bool dcn21_validate_band + int vlevel = 0; + int pipe_split_from[MAX_PIPES]; + int pipe_cnt = 0; +- display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL); ++ display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_ATOMIC); + DC_LOGGER_INIT(dc->ctx->logger); + + BW_VAL_TRACE_COUNT(); diff --git a/queue-5.10/drm-compat-clear-bounce-structures.patch b/queue-5.10/drm-compat-clear-bounce-structures.patch new file mode 100644 index 00000000000..ccddf465097 --- /dev/null +++ b/queue-5.10/drm-compat-clear-bounce-structures.patch @@ -0,0 +1,79 @@ +From de066e116306baf3a6a62691ac63cfc0b1dabddb Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Mon, 22 Feb 2021 11:06:43 +0100 +Subject: drm/compat: Clear bounce structures + +From: Daniel Vetter + +commit de066e116306baf3a6a62691ac63cfc0b1dabddb upstream. + +Some of them have gaps, or fields we don't clear. Native ioctl code +does full copies plus zero-extends on size mismatch, so nothing can +leak. But compat is more hand-rolled so need to be careful. + +None of these matter for performance, so just memset. + +Also I didn't fix up the CONFIG_DRM_LEGACY or CONFIG_DRM_AGP ioctl, those +are security holes anyway. + +Acked-by: Maxime Ripard +Reported-by: syzbot+620cf21140fc7e772a5d@syzkaller.appspotmail.com # vblank ioctl +Cc: syzbot+620cf21140fc7e772a5d@syzkaller.appspotmail.com +Cc: stable@vger.kernel.org +Signed-off-by: Daniel Vetter +Link: https://patchwork.freedesktop.org/patch/msgid/20210222100643.400935-1-daniel.vetter@ffwll.ch +(cherry picked from commit e926c474ebee404441c838d18224cd6f246a71b7) +Signed-off-by: Maarten Lankhorst +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/drm_ioc32.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/gpu/drm/drm_ioc32.c ++++ b/drivers/gpu/drm/drm_ioc32.c +@@ -99,6 +99,8 @@ static int compat_drm_version(struct fil + if (copy_from_user(&v32, (void __user *)arg, sizeof(v32))) + return -EFAULT; + ++ memset(&v, 0, sizeof(v)); ++ + v = (struct drm_version) { + .name_len = v32.name_len, + .name = compat_ptr(v32.name), +@@ -137,6 +139,9 @@ static int compat_drm_getunique(struct f + + if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32))) + return -EFAULT; ++ ++ memset(&uq, 0, sizeof(uq)); ++ + uq = (struct drm_unique){ + .unique_len = uq32.unique_len, + .unique = compat_ptr(uq32.unique), +@@ -265,6 +270,8 @@ static int compat_drm_getclient(struct f + if (copy_from_user(&c32, argp, sizeof(c32))) + return -EFAULT; + ++ memset(&client, 0, sizeof(client)); ++ + client.idx = c32.idx; + + err = drm_ioctl_kernel(file, drm_getclient, &client, 0); +@@ -852,6 +859,8 @@ static int compat_drm_wait_vblank(struct + if (copy_from_user(&req32, argp, sizeof(req32))) + return -EFAULT; + ++ memset(&req, 0, sizeof(req)); ++ + req.request.type = req32.request.type; + req.request.sequence = req32.request.sequence; + req.request.signal = req32.request.signal; +@@ -889,6 +898,8 @@ static int compat_drm_mode_addfb2(struct + struct drm_mode_fb_cmd2 req64; + int err; + ++ memset(&req64, 0, sizeof(req64)); ++ + if (copy_from_user(&req64, argp, + offsetof(drm_mode_fb_cmd232_t, modifier))) + return -EFAULT; diff --git a/queue-5.10/drm-shmem-helper-check-for-purged-buffers-in-fault-handler.patch b/queue-5.10/drm-shmem-helper-check-for-purged-buffers-in-fault-handler.patch new file mode 100644 index 00000000000..58573220822 --- /dev/null +++ b/queue-5.10/drm-shmem-helper-check-for-purged-buffers-in-fault-handler.patch @@ -0,0 +1,56 @@ +From d611b4a0907cece060699f2fd347c492451cd2aa Mon Sep 17 00:00:00 2001 +From: Neil Roberts +Date: Tue, 23 Feb 2021 16:51:24 +0100 +Subject: drm/shmem-helper: Check for purged buffers in fault handler + +From: Neil Roberts + +commit d611b4a0907cece060699f2fd347c492451cd2aa upstream. + +When a buffer is madvised as not needed and then purged, any attempts to +access the buffer from user-space should cause a bus fault. This patch +adds a check for that. + +Cc: stable@vger.kernel.org +Fixes: 17acb9f35ed7 ("drm/shmem: Add madvise state and purge helpers") +Signed-off-by: Neil Roberts +Reviewed-by: Steven Price +Signed-off-by: Steven Price +Link: https://patchwork.freedesktop.org/patch/msgid/20210223155125.199577-2-nroberts@igalia.com +Signed-off-by: Maarten Lankhorst +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -534,14 +534,24 @@ static vm_fault_t drm_gem_shmem_fault(st + struct drm_gem_object *obj = vma->vm_private_data; + struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); + loff_t num_pages = obj->size >> PAGE_SHIFT; ++ vm_fault_t ret; + struct page *page; + +- if (vmf->pgoff >= num_pages || WARN_ON_ONCE(!shmem->pages)) +- return VM_FAULT_SIGBUS; ++ mutex_lock(&shmem->pages_lock); + +- page = shmem->pages[vmf->pgoff]; ++ if (vmf->pgoff >= num_pages || ++ WARN_ON_ONCE(!shmem->pages) || ++ shmem->madv < 0) { ++ ret = VM_FAULT_SIGBUS; ++ } else { ++ page = shmem->pages[vmf->pgoff]; + +- return vmf_insert_page(vma, vmf->address, page); ++ ret = vmf_insert_page(vma, vmf->address, page); ++ } ++ ++ mutex_unlock(&shmem->pages_lock); ++ ++ return ret; + } + + static void drm_gem_shmem_vm_open(struct vm_area_struct *vma) diff --git a/queue-5.10/drm-shmem-helper-don-t-remove-the-offset-in-vm_area_struct-pgoff.patch b/queue-5.10/drm-shmem-helper-don-t-remove-the-offset-in-vm_area_struct-pgoff.patch new file mode 100644 index 00000000000..4cafc43c40a --- /dev/null +++ b/queue-5.10/drm-shmem-helper-don-t-remove-the-offset-in-vm_area_struct-pgoff.patch @@ -0,0 +1,74 @@ +From 11d5a4745e00e73745774671dbf2fb07bd6e2363 Mon Sep 17 00:00:00 2001 +From: Neil Roberts +Date: Tue, 23 Feb 2021 16:51:25 +0100 +Subject: drm/shmem-helper: Don't remove the offset in vm_area_struct pgoff + +From: Neil Roberts + +commit 11d5a4745e00e73745774671dbf2fb07bd6e2363 upstream. + +When mmapping the shmem, it would previously adjust the pgoff in the +vm_area_struct to remove the fake offset that is added to be able to +identify the buffer. This patch removes the adjustment and makes the +fault handler use the vm_fault address to calculate the page offset +instead. Although using this address is apparently discouraged, several +DRM drivers seem to be doing it anyway. + +The problem with removing the pgoff is that it prevents +drm_vma_node_unmap from working because that searches the mapping tree +by address. That doesn't work because all of the mappings are at offset +0. drm_vma_node_unmap is being used by the shmem helpers when purging +the buffer. + +This fixes a bug in Panfrost which is using drm_gem_shmem_purge. Without +this the mapping for the purged buffer can still be accessed which might +mean it would access random pages from other buffers + +v2: Don't check whether the unsigned page_offset is less than 0. + +Cc: stable@vger.kernel.org +Fixes: 17acb9f35ed7 ("drm/shmem: Add madvise state and purge helpers") +Signed-off-by: Neil Roberts +Reviewed-by: Steven Price +Signed-off-by: Steven Price +Link: https://patchwork.freedesktop.org/patch/msgid/20210223155125.199577-3-nroberts@igalia.com +Signed-off-by: Maarten Lankhorst +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -536,15 +536,19 @@ static vm_fault_t drm_gem_shmem_fault(st + loff_t num_pages = obj->size >> PAGE_SHIFT; + vm_fault_t ret; + struct page *page; ++ pgoff_t page_offset; ++ ++ /* We don't use vmf->pgoff since that has the fake offset */ ++ page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT; + + mutex_lock(&shmem->pages_lock); + +- if (vmf->pgoff >= num_pages || ++ if (page_offset >= num_pages || + WARN_ON_ONCE(!shmem->pages) || + shmem->madv < 0) { + ret = VM_FAULT_SIGBUS; + } else { +- page = shmem->pages[vmf->pgoff]; ++ page = shmem->pages[page_offset]; + + ret = vmf_insert_page(vma, vmf->address, page); + } +@@ -600,9 +604,6 @@ int drm_gem_shmem_mmap(struct drm_gem_ob + struct drm_gem_shmem_object *shmem; + int ret; + +- /* Remove the fake offset */ +- vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node); +- + if (obj->import_attach) { + /* Drop the reference drm_gem_mmap_obj() acquired.*/ + drm_gem_object_put(obj); diff --git a/queue-5.10/drm-use-usb-controller-s-dma-mask-when-importing-dmabufs.patch b/queue-5.10/drm-use-usb-controller-s-dma-mask-when-importing-dmabufs.patch new file mode 100644 index 00000000000..585b1c8edb4 --- /dev/null +++ b/queue-5.10/drm-use-usb-controller-s-dma-mask-when-importing-dmabufs.patch @@ -0,0 +1,347 @@ +From 659ab7a49cbebe0deffcbe1f9560e82006b21817 Mon Sep 17 00:00:00 2001 +From: Thomas Zimmermann +Date: Wed, 3 Mar 2021 14:32:29 +0100 +Subject: drm: Use USB controller's DMA mask when importing dmabufs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Zimmermann + +commit 659ab7a49cbebe0deffcbe1f9560e82006b21817 upstream. + +USB devices cannot perform DMA and hence have no dma_mask set in their +device structure. Therefore importing dmabuf into a USB-based driver +fails, which breaks joining and mirroring of display in X11. + +For USB devices, pick the associated USB controller as attachment device. +This allows the DRM import helpers to perform the DMA setup. If the DMA +controller does not support DMA transfers, we're out of luck and cannot +import. Our current USB-based DRM drivers don't use DMA, so the actual +DMA device is not important. + +Tested by joining/mirroring displays of udl and radeon under Gnome/X11. + +v8: + * release dmadev if device initialization fails (Noralf) + * fix commit description (Noralf) +v7: + * fix use-before-init bug in gm12u320 (Dan) +v6: + * implement workaround in DRM drivers and hold reference to + DMA device while USB device is in use + * remove dev_is_usb() (Greg) + * collapse USB helper into usb_intf_get_dma_device() (Alan) + * integrate Daniel's TODO statement (Daniel) + * fix typos (Greg) +v5: + * provide a helper for USB interfaces (Alan) + * add FIXME item to documentation and TODO list (Daniel) +v4: + * implement workaround with USB helper functions (Greg) + * use struct usb_device->bus->sysdev as DMA device (Takashi) +v3: + * drop gem_create_object + * use DMA mask of USB controller, if any (Daniel, Christian, Noralf) +v2: + * move fix to importer side (Christian, Daniel) + * update SHMEM and CMA helpers for new PRIME callbacks + +Signed-off-by: Thomas Zimmermann +Fixes: 6eb0233ec2d0 ("usb: don't inherity DMA properties for USB devices") +Tested-by: Pavel Machek +Reviewed-by: Greg Kroah-Hartman +Acked-by: Christian König +Acked-by: Daniel Vetter +Acked-by: Noralf Trønnes +Cc: Christoph Hellwig +Cc: Greg Kroah-Hartman +Cc: # v5.10+ +Signed-off-by: Thomas Zimmermann +Link: https://patchwork.freedesktop.org/patch/msgid/20210303133229.3288-1-tzimmermann@suse.de +Signed-off-by: Maarten Lankhorst +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/gpu/todo.rst | 21 +++++++++++++++++++ + drivers/gpu/drm/tiny/gm12u320.c | 44 ++++++++++++++++++++++++++++++++-------- + drivers/gpu/drm/udl/udl_drv.c | 17 +++++++++++++++ + drivers/gpu/drm/udl/udl_drv.h | 1 + drivers/gpu/drm/udl/udl_main.c | 10 +++++++++ + drivers/usb/core/usb.c | 32 +++++++++++++++++++++++++++++ + include/linux/usb.h | 2 + + 7 files changed, 119 insertions(+), 8 deletions(-) + +--- a/Documentation/gpu/todo.rst ++++ b/Documentation/gpu/todo.rst +@@ -560,6 +560,27 @@ Some of these date from the very introdu + + Level: Intermediate + ++Remove automatic page mapping from dma-buf importing ++---------------------------------------------------- ++ ++When importing dma-bufs, the dma-buf and PRIME frameworks automatically map ++imported pages into the importer's DMA area. drm_gem_prime_fd_to_handle() and ++drm_gem_prime_handle_to_fd() require that importers call dma_buf_attach() ++even if they never do actual device DMA, but only CPU access through ++dma_buf_vmap(). This is a problem for USB devices, which do not support DMA ++operations. ++ ++To fix the issue, automatic page mappings should be removed from the ++buffer-sharing code. Fixing this is a bit more involved, since the import/export ++cache is also tied to &drm_gem_object.import_attach. Meanwhile we paper over ++this problem for USB devices by fishing out the USB host controller device, as ++long as that supports DMA. Otherwise importing can still needlessly fail. ++ ++Contact: Thomas Zimmermann , Daniel Vetter ++ ++Level: Advanced ++ ++ + Better Testing + ============== + +--- a/drivers/gpu/drm/tiny/gm12u320.c ++++ b/drivers/gpu/drm/tiny/gm12u320.c +@@ -83,6 +83,7 @@ MODULE_PARM_DESC(eco_mode, "Turn on Eco + + struct gm12u320_device { + struct drm_device dev; ++ struct device *dmadev; + struct drm_simple_display_pipe pipe; + struct drm_connector conn; + struct usb_device *udev; +@@ -598,6 +599,22 @@ static const uint64_t gm12u320_pipe_modi + DRM_FORMAT_MOD_INVALID + }; + ++/* ++ * FIXME: Dma-buf sharing requires DMA support by the importing device. ++ * This function is a workaround to make USB devices work as well. ++ * See todo.rst for how to fix the issue in the dma-buf framework. ++ */ ++static struct drm_gem_object *gm12u320_gem_prime_import(struct drm_device *dev, ++ struct dma_buf *dma_buf) ++{ ++ struct gm12u320_device *gm12u320 = to_gm12u320(dev); ++ ++ if (!gm12u320->dmadev) ++ return ERR_PTR(-ENODEV); ++ ++ return drm_gem_prime_import_dev(dev, dma_buf, gm12u320->dmadev); ++} ++ + DEFINE_DRM_GEM_FOPS(gm12u320_fops); + + static struct drm_driver gm12u320_drm_driver = { +@@ -611,6 +628,7 @@ static struct drm_driver gm12u320_drm_dr + + .fops = &gm12u320_fops, + DRM_GEM_SHMEM_DRIVER_OPS, ++ .gem_prime_import = gm12u320_gem_prime_import, + }; + + static const struct drm_mode_config_funcs gm12u320_mode_config_funcs = { +@@ -637,16 +655,19 @@ static int gm12u320_usb_probe(struct usb + struct gm12u320_device, dev); + if (IS_ERR(gm12u320)) + return PTR_ERR(gm12u320); ++ dev = &gm12u320->dev; ++ ++ gm12u320->dmadev = usb_intf_get_dma_device(to_usb_interface(dev->dev)); ++ if (!gm12u320->dmadev) ++ drm_warn(dev, "buffer sharing not supported"); /* not an error */ + + 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 = drmm_mode_config_init(dev); + if (ret) +- return ret; ++ goto err_put_device; + + dev->mode_config.min_width = GM12U320_USER_WIDTH; + dev->mode_config.max_width = GM12U320_USER_WIDTH; +@@ -656,15 +677,15 @@ static int gm12u320_usb_probe(struct usb + + ret = gm12u320_usb_alloc(gm12u320); + if (ret) +- return ret; ++ goto err_put_device; + + ret = gm12u320_set_ecomode(gm12u320); + if (ret) +- return ret; ++ goto err_put_device; + + ret = gm12u320_conn_init(gm12u320); + if (ret) +- return ret; ++ goto err_put_device; + + ret = drm_simple_display_pipe_init(&gm12u320->dev, + &gm12u320->pipe, +@@ -674,24 +695,31 @@ static int gm12u320_usb_probe(struct usb + gm12u320_pipe_modifiers, + &gm12u320->conn); + if (ret) +- return ret; ++ goto err_put_device; + + drm_mode_config_reset(dev); + + usb_set_intfdata(interface, dev); + ret = drm_dev_register(dev, 0); + if (ret) +- return ret; ++ goto err_put_device; + + drm_fbdev_generic_setup(dev, 0); + + return 0; ++ ++err_put_device: ++ put_device(gm12u320->dmadev); ++ return ret; + } + + static void gm12u320_usb_disconnect(struct usb_interface *interface) + { + struct drm_device *dev = usb_get_intfdata(interface); ++ struct gm12u320_device *gm12u320 = to_gm12u320(dev); + ++ put_device(gm12u320->dmadev); ++ gm12u320->dmadev = NULL; + drm_dev_unplug(dev); + drm_atomic_helper_shutdown(dev); + } +--- a/drivers/gpu/drm/udl/udl_drv.c ++++ b/drivers/gpu/drm/udl/udl_drv.c +@@ -32,6 +32,22 @@ static int udl_usb_resume(struct usb_int + return drm_mode_config_helper_resume(dev); + } + ++/* ++ * FIXME: Dma-buf sharing requires DMA support by the importing device. ++ * This function is a workaround to make USB devices work as well. ++ * See todo.rst for how to fix the issue in the dma-buf framework. ++ */ ++static struct drm_gem_object *udl_driver_gem_prime_import(struct drm_device *dev, ++ struct dma_buf *dma_buf) ++{ ++ struct udl_device *udl = to_udl(dev); ++ ++ if (!udl->dmadev) ++ return ERR_PTR(-ENODEV); ++ ++ return drm_gem_prime_import_dev(dev, dma_buf, udl->dmadev); ++} ++ + DEFINE_DRM_GEM_FOPS(udl_driver_fops); + + static struct drm_driver driver = { +@@ -42,6 +58,7 @@ static struct drm_driver driver = { + + .fops = &udl_driver_fops, + DRM_GEM_SHMEM_DRIVER_OPS, ++ .gem_prime_import = udl_driver_gem_prime_import, + + .name = DRIVER_NAME, + .desc = DRIVER_DESC, +--- a/drivers/gpu/drm/udl/udl_drv.h ++++ b/drivers/gpu/drm/udl/udl_drv.h +@@ -50,6 +50,7 @@ struct urb_list { + struct udl_device { + struct drm_device drm; + struct device *dev; ++ struct device *dmadev; + struct usb_device *udev; + + struct drm_simple_display_pipe display_pipe; +--- a/drivers/gpu/drm/udl/udl_main.c ++++ b/drivers/gpu/drm/udl/udl_main.c +@@ -314,6 +314,10 @@ int udl_init(struct udl_device *udl) + + DRM_DEBUG("\n"); + ++ udl->dmadev = usb_intf_get_dma_device(to_usb_interface(dev->dev)); ++ if (!udl->dmadev) ++ drm_warn(dev, "buffer sharing not supported"); /* not an error */ ++ + mutex_init(&udl->gem_lock); + + if (!udl_parse_vendor_descriptor(dev, udl->udev)) { +@@ -342,12 +346,18 @@ int udl_init(struct udl_device *udl) + err: + if (udl->urbs.count) + udl_free_urb_list(dev); ++ put_device(udl->dmadev); + DRM_ERROR("%d\n", ret); + return ret; + } + + int udl_drop_usb(struct drm_device *dev) + { ++ struct udl_device *udl = to_udl(dev); ++ + udl_free_urb_list(dev); ++ put_device(udl->dmadev); ++ udl->dmadev = NULL; ++ + return 0; + } +--- a/drivers/usb/core/usb.c ++++ b/drivers/usb/core/usb.c +@@ -748,6 +748,38 @@ void usb_put_intf(struct usb_interface * + } + EXPORT_SYMBOL_GPL(usb_put_intf); + ++/** ++ * usb_intf_get_dma_device - acquire a reference on the usb interface's DMA endpoint ++ * @intf: the usb interface ++ * ++ * While a USB device cannot perform DMA operations by itself, many USB ++ * controllers can. A call to usb_intf_get_dma_device() returns the DMA endpoint ++ * for the given USB interface, if any. The returned device structure must be ++ * released with put_device(). ++ * ++ * See also usb_get_dma_device(). ++ * ++ * Returns: A reference to the usb interface's DMA endpoint; or NULL if none ++ * exists. ++ */ ++struct device *usb_intf_get_dma_device(struct usb_interface *intf) ++{ ++ struct usb_device *udev = interface_to_usbdev(intf); ++ struct device *dmadev; ++ ++ if (!udev->bus) ++ return NULL; ++ ++ dmadev = get_device(udev->bus->sysdev); ++ if (!dmadev || !dmadev->dma_mask) { ++ put_device(dmadev); ++ return NULL; ++ } ++ ++ return dmadev; ++} ++EXPORT_SYMBOL_GPL(usb_intf_get_dma_device); ++ + /* USB device locking + * + * USB devices and interfaces are locked using the semaphore in their +--- a/include/linux/usb.h ++++ b/include/linux/usb.h +@@ -746,6 +746,8 @@ extern int usb_lock_device_for_reset(str + extern int usb_reset_device(struct usb_device *dev); + extern void usb_queue_reset_device(struct usb_interface *dev); + ++extern struct device *usb_intf_get_dma_device(struct usb_interface *intf); ++ + #ifdef CONFIG_ACPI + extern int usb_acpi_set_power_state(struct usb_device *hdev, int index, + bool enable); diff --git a/queue-5.10/series b/queue-5.10/series index 1c7d99d90d1..7b229a036ca 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -82,3 +82,14 @@ gpiolib-acpi-allow-to-find-gpioint-resource-by-name-and-index.patch gpiolib-read-gpio-line-names-from-a-firmware-node.patch gpio-pca953x-set-irq-type-when-handle-intel-galileo-gen-2.patch gpio-fix-gpio-device-list-corruption.patch +drm-compat-clear-bounce-structures.patch +drm-amd-display-add-a-backlight-module-option.patch +drm-amdgpu-display-use-gfp_atomic-in-dcn21_validate_bandwidth_fp.patch +drm-amd-display-fix-nested-fpu-context-in-dcn21_validate_bandwidth.patch +drm-amd-pm-bug-fix-for-pcie-dpm.patch +drm-amdgpu-display-simplify-backlight-setting.patch +drm-amdgpu-display-don-t-assert-in-set-backlight-function.patch +drm-amdgpu-display-handle-aux-backlight-in-backlight_get_brightness.patch +drm-shmem-helper-check-for-purged-buffers-in-fault-handler.patch +drm-shmem-helper-don-t-remove-the-offset-in-vm_area_struct-pgoff.patch +drm-use-usb-controller-s-dma-mask-when-importing-dmabufs.patch