Commit a175eca0 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull drm fixes from Dave Airlie:
 "Bit quieter this week, the main thing is it pulls in the fixes for the
  sysfb resource issue you were seeing. these had been queued for next
  so should have had some decent testing.

  Otherwise amdgpu, i915 and msm each have a few fixes, and vc4 has one.

  fbdev:
   - sysfb fixes/conflicting fb fixes

  amdgpu:
   - GPU recovery fix

   - Fix integer type usage in fourcc header for AMD modifiers

   - KFD TLB flush fix for gfx9 APUs

   - Display fix

  i915:
   - Fix ioctl argument error return

   - Fix d3cold disable to allow PCI upstream bridge D3 transition

   - Fix setting cache_dirty for dma-buf objects on discrete

  msm:
   - Fix to increment vsync_cnt before calling drm_crtc_handle_vblank so
     that userspace sees the value *after* it is incremented if waiting
     for vblank events

   - Fix to reset drm_dev to NULL in dp_display_unbind to avoid a crash
     in probe/bind error paths

   - Fix to resolve the smatch error of de-referencing before NULL check
     in dpu_encoder_phys_wb.c

   - Fix error return to userspace if fence-id allocation fails in
     submit ioctl

  vc4:
   - NULL ptr dereference fix"

* tag 'drm-fixes-2022-07-01' of git://anongit.freedesktop.org/drm/drm:
  Revert "drm/amdgpu/display: set vblank_disable_immediate for DC"
  drm/amdgpu: To flush tlb for MMHUB of RAVEN series
  drm/fourcc: fix integer type usage in uapi header
  drm/amdgpu: fix adev variable used in amdgpu_device_gpu_recover()
  fbdev: Disable sysfb device registration when removing conflicting FBs
  firmware: sysfb: Add sysfb_disable() helper function
  firmware: sysfb: Make sysfb_create_simplefb() return a pdev pointer
  drm/msm/gem: Fix error return on fence id alloc fail
  drm/i915: tweak the ordering in cpu_write_needs_clflush
  drm/i915/dgfx: Disable d3cold at gfx root port
  drm/i915/gem: add missing else
  drm/vc4: perfmon: Fix variable dereferenced before check
  drm/msm/dpu: Fix variable dereferenced before check
  drm/msm/dp: reset drm_dev to NULL at dp_display_unbind()
  drm/msm/dpu: Increment vsync_cnt before waking up userspace
parents 5e837935 b8f0009b
......@@ -13,6 +13,12 @@ EDD Interfaces
.. kernel-doc:: drivers/firmware/edd.c
:internal:
Generic System Framebuffers Interface
-------------------------------------
.. kernel-doc:: drivers/firmware/sysfb.c
:export:
Intel Stratix10 SoC Service Layer
---------------------------------
Some features of the Intel Stratix10 SoC require a level of privilege
......
......@@ -34,21 +34,59 @@
#include <linux/screen_info.h>
#include <linux/sysfb.h>
static struct platform_device *pd;
static DEFINE_MUTEX(disable_lock);
static bool disabled;
static bool sysfb_unregister(void)
{
if (IS_ERR_OR_NULL(pd))
return false;
platform_device_unregister(pd);
pd = NULL;
return true;
}
/**
* sysfb_disable() - disable the Generic System Framebuffers support
*
* This disables the registration of system framebuffer devices that match the
* generic drivers that make use of the system framebuffer set up by firmware.
*
* It also unregisters a device if this was already registered by sysfb_init().
*
* Context: The function can sleep. A @disable_lock mutex is acquired to serialize
* against sysfb_init(), that registers a system framebuffer device.
*/
void sysfb_disable(void)
{
mutex_lock(&disable_lock);
sysfb_unregister();
disabled = true;
mutex_unlock(&disable_lock);
}
EXPORT_SYMBOL_GPL(sysfb_disable);
static __init int sysfb_init(void)
{
struct screen_info *si = &screen_info;
struct simplefb_platform_data mode;
struct platform_device *pd;
const char *name;
bool compatible;
int ret;
int ret = 0;
mutex_lock(&disable_lock);
if (disabled)
goto unlock_mutex;
/* try to create a simple-framebuffer device */
compatible = sysfb_parse_mode(si, &mode);
if (compatible) {
ret = sysfb_create_simplefb(si, &mode);
if (!ret)
return 0;
pd = sysfb_create_simplefb(si, &mode);
if (!IS_ERR(pd))
goto unlock_mutex;
}
/* if the FB is incompatible, create a legacy framebuffer device */
......@@ -60,8 +98,10 @@ static __init int sysfb_init(void)
name = "platform-framebuffer";
pd = platform_device_alloc(name, 0);
if (!pd)
return -ENOMEM;
if (!pd) {
ret = -ENOMEM;
goto unlock_mutex;
}
sysfb_apply_efi_quirks(pd);
......@@ -73,9 +113,11 @@ static __init int sysfb_init(void)
if (ret)
goto err;
return 0;
goto unlock_mutex;
err:
platform_device_put(pd);
unlock_mutex:
mutex_unlock(&disable_lock);
return ret;
}
......
......@@ -57,7 +57,7 @@ __init bool sysfb_parse_mode(const struct screen_info *si,
return false;
}
__init int sysfb_create_simplefb(const struct screen_info *si,
__init struct platform_device *sysfb_create_simplefb(const struct screen_info *si,
const struct simplefb_platform_data *mode)
{
struct platform_device *pd;
......@@ -76,7 +76,7 @@ __init int sysfb_create_simplefb(const struct screen_info *si,
base |= (u64)si->ext_lfb_base << 32;
if (!base || (u64)(resource_size_t)base != base) {
printk(KERN_DEBUG "sysfb: inaccessible VRAM base\n");
return -EINVAL;
return ERR_PTR(-EINVAL);
}
/*
......@@ -93,7 +93,7 @@ __init int sysfb_create_simplefb(const struct screen_info *si,
length = mode->height * mode->stride;
if (length > size) {
printk(KERN_WARNING "sysfb: VRAM smaller than advertised\n");
return -EINVAL;
return ERR_PTR(-EINVAL);
}
length = PAGE_ALIGN(length);
......@@ -104,11 +104,11 @@ __init int sysfb_create_simplefb(const struct screen_info *si,
res.start = base;
res.end = res.start + length - 1;
if (res.end <= res.start)
return -EINVAL;
return ERR_PTR(-EINVAL);
pd = platform_device_alloc("simple-framebuffer", 0);
if (!pd)
return -ENOMEM;
return ERR_PTR(-ENOMEM);
sysfb_apply_efi_quirks(pd);
......@@ -124,10 +124,10 @@ __init int sysfb_create_simplefb(const struct screen_info *si,
if (ret)
goto err_put_device;
return 0;
return pd;
err_put_device:
platform_device_put(pd);
return ret;
return ERR_PTR(ret);
}
......@@ -714,7 +714,8 @@ int amdgpu_amdkfd_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
{
bool all_hub = false;
if (adev->family == AMDGPU_FAMILY_AI)
if (adev->family == AMDGPU_FAMILY_AI ||
adev->family == AMDGPU_FAMILY_RV)
all_hub = true;
return amdgpu_gmc_flush_gpu_tlb_pasid(adev, pasid, flush_type, all_hub);
......
......@@ -5164,7 +5164,7 @@ int amdgpu_device_gpu_recover_imp(struct amdgpu_device *adev,
*/
amdgpu_unregister_gpu_instance(tmp_adev);
drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, true);
drm_fb_helper_set_suspend_unlocked(adev_to_drm(tmp_adev)->fb_helper, true);
/* disable ras on ALL IPs */
if (!need_emergency_restart &&
......
......@@ -320,6 +320,7 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
if (!amdgpu_device_has_dc_support(adev)) {
if (!adev->enable_virtual_display)
/* Disable vblank IRQs aggressively for power-saving */
/* XXX: can this be enabled for DC? */
adev_to_drm(adev)->vblank_disable_immediate = true;
r = drm_vblank_init(adev_to_drm(adev), adev->mode_info.num_crtc);
......
......@@ -4259,9 +4259,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
}
}
/* Disable vblank IRQs aggressively for power-saving. */
adev_to_drm(adev)->vblank_disable_immediate = true;
/* loops over all connectors on the board */
for (i = 0; i < link_cnt; i++) {
struct dc_link *link = NULL;
......
......@@ -933,6 +933,7 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
case I915_CONTEXT_PARAM_PERSISTENCE:
if (args->size)
ret = -EINVAL;
else
ret = proto_context_set_persistence(fpriv->dev_priv, pc,
args->value);
break;
......
......@@ -35,12 +35,12 @@ bool i915_gem_cpu_write_needs_clflush(struct drm_i915_gem_object *obj)
if (obj->cache_dirty)
return false;
if (!(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE))
return true;
if (IS_DGFX(i915))
return false;
if (!(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE))
return true;
/* Currently in use by HW (display engine)? Keep flushed. */
return i915_gem_object_is_framebuffer(obj);
}
......
......@@ -530,6 +530,7 @@ static int i915_set_dma_info(struct drm_i915_private *i915)
static int i915_driver_hw_probe(struct drm_i915_private *dev_priv)
{
struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
struct pci_dev *root_pdev;
int ret;
if (i915_inject_probe_failure(dev_priv))
......@@ -641,6 +642,15 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv)
intel_bw_init_hw(dev_priv);
/*
* FIXME: Temporary hammer to avoid freezing the machine on our DGFX
* This should be totally removed when we handle the pci states properly
* on runtime PM and on s2idle cases.
*/
root_pdev = pcie_find_root_port(pdev);
if (root_pdev)
pci_d3cold_disable(root_pdev);
return 0;
err_msi:
......@@ -664,11 +674,16 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv)
static void i915_driver_hw_remove(struct drm_i915_private *dev_priv)
{
struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
struct pci_dev *root_pdev;
i915_perf_fini(dev_priv);
if (pdev->msi_enabled)
pci_disable_msi(pdev);
root_pdev = pcie_find_root_port(pdev);
if (root_pdev)
pci_d3cold_enable(root_pdev);
}
/**
......@@ -1193,14 +1208,6 @@ static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation)
goto out;
}
/*
* FIXME: Temporary hammer to avoid freezing the machine on our DGFX
* This should be totally removed when we handle the pci states properly
* on runtime PM and on s2idle cases.
*/
if (suspend_to_idle(dev_priv))
pci_d3cold_disable(pdev);
pci_disable_device(pdev);
/*
* During hibernation on some platforms the BIOS may try to access
......@@ -1365,8 +1372,6 @@ static int i915_drm_resume_early(struct drm_device *dev)
pci_set_master(pdev);
pci_d3cold_enable(pdev);
disable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
ret = vlv_resume_prepare(dev_priv, false);
......@@ -1543,7 +1548,6 @@ static int intel_runtime_suspend(struct device *kdev)
{
struct drm_i915_private *dev_priv = kdev_to_i915(kdev);
struct intel_runtime_pm *rpm = &dev_priv->runtime_pm;
struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
int ret;
if (drm_WARN_ON_ONCE(&dev_priv->drm, !HAS_RUNTIME_PM(dev_priv)))
......@@ -1589,12 +1593,6 @@ static int intel_runtime_suspend(struct device *kdev)
drm_err(&dev_priv->drm,
"Unclaimed access detected prior to suspending\n");
/*
* FIXME: Temporary hammer to avoid freezing the machine on our DGFX
* This should be totally removed when we handle the pci states properly
* on runtime PM and on s2idle cases.
*/
pci_d3cold_disable(pdev);
rpm->suspended = true;
/*
......@@ -1633,7 +1631,6 @@ static int intel_runtime_resume(struct device *kdev)
{
struct drm_i915_private *dev_priv = kdev_to_i915(kdev);
struct intel_runtime_pm *rpm = &dev_priv->runtime_pm;
struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
int ret;
if (drm_WARN_ON_ONCE(&dev_priv->drm, !HAS_RUNTIME_PM(dev_priv)))
......@@ -1646,7 +1643,6 @@ static int intel_runtime_resume(struct device *kdev)
intel_opregion_notify_adapter(dev_priv, PCI_D0);
rpm->suspended = false;
pci_d3cold_enable(pdev);
if (intel_uncore_unclaimed_mmio(&dev_priv->uncore))
drm_dbg(&dev_priv->drm,
"Unclaimed access during suspend, bios?\n");
......
......@@ -1251,12 +1251,13 @@ static void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc,
DPU_ATRACE_BEGIN("encoder_vblank_callback");
dpu_enc = to_dpu_encoder_virt(drm_enc);
atomic_inc(&phy_enc->vsync_cnt);
spin_lock_irqsave(&dpu_enc->enc_spinlock, lock_flags);
if (dpu_enc->crtc)
dpu_crtc_vblank_callback(dpu_enc->crtc);
spin_unlock_irqrestore(&dpu_enc->enc_spinlock, lock_flags);
atomic_inc(&phy_enc->vsync_cnt);
DPU_ATRACE_END("encoder_vblank_callback");
}
......
......@@ -252,11 +252,6 @@ static int dpu_encoder_phys_wb_atomic_check(
DPU_DEBUG("[atomic_check:%d, \"%s\",%d,%d]\n",
phys_enc->wb_idx, mode->name, mode->hdisplay, mode->vdisplay);
if (!conn_state->writeback_job || !conn_state->writeback_job->fb)
return 0;
fb = conn_state->writeback_job->fb;
if (!conn_state || !conn_state->connector) {
DPU_ERROR("invalid connector state\n");
return -EINVAL;
......@@ -267,6 +262,11 @@ static int dpu_encoder_phys_wb_atomic_check(
return -EINVAL;
}
if (!conn_state->writeback_job || !conn_state->writeback_job->fb)
return 0;
fb = conn_state->writeback_job->fb;
DPU_DEBUG("[fb_id:%u][fb:%u,%u]\n", fb->base.id,
fb->width, fb->height);
......
......@@ -316,6 +316,8 @@ static void dp_display_unbind(struct device *dev, struct device *master,
dp_power_client_deinit(dp->power);
dp_aux_unregister(dp->aux);
dp->drm_dev = NULL;
dp->aux->drm_dev = NULL;
priv->dp[dp->id] = NULL;
}
......
......@@ -928,7 +928,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
INT_MAX, GFP_KERNEL);
}
if (submit->fence_id < 0) {
ret = submit->fence_id = 0;
ret = submit->fence_id;
submit->fence_id = 0;
}
......
......@@ -17,12 +17,15 @@
void vc4_perfmon_get(struct vc4_perfmon *perfmon)
{
struct vc4_dev *vc4 = perfmon->dev;
struct vc4_dev *vc4;
if (!perfmon)
return;
vc4 = perfmon->dev;
if (WARN_ON_ONCE(vc4->is_vc5))
return;
if (perfmon)
refcount_inc(&perfmon->refcnt);
}
......
......@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/slab.h>
#include <linux/sysfb.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/vt.h>
......@@ -1752,6 +1753,17 @@ int remove_conflicting_framebuffers(struct apertures_struct *a,
do_free = true;
}
/*
* If a driver asked to unregister a platform device registered by
* sysfb, then can be assumed that this is a driver for a display
* that is set up by the system firmware and has a generic driver.
*
* Drivers for devices that don't have a generic driver will never
* ask for this, so let's assume that a real driver for the display
* was already probed and prevent sysfb to register devices later.
*/
sysfb_disable();
mutex_lock(&registration_lock);
do_remove_conflicting_framebuffers(a, name, primary);
mutex_unlock(&registration_lock);
......
......@@ -55,6 +55,18 @@ struct efifb_dmi_info {
int flags;
};
#ifdef CONFIG_SYSFB
void sysfb_disable(void);
#else /* CONFIG_SYSFB */
static inline void sysfb_disable(void)
{
}
#endif /* CONFIG_SYSFB */
#ifdef CONFIG_EFI
extern struct efifb_dmi_info efifb_dmi_list[];
......@@ -72,7 +84,7 @@ static inline void sysfb_apply_efi_quirks(struct platform_device *pd)
bool sysfb_parse_mode(const struct screen_info *si,
struct simplefb_platform_data *mode);
int sysfb_create_simplefb(const struct screen_info *si,
struct platform_device *sysfb_create_simplefb(const struct screen_info *si,
const struct simplefb_platform_data *mode);
#else /* CONFIG_SYSFB_SIMPLE */
......@@ -83,10 +95,10 @@ static inline bool sysfb_parse_mode(const struct screen_info *si,
return false;
}
static inline int sysfb_create_simplefb(const struct screen_info *si,
static inline struct platform_device *sysfb_create_simplefb(const struct screen_info *si,
const struct simplefb_platform_data *mode)
{
return -EINVAL;
return ERR_PTR(-EINVAL);
}
#endif /* CONFIG_SYSFB_SIMPLE */
......
......@@ -1444,11 +1444,11 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier)
#define AMD_FMT_MOD_PIPE_MASK 0x7
#define AMD_FMT_MOD_SET(field, value) \
((uint64_t)(value) << AMD_FMT_MOD_##field##_SHIFT)
((__u64)(value) << AMD_FMT_MOD_##field##_SHIFT)
#define AMD_FMT_MOD_GET(field, value) \
(((value) >> AMD_FMT_MOD_##field##_SHIFT) & AMD_FMT_MOD_##field##_MASK)
#define AMD_FMT_MOD_CLEAR(field) \
(~((uint64_t)AMD_FMT_MOD_##field##_MASK << AMD_FMT_MOD_##field##_SHIFT))
(~((__u64)AMD_FMT_MOD_##field##_MASK << AMD_FMT_MOD_##field##_SHIFT))
#if defined(__cplusplus)
}
......
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