diff --git a/patches.suse/drm-msm-dp-Clean-up-handling-of-DP-AUX-interrupts.patch b/patches.suse/drm-msm-dp-Clean-up-handling-of-DP-AUX-interrupts.patch new file mode 100644 index 0000000..f6adbc8 --- /dev/null +++ b/patches.suse/drm-msm-dp-Clean-up-handling-of-DP-AUX-interrupts.patch @@ -0,0 +1,201 @@ +From b20566cdef05cd40d95f10869d2a7646f48b1bbe Mon Sep 17 00:00:00 2001 +From: Douglas Anderson +Date: Thu, 26 Jan 2023 17:09:12 -0800 +Subject: [PATCH] drm/msm/dp: Clean up handling of DP AUX interrupts +Git-commit: b20566cdef05cd40d95f10869d2a7646f48b1bbe +Patch-mainline: v6.4-rc1 +References: git-fixes + +The DP AUX interrupt handling was a bit of a mess. +* There were two functions (one for "native" transfers and one for + "i2c" transfers) that were quite similar. It was hard to say how + many of the differences between the two functions were on purpose + and how many of them were just an accident of how they were coded. +* Each function sometimes used "else if" to test for error bits and + sometimes didn't and again it was hard to say if this was on purpose + or just an accident. +* The two functions wouldn't notice whether "unknown" bits were + set. For instance, there seems to be a bit "DP_INTR_PLL_UNLOCKED" + and if it was set there would be no indication. +* The two functions wouldn't notice if more than one error was set. + +Let's fix this by being more consistent / explicit about what we're +doing. + +By design this could cause different handling for AUX transfers, +though I'm not actually aware of any bug fixed as a result of +this patch (this patch was created because we simply noticed how odd +the old code was by code inspection). Specific notes here: +1. In the old native transfer case if we got "done + wrong address" + we'd ignore the "wrong address" (because of the "else if"). Now we + won't. +2. In the old native transfer case if we got "done + timeout" we'd + ignore the "timeout" (because of the "else if"). Now we won't. +3. In the old native transfer case we'd see "nack_defer" and translate + it to the error number for "nack". This differed from the i2c + transfer case where "nack_defer" was given the error number for + "nack_defer". This 100% can't matter because the only user of this + error number treats "nack defer" the same as "nack", so it's clear + that the difference between the "native" and "i2c" was pointless + here. +4. In the old i2c transfer case if we got "done" plus any error + besides "nack" or "defer" then we'd ignore the error. Now we don't. +5. If there is more than one error signaled by the hardware it's + possible that we'll report a different one than we used to. I don't + know if this matters. If someone is aware of a case this matters we + should document it and change the code to make it explicit. +6. One quirk we keep (I don't know if this is important) is that in + the i2c transfer case if we see "done + defer" we report that as a + "nack". That seemed too intentional in the old code to just drop. + +After this change we will add extra logging, including: +* A warning if we see more than one error bit set. +* A warning if we see an unexpected interrupt. +* A warning if we get an AUX transfer interrupt when shouldn't. + +It actually turns out that as a result of this change then at boot we +sometimes see an error: + [drm:dp_aux_isr] *ERROR* Unexpected DP AUX IRQ 0x01000000 when not busy +That means that, during init, we are seeing DP_INTR_PLL_UNLOCKED. For +now I'm going to say that leaving this error reported in the logs is +OK-ish and hopefully it will encourage someone to track down what's +going on at init time. + +One last note here is that this change renames one of the interrupt +bits. The bit named "i2c done" clearly was used for native transfers +being done too, so I renamed it to indicate this. + +Signed-off-by: Douglas Anderson +Tested-by: Kuogee Hsieh +Reviewed-by: Kuogee Hsieh +Patchwork: https://patchwork.freedesktop.org/patch/520658/ +Link: https://lore.kernel.org/r/20230126170745.v2.1.I90ffed3ddd21e818ae534f820cb4d6d8638859ab@changeid +Signed-off-by: Dmitry Baryshkov +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/msm/dp/dp_aux.c | 80 +++++++++++++++--------------------- + drivers/gpu/drm/msm/dp/dp_catalog.c | 2 + drivers/gpu/drm/msm/dp/dp_catalog.h | 2 + 3 files changed, 36 insertions(+), 48 deletions(-) + +--- a/drivers/gpu/drm/msm/dp/dp_aux.c ++++ b/drivers/gpu/drm/msm/dp/dp_aux.c +@@ -161,47 +161,6 @@ static ssize_t dp_aux_cmd_fifo_rx(struct + return i; + } + +-static void dp_aux_native_handler(struct dp_aux_private *aux, u32 isr) +-{ +- if (isr & DP_INTR_AUX_I2C_DONE) +- aux->aux_error_num = DP_AUX_ERR_NONE; +- else if (isr & DP_INTR_WRONG_ADDR) +- aux->aux_error_num = DP_AUX_ERR_ADDR; +- else if (isr & DP_INTR_TIMEOUT) +- aux->aux_error_num = DP_AUX_ERR_TOUT; +- if (isr & DP_INTR_NACK_DEFER) +- aux->aux_error_num = DP_AUX_ERR_NACK; +- if (isr & DP_INTR_AUX_ERROR) { +- aux->aux_error_num = DP_AUX_ERR_PHY; +- dp_catalog_aux_clear_hw_interrupts(aux->catalog); +- } +-} +- +-static void dp_aux_i2c_handler(struct dp_aux_private *aux, u32 isr) +-{ +- if (isr & DP_INTR_AUX_I2C_DONE) { +- if (isr & (DP_INTR_I2C_NACK | DP_INTR_I2C_DEFER)) +- aux->aux_error_num = DP_AUX_ERR_NACK; +- else +- aux->aux_error_num = DP_AUX_ERR_NONE; +- } else { +- if (isr & DP_INTR_WRONG_ADDR) +- aux->aux_error_num = DP_AUX_ERR_ADDR; +- else if (isr & DP_INTR_TIMEOUT) +- aux->aux_error_num = DP_AUX_ERR_TOUT; +- if (isr & DP_INTR_NACK_DEFER) +- aux->aux_error_num = DP_AUX_ERR_NACK_DEFER; +- if (isr & DP_INTR_I2C_NACK) +- aux->aux_error_num = DP_AUX_ERR_NACK; +- if (isr & DP_INTR_I2C_DEFER) +- aux->aux_error_num = DP_AUX_ERR_DEFER; +- if (isr & DP_INTR_AUX_ERROR) { +- aux->aux_error_num = DP_AUX_ERR_PHY; +- dp_catalog_aux_clear_hw_interrupts(aux->catalog); +- } +- } +-} +- + static void dp_aux_update_offset_and_segment(struct dp_aux_private *aux, + struct drm_dp_aux_msg *input_msg) + { +@@ -410,13 +369,42 @@ void dp_aux_isr(struct drm_dp_aux *dp_au + if (!isr) + return; + +- if (!aux->cmd_busy) ++ if (!aux->cmd_busy) { ++ DRM_ERROR("Unexpected DP AUX IRQ %#010x when not busy\n", isr); + return; ++ } + +- if (aux->native) +- dp_aux_native_handler(aux, isr); +- else +- dp_aux_i2c_handler(aux, isr); ++ /* ++ * The logic below assumes only one error bit is set (other than "done" ++ * which can apparently be set at the same time as some of the other ++ * bits). Warn if more than one get set so we know we need to improve ++ * the logic. ++ */ ++ if (hweight32(isr & ~DP_INTR_AUX_XFER_DONE) > 1) ++ DRM_WARN("Some DP AUX interrupts unhandled: %#010x\n", isr); ++ ++ if (isr & DP_INTR_AUX_ERROR) { ++ aux->aux_error_num = DP_AUX_ERR_PHY; ++ dp_catalog_aux_clear_hw_interrupts(aux->catalog); ++ } else if (isr & DP_INTR_NACK_DEFER) { ++ aux->aux_error_num = DP_AUX_ERR_NACK_DEFER; ++ } else if (isr & DP_INTR_WRONG_ADDR) { ++ aux->aux_error_num = DP_AUX_ERR_ADDR; ++ } else if (isr & DP_INTR_TIMEOUT) { ++ aux->aux_error_num = DP_AUX_ERR_TOUT; ++ } else if (!aux->native && (isr & DP_INTR_I2C_NACK)) { ++ aux->aux_error_num = DP_AUX_ERR_NACK; ++ } else if (!aux->native && (isr & DP_INTR_I2C_DEFER)) { ++ if (isr & DP_INTR_AUX_XFER_DONE) ++ aux->aux_error_num = DP_AUX_ERR_NACK; ++ else ++ aux->aux_error_num = DP_AUX_ERR_DEFER; ++ } else if (isr & DP_INTR_AUX_XFER_DONE) { ++ aux->aux_error_num = DP_AUX_ERR_NONE; ++ } else { ++ DRM_WARN("Unexpected interrupt: %#010x\n", isr); ++ return; ++ } + + complete(&aux->comp); + } +--- a/drivers/gpu/drm/msm/dp/dp_catalog.c ++++ b/drivers/gpu/drm/msm/dp/dp_catalog.c +@@ -34,7 +34,7 @@ + #define MSM_DP_CONTROLLER_P0_SIZE 0x0400 + + #define DP_INTERRUPT_STATUS1 \ +- (DP_INTR_AUX_I2C_DONE| \ ++ (DP_INTR_AUX_XFER_DONE| \ + DP_INTR_WRONG_ADDR | DP_INTR_TIMEOUT | \ + DP_INTR_NACK_DEFER | DP_INTR_WRONG_DATA_CNT | \ + DP_INTR_I2C_NACK | DP_INTR_I2C_DEFER | \ +--- a/drivers/gpu/drm/msm/dp/dp_catalog.h ++++ b/drivers/gpu/drm/msm/dp/dp_catalog.h +@@ -13,7 +13,7 @@ + + /* interrupts */ + #define DP_INTR_HPD BIT(0) +-#define DP_INTR_AUX_I2C_DONE BIT(3) ++#define DP_INTR_AUX_XFER_DONE BIT(3) + #define DP_INTR_WRONG_ADDR BIT(6) + #define DP_INTR_TIMEOUT BIT(9) + #define DP_INTR_NACK_DEFER BIT(12) diff --git a/series.conf b/series.conf index b5118b2..dc30321 100644 --- a/series.conf +++ b/series.conf @@ -19840,6 +19840,7 @@ patches.suse/drm-msm-adreno-drop-bogus-pm_runtime_set_active.patch patches.suse/drm-msm-adreno-Disable-preemption-on-Adreno-510.patch patches.suse/drm-msm-fix-NULL-deref-on-snapshot-tear-down.patch + patches.suse/drm-msm-dp-Clean-up-handling-of-DP-AUX-interrupts.patch patches.suse/drm-amd-display-Fix-potential-null-dereference.patch patches.suse/drm-i915-Make-intel_get_crtc_new_encoder-less-oopsy.patch patches.suse/media-av7110-prevent-underflow-in-write_ts_to_decode.patch