Skip to content

Commit

Permalink
Merge tag 'drm-fixes-2022-07-01' of git://anongit.freedesktop.org/drm…
Browse files Browse the repository at this point in the history
…/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
  • Loading branch information
Linus Torvalds committed Jul 1, 2022
2 parents 5e83793 + b8f0009 commit a175eca
Show file tree
Hide file tree
Showing 18 changed files with 136 additions and 62 deletions.
6 changes: 6 additions & 0 deletions Documentation/driver-api/firmware/other_interfaces.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
58 changes: 50 additions & 8 deletions drivers/firmware/sysfb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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);

Expand All @@ -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;
}

Expand Down
16 changes: 8 additions & 8 deletions drivers/firmware/sysfb_simplefb.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ __init bool sysfb_parse_mode(const struct screen_info *si,
return false;
}

__init int sysfb_create_simplefb(const struct screen_info *si,
const struct simplefb_platform_data *mode)
__init struct platform_device *sysfb_create_simplefb(const struct screen_info *si,
const struct simplefb_platform_data *mode)
{
struct platform_device *pd;
struct resource res;
Expand All @@ -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);
}

/*
Expand All @@ -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);

Expand All @@ -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);

Expand All @@ -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);
}
3 changes: 2 additions & 1 deletion drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 0 additions & 3 deletions drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 3 additions & 2 deletions drivers/gpu/drm/i915/gem/i915_gem_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -933,8 +933,9 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
case I915_CONTEXT_PARAM_PERSISTENCE:
if (args->size)
ret = -EINVAL;
ret = proto_context_set_persistence(fpriv->dev_priv, pc,
args->value);
else
ret = proto_context_set_persistence(fpriv->dev_priv, pc,
args->value);
break;

case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
Expand Down
6 changes: 3 additions & 3 deletions drivers/gpu/drm/i915/gem/i915_gem_domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
34 changes: 15 additions & 19 deletions drivers/gpu/drm/i915/i915_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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:
Expand All @@ -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);
}

/**
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)))
Expand Down Expand Up @@ -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;

/*
Expand Down Expand Up @@ -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)))
Expand All @@ -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");
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}

Expand Down
10 changes: 5 additions & 5 deletions drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);

Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/msm/dp/dp_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/msm/msm_gem_submit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
Loading

0 comments on commit a175eca

Please sign in to comment.