Commit ad5594ad authored by Michael Strauss's avatar Michael Strauss Committed by Alex Deucher

drm/amd/display: Support Compliance Test Pattern Generation with DP2 Retimer

[WHY]
Certain retimer requires workarounds in order to correctly output test patterns.

[HOW]
Add vendor-specific aux sequences to program retimer's TX and pattern generator
when specific compliance test patterns are requested by sink.
Note: SQ128 w/a in DPMF mode only works in one flip orientation currently
Reviewed-by: default avatarHansen Dsouza <hansen.dsouza@amd.com>
Reviewed-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Acked-by: default avatarStylon Wang <stylon.wang@amd.com>
Signed-off-by: default avatarMichael Strauss <michael.strauss@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent dba24294
......@@ -45,6 +45,8 @@
#include "link/hwss/link_hwss_dio.h"
#include "link/hwss/link_hwss_dpia.h"
#include "link/hwss/link_hwss_hpo_dp.h"
#include "link/hwss/link_hwss_dio_fixed_vs_pe_retimer.h"
#include "link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.h"
#if defined(CONFIG_DRM_AMD_DC_SI)
#include "dce60/dce60_resource.h"
......@@ -4198,11 +4200,13 @@ const struct link_hwss *get_link_hwss(const struct dc_link *link,
* with an hpo encoder. Or we can return a very dummy one that doesn't
* do work for all functions
*/
return get_hpo_dp_link_hwss();
return (requires_fixed_vs_pe_retimer_hpo_link_hwss(link) ?
get_hpo_fixed_vs_pe_retimer_dp_link_hwss() : get_hpo_dp_link_hwss());
else if (can_use_dpia_link_hwss(link, link_res))
return get_dpia_link_hwss();
else if (can_use_dio_link_hwss(link, link_res))
return get_dio_link_hwss();
return (requires_fixed_vs_pe_retimer_dio_link_hwss(link)) ?
get_dio_fixed_vs_pe_retimer_link_hwss() : get_dio_link_hwss();
else
return get_virtual_link_hwss();
}
......
......@@ -1498,6 +1498,7 @@ struct dc_link {
enum engine_id eng_id;
bool test_pattern_enabled;
enum dp_test_pattern current_test_pattern;
union compliance_test_state compliance_test_state;
void *priv;
......
......@@ -179,6 +179,10 @@ struct link_service {
int (*aux_transfer_raw)(struct ddc_service *ddc,
struct aux_payload *payload,
enum aux_return_code_type *operation_result);
bool (*configure_fixed_vs_pe_retimer)(
struct ddc_service *ddc,
const uint8_t *data,
uint32_t len);
bool (*aux_transfer_with_retries_no_mutex)(struct ddc_service *ddc,
struct aux_payload *payload);
bool (*is_in_aux_transaction_mode)(struct ddc_service *ddc);
......
......@@ -42,7 +42,8 @@ AMD_DISPLAY_FILES += $(AMD_DAL_LINK_ACCESSORIES)
###############################################################################
# hwss
###############################################################################
LINK_HWSS = link_hwss_dio.o link_hwss_dpia.o link_hwss_hpo_dp.o
LINK_HWSS = link_hwss_dio.o link_hwss_dpia.o link_hwss_hpo_dp.o \
link_hwss_dio_fixed_vs_pe_retimer.o link_hwss_hpo_fixed_vs_pe_retimer_dp.o
AMD_DAL_LINK_HWSS = $(addprefix $(AMDDALPATH)/dc/link/hwss/, \
$(LINK_HWSS))
......
......@@ -703,6 +703,7 @@ bool dp_set_test_pattern(
/* Reset Test Pattern state */
link->test_pattern_enabled = false;
link->current_test_pattern = test_pattern;
return true;
}
......@@ -740,6 +741,7 @@ bool dp_set_test_pattern(
if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
/* Set Test Pattern state */
link->test_pattern_enabled = true;
link->current_test_pattern = test_pattern;
if (p_link_settings != NULL)
dpcd_set_link_settings(link,
p_link_settings);
......@@ -938,6 +940,7 @@ bool dp_set_test_pattern(
/* Set Test Pattern state */
link->test_pattern_enabled = true;
link->current_test_pattern = test_pattern;
}
return true;
......
......@@ -166,7 +166,7 @@ void set_dio_dp_lane_settings(struct dc_link *link,
link_enc->funcs->dp_set_lane_settings(link_enc, link_settings, lane_settings);
}
static void update_dio_stream_allocation_table(struct dc_link *link,
void update_dio_stream_allocation_table(struct dc_link *link,
const struct link_resource *link_res,
const struct link_mst_stream_allocation_table *table)
{
......
......@@ -55,5 +55,8 @@ void setup_dio_audio_output(struct pipe_ctx *pipe_ctx,
struct audio_output *audio_output, uint32_t audio_inst);
void enable_dio_audio_packet(struct pipe_ctx *pipe_ctx);
void disable_dio_audio_packet(struct pipe_ctx *pipe_ctx);
void update_dio_stream_allocation_table(struct dc_link *link,
const struct link_resource *link_res,
const struct link_mst_stream_allocation_table *table);
#endif /* __LINK_HWSS_DIO_H__ */
/*
* Copyright 2023 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include "link_hwss_dio.h"
#include "link_hwss_dio_fixed_vs_pe_retimer.h"
#include "link_enc_cfg.h"
uint8_t dp_dio_fixed_vs_pe_retimer_lane_cfg_to_hw_cfg(struct dc_link *link)
{
// TODO: Get USB-C cable orientation
if (link->cur_link_settings.lane_count == LANE_COUNT_FOUR)
return 0xF2;
else
return 0x12;
}
void dp_dio_fixed_vs_pe_retimer_exit_manual_automation(struct dc_link *link)
{
const uint8_t dp_type = dp_dio_fixed_vs_pe_retimer_lane_cfg_to_hw_cfg(link);
const uint8_t vendor_lttpr_exit_manual_automation_0[4] = {0x1, 0x11, 0x0, 0x06};
const uint8_t vendor_lttpr_exit_manual_automation_1[4] = {0x1, 0x50, dp_type, 0x0};
const uint8_t vendor_lttpr_exit_manual_automation_2[4] = {0x1, 0x50, 0x50, 0x0};
const uint8_t vendor_lttpr_exit_manual_automation_3[4] = {0x1, 0x51, 0x50, 0x0};
const uint8_t vendor_lttpr_exit_manual_automation_4[4] = {0x1, 0x10, 0x58, 0x0};
const uint8_t vendor_lttpr_exit_manual_automation_5[4] = {0x1, 0x10, 0x59, 0x0};
const uint8_t vendor_lttpr_exit_manual_automation_6[4] = {0x1, 0x30, 0x51, 0x0};
const uint8_t vendor_lttpr_exit_manual_automation_7[4] = {0x1, 0x30, 0x52, 0x0};
const uint8_t vendor_lttpr_exit_manual_automation_8[4] = {0x1, 0x30, 0x54, 0x0};
const uint8_t vendor_lttpr_exit_manual_automation_9[4] = {0x1, 0x30, 0x55, 0x0};
link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc,
&vendor_lttpr_exit_manual_automation_0[0], sizeof(vendor_lttpr_exit_manual_automation_0));
link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc,
&vendor_lttpr_exit_manual_automation_1[0], sizeof(vendor_lttpr_exit_manual_automation_1));
link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc,
&vendor_lttpr_exit_manual_automation_2[0], sizeof(vendor_lttpr_exit_manual_automation_2));
link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc,
&vendor_lttpr_exit_manual_automation_3[0], sizeof(vendor_lttpr_exit_manual_automation_3));
link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc,
&vendor_lttpr_exit_manual_automation_4[0], sizeof(vendor_lttpr_exit_manual_automation_4));
link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc,
&vendor_lttpr_exit_manual_automation_5[0], sizeof(vendor_lttpr_exit_manual_automation_5));
link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc,
&vendor_lttpr_exit_manual_automation_6[0], sizeof(vendor_lttpr_exit_manual_automation_6));
link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc,
&vendor_lttpr_exit_manual_automation_7[0], sizeof(vendor_lttpr_exit_manual_automation_7));
link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc,
&vendor_lttpr_exit_manual_automation_8[0], sizeof(vendor_lttpr_exit_manual_automation_8));
link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc,
&vendor_lttpr_exit_manual_automation_9[0], sizeof(vendor_lttpr_exit_manual_automation_9));
}
static bool set_dio_fixed_vs_pe_retimer_dp_link_test_pattern_override(struct dc_link *link,
const struct link_resource *link_res, struct encoder_set_dp_phy_pattern_param *tp_params,
const struct link_hwss *link_hwss)
{
struct encoder_set_dp_phy_pattern_param hw_tp_params = { 0 };
const uint8_t pltpat_custom[10] = {0x1F, 0x7C, 0xF0, 0xC1, 0x07, 0x1F, 0x7C, 0xF0, 0xC1, 0x07};
const uint8_t vendor_lttpr_write_data_pg0[4] = {0x1, 0x11, 0x0, 0x0};
const uint8_t vendor_lttpr_exit_manual_automation_0[4] = {0x1, 0x11, 0x0, 0x06};
if (tp_params == NULL)
return false;
if (link->current_test_pattern >= DP_TEST_PATTERN_SQUARE_BEGIN &&
link->current_test_pattern <= DP_TEST_PATTERN_SQUARE_END) {
// Deprogram overrides from previous test pattern
dp_dio_fixed_vs_pe_retimer_exit_manual_automation(link);
}
switch (tp_params->dp_phy_pattern) {
case DP_TEST_PATTERN_80BIT_CUSTOM:
if (tp_params->custom_pattern_size == 0 || memcmp(tp_params->custom_pattern,
pltpat_custom, tp_params->custom_pattern_size) != 0)
return false;
break;
case DP_TEST_PATTERN_D102:
break;
default:
if (link->current_test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM ||
link->current_test_pattern == DP_TEST_PATTERN_D102)
// Deprogram overrides from previous test pattern
link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc,
&vendor_lttpr_exit_manual_automation_0[0],
sizeof(vendor_lttpr_exit_manual_automation_0));
return false;
}
hw_tp_params.dp_phy_pattern = tp_params->dp_phy_pattern;
hw_tp_params.dp_panel_mode = tp_params->dp_panel_mode;
if (link_hwss->ext.set_dp_link_test_pattern)
link_hwss->ext.set_dp_link_test_pattern(link, link_res, &hw_tp_params);
link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc,
&vendor_lttpr_write_data_pg0[0], sizeof(vendor_lttpr_write_data_pg0));
return true;
}
static void set_dio_fixed_vs_pe_retimer_dp_link_test_pattern(struct dc_link *link,
const struct link_resource *link_res,
struct encoder_set_dp_phy_pattern_param *tp_params)
{
struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link);
if (!set_dio_fixed_vs_pe_retimer_dp_link_test_pattern_override(
link, link_res, tp_params, get_dio_link_hwss())) {
link_enc->funcs->dp_set_phy_pattern(link_enc, tp_params);
}
link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN);
}
void enable_dio_fixed_vs_pe_retimer_program_4lane_output(struct dc_link *link)
{
const uint8_t vendor_lttpr_write_data_4lane_1[4] = {0x1, 0x6E, 0xF2, 0x19};
const uint8_t vendor_lttpr_write_data_4lane_2[4] = {0x1, 0x6B, 0xF2, 0x01};
const uint8_t vendor_lttpr_write_data_4lane_3[4] = {0x1, 0x6D, 0xF2, 0x18};
const uint8_t vendor_lttpr_write_data_4lane_4[4] = {0x1, 0x6C, 0xF2, 0x03};
const uint8_t vendor_lttpr_write_data_4lane_5[4] = {0x1, 0x03, 0xF3, 0x06};
link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc,
&vendor_lttpr_write_data_4lane_1[0], sizeof(vendor_lttpr_write_data_4lane_1));
link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc,
&vendor_lttpr_write_data_4lane_2[0], sizeof(vendor_lttpr_write_data_4lane_2));
link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc,
&vendor_lttpr_write_data_4lane_3[0], sizeof(vendor_lttpr_write_data_4lane_3));
link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc,
&vendor_lttpr_write_data_4lane_4[0], sizeof(vendor_lttpr_write_data_4lane_4));
link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc,
&vendor_lttpr_write_data_4lane_5[0], sizeof(vendor_lttpr_write_data_4lane_5));
}
static void enable_dio_fixed_vs_pe_retimer_dp_link_output(struct dc_link *link,
const struct link_resource *link_res,
enum signal_type signal,
enum clock_source_id clock_source,
const struct dc_link_settings *link_settings)
{
if (link_settings->lane_count == LANE_COUNT_FOUR)
enable_dio_fixed_vs_pe_retimer_program_4lane_output(link);
enable_dio_dp_link_output(link, link_res, signal, clock_source, link_settings);
}
static const struct link_hwss dio_fixed_vs_pe_retimer_link_hwss = {
.setup_stream_encoder = setup_dio_stream_encoder,
.reset_stream_encoder = reset_dio_stream_encoder,
.setup_stream_attribute = setup_dio_stream_attribute,
.disable_link_output = disable_dio_link_output,
.setup_audio_output = setup_dio_audio_output,
.enable_audio_packet = enable_dio_audio_packet,
.disable_audio_packet = disable_dio_audio_packet,
.ext = {
.set_throttled_vcp_size = set_dio_throttled_vcp_size,
.enable_dp_link_output = enable_dio_fixed_vs_pe_retimer_dp_link_output,
.set_dp_link_test_pattern = set_dio_fixed_vs_pe_retimer_dp_link_test_pattern,
.set_dp_lane_settings = set_dio_dp_lane_settings,
.update_stream_allocation_table = update_dio_stream_allocation_table,
},
};
bool requires_fixed_vs_pe_retimer_dio_link_hwss(const struct dc_link *link)
{
if (!(link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN))
return false;
if (!link->dpcd_caps.lttpr_caps.main_link_channel_coding.bits.DP_128b_132b_SUPPORTED)
return false;
return true;
}
const struct link_hwss *get_dio_fixed_vs_pe_retimer_link_hwss(void)
{
return &dio_fixed_vs_pe_retimer_link_hwss;
}
/*
* Copyright 2023 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef __LINK_HWSS_DIO_FIXED_VS_PE_RETIMER_H__
#define __LINK_HWSS_DIO_FIXED_VS_PE_RETIMER_H__
#include "link.h"
uint32_t dp_dio_fixed_vs_pe_retimer_get_lttpr_write_address(struct dc_link *link);
uint8_t dp_dio_fixed_vs_pe_retimer_lane_cfg_to_hw_cfg(struct dc_link *link);
void dp_dio_fixed_vs_pe_retimer_exit_manual_automation(struct dc_link *link);
void enable_dio_fixed_vs_pe_retimer_program_4lane_output(struct dc_link *link);
bool requires_fixed_vs_pe_retimer_dio_link_hwss(const struct dc_link *link);
const struct link_hwss *get_dio_fixed_vs_pe_retimer_link_hwss(void);
#endif /* __LINK_HWSS_DIO_FIXED_VS_PE_RETIMER_H__ */
......@@ -28,7 +28,7 @@
#include "dccg.h"
#include "clk_mgr.h"
static void set_hpo_dp_throttled_vcp_size(struct pipe_ctx *pipe_ctx,
void set_hpo_dp_throttled_vcp_size(struct pipe_ctx *pipe_ctx,
struct fixed31_32 throttled_vcp_size)
{
struct hpo_dp_stream_encoder *hpo_dp_stream_encoder =
......@@ -41,7 +41,7 @@ static void set_hpo_dp_throttled_vcp_size(struct pipe_ctx *pipe_ctx,
throttled_vcp_size);
}
static void set_hpo_dp_hblank_min_symbol_width(struct pipe_ctx *pipe_ctx,
void set_hpo_dp_hblank_min_symbol_width(struct pipe_ctx *pipe_ctx,
const struct dc_link_settings *link_settings,
struct fixed31_32 throttled_vcp_size)
{
......@@ -69,7 +69,7 @@ static void set_hpo_dp_hblank_min_symbol_width(struct pipe_ctx *pipe_ctx,
hblank_min_symbol_width);
}
static void setup_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx)
void setup_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx)
{
struct hpo_dp_stream_encoder *stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc;
struct hpo_dp_link_encoder *link_enc = pipe_ctx->link_res.hpo_dp_link_enc;
......@@ -78,14 +78,14 @@ static void setup_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx)
stream_enc->funcs->map_stream_to_link(stream_enc, stream_enc->inst, link_enc->inst);
}
static void reset_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx)
void reset_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx)
{
struct hpo_dp_stream_encoder *stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc;
stream_enc->funcs->disable(stream_enc);
}
static void setup_hpo_dp_stream_attribute(struct pipe_ctx *pipe_ctx)
void setup_hpo_dp_stream_attribute(struct pipe_ctx *pipe_ctx)
{
struct hpo_dp_stream_encoder *stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc;
struct dc_stream_state *stream = pipe_ctx->stream;
......@@ -102,7 +102,7 @@ static void setup_hpo_dp_stream_attribute(struct pipe_ctx *pipe_ctx)
DPCD_SOURCE_SEQ_AFTER_DP_STREAM_ATTR);
}
static void enable_hpo_dp_link_output(struct dc_link *link,
void enable_hpo_dp_link_output(struct dc_link *link,
const struct link_resource *link_res,
enum signal_type signal,
enum clock_source_id clock_source,
......@@ -120,7 +120,7 @@ static void enable_hpo_dp_link_output(struct dc_link *link,
link->link_enc->hpd_source);
}
static void disable_hpo_dp_link_output(struct dc_link *link,
void disable_hpo_dp_link_output(struct dc_link *link,
const struct link_resource *link_res,
enum signal_type signal)
{
......@@ -154,7 +154,7 @@ static void set_hpo_dp_lane_settings(struct dc_link *link,
lane_settings[0].FFE_PRESET.raw);
}
static void update_hpo_dp_stream_allocation_table(struct dc_link *link,
void update_hpo_dp_stream_allocation_table(struct dc_link *link,
const struct link_resource *link_res,
const struct link_mst_stream_allocation_table *table)
{
......@@ -163,7 +163,7 @@ static void update_hpo_dp_stream_allocation_table(struct dc_link *link,
table);
}
static void setup_hpo_dp_audio_output(struct pipe_ctx *pipe_ctx,
void setup_hpo_dp_audio_output(struct pipe_ctx *pipe_ctx,
struct audio_output *audio_output, uint32_t audio_inst)
{
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_audio_setup(
......@@ -172,13 +172,13 @@ static void setup_hpo_dp_audio_output(struct pipe_ctx *pipe_ctx,
&pipe_ctx->stream->audio_info);
}
static void enable_hpo_dp_audio_packet(struct pipe_ctx *pipe_ctx)
void enable_hpo_dp_audio_packet(struct pipe_ctx *pipe_ctx)
{
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_audio_enable(
pipe_ctx->stream_res.hpo_dp_stream_enc);
}
static void disable_hpo_dp_audio_packet(struct pipe_ctx *pipe_ctx)
void disable_hpo_dp_audio_packet(struct pipe_ctx *pipe_ctx)
{
if (pipe_ctx->stream_res.audio)
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_audio_disable(
......
......@@ -28,9 +28,35 @@
#include "link_hwss.h"
#include "link.h"
void set_hpo_dp_throttled_vcp_size(struct pipe_ctx *pipe_ctx,
struct fixed31_32 throttled_vcp_size);
void set_hpo_dp_hblank_min_symbol_width(struct pipe_ctx *pipe_ctx,
const struct dc_link_settings *link_settings,
struct fixed31_32 throttled_vcp_size);
void set_hpo_dp_hblank_min_symbol_width(struct pipe_ctx *pipe_ctx,
const struct dc_link_settings *link_settings,
struct fixed31_32 throttled_vcp_size);
void setup_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx);
void reset_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx);
void setup_hpo_dp_stream_attribute(struct pipe_ctx *pipe_ctx);
void enable_hpo_dp_link_output(struct dc_link *link,
const struct link_resource *link_res,
enum signal_type signal,
enum clock_source_id clock_source,
const struct dc_link_settings *link_settings);
void disable_hpo_dp_link_output(struct dc_link *link,
const struct link_resource *link_res,
enum signal_type signal);
void update_hpo_dp_stream_allocation_table(struct dc_link *link,
const struct link_resource *link_res,
const struct link_mst_stream_allocation_table *table);
void setup_hpo_dp_audio_output(struct pipe_ctx *pipe_ctx,
struct audio_output *audio_output, uint32_t audio_inst);
void enable_hpo_dp_audio_packet(struct pipe_ctx *pipe_ctx);
void disable_hpo_dp_audio_packet(struct pipe_ctx *pipe_ctx);
const struct link_hwss *get_hpo_dp_link_hwss(void);
bool can_use_hpo_dp_link_hwss(const struct dc_link *link,
const struct link_resource *link_res);
const struct link_hwss *get_hpo_dp_link_hwss(void);
#endif /* __LINK_HWSS_HPO_DP_H__ */
/*
* Copyright 2023 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef __LINK_HWSS_HPO_FIXED_VS_PE_RETIMER_DP_H__
#define __LINK_HWSS_HPO_FIXED_VS_PE_RETIMER_DP_H__
#include "link.h"
bool requires_fixed_vs_pe_retimer_hpo_link_hwss(const struct dc_link *link);
const struct link_hwss *get_hpo_fixed_vs_pe_retimer_dp_link_hwss(void);
#endif /* __LINK_HWSS_HPO_FIXED_VS_PE_RETIMER_DP_H__ */
......@@ -132,6 +132,7 @@ static void construct_link_service_ddc(struct link_service *link_srv)
link_srv->destroy_ddc_service = link_destroy_ddc_service;
link_srv->query_ddc_data = link_query_ddc_data;
link_srv->aux_transfer_raw = link_aux_transfer_raw;
link_srv->configure_fixed_vs_pe_retimer = link_configure_fixed_vs_pe_retimer;
link_srv->aux_transfer_with_retries_no_mutex =
link_aux_transfer_with_retries_no_mutex;
link_srv->is_in_aux_transaction_mode = link_is_in_aux_transaction_mode;
......
......@@ -412,6 +412,88 @@ int link_aux_transfer_raw(struct ddc_service *ddc,
}
}
uint32_t link_get_fixed_vs_pe_retimer_write_address(struct dc_link *link)
{
uint32_t vendor_lttpr_write_address = 0xF004F;
uint8_t offset;
switch (link->dpcd_caps.lttpr_caps.phy_repeater_cnt) {
case 0x80: // 1 lttpr repeater
offset = 1;
break;
case 0x40: // 2 lttpr repeaters
offset = 2;
break;
case 0x20: // 3 lttpr repeaters
offset = 3;
break;
case 0x10: // 4 lttpr repeaters
offset = 4;
break;
case 0x08: // 5 lttpr repeaters
offset = 5;
break;
case 0x04: // 6 lttpr repeaters
offset = 6;
break;
case 0x02: // 7 lttpr repeaters
offset = 7;
break;
case 0x01: // 8 lttpr repeaters
offset = 8;
break;
default:
offset = 0xFF;
}
if (offset != 0xFF) {
vendor_lttpr_write_address +=
((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
}
return vendor_lttpr_write_address;
}
uint32_t link_get_fixed_vs_pe_retimer_read_address(struct dc_link *link)
{
return link_get_fixed_vs_pe_retimer_write_address(link) + 4;
}
bool link_configure_fixed_vs_pe_retimer(struct ddc_service *ddc, const uint8_t *data, uint32_t length)
{
struct aux_payload write_payload = {
.i2c_over_aux = false,
.write = true,
.address = link_get_fixed_vs_pe_retimer_write_address(ddc->link),
.length = length,
.data = (uint8_t *) data,
.reply = NULL,
.mot = I2C_MOT_UNDEF,
.write_status_update = false,
.defer_delay = 0,
};
return link_aux_transfer_with_retries_no_mutex(ddc,
&write_payload);
}
bool link_query_fixed_vs_pe_retimer(struct ddc_service *ddc, uint8_t *data, uint32_t length)
{
struct aux_payload read_payload = {
.i2c_over_aux = false,
.write = false,
.address = link_get_fixed_vs_pe_retimer_read_address(ddc->link),
.length = length,
.data = data,
.reply = NULL,
.mot = I2C_MOT_UNDEF,
.write_status_update = false,
.defer_delay = 0,
};
return link_aux_transfer_with_retries_no_mutex(ddc,
&read_payload);
}
bool link_aux_transfer_with_retries_no_mutex(struct ddc_service *ddc,
struct aux_payload *payload)
{
......
......@@ -72,6 +72,20 @@ bool link_query_ddc_data(
bool link_aux_transfer_with_retries_no_mutex(struct ddc_service *ddc,
struct aux_payload *payload);
bool link_configure_fixed_vs_pe_retimer(
struct ddc_service *ddc,
const uint8_t *data,
uint32_t length);
bool link_query_fixed_vs_pe_retimer(
struct ddc_service *ddc,
uint8_t *data,
uint32_t length);
uint32_t link_get_fixed_vs_pe_retimer_read_address(struct dc_link *link);
uint32_t link_get_fixed_vs_pe_retimer_write_address(struct dc_link *link);
void write_scdc_data(
struct ddc_service *ddc_service,
uint32_t pix_clk,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment