Commit 31684701 authored by Alex Deucher's avatar Alex Deucher

drm/amdgpu/display: create fake mst encoders ahead of time (v4)

Prevents a warning in the MST create connector case.

v2: create global fake encoders rather per connector fake encoders
to avoid running out of encoder indices.

v3: use the actual number of crtcs on the asic rather than the max
to conserve encoders.

v4: v3 plus missing hunk I forgot to git add.

Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1108
Fixes: c6385e50 ("drm/amdgpu: drop legacy drm load and unload callbacks")
Reviewed-by: default avatarNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org # 5.7.x
parent d845a205
...@@ -974,6 +974,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) ...@@ -974,6 +974,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
/* Update the actual used number of crtc */ /* Update the actual used number of crtc */
adev->mode_info.num_crtc = adev->dm.display_indexes_num; adev->mode_info.num_crtc = adev->dm.display_indexes_num;
/* create fake encoders for MST */
dm_dp_create_fake_mst_encoders(adev);
/* TODO: Add_display_info? */ /* TODO: Add_display_info? */
/* TODO use dynamic cursor width */ /* TODO use dynamic cursor width */
...@@ -997,6 +1000,12 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) ...@@ -997,6 +1000,12 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
static void amdgpu_dm_fini(struct amdgpu_device *adev) static void amdgpu_dm_fini(struct amdgpu_device *adev)
{ {
int i;
for (i = 0; i < adev->dm.display_indexes_num; i++) {
drm_encoder_cleanup(&adev->dm.mst_encoders[i].base);
}
amdgpu_dm_audio_fini(adev); amdgpu_dm_audio_fini(adev);
amdgpu_dm_destroy_drm_device(&adev->dm); amdgpu_dm_destroy_drm_device(&adev->dm);
......
...@@ -43,6 +43,9 @@ ...@@ -43,6 +43,9 @@
*/ */
#define AMDGPU_DM_MAX_DISPLAY_INDEX 31 #define AMDGPU_DM_MAX_DISPLAY_INDEX 31
#define AMDGPU_DM_MAX_CRTC 6
/* /*
#include "include/amdgpu_dal_power_if.h" #include "include/amdgpu_dal_power_if.h"
#include "amdgpu_dm_irq.h" #include "amdgpu_dm_irq.h"
...@@ -328,6 +331,13 @@ struct amdgpu_display_manager { ...@@ -328,6 +331,13 @@ struct amdgpu_display_manager {
* available in FW * available in FW
*/ */
const struct gpu_info_soc_bounding_box_v1_0 *soc_bounding_box; const struct gpu_info_soc_bounding_box_v1_0 *soc_bounding_box;
/**
* @mst_encoders:
*
* fake encoders used for DP MST.
*/
struct amdgpu_encoder mst_encoders[AMDGPU_DM_MAX_CRTC];
}; };
struct amdgpu_dm_connector { struct amdgpu_dm_connector {
...@@ -356,7 +366,6 @@ struct amdgpu_dm_connector { ...@@ -356,7 +366,6 @@ struct amdgpu_dm_connector {
struct amdgpu_dm_dp_aux dm_dp_aux; struct amdgpu_dm_dp_aux dm_dp_aux;
struct drm_dp_mst_port *port; struct drm_dp_mst_port *port;
struct amdgpu_dm_connector *mst_port; struct amdgpu_dm_connector *mst_port;
struct amdgpu_encoder *mst_encoder;
struct drm_dp_aux *dsc_aux; struct drm_dp_aux *dsc_aux;
/* TODO see if we can merge with ddc_bus or make a dm_connector */ /* TODO see if we can merge with ddc_bus or make a dm_connector */
......
...@@ -95,7 +95,6 @@ dm_dp_mst_connector_destroy(struct drm_connector *connector) ...@@ -95,7 +95,6 @@ dm_dp_mst_connector_destroy(struct drm_connector *connector)
{ {
struct amdgpu_dm_connector *aconnector = struct amdgpu_dm_connector *aconnector =
to_amdgpu_dm_connector(connector); to_amdgpu_dm_connector(connector);
struct amdgpu_encoder *amdgpu_encoder = aconnector->mst_encoder;
if (aconnector->dc_sink) { if (aconnector->dc_sink) {
dc_link_remove_remote_sink(aconnector->dc_link, dc_link_remove_remote_sink(aconnector->dc_link,
...@@ -105,8 +104,6 @@ dm_dp_mst_connector_destroy(struct drm_connector *connector) ...@@ -105,8 +104,6 @@ dm_dp_mst_connector_destroy(struct drm_connector *connector)
kfree(aconnector->edid); kfree(aconnector->edid);
drm_encoder_cleanup(&amdgpu_encoder->base);
kfree(amdgpu_encoder);
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
drm_dp_mst_put_port_malloc(aconnector->port); drm_dp_mst_put_port_malloc(aconnector->port);
kfree(aconnector); kfree(aconnector);
...@@ -243,7 +240,11 @@ static struct drm_encoder * ...@@ -243,7 +240,11 @@ static struct drm_encoder *
dm_mst_atomic_best_encoder(struct drm_connector *connector, dm_mst_atomic_best_encoder(struct drm_connector *connector,
struct drm_connector_state *connector_state) struct drm_connector_state *connector_state)
{ {
return &to_amdgpu_dm_connector(connector)->mst_encoder->base; struct drm_device *dev = connector->dev;
struct amdgpu_device *adev = dev->dev_private;
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(connector_state->crtc);
return &adev->dm.mst_encoders[acrtc->crtc_id].base;
} }
static int static int
...@@ -306,19 +307,16 @@ static const struct drm_encoder_funcs amdgpu_dm_encoder_funcs = { ...@@ -306,19 +307,16 @@ static const struct drm_encoder_funcs amdgpu_dm_encoder_funcs = {
.destroy = amdgpu_dm_encoder_destroy, .destroy = amdgpu_dm_encoder_destroy,
}; };
static struct amdgpu_encoder * void
dm_dp_create_fake_mst_encoder(struct amdgpu_dm_connector *connector) dm_dp_create_fake_mst_encoders(struct amdgpu_device *adev)
{ {
struct drm_device *dev = connector->base.dev; struct drm_device *dev = adev->ddev;
struct amdgpu_device *adev = dev->dev_private; int i;
struct amdgpu_encoder *amdgpu_encoder;
struct drm_encoder *encoder;
amdgpu_encoder = kzalloc(sizeof(*amdgpu_encoder), GFP_KERNEL); for (i = 0; i < adev->dm.display_indexes_num; i++) {
if (!amdgpu_encoder) struct amdgpu_encoder *amdgpu_encoder = &adev->dm.mst_encoders[i];
return NULL; struct drm_encoder *encoder = &amdgpu_encoder->base;
encoder = &amdgpu_encoder->base;
encoder->possible_crtcs = amdgpu_dm_get_encoder_crtc_mask(adev); encoder->possible_crtcs = amdgpu_dm_get_encoder_crtc_mask(adev);
drm_encoder_init( drm_encoder_init(
...@@ -329,8 +327,7 @@ dm_dp_create_fake_mst_encoder(struct amdgpu_dm_connector *connector) ...@@ -329,8 +327,7 @@ dm_dp_create_fake_mst_encoder(struct amdgpu_dm_connector *connector)
NULL); NULL);
drm_encoder_helper_add(encoder, &amdgpu_dm_encoder_helper_funcs); drm_encoder_helper_add(encoder, &amdgpu_dm_encoder_helper_funcs);
}
return amdgpu_encoder;
} }
static struct drm_connector * static struct drm_connector *
...@@ -343,6 +340,7 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, ...@@ -343,6 +340,7 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
struct amdgpu_device *adev = dev->dev_private; struct amdgpu_device *adev = dev->dev_private;
struct amdgpu_dm_connector *aconnector; struct amdgpu_dm_connector *aconnector;
struct drm_connector *connector; struct drm_connector *connector;
int i;
aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL); aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL);
if (!aconnector) if (!aconnector)
...@@ -369,9 +367,10 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, ...@@ -369,9 +367,10 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
master->dc_link, master->dc_link,
master->connector_id); master->connector_id);
aconnector->mst_encoder = dm_dp_create_fake_mst_encoder(master); for (i = 0; i < adev->dm.display_indexes_num; i++) {
drm_connector_attach_encoder(&aconnector->base, drm_connector_attach_encoder(&aconnector->base,
&aconnector->mst_encoder->base); &adev->dm.mst_encoders[i].base);
}
connector->max_bpc_property = master->base.max_bpc_property; connector->max_bpc_property = master->base.max_bpc_property;
if (connector->max_bpc_property) if (connector->max_bpc_property)
......
...@@ -35,6 +35,9 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, ...@@ -35,6 +35,9 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
struct amdgpu_dm_connector *aconnector, struct amdgpu_dm_connector *aconnector,
int link_index); int link_index);
void
dm_dp_create_fake_mst_encoders(struct amdgpu_device *adev);
#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_DC_DCN)
bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
struct dc_state *dc_state); struct dc_state *dc_state);
......
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