Skip to content

Commit d108e4b

Browse files
George ShenSasha Levin
authored andcommitted
drm/amd/display: Check DP Alt mode DPCS state via DMUB
[ Upstream commit 7d1e9d0 ] [Why] Currently, driver state for DCN3.2 is not strictly matching HW state for the USBC port. To reduce inconsistencies while debugging, the driver should match HW configuration. [How] Update link encoder flag to indicate USBC port. Call into DMUB to check when DP Alt mode is entered, and also to check for 2-lane versuse 4-lane mode. Reviewed-by: Charlene Liu <charlene.liu@amd.com> Acked-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: George Shen <george.shen@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Stable-dep-of: 91f10a3 ("Revert "drm/amd/display: fix USB-C flag update after enc10 feature init"") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 1dab98a commit d108e4b

File tree

2 files changed

+71
-19
lines changed

2 files changed

+71
-19
lines changed

drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c

Lines changed: 66 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "dc_bios_types.h"
3535
#include "link_enc_cfg.h"
3636

37+
#include "dc_dmub_srv.h"
3738
#include "gpio_service_interface.h"
3839

3940
#ifndef MIN
@@ -61,6 +62,38 @@
6162
#define AUX_REG_WRITE(reg_name, val) \
6263
dm_write_reg(CTX, AUX_REG(reg_name), val)
6364

65+
static uint8_t phy_id_from_transmitter(enum transmitter t)
66+
{
67+
uint8_t phy_id;
68+
69+
switch (t) {
70+
case TRANSMITTER_UNIPHY_A:
71+
phy_id = 0;
72+
break;
73+
case TRANSMITTER_UNIPHY_B:
74+
phy_id = 1;
75+
break;
76+
case TRANSMITTER_UNIPHY_C:
77+
phy_id = 2;
78+
break;
79+
case TRANSMITTER_UNIPHY_D:
80+
phy_id = 3;
81+
break;
82+
case TRANSMITTER_UNIPHY_E:
83+
phy_id = 4;
84+
break;
85+
case TRANSMITTER_UNIPHY_F:
86+
phy_id = 5;
87+
break;
88+
case TRANSMITTER_UNIPHY_G:
89+
phy_id = 6;
90+
break;
91+
default:
92+
phy_id = 0;
93+
break;
94+
}
95+
return phy_id;
96+
}
6497

6598
void enc32_hw_init(struct link_encoder *enc)
6699
{
@@ -117,38 +150,50 @@ void dcn32_link_encoder_enable_dp_output(
117150
}
118151
}
119152

120-
static bool dcn32_link_encoder_is_in_alt_mode(struct link_encoder *enc)
153+
static bool query_dp_alt_from_dmub(struct link_encoder *enc,
154+
union dmub_rb_cmd *cmd)
121155
{
122156
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
123-
uint32_t dp_alt_mode_disable = 0;
124-
bool is_usb_c_alt_mode = false;
125157

126-
if (enc->features.flags.bits.DP_IS_USB_C) {
127-
/* if value == 1 alt mode is disabled, otherwise it is enabled */
128-
REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
129-
is_usb_c_alt_mode = (dp_alt_mode_disable == 0);
130-
}
158+
memset(cmd, 0, sizeof(*cmd));
159+
cmd->query_dp_alt.header.type = DMUB_CMD__VBIOS;
160+
cmd->query_dp_alt.header.sub_type =
161+
DMUB_CMD__VBIOS_TRANSMITTER_QUERY_DP_ALT;
162+
cmd->query_dp_alt.header.payload_bytes = sizeof(cmd->query_dp_alt.data);
163+
cmd->query_dp_alt.data.phy_id = phy_id_from_transmitter(enc10->base.transmitter);
164+
165+
if (!dc_wake_and_execute_dmub_cmd(enc->ctx, cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY))
166+
return false;
131167

132-
return is_usb_c_alt_mode;
168+
return true;
133169
}
134170

135-
static void dcn32_link_encoder_get_max_link_cap(struct link_encoder *enc,
171+
bool dcn32_link_encoder_is_in_alt_mode(struct link_encoder *enc)
172+
{
173+
union dmub_rb_cmd cmd;
174+
175+
if (!query_dp_alt_from_dmub(enc, &cmd))
176+
return false;
177+
178+
return (cmd.query_dp_alt.data.is_dp_alt_disable == 0);
179+
}
180+
181+
void dcn32_link_encoder_get_max_link_cap(struct link_encoder *enc,
136182
struct dc_link_settings *link_settings)
137183
{
138-
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
139-
uint32_t is_in_usb_c_dp4_mode = 0;
184+
union dmub_rb_cmd cmd;
140185

141186
dcn10_link_encoder_get_max_link_cap(enc, link_settings);
142187

143-
/* in usb c dp2 mode, max lane count is 2 */
144-
if (enc->funcs->is_in_alt_mode && enc->funcs->is_in_alt_mode(enc)) {
145-
REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode);
146-
if (!is_in_usb_c_dp4_mode)
147-
link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count);
148-
}
188+
if (!query_dp_alt_from_dmub(enc, &cmd))
189+
return;
149190

191+
if (cmd.query_dp_alt.data.is_usb &&
192+
cmd.query_dp_alt.data.is_dp4 == 0)
193+
link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count);
150194
}
151195

196+
152197
static const struct link_encoder_funcs dcn32_link_enc_funcs = {
153198
.read_state = link_enc2_read_state,
154199
.validate_output_with_stream =
@@ -203,13 +248,15 @@ void dcn32_link_encoder_construct(
203248
enc10->base.hpd_source = init_data->hpd_source;
204249
enc10->base.connector = init_data->connector;
205250

206-
207251
enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
208252

209253
enc10->base.features = *enc_features;
210254
if (enc10->base.connector.id == CONNECTOR_ID_USBC)
211255
enc10->base.features.flags.bits.DP_IS_USB_C = 1;
212256

257+
if (enc10->base.connector.id == CONNECTOR_ID_USBC)
258+
enc10->base.features.flags.bits.DP_IS_USB_C = 1;
259+
213260
enc10->base.transmitter = init_data->transmitter;
214261

215262
/* set the flag to indicate whether driver poll the I2C data pin

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,9 @@ void dcn32_link_encoder_enable_dp_output(
5353
const struct dc_link_settings *link_settings,
5454
enum clock_source_id clock_source);
5555

56+
bool dcn32_link_encoder_is_in_alt_mode(struct link_encoder *enc);
57+
58+
void dcn32_link_encoder_get_max_link_cap(struct link_encoder *enc,
59+
struct dc_link_settings *link_settings);
60+
5661
#endif /* __DC_LINK_ENCODER__DCN32_H__ */

0 commit comments

Comments
 (0)