All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jani Nikula <jani.nikula@intel.com>
To: "Michał Grzelak" <michal.grzelak@intel.com>,
	intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org
Cc: "Suraj Kandpal" <suraj.kandpal@intel.com>,
	"Michał Grzelak" <michal.grzelak@intel.com>
Subject: Re: [PATCH v10 7/8] drm/i915: override Combo's VS/PE when requested
Date: Tue, 11 Aug 2026 18:51:22 +0300	[thread overview]
Message-ID: <7fa2b7fd70bdc17eba3f6a9dcac6be42cb692f8c@intel.com> (raw)
In-Reply-To: <20260702185839.4042397-8-michal.grzelak@intel.com>

On Thu, 02 Jul 2026, Michał Grzelak <michal.grzelak@intel.com> wrote:
> Add accessor function for Combo to read requested table from VBT #57.
> Parse the requested table and transform data into port's buffer.
>
> For EHL, in cases when eDP encoder uses low vswing, choose 3rd table if
> encoder supports HBR3. Otherwise use 2nd table for eDP using low vswing.
>
> In cases when eDP encoder does not use low vswing, choose 2nd table if
> encoder supports mode higher or including HBR2. Otherwise use 3rd table
> for eDP not using low vswing.
>
> For external DP use 2nd table if encoder supports modes higher than or
> including HBR2. Use 1st table if external DP encoder supports modes
> lower than HBR2.
>
> For JSL, always use 1st table for external DP. For eDPs not using low
> vswing use 1st table as well.
>
> In cases when eDP encoder uses low vswing, choose 1st table if encoder
> supports HBR3. When encoder supports HBR2 choose 3rd table. When
> encoder supports modes lower than HBR2 choose 2nd table.
>
> There are no changes to intel_ddi_dp_level() since selection of correct
> row of intel_ddi_buf_trans_entry is same as when no override request has
> been done.
>
> Looking from other OSes, in case when encoder does not support DP we
> could theoretically use 1st table. However, as of now, use default
> tables.
>
> v9->v10
> - call dedicated VS/PE-O vfunc
> - drop deconstifying default tables (Suraj, Jani)
> - cache `entries` into const field after data is overwritten (Jani)
>
> v8->v9
> - deconstify intel_ddi_buf_trans_entry
>
> v6->v7
> - handle VS/PE-O's VBT details in intel_bios_* functions (Jani)
> - remove vspeo's cast to (void *) (Jani)
> - call encoder->get_buf_trans() once (Jani)
> - return NULL from intel_bios_get_* when using default (Jani)
> - validate VS/PE-O in intel_bios.c (Jani)
> - check devdata->vspeo if VS/PE-O was requested
> - inline {jsl,ehl}_combo_get_vspeo_buf_trans()
> - remove temporarily LT
>
> v4->v5
> - blend index computation with table parsing
> - remove enums entirely
> - add spaces around operators (Suraj)
> - remove spaces after type casting (Suraj)
> - remove INTEL_DISPLAY_STATE_WARN (Suraj)
>
> Signed-off-by: Michał Grzelak <michal.grzelak@intel.com>
> Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_bios.c     | 104 ++++++++++++++++++
>  drivers/gpu/drm/i915/display/intel_bios.h     |   6 +
>  .../drm/i915/display/intel_ddi_buf_trans.c    |  41 ++++++-
>  3 files changed, 148 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
> index f897ac067585..b84552527050 100644
> --- a/drivers/gpu/drm/i915/display/intel_bios.c
> +++ b/drivers/gpu/drm/i915/display/intel_bios.c
> @@ -3985,6 +3985,110 @@ intel_bios_get_c10_vspeo(const struct intel_bios_encoder_data *devdata,
>  	return vspeo;
>  }
>  
> +const struct intel_ddi_buf_trans *
> +intel_bios_get_ehl_combo_vspeo(const struct intel_bios_encoder_data *devdata,
> +			       bool has_dp, int port_clock, bool has_edp)
> +{
> +	struct intel_display *display;
> +	union intel_ddi_buf_trans_entry *entries;
> +	int num_columns, num_rows, level, idx;
> +	struct intel_ddi_buf_trans *vspeo;
> +	const u32 *tables;
> +	size_t offset = 0;
> +
> +	if (!validate_vspeo(devdata, has_dp))
> +		return NULL;
> +
> +	display = devdata->display;
> +	vspeo = devdata->vspeo;
> +	entries = devdata->entries;
> +	tables = display->vbt.vspeo.tables;
> +	num_columns = display->vbt.vspeo.num_columns;
> +	num_rows = display->vbt.vspeo.num_rows;

Same thing about initialization as in the preceding patch.


> +
> +	idx = port_clock > 270000 ? 1 : 0;
> +	if (has_edp)
> +		idx = port_clock > 540000 ? 2 : 1;

Init once, not twice for has_edp.

> +
> +	offset += idx * num_rows * num_columns;
> +
> +	for (level = 0; level < num_rows; level++) {
> +		u32 dw2_swing_sel = tables[offset];
> +		u32 dw7_n_scalar = tables[offset + 1];
> +		u32 dw4_cursor_coeff = tables[offset + 2];
> +		u32 dw4_post_cursor_2 = tables[offset + 3];
> +		u32 dw4_post_cursor_1 = tables[offset + 4];
> +
> +		entries[level].icl.dw2_swing_sel = dw2_swing_sel;
> +		entries[level].icl.dw7_n_scalar = dw7_n_scalar;
> +		entries[level].icl.dw4_cursor_coeff = dw4_cursor_coeff;
> +		entries[level].icl.dw4_post_cursor_2 = dw4_post_cursor_2;
> +		entries[level].icl.dw4_post_cursor_1 = dw4_post_cursor_1;

Again, u8 vs. u32.

> +
> +		offset += num_columns;
> +	}
> +
> +	vspeo->entries = entries;
> +	vspeo->num_entries = num_rows;
> +
> +	return vspeo;
> +}
> +
> +const struct intel_ddi_buf_trans *
> +intel_bios_get_jsl_combo_vspeo(const struct intel_bios_encoder_data *devdata,
> +			       bool has_dp, int port_clock, bool low_vswing_edp)
> +{
> +	struct intel_display *display;
> +	union intel_ddi_buf_trans_entry *entries;
> +	int num_columns, num_rows, level, idx;
> +	struct intel_ddi_buf_trans *vspeo;
> +	const u32 *tables;
> +	size_t offset = 0;
> +
> +	if (!validate_vspeo(devdata, has_dp))
> +		return NULL;
> +
> +	display = devdata->display;
> +	vspeo = devdata->vspeo;
> +	entries = devdata->entries;
> +	tables = display->vbt.vspeo.tables;
> +	num_columns = display->vbt.vspeo.num_columns;
> +	num_rows = display->vbt.vspeo.num_rows;

Same.

> +
> +	idx = 0;

Again, IMO bad form to do something once, and then override in some
other cases, *unless* you do this kind of "default" init at declaration.

> +	if (low_vswing_edp) {
> +		if (port_clock > 540000)
> +			idx = 0;
> +		else if (port_clock > 270000)
> +			idx = 1;
> +		else
> +			idx = 2;
> +	}
> +
> +	offset += idx * num_rows * num_columns;
> +
> +	for (level = 0; level < num_rows; level++) {
> +		u32 dw2_swing_sel = tables[offset];
> +		u32 dw7_n_scalar = tables[offset + 1];
> +		u32 dw4_cursor_coeff = tables[offset + 2];
> +		u32 dw4_post_cursor_2 = tables[offset + 3];
> +		u32 dw4_post_cursor_1 = tables[offset + 4];
> +
> +		entries[level].icl.dw2_swing_sel = dw2_swing_sel;
> +		entries[level].icl.dw7_n_scalar = dw7_n_scalar;
> +		entries[level].icl.dw4_cursor_coeff = dw4_cursor_coeff;
> +		entries[level].icl.dw4_post_cursor_2 = dw4_post_cursor_2;
> +		entries[level].icl.dw4_post_cursor_1 = dw4_post_cursor_1;

u32 vs. u8

> +
> +		offset += num_columns;
> +	}
> +
> +	vspeo->entries = entries;
> +	vspeo->num_entries = num_rows;
> +
> +	return vspeo;
> +}
> +
>  bool intel_bios_encoder_is_dedicated_external(const struct intel_bios_encoder_data *devdata)
>  {
>  	return devdata->display->vbt.version >= 264 &&
> diff --git a/drivers/gpu/drm/i915/display/intel_bios.h b/drivers/gpu/drm/i915/display/intel_bios.h
> index 49acf8c405e2..c55765a94594 100644
> --- a/drivers/gpu/drm/i915/display/intel_bios.h
> +++ b/drivers/gpu/drm/i915/display/intel_bios.h
> @@ -79,6 +79,12 @@ intel_bios_get_c20_vspeo(const struct intel_bios_encoder_data *devdata,
>  const struct intel_ddi_buf_trans *
>  intel_bios_get_c10_vspeo(const struct intel_bios_encoder_data *devdata,
>  			 bool has_dp, int port_clock, bool has_edp);
> +const struct intel_ddi_buf_trans *
> +intel_bios_get_ehl_combo_vspeo(const struct intel_bios_encoder_data *devdata,
> +			       bool has_dp, int port_clock, bool has_edp);
> +const struct intel_ddi_buf_trans *
> +intel_bios_get_jsl_combo_vspeo(const struct intel_bios_encoder_data *devdata,
> +			       bool has_dp, int port_clock, bool low_vswing_edp);
>  
>  bool intel_bios_encoder_requests_vspeo(const struct intel_bios_encoder_data *devdata);
>  bool intel_bios_encoder_supports_dvi(const struct intel_bios_encoder_data *devdata);
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
> index 92c0d0f933ab..0843b3e2bfa6 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
> @@ -1784,6 +1784,39 @@ xe3plpd_get_lt_buf_trans(struct intel_encoder *encoder,
>  		return intel_get_buf_trans(&xe3plpd_lt_trans_dp14, n_entries);
>  }
>  
> +static const struct intel_ddi_buf_trans *
> +jsl_get_combo_buf_trans_override(struct intel_encoder *encoder,
> +				 const struct intel_crtc_state *crtc_state,
> +				 int *n_entries)
> +{
> +	const struct intel_bios_encoder_data *devdata = encoder->devdata;
> +	bool has_edp, has_dp;
> +	int port_clock;
> +
> +	has_edp = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP);
> +	has_dp = intel_crtc_has_dp_encoder(crtc_state);
> +	port_clock = crtc_state->port_clock;
> +
> +	return intel_bios_get_jsl_combo_vspeo(devdata, has_dp, port_clock,
> +					      has_edp && use_edp_low_vswing(encoder));
> +}
> +
> +static const struct intel_ddi_buf_trans *
> +ehl_get_combo_buf_trans_override(struct intel_encoder *encoder,
> +				 const struct intel_crtc_state *crtc_state,
> +				 int *n_entries)
> +{
> +	const struct intel_bios_encoder_data *devdata = encoder->devdata;
> +	bool has_edp, has_dp;
> +	int port_clock;
> +
> +	has_edp = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP);
> +	has_dp = intel_crtc_has_dp_encoder(crtc_state);
> +	port_clock = crtc_state->port_clock;
> +
> +	return intel_bios_get_ehl_combo_vspeo(devdata, has_dp, port_clock, has_edp);
> +}
> +
>  static const struct intel_ddi_buf_trans *
>  mtl_get_c10_buf_trans_override(struct intel_encoder *encoder,
>  			       const struct intel_crtc_state *crtc_state,
> @@ -1847,11 +1880,13 @@ void intel_ddi_buf_trans_init(struct intel_encoder *encoder)
>  		else
>  			encoder->get_buf_trans = tgl_get_dkl_buf_trans;
>  	} else if (DISPLAY_VER(display) == 11) {
> -		if (display->platform.jasperlake)
> +		if (display->platform.jasperlake) {
>  			encoder->get_buf_trans = jsl_get_combo_buf_trans;
> -		else if (display->platform.elkhartlake)
> +			encoder->get_buf_trans_override = jsl_get_combo_buf_trans_override;
> +		} else if (display->platform.elkhartlake) {
>  			encoder->get_buf_trans = ehl_get_combo_buf_trans;
> -		else if (intel_encoder_is_combo(encoder))
> +			encoder->get_buf_trans_override = ehl_get_combo_buf_trans_override;
> +		} else if (intel_encoder_is_combo(encoder))
>  			encoder->get_buf_trans = icl_get_combo_buf_trans;
>  		else
>  			encoder->get_buf_trans = icl_get_mg_buf_trans;

-- 
Jani Nikula, Intel

  reply	other threads:[~2026-08-11 15:51 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-02 18:58 [PATCH v10 0/8] Vswing / Pre-emphasis Override Michał Grzelak
2026-07-02 18:58 ` [PATCH v10 1/8] drm/i915/bios: search for VBT #57 by default Michał Grzelak
2026-07-02 18:58 ` [PATCH v10 2/8] drm/i915/bios: store VBT #57's metadata in intel_vbt_data Michał Grzelak
2026-07-02 18:58 ` [PATCH v10 3/8] drm/i915/bios: print VS/PE-O port info Michał Grzelak
2026-07-02 18:58 ` [PATCH v10 4/8] drm/i915/bios: de/allocate VS/PE-O buffers for each port Michał Grzelak
2026-07-02 18:58 ` [PATCH v10 5/8] drm/i915/buf_trans: add vfunc for VS/PE-O Michał Grzelak
2026-07-06  6:12   ` Kandpal, Suraj
2026-07-02 18:58 ` [PATCH v10 6/8] drm/i915: override Snps's VS/PE when requested Michał Grzelak
2026-08-11 15:48   ` Jani Nikula
2026-08-13 15:52     ` Michał Grzelak
2026-07-02 18:58 ` [PATCH v10 7/8] drm/i915: override Combo's " Michał Grzelak
2026-08-11 15:51   ` Jani Nikula [this message]
2026-07-02 18:58 ` [PATCH v10 8/8] drm/i915/bios: remove VS/PE-O warning Michał Grzelak
2026-07-02 19:06 ` ✗ CI.checkpatch: warning for Vswing / Pre-emphasis Override (rev5) Patchwork
2026-07-02 19:07 ` ✓ CI.KUnit: success " Patchwork
2026-07-02 20:07 ` ✓ Xe.CI.BAT: " Patchwork
2026-07-02 20:07 ` ✓ i915.CI.BAT: " Patchwork
2026-07-03 13:55 ` ✓ Xe.CI.FULL: " Patchwork
2026-07-03 15:39 ` ✗ i915.CI.Full: failure " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7fa2b7fd70bdc17eba3f6a9dcac6be42cb692f8c@intel.com \
    --to=jani.nikula@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=michal.grzelak@intel.com \
    --cc=suraj.kandpal@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.