Commit ec0ca697 authored by David Francis's avatar David Francis Committed by Alex Deucher

drm/amd/display: Validate DSC caps on MST endpoints

During MST mode enumeration, if a new dc_sink is created,
populate it with dsc caps as appropriate.

Use drm_dp_mst_dsc_aux_for_port to get the raw caps,
then parse them onto dc_sink with dc_dsc_parse_dsc_dpcd.
Reviewed-by: default avatarWenjing Liu <Wenjing.Liu@amd.com>
Signed-off-by: default avatarDavid Francis <David.Francis@amd.com>
Signed-off-by: default avatarMikita Lipski <mikita.lipski@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent b6adc57c
...@@ -330,6 +330,7 @@ struct amdgpu_dm_connector { ...@@ -330,6 +330,7 @@ struct amdgpu_dm_connector {
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 amdgpu_encoder *mst_encoder;
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 */
struct amdgpu_i2c_adapter *i2c; struct amdgpu_i2c_adapter *i2c;
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/version.h> #include <linux/version.h>
#include <drm/drm_atomic_helper.h> #include <drm/drm_atomic_helper.h>
#include <drm/drm_dp_mst_helper.h>
#include "dm_services.h" #include "dm_services.h"
#include "amdgpu.h" #include "amdgpu.h"
#include "amdgpu_dm.h" #include "amdgpu_dm.h"
...@@ -180,6 +181,28 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = { ...@@ -180,6 +181,28 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = {
.early_unregister = amdgpu_dm_mst_connector_early_unregister, .early_unregister = amdgpu_dm_mst_connector_early_unregister,
}; };
static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnector)
{
struct dc_sink *dc_sink = aconnector->dc_sink;
struct drm_dp_mst_port *port = aconnector->port;
u8 dsc_caps[16] = { 0 };
aconnector->dsc_aux = drm_dp_mst_dsc_aux_for_port(port);
if (!aconnector->dsc_aux)
return false;
if (drm_dp_dpcd_read(aconnector->dsc_aux, DP_DSC_SUPPORT, dsc_caps, 16) < 0)
return false;
if (!dc_dsc_parse_dsc_dpcd(aconnector->dc_link->ctx->dc,
dsc_caps, NULL,
&dc_sink->sink_dsc_caps.dsc_dec_caps))
return false;
return true;
}
static int dm_dp_mst_get_modes(struct drm_connector *connector) static int dm_dp_mst_get_modes(struct drm_connector *connector)
{ {
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
...@@ -222,10 +245,14 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector) ...@@ -222,10 +245,14 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
/* dc_link_add_remote_sink returns a new reference */ /* dc_link_add_remote_sink returns a new reference */
aconnector->dc_sink = dc_sink; aconnector->dc_sink = dc_sink;
if (aconnector->dc_sink) if (aconnector->dc_sink) {
amdgpu_dm_update_freesync_caps( amdgpu_dm_update_freesync_caps(
connector, aconnector->edid); connector, aconnector->edid);
if (!validate_dsc_caps_on_connector(aconnector))
memset(&aconnector->dc_sink->sink_dsc_caps,
0, sizeof(aconnector->dc_sink->sink_dsc_caps));
}
} }
drm_connector_update_edid_property( drm_connector_update_edid_property(
......
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