drm/amd/display: Replace repeated no-native-i2c checks with force_i2c_over_aux field

[Why]
The compound condition checking dp_connector_no_native_i2c
and no_ddc_pin was duplicated across many files, obscuring
intent at every call site.

[How]
Add bool force_i2c_over_aux to struct dc_link, initialized
once during link creation. Add link_get_ddc_aux_inst()
helper to select the correct aux instance. Wire into
link_service via construct_link_service_ddc(). Replace all
duplicated condition checks and aux instance selection
blocks with the new field and helper. No functional change.

Reviewed-by: Nevenko Stupar <nevenko.stupar@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
Signed-off-by: George Zhang <george.zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Wenjing Liu 2026-06-09 22:21:16 -04:00 committed by Alex Deucher
parent d37d3555dd
commit 7a39b1c3b2
12 changed files with 43 additions and 44 deletions

View File

@ -1845,6 +1845,10 @@ struct dc_scratch_space {
* of ddc_pin to know which aux instance is associated with link.
*/
bool no_ddc_pin;
/** When set, forces all native I2C communication on this DP connector
* to use the I2C-over-AUX protocol instead of native I2C signaling.
*/
bool force_to_use_aux;
enum gpio_ddc_line aux_hw_inst;
enum gpio_ddc_line ddc_hw_inst;

View File

@ -529,7 +529,7 @@ static uint32_t dce_aux_configure_timeout(struct ddc_service *ddc,
uint32_t prev_timeout_val = 0;
struct ddc *ddc_pin = ddc->ddc_pin;
if (ddc->ctx->dc->config.dp_connector_no_native_i2c && ddc->link->no_ddc_pin)
if (ddc->link->force_to_use_aux)
return dce_aux_configure_timeout_without_ddc_pin(ddc, timeout_in_us);
struct dce_aux *aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
@ -652,7 +652,7 @@ int dce_aux_transfer_raw(struct ddc_service *ddc,
struct aux_payload *payload,
enum aux_return_code_type *operation_result)
{
if (ddc->ctx->dc->config.dp_connector_no_native_i2c && ddc->link->no_ddc_pin) {
if (ddc->link->force_to_use_aux) {
/* Check whether aux to be processed via dmub or dcn directly */
if (ddc->ctx->dc->debug.enable_dmub_aux_for_legacy_ddc) {
return dce_aux_transfer_dmub_raw(ddc, payload, operation_result);
@ -795,7 +795,7 @@ int dce_aux_transfer_dmub_raw(struct ddc_service *ddc,
release_engine(aux_engine);
}
if (ddc->ctx->dc->config.dp_connector_no_native_i2c && ddc->link->no_ddc_pin) {
if (ddc->link->force_to_use_aux) {
struct dce_aux *aux_engine = ddc->ctx->dc->res_pool->engines[ddc->link->aux_hw_inst];
if (!acquire_aux_engine_without_ddc_pin(aux_engine, ddc_pin)) {
@ -893,7 +893,7 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
aux110 = FROM_AUX_ENGINE(aux_engine);
}
if (ddc->ctx->dc->config.dp_connector_no_native_i2c && ddc->link->no_ddc_pin) {
if (ddc->link->force_to_use_aux) {
aux_engine = ddc->ctx->dc->res_pool->engines[ddc->link->aux_hw_inst];
aux110 = FROM_AUX_ENGINE(aux_engine);
}

View File

@ -321,7 +321,7 @@ void dcn401_init_hw(struct dc *dc)
user_level = link->panel_cntl->stored_backlight_registers.USER_LEVEL;
}
if (link->ctx->dc->config.dp_connector_no_native_i2c && link->no_ddc_pin) {
if (link->force_to_use_aux) {
struct graphics_object_i2c_info i2c_info;
struct ddc *ddc_pin;
struct gpio_ddc_hw_info hw_info;

View File

@ -193,6 +193,7 @@ struct link_service {
struct aux_payload *payload);
bool (*is_in_aux_transaction_mode)(struct ddc_service *ddc);
uint32_t (*get_aux_defer_delay)(struct ddc_service *ddc);
uint8_t (*get_ddc_aux_inst)(const struct dc_link *link);
/*************************** DP Capability ****************************/

View File

@ -143,6 +143,7 @@ static void construct_link_service_ddc(struct link_service *link_srv)
link_aux_transfer_with_retries_no_mutex;
link_srv->is_in_aux_transaction_mode = link_is_in_aux_transaction_mode;
link_srv->get_aux_defer_delay = link_get_aux_defer_delay;
link_srv->get_ddc_aux_inst = link_get_ddc_aux_inst;
}
/* link dp capability implements dp specific link capability retrieval sequence.
@ -441,7 +442,7 @@ static enum channel_id get_ddc_line(struct dc_link *link)
channel = CHANNEL_ID_UNKNOWN;
if (link->ctx->dc->config.dp_connector_no_native_i2c && link->no_ddc_pin) {
if (link->force_to_use_aux) {
channel = link->aux_hw_inst + 1;
} else {
ddc = get_ddc_pin(link->ddc);
@ -576,6 +577,8 @@ static bool construct_phy(struct dc_link *link,
link->is_internal_display = (disp_connect_caps_info.INTERNAL_DISPLAY != 0);
DC_LOG_DC("BIOS object table - is_internal_display: %d", link->is_internal_display);
link->no_ddc_pin = disp_connect_caps_info.NO_DDC_PIN != 0;
link->force_to_use_aux = link->dc->config.dp_connector_no_native_i2c
&& link->no_ddc_pin;
}
if (link->link_id.type != OBJECT_TYPE_CONNECTOR) {
@ -598,7 +601,7 @@ static bool construct_phy(struct dc_link *link,
goto ddc_create_fail;
}
if (link->ctx->dc->config.dp_connector_no_native_i2c && link->no_ddc_pin) {
if (link->force_to_use_aux) {
link->ddc_hw_inst = link->aux_hw_inst;
} else {
/* Embedded display connectors such as LVDS may not have DDC. */

View File

@ -120,8 +120,7 @@ static void ddc_service_construct(
ddc_service->link = init_data->link;
ddc_service->ctx = init_data->ctx;
if (ddc_service->link && ddc_service->ctx->dc->config.dp_connector_no_native_i2c &&
ddc_service->link->no_ddc_pin) {
if (ddc_service->link && ddc_service->link->force_to_use_aux) {
// Obtain aux instance info from i2c_info without GPIO DDC pin info
if (dcb->funcs->get_connector_aux_info(dcb, init_data->id, &i2c_info) == BP_RESULT_OK)
ddc_service->link->aux_hw_inst = (uint8_t)i2c_info.i2c_line;
@ -252,6 +251,21 @@ static uint32_t defer_delay_converter_wa(
#define DP_TRANSLATOR_DELAY 5
/**
* link_get_ddc_aux_inst - Return the AUX/DDC hardware instance for a link.
* @link: the link to query
*
* Return: aux_hw_inst when I2C is forced over AUX, otherwise the DDC pin
* channel index.
*/
uint8_t link_get_ddc_aux_inst(const struct dc_link *link)
{
if (link->force_to_use_aux)
return link->aux_hw_inst;
ASSERT(link->ddc->ddc_pin->hw_info.ddc_channel <= 0xFF);
return (uint8_t)link->ddc->ddc_pin->hw_info.ddc_channel;
}
uint32_t link_get_aux_defer_delay(struct ddc_service *ddc)
{
uint32_t defer_delay = 0;
@ -526,7 +540,7 @@ bool try_to_configure_aux_timeout(struct ddc_service *ddc,
if (ddc->link->ep_type != DISPLAY_ENDPOINT_PHY)
return true;
if (ddc->ctx->dc->config.dp_connector_no_native_i2c && ddc->link->no_ddc_pin) {
if (ddc->link->force_to_use_aux) {
if (ddc->ctx->dc->res_pool->engines[ddc->link->aux_hw_inst]->funcs->configure_timeout) {
ddc->ctx->dc->res_pool->engines[ddc->link->aux_hw_inst]->funcs->configure_timeout(ddc, timeout);
result = true;

View File

@ -46,6 +46,8 @@ void set_ddc_transaction_type(
struct ddc_service *ddc,
enum ddc_transaction_type type);
uint8_t link_get_ddc_aux_inst(const struct dc_link *link);
uint32_t link_get_aux_defer_delay(struct ddc_service *ddc);
bool link_is_in_aux_transaction_mode(struct ddc_service *ddc);

View File

@ -2583,7 +2583,7 @@ bool dp_is_sink_present(struct dc_link *link)
/* We can't perform the step below for ASICs with no Native
* I2C signaling support on DP connectors, so skip it.
*/
if (link->ctx->dc->config.dp_connector_no_native_i2c && link->no_ddc_pin)
if (link->force_to_use_aux)
return present;
ddc = get_ddc_pin(link->ddc);

View File

@ -25,6 +25,7 @@
#include "link_dp_panel_replay.h"
#include "link_edp_panel_control.h"
#include "link_ddc.h"
#include "link_dpcd.h"
#include "dm_helpers.h"
#include "dc/dc_dmub_srv.h"
@ -119,11 +120,7 @@ static bool dp_setup_panel_replay(struct dc_link *link, const struct dc_stream_s
if (!dp_pr_get_panel_inst(dc, link, &panel_inst))
return false;
if (dc->config.dp_connector_no_native_i2c && link->no_ddc_pin) {
replay_context.aux_inst = (enum channel_id) link->aux_hw_inst;
} else {
replay_context.aux_inst = link->ddc->ddc_pin->hw_info.ddc_channel;
}
replay_context.aux_inst = (enum channel_id) link_get_ddc_aux_inst(link);
replay_context.digbe_inst = link->link_enc->transmitter;
replay_context.digfe_inst = link->link_enc->preferred_engine;

View File

@ -29,6 +29,7 @@
*/
#include "link_edp_panel_control.h"
#include "link_ddc.h"
#include "link_dpcd.h"
#include "link_dp_capability.h"
#include "dm_helpers.h"
@ -788,11 +789,7 @@ bool edp_setup_psr(struct dc_link *link,
}
}
if (dc->config.dp_connector_no_native_i2c && link->no_ddc_pin) {
psr_context->channel = (enum channel_id)link->aux_hw_inst;
} else {
psr_context->channel = link->ddc->ddc_pin->hw_info.ddc_channel;
}
psr_context->channel = link_get_ddc_aux_inst(link);
psr_context->transmitterId = link->link_enc->transmitter;
psr_context->engineId = link->link_enc->preferred_engine;
@ -1025,11 +1022,7 @@ bool edp_setup_freesync_replay(struct dc_link *link, const struct dc_stream_stat
if (!dp_pr_get_panel_inst(dc, link, &panel_inst))
return false;
if (dc->config.dp_connector_no_native_i2c && link->no_ddc_pin) {
replay_context.aux_inst = (enum channel_id) link->aux_hw_inst;
} else {
replay_context.aux_inst = link->ddc->ddc_pin->hw_info.ddc_channel;
}
replay_context.aux_inst = link_get_ddc_aux_inst(link);
replay_context.digbe_inst = link->link_enc->transmitter;
replay_context.digfe_inst = link->link_enc->preferred_engine;

View File

@ -483,12 +483,7 @@ bool mod_power_notify_mode_change(struct mod_power *mod_power,
link = dc_stream_get_link(stream);
if (link != NULL && dc_get_edp_link_panel_inst(dc, link, &panel_inst)) {
if (link->ctx->dc->config.dp_connector_no_native_i2c && link->no_ddc_pin) {
aux_inst = (uint8_t)link->aux_hw_inst;
} else {
ASSERT(link->ddc->ddc_pin->hw_info.ddc_channel <= 0xFF);
aux_inst = (uint8_t)link->ddc->ddc_pin->hw_info.ddc_channel;
}
aux_inst = link->dc->link_srv->get_ddc_aux_inst(link);
mod_power_update_backlight_on_mode_change(core_power, link, panel_inst, aux_inst, is_hdr);

View File

@ -849,12 +849,7 @@ bool mod_power_set_backlight_nits(struct mod_power *mod_power,
core_power = MOD_POWER_TO_CORE(mod_power);
link = dc_stream_get_link(stream);
if (link->ctx->dc->config.dp_connector_no_native_i2c && link->no_ddc_pin) {
aux_inst = (uint8_t)link->aux_hw_inst;
} else {
ASSERT(link->ddc->ddc_pin->hw_info.ddc_channel <= 0xFF);
aux_inst = (uint8_t)link->ddc->ddc_pin->hw_info.ddc_channel;
}
aux_inst = link->dc->link_srv->get_ddc_aux_inst(link);
if (!dc_get_edp_link_panel_inst(core_power->dc, stream->link, &panel_inst))
return false;
@ -941,12 +936,7 @@ bool mod_power_set_backlight_percent(struct mod_power *mod_power,
core_power = MOD_POWER_TO_CORE(mod_power);
link = dc_stream_get_link(stream);
if (link->ctx->dc->config.dp_connector_no_native_i2c && link->no_ddc_pin) {
aux_inst = (uint8_t)link->aux_hw_inst;
} else {
ASSERT(link->ddc->ddc_pin->hw_info.ddc_channel <= 0xFF);
aux_inst = (uint8_t)link->ddc->ddc_pin->hw_info.ddc_channel;
}
aux_inst = link->dc->link_srv->get_ddc_aux_inst(link);
if (!dc_get_edp_link_panel_inst(core_power->dc, stream->link, &panel_inst))
return false;