[Freedreno] [PATCH v8 2/4] drm/msm/dp: Support only IRQ_HPD and REPLUG interrupts for eDP
Doug Anderson
dianders at chromium.org
Thu Apr 21 17:12:08 UTC 2022
Hi,
On Thu, Apr 21, 2022 at 9:39 AM Sankeerth Billakanti (QUIC)
<quic_sbillaka at quicinc.com> wrote:
>
> Hi Doug,
>
> >On Thu, Apr 21, 2022 at 7:37 AM Sankeerth Billakanti
> ><quic_sbillaka at quicinc.com> wrote:
> >>
> >> The panel-edp enables the eDP panel power during probe, get_modes and
> >> pre-enable. The eDP connect and disconnect interrupts for the eDP/DP
> >> controller are directly dependent on panel power. As eDP display can
> >> be assumed as always connected, the controller driver can skip the eDP
> >> connect and disconnect interrupts. Any disruption in the link status
> >> will be indicated via the IRQ_HPD interrupts.
> >>
> >> So, the eDP controller driver can just enable the IRQ_HPD and replug
> >> interrupts. The DP controller driver still needs to enable all the
> >> interrupts.
> >>
> >> Signed-off-by: Sankeerth Billakanti <quic_sbillaka at quicinc.com>
> >> ---
> >> Changes in v8:
> >> - add comment explaining the interrupt status return
> >>
> >> Changes in v7:
> >> - reordered the patch in the series
> >> - modified the return statement for isr
> >> - connector check modified to just check for eDP
> >>
> >> drivers/gpu/drm/msm/dp/dp_catalog.c | 18 ++++++++++++------
> >> drivers/gpu/drm/msm/dp/dp_display.c | 22 +++++++++++++++++++++-
> >> 2 files changed, 33 insertions(+), 7 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c
> >> b/drivers/gpu/drm/msm/dp/dp_catalog.c
> >> index fac815f..3a298e9 100644
> >> --- a/drivers/gpu/drm/msm/dp/dp_catalog.c
> >> +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
> >> @@ -569,10 +569,6 @@ void dp_catalog_ctrl_hpd_config(struct dp_catalog
> >> *dp_catalog)
> >>
> >> u32 reftimer = dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER);
> >>
> >> - /* enable HPD plug and unplug interrupts */
> >> - dp_catalog_hpd_config_intr(dp_catalog,
> >> - DP_DP_HPD_PLUG_INT_MASK |
> >DP_DP_HPD_UNPLUG_INT_MASK, true);
> >> -
> >> /* Configure REFTIMER and enable it */
> >> reftimer |= DP_DP_HPD_REFTIMER_ENABLE;
> >> dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer); @@
> >> -599,13 +595,23 @@ u32 dp_catalog_hpd_get_intr_status(struct
> >> dp_catalog *dp_catalog) {
> >> struct dp_catalog_private *catalog = container_of(dp_catalog,
> >> struct dp_catalog_private, dp_catalog);
> >> - int isr = 0;
> >> + int isr, mask;
> >>
> >> isr = dp_read_aux(catalog, REG_DP_DP_HPD_INT_STATUS);
> >> dp_write_aux(catalog, REG_DP_DP_HPD_INT_ACK,
> >> (isr & DP_DP_HPD_INT_MASK));
> >> + mask = dp_read_aux(catalog, REG_DP_DP_HPD_INT_MASK);
> >>
> >> - return isr;
> >> + /*
> >> + * REG_DP_DP_HPD_INT_STATUS reports the status of all interrupts
> >> + * irrespective of their masked status. The HW interrupt will not be
> >> + * generated if an interrupt is masked. However, the interrupt status
> >> + * bit in the register will still be set. The eDP controller driver
> >> + * masks the plug and unplug interrupts unlike DP controller which
> >> + * unmasks all the interrupts. So, do not report the status of the
> >> + * masked interrupts.
> >> + */
> >> + return isr & (mask | ~DP_DP_HPD_INT_MASK);
> >
> >What's still missing in your comments is why you aren't just doing "return isr &
> >mask;". In other words, why is the API for HPD bits different from the API for
> >non-HPD bits? What code out there wants to know about non-HPD interrupts
> >even if they are masked?
>
> The mask register bitfields are different from the INT_STATUS register.
> The INT_STATUS register has additional bits [31:28] which indicates the HPD state machine
> status and [3:0] indicates the actual generated/set interrupt. The fields [3:0] are similar to
> the mask and ack interrupts.
>
> #define DP_DP_HPD_STATE_STATUS_CONNECTED (0x40000000)
> #define DP_DP_HPD_STATE_STATUS_PENDING (0x20000000)
> #define DP_DP_HPD_STATE_STATUS_DISCONNECTED (0x00000000)
> #define DP_DP_HPD_STATE_STATUS_MASK (0xE0000000)
>
> So, earlier I returned isr & (mask | DP_DP_HPD_STATE_STATUS_MASK);
>
> Actually, there is no reason to do this. We can just do the below:
> return isr & mask;
>
> >
> >Actually, thinking about this more, my preference would be this:
> >
> >a) Rename the existing function to dp_catalog_hpd_get_intr_status_raw()
> >
> >b) Create a new function called dp_catalog_hpd_get_intr_status() whose
> >implementation is:
> >
> > return dp_catalog_hpd_get_intr_status_raw() & mask;
> >
> >Then any callers who care about the raw status can be changed to call
> >dp_catalog_hpd_get_intr_status_raw(). If no callers need
> >dp_catalog_hpd_get_intr_status_raw() then you don't actually need to
> >create this function.
> >
>
> There is no caller for raw status. All interrupts are unmasked for DP.
> While handling the aux interrupts generated during the transfer call from panel probe,
> we read that the HPD interrupt status [3:0] bit0 is set and proceed to handle connect like DP.
> We experimented to find out that the connect interrupt is not generated but just the status
> bit is set.
>
> As the interrupts are generated over a single MDSS line, the controller driver has to read all the
> interrupt status registers and handle all the set interrupt bits. So, while handling aux transfer
> interrupts, we were proceeding to handle connect interrupt also as a consequence.
Ah, I see. There aren't other _interrupts_ in this register. There's
just other status info that someone jammed into this register. Got it.
So with this comment I'm happy with my Reviewed-by:
/*
* We only want to return interrupts that are unmasked to the caller.
* However, the interrupt status field also contains other
* informational bits about the HPD state status, so we only mask
* out the part of the register that tells us about which interrupts
* are pending.
*/
-Doug
More information about the Freedreno
mailing list