[PATCH] drm/i915/display: Skip unavailable power wells based on pipe mask
Gustavo Sousa
gustavo.sousa at intel.com
Fri Jul 18 20:16:20 UTC 2025
Quoting Imre Deak (2025-07-18 14:17:09-03:00)
>On Fri, Jul 18, 2025 at 01:33:26PM -0300, Gustavo Sousa wrote:
>> Quoting Imre Deak (2025-07-18 12:54:11-03:00)
>> >On Thu, Jul 17, 2025 at 09:02:45AM -0300, Gustavo Sousa wrote:
>> >> Quoting Chaitanya Kumar Borah (2025-07-17 02:16:03-03:00)
>> >> >Some power wells are only relevant for certain display pipes. Add a check
>> >> >to ensure we only allocate and initialize power wells whose associated
>> >> >pipes are available on the platform.
>> >> >
>> >> >This avoids unnecessary mapping of power wells, particularly when platforms
>> >> >support a subset of pipes described in the power well descriptors.
>> >> >
>> >> >Suggested-by: Imre Deak <imre.deak at intel.com>
>> >> >Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah at intel.com>
>> >> >---
>> >> > .../i915/display/intel_display_power_map.c | 19 +++++++++++++++++--
>> >> > 1 file changed, 17 insertions(+), 2 deletions(-)
>> >> >
>> >> >diff --git a/drivers/gpu/drm/i915/display/intel_display_power_map.c b/drivers/gpu/drm/i915/display/intel_display_power_map.c
>> >> >index 77268802b55e..ca73e4084354 100644
>> >> >--- a/drivers/gpu/drm/i915/display/intel_display_power_map.c
>> >> >+++ b/drivers/gpu/drm/i915/display/intel_display_power_map.c
>> >> >@@ -1748,6 +1748,16 @@ static void init_power_well_domains(const struct i915_power_well_instance *inst,
>> >> > for_each_power_well_instance_in_desc_list((_descs)->list, (_descs)->count, \
>> >> > (_desc), (_inst))
>> >> >
>> >> >+static bool
>> >> >+is_power_well_available(struct intel_display *display, const struct i915_power_well_desc *desc)
>> >> >+{
>> >> >+ if (desc->irq_pipe_mask &&
>> >> >+ !(desc->irq_pipe_mask & DISPLAY_RUNTIME_INFO(display)->pipe_mask))
>> >>
>> >> According to irq_pipe_mask's documentation, that member contains a "mask
>> >> of pipes whose IRQ logic is backed by the pw". I think we are
>> >> overloading the meaning of that field with this logic.
>> >>
>> >> * Do we have guarantees that irq_pipe_mask will always be associated
>> >> with the power well that powers the pipe?
>> >
>> >It is the case on all the platforms and so it also provides the required
>> >way to identify the power well for a particular pipe. irq_pipe_mask
>> >could be renamed to pipe_mask accordingly.
>>
>> I mean, that *exclusively* powers the pipe(s).
>>
>> As an example, bdw_pwdoms_display appears to be responsible not only for
>> pipe B and C, but also ddi lanes and audio, for example.
>
>Yes, these power wells do support other functionalities as well and so
>they must be registered unconditionally. pipe_mask would still be
>correctly indicating that this is the power well for the pipes in the
>mask; these power wells wouldn't be skipped either during registration,
>since that logic must use a platform pipe power well mask vs. a
>non-fused-off pipe mask.
Yep. I think that works for the platforms that we have today. That said,
this whole thing started because I had the impression that pipe D was
fused-off and that power wells for fused-off pipes should not be
touched.
It turns out I was wrong in both cases:
* I just got confirmation from hardware team that WCL does not have
pipe D neither power well D.
* As you explained in a previous reply, the driver needs to deal with
power wells of fused-off pipes to ensure those get properly powered
off in case whatever was controlling display before the driver takes
control let them enabled.
So, I guess we could either
(1) go back to Chaitanya's original patch;
(2) or tweak this patch to use a mask of pipes supported by the
display IP instead of non-fused-off ones.
I personally would prefer (1), since then we would make the presence of
power wells and mapping more explicit in the code; but I wouldn't be
against (2).
--
Gustavo Sousa
>
>> >> * If the power well that has irq_pipe_mask is also used to power
>> >> something else than the pipes, we could have issues if pipes in that
>> >> mask are fused off.
>> >>
>> >> I'm leaning more toward a solution that makes POWER_DOMAIN_INIT map to
>> >> POWER_DOMAIN_PIPE_* based on DISPLAY_RUNTIME_INFO(display)->pipe_mask. I
>> >> have some idea of how to do that without rewriting code to use a
>> >> hierarchical structure (which IMO would be ideal, but takes more
>> >> effort).
>> >>
>> >> The idea is to, during runtime and initialization of the mapping, set
>> >> the bit respective to POWER_DOMAIN_INIT in each power well that has the
>> >> bit for POWER_DOMAIN_PIPE_* set for non-fused off pipes. That would
>> >> also require removing the POWER_DOMAIN_INIT from the static mapping for
>> >> power wells directly responsible for POWER_DOMAIN_PIPE_*.
>> >
>> >Power wells that don't exist on a platform shouldn't be registered in
>> >the first place, so it's not enough to only remove them from the power
>> >well->domain mapping, while still registering the power well. Otherwise
>> >these non-existant power wells would still be accessed while disabling
>> >any unused power well during driver loading/resume. Also these power
>> >wells non-existant on a platform would be incorrectly listed in debugfs
>> >and other state dumps.
>> >
>> >However, I realized that pipe power wells that do exist on a platform,
>> >but for which the corresponing pipe is fused off (for instance pipe
>> >A/B/C on WCL) we still need to register the power well. On some
>> >platforms at least such power wells may be enabled after HW reset/by
>> >BIOS and so these still need to be checked and disabled if needed during
>> >driver loading/resume. I.e. instead of the above
>>
>> Ah, I see. Yeah, that makes sense. Thanks for the details!
>>
>> Well, although Bspec overview page tells that WCL's display has only
>> pipes A, B and C, the page specific for power wells still lists power
>> well D. So I'm wondering if WCL display just has pipe D fused off and
>> the power well still exists or if power well D being listed in Bspec is
>> just a documentation mistake. I'll check with the hardware team.
>>
>> >
>> >DISPLAY_RUNTIME_INFO(display)->pipe_mask
>> >
>> >something like the following should be used:
>> >
>> >u8 pipe_pw_mask(display)
>> >{
>> > if (DISPLAY_VERx100(display) == 3002)
>> > return BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C);
>> >
>> > return BIT(I915_MAX_PIPES + 1) - 1;
>> >}
>>
>> Well, if power well D does not exist indeed (i.e. not a case of pipe D
>> fused-off), we need either this above or maybe go back to Chaitanya's
>> original patch.
>>
>> I think I prefer the original patch, making the power well mapping
>> explicit.
>>
>> --
>> Gustavo Sousa
>>
>> >
>> >> --
>> >> Gustavo Sousa
>> >>
>> >> >+ return false;
>> >> >+
>> >> >+ return true;
>> >> >+}
>> >> >+
>> >> > static int
>> >> > __set_power_wells(struct i915_power_domains *power_domains,
>> >> > const struct i915_power_well_desc_list *power_well_descs,
>> >> >@@ -1763,8 +1773,10 @@ __set_power_wells(struct i915_power_domains *power_domains,
>> >> > int power_well_count = 0;
>> >> > int plt_idx = 0;
>> >> >
>> >> >- for_each_power_well_instance(power_well_descs, power_well_descs_sz, desc_list, desc, inst)
>> >> >- power_well_count++;
>> >> >+ for_each_power_well_instance(power_well_descs, power_well_descs_sz, desc_list, desc, inst) {
>> >> >+ if (is_power_well_available(display, desc))
>> >> >+ power_well_count++;
>> >> >+ }
>> >> >
>> >> > power_domains->power_well_count = power_well_count;
>> >> > power_domains->power_wells =
>> >> >@@ -1778,6 +1790,9 @@ __set_power_wells(struct i915_power_domains *power_domains,
>> >> > struct i915_power_well *pw = &power_domains->power_wells[plt_idx];
>> >> > enum i915_power_well_id id = inst->id;
>> >> >
>> >> >+ if (!is_power_well_available(display, desc))
>> >> >+ continue;
>> >> >+
>> >> > pw->desc = desc;
>> >> > drm_WARN_ON(display->drm,
>> >> > overflows_type(inst - desc->instances->list, pw->instance_idx));
>> >> >--
>> >> >2.25.1
>> >> >
More information about the Intel-xe
mailing list