All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anson Jacob <Anson.Jacob@amd.com>
To: <amd-gfx@lists.freedesktop.org>
Cc: Wesley Chalmers <Wesley.Chalmers@amd.com>,
	Eryk.Brol@amd.com, Sunpeng.Li@amd.com, Harry.Wentland@amd.com,
	qingqing.zhuo@amd.com, Rodrigo.Siqueira@amd.com,
	roman.li@amd.com, Anson.Jacob@amd.com, Aurabindo.Pillai@amd.com,
	Jun Lei <Jun.Lei@amd.com>,
	Bhawanpreet.Lakha@amd.com, bindu.r@amd.com
Subject: [PATCH 21/24] drm/amd/display: Partition DPCD address space and break up transactions
Date: Thu, 10 Jun 2021 12:28:35 -0400	[thread overview]
Message-ID: <20210610162838.287723-22-Anson.Jacob@amd.com> (raw)
In-Reply-To: <20210610162838.287723-1-Anson.Jacob@amd.com>

From: Wesley Chalmers <Wesley.Chalmers@amd.com>

[WHY]
SCR for DP 2.0 spec says that multiple LTTPRs must not be accessed in a
single AUX transaction.
There may be other places in future where breaking up AUX accesses is
necessary.

[HOW]
Partition the entire DPCD address space into blocks. When an incoming AUX
request spans multiple blocks, break up the request into multiple requests.

Signed-off-by: Wesley Chalmers <Wesley.Chalmers@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Anson Jacob <Anson.Jacob@amd.com>
---
 .../drm/amd/display/dc/core/dc_link_dpcd.c    | 87 ++++++++++++++++++-
 include/drm/drm_dp_helper.h                   | 17 ++++
 2 files changed, 102 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c
index 8957565f87bc..27ec1e6e9c43 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c
@@ -43,6 +43,60 @@ static enum dc_status internal_link_write_dpcd(
 	return DC_OK;
 }
 
+/*
+ * Partition the entire DPCD address space
+ * XXX: This partitioning must cover the entire DPCD address space,
+ * and must contain no gaps or overlapping address ranges.
+ */
+static const struct dpcd_address_range mandatory_dpcd_partitions[] = {
+	{ 0, DP_TRAINING_PATTERN_SET_PHY_REPEATER(DP_PHY_LTTPR1) - 1},
+	{ DP_TRAINING_PATTERN_SET_PHY_REPEATER(DP_PHY_LTTPR1), DP_TRAINING_PATTERN_SET_PHY_REPEATER(DP_PHY_LTTPR2) - 1 },
+	{ DP_TRAINING_PATTERN_SET_PHY_REPEATER(DP_PHY_LTTPR2), DP_TRAINING_PATTERN_SET_PHY_REPEATER(DP_PHY_LTTPR3) - 1 },
+	{ DP_TRAINING_PATTERN_SET_PHY_REPEATER(DP_PHY_LTTPR3), DP_TRAINING_PATTERN_SET_PHY_REPEATER(DP_PHY_LTTPR4) - 1 },
+	{ DP_TRAINING_PATTERN_SET_PHY_REPEATER(DP_PHY_LTTPR4), DP_TRAINING_PATTERN_SET_PHY_REPEATER(DP_PHY_LTTPR5) - 1 },
+	{ DP_TRAINING_PATTERN_SET_PHY_REPEATER(DP_PHY_LTTPR5), DP_TRAINING_PATTERN_SET_PHY_REPEATER(DP_PHY_LTTPR6) - 1 },
+	{ DP_TRAINING_PATTERN_SET_PHY_REPEATER(DP_PHY_LTTPR6), DP_TRAINING_PATTERN_SET_PHY_REPEATER(DP_PHY_LTTPR7) - 1 },
+	{ DP_TRAINING_PATTERN_SET_PHY_REPEATER(DP_PHY_LTTPR7), DP_TRAINING_PATTERN_SET_PHY_REPEATER(DP_PHY_LTTPR8) - 1 },
+	{ DP_TRAINING_PATTERN_SET_PHY_REPEATER(DP_PHY_LTTPR8), DP_FEC_STATUS_PHY_REPEATER(DP_PHY_LTTPR1) - 1 },
+	/*
+	 * The FEC registers are contiguous
+	 */
+	{ DP_FEC_STATUS_PHY_REPEATER(DP_PHY_LTTPR1), DP_FEC_STATUS_PHY_REPEATER(DP_PHY_LTTPR1) - 1 },
+	{ DP_FEC_STATUS_PHY_REPEATER(DP_PHY_LTTPR2), DP_FEC_STATUS_PHY_REPEATER(DP_PHY_LTTPR2) - 1 },
+	{ DP_FEC_STATUS_PHY_REPEATER(DP_PHY_LTTPR3), DP_FEC_STATUS_PHY_REPEATER(DP_PHY_LTTPR3) - 1 },
+	{ DP_FEC_STATUS_PHY_REPEATER(DP_PHY_LTTPR4), DP_FEC_STATUS_PHY_REPEATER(DP_PHY_LTTPR4) - 1 },
+	{ DP_FEC_STATUS_PHY_REPEATER(DP_PHY_LTTPR5), DP_FEC_STATUS_PHY_REPEATER(DP_PHY_LTTPR5) - 1 },
+	{ DP_FEC_STATUS_PHY_REPEATER(DP_PHY_LTTPR6), DP_FEC_STATUS_PHY_REPEATER(DP_PHY_LTTPR6) - 1 },
+	{ DP_FEC_STATUS_PHY_REPEATER(DP_PHY_LTTPR7), DP_FEC_STATUS_PHY_REPEATER(DP_PHY_LTTPR7) - 1 },
+	{ DP_FEC_STATUS_PHY_REPEATER(DP_PHY_LTTPR8), DP_LTTPR_MAX_ADD },
+	/* all remaining DPCD addresses */
+	{ DP_LTTPR_MAX_ADD + 1, DP_DPCD_MAX_ADD } };
+
+static inline bool do_addresses_intersect_with_range(
+		const struct dpcd_address_range *range,
+		const uint32_t start_address,
+		const uint32_t end_address)
+{
+	return start_address <= range->end && end_address >= range->start;
+}
+
+static uint32_t dpcd_get_next_partition_size(const uint32_t address, const uint32_t size)
+{
+	const uint32_t end_address = END_ADDRESS(address, size);
+	uint32_t partition_iterator = 0;
+
+	/*
+	 * find current partition
+	 * this loop spins forever if partition map above is not surjective
+	 */
+	while (!do_addresses_intersect_with_range(&mandatory_dpcd_partitions[partition_iterator],
+				address, end_address))
+		partition_iterator++;
+	if (end_address < mandatory_dpcd_partitions[partition_iterator].end)
+		return size;
+	return ADDRESS_RANGE_SIZE(address, mandatory_dpcd_partitions[partition_iterator].end);
+}
+
 /*
  * Ranges of DPCD addresses that must be read in a single transaction
  * XXX: Do not allow any two address ranges in this array to overlap
@@ -115,12 +169,28 @@ enum dc_status core_link_read_dpcd(
 	uint32_t size)
 {
 	uint32_t extended_address;
+	uint32_t partitioned_address;
 	uint8_t *extended_data;
 	uint32_t extended_size;
+	/* size of the remaining partitioned address space */
+	uint32_t size_left_to_read;
 	enum dc_status status;
+	/* size of the next partition to be read from */
+	uint32_t partition_size;
+	uint32_t data_index = 0;
 
 	dpcd_extend_address_range(address, data, size, &extended_address, &extended_data, &extended_size);
-	status = internal_link_read_dpcd(link, extended_address, extended_data, extended_size);
+	partitioned_address = extended_address;
+	size_left_to_read = extended_size;
+	while (size_left_to_read) {
+		partition_size = dpcd_get_next_partition_size(partitioned_address, size_left_to_read);
+		status = internal_link_read_dpcd(link, partitioned_address, &extended_data[data_index], partition_size);
+		if (status != DC_OK)
+			break;
+		partitioned_address += partition_size;
+		data_index += partition_size;
+		size_left_to_read -= partition_size;
+	}
 	dpcd_reduce_address_range(extended_address, extended_data, extended_size, address, data, size);
 	return status;
 }
@@ -131,5 +201,18 @@ enum dc_status core_link_write_dpcd(
 	const uint8_t *data,
 	uint32_t size)
 {
-	return internal_link_write_dpcd(link, address, data, size);
+	uint32_t partition_size;
+	uint32_t data_index = 0;
+	enum dc_status status;
+
+	while (size) {
+		partition_size = dpcd_get_next_partition_size(address, size);
+		status = internal_link_write_dpcd(link, address, &data[data_index], partition_size);
+		if (status != DC_OK)
+			break;
+		address += partition_size;
+		data_index += partition_size;
+		size -= partition_size;
+	}
+	return status;
 }
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index edffd1dcca3e..35ac1f537530 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1369,10 +1369,27 @@ enum drm_dp_phy {
 #define DP_SYMBOL_ERROR_COUNT_LANE1_PHY_REPEATER1	    0xf0037 /* 1.3 */
 #define DP_SYMBOL_ERROR_COUNT_LANE2_PHY_REPEATER1	    0xf0039 /* 1.3 */
 #define DP_SYMBOL_ERROR_COUNT_LANE3_PHY_REPEATER1	    0xf003b /* 1.3 */
+
+#define __DP_FEC1_BASE					    0xf0290 /* 1.4 */
+#define __DP_FEC2_BASE					    0xf0298 /* 1.4 */
+#define DP_FEC_BASE(dp_phy) \
+	(__DP_FEC1_BASE + ((__DP_FEC2_BASE - __DP_FEC1_BASE) * \
+			   ((dp_phy) - DP_PHY_LTTPR1)))
+
+#define DP_FEC_REG(dp_phy, fec1_reg) \
+	(DP_FEC_BASE(dp_phy) - DP_FEC_BASE(DP_PHY_LTTPR1) + fec1_reg)
+
 #define DP_FEC_STATUS_PHY_REPEATER1			    0xf0290 /* 1.4 */
+#define DP_FEC_STATUS_PHY_REPEATER(dp_phy) \
+	DP_FEC_REG(dp_phy, DP_FEC_STATUS_PHY_REPEATER1)
+
 #define DP_FEC_ERROR_COUNT_PHY_REPEATER1                    0xf0291 /* 1.4 */
 #define DP_FEC_CAPABILITY_PHY_REPEATER1                     0xf0294 /* 1.4a */
 
+#define DP_LTTPR_MAX_ADD				    0xf02ff /* 1.4 */
+
+#define DP_DPCD_MAX_ADD					    0xfffff /* 1.4 */
+
 /* Repeater modes */
 #define DP_PHY_REPEATER_MODE_TRANSPARENT		    0x55    /* 1.3 */
 #define DP_PHY_REPEATER_MODE_NON_TRANSPARENT		    0xaa    /* 1.3 */
-- 
2.25.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

  parent reply	other threads:[~2021-06-10 16:29 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-10 16:28 [PATCH 00/24] DC Patches June 10, 2021 Anson Jacob
2021-06-10 16:28 ` [PATCH 01/24] drm/amd/display: Remove unnecessary blank lines Anson Jacob
2021-06-10 16:28 ` [PATCH 02/24] drm/amd/display: add DMUB registers to crash dump diagnostic data Anson Jacob
2021-06-10 16:28 ` [PATCH 03/24] drm/amd/display: add config option for eDP hotplug detection Anson Jacob
2021-06-10 16:28 ` [PATCH 04/24] drm/amd/display: tune backlight ramping profiles Anson Jacob
2021-06-10 16:28 ` [PATCH 05/24] drm/amd/display: dp mst detection code refactor Anson Jacob
2021-06-10 16:28 ` [PATCH 06/24] drm/amd/display: Change swizzle visual confirm reference pipe Anson Jacob
2021-06-10 16:28 ` [PATCH 07/24] drm/amd/display: Updated variable name Anson Jacob
2021-06-10 16:28 ` [PATCH 08/24] drm/amd/display: [FW Promotion] Release 0.0.70 Anson Jacob
2021-06-10 16:28 ` [PATCH 09/24] drm/amd/display: 3.2.140 Anson Jacob
2021-06-10 16:28 ` [PATCH 10/24] drm/amd/display: move psr dm interface to separate files Anson Jacob
2021-06-10 16:28 ` [PATCH 11/24] drm/amd/display: Read LTTPR caps first on hotplug Anson Jacob
2021-06-10 16:28 ` [PATCH 12/24] drm/amd/display: Move LTTPR cap read into its own function Anson Jacob
2021-06-10 16:28 ` [PATCH 13/24] drm/amd/display: Read LTTPR caps first on bootup Anson Jacob
2021-06-10 16:28 ` [PATCH 14/24] drm/amd/display: Set LTTPR Transparent Mode after read link cap Anson Jacob
2021-06-10 16:28 ` [PATCH 15/24] drm/amd/display: Always write repeater mode regardless of LTTPR Anson Jacob
2021-06-10 16:28 ` [PATCH 16/24] drm/amd/display: Improve logic for is_lttpr_present Anson Jacob
2021-06-10 16:28 ` [PATCH 17/24] drm/amd/display: Enforce DPCD Address ranges Anson Jacob
2021-06-10 16:28 ` [PATCH 18/24] drm/amd/display: Rename constant Anson Jacob
2021-06-10 16:28 ` [PATCH 19/24] drm/amd/display: 7 retries + 50 ms timeout on AUX DEFER Anson Jacob
2021-06-10 16:28 ` [PATCH 20/24] drm/amd/display: Do not count I2C DEFERs with AUX DEFERs Anson Jacob
2021-06-10 16:28 ` Anson Jacob [this message]
2021-06-10 16:28 ` [PATCH 22/24] drm/amd/display: Add interface to get Calibrated Avg Level from FIFO Anson Jacob
2021-06-10 16:28 ` [PATCH 23/24] drm/amd/display: Cover edge-case when changing DISPCLK WDIVIDER Anson Jacob
2021-06-10 16:28 ` [PATCH 24/24] drm/amd/display: Extend AUX timeout for DP initial reads Anson Jacob
2021-06-14 13:23 ` [PATCH 00/24] DC Patches June 10, 2021 Wheeler, Daniel

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=20210610162838.287723-22-Anson.Jacob@amd.com \
    --to=anson.jacob@amd.com \
    --cc=Aurabindo.Pillai@amd.com \
    --cc=Bhawanpreet.Lakha@amd.com \
    --cc=Eryk.Brol@amd.com \
    --cc=Harry.Wentland@amd.com \
    --cc=Jun.Lei@amd.com \
    --cc=Rodrigo.Siqueira@amd.com \
    --cc=Sunpeng.Li@amd.com \
    --cc=Wesley.Chalmers@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=bindu.r@amd.com \
    --cc=qingqing.zhuo@amd.com \
    --cc=roman.li@amd.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.