[Intel-gfx] [PATCH] drm/i915/pps: added get_pps_idx() hook as part of pps_get_register() cleanup
Manna, Animesh
animesh.manna at intel.com
Fri Aug 5 08:11:58 UTC 2022
> -----Original Message-----
> From: Nikula, Jani <jani.nikula at intel.com>
> Sent: Wednesday, August 3, 2022 1:44 PM
> To: Manna, Animesh <animesh.manna at intel.com>; intel-
> gfx at lists.freedesktop.org
> Cc: ville.syrjala at linux.intel.com; Shankar, Uma <uma.shankar at intel.com>;
> Manna, Animesh <animesh.manna at intel.com>
> Subject: Re: [PATCH] drm/i915/pps: added get_pps_idx() hook as part of
> pps_get_register() cleanup
>
> On Wed, 03 Aug 2022, Animesh Manna <animesh.manna at intel.com> wrote:
> > To support dual LFP two instances of pps added from display gen12 onwards.
> > Few older platform like VLV also has dual pps support but handling is
> > different. So added separate hook get_pps_idx() to formulate which pps
> > instance to used for a soecific LFP on a specific platform.
> >
> > Simplified pps_get_register() which use get_pps_idx() hook to derive
> > the pps instance and get_pps_idx() will be initialized at pps_init().
> >
> > Signed-off-by: Animesh Manna <animesh.manna at intel.com>
> > ---
> > drivers/gpu/drm/i915/display/intel_bios.c | 5 ++++
> > drivers/gpu/drm/i915/display/intel_bios.h | 1 +
> > .../drm/i915/display/intel_display_types.h | 2 ++
> > drivers/gpu/drm/i915/display/intel_pps.c | 25 ++++++++++++++-----
> > 4 files changed, 27 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_bios.c
> > b/drivers/gpu/drm/i915/display/intel_bios.c
> > index 51dde5bfd956..42315615a728 100644
> > --- a/drivers/gpu/drm/i915/display/intel_bios.c
> > +++ b/drivers/gpu/drm/i915/display/intel_bios.c
> > @@ -611,6 +611,11 @@ static int opregion_get_panel_type(struct
> drm_i915_private *i915,
> > return intel_opregion_get_panel_type(i915);
> > }
> >
> > +bool intel_bios_is_lfp2(struct intel_encoder *encoder) {
> > + return encoder->devdata && encoder->devdata->child.handle ==
> > +DEVICE_HANDLE_LFP2; }
>
> AFAICS the encoder never really needs to know whether it's "lfp1" or "lfp2". It
> needs to know the pps controller number.
>
> > +
> > static int vbt_get_panel_type(struct drm_i915_private *i915,
> > const struct intel_bios_encoder_data *devdata,
> > const struct edid *edid)
> > diff --git a/drivers/gpu/drm/i915/display/intel_bios.h
> > b/drivers/gpu/drm/i915/display/intel_bios.h
> > index e47582b0de0a..aea72a87ea2c 100644
> > --- a/drivers/gpu/drm/i915/display/intel_bios.h
> > +++ b/drivers/gpu/drm/i915/display/intel_bios.h
> > @@ -251,6 +251,7 @@ bool intel_bios_is_lspcon_present(const struct
> drm_i915_private *i915,
> > enum port port);
> > bool intel_bios_is_lane_reversal_needed(const struct drm_i915_private *i915,
> > enum port port);
> > +bool intel_bios_is_lfp2(struct intel_encoder *encoder);
> > enum aux_ch intel_bios_port_aux_ch(struct drm_i915_private *dev_priv,
> > enum port port); bool intel_bios_get_dsc_params(struct intel_encoder
> *encoder,
> > struct intel_crtc_state *crtc_state, diff --git
> > a/drivers/gpu/drm/i915/display/intel_display_types.h
> > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > index 0da9b208d56e..95f71a572b07 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > @@ -1723,6 +1723,8 @@ struct intel_dp {
> >
> > /* When we last wrote the OUI for eDP */
> > unsigned long last_oui_write;
> > +
> > + int (*get_pps_idx)(struct intel_dp *intel_dp);
>
> Making this a function pointer should be a separate step. Please don't try to do
> too many things at once. Rule of thumb, one change per patch.
>
> Also, this should be placed near the other function pointer members in struct
> intel_dp.
>
> > };
> >
> > enum lspcon_vendor {
> > diff --git a/drivers/gpu/drm/i915/display/intel_pps.c
> > b/drivers/gpu/drm/i915/display/intel_pps.c
> > index 1b21a341962f..c9cdb302d318 100644
> > --- a/drivers/gpu/drm/i915/display/intel_pps.c
> > +++ b/drivers/gpu/drm/i915/display/intel_pps.c
> > @@ -231,6 +231,17 @@ bxt_power_sequencer_idx(struct intel_dp *intel_dp)
> > return backlight_controller;
> > }
> >
> > +static int
> > +gen12_power_sequencer_idx(struct intel_dp *intel_dp) {
> > + struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
> > +
> > + if (intel_bios_is_lfp2(encoder))
> > + return 1;
>
> This is actually not how this works. The bxt_power_sequencer_idx() matches
> bspec 20149: "PWM and PPS are assumed to be aligned to be from same block
> and not mismatch" i.e. the backlight controller id and the pps id are the same.
> There are no requirements to map lfp# and pps controller like this, even if it
> might be true in the common case.
>
> The problem is we need the information *before* we call
> intel_bios_init_panel().
>
> It's a catch-22. We need the pps id to read the panel EDID, and we need the
> panel EDID to choose the correct panel type in VBT, which we need to get the
> pps id from the VBT.
>
> This is highlighted in [1]. The 2nd eDP (which is not even physically present, only
> in the VBT, *sigh*) screws up the PPS for the 1st during init.
>
> I think Ville had some ideas here.
I will check with Ville, currently not very clear about the solution. Try to get some info how it is handled in windows
Regards,
Animesh
>
>
> BR,
> Jani.
>
>
> [1] https://gitlab.freedesktop.org/drm/intel/-/issues/5531
>
>
> > +
> > + return 0;
> > +}
> > +
> > typedef bool (*vlv_pipe_check)(struct drm_i915_private *dev_priv,
> > enum pipe pipe);
> >
> > @@ -361,15 +372,10 @@ static void intel_pps_get_registers(struct intel_dp
> *intel_dp,
> > struct pps_registers *regs)
> > {
> > struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > - int pps_idx = 0;
> > + int pps_idx = intel_dp->get_pps_idx(intel_dp);
> >
> > memset(regs, 0, sizeof(*regs));
> >
> > - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
> > - pps_idx = bxt_power_sequencer_idx(intel_dp);
> > - else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> > - pps_idx = vlv_power_sequencer_pipe(intel_dp);
> > -
> > regs->pp_ctrl = PP_CONTROL(pps_idx);
> > regs->pp_stat = PP_STATUS(pps_idx);
> > regs->pp_on = PP_ON_DELAYS(pps_idx); @@ -1431,6 +1437,13 @@
> void
> > intel_pps_init(struct intel_dp *intel_dp)
> > intel_dp->pps.initializing = true;
> > INIT_DELAYED_WORK(&intel_dp->pps.panel_vdd_work,
> > edp_panel_vdd_work);
> >
> > + if (IS_GEMINILAKE(i915) || IS_BROXTON(i915))
> > + intel_dp->get_pps_idx = bxt_power_sequencer_idx;
> > + else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
> > + intel_dp->get_pps_idx = vlv_power_sequencer_pipe;
> > + else if (DISPLAY_VER(i915) >= 12)
> > + intel_dp->get_pps_idx = gen12_power_sequencer_idx;
> > +
> > pps_init_timestamps(intel_dp);
> >
> > with_intel_pps_lock(intel_dp, wakeref) {
>
> --
> Jani Nikula, Intel Open Source Graphics Center
More information about the Intel-gfx
mailing list