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: c6385e503a
("drm/amdgpu: drop legacy drm load and unload callbacks")
Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
4afaa61db9
commit
f74367e492
4 changed files with 48 additions and 28 deletions
|
@ -978,6 +978,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 */
|
||||||
|
@ -1001,6 +1004,12 @@ error:
|
||||||
|
|
||||||
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 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#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"
|
||||||
|
@ -330,6 +333,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 {
|
||||||
|
@ -358,7 +368,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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
|
|
||||||
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 *
|
||||||
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,31 +307,27 @@ 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(
|
||||||
dev,
|
dev,
|
||||||
&amdgpu_encoder->base,
|
&amdgpu_encoder->base,
|
||||||
&amdgpu_dm_encoder_funcs,
|
&amdgpu_dm_encoder_funcs,
|
||||||
DRM_MODE_ENCODER_DPMST,
|
DRM_MODE_ENCODER_DPMST,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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);
|
||||||
|
|
Loading…
Add table
Reference in a new issue