Commit 3698a75f authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-next-fixes-2023-08-24' of...

Merge tag 'drm-intel-next-fixes-2023-08-24' of git://anongit.freedesktop.org/drm/drm-intel into drm-next

- Fix TLB invalidation (Alan)
- Fix Display HPD polling (Imre)
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/ZOdOP31OE/Cf1ojo@intel.com
parents bc609f48 cfd48ad8
...@@ -262,6 +262,26 @@ static bool drm_kms_helper_enable_hpd(struct drm_device *dev) ...@@ -262,6 +262,26 @@ static bool drm_kms_helper_enable_hpd(struct drm_device *dev)
} }
#define DRM_OUTPUT_POLL_PERIOD (10*HZ) #define DRM_OUTPUT_POLL_PERIOD (10*HZ)
static void reschedule_output_poll_work(struct drm_device *dev)
{
unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
if (dev->mode_config.delayed_event)
/*
* FIXME:
*
* Use short (1s) delay to handle the initial delayed event.
* This delay should not be needed, but Optimus/nouveau will
* fail in a mysterious way if the delayed event is handled as
* soon as possible like it is done in
* drm_helper_probe_single_connector_modes() in case the poll
* was enabled before.
*/
delay = HZ;
schedule_delayed_work(&dev->mode_config.output_poll_work, delay);
}
/** /**
* drm_kms_helper_poll_enable - re-enable output polling. * drm_kms_helper_poll_enable - re-enable output polling.
* @dev: drm_device * @dev: drm_device
...@@ -279,37 +299,41 @@ static bool drm_kms_helper_enable_hpd(struct drm_device *dev) ...@@ -279,37 +299,41 @@ static bool drm_kms_helper_enable_hpd(struct drm_device *dev)
*/ */
void drm_kms_helper_poll_enable(struct drm_device *dev) void drm_kms_helper_poll_enable(struct drm_device *dev)
{ {
bool poll = false;
unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll || if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll ||
dev->mode_config.poll_running) dev->mode_config.poll_running)
return; return;
poll = drm_kms_helper_enable_hpd(dev); if (drm_kms_helper_enable_hpd(dev) ||
dev->mode_config.delayed_event)
if (dev->mode_config.delayed_event) { reschedule_output_poll_work(dev);
/*
* FIXME:
*
* Use short (1s) delay to handle the initial delayed event.
* This delay should not be needed, but Optimus/nouveau will
* fail in a mysterious way if the delayed event is handled as
* soon as possible like it is done in
* drm_helper_probe_single_connector_modes() in case the poll
* was enabled before.
*/
poll = true;
delay = HZ;
}
if (poll)
schedule_delayed_work(&dev->mode_config.output_poll_work, delay);
dev->mode_config.poll_running = true; dev->mode_config.poll_running = true;
} }
EXPORT_SYMBOL(drm_kms_helper_poll_enable); EXPORT_SYMBOL(drm_kms_helper_poll_enable);
/**
* drm_kms_helper_poll_reschedule - reschedule the output polling work
* @dev: drm_device
*
* This function reschedules the output polling work, after polling for a
* connector has been enabled.
*
* Drivers must call this helper after enabling polling for a connector by
* setting %DRM_CONNECTOR_POLL_CONNECT / %DRM_CONNECTOR_POLL_DISCONNECT flags
* in drm_connector::polled. Note that after disabling polling by clearing these
* flags for a connector will stop the output polling work automatically if
* the polling is disabled for all other connectors as well.
*
* The function can be called only after polling has been enabled by calling
* drm_kms_helper_poll_init() / drm_kms_helper_poll_enable().
*/
void drm_kms_helper_poll_reschedule(struct drm_device *dev)
{
if (dev->mode_config.poll_running)
reschedule_output_poll_work(dev);
}
EXPORT_SYMBOL(drm_kms_helper_poll_reschedule);
static enum drm_connector_status static enum drm_connector_status
drm_helper_probe_detect_ctx(struct drm_connector *connector, bool force) drm_helper_probe_detect_ctx(struct drm_connector *connector, bool force)
{ {
......
...@@ -211,7 +211,7 @@ intel_hpd_irq_storm_switch_to_polling(struct drm_i915_private *dev_priv) ...@@ -211,7 +211,7 @@ intel_hpd_irq_storm_switch_to_polling(struct drm_i915_private *dev_priv)
/* Enable polling and queue hotplug re-enabling. */ /* Enable polling and queue hotplug re-enabling. */
if (hpd_disabled) { if (hpd_disabled) {
drm_kms_helper_poll_enable(&dev_priv->drm); drm_kms_helper_poll_reschedule(&dev_priv->drm);
mod_delayed_work(dev_priv->unordered_wq, mod_delayed_work(dev_priv->unordered_wq,
&dev_priv->display.hotplug.reenable_work, &dev_priv->display.hotplug.reenable_work,
msecs_to_jiffies(HPD_STORM_REENABLE_DELAY)); msecs_to_jiffies(HPD_STORM_REENABLE_DELAY));
...@@ -661,7 +661,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work) ...@@ -661,7 +661,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work)
drm_connector_list_iter_end(&conn_iter); drm_connector_list_iter_end(&conn_iter);
if (enabled) if (enabled)
drm_kms_helper_poll_enable(&dev_priv->drm); drm_kms_helper_poll_reschedule(&dev_priv->drm);
mutex_unlock(&dev_priv->drm.mode_config.mutex); mutex_unlock(&dev_priv->drm.mode_config.mutex);
......
...@@ -1356,7 +1356,7 @@ void vma_invalidate_tlb(struct i915_address_space *vm, u32 *tlb) ...@@ -1356,7 +1356,7 @@ void vma_invalidate_tlb(struct i915_address_space *vm, u32 *tlb)
*/ */
for_each_gt(gt, vm->i915, id) for_each_gt(gt, vm->i915, id)
WRITE_ONCE(tlb[id], WRITE_ONCE(tlb[id],
intel_gt_next_invalidate_tlb_full(vm->gt)); intel_gt_next_invalidate_tlb_full(gt));
} }
static void __vma_put_pages(struct i915_vma *vma, unsigned int count) static void __vma_put_pages(struct i915_vma *vma, unsigned int count)
......
...@@ -25,6 +25,7 @@ void drm_kms_helper_connector_hotplug_event(struct drm_connector *connector); ...@@ -25,6 +25,7 @@ void drm_kms_helper_connector_hotplug_event(struct drm_connector *connector);
void drm_kms_helper_poll_disable(struct drm_device *dev); void drm_kms_helper_poll_disable(struct drm_device *dev);
void drm_kms_helper_poll_enable(struct drm_device *dev); void drm_kms_helper_poll_enable(struct drm_device *dev);
void drm_kms_helper_poll_reschedule(struct drm_device *dev);
bool drm_kms_helper_is_poll_worker(void); bool drm_kms_helper_is_poll_worker(void);
enum drm_mode_status drm_crtc_helper_mode_valid_fixed(struct drm_crtc *crtc, enum drm_mode_status drm_crtc_helper_mode_valid_fixed(struct drm_crtc *crtc,
......
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