]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 12 Mar 2021 13:39:13 +0000 (14:39 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 12 Mar 2021 13:39:13 +0000 (14:39 +0100)
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

12 files changed:
queue-5.10/drm-amd-display-add-a-backlight-module-option.patch [new file with mode: 0644]
queue-5.10/drm-amd-display-fix-nested-fpu-context-in-dcn21_validate_bandwidth.patch [new file with mode: 0644]
queue-5.10/drm-amd-pm-bug-fix-for-pcie-dpm.patch [new file with mode: 0644]
queue-5.10/drm-amdgpu-display-don-t-assert-in-set-backlight-function.patch [new file with mode: 0644]
queue-5.10/drm-amdgpu-display-handle-aux-backlight-in-backlight_get_brightness.patch [new file with mode: 0644]
queue-5.10/drm-amdgpu-display-simplify-backlight-setting.patch [new file with mode: 0644]
queue-5.10/drm-amdgpu-display-use-gfp_atomic-in-dcn21_validate_bandwidth_fp.patch [new file with mode: 0644]
queue-5.10/drm-compat-clear-bounce-structures.patch [new file with mode: 0644]
queue-5.10/drm-shmem-helper-check-for-purged-buffers-in-fault-handler.patch [new file with mode: 0644]
queue-5.10/drm-shmem-helper-don-t-remove-the-offset-in-vm_area_struct-pgoff.patch [new file with mode: 0644]
queue-5.10/drm-use-usb-controller-s-dma-mask-when-importing-dmabufs.patch [new file with mode: 0644]
queue-5.10/series

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 (file)
index 0000000..54e4430
--- /dev/null
@@ -0,0 +1,68 @@
+From 7a46f05e5e163c00e41892e671294286e53fe15c Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Wed, 3 Feb 2021 13:42:41 +0100
+Subject: drm/amd/display: Add a backlight module option
+
+From: Takashi Iwai <tiwai@suse.de>
+
+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 <nicholas.kazlauskas@amd.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..4a18b81
--- /dev/null
@@ -0,0 +1,60 @@
+From 15e8b95d5f7509e0b09289be8c422c459c9f0412 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Holger=20Hoffst=C3=A4tte?= <holger@applied-asynchrony.com>
+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 <holger@applied-asynchrony.com>
+
+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 <holger@applied-asynchrony.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..ff007d1
--- /dev/null
@@ -0,0 +1,258 @@
+From 50ceb1fe7acd50831180f4b5597bf7b39e8059c8 Mon Sep 17 00:00:00 2001
+From: Kenneth Feng <kenneth.feng@amd.com>
+Date: Tue, 9 Mar 2021 21:10:16 +0800
+Subject: drm/amd/pm: bug fix for pcie dpm
+
+From: Kenneth Feng <kenneth.feng@amd.com>
+
+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 <kenneth.feng@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..8630b0e
--- /dev/null
@@ -0,0 +1,29 @@
+From dfd8b7fbd985ec1cf76fe10f2875a50b10833740 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Thu, 10 Dec 2020 01:20:08 -0500
+Subject: drm/amdgpu/display: don't assert in set backlight function
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit dfd8b7fbd985ec1cf76fe10f2875a50b10833740 upstream.
+
+It just spams the logs.
+
+Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..49d88c7
--- /dev/null
@@ -0,0 +1,53 @@
+From 0ad3e64eb46d8c47de3af552e282894e3893e973 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Thu, 10 Dec 2020 01:45:12 -0500
+Subject: drm/amdgpu/display: handle aux backlight in backlight_get_brightness
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 0ad3e64eb46d8c47de3af552e282894e3893e973 upstream.
+
+Need to fetch it via aux.
+
+Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..7cf0297
--- /dev/null
@@ -0,0 +1,55 @@
+From a2f8d988698d7d3645b045f4940415b045140b81 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Thu, 10 Dec 2020 01:18:40 -0500
+Subject: drm/amdgpu/display: simplify backlight setting
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit a2f8d988698d7d3645b045f4940415b045140b81 upstream.
+
+Avoid the extra wrapper function.
+
+Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..3897778
--- /dev/null
@@ -0,0 +1,37 @@
+From 680174cfd1e1cea70a8f30ccb44d8fbdf996018e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Holger=20Hoffst=C3=A4tte?= <holger@applied-asynchrony.com>
+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 <holger@applied-asynchrony.com>
+
+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 <holger@applied-asynchrony.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..ccddf46
--- /dev/null
@@ -0,0 +1,79 @@
+From de066e116306baf3a6a62691ac63cfc0b1dabddb Mon Sep 17 00:00:00 2001
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+Date: Mon, 22 Feb 2021 11:06:43 +0100
+Subject: drm/compat: Clear bounce structures
+
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+
+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 <mripard@kernel.org>
+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 <daniel.vetter@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210222100643.400935-1-daniel.vetter@ffwll.ch
+(cherry picked from commit e926c474ebee404441c838d18224cd6f246a71b7)
+Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..5857322
--- /dev/null
@@ -0,0 +1,56 @@
+From d611b4a0907cece060699f2fd347c492451cd2aa Mon Sep 17 00:00:00 2001
+From: Neil Roberts <nroberts@igalia.com>
+Date: Tue, 23 Feb 2021 16:51:24 +0100
+Subject: drm/shmem-helper: Check for purged buffers in fault handler
+
+From: Neil Roberts <nroberts@igalia.com>
+
+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 <nroberts@igalia.com>
+Reviewed-by: Steven Price <steven.price@arm.com>
+Signed-off-by: Steven Price <steven.price@arm.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210223155125.199577-2-nroberts@igalia.com
+Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..4cafc43
--- /dev/null
@@ -0,0 +1,74 @@
+From 11d5a4745e00e73745774671dbf2fb07bd6e2363 Mon Sep 17 00:00:00 2001
+From: Neil Roberts <nroberts@igalia.com>
+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 <nroberts@igalia.com>
+
+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 <nroberts@igalia.com>
+Reviewed-by: Steven Price <steven.price@arm.com>
+Signed-off-by: Steven Price <steven.price@arm.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210223155125.199577-3-nroberts@igalia.com
+Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..585b1c8
--- /dev/null
@@ -0,0 +1,347 @@
+From 659ab7a49cbebe0deffcbe1f9560e82006b21817 Mon Sep 17 00:00:00 2001
+From: Thomas Zimmermann <tzimmermann@suse.de>
+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 <tzimmermann@suse.de>
+
+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 <tzimmermann@suse.de>
+Fixes: 6eb0233ec2d0 ("usb: don't inherity DMA properties for USB devices")
+Tested-by: Pavel Machek <pavel@ucw.cz>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Christian König <christian.koenig@amd.com>
+Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Acked-by: Noralf Trønnes <noralf@tronnes.org>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: <stable@vger.kernel.org> # v5.10+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210303133229.3288-1-tzimmermann@suse.de
+Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 <tzimmermann@suse.de>, 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);
index 1c7d99d90d15a56abb88d435618cd337f046fab7..7b229a036caeec675fc9b7414f650522464521ba 100644 (file)
@@ -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