Commit 29851567 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'drm-fixes-2022-07-12' of git://anongit.freedesktop.org/drm/drm

Pull drm fixes from Dave Airlie:
 "I see you picked up one of the fbdev fixes, this is the other stuff
  that was queued up last week.

  A bit of a scattering of fixes, three for i915, one amdgpu, and a
  couple of panfrost, rockchip, panel and bridge ones.

  amdgpu:
   - Hibernation fix

  dma-buf:
   - fix use after free of fence

  i915:
   - Fix a possible refcount leak in DP MST connector (Hangyu)
   - Fix on loading guc on ADL-N (Daniele)
   - Fix vm use-after-free in vma destruction (Thomas)

  bridge:
   - fsl-ldb : 3 LVDS modesetting fixes

  rockchip:
   - iommu domain fix

  panfrost:
   - fix memory corruption
   - error path fix

  panel:
   - orientation quirk fix for Yoga tablet 2

  ssd130x:
   - fix pre-charge period setting"

* tag 'drm-fixes-2022-07-12' of git://anongit.freedesktop.org/drm/drm:
  drm/ssd130x: Fix pre-charge period setting
  dma-buf: Fix one use-after-free of fence
  drm/i915: Fix vm use-after-free in vma destruction
  drm/i915/guc: ADL-N should use the same GuC FW as ADL-S
  drm/i915: fix a possible refcount leak in intel_dp_add_mst_connector()
  drm/amdgpu/display: disable prefer_shadow for generic fb helpers
  drm/amdgpu: keep fbdev buffers pinned during suspend
  drm/panfrost: Fix shrinker list corruption by madvise IOCTL
  drm/panfrost: Put mapping instead of shmem obj on panfrost_mmu_map_fault_addr() error
  drm/rockchip: Detach from ARM DMA domain in attach_device
  drm/bridge: fsl-ldb: Drop DE signal polarity inversion
  drm/bridge: fsl-ldb: Enable split mode for LVDS dual link
  drm/bridge: fsl-ldb: Fix mode clock rate validation
  drm/aperture: Run fbdev removal before internal helpers
  drm: panel-orientation-quirks: Add quirk for the Lenovo Yoga Tablet 2 830
parents 0d8ba24e 3590b44b
...@@ -343,7 +343,7 @@ void dma_resv_replace_fences(struct dma_resv *obj, uint64_t context, ...@@ -343,7 +343,7 @@ void dma_resv_replace_fences(struct dma_resv *obj, uint64_t context,
if (old->context != context) if (old->context != context)
continue; continue;
dma_resv_list_set(list, i, replacement, usage); dma_resv_list_set(list, i, dma_fence_get(replacement), usage);
dma_fence_put(old); dma_fence_put(old);
} }
} }
......
...@@ -1528,6 +1528,21 @@ bool amdgpu_crtc_get_scanout_position(struct drm_crtc *crtc, ...@@ -1528,6 +1528,21 @@ bool amdgpu_crtc_get_scanout_position(struct drm_crtc *crtc,
stime, etime, mode); stime, etime, mode);
} }
static bool
amdgpu_display_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj)
{
struct drm_device *dev = adev_to_drm(adev);
struct drm_fb_helper *fb_helper = dev->fb_helper;
if (!fb_helper || !fb_helper->buffer)
return false;
if (gem_to_amdgpu_bo(fb_helper->buffer->gem) != robj)
return false;
return true;
}
int amdgpu_display_suspend_helper(struct amdgpu_device *adev) int amdgpu_display_suspend_helper(struct amdgpu_device *adev)
{ {
struct drm_device *dev = adev_to_drm(adev); struct drm_device *dev = adev_to_drm(adev);
...@@ -1563,10 +1578,12 @@ int amdgpu_display_suspend_helper(struct amdgpu_device *adev) ...@@ -1563,10 +1578,12 @@ int amdgpu_display_suspend_helper(struct amdgpu_device *adev)
continue; continue;
} }
robj = gem_to_amdgpu_bo(fb->obj[0]); robj = gem_to_amdgpu_bo(fb->obj[0]);
r = amdgpu_bo_reserve(robj, true); if (!amdgpu_display_robj_is_fb(adev, robj)) {
if (r == 0) { r = amdgpu_bo_reserve(robj, true);
amdgpu_bo_unpin(robj); if (r == 0) {
amdgpu_bo_unreserve(robj); amdgpu_bo_unpin(robj);
amdgpu_bo_unreserve(robj);
}
} }
} }
return 0; return 0;
......
...@@ -496,7 +496,8 @@ static int amdgpu_vkms_sw_init(void *handle) ...@@ -496,7 +496,8 @@ static int amdgpu_vkms_sw_init(void *handle)
adev_to_drm(adev)->mode_config.max_height = YRES_MAX; adev_to_drm(adev)->mode_config.max_height = YRES_MAX;
adev_to_drm(adev)->mode_config.preferred_depth = 24; adev_to_drm(adev)->mode_config.preferred_depth = 24;
adev_to_drm(adev)->mode_config.prefer_shadow = 1; /* disable prefer shadow for now due to hibernation issues */
adev_to_drm(adev)->mode_config.prefer_shadow = 0;
adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base; adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
......
...@@ -2796,7 +2796,8 @@ static int dce_v10_0_sw_init(void *handle) ...@@ -2796,7 +2796,8 @@ static int dce_v10_0_sw_init(void *handle)
adev_to_drm(adev)->mode_config.max_height = 16384; adev_to_drm(adev)->mode_config.max_height = 16384;
adev_to_drm(adev)->mode_config.preferred_depth = 24; adev_to_drm(adev)->mode_config.preferred_depth = 24;
adev_to_drm(adev)->mode_config.prefer_shadow = 1; /* disable prefer shadow for now due to hibernation issues */
adev_to_drm(adev)->mode_config.prefer_shadow = 0;
adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true; adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
......
...@@ -2914,7 +2914,8 @@ static int dce_v11_0_sw_init(void *handle) ...@@ -2914,7 +2914,8 @@ static int dce_v11_0_sw_init(void *handle)
adev_to_drm(adev)->mode_config.max_height = 16384; adev_to_drm(adev)->mode_config.max_height = 16384;
adev_to_drm(adev)->mode_config.preferred_depth = 24; adev_to_drm(adev)->mode_config.preferred_depth = 24;
adev_to_drm(adev)->mode_config.prefer_shadow = 1; /* disable prefer shadow for now due to hibernation issues */
adev_to_drm(adev)->mode_config.prefer_shadow = 0;
adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true; adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
......
...@@ -2673,7 +2673,8 @@ static int dce_v6_0_sw_init(void *handle) ...@@ -2673,7 +2673,8 @@ static int dce_v6_0_sw_init(void *handle)
adev_to_drm(adev)->mode_config.max_width = 16384; adev_to_drm(adev)->mode_config.max_width = 16384;
adev_to_drm(adev)->mode_config.max_height = 16384; adev_to_drm(adev)->mode_config.max_height = 16384;
adev_to_drm(adev)->mode_config.preferred_depth = 24; adev_to_drm(adev)->mode_config.preferred_depth = 24;
adev_to_drm(adev)->mode_config.prefer_shadow = 1; /* disable prefer shadow for now due to hibernation issues */
adev_to_drm(adev)->mode_config.prefer_shadow = 0;
adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true; adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base; adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
......
...@@ -2693,7 +2693,8 @@ static int dce_v8_0_sw_init(void *handle) ...@@ -2693,7 +2693,8 @@ static int dce_v8_0_sw_init(void *handle)
adev_to_drm(adev)->mode_config.max_height = 16384; adev_to_drm(adev)->mode_config.max_height = 16384;
adev_to_drm(adev)->mode_config.preferred_depth = 24; adev_to_drm(adev)->mode_config.preferred_depth = 24;
adev_to_drm(adev)->mode_config.prefer_shadow = 1; /* disable prefer shadow for now due to hibernation issues */
adev_to_drm(adev)->mode_config.prefer_shadow = 0;
adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true; adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
......
...@@ -3822,7 +3822,8 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev) ...@@ -3822,7 +3822,8 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev)
adev_to_drm(adev)->mode_config.max_height = 16384; adev_to_drm(adev)->mode_config.max_height = 16384;
adev_to_drm(adev)->mode_config.preferred_depth = 24; adev_to_drm(adev)->mode_config.preferred_depth = 24;
adev_to_drm(adev)->mode_config.prefer_shadow = 1; /* disable prefer shadow for now due to hibernation issues */
adev_to_drm(adev)->mode_config.prefer_shadow = 0;
/* indicates support for immediate flip */ /* indicates support for immediate flip */
adev_to_drm(adev)->mode_config.async_page_flip = true; adev_to_drm(adev)->mode_config.async_page_flip = true;
......
...@@ -74,22 +74,6 @@ static int fsl_ldb_attach(struct drm_bridge *bridge, ...@@ -74,22 +74,6 @@ static int fsl_ldb_attach(struct drm_bridge *bridge,
bridge, flags); bridge, flags);
} }
static int fsl_ldb_atomic_check(struct drm_bridge *bridge,
struct drm_bridge_state *bridge_state,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
{
/* Invert DE signal polarity. */
bridge_state->input_bus_cfg.flags &= ~(DRM_BUS_FLAG_DE_LOW |
DRM_BUS_FLAG_DE_HIGH);
if (bridge_state->output_bus_cfg.flags & DRM_BUS_FLAG_DE_LOW)
bridge_state->input_bus_cfg.flags |= DRM_BUS_FLAG_DE_HIGH;
else if (bridge_state->output_bus_cfg.flags & DRM_BUS_FLAG_DE_HIGH)
bridge_state->input_bus_cfg.flags |= DRM_BUS_FLAG_DE_LOW;
return 0;
}
static void fsl_ldb_atomic_enable(struct drm_bridge *bridge, static void fsl_ldb_atomic_enable(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state) struct drm_bridge_state *old_bridge_state)
{ {
...@@ -153,7 +137,7 @@ static void fsl_ldb_atomic_enable(struct drm_bridge *bridge, ...@@ -153,7 +137,7 @@ static void fsl_ldb_atomic_enable(struct drm_bridge *bridge,
reg = LDB_CTRL_CH0_ENABLE; reg = LDB_CTRL_CH0_ENABLE;
if (fsl_ldb->lvds_dual_link) if (fsl_ldb->lvds_dual_link)
reg |= LDB_CTRL_CH1_ENABLE; reg |= LDB_CTRL_CH1_ENABLE | LDB_CTRL_SPLIT_MODE;
if (lvds_format_24bpp) { if (lvds_format_24bpp) {
reg |= LDB_CTRL_CH0_DATA_WIDTH; reg |= LDB_CTRL_CH0_DATA_WIDTH;
...@@ -233,7 +217,7 @@ fsl_ldb_mode_valid(struct drm_bridge *bridge, ...@@ -233,7 +217,7 @@ fsl_ldb_mode_valid(struct drm_bridge *bridge,
{ {
struct fsl_ldb *fsl_ldb = to_fsl_ldb(bridge); struct fsl_ldb *fsl_ldb = to_fsl_ldb(bridge);
if (mode->clock > (fsl_ldb->lvds_dual_link ? 80000 : 160000)) if (mode->clock > (fsl_ldb->lvds_dual_link ? 160000 : 80000))
return MODE_CLOCK_HIGH; return MODE_CLOCK_HIGH;
return MODE_OK; return MODE_OK;
...@@ -241,7 +225,6 @@ fsl_ldb_mode_valid(struct drm_bridge *bridge, ...@@ -241,7 +225,6 @@ fsl_ldb_mode_valid(struct drm_bridge *bridge,
static const struct drm_bridge_funcs funcs = { static const struct drm_bridge_funcs funcs = {
.attach = fsl_ldb_attach, .attach = fsl_ldb_attach,
.atomic_check = fsl_ldb_atomic_check,
.atomic_enable = fsl_ldb_atomic_enable, .atomic_enable = fsl_ldb_atomic_enable,
.atomic_disable = fsl_ldb_atomic_disable, .atomic_disable = fsl_ldb_atomic_disable,
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
......
...@@ -286,6 +286,21 @@ static const struct dmi_system_id orientation_data[] = { ...@@ -286,6 +286,21 @@ static const struct dmi_system_id orientation_data[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"), DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"),
}, },
.driver_data = (void *)&lcd1200x1920_rightside_up, .driver_data = (void *)&lcd1200x1920_rightside_up,
}, { /* Lenovo Yoga Tablet 2 830F / 830L */
.matches = {
/*
* Note this also matches the Lenovo Yoga Tablet 2 1050F/L
* since that uses the same mainboard. The resolution match
* will limit this to only matching on the 830F/L. Neither has
* any external video outputs so those are not a concern.
*/
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."),
DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"),
DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"),
/* Partial match on beginning of BIOS version */
DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"),
},
.driver_data = (void *)&lcd1200x1920_rightside_up,
}, { /* OneGX1 Pro */ }, { /* OneGX1 Pro */
.matches = { .matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SYSTEM_MANUFACTURER"), DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SYSTEM_MANUFACTURER"),
......
...@@ -839,6 +839,7 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo ...@@ -839,6 +839,7 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
ret = drm_connector_init(dev, connector, &intel_dp_mst_connector_funcs, ret = drm_connector_init(dev, connector, &intel_dp_mst_connector_funcs,
DRM_MODE_CONNECTOR_DisplayPort); DRM_MODE_CONNECTOR_DisplayPort);
if (ret) { if (ret) {
drm_dp_mst_put_port_malloc(port);
intel_connector_free(intel_connector); intel_connector_free(intel_connector);
return NULL; return NULL;
} }
......
...@@ -162,6 +162,15 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw) ...@@ -162,6 +162,15 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
u8 rev = INTEL_REVID(i915); u8 rev = INTEL_REVID(i915);
int i; int i;
/*
* The only difference between the ADL GuC FWs is the HWConfig support.
* ADL-N does not support HWConfig, so we should use the same binary as
* ADL-S, otherwise the GuC might attempt to fetch a config table that
* does not exist.
*/
if (IS_ADLP_N(i915))
p = INTEL_ALDERLAKE_S;
GEM_BUG_ON(uc_fw->type >= ARRAY_SIZE(blobs_all)); GEM_BUG_ON(uc_fw->type >= ARRAY_SIZE(blobs_all));
fw_blobs = blobs_all[uc_fw->type].blobs; fw_blobs = blobs_all[uc_fw->type].blobs;
fw_count = blobs_all[uc_fw->type].count; fw_count = blobs_all[uc_fw->type].count;
......
...@@ -1637,10 +1637,10 @@ static void force_unbind(struct i915_vma *vma) ...@@ -1637,10 +1637,10 @@ static void force_unbind(struct i915_vma *vma)
GEM_BUG_ON(drm_mm_node_allocated(&vma->node)); GEM_BUG_ON(drm_mm_node_allocated(&vma->node));
} }
static void release_references(struct i915_vma *vma, bool vm_ddestroy) static void release_references(struct i915_vma *vma, struct intel_gt *gt,
bool vm_ddestroy)
{ {
struct drm_i915_gem_object *obj = vma->obj; struct drm_i915_gem_object *obj = vma->obj;
struct intel_gt *gt = vma->vm->gt;
GEM_BUG_ON(i915_vma_is_active(vma)); GEM_BUG_ON(i915_vma_is_active(vma));
...@@ -1695,11 +1695,12 @@ void i915_vma_destroy_locked(struct i915_vma *vma) ...@@ -1695,11 +1695,12 @@ void i915_vma_destroy_locked(struct i915_vma *vma)
force_unbind(vma); force_unbind(vma);
list_del_init(&vma->vm_link); list_del_init(&vma->vm_link);
release_references(vma, false); release_references(vma, vma->vm->gt, false);
} }
void i915_vma_destroy(struct i915_vma *vma) void i915_vma_destroy(struct i915_vma *vma)
{ {
struct intel_gt *gt;
bool vm_ddestroy; bool vm_ddestroy;
mutex_lock(&vma->vm->mutex); mutex_lock(&vma->vm->mutex);
...@@ -1707,8 +1708,11 @@ void i915_vma_destroy(struct i915_vma *vma) ...@@ -1707,8 +1708,11 @@ void i915_vma_destroy(struct i915_vma *vma)
list_del_init(&vma->vm_link); list_del_init(&vma->vm_link);
vm_ddestroy = vma->vm_ddestroy; vm_ddestroy = vma->vm_ddestroy;
vma->vm_ddestroy = false; vma->vm_ddestroy = false;
/* vma->vm may be freed when releasing vma->vm->mutex. */
gt = vma->vm->gt;
mutex_unlock(&vma->vm->mutex); mutex_unlock(&vma->vm->mutex);
release_references(vma, vm_ddestroy); release_references(vma, gt, vm_ddestroy);
} }
void i915_vma_parked(struct intel_gt *gt) void i915_vma_parked(struct intel_gt *gt)
......
...@@ -433,8 +433,8 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data, ...@@ -433,8 +433,8 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data,
if (args->retained) { if (args->retained) {
if (args->madv == PANFROST_MADV_DONTNEED) if (args->madv == PANFROST_MADV_DONTNEED)
list_add_tail(&bo->base.madv_list, list_move_tail(&bo->base.madv_list,
&pfdev->shrinker_list); &pfdev->shrinker_list);
else if (args->madv == PANFROST_MADV_WILLNEED) else if (args->madv == PANFROST_MADV_WILLNEED)
list_del_init(&bo->base.madv_list); list_del_init(&bo->base.madv_list);
} }
......
...@@ -518,7 +518,7 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as, ...@@ -518,7 +518,7 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as,
err_pages: err_pages:
drm_gem_shmem_put_pages(&bo->base); drm_gem_shmem_put_pages(&bo->base);
err_bo: err_bo:
drm_gem_object_put(&bo->base.base); panfrost_gem_mapping_put(bomapping);
return ret; return ret;
} }
......
...@@ -23,6 +23,14 @@ ...@@ -23,6 +23,14 @@
#include <drm/drm_probe_helper.h> #include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h> #include <drm/drm_vblank.h>
#if defined(CONFIG_ARM_DMA_USE_IOMMU)
#include <asm/dma-iommu.h>
#else
#define arm_iommu_detach_device(...) ({ })
#define arm_iommu_release_mapping(...) ({ })
#define to_dma_iommu_mapping(dev) NULL
#endif
#include "rockchip_drm_drv.h" #include "rockchip_drm_drv.h"
#include "rockchip_drm_fb.h" #include "rockchip_drm_fb.h"
#include "rockchip_drm_gem.h" #include "rockchip_drm_gem.h"
...@@ -49,6 +57,15 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev, ...@@ -49,6 +57,15 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
if (!private->domain) if (!private->domain)
return 0; return 0;
if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) {
struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
if (mapping) {
arm_iommu_detach_device(dev);
arm_iommu_release_mapping(mapping);
}
}
ret = iommu_attach_device(private->domain, dev); ret = iommu_attach_device(private->domain, dev);
if (ret) { if (ret) {
DRM_DEV_ERROR(dev, "Failed to attach iommu device\n"); DRM_DEV_ERROR(dev, "Failed to attach iommu device\n");
......
...@@ -350,7 +350,7 @@ static int ssd130x_init(struct ssd130x_device *ssd130x) ...@@ -350,7 +350,7 @@ static int ssd130x_init(struct ssd130x_device *ssd130x)
/* Set precharge period in number of ticks from the internal clock */ /* Set precharge period in number of ticks from the internal clock */
precharge = (SSD130X_SET_PRECHARGE_PERIOD1_SET(ssd130x->prechargep1) | precharge = (SSD130X_SET_PRECHARGE_PERIOD1_SET(ssd130x->prechargep1) |
SSD130X_SET_PRECHARGE_PERIOD1_SET(ssd130x->prechargep2)); SSD130X_SET_PRECHARGE_PERIOD2_SET(ssd130x->prechargep2));
ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_PRECHARGE_PERIOD, precharge); ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_PRECHARGE_PERIOD, precharge);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment