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
next prev 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