Skip to content

Commit beaa71d

Browse files
committed
Merge tag 'drm-fixes-2023-08-25' of git://anongit.freedesktop.org/drm/drm
Pull drm fixes from Dave Airlie: "A bit bigger than I'd care for, but it's mostly a single vmwgfx fix and a fix for an i915 hotplug probing. Otherwise misc i915, bridge, panfrost and dma-buf fixes. core: - add a HPD poll helper i915: - fix regression in i915 polling - fix docs build warning - fix DG2 idle power consumption bridge: - samsung-dsim: init fix panfrost: - fix speed binning issue dma-buf: - fix recursive lock in fence signal vmwgfx: - fix shader stage validation - fix NULL ptr derefs in gem put" * tag 'drm-fixes-2023-08-25' of git://anongit.freedesktop.org/drm/drm: drm/i915: Fix HPD polling, reenabling the output poll work as needed drm: Add an HPD poll helper to reschedule the poll work drm/vmwgfx: Fix possible invalid drm gem put calls drm/vmwgfx: Fix shader stage validation dma-buf/sw_sync: Avoid recursive lock during fence signal drm/i915: fix Sphinx indentation warning drm/i915/dgfx: Enable d3cold at s2idle drm/display/dp: Fix the DP DSC Receiver cap size drm/panfrost: Skip speed binning on EOPNOTSUPP drm: bridge: samsung-dsim: Fix init during host transfer
2 parents 4f9e7fa + 59fe202 commit beaa71d

File tree

16 files changed

+136
-94
lines changed

16 files changed

+136
-94
lines changed

drivers/dma-buf/sw_sync.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ static const struct dma_fence_ops timeline_fence_ops = {
191191
*/
192192
static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc)
193193
{
194+
LIST_HEAD(signalled);
194195
struct sync_pt *pt, *next;
195196

196197
trace_sync_timeline(obj);
@@ -203,21 +204,20 @@ static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc)
203204
if (!timeline_fence_signaled(&pt->base))
204205
break;
205206

206-
list_del_init(&pt->link);
207+
dma_fence_get(&pt->base);
208+
209+
list_move_tail(&pt->link, &signalled);
207210
rb_erase(&pt->node, &obj->pt_tree);
208211

209-
/*
210-
* A signal callback may release the last reference to this
211-
* fence, causing it to be freed. That operation has to be
212-
* last to avoid a use after free inside this loop, and must
213-
* be after we remove the fence from the timeline in order to
214-
* prevent deadlocking on timeline->lock inside
215-
* timeline_fence_release().
216-
*/
217212
dma_fence_signal_locked(&pt->base);
218213
}
219214

220215
spin_unlock_irq(&obj->lock);
216+
217+
list_for_each_entry_safe(pt, next, &signalled, link) {
218+
list_del_init(&pt->link);
219+
dma_fence_put(&pt->base);
220+
}
221221
}
222222

223223
/**

drivers/gpu/drm/bridge/samsung-dsim.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,6 +1386,18 @@ static void samsung_dsim_disable_irq(struct samsung_dsim *dsi)
13861386
disable_irq(dsi->irq);
13871387
}
13881388

1389+
static void samsung_dsim_set_stop_state(struct samsung_dsim *dsi, bool enable)
1390+
{
1391+
u32 reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);
1392+
1393+
if (enable)
1394+
reg |= DSIM_FORCE_STOP_STATE;
1395+
else
1396+
reg &= ~DSIM_FORCE_STOP_STATE;
1397+
1398+
samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg);
1399+
}
1400+
13891401
static int samsung_dsim_init(struct samsung_dsim *dsi)
13901402
{
13911403
const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;
@@ -1445,15 +1457,12 @@ static void samsung_dsim_atomic_enable(struct drm_bridge *bridge,
14451457
struct drm_bridge_state *old_bridge_state)
14461458
{
14471459
struct samsung_dsim *dsi = bridge_to_dsi(bridge);
1448-
u32 reg;
14491460

14501461
if (samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) {
14511462
samsung_dsim_set_display_mode(dsi);
14521463
samsung_dsim_set_display_enable(dsi, true);
14531464
} else {
1454-
reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);
1455-
reg &= ~DSIM_FORCE_STOP_STATE;
1456-
samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg);
1465+
samsung_dsim_set_stop_state(dsi, false);
14571466
}
14581467

14591468
dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
@@ -1463,16 +1472,12 @@ static void samsung_dsim_atomic_disable(struct drm_bridge *bridge,
14631472
struct drm_bridge_state *old_bridge_state)
14641473
{
14651474
struct samsung_dsim *dsi = bridge_to_dsi(bridge);
1466-
u32 reg;
14671475

14681476
if (!(dsi->state & DSIM_STATE_ENABLED))
14691477
return;
14701478

1471-
if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) {
1472-
reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);
1473-
reg |= DSIM_FORCE_STOP_STATE;
1474-
samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg);
1475-
}
1479+
if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type))
1480+
samsung_dsim_set_stop_state(dsi, true);
14761481

14771482
dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
14781483
}
@@ -1775,6 +1780,8 @@ static ssize_t samsung_dsim_host_transfer(struct mipi_dsi_host *host,
17751780
if (ret)
17761781
return ret;
17771782

1783+
samsung_dsim_set_stop_state(dsi, false);
1784+
17781785
ret = mipi_dsi_create_packet(&xfer.packet, msg);
17791786
if (ret < 0)
17801787
return ret;

drivers/gpu/drm/drm_probe_helper.c

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,26 @@ static bool drm_kms_helper_enable_hpd(struct drm_device *dev)
262262
}
263263

264264
#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
265+
static void reschedule_output_poll_work(struct drm_device *dev)
266+
{
267+
unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
268+
269+
if (dev->mode_config.delayed_event)
270+
/*
271+
* FIXME:
272+
*
273+
* Use short (1s) delay to handle the initial delayed event.
274+
* This delay should not be needed, but Optimus/nouveau will
275+
* fail in a mysterious way if the delayed event is handled as
276+
* soon as possible like it is done in
277+
* drm_helper_probe_single_connector_modes() in case the poll
278+
* was enabled before.
279+
*/
280+
delay = HZ;
281+
282+
schedule_delayed_work(&dev->mode_config.output_poll_work, delay);
283+
}
284+
265285
/**
266286
* drm_kms_helper_poll_enable - re-enable output polling.
267287
* @dev: drm_device
@@ -279,37 +299,41 @@ static bool drm_kms_helper_enable_hpd(struct drm_device *dev)
279299
*/
280300
void drm_kms_helper_poll_enable(struct drm_device *dev)
281301
{
282-
bool poll = false;
283-
unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
284-
285302
if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll ||
286303
dev->mode_config.poll_running)
287304
return;
288305

289-
poll = drm_kms_helper_enable_hpd(dev);
290-
291-
if (dev->mode_config.delayed_event) {
292-
/*
293-
* FIXME:
294-
*
295-
* Use short (1s) delay to handle the initial delayed event.
296-
* This delay should not be needed, but Optimus/nouveau will
297-
* fail in a mysterious way if the delayed event is handled as
298-
* soon as possible like it is done in
299-
* drm_helper_probe_single_connector_modes() in case the poll
300-
* was enabled before.
301-
*/
302-
poll = true;
303-
delay = HZ;
304-
}
305-
306-
if (poll)
307-
schedule_delayed_work(&dev->mode_config.output_poll_work, delay);
306+
if (drm_kms_helper_enable_hpd(dev) ||
307+
dev->mode_config.delayed_event)
308+
reschedule_output_poll_work(dev);
308309

309310
dev->mode_config.poll_running = true;
310311
}
311312
EXPORT_SYMBOL(drm_kms_helper_poll_enable);
312313

314+
/**
315+
* drm_kms_helper_poll_reschedule - reschedule the output polling work
316+
* @dev: drm_device
317+
*
318+
* This function reschedules the output polling work, after polling for a
319+
* connector has been enabled.
320+
*
321+
* Drivers must call this helper after enabling polling for a connector by
322+
* setting %DRM_CONNECTOR_POLL_CONNECT / %DRM_CONNECTOR_POLL_DISCONNECT flags
323+
* in drm_connector::polled. Note that after disabling polling by clearing these
324+
* flags for a connector will stop the output polling work automatically if
325+
* the polling is disabled for all other connectors as well.
326+
*
327+
* The function can be called only after polling has been enabled by calling
328+
* drm_kms_helper_poll_init() / drm_kms_helper_poll_enable().
329+
*/
330+
void drm_kms_helper_poll_reschedule(struct drm_device *dev)
331+
{
332+
if (dev->mode_config.poll_running)
333+
reschedule_output_poll_work(dev);
334+
}
335+
EXPORT_SYMBOL(drm_kms_helper_poll_reschedule);
336+
313337
static enum drm_connector_status
314338
drm_helper_probe_detect_ctx(struct drm_connector *connector, bool force)
315339
{

drivers/gpu/drm/i915/display/intel_hotplug.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ intel_hpd_irq_storm_switch_to_polling(struct drm_i915_private *dev_priv)
211211

212212
/* Enable polling and queue hotplug re-enabling. */
213213
if (hpd_disabled) {
214-
drm_kms_helper_poll_enable(&dev_priv->drm);
214+
drm_kms_helper_poll_reschedule(&dev_priv->drm);
215215
mod_delayed_work(dev_priv->unordered_wq,
216216
&dev_priv->display.hotplug.reenable_work,
217217
msecs_to_jiffies(HPD_STORM_REENABLE_DELAY));
@@ -649,7 +649,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work)
649649
drm_connector_list_iter_end(&conn_iter);
650650

651651
if (enabled)
652-
drm_kms_helper_poll_enable(&dev_priv->drm);
652+
drm_kms_helper_poll_reschedule(&dev_priv->drm);
653653

654654
mutex_unlock(&dev_priv->drm.mode_config.mutex);
655655

drivers/gpu/drm/i915/gt/uc/intel_huc.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,15 @@
2626
* The kernel driver is only responsible for loading the HuC firmware and
2727
* triggering its security authentication. This is done differently depending
2828
* on the platform:
29+
*
2930
* - older platforms (from Gen9 to most Gen12s): the load is performed via DMA
3031
* and the authentication via GuC
3132
* - DG2: load and authentication are both performed via GSC.
3233
* - MTL and newer platforms: the load is performed via DMA (same as with
3334
* not-DG2 older platforms), while the authentication is done in 2-steps,
3435
* a first auth for clear-media workloads via GuC and a second one for all
3536
* workloads via GSC.
37+
*
3638
* On platforms where the GuC does the authentication, to correctly do so the
3739
* HuC binary must be loaded before the GuC one.
3840
* Loading the HuC is optional; however, not using the HuC might negatively

drivers/gpu/drm/i915/i915_driver.c

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,6 @@ static int i915_pcode_init(struct drm_i915_private *i915)
443443
static int i915_driver_hw_probe(struct drm_i915_private *dev_priv)
444444
{
445445
struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
446-
struct pci_dev *root_pdev;
447446
int ret;
448447

449448
if (i915_inject_probe_failure(dev_priv))
@@ -557,15 +556,6 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv)
557556

558557
intel_bw_init_hw(dev_priv);
559558

560-
/*
561-
* FIXME: Temporary hammer to avoid freezing the machine on our DGFX
562-
* This should be totally removed when we handle the pci states properly
563-
* on runtime PM and on s2idle cases.
564-
*/
565-
root_pdev = pcie_find_root_port(pdev);
566-
if (root_pdev)
567-
pci_d3cold_disable(root_pdev);
568-
569559
return 0;
570560

571561
err_opregion:
@@ -591,18 +581,13 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv)
591581
static void i915_driver_hw_remove(struct drm_i915_private *dev_priv)
592582
{
593583
struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
594-
struct pci_dev *root_pdev;
595584

596585
i915_perf_fini(dev_priv);
597586

598587
intel_opregion_cleanup(dev_priv);
599588

600589
if (pdev->msi_enabled)
601590
pci_disable_msi(pdev);
602-
603-
root_pdev = pcie_find_root_port(pdev);
604-
if (root_pdev)
605-
pci_d3cold_enable(root_pdev);
606591
}
607592

608593
/**
@@ -1517,6 +1502,8 @@ static int intel_runtime_suspend(struct device *kdev)
15171502
{
15181503
struct drm_i915_private *dev_priv = kdev_to_i915(kdev);
15191504
struct intel_runtime_pm *rpm = &dev_priv->runtime_pm;
1505+
struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
1506+
struct pci_dev *root_pdev;
15201507
struct intel_gt *gt;
15211508
int ret, i;
15221509

@@ -1568,6 +1555,15 @@ static int intel_runtime_suspend(struct device *kdev)
15681555
drm_err(&dev_priv->drm,
15691556
"Unclaimed access detected prior to suspending\n");
15701557

1558+
/*
1559+
* FIXME: Temporary hammer to avoid freezing the machine on our DGFX
1560+
* This should be totally removed when we handle the pci states properly
1561+
* on runtime PM.
1562+
*/
1563+
root_pdev = pcie_find_root_port(pdev);
1564+
if (root_pdev)
1565+
pci_d3cold_disable(root_pdev);
1566+
15711567
rpm->suspended = true;
15721568

15731569
/*
@@ -1606,6 +1602,8 @@ static int intel_runtime_resume(struct device *kdev)
16061602
{
16071603
struct drm_i915_private *dev_priv = kdev_to_i915(kdev);
16081604
struct intel_runtime_pm *rpm = &dev_priv->runtime_pm;
1605+
struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
1606+
struct pci_dev *root_pdev;
16091607
struct intel_gt *gt;
16101608
int ret, i;
16111609

@@ -1619,6 +1617,11 @@ static int intel_runtime_resume(struct device *kdev)
16191617

16201618
intel_opregion_notify_adapter(dev_priv, PCI_D0);
16211619
rpm->suspended = false;
1620+
1621+
root_pdev = pcie_find_root_port(pdev);
1622+
if (root_pdev)
1623+
pci_d3cold_enable(root_pdev);
1624+
16221625
if (intel_uncore_unclaimed_mmio(&dev_priv->uncore))
16231626
drm_dbg(&dev_priv->drm,
16241627
"Unclaimed access during suspend, bios?\n");

drivers/gpu/drm/panfrost/panfrost_devfreq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ static int panfrost_read_speedbin(struct device *dev)
9696
* keep going without it; any other error means that we are
9797
* supposed to read the bin value, but we failed doing so.
9898
*/
99-
if (ret != -ENOENT) {
99+
if (ret != -ENOENT && ret != -EOPNOTSUPP) {
100100
DRM_DEV_ERROR(dev, "Cannot read speed-bin (%d).", ret);
101101
return ret;
102102
}

drivers/gpu/drm/vmwgfx/vmwgfx_bo.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -497,10 +497,9 @@ static int vmw_user_bo_synccpu_release(struct drm_file *filp,
497497
if (!(flags & drm_vmw_synccpu_allow_cs)) {
498498
atomic_dec(&vmw_bo->cpu_writers);
499499
}
500-
ttm_bo_put(&vmw_bo->tbo);
500+
vmw_user_bo_unref(vmw_bo);
501501
}
502502

503-
drm_gem_object_put(&vmw_bo->tbo.base);
504503
return ret;
505504
}
506505

@@ -540,8 +539,7 @@ int vmw_user_bo_synccpu_ioctl(struct drm_device *dev, void *data,
540539
return ret;
541540

542541
ret = vmw_user_bo_synccpu_grab(vbo, arg->flags);
543-
vmw_bo_unreference(&vbo);
544-
drm_gem_object_put(&vbo->tbo.base);
542+
vmw_user_bo_unref(vbo);
545543
if (unlikely(ret != 0)) {
546544
if (ret == -ERESTARTSYS || ret == -EBUSY)
547545
return -EBUSY;

drivers/gpu/drm/vmwgfx/vmwgfx_bo.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,14 @@ static inline struct vmw_bo *vmw_bo_reference(struct vmw_bo *buf)
195195
return buf;
196196
}
197197

198+
static inline void vmw_user_bo_unref(struct vmw_bo *vbo)
199+
{
200+
if (vbo) {
201+
ttm_bo_put(&vbo->tbo);
202+
drm_gem_object_put(&vbo->tbo.base);
203+
}
204+
}
205+
198206
static inline struct vmw_bo *to_vmw_bo(struct drm_gem_object *gobj)
199207
{
200208
return container_of((gobj), struct vmw_bo, tbo.base);

drivers/gpu/drm/vmwgfx/vmwgfx_drv.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,4 +1513,16 @@ static inline bool vmw_has_fences(struct vmw_private *vmw)
15131513
return (vmw_fifo_caps(vmw) & SVGA_FIFO_CAP_FENCE) != 0;
15141514
}
15151515

1516+
static inline bool vmw_shadertype_is_valid(enum vmw_sm_type shader_model,
1517+
u32 shader_type)
1518+
{
1519+
SVGA3dShaderType max_allowed = SVGA3D_SHADERTYPE_PREDX_MAX;
1520+
1521+
if (shader_model >= VMW_SM_5)
1522+
max_allowed = SVGA3D_SHADERTYPE_MAX;
1523+
else if (shader_model >= VMW_SM_4)
1524+
max_allowed = SVGA3D_SHADERTYPE_DX10_MAX;
1525+
return shader_type >= SVGA3D_SHADERTYPE_MIN && shader_type < max_allowed;
1526+
}
1527+
15161528
#endif

0 commit comments

Comments
 (0)