[PATCH v2 6/9] drm/i915/dmc: Reload pipe DMC MMIO registers for pipe C/D on various platforms
Shankar, Uma
uma.shankar at intel.com
Wed Jun 18 14:32:39 UTC 2025
> -----Original Message-----
> From: Intel-xe <intel-xe-bounces at lists.freedesktop.org> On Behalf Of Ville
> Syrjala
> Sent: Tuesday, June 17, 2025 10:38 PM
> To: intel-gfx at lists.freedesktop.org
> Cc: intel-xe at lists.freedesktop.org
> Subject: [PATCH v2 6/9] drm/i915/dmc: Reload pipe DMC MMIO registers for pipe
> C/D on various platforms
>
> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
>
> On ADL/MTL pipe DMC MMIO state evidently lives in PG0. The main DMC
> saves/restores it for pipes A/B, but for pipes C/D we have to do it in the driver.
>
> On PTL the situation is mostly the same, except the main DMC firmware doesn't
> seem to have the PG0 save/restore code anymore, and instead the hardware (or
> maybe Punit?) seems to take care of this job now. Pipes C/D still need a manual
> restore by the driver.
>
> On LNL I've been unable to lose any pipe DMC state, despite the main DMC
> firmware still implementing the PG0 save/restore for pipes A/B.
> Not sure what's going on here.
>
> On DG2 I've also not been able to lose the pipe DMC state. DG2 doesn't support
> DC6, so that might explain part of it. But even
> DC9 doesn't make a difference here. Perhaps PG0 is just always on for DG2?
>
> BMG I've not tested at all. The main DMC firmware does appaer to implement the
> PG0 pipe A/B save/restore logic.
Nice to get the behaviour on all the platforms, I think we can even ask DMC team to get
this properly documented in spec as well.
Changes Look Good to me.
Reviewed-by: Uma Shankar <uma.shankar at intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
> ---
> drivers/gpu/drm/i915/display/intel_dmc.c | 67 +++++++++++++++++++++---
> 1 file changed, 61 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c
> b/drivers/gpu/drm/i915/display/intel_dmc.c
> index fd99c4645260..dd15d35fbae8 100644
> --- a/drivers/gpu/drm/i915/display/intel_dmc.c
> +++ b/drivers/gpu/drm/i915/display/intel_dmc.c
> @@ -575,8 +575,18 @@ static u32 dmc_mmiodata(struct intel_display *display,
> return dmc->dmc_info[dmc_id].mmiodata[i];
> }
>
> -static void dmc_load_program(struct intel_display *display,
> - enum intel_dmc_id dmc_id)
> +static void dmc_load_mmio(struct intel_display *display, enum
> +intel_dmc_id dmc_id) {
> + struct intel_dmc *dmc = display_to_dmc(display);
> + int i;
> +
> + for (i = 0; i < dmc->dmc_info[dmc_id].mmio_count; i++) {
> + intel_de_write(display, dmc->dmc_info[dmc_id].mmioaddr[i],
> + dmc_mmiodata(display, dmc, dmc_id, i));
> + }
> +}
> +
> +static void dmc_load_program(struct intel_display *display, enum
> +intel_dmc_id dmc_id)
> {
> struct intel_dmc *dmc = display_to_dmc(display);
> int i;
> @@ -593,10 +603,7 @@ static void dmc_load_program(struct intel_display
> *display,
>
> preempt_enable();
>
> - for (i = 0; i < dmc->dmc_info[dmc_id].mmio_count; i++) {
> - intel_de_write(display, dmc->dmc_info[dmc_id].mmioaddr[i],
> - dmc_mmiodata(display, dmc, dmc_id, i));
> - }
> + dmc_load_mmio(display, dmc_id);
> }
>
> static bool need_pipedmc_load_program(struct intel_display *display) @@ -605,6
> +612,52 @@ static bool need_pipedmc_load_program(struct intel_display
> *display)
> return DISPLAY_VER(display) == 12;
> }
>
> +static bool need_pipedmc_load_mmio(struct intel_display *display, enum
> +pipe pipe) {
> + /*
> + * PTL:
> + * - pipe A/B DMC doesn't need save/restore
> + * - pipe C/D DMC is in PG0, needs manual save/restore
> + */
> + if (DISPLAY_VER(display) == 30)
> + return pipe >= PIPE_C;
> +
> + /*
> + * FIXME LNL unclear, main DMC firmware has the pipe DMC A/B PG0
> + * save/restore, but so far unable to see the loss of pipe DMC state
> + * in action. Are we just failing to turn off PG0 due to some other
> + * SoC level stuff?
> + */
> + if (DISPLAY_VER(display) == 20)
> + return false;
> +
> + /*
> + * FIXME BMG untested, main DMC firmware has the
> + * pipe DMC A/B PG0 save/restore...
> + */
> + if (display->platform.battlemage)
> + return false;
> +
> + /*
> + * DG2:
> + * - Pipe DMCs presumably in PG0?
> + * - No DC6, and even DC9 doesn't seem to result
> + * in loss of DMC state for whatever reason
> + */
> + if (display->platform.dg2)
> + return false;
> +
> + /*
> + * ADL/MTL:
> + * - pipe A/B DMC is in PG0, saved/restored by the main DMC
> + * - pipe C/D DMC is in PG0, needs manual save/restore
> + */
> + if (IS_DISPLAY_VER(display, 13, 14))
> + return pipe >= PIPE_C;
> +
> + return false;
> +}
> +
> void intel_dmc_enable_pipe(struct intel_display *display, enum pipe pipe) {
> enum intel_dmc_id dmc_id = PIPE_TO_DMC_ID(pipe); @@ -614,6 +667,8
> @@ void intel_dmc_enable_pipe(struct intel_display *display, enum pipe pipe)
>
> if (need_pipedmc_load_program(display))
> dmc_load_program(display, dmc_id);
> + else if (need_pipedmc_load_mmio(display, pipe))
> + dmc_load_mmio(display, dmc_id);
>
> if (DISPLAY_VER(display) >= 20) {
> intel_de_write(display, PIPEDMC_INTERRUPT(pipe),
> pipedmc_interrupt_mask(display));
> --
> 2.49.0
More information about the Intel-xe
mailing list