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: Wenjing Liu <Wenjing.Liu@amd.com> Signed-off-by: David Francis <David.Francis@amd.com> Signed-off-by: Mikita Lipski <mikita.lipski@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
b6adc57cff
commit
ec0ca697dd
@ -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 @@
|
|||||||
|
|
||||||
#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 = {
|
|||||||
.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)
|
|||||||
/* 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(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user