Commit 9fa0fb77 authored by Meenakshikumar Somasundaram's avatar Meenakshikumar Somasundaram Committed by Alex Deucher

drm/amd/display: USB4 DPIA enumeration and AUX Tunneling

[WHY]
To enable dc links for USB4 DPIA ports and AUX command tunneling
for YELLOW_CARP_B0.

[HOW]
1) Created dc links for all USB4 DPIA ports in create_links().
   dc_link_construct() implementation is split for legacy DDC and DPIAs.
   As usb4 has no ddc, ddc->ddc_pin will be set to NULL for its dc link
   and this parameter will be used to identify the dc links as DPIA. The
   dc link for DPIA is further to be enhanced with implementation for link
   encoder and link initialization.
2) usb4_dpia_count in struct resource_pool will be initialized to 4 in
   dcn31_resource_construct() if the DCN is YELLOW_CARP_B0.
3) Enabled DMUB AUX via outbox for YELLOW_CARP_B0.
Reviewed-by: default avatarJimmy Kizito <Jimmy.Kizito@amd.com>
Acked-by: default avatarWayne Lin <Wayne.Lin@amd.com>
Acked-by: default avatarNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Acked-by: default avatarHarry Wentland <harry.wentland@amd.com>
Signed-off-by: default avatarMeenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent eabf2019
...@@ -231,6 +231,25 @@ static bool create_links( ...@@ -231,6 +231,25 @@ static bool create_links(
DC_LOG_DC("BIOS object table - end"); DC_LOG_DC("BIOS object table - end");
/* Create a link for each usb4 dpia port */
for (i = 0; i < dc->res_pool->usb4_dpia_count; i++) {
struct link_init_data link_init_params = {0};
struct dc_link *link;
link_init_params.ctx = dc->ctx;
link_init_params.connector_index = i;
link_init_params.link_index = dc->link_count;
link_init_params.dc = dc;
link_init_params.is_dpia_link = true;
link = link_create(&link_init_params);
if (link) {
dc->links[dc->link_count] = link;
link->dc = dc;
++dc->link_count;
}
}
for (i = 0; i < num_virtual_links; i++) { for (i = 0; i < num_virtual_links; i++) {
struct dc_link *link = kzalloc(sizeof(*link), GFP_KERNEL); struct dc_link *link = kzalloc(sizeof(*link), GFP_KERNEL);
struct encoder_init_data enc_init = {0}; struct encoder_init_data enc_init = {0};
...@@ -3557,6 +3576,12 @@ void dc_hardware_release(struct dc *dc) ...@@ -3557,6 +3576,12 @@ void dc_hardware_release(struct dc *dc)
*/ */
bool dc_enable_dmub_notifications(struct dc *dc) bool dc_enable_dmub_notifications(struct dc *dc)
{ {
#if defined(CONFIG_DRM_AMD_DC_DCN)
/* YELLOW_CARP B0 USB4 DPIA needs dmub notifications for interrupts */
if (dc->ctx->asic_id.chip_family == FAMILY_YELLOW_CARP &&
dc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0)
return true;
#endif
/* dmub aux needs dmub notifications to be enabled */ /* dmub aux needs dmub notifications to be enabled */
return dc->debug.enable_dmub_aux_for_legacy_ddc; return dc->debug.enable_dmub_aux_for_legacy_ddc;
} }
...@@ -3582,7 +3607,12 @@ bool dc_process_dmub_aux_transfer_async(struct dc *dc, ...@@ -3582,7 +3607,12 @@ bool dc_process_dmub_aux_transfer_async(struct dc *dc,
cmd.dp_aux_access.header.type = DMUB_CMD__DP_AUX_ACCESS; cmd.dp_aux_access.header.type = DMUB_CMD__DP_AUX_ACCESS;
cmd.dp_aux_access.header.payload_bytes = 0; cmd.dp_aux_access.header.payload_bytes = 0;
cmd.dp_aux_access.aux_control.type = AUX_CHANNEL_LEGACY_DDC; /* For dpia, ddc_pin is set to NULL */
if (!dc->links[link_index]->ddc->ddc_pin)
cmd.dp_aux_access.aux_control.type = AUX_CHANNEL_DPIA;
else
cmd.dp_aux_access.aux_control.type = AUX_CHANNEL_LEGACY_DDC;
cmd.dp_aux_access.aux_control.instance = dc->links[link_index]->ddc_hw_inst; cmd.dp_aux_access.aux_control.instance = dc->links[link_index]->ddc_hw_inst;
cmd.dp_aux_access.aux_control.sw_crc_enabled = 0; cmd.dp_aux_access.aux_control.sw_crc_enabled = 0;
cmd.dp_aux_access.aux_control.timeout = 0; cmd.dp_aux_access.aux_control.timeout = 0;
......
...@@ -1425,8 +1425,8 @@ static enum transmitter translate_encoder_to_transmitter(struct graphics_object_ ...@@ -1425,8 +1425,8 @@ static enum transmitter translate_encoder_to_transmitter(struct graphics_object_
} }
} }
static bool dc_link_construct(struct dc_link *link, static bool dc_link_construct_legacy(struct dc_link *link,
const struct link_init_data *init_params) const struct link_init_data *init_params)
{ {
uint8_t i; uint8_t i;
struct ddc_service_init_data ddc_service_init_data = { { 0 } }; struct ddc_service_init_data ddc_service_init_data = { { 0 } };
...@@ -1701,6 +1701,73 @@ static bool dc_link_construct(struct dc_link *link, ...@@ -1701,6 +1701,73 @@ static bool dc_link_construct(struct dc_link *link,
return false; return false;
} }
static bool dc_link_construct_dpia(struct dc_link *link,
const struct link_init_data *init_params)
{
struct ddc_service_init_data ddc_service_init_data = { { 0 } };
struct dc_context *dc_ctx = init_params->ctx;
DC_LOGGER_INIT(dc_ctx->logger);
/* Initialized dummy hpd and hpd rx */
link->irq_source_hpd = DC_IRQ_SOURCE_USB4_DMUB_HPD;
link->irq_source_hpd_rx = DC_IRQ_SOURCE_USB4_DMUB_HPDRX;
link->link_status.dpcd_caps = &link->dpcd_caps;
link->dc = init_params->dc;
link->ctx = dc_ctx;
link->link_index = init_params->link_index;
memset(&link->preferred_training_settings, 0,
sizeof(struct dc_link_training_overrides));
memset(&link->preferred_link_setting, 0,
sizeof(struct dc_link_settings));
/* Dummy Init for linkid */
link->link_id.type = OBJECT_TYPE_CONNECTOR;
link->link_id.id = CONNECTOR_ID_DISPLAY_PORT;
link->is_internal_display = false;
link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
LINK_INFO("Connector[%d] description:signal %d\n",
init_params->connector_index,
link->connector_signal);
/* TODO: Initialize link : funcs->link_init */
ddc_service_init_data.ctx = link->ctx;
ddc_service_init_data.id = link->link_id;
ddc_service_init_data.link = link;
/* Set indicator for dpia link so that ddc won't be created */
ddc_service_init_data.is_dpia_link = true;
link->ddc = dal_ddc_service_create(&ddc_service_init_data);
if (!link->ddc) {
DC_ERROR("Failed to create ddc_service!\n");
goto ddc_create_fail;
}
/* Set dpia port index : 0 to number of dpia ports */
link->ddc_hw_inst = init_params->connector_index;
/* TODO: Create link encoder */
link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
return true;
ddc_create_fail:
return false;
}
static bool dc_link_construct(struct dc_link *link,
const struct link_init_data *init_params)
{
/* Handle dpia case */
if (init_params->is_dpia_link)
return dc_link_construct_dpia(link, init_params);
else
return dc_link_construct_legacy(link, init_params);
}
/******************************************************************************* /*******************************************************************************
* Public functions * Public functions
******************************************************************************/ ******************************************************************************/
......
...@@ -196,7 +196,8 @@ static void ddc_service_construct( ...@@ -196,7 +196,8 @@ static void ddc_service_construct(
ddc_service->link = init_data->link; ddc_service->link = init_data->link;
ddc_service->ctx = init_data->ctx; ddc_service->ctx = init_data->ctx;
if (BP_RESULT_OK != dcb->funcs->get_i2c_info(dcb, init_data->id, &i2c_info)) { if (init_data->is_dpia_link ||
dcb->funcs->get_i2c_info(dcb, init_data->id, &i2c_info) != BP_RESULT_OK) {
ddc_service->ddc_pin = NULL; ddc_service->ddc_pin = NULL;
} else { } else {
DC_LOGGER_INIT(ddc_service->ctx->logger); DC_LOGGER_INIT(ddc_service->ctx->logger);
......
...@@ -174,6 +174,10 @@ void dcn31_init_hw(struct dc *dc) ...@@ -174,6 +174,10 @@ void dcn31_init_hw(struct dc *dc)
if (hws->funcs.dsc_pg_control != NULL) if (hws->funcs.dsc_pg_control != NULL)
hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false); hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
/* Enables outbox notifications for usb4 dpia */
if (dc->res_pool->usb4_dpia_count)
dmub_enable_outbox_notification(dc);
/* we want to turn off all dp displays before doing detection */ /* we want to turn off all dp displays before doing detection */
if (dc->config.power_down_display_on_boot) if (dc->config.power_down_display_on_boot)
blank_all_dp_displays(dc, true); blank_all_dp_displays(dc, true);
...@@ -278,8 +282,10 @@ void dcn31_init_hw(struct dc *dc) ...@@ -278,8 +282,10 @@ void dcn31_init_hw(struct dc *dc)
if (dc->res_pool->hubbub->funcs->force_pstate_change_control) if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
dc->res_pool->hubbub->funcs->force_pstate_change_control( dc->res_pool->hubbub->funcs->force_pstate_change_control(
dc->res_pool->hubbub, false, false); dc->res_pool->hubbub, false, false);
#if defined(CONFIG_DRM_AMD_DC_DCN)
if (dc->res_pool->hubbub->funcs->init_crb) if (dc->res_pool->hubbub->funcs->init_crb)
dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub); dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub);
#endif
} }
void dcn31_dsc_pg_control( void dcn31_dsc_pg_control(
......
...@@ -2427,6 +2427,12 @@ static bool dcn31_resource_construct( ...@@ -2427,6 +2427,12 @@ static bool dcn31_resource_construct(
pool->base.sw_i2cs[i] = NULL; pool->base.sw_i2cs[i] = NULL;
} }
if (dc->ctx->asic_id.chip_family == FAMILY_YELLOW_CARP &&
dc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) {
/* YELLOW CARP B0 has 4 DPIA's */
pool->base.usb4_dpia_count = 4;
}
/* Audio, Stream Encoders including HPO and virtual, MPC 3D LUTs */ /* Audio, Stream Encoders including HPO and virtual, MPC 3D LUTs */
if (!resource_construct(num_virtual_links, dc, &pool->base, if (!resource_construct(num_virtual_links, dc, &pool->base,
(!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ? (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ?
......
...@@ -62,6 +62,7 @@ struct link_init_data { ...@@ -62,6 +62,7 @@ struct link_init_data {
uint32_t connector_index; /* this will be mapped to the HPD pins */ uint32_t connector_index; /* this will be mapped to the HPD pins */
uint32_t link_index; /* this is mapped to DAL display_index uint32_t link_index; /* this is mapped to DAL display_index
TODO: remove it when DC is complete. */ TODO: remove it when DC is complete. */
bool is_dpia_link;
}; };
struct dc_link *link_create(const struct link_init_data *init_params); struct dc_link *link_create(const struct link_init_data *init_params);
......
...@@ -69,6 +69,7 @@ struct ddc_service_init_data { ...@@ -69,6 +69,7 @@ struct ddc_service_init_data {
struct graphics_object_id id; struct graphics_object_id id;
struct dc_context *ctx; struct dc_context *ctx;
struct dc_link *link; struct dc_link *link;
bool is_dpia_link;
}; };
struct ddc_service *dal_ddc_service_create( struct ddc_service *dal_ddc_service_create(
......
...@@ -153,7 +153,10 @@ enum dc_irq_source { ...@@ -153,7 +153,10 @@ enum dc_irq_source {
DC_IRQ_SOURCE_DMCUB_OUTBOX, DC_IRQ_SOURCE_DMCUB_OUTBOX,
DC_IRQ_SOURCE_DMCUB_OUTBOX0, DC_IRQ_SOURCE_DMCUB_OUTBOX0,
DC_IRQ_SOURCE_DMCUB_GENERAL_DATAOUT, DC_IRQ_SOURCE_DMCUB_GENERAL_DATAOUT,
DAL_IRQ_SOURCES_NUMBER DAL_IRQ_SOURCES_NUMBER,
/* Dummy interrupt source for USB4 HPD & HPD RX */
DC_IRQ_SOURCE_USB4_DMUB_HPD,
DC_IRQ_SOURCE_USB4_DMUB_HPDRX,
}; };
enum irq_type enum irq_type
......
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