summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
diff options
context:
space:
mode:
authorabdoulaye berthe <abdoulaye.berthe@amd.com>2019-07-24 18:01:44 +0300
committerAlex Deucher <alexander.deucher@amd.com>2019-11-13 23:29:43 +0300
commit64c12b733fe7eaffa9207e6f30b313595c6e6597 (patch)
tree81f8d74db85380b363384e11c44730cb9df3881b /drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
parentbad7ab0be9bea2a4128158751bc29ac4b1c3bce2 (diff)
downloadlinux-64c12b733fe7eaffa9207e6f30b313595c6e6597.tar.xz
drm/amd/display: implement lttpr logic
1-If at least one repeater is present in the link and we are in non transparent mode, perform clock recovery then channel equalization with all repeaters one by one before training DPRX. 2-Mark the end of LT with a repeater by setting training pattern 0 at the end of channel equalization with each repeater. Signed-off-by: abdoulaye berthe <abdoulaye.berthe@amd.com> Reviewed-by: Aric Cyr <Aric.Cyr@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c')
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
index a519dbc5ecb6..5efbdc1eb173 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
@@ -19,6 +19,36 @@
#include "resource.h"
#endif
+static uint8_t convert_to_count(uint8_t lttpr_repeater_count)
+{
+ switch (lttpr_repeater_count) {
+ case 0x80: // 1 lttpr repeater
+ return 1;
+ case 0x40: // 2 lttpr repeaters
+ return 2;
+ case 0x20: // 3 lttpr repeaters
+ return 3;
+ case 0x10: // 4 lttpr repeaters
+ return 4;
+ case 0x08: // 5 lttpr repeaters
+ return 5;
+ case 0x04: // 6 lttpr repeaters
+ return 6;
+ case 0x02: // 7 lttpr repeaters
+ return 7;
+ case 0x01: // 8 lttpr repeaters
+ return 8;
+ default:
+ break;
+ }
+ return 0; // invalid value
+}
+
+static inline bool is_immediate_downstream(struct dc_link *link, uint32_t offset)
+{
+ return (convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) == offset);
+}
+
enum dc_status core_link_read_dpcd(
struct dc_link *link,
uint32_t address,
@@ -212,7 +242,8 @@ void dp_disable_link_phy_mst(struct dc_link *link, enum signal_type signal)
bool dp_set_hw_training_pattern(
struct dc_link *link,
- enum dc_dp_training_pattern pattern)
+ enum dc_dp_training_pattern pattern,
+ uint32_t offset)
{
enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
@@ -240,10 +271,14 @@ bool dp_set_hw_training_pattern(
void dp_set_hw_lane_settings(
struct dc_link *link,
- const struct link_training_settings *link_settings)
+ const struct link_training_settings *link_settings,
+ uint32_t offset)
{
struct link_encoder *encoder = link->link_enc;
+ if (!link->is_lttpr_mode_transparent && !is_immediate_downstream(link, offset))
+ return;
+
/* call Encoder to set lane settings */
encoder->funcs->dp_set_lane_settings(encoder, link_settings);
}