diff mbox series

[v8,15/17] drm/amd/display: Recalculate VCPI slots for new DSC connectors

Message ID 20191203143530.27262-16-mikita.lipski@amd.com (mailing list archive)
State New, archived
Headers show
Series DSC MST support for DRM and AMDGPU | expand

Commit Message

Lipski, Mikita Dec. 3, 2019, 2:35 p.m. UTC
From: Mikita Lipski <mikita.lipski@amd.com>

[why]
Since for DSC MST connector's PBN is claculated differently
due to compression, we have to recalculate both PBN and
VCPI slots for that connector.

[how]
The function iterates through all the active streams to
find, which have DSC enabled, then recalculates PBN for
it and calls drm_dp_helper_update_vcpi_slots_for_dsc to
update connector's VCPI slots.

v2: - use drm_dp_mst_atomic_enable_dsc per port to
enable/disable DSC

v3: - Iterate through connector states from the state passed
    - On each connector state get stream from dc_state,
instead CRTC state

Cc: Jerry Zuo <Jerry.Zuo@amd.com>
Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Lyude Paul <lyude@redhat.com>
Cc: Manasi Navare <manasi.d.navare@intel.com>
Signed-off-by: Mikita Lipski <mikita.lipski@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 76 +++++++++++++++++--
 1 file changed, 71 insertions(+), 5 deletions(-)

Comments

Lyude Paul Dec. 7, 2019, 12:52 a.m. UTC | #1
Reviewed-by: Lyude Paul <lyude@redhat.com>

On Tue, 2019-12-03 at 09:35 -0500, mikita.lipski@amd.com wrote:
> From: Mikita Lipski <mikita.lipski@amd.com>
> 
> [why]
> Since for DSC MST connector's PBN is claculated differently
> due to compression, we have to recalculate both PBN and
> VCPI slots for that connector.
> 
> [how]
> The function iterates through all the active streams to
> find, which have DSC enabled, then recalculates PBN for
> it and calls drm_dp_helper_update_vcpi_slots_for_dsc to
> update connector's VCPI slots.
> 
> v2: - use drm_dp_mst_atomic_enable_dsc per port to
> enable/disable DSC
> 
> v3: - Iterate through connector states from the state passed
>     - On each connector state get stream from dc_state,
> instead CRTC state
> 
> Cc: Jerry Zuo <Jerry.Zuo@amd.com>
> Cc: Harry Wentland <harry.wentland@amd.com>
> Cc: Lyude Paul <lyude@redhat.com>
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> Signed-off-by: Mikita Lipski <mikita.lipski@amd.com>
> ---
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 76 +++++++++++++++++--
>  1 file changed, 71 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 93a230d956ee..2ac3a2f0b452 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -4986,6 +4986,69 @@ const struct drm_encoder_helper_funcs
> amdgpu_dm_encoder_helper_funcs = {
>  	.atomic_check = dm_encoder_helper_atomic_check
>  };
>  
> +static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
> +					    struct dc_state *dc_state)
> +{
> +	struct dc_stream_state *stream = NULL;
> +	struct drm_connector *connector;
> +	struct drm_connector_state *new_con_state, *old_con_state;
> +	struct amdgpu_dm_connector *aconnector;
> +	struct dm_connector_state *dm_conn_state;
> +	int i, j, clock, bpp;
> +	int vcpi, pbn_div, pbn = 0;
> +
> +	for_each_oldnew_connector_in_state(state, connector, old_con_state,
> new_con_state, i) {
> +
> +		aconnector = to_amdgpu_dm_connector(connector);
> +
> +		if (!aconnector->port)
> +			continue;
> +
> +		if (!new_con_state || !new_con_state->crtc)
> +			continue;
> +
> +		dm_conn_state = to_dm_connector_state(new_con_state);
> +
> +		for (j = 0; j < dc_state->stream_count; j++) {
> +			stream = dc_state->streams[j];
> +			if (!stream)
> +				continue;
> +
> +			if ((struct amdgpu_dm_connector*)stream-
> >dm_stream_context == aconnector)
> +				break;
> +
> +			stream = NULL;
> +		}
> +
> +		if (!stream)
> +			continue;
> +
> +		if (stream->timing.flags.DSC != 1) {
> +			drm_dp_mst_atomic_enable_dsc(state,
> +						     aconnector->port,
> +						     dm_conn_state->pbn,
> +						     0,
> +						     false);
> +			continue;
> +		}
> +
> +		pbn_div = dm_mst_get_pbn_divider(stream->link);
> +		bpp = stream->timing.dsc_cfg.bits_per_pixel;
> +		clock = stream->timing.pix_clk_100hz / 10;
> +		pbn = drm_dp_calc_pbn_mode(clock, bpp, true);
> +		vcpi = drm_dp_mst_atomic_enable_dsc(state,
> +						    aconnector->port,
> +						    pbn, pbn_div,
> +						    true);
> +		if (vcpi < 0)
> +			return vcpi;
> +
> +		dm_conn_state->pbn = pbn;
> +		dm_conn_state->vcpi_slots = vcpi;
> +	}
> +	return 0;
> +}
> +
>  static void dm_drm_plane_reset(struct drm_plane *plane)
>  {
>  	struct dm_plane_state *amdgpu_state = NULL;
> @@ -8022,11 +8085,6 @@ static int amdgpu_dm_atomic_check(struct drm_device
> *dev,
>  	if (ret)
>  		goto fail;
>  
> -	/* Perform validation of MST topology in the state*/
> -	ret = drm_dp_mst_atomic_check(state);
> -	if (ret)
> -		goto fail;
> -
>  	if (state->legacy_cursor_update) {
>  		/*
>  		 * This is a fast cursor update coming from the plane update
> @@ -8098,6 +8156,10 @@ static int amdgpu_dm_atomic_check(struct drm_device
> *dev,
>  		if (!compute_mst_dsc_configs_for_state(state, dm_state-
> >context))
>  			goto fail;
>  
> +		ret = dm_update_mst_vcpi_slots_for_dsc(state, dm_state-
> >context);
> +		if (ret)
> +			goto fail;
> +
>  		if (dc_validate_global_state(dc, dm_state->context, false) !=
> DC_OK) {
>  			ret = -EINVAL;
>  			goto fail;
> @@ -8126,6 +8188,10 @@ static int amdgpu_dm_atomic_check(struct drm_device
> *dev,
>  				dc_retain_state(old_dm_state->context);
>  		}
>  	}
> +	/* Perform validation of MST topology in the state*/
> +	ret = drm_dp_mst_atomic_check(state);
> +	if (ret)
> +		goto fail;
>  
>  	/* Store the overall update type for use later in atomic check. */
>  	for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) {
diff mbox series

Patch

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 93a230d956ee..2ac3a2f0b452 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4986,6 +4986,69 @@  const struct drm_encoder_helper_funcs amdgpu_dm_encoder_helper_funcs = {
 	.atomic_check = dm_encoder_helper_atomic_check
 };
 
+static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
+					    struct dc_state *dc_state)
+{
+	struct dc_stream_state *stream = NULL;
+	struct drm_connector *connector;
+	struct drm_connector_state *new_con_state, *old_con_state;
+	struct amdgpu_dm_connector *aconnector;
+	struct dm_connector_state *dm_conn_state;
+	int i, j, clock, bpp;
+	int vcpi, pbn_div, pbn = 0;
+
+	for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
+
+		aconnector = to_amdgpu_dm_connector(connector);
+
+		if (!aconnector->port)
+			continue;
+
+		if (!new_con_state || !new_con_state->crtc)
+			continue;
+
+		dm_conn_state = to_dm_connector_state(new_con_state);
+
+		for (j = 0; j < dc_state->stream_count; j++) {
+			stream = dc_state->streams[j];
+			if (!stream)
+				continue;
+
+			if ((struct amdgpu_dm_connector*)stream->dm_stream_context == aconnector)
+				break;
+
+			stream = NULL;
+		}
+
+		if (!stream)
+			continue;
+
+		if (stream->timing.flags.DSC != 1) {
+			drm_dp_mst_atomic_enable_dsc(state,
+						     aconnector->port,
+						     dm_conn_state->pbn,
+						     0,
+						     false);
+			continue;
+		}
+
+		pbn_div = dm_mst_get_pbn_divider(stream->link);
+		bpp = stream->timing.dsc_cfg.bits_per_pixel;
+		clock = stream->timing.pix_clk_100hz / 10;
+		pbn = drm_dp_calc_pbn_mode(clock, bpp, true);
+		vcpi = drm_dp_mst_atomic_enable_dsc(state,
+						    aconnector->port,
+						    pbn, pbn_div,
+						    true);
+		if (vcpi < 0)
+			return vcpi;
+
+		dm_conn_state->pbn = pbn;
+		dm_conn_state->vcpi_slots = vcpi;
+	}
+	return 0;
+}
+
 static void dm_drm_plane_reset(struct drm_plane *plane)
 {
 	struct dm_plane_state *amdgpu_state = NULL;
@@ -8022,11 +8085,6 @@  static int amdgpu_dm_atomic_check(struct drm_device *dev,
 	if (ret)
 		goto fail;
 
-	/* Perform validation of MST topology in the state*/
-	ret = drm_dp_mst_atomic_check(state);
-	if (ret)
-		goto fail;
-
 	if (state->legacy_cursor_update) {
 		/*
 		 * This is a fast cursor update coming from the plane update
@@ -8098,6 +8156,10 @@  static int amdgpu_dm_atomic_check(struct drm_device *dev,
 		if (!compute_mst_dsc_configs_for_state(state, dm_state->context))
 			goto fail;
 
+		ret = dm_update_mst_vcpi_slots_for_dsc(state, dm_state->context);
+		if (ret)
+			goto fail;
+
 		if (dc_validate_global_state(dc, dm_state->context, false) != DC_OK) {
 			ret = -EINVAL;
 			goto fail;
@@ -8126,6 +8188,10 @@  static int amdgpu_dm_atomic_check(struct drm_device *dev,
 				dc_retain_state(old_dm_state->context);
 		}
 	}
+	/* Perform validation of MST topology in the state*/
+	ret = drm_dp_mst_atomic_check(state);
+	if (ret)
+		goto fail;
 
 	/* Store the overall update type for use later in atomic check. */
 	for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) {