drm/i915/aux: use polling when irqs are unavailable

JIRA: https://issues.redhat.com/browse/RHEL-180329

commit ef1add67462324cc1a3d7d57a2efcc27b6ed33d3
Author: Michał Grzelak <michal.grzelak@intel.com>
Date:   Thu Apr 16 18:37:44 2026 +0200

    drm/i915/aux: use polling when irqs are unavailable

    [ Upstream commit 202e77cf2e839e1adc804433322dc5c9ee511c9f ]

    PTL with physically disconnected display was observed to have 40s longer
    execution time when testing xe_fault_injection@xe_guc_mmio_send_recv.
    The issue has not been seen when reverting commit 40a9f77a28fa ("Revert
    "drm/i915/dp: change aux_ctl reg read to polling read"").

    Apparently the configuration suffers from not having AUX enabled when
    using interrupts. One probable cause can be xe enabling interrupts too
    late: interrupts need memory allocations which currently can't be done
    before the display FB takeover is done.

    As for now, use polling for AUX in case interrupts are unavailable.

    Fixes: 40a9f77a28fa ("Revert "drm/i915/dp: change aux_ctl reg read to polling read"")
    Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
    Signed-off-by: Michał Grzelak <michal.grzelak@intel.com>
    Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
    Link: https://patch.msgid.link/20260416163744.288107-1-michal.grzelak@intel.com
    (cherry picked from commit 05e0550b65cd1604bd515fbc65f522bce4c10a87)
    Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
    Signed-off-by: Sasha Levin <sashal@kernel.org>

Signed-off-by: Anusha Srivatsa <asrivats@redhat.com>
This commit is contained in:
Anusha Srivatsa
2026-08-03 14:53:52 -05:00
parent b139453f32
commit c6ba01030d
+16 -4
View File
@@ -12,6 +12,7 @@
#include "intel_dp.h"
#include "intel_dp_aux.h"
#include "intel_dp_aux_regs.h"
#include "intel_parent.h"
#include "intel_pps.h"
#include "intel_quirks.h"
#include "intel_tc.h"
@@ -60,18 +61,29 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp)
struct intel_display *display = to_intel_display(intel_dp);
i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg(intel_dp);
const unsigned int timeout_ms = 10;
bool done = true;
u32 status;
bool done;
int ret;
if (intel_parent_irq_enabled(display)) {
#define C (((status = intel_de_read_notrace(display, ch_ctl)) & DP_AUX_CH_CTL_SEND_BUSY) == 0)
done = wait_event_timeout(display->gmbus.wait_queue, C,
msecs_to_jiffies_timeout(timeout_ms));
done = wait_event_timeout(display->gmbus.wait_queue, C,
msecs_to_jiffies_timeout(timeout_ms));
#undef C
} else {
ret = intel_de_wait_ms(display, ch_ctl,
DP_AUX_CH_CTL_SEND_BUSY, 0,
timeout_ms, &status);
if (ret == -ETIMEDOUT)
done = false;
}
if (!done)
drm_err(display->drm,
"%s: did not complete or timeout within %ums (status 0x%08x)\n",
intel_dp->aux.name, timeout_ms, status);
#undef C
return status;
}