On Fri, Nov 14, 2025 at 05:52:08PM -0300, Gustavo Sousa wrote:
> VBT version 264 adds new fields associated to Xe3p_LPD's new ways of
> configuring SoC for TC ports and PHYs.  Update the code to match the
> updates in VBT.
> 
> The new field dedicated_external is used to represent TC ports that are
> connected to PHYs outside of the Type-C subsystem, meaning that they
> behave like dedicated ports and don't require the extra Type-C
> programming.  In an upcoming change, we will update the driver to take
> this field into consideration when detecting the type of port.
> 
> The new field dyn_port_over_tc is used to inform that the TC port can be
> dynamically allocated for a legacy connector in the Type-C subsystem,
> which is a new feature in Xe3p_LPD.  In upcoming changes, we will use
> that field in order to handle the IOM resource management programming
> required for that.
> 
> Note that, when dedicated_external is set, the fields dp_usb_type_c and
> tbt are tagged as "don't care" in the spec, so they should be ignored in
> that case, so also add a sanitization function to take care of forcing
> them to zero when dedicated_external is true.
> 
> v2:
>   - Use sanitization function to force dp_usb_type_c and tbt fields to
>     be zero instead of adding a
>     intel_bios_encoder_is_dedicated_external() check in each of their
>     respective accessor functions. (Jani)
>   - Print info about dedicated external ports in print_ddi_port().
>     (Jani)
> v3:
>   - Also zero out field dyn_port_over_tc when dedicated_external is set.
>     (Imre)
>   - Use intel_bios_encoder_is_dedicated_external() directly instead of
>     storing return value into variable in print_ddi_port(). (Imre)
>   - Also print info for dyn_port_over_tc in print_ddi_port(). (Imre)
> 
> Bspec: 20124, 68954, 74304
> Cc: Imre Deak <[email protected]>
> Cc: Jani Nikula <[email protected]>
> Cc: Shekhar Chauhan <[email protected]>
> Signed-off-by: Gustavo Sousa <[email protected]>

Reviewed-by: Imre Deak <[email protected]>

> ---
>  drivers/gpu/drm/i915/display/intel_bios.c     | 73 
> ++++++++++++++++++++++++++-
>  drivers/gpu/drm/i915/display/intel_bios.h     |  2 +
>  drivers/gpu/drm/i915/display/intel_vbt_defs.h |  3 +-
>  3 files changed, 76 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_bios.c 
> b/drivers/gpu/drm/i915/display/intel_bios.c
> index 4b41068e9e35..0283c0d418cf 100644
> --- a/drivers/gpu/drm/i915/display/intel_bios.c
> +++ b/drivers/gpu/drm/i915/display/intel_bios.c
> @@ -2529,6 +2529,54 @@ intel_bios_encoder_reject_edp_rate(const struct 
> intel_bios_encoder_data *devdata
>       return devdata->child.edp_data_rate_override & 
> edp_rate_override_mask(rate);
>  }
>  
> +static void sanitize_dedicated_external(struct intel_bios_encoder_data 
> *devdata,
> +                                     enum port port)
> +{
> +     struct intel_display *display = devdata->display;
> +
> +     if (!intel_bios_encoder_is_dedicated_external(devdata))
> +             return;
> +
> +     /*
> +      * Since dedicated_external is for ports connected to PHYs outside of
> +      * the Type-C subsystem, clear bits that would only make sense for ports
> +      * with PHYs in the Type-C subsystem.
> +      */
> +
> +     /*
> +      * Bit dp_usb_type_c is marked as "don't care" in Bspec when
> +      * dedicated_external is set.
> +      */
> +     if (devdata->child.dp_usb_type_c) {
> +             drm_dbg_kms(display->drm,
> +                         "VBT claims Port %c supports USB Type-C, but the 
> port is dedicated external, ignoring\n",
> +                         port_name(port));
> +             devdata->child.dp_usb_type_c = 0;
> +     }
> +
> +     /*
> +      * Bit tbt is marked as "don't care" in Bspec when dedicated_external is
> +      * set.
> +      */
> +     if (devdata->child.tbt) {
> +             drm_dbg_kms(display->drm,
> +                         "VBT claims Port %c supports TBT, but the port is 
> dedicated external, ignoring\n",
> +                         port_name(port));
> +             devdata->child.tbt = 0;
> +     }
> +
> +     /*
> +      * DDI allocation for TC capable ports only make sense for PHYs in the
> +      * Type-C subsystem.
> +      */
> +     if (devdata->child.dyn_port_over_tc) {
> +             drm_dbg_kms(display->drm,
> +                         "VBT claims Port %c supports dynamic DDI allocation 
> in TCSS, but the port is dedicated external, ignoring\n",
> +                         port_name(port));
> +             devdata->child.dyn_port_over_tc = 0;
> +     }
> +}
> +
>  static void sanitize_device_type(struct intel_bios_encoder_data *devdata,
>                                enum port port)
>  {
> @@ -2693,6 +2741,16 @@ static void print_ddi_port(const struct 
> intel_bios_encoder_data *devdata)
>                   supports_typec_usb, supports_tbt,
>                   devdata->dsc != NULL);
>  
> +     if (intel_bios_encoder_is_dedicated_external(devdata))
> +             drm_dbg_kms(display->drm,
> +                         "Port %c is dedicated external\n",
> +                         port_name(port));
> +
> +     if (intel_bios_encoder_supports_dyn_port_over_tc(devdata))
> +             drm_dbg_kms(display->drm,
> +                         "Port %c supports dynamic DDI allocation in TCSS\n",
> +                         port_name(port));
> +
>       hdmi_level_shift = intel_bios_hdmi_level_shift(devdata);
>       if (hdmi_level_shift >= 0) {
>               drm_dbg_kms(display->drm,
> @@ -2750,6 +2808,7 @@ static void parse_ddi_port(struct 
> intel_bios_encoder_data *devdata)
>               return;
>       }
>  
> +     sanitize_dedicated_external(devdata, port);
>       sanitize_device_type(devdata, port);
>       sanitize_hdmi_level_shift(devdata, port);
>  }
> @@ -2777,7 +2836,7 @@ static int child_device_expected_size(u16 version)
>  {
>       BUILD_BUG_ON(sizeof(struct child_device_config) < 40);
>  
> -     if (version > 263)
> +     if (version > 264)
>               return -ENOENT;
>       else if (version >= 263)
>               return 44;
> @@ -3721,6 +3780,18 @@ bool intel_bios_encoder_supports_tbt(const struct 
> intel_bios_encoder_data *devda
>       return devdata->display->vbt.version >= 209 && devdata->child.tbt;
>  }
>  
> +bool intel_bios_encoder_is_dedicated_external(const struct 
> intel_bios_encoder_data *devdata)
> +{
> +     return devdata->display->vbt.version >= 264 &&
> +             devdata->child.dedicated_external;
> +}
> +
> +bool intel_bios_encoder_supports_dyn_port_over_tc(const struct 
> intel_bios_encoder_data *devdata)
> +{
> +     return devdata->display->vbt.version >= 264 &&
> +             devdata->child.dyn_port_over_tc;
> +}
> +
>  bool intel_bios_encoder_lane_reversal(const struct intel_bios_encoder_data 
> *devdata)
>  {
>       return devdata && devdata->child.lane_reversal;
> diff --git a/drivers/gpu/drm/i915/display/intel_bios.h 
> b/drivers/gpu/drm/i915/display/intel_bios.h
> index f9e438b2787b..75dff27b4228 100644
> --- a/drivers/gpu/drm/i915/display/intel_bios.h
> +++ b/drivers/gpu/drm/i915/display/intel_bios.h
> @@ -79,6 +79,8 @@ bool intel_bios_encoder_supports_dp(const struct 
> intel_bios_encoder_data *devdat
>  bool intel_bios_encoder_supports_edp(const struct intel_bios_encoder_data 
> *devdata);
>  bool intel_bios_encoder_supports_typec_usb(const struct 
> intel_bios_encoder_data *devdata);
>  bool intel_bios_encoder_supports_tbt(const struct intel_bios_encoder_data 
> *devdata);
> +bool intel_bios_encoder_is_dedicated_external(const struct 
> intel_bios_encoder_data *devdata);
> +bool intel_bios_encoder_supports_dyn_port_over_tc(const struct 
> intel_bios_encoder_data *devdata);
>  bool intel_bios_encoder_supports_dsi(const struct intel_bios_encoder_data 
> *devdata);
>  bool intel_bios_encoder_supports_dp_dual_mode(const struct 
> intel_bios_encoder_data *devdata);
>  bool intel_bios_encoder_is_lspcon(const struct intel_bios_encoder_data 
> *devdata);
> diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h 
> b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
> index 70e31520c560..57fda5824c9c 100644
> --- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h
> +++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
> @@ -554,7 +554,8 @@ struct child_device_config {
>       u8 dvo_function;
>       u8 dp_usb_type_c:1;                                     /* 195+ */
>       u8 tbt:1;                                               /* 209+ */
> -     u8 flags2_reserved:2;                                   /* 195+ */
> +     u8 dedicated_external:1;                                /* 264+ */
> +     u8 dyn_port_over_tc:1;                                  /* 264+ */
>       u8 dp_port_trace_length:4;                              /* 209+ */
>       u8 dp_gpio_index;                                       /* 195+ */
>       u16 dp_gpio_pin_num;                                    /* 195+ */
> 
> -- 
> 2.51.0
> 

Reply via email to