[PATCH 02/30] drm/amd/display: Update link encoder object creation.
Timo Aaltonen
tjaalton at ubuntu.com
Mon Nov 22 18:06:02 UTC 2021
From: Jimmy Kizito <Jimmy.Kizito at amd.com>
BugLink: https://bugs.launchpad.net/bugs/1951868
[Why & How]
USB4 endpoints are dynamically mapped. We create additional link
encoders for USB4 use when DC is created and destroy them when DC
is destructed
Reviewed-by: Jun Lei <Jun.Lei at amd.com>
Acked-by: Wayne Lin <Wayne.Lin at amd.com>
Acked-by: Nicholas Kazlauskas <nicholas.kazlauskas at amd.com>
Acked-by: Harry Wentland <harry.wentland at amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito at amd.com>
Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
(backported from commit eabf2019b7e5bf8216e373a74e08f13ca6b6c550 -- fix conflict in resource.h)
Signed-off-by: Timo Aaltonen <timo.aaltonen at canonical.com>
---
drivers/gpu/drm/amd/display/dc/core/dc.c | 77 +++++++++++++++++++
.../gpu/drm/amd/display/dc/inc/core_types.h | 2 +
drivers/gpu/drm/amd/display/dc/inc/resource.h | 1 +
3 files changed, 80 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index c798c65d4276..6379be3bd729 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -276,6 +276,75 @@ static bool create_links(
return false;
}
+/* Create additional DIG link encoder objects if fewer than the platform
+ * supports were created during link construction. This can happen if the
+ * number of physical connectors is less than the number of DIGs.
+ */
+static bool create_link_encoders(struct dc *dc)
+{
+ bool res = true;
+ unsigned int num_usb4_dpia = dc->res_pool->res_cap->num_usb4_dpia;
+ unsigned int num_dig_link_enc = dc->res_pool->res_cap->num_dig_link_enc;
+ int i;
+
+ /* A platform without USB4 DPIA endpoints has a fixed mapping between DIG
+ * link encoders and physical display endpoints and does not require
+ * additional link encoder objects.
+ */
+ if (num_usb4_dpia == 0)
+ return res;
+
+ /* Create as many link encoder objects as the platform supports. DPIA
+ * endpoints can be programmably mapped to any DIG.
+ */
+ if (num_dig_link_enc > dc->res_pool->dig_link_enc_count) {
+ for (i = 0; i < num_dig_link_enc; i++) {
+ struct link_encoder *link_enc = dc->res_pool->link_encoders[i];
+
+ if (!link_enc && dc->res_pool->funcs->link_enc_create_minimal) {
+ link_enc = dc->res_pool->funcs->link_enc_create_minimal(dc->ctx,
+ (enum engine_id)(ENGINE_ID_DIGA + i));
+ if (link_enc) {
+ dc->res_pool->link_encoders[i] = link_enc;
+ dc->res_pool->dig_link_enc_count++;
+ } else {
+ res = false;
+ }
+ }
+ }
+ }
+
+ return res;
+}
+
+/* Destroy any additional DIG link encoder objects created by
+ * create_link_encoders().
+ * NB: Must only be called after destroy_links().
+ */
+static void destroy_link_encoders(struct dc *dc)
+{
+ unsigned int num_usb4_dpia = dc->res_pool->res_cap->num_usb4_dpia;
+ unsigned int num_dig_link_enc = dc->res_pool->res_cap->num_dig_link_enc;
+ int i;
+
+ /* A platform without USB4 DPIA endpoints has a fixed mapping between DIG
+ * link encoders and physical display endpoints and does not require
+ * additional link encoder objects.
+ */
+ if (num_usb4_dpia == 0)
+ return;
+
+ for (i = 0; i < num_dig_link_enc; i++) {
+ struct link_encoder *link_enc = dc->res_pool->link_encoders[i];
+
+ if (link_enc) {
+ link_enc->funcs->destroy(&link_enc);
+ dc->res_pool->link_encoders[i] = NULL;
+ dc->res_pool->dig_link_enc_count--;
+ }
+ }
+}
+
static struct dc_perf_trace *dc_perf_trace_create(void)
{
return kzalloc(sizeof(struct dc_perf_trace), GFP_KERNEL);
@@ -709,6 +778,8 @@ static void dc_destruct(struct dc *dc)
destroy_links(dc);
+ destroy_link_encoders(dc);
+
if (dc->clk_mgr) {
dc_destroy_clk_mgr(dc->clk_mgr);
dc->clk_mgr = NULL;
@@ -913,6 +984,12 @@ static bool dc_construct(struct dc *dc,
if (!create_links(dc, init_params->num_virtual_links))
goto fail;
+ /* Create additional DIG link encoder objects if fewer than the platform
+ * supports were created during link construction.
+ */
+ if (!create_link_encoders(dc))
+ goto fail;
+
/* Initialise DIG link encoder resource tracking variables. */
link_enc_cfg_init(dc, dc->current_state);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
index 45a6216dfa2a..f90d78e557a3 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -245,6 +245,8 @@ struct resource_pool {
* entries in link_encoders array.
*/
unsigned int dig_link_enc_count;
+ /* Number of USB4 DPIA (DisplayPort Input Adapter) link objects created.*/
+ unsigned int usb4_dpia_count;
#if defined(CONFIG_DRM_AMD_DC_DCN)
struct dc_3dlut *mpc_lut[MAX_PIPES];
diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h
index fe1e5833c96a..453973d1ce50 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/resource.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h
@@ -49,6 +49,7 @@ struct resource_caps {
int num_vmid;
int num_dsc;
unsigned int num_dig_link_enc; // Total number of DIGs (digital encoders) in DIO (Display Input/Output).
+ unsigned int num_usb4_dpia; // Total number of USB4 DPIA (DisplayPort Input Adapters).
int num_mpc_3dlut;
};
--
2.32.0
More information about the kernel-team
mailing list