On Tue, 20 Aug 2024, Matt Roper <[email protected]> wrote:
> On Tue, Aug 20, 2024 at 10:00:40PM +0300, Jani Nikula wrote:
>> Both i915 and xe have code to identify display steppings. Start
>> deduplicating this by, uh, adding a third copy in display code. This is
>> not yet used for anything other than debug logging. We'll switch over
>> later.
>> 
>> For platforms before GMD ID, attach the mapping from PCI revision to
>> stepping in the platform and subplatform descriptors. This is a
>> considerably cleaner approach than having it completely separate.
>> 
>> Also add a separate field for stepping in display runtime info,
>> preserving the value from GMD ID.
>> 
>> Signed-off-by: Jani Nikula <[email protected]>
>> ---
>>  .../drm/i915/display/intel_display_device.c   | 224 +++++++++++++++++-
>>  .../drm/i915/display/intel_display_device.h   |   3 +-
>>  .../drm/xe/compat-i915-headers/intel_step.h   |   1 +
>>  3 files changed, 216 insertions(+), 12 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c 
>> b/drivers/gpu/drm/i915/display/intel_display_device.c
>> index a31f89df2c0a..1ac3ab3954a1 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_device.c
>> +++ b/drivers/gpu/drm/i915/display/intel_display_device.c
>> @@ -16,14 +16,25 @@
>>  #include "intel_display_power.h"
>>  #include "intel_display_reg_defs.h"
>>  #include "intel_fbc.h"
>> +#include "intel_step.h"
>>  
>>  __diag_push();
>>  __diag_ignore_all("-Woverride-init", "Allow field initialization overrides 
>> for display info");
>>  
>> +struct stepping_desc {
>> +    const enum intel_step *map; /* revid to step map */
>> +    size_t size; /* map size */
>> +};
>> +
>> +#define STEP_INFO(_map)                             \
>> +    .step_info.map = _map,                  \
>> +    .step_info.size = ARRAY_SIZE(_map)
>> +
>>  struct subplatform_desc {
>>      enum intel_display_subplatform subplatform;
>>      const char *name;
>>      const u16 *pciidlist;
>> +    struct stepping_desc step_info;
>>  };
>>  
>>  struct platform_desc {
>> @@ -31,6 +42,7 @@ struct platform_desc {
>>      const char *name;
>>      const struct subplatform_desc *subplatforms;
>>      const struct intel_display_device_info *info; /* NULL for GMD ID */
>> +    struct stepping_desc step_info;
>>  };
>>  
>>  #define PLATFORM(_platform)                  \
>> @@ -610,6 +622,13 @@ static const u16 skl_ulx_ids[] = {
>>      0
>>  };
>>  
>> +static const enum intel_step skl_steppings[] = {
>> +    [0x6] = STEP_G0,
>> +    [0x7] = STEP_H0,
>> +    [0x9] = STEP_J0,
>> +    [0xA] = STEP_I1,
>> +};
>> +
>>  static const struct platform_desc skl_desc = {
>>      PLATFORM(SKYLAKE),
>>      .subplatforms = (const struct subplatform_desc[]) {
>> @@ -618,6 +637,7 @@ static const struct platform_desc skl_desc = {
>>              {},
>>      },
>>      .info = &skl_display,
>> +    STEP_INFO(skl_steppings),
>>  };
>>  
>>  static const u16 kbl_ult_ids[] = {
>> @@ -634,6 +654,16 @@ static const u16 kbl_ulx_ids[] = {
>>      0
>>  };
>>  
>> +static const enum intel_step kbl_steppings[] = {
>> +    [1] = STEP_B0,
>> +    [2] = STEP_B0,
>> +    [3] = STEP_B0,
>> +    [4] = STEP_C0,
>> +    [5] = STEP_B1,
>> +    [6] = STEP_B1,
>> +    [7] = STEP_C0,
>> +};
>> +
>>  static const struct platform_desc kbl_desc = {
>>      PLATFORM(KABYLAKE),
>>      .subplatforms = (const struct subplatform_desc[]) {
>> @@ -642,6 +672,7 @@ static const struct platform_desc kbl_desc = {
>>              {},
>>      },
>>      .info = &skl_display,
>> +    STEP_INFO(kbl_steppings),
>>  };
>>  
>>  static const u16 cfl_ult_ids[] = {
>> @@ -706,6 +737,13 @@ static const struct platform_desc cml_desc = {
>>              BIT(TRANSCODER_DSI_A) | BIT(TRANSCODER_DSI_C), \
>>      .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C)
>>  
>> +static const enum intel_step bxt_steppings[] = {
>> +    [0xA] = STEP_C0,
>> +    [0xB] = STEP_C0,
>> +    [0xC] = STEP_D0,
>> +    [0xD] = STEP_E0,
>> +};
>> +
>>  static const struct platform_desc bxt_desc = {
>>      PLATFORM(BROXTON),
>>      .info = &(const struct intel_display_device_info) {
>> @@ -714,6 +752,11 @@ static const struct platform_desc bxt_desc = {
>>  
>>              .__runtime_defaults.ip.ver = 9,
>>      },
>> +    STEP_INFO(bxt_steppings),
>> +};
>> +
>> +static const enum intel_step glk_steppings[] = {
>> +    [3] = STEP_B0,
>>  };
>>  
>>  static const struct platform_desc glk_desc = {
>> @@ -725,6 +768,7 @@ static const struct platform_desc glk_desc = {
>>  
>>              .__runtime_defaults.ip.ver = 10,
>>      },
>> +    STEP_INFO(glk_steppings),
>>  };
>>  
>>  #define ICL_DISPLAY \
>> @@ -773,6 +817,10 @@ static const u16 icl_port_f_ids[] = {
>>      0
>>  };
>>  
>> +static const enum intel_step icl_steppings[] = {
>> +    [7] = STEP_D0,
>> +};
>> +
>>  static const struct platform_desc icl_desc = {
>>      PLATFORM(ICELAKE),
>>      .subplatforms = (const struct subplatform_desc[]) {
>> @@ -784,6 +832,7 @@ static const struct platform_desc icl_desc = {
>>  
>>              .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | 
>> BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
>>      },
>> +    STEP_INFO(icl_steppings),
>>  };
>>  
>>  static const struct intel_display_device_info jsl_ehl_display = {
>> @@ -792,14 +841,21 @@ static const struct intel_display_device_info 
>> jsl_ehl_display = {
>>      .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) 
>> | BIT(PORT_D),
>>  };
>>  
>> +static const enum intel_step jsl_ehl_steppings[] = {
>> +    [0] = STEP_A0,
>> +    [1] = STEP_B0,
>> +};
>> +
>>  static const struct platform_desc jsl_desc = {
>>      PLATFORM(JASPERLAKE),
>>      .info = &jsl_ehl_display,
>> +    STEP_INFO(jsl_ehl_steppings),
>>  };
>>  
>>  static const struct platform_desc ehl_desc = {
>>      PLATFORM(ELKHARTLAKE),
>>      .info = &jsl_ehl_display,
>> +    STEP_INFO(jsl_ehl_steppings),
>>  };
>>  
>>  #define XE_D_DISPLAY \
>> @@ -850,10 +906,23 @@ static const u16 tgl_uy_ids[] = {
>>      0
>>  };
>>  
>> +static const enum intel_step tgl_steppings[] = {
>> +    [0] = STEP_B0,
>> +    [1] = STEP_D0,
>> +};
>> +
>> +static const enum intel_step tgl_uy_steppings[] = {
>> +    [0] = STEP_A0,
>> +    [1] = STEP_C0,
>> +    [2] = STEP_C0,
>> +    [3] = STEP_D0,
>> +};
>> +
>>  static const struct platform_desc tgl_desc = {
>>      PLATFORM(TIGERLAKE),
>>      .subplatforms = (const struct subplatform_desc[]) {
>> -            { INTEL_DISPLAY_TIGERLAKE_UY, "UY", tgl_uy_ids },
>> +            { INTEL_DISPLAY_TIGERLAKE_UY, "UY", tgl_uy_ids,
>> +              STEP_INFO(tgl_uy_steppings) },
>>              {},
>>      },
>>      .info = &(const struct intel_display_device_info) {
>> @@ -866,6 +935,12 @@ static const struct platform_desc tgl_desc = {
>>              .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
>>              BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4) | 
>> BIT(PORT_TC5) | BIT(PORT_TC6),
>>      },
>> +    STEP_INFO(tgl_steppings),
>> +};
>> +
>> +static const enum intel_step dg1_steppings[] = {
>> +    [0] = STEP_A0,
>> +    [1] = STEP_B0,
>>  };
>>  
>>  static const struct platform_desc dg1_desc = {
>> @@ -876,6 +951,13 @@ static const struct platform_desc dg1_desc = {
>>              .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
>>              BIT(PORT_TC1) | BIT(PORT_TC2),
>>      },
>> +    STEP_INFO(dg1_steppings),
>> +};
>> +
>> +static const enum intel_step rkl_steppings[] = {
>> +    [0] = STEP_A0,
>> +    [1] = STEP_B0,
>> +    [4] = STEP_C0,
>>  };
>>  
>>  static const struct platform_desc rkl_desc = {
>> @@ -892,6 +974,7 @@ static const struct platform_desc rkl_desc = {
>>              .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
>>              BIT(PORT_TC1) | BIT(PORT_TC2),
>>      },
>> +    STEP_INFO(rkl_steppings),
>>  };
>>  
>>  static const u16 adls_rpls_ids[] = {
>> @@ -899,10 +982,24 @@ static const u16 adls_rpls_ids[] = {
>>      0
>>  };
>>  
>> +static const enum intel_step adl_s_steppings[] = {
>> +    [0x0] = STEP_A0,
>> +    [0x1] = STEP_A2,
>> +    [0x4] = STEP_B0,
>> +    [0x8] = STEP_B0,
>> +    [0xC] = STEP_C0,
>> +};
>> +
>> +static const enum intel_step adl_s_rpl_s_steppings[] = {
>> +    [0x4] = STEP_D0,
>> +    [0xC] = STEP_C0,
>> +};
>> +
>>  static const struct platform_desc adl_s_desc = {
>>      PLATFORM(ALDERLAKE_S),
>>      .subplatforms = (const struct subplatform_desc[]) {
>> -            { INTEL_DISPLAY_ALDERLAKE_S_RAPTORLAKE_S, "RPL-S", 
>> adls_rpls_ids },
>> +            { INTEL_DISPLAY_ALDERLAKE_S_RAPTORLAKE_S, "RPL-S", 
>> adls_rpls_ids,
>> +              STEP_INFO(adl_s_rpl_s_steppings) },
>>              {},
>>      },
>>      .info = &(const struct intel_display_device_info) {
>> @@ -913,6 +1010,7 @@ static const struct platform_desc adl_s_desc = {
>>              .__runtime_defaults.port_mask = BIT(PORT_A) |
>>              BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4),
>>      },
>> +    STEP_INFO(adl_s_steppings),
>>  };
>>  
>>  #define XE_LPD_FEATURES \
>> @@ -986,15 +1084,34 @@ static const u16 adlp_rplp_ids[] = {
>>      0
>>  };
>>  
>> +static const enum intel_step adl_p_steppings[] = {
>> +    [0x0] = STEP_A0,
>> +    [0x4] = STEP_B0,
>> +    [0x8] = STEP_C0,
>> +    [0xC] = STEP_D0,
>> +};
>> +
>> +static const enum intel_step adl_p_adl_n_steppings[] = {
>> +    [0x0] = STEP_D0,
>> +};
>> +
>> +static const enum intel_step adl_p_rpl_pu_steppings[] = {
>> +    [0x4] = STEP_E0,
>> +};
>> +
>>  static const struct platform_desc adl_p_desc = {
>>      PLATFORM(ALDERLAKE_P),
>>      .subplatforms = (const struct subplatform_desc[]) {
>> -            { INTEL_DISPLAY_ALDERLAKE_P_ALDERLAKE_N, "ADL-N", adlp_adln_ids 
>> },
>> -            { INTEL_DISPLAY_ALDERLAKE_P_RAPTORLAKE_U, "RPL-U", 
>> adlp_rplu_ids },
>> -            { INTEL_DISPLAY_ALDERLAKE_P_RAPTORLAKE_P, "RPL-P", 
>> adlp_rplp_ids },
>> +            { INTEL_DISPLAY_ALDERLAKE_P_ALDERLAKE_N, "ADL-N", adlp_adln_ids,
>> +              STEP_INFO(adl_p_adl_n_steppings) },
>> +            { INTEL_DISPLAY_ALDERLAKE_P_RAPTORLAKE_P, "RPL-P", 
>> adlp_rplp_ids,
>> +              STEP_INFO(adl_p_rpl_pu_steppings) },
>> +            { INTEL_DISPLAY_ALDERLAKE_P_RAPTORLAKE_U, "RPL-U", 
>> adlp_rplu_ids,
>> +              STEP_INFO(adl_p_rpl_pu_steppings) },
>>              {},
>>      },
>>      .info = &xe_lpd_display,
>> +    STEP_INFO(adl_p_steppings),
>>  };
>>  
>>  static const struct intel_display_device_info xe_hpd_display = {
>> @@ -1023,12 +1140,33 @@ static const u16 dg2_g12_ids[] = {
>>      0
>>  };
>>  
>> +static const enum intel_step dg2_g10_steppings[] = {
>> +    [0x0] = STEP_A0,
>> +    [0x1] = STEP_A0,
>> +    [0x4] = STEP_B0,
>> +    [0x8] = STEP_C0,
>> +};
>> +
>> +static const enum intel_step dg2_g11_steppings[] = {
>> +    [0x0] = STEP_B0,
>> +    [0x4] = STEP_C0,
>> +    [0x5] = STEP_C0,
>> +};
>> +
>> +static const enum intel_step dg2_g12_steppings[] = {
>> +    [0x0] = STEP_C0,
>> +    [0x1] = STEP_C0,
>> +};
>> +
>>  static const struct platform_desc dg2_desc = {
>>      PLATFORM(DG2),
>>      .subplatforms = (const struct subplatform_desc[]) {
>> -            { INTEL_DISPLAY_DG2_G10, "G10", dg2_g10_ids },
>> -            { INTEL_DISPLAY_DG2_G11, "G11", dg2_g11_ids },
>> -            { INTEL_DISPLAY_DG2_G12, "G12", dg2_g12_ids },
>> +            { INTEL_DISPLAY_DG2_G10, "G10", dg2_g10_ids,
>> +              STEP_INFO(dg2_g10_steppings) },
>> +            { INTEL_DISPLAY_DG2_G11, "G11", dg2_g11_ids,
>> +              STEP_INFO(dg2_g11_steppings) },
>> +            { INTEL_DISPLAY_DG2_G12, "G12", dg2_g12_ids,
>> +              STEP_INFO(dg2_g12_steppings) },
>>              {},
>>      },
>>      .info = &xe_hpd_display,
>> @@ -1261,13 +1399,66 @@ find_subplatform_desc(struct pci_dev *pdev, const 
>> struct platform_desc *desc)
>>      return NULL;
>>  }
>>  
>> +static enum intel_step get_pre_gmdid_step(struct intel_display *display,
>> +                                      const struct stepping_desc *main,
>> +                                      const struct stepping_desc *sub)
>> +{
>> +    struct pci_dev *pdev = to_pci_dev(display->drm->dev);
>> +    const enum intel_step *map = main->map;
>> +    int size = main->size;
>> +    int revision = pdev->revision;
>> +    enum intel_step step;
>> +
>> +    /* subplatform stepping info trumps main platform info */
>> +    if (sub->map && sub->size) {
>> +            map = sub->map;
>> +            size = sub->size;
>> +    }
>> +
>> +    /* not all platforms define steppings, and it's fine */
>> +    if (!map || !size)
>> +            return STEP_NONE;
>> +
>> +    if (revision < size && map[revision] != STEP_NONE) {
>> +            step = map[revision];
>> +    } else {
>> +            drm_warn(display->drm, "Unknown revision 0x%02x\n", revision);
>> +
>> +            /*
>> +             * If we hit a gap in the revision to step map, use the 
>> information
>> +             * for the next revision.
>> +             *
>> +             * This may be wrong in all sorts of ways, especially if the
>> +             * steppings in the array are not monotonically increasing, but
>> +             * it's better than defaulting to 0.
>> +             */
>> +            while (revision < size && map[revision] == STEP_NONE)
>> +                    revision++;
>> +
>> +            if (revision < size) {
>> +                    drm_dbg_kms(display->drm, "Using display stepping for 
>> revision 0x%02x\n",
>> +                                revision);
>> +                    step = map[revision];
>> +            } else {
>> +                    drm_dbg_kms(display->drm, "Using future display 
>> stepping\n");
>> +                    step = STEP_FUTURE;
>> +            }
>> +    }
>> +
>> +    drm_WARN_ON(display->drm, step == STEP_NONE);
>> +
>> +    return step;
>> +}
>> +
>>  void intel_display_device_probe(struct drm_i915_private *i915)
>>  {
>> +    struct intel_display *display = &i915->display;
>>      struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
>>      const struct intel_display_device_info *info;
>>      struct intel_display_ip_ver ip_ver = {};
>>      const struct platform_desc *desc;
>>      const struct subplatform_desc *subdesc;
>> +    enum intel_step step;
>>  
>>      /* Add drm device backpointer as early as possible. */
>>      i915->display.drm = &i915->drm;
>> @@ -1307,13 +1498,24 @@ void intel_display_device_probe(struct 
>> drm_i915_private *i915)
>>              DISPLAY_RUNTIME_INFO(i915)->subplatform = subdesc->subplatform;
>>      }
>>  
>> -    if (ip_ver.ver || ip_ver.rel || ip_ver.step)
>> +    if (ip_ver.ver || ip_ver.rel || ip_ver.step) {
>>              DISPLAY_RUNTIME_INFO(i915)->ip = ip_ver;
>> +            step = STEP_A0 + ip_ver.step;
>> +            if (step > STEP_FUTURE) {
>> +                    drm_dbg_kms(display->drm, "Using future display 
>> stepping\n");
>> +                    step = STEP_FUTURE;
>> +            }
>> +    } else {
>> +            step = get_pre_gmdid_step(display, &desc->step_info, 
>> &subdesc->step_info);
>
> Can't subdesc still be NULL here?  And if we change this to something
> like "subdesc ? &subdesc->step_info : NULL" then we'll also need a
> nullcheck inside get_pre_gmdid_step as well to prevent a npd.

Indeed, good catch! And CI appears to have caught it too.

Thanks,
Jani.

>
>
> Matt
>
>> +    }
>> +
>> +    DISPLAY_RUNTIME_INFO(i915)->step = step;
>>  
>> -    drm_info(&i915->drm, "Found %s%s%s (device ID %04x) display version 
>> %u.%02u\n",
>> +    drm_info(&i915->drm, "Found %s%s%s (device ID %04x) display version 
>> %u.%02u stepping %s\n",
>>               desc->name, subdesc ? "/" : "", subdesc ? subdesc->name : "",
>>               pdev->device, DISPLAY_RUNTIME_INFO(i915)->ip.ver,
>> -             DISPLAY_RUNTIME_INFO(i915)->ip.rel);
>> +             DISPLAY_RUNTIME_INFO(i915)->ip.rel,
>> +             step != STEP_NONE ? intel_step_name(step) : "N/A");
>>  
>>      return;
>>  
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h 
>> b/drivers/gpu/drm/i915/display/intel_display_device.h
>> index 8bd342658291..1c75cbd68dea 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_device.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_device.h
>> @@ -201,8 +201,9 @@ struct intel_display_runtime_info {
>>      struct intel_display_ip_ver {
>>              u16 ver;
>>              u16 rel;
>> -            u16 step;
>> +            u16 step; /* hardware */
>>      } ip;
>> +    int step; /* symbolic */
>>  
>>      u8 pipe_mask;
>>      u8 cpu_transcoder_mask;
>> diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_step.h 
>> b/drivers/gpu/drm/xe/compat-i915-headers/intel_step.h
>> index ee3f45b668b9..2cf13a572ab0 100644
>> --- a/drivers/gpu/drm/xe/compat-i915-headers/intel_step.h
>> +++ b/drivers/gpu/drm/xe/compat-i915-headers/intel_step.h
>> @@ -8,6 +8,7 @@
>>  
>>  #include "xe_step.h"
>>  
>> +#define intel_step xe_step
>>  #define intel_step_name xe_step_name
>>  
>>  #endif /* __INTEL_STEP_H__ */
>> -- 
>> 2.39.2
>> 

-- 
Jani Nikula, Intel

Reply via email to