Skip to content

Commit 44063db

Browse files
Peichen Huangalexdeucher
authored andcommitted
drm/amd/display: have pretrain for dpia
[WHY] We like to have pretrain for dpia link so that dp and dp tunneling have aligned behavior. The Main difficult for dpia pretrain is that encoder can not get corresponded dpia port when link detection in current implementation. [HOW] 1. create enable/disable dpia output functions for dcn35 encoder and have dpia_id and other necessary info as inputs. 2. dcn35 dpia use the new functions to enable/disable output. 3. have a option to enable/disable the change. Reviewed-by: Wenjing Liu <[email protected]> Reviewed-by: Meenakshikumar Somasundaram <[email protected]> Signed-off-by: Peichen Huang <[email protected]> Signed-off-by: Roman Li <[email protected]> Tested-by: Daniel Wheeler <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 5acacec commit 44063db

File tree

10 files changed

+180
-7
lines changed

10 files changed

+180
-7
lines changed

drivers/gpu/drm/amd/display/dc/dc.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ struct dc_config {
472472
bool disable_hbr_audio_dp2;
473473
bool consolidated_dpia_dp_lt;
474474
bool set_pipe_unlock_order;
475+
bool enable_dpia_pre_training;
475476
};
476477

477478
enum visual_confirm {
@@ -775,7 +776,8 @@ union dpia_debug_options {
775776
uint32_t enable_force_tbt3_work_around:1; /* bit 4 */
776777
uint32_t disable_usb4_pm_support:1; /* bit 5 */
777778
uint32_t enable_consolidated_dpia_dp_lt:1; /* bit 6 */
778-
uint32_t reserved:25;
779+
uint32_t enable_dpia_pre_training:1; /* bit 7 */
780+
uint32_t reserved:24;
779781
} bits;
780782
uint32_t raw;
781783
};

drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_link_encoder.c

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "link_encoder.h"
2929
#include "dcn31/dcn31_dio_link_encoder.h"
3030
#include "dcn35_dio_link_encoder.h"
31+
#include "dc_dmub_srv.h"
3132
#define CTX \
3233
enc10->base.ctx
3334
#define DC_LOGGER \
@@ -159,6 +160,8 @@ static const struct link_encoder_funcs dcn35_link_enc_funcs = {
159160
.is_in_alt_mode = dcn31_link_encoder_is_in_alt_mode,
160161
.get_max_link_cap = dcn31_link_encoder_get_max_link_cap,
161162
.set_dio_phy_mux = dcn31_link_encoder_set_dio_phy_mux,
163+
.enable_dpia_output = dcn35_link_encoder_enable_dpia_output,
164+
.disable_dpia_output = dcn35_link_encoder_disable_dpia_output,
162165
};
163166

164167
void dcn35_link_encoder_construct(
@@ -265,3 +268,80 @@ void dcn35_link_encoder_construct(
265268
enc10->base.features.flags.bits.HDMI_6GB_EN = 0;
266269

267270
}
271+
272+
/* DPIA equivalent of link_transmitter_control. */
273+
static bool link_dpia_control(struct dc_context *dc_ctx,
274+
struct dmub_cmd_dig_dpia_control_data *dpia_control)
275+
{
276+
union dmub_rb_cmd cmd;
277+
278+
memset(&cmd, 0, sizeof(cmd));
279+
280+
cmd.dig1_dpia_control.header.type = DMUB_CMD__DPIA;
281+
cmd.dig1_dpia_control.header.sub_type =
282+
DMUB_CMD__DPIA_DIG1_DPIA_CONTROL;
283+
cmd.dig1_dpia_control.header.payload_bytes =
284+
sizeof(cmd.dig1_dpia_control) -
285+
sizeof(cmd.dig1_dpia_control.header);
286+
287+
cmd.dig1_dpia_control.dpia_control = *dpia_control;
288+
289+
dc_wake_and_execute_dmub_cmd(dc_ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
290+
291+
return true;
292+
}
293+
294+
static void link_encoder_disable(struct dcn10_link_encoder *enc10)
295+
{
296+
/* reset training complete */
297+
REG_UPDATE(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, 0);
298+
}
299+
300+
void dcn35_link_encoder_enable_dpia_output(
301+
struct link_encoder *enc,
302+
const struct dc_link_settings *link_settings,
303+
uint8_t dpia_id,
304+
uint8_t digmode,
305+
uint8_t fec_rdy)
306+
{
307+
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
308+
struct dmub_cmd_dig_dpia_control_data dpia_control = { 0 };
309+
310+
enc1_configure_encoder(enc10, link_settings);
311+
312+
dpia_control.action = (uint8_t)TRANSMITTER_CONTROL_ENABLE;
313+
dpia_control.enc_id = enc->preferred_engine;
314+
dpia_control.mode_laneset.digmode = digmode;
315+
dpia_control.lanenum = (uint8_t)link_settings->lane_count;
316+
dpia_control.symclk_10khz = link_settings->link_rate *
317+
LINK_RATE_REF_FREQ_IN_KHZ / 10;
318+
/* DIG_BE_CNTL.DIG_HPD_SELECT set to 5 (hpdsel - 1) to indicate HPD pin unused by DPIA. */
319+
dpia_control.hpdsel = 6;
320+
dpia_control.dpia_id = dpia_id;
321+
dpia_control.fec_rdy = fec_rdy;
322+
323+
DC_LOG_DEBUG("%s: DPIA(%d) - enc_id(%d)\n", __func__, dpia_control.dpia_id, dpia_control.enc_id);
324+
link_dpia_control(enc->ctx, &dpia_control);
325+
}
326+
327+
void dcn35_link_encoder_disable_dpia_output(
328+
struct link_encoder *enc,
329+
uint8_t dpia_id,
330+
uint8_t digmode)
331+
{
332+
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
333+
struct dmub_cmd_dig_dpia_control_data dpia_control = { 0 };
334+
335+
if (enc->funcs->is_dig_enabled && !enc->funcs->is_dig_enabled(enc))
336+
return;
337+
338+
dpia_control.action = (uint8_t)TRANSMITTER_CONTROL_DISABLE;
339+
dpia_control.enc_id = enc->preferred_engine;
340+
dpia_control.mode_laneset.digmode = digmode;
341+
dpia_control.dpia_id = dpia_id;
342+
343+
DC_LOG_DEBUG("%s: DPIA(%d) - enc_id(%d)\n", __func__, dpia_control.dpia_id, dpia_control.enc_id);
344+
link_dpia_control(enc->ctx, &dpia_control);
345+
346+
link_encoder_disable(enc10);
347+
}

drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_link_encoder.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,22 @@ bool dcn35_is_dig_enabled(struct link_encoder *enc);
144144
enum signal_type dcn35_get_dig_mode(struct link_encoder *enc);
145145
void dcn35_link_encoder_setup(struct link_encoder *enc, enum signal_type signal);
146146

147+
/*
148+
* Enable DP transmitter and its encoder for dpia port.
149+
*/
150+
void dcn35_link_encoder_enable_dpia_output(
151+
struct link_encoder *enc,
152+
const struct dc_link_settings *link_settings,
153+
uint8_t dpia_id,
154+
uint8_t digmode,
155+
uint8_t fec_rdy);
156+
157+
/*
158+
* Disable transmitter and its encoder for dpia port.
159+
*/
160+
void dcn35_link_encoder_disable_dpia_output(
161+
struct link_encoder *enc,
162+
uint8_t dpia_id,
163+
uint8_t digmode);
164+
147165
#endif /* __DC_LINK_ENCODER__DCN35_H__ */

drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,14 @@ struct link_encoder_funcs {
168168
struct link_encoder *enc,
169169
enum encoder_type_select sel,
170170
uint32_t hpo_inst);
171+
void (*enable_dpia_output)(struct link_encoder *enc,
172+
const struct dc_link_settings *link_settings,
173+
uint8_t dpia_id,
174+
uint8_t digmode,
175+
uint8_t fec_rdy);
176+
void (*disable_dpia_output)(struct link_encoder *link_enc,
177+
uint8_t dpia_id,
178+
uint8_t digmode);
171179
};
172180

173181
/*

drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,9 @@ void disable_dio_link_output(struct dc_link *link,
164164
{
165165
struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link);
166166

167-
link_enc->funcs->disable_output(link_enc, signal);
167+
if (link_enc != NULL)
168+
link_enc->funcs->disable_output(link_enc, signal);
169+
168170
link->dc->link_srv->dp_trace_source_sequence(link,
169171
DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
170172
}

drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dpia.c

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,74 @@ static void set_dio_dpia_lane_settings(struct dc_link *link,
7777
{
7878
}
7979

80+
static void enable_dpia_link_output(struct dc_link *link,
81+
const struct link_resource *link_res,
82+
enum signal_type signal,
83+
enum clock_source_id clock_source,
84+
const struct dc_link_settings *link_settings)
85+
{
86+
struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link);
87+
88+
if (link_enc != NULL) {
89+
if (link->dc->config.enable_dpia_pre_training && link_enc->funcs->enable_dpia_output) {
90+
uint8_t fec_rdy = link->dc->link_srv->dp_should_enable_fec(link);
91+
uint8_t digmode = dc_is_dp_sst_signal(signal) ? DIG_SST_MODE : DIG_MST_MODE;
92+
93+
link_enc->funcs->enable_dpia_output(
94+
link_enc,
95+
link_settings,
96+
link->ddc_hw_inst,
97+
digmode,
98+
fec_rdy);
99+
} else {
100+
if (dc_is_dp_sst_signal(signal))
101+
link_enc->funcs->enable_dp_output(
102+
link_enc,
103+
link_settings,
104+
clock_source);
105+
else
106+
link_enc->funcs->enable_dp_mst_output(
107+
link_enc,
108+
link_settings,
109+
clock_source);
110+
}
111+
112+
}
113+
114+
link->dc->link_srv->dp_trace_source_sequence(link,
115+
DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
116+
}
117+
118+
static void disable_dpia_link_output(struct dc_link *link,
119+
const struct link_resource *link_res,
120+
enum signal_type signal)
121+
{
122+
struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link);
123+
124+
if (link_enc != NULL) {
125+
if (link->dc->config.enable_dpia_pre_training && link_enc->funcs->disable_dpia_output) {
126+
uint8_t digmode = dc_is_dp_sst_signal(signal) ? DIG_SST_MODE : DIG_MST_MODE;
127+
128+
link_enc->funcs->disable_dpia_output(link_enc, link->ddc_hw_inst, digmode);
129+
} else
130+
link_enc->funcs->disable_output(link_enc, signal);
131+
}
132+
133+
link->dc->link_srv->dp_trace_source_sequence(link,
134+
DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
135+
}
136+
80137
static const struct link_hwss dpia_link_hwss = {
81138
.setup_stream_encoder = setup_dio_stream_encoder,
82139
.reset_stream_encoder = reset_dio_stream_encoder,
83140
.setup_stream_attribute = setup_dio_stream_attribute,
84-
.disable_link_output = disable_dio_link_output,
141+
.disable_link_output = disable_dpia_link_output,
85142
.setup_audio_output = setup_dio_audio_output,
86143
.enable_audio_packet = enable_dio_audio_packet,
87144
.disable_audio_packet = disable_dio_audio_packet,
88145
.ext = {
89146
.set_throttled_vcp_size = set_dio_throttled_vcp_size,
90-
.enable_dp_link_output = enable_dio_dp_link_output,
147+
.enable_dp_link_output = enable_dpia_link_output,
91148
.set_dp_link_test_pattern = set_dio_dpia_link_test_pattern,
92149
.set_dp_lane_settings = set_dio_dpia_lane_settings,
93150
.update_stream_allocation_table = update_dpia_stream_allocation_table,

drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dpia.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727

2828
#include "link_hwss.h"
2929

30+
#define DIG_SST_MODE 0
31+
#define DIG_MST_MODE 5
32+
3033
const struct link_hwss *get_dpia_link_hwss(void);
3134
bool can_use_dpia_link_hwss(const struct dc_link *link,
3235
const struct link_resource *link_res);

drivers/gpu/drm/amd/display/dc/link/link_detection.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,8 @@ static bool should_verify_link_capability_destructively(struct dc_link *link,
829829

830830
if (link->dc->debug.skip_detection_link_training ||
831831
dc_is_embedded_signal(link->local_sink->sink_signal) ||
832-
link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) {
832+
(link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
833+
!link->dc->config.enable_dpia_pre_training)) {
833834
destrictive = false;
834835
} else if (link_dp_get_encoding_format(&max_link_cap) ==
835836
DP_8b_10b_ENCODING) {

drivers/gpu/drm/amd/display/dc/link/link_dpms.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2043,7 +2043,8 @@ static enum dc_status enable_link_dp(struct dc_state *state,
20432043
/* Train with fallback when enabling DPIA link. Conventional links are
20442044
* trained with fallback during sink detection.
20452045
*/
2046-
if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
2046+
if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
2047+
!link->dc->config.enable_dpia_pre_training)
20472048
do_fallback = true;
20482049

20492050
/*

drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,8 @@ bool dp_handle_hpd_rx_irq(struct dc_link *link,
410410

411411
if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.AUTOMATED_TEST) {
412412
// Workaround for DP 1.4a LL Compliance CTS as USB4 has to share encoders unlike DP and USBC
413-
if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
413+
if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
414+
!link->dc->config.enable_dpia_pre_training)
414415
link->skip_fallback_on_link_loss = true;
415416

416417
device_service_clear.bits.AUTOMATED_TEST = 1;

0 commit comments

Comments
 (0)