public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
From: Jani Nikula <jani.nikula@intel.com>
To: intel-gfx@lists.freedesktop.org,
	Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	Maxime Ripard <mripard@kernel.org>,
	Thomas Zimmermann <tzimmermann@suse.de>
Cc: dri-devel@lists.freedesktop.org, ville.syrjala@linux.intel.com,
Subject: Re: [Intel-gfx] [PATCH 1/3] drm/dp: add helpers to read link training delays
Date: Fri, 15 Oct 2021 18:21:35 +0300	[thread overview]
Message-ID: <871r4muxds.fsf@intel.com> (raw)
In-Reply-To: <20211014150059.28957-1-jani.nikula@intel.com>

On Thu, 14 Oct 2021, Jani Nikula <jani.nikula@intel.com> wrote:
> The link training delays are different and/or available in different
> DPCD offsets depending on:
>
> - Clock recovery vs. channel equalization
> - DPRX vs. LTTPR
> - 128b/132b vs. 8b/10b
> - DPCD 1.4+ vs. earlier
>
> Add helpers to get the correct delays in us, reading DPCD if
> necessary. This is more straightforward than trying to retrofit the
> existing helpers to take 128b/132b into account.
>
> Having to pass in the DPCD receiver cap field seems unavoidable, because
> reading it involves checking the revision and reading extended receiver
> cap. So unfortunately the interface is mixed cached and read as needed.
>
> v2: Remove delay_us < 0 check and the whole local var (Ville)
>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Maarten, Maxime, Thomas -

Ack on the first two patches in this series?

Should we merge them via a topic branch to both drm-misc-next and
drm-intel-next, or is it fine to merge them all via drm-intel-next? We
might be at a point in the development cycle that it takes a while to
get the branches in sync again.

BR,
Jani.



> ---
>  drivers/gpu/drm/drm_dp_helper.c | 127 ++++++++++++++++++++++++++++++++
>  include/drm/drm_dp_helper.h     |  21 +++++-
>  2 files changed, 146 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
> index 4d0d1e8e51fa..f7ebf5974fa7 100644
> --- a/drivers/gpu/drm/drm_dp_helper.c
> +++ b/drivers/gpu/drm/drm_dp_helper.c
> @@ -154,6 +154,133 @@ u8 drm_dp_get_adjust_request_post_cursor(const u8 link_status[DP_LINK_STATUS_SIZ
>  }
>  EXPORT_SYMBOL(drm_dp_get_adjust_request_post_cursor);
>  
> +static int __8b10b_clock_recovery_delay_us(const struct drm_dp_aux *aux, u8 rd_interval)
> +{
> +	if (rd_interval > 4)
> +		drm_dbg_kms(aux->drm_dev, "%s: invalid AUX interval 0x%02x (max 4)\n",
> +			    aux->name, rd_interval);
> +
> +	if (rd_interval == 0)
> +		return 100;
> +
> +	return rd_interval * 4 * USEC_PER_MSEC;
> +}
> +
> +static int __8b10b_channel_eq_delay_us(const struct drm_dp_aux *aux, u8 rd_interval)
> +{
> +	if (rd_interval > 4)
> +		drm_dbg_kms(aux->drm_dev, "%s: invalid AUX interval 0x%02x (max 4)\n",
> +			    aux->name, rd_interval);
> +
> +	if (rd_interval == 0)
> +		return 400;
> +
> +	return rd_interval * 4 * USEC_PER_MSEC;
> +}
> +
> +static int __128b132b_channel_eq_delay_us(const struct drm_dp_aux *aux, u8 rd_interval)
> +{
> +	switch (rd_interval) {
> +	default:
> +		drm_dbg_kms(aux->drm_dev, "%s: invalid AUX interval 0x%02x\n",
> +			    aux->name, rd_interval);
> +		fallthrough;
> +	case DP_128B132B_TRAINING_AUX_RD_INTERVAL_400_US:
> +		return 400;
> +	case DP_128B132B_TRAINING_AUX_RD_INTERVAL_4_MS:
> +		return 4000;
> +	case DP_128B132B_TRAINING_AUX_RD_INTERVAL_8_MS:
> +		return 8000;
> +	case DP_128B132B_TRAINING_AUX_RD_INTERVAL_12_MS:
> +		return 12000;
> +	case DP_128B132B_TRAINING_AUX_RD_INTERVAL_16_MS:
> +		return 16000;
> +	case DP_128B132B_TRAINING_AUX_RD_INTERVAL_32_MS:
> +		return 32000;
> +	case DP_128B132B_TRAINING_AUX_RD_INTERVAL_64_MS:
> +		return 64000;
> +	}
> +}
> +
> +/*
> + * The link training delays are different for:
> + *
> + *  - Clock recovery vs. channel equalization
> + *  - DPRX vs. LTTPR
> + *  - 128b/132b vs. 8b/10b
> + *  - DPCD rev 1.3 vs. later
> + *
> + * Get the correct delay in us, reading DPCD if necessary.
> + */
> +static int __read_delay(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE],
> +			enum drm_dp_phy dp_phy, bool uhbr, bool cr)
> +{
> +	int (*parse)(const struct drm_dp_aux *aux, u8 rd_interval);
> +	unsigned int offset;
> +	u8 rd_interval, mask;
> +
> +	if (dp_phy == DP_PHY_DPRX) {
> +		if (uhbr) {
> +			if (cr)
> +				return 100;
> +
> +			offset = DP_128B132B_TRAINING_AUX_RD_INTERVAL;
> +			mask = DP_128B132B_TRAINING_AUX_RD_INTERVAL_MASK;
> +			parse = __128b132b_channel_eq_delay_us;
> +		} else {
> +			if (cr && dpcd[DP_DPCD_REV] >= DP_DPCD_REV_14)
> +				return 100;
> +
> +			offset = DP_TRAINING_AUX_RD_INTERVAL;
> +			mask = DP_TRAINING_AUX_RD_MASK;
> +			if (cr)
> +				parse = __8b10b_clock_recovery_delay_us;
> +			else
> +				parse = __8b10b_channel_eq_delay_us;
> +		}
> +	} else {
> +		if (uhbr) {
> +			offset = DP_128B132B_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER(dp_phy);
> +			mask = DP_128B132B_TRAINING_AUX_RD_INTERVAL_MASK;
> +			parse = __128b132b_channel_eq_delay_us;
> +		} else {
> +			if (cr)
> +				return 100;
> +
> +			offset = DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER(dp_phy);
> +			mask = DP_TRAINING_AUX_RD_MASK;
> +			parse = __8b10b_channel_eq_delay_us;
> +		}
> +	}
> +
> +	if (offset < DP_RECEIVER_CAP_SIZE) {
> +		rd_interval = dpcd[offset];
> +	} else {
> +		if (drm_dp_dpcd_readb(aux, offset, &rd_interval) != 1) {
> +			drm_dbg_kms(aux->drm_dev, "%s: failed rd interval read\n",
> +				    aux->name);
> +			/* arbitrary default delay */
> +			return 400;
> +		}
> +	}
> +
> +	return parse(aux, rd_interval & mask);
> +}
> +
> +int drm_dp_read_clock_recovery_delay(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE],
> +				     enum drm_dp_phy dp_phy, bool uhbr)
> +{
> +	return __read_delay(aux, dpcd, dp_phy, uhbr, true);
> +}
> +EXPORT_SYMBOL(drm_dp_read_clock_recovery_delay);
> +
> +int drm_dp_read_channel_eq_delay(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE],
> +				 enum drm_dp_phy dp_phy, bool uhbr)
> +{
> +	return __read_delay(aux, dpcd, dp_phy, uhbr, false);
> +}
> +EXPORT_SYMBOL(drm_dp_read_channel_eq_delay);
> +
>  void drm_dp_link_train_clock_recovery_delay(const struct drm_dp_aux *aux,
>  					    const u8 dpcd[DP_RECEIVER_CAP_SIZE])
>  {
> diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> index b52df4db3e8f..afdf7f4183f9 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -1114,8 +1114,15 @@ struct drm_panel;
>  # define DP_UHBR20                             (1 << 1)
>  # define DP_UHBR13_5                           (1 << 2)
>  
> -#define DP_128B132B_TRAINING_AUX_RD_INTERVAL   0x2216 /* 2.0 */
> -# define DP_128B132B_TRAINING_AUX_RD_INTERVAL_MASK 0x7f
> +#define DP_128B132B_TRAINING_AUX_RD_INTERVAL                    0x2216 /* 2.0 */
> +# define DP_128B132B_TRAINING_AUX_RD_INTERVAL_MASK              0x7f
> +# define DP_128B132B_TRAINING_AUX_RD_INTERVAL_400_US            0x00
> +# define DP_128B132B_TRAINING_AUX_RD_INTERVAL_4_MS              0x01
> +# define DP_128B132B_TRAINING_AUX_RD_INTERVAL_8_MS              0x02
> +# define DP_128B132B_TRAINING_AUX_RD_INTERVAL_12_MS             0x03
> +# define DP_128B132B_TRAINING_AUX_RD_INTERVAL_16_MS             0x04
> +# define DP_128B132B_TRAINING_AUX_RD_INTERVAL_32_MS             0x05
> +# define DP_128B132B_TRAINING_AUX_RD_INTERVAL_64_MS             0x06
>  
>  #define DP_TEST_264BIT_CUSTOM_PATTERN_7_0		0x2230
>  #define DP_TEST_264BIT_CUSTOM_PATTERN_263_256	0x2250
> @@ -1389,6 +1396,11 @@ enum drm_dp_phy {
>  # define DP_VOLTAGE_SWING_LEVEL_3_SUPPORTED		    BIT(0)
>  # define DP_PRE_EMPHASIS_LEVEL_3_SUPPORTED		    BIT(1)
>  
> +#define DP_128B132B_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1  0xf0022 /* 2.0 */
> +#define DP_128B132B_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER(dp_phy)	\
> +	DP_LTTPR_REG(dp_phy, DP_128B132B_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1)
> +/* see DP_128B132B_TRAINING_AUX_RD_INTERVAL for values */
> +
>  #define DP_LANE0_1_STATUS_PHY_REPEATER1			    0xf0030 /* 1.3 */
>  #define DP_LANE0_1_STATUS_PHY_REPEATER(dp_phy) \
>  	DP_LTTPR_REG(dp_phy, DP_LANE0_1_STATUS_PHY_REPEATER1)
> @@ -1527,6 +1539,11 @@ u8 drm_dp_get_adjust_request_post_cursor(const u8 link_status[DP_LINK_STATUS_SIZ
>  #define DP_LTTPR_COMMON_CAP_SIZE	8
>  #define DP_LTTPR_PHY_CAP_SIZE		3
>  
> +int drm_dp_read_clock_recovery_delay(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE],
> +				     enum drm_dp_phy dp_phy, bool uhbr);
> +int drm_dp_read_channel_eq_delay(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE],
> +				 enum drm_dp_phy dp_phy, bool uhbr);
> +
>  void drm_dp_link_train_clock_recovery_delay(const struct drm_dp_aux *aux,
>  					    const u8 dpcd[DP_RECEIVER_CAP_SIZE]);
>  void drm_dp_lttpr_link_train_clock_recovery_delay(void);

-- 
Jani Nikula, Intel Open Source Graphics Center

  parent reply	other threads:[~2021-10-15 15:21 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-14 15:00 [Intel-gfx] [PATCH 1/3] drm/dp: add helpers to read link training delays Jani Nikula
2021-10-14 15:00 ` [Intel-gfx] [PATCH 2/3] drm/dp: reuse the 8b/10b link training delay helpers Jani Nikula
2021-10-14 15:43   ` Ville Syrjälä
2021-10-14 15:00 ` [Intel-gfx] [PATCH 3/3] drm/i915/dp: use new " Jani Nikula
2021-10-19 15:38   ` Jani Nikula
2021-10-14 22:42 ` [Intel-gfx] ✗ Fi.CI.SPARSE: warning for series starting with [1/3] drm/dp: add helpers to read link training delays Patchwork
2021-10-14 23:12 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2021-10-15  4:35 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
2021-10-15 15:21 ` Jani Nikula [this message]
2021-10-18  8:41   ` [Intel-gfx] [PATCH 1/3] " Maxime Ripard
2021-10-19 12:39     ` Jani Nikula

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=871r4muxds.fsf@intel.com \
    --to=jani.nikula@intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mripard@kernel.org \
    --cc=tzimmermann@suse.de \
    --cc=ville.syrjala@linux.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox