Re: [PATCH 01/13] drm/amd/display: Add MST atomic routines

2019-10-31 Thread Mikita Lipski

On 31.10.2019 9:16, Kazlauskas, Nicholas wrote:
> On 2019-10-30 3:24 p.m., mikita.lip...@amd.com wrote:
>> From: Mikita Lipski 
>>
>> - Adding encoder atomic check to find vcpi slots for a connector
>> - Using DRM helper functions to calculate PBN
>> - Adding connector atomic check to release vcpi slots if connector
>> loses CRTC
>> - Calculate  PBN and VCPI slots only once during atomic
>> check and store them on crtc_state to eliminate
>> redundant calculation
>> - Call drm_dp_mst_atomic_check to verify validity of MST topology
>> during state atomic check
>>
>> v2: squashed previous 3 separate patches, removed DSC PBN calculation,
>> and added PBN and VCPI slots properties to amdgpu connector
>>
>> v3:
>> - moved vcpi_slots and pbn properties to dm_crtc_state and dc_stream_state
>> - updates stream's vcpi_slots and pbn on commit
>> - separated patch from the DSC MST series
>>
>> v4:
>> - set vcpi_slots and pbn properties to dm_connector_state
>> - copy porperties from connector state on to crtc state
>>
>> v5:
>> - keep the pbn and vcpi values only on connnector state
>> - added a void pointer to the stream state instead on two ints,
>> because dc_stream_state is OS agnostic. Pointer points to the
>> current dm_connector_state.
>>
>> v6:
>> - Remove new param from stream
>>
>> v7:
>> - Fix error with using max capable bpc
>>
>> Cc: Jun Lei 
>> Cc: Jerry Zuo 
>> Cc: Harry Wentland 
>> Cc: Nicholas Kazlauskas 
>> Cc: Lyude Paul 
>> Signed-off-by: Mikita Lipski 
> Reviewed-by: Nicholas Kazlauskas 
>
> You might want to verify that this still works as you expect when
> changing "max bpc" on an MST display.
>
> My understanding is that it'd still force a new modeset before encoder
> atomic check is called so you *should* have the correct bpc value during
> MST calculations.

Thanks.

It does still works with MST even if you change the mode to the lower 
resolution.

The encoder atomic check is called during drm_atomic_helper_check_modeset
so new modeset is already forced then.

>> ---
>>.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 65 ++-
>>.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 +
>>.../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 51 ---
>>.../display/amdgpu_dm/amdgpu_dm_mst_types.c   | 32 +
>>4 files changed, 109 insertions(+), 41 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 48f5b43e2698..d75726013436 100644
>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> @@ -4180,7 +4180,8 @@ void amdgpu_dm_connector_funcs_reset(struct 
>> drm_connector *connector)
>>  state->underscan_hborder = 0;
>>  state->underscan_vborder = 0;
>>  state->base.max_requested_bpc = 8;
>> -
>> +state->vcpi_slots = 0;
>> +state->pbn = 0;
>>  if (connector->connector_type == DRM_MODE_CONNECTOR_eDP)
>>  state->abm_level = amdgpu_dm_abm_level;
>>
>> @@ -4209,7 +4210,8 @@ amdgpu_dm_connector_atomic_duplicate_state(struct 
>> drm_connector *connector)
>>  new_state->underscan_enable = state->underscan_enable;
>>  new_state->underscan_hborder = state->underscan_hborder;
>>  new_state->underscan_vborder = state->underscan_vborder;
>> -
>> +new_state->vcpi_slots = state->vcpi_slots;
>> +new_state->pbn = state->pbn;
>>  return &new_state->base;
>>}
>>
>> @@ -4606,10 +4608,64 @@ static void dm_encoder_helper_disable(struct 
>> drm_encoder *encoder)
>>
>>}
>>
>> +static int convert_dc_color_depth_into_bpc (enum dc_color_depth 
>> display_color_depth)
>> +{
>> +switch (display_color_depth) {
>> +case COLOR_DEPTH_666:
>> +return 6;
>> +case COLOR_DEPTH_888:
>> +return 8;
>> +case COLOR_DEPTH_101010:
>> +return 10;
>> +case COLOR_DEPTH_121212:
>> +return 12;
>> +case COLOR_DEPTH_141414:
>> +return 14;
>> +case COLOR_DEPTH_161616:
>> +return 16;
>> +default:
>> +break;
>> +}
>> +return 0;
>> +}
>> +
>>static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder,
>>struct drm_crtc_state *crtc_state,
>>struct drm_connector_state 
>> *conn_state)
>>{
>> +struct drm_atomic_state *state = crtc_state->state;
>> +struct drm_connector *connector = conn_state->connector;
>> +struct amdgpu_dm_connector *aconnector = 
>> to_amdgpu_dm_connector(connector);
>> +struct dm_connector_state *dm_new_connector_state = 
>> to_dm_connector_state(conn_state);
>> +const struct drm_display_mode *adjusted_mode = 
>> &crtc_state->adjusted_mode;
>> 

Re: [PATCH 01/13] drm/amd/display: Add MST atomic routines

2019-10-31 Thread Kazlauskas, Nicholas
On 2019-10-30 3:24 p.m., mikita.lip...@amd.com wrote:
> From: Mikita Lipski 
> 
> - Adding encoder atomic check to find vcpi slots for a connector
> - Using DRM helper functions to calculate PBN
> - Adding connector atomic check to release vcpi slots if connector
> loses CRTC
> - Calculate  PBN and VCPI slots only once during atomic
> check and store them on crtc_state to eliminate
> redundant calculation
> - Call drm_dp_mst_atomic_check to verify validity of MST topology
> during state atomic check
> 
> v2: squashed previous 3 separate patches, removed DSC PBN calculation,
> and added PBN and VCPI slots properties to amdgpu connector
> 
> v3:
> - moved vcpi_slots and pbn properties to dm_crtc_state and dc_stream_state
> - updates stream's vcpi_slots and pbn on commit
> - separated patch from the DSC MST series
> 
> v4:
> - set vcpi_slots and pbn properties to dm_connector_state
> - copy porperties from connector state on to crtc state
> 
> v5:
> - keep the pbn and vcpi values only on connnector state
> - added a void pointer to the stream state instead on two ints,
> because dc_stream_state is OS agnostic. Pointer points to the
> current dm_connector_state.
> 
> v6:
> - Remove new param from stream
> 
> v7:
> - Fix error with using max capable bpc
> 
> Cc: Jun Lei 
> Cc: Jerry Zuo 
> Cc: Harry Wentland 
> Cc: Nicholas Kazlauskas 
> Cc: Lyude Paul 
> Signed-off-by: Mikita Lipski 

Reviewed-by: Nicholas Kazlauskas 

You might want to verify that this still works as you expect when 
changing "max bpc" on an MST display.

My understanding is that it'd still force a new modeset before encoder 
atomic check is called so you *should* have the correct bpc value during 
MST calculations.

> ---
>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 65 ++-
>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 +
>   .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 51 ---
>   .../display/amdgpu_dm/amdgpu_dm_mst_types.c   | 32 +
>   4 files changed, 109 insertions(+), 41 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 48f5b43e2698..d75726013436 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -4180,7 +4180,8 @@ void amdgpu_dm_connector_funcs_reset(struct 
> drm_connector *connector)
>   state->underscan_hborder = 0;
>   state->underscan_vborder = 0;
>   state->base.max_requested_bpc = 8;
> -
> + state->vcpi_slots = 0;
> + state->pbn = 0;
>   if (connector->connector_type == DRM_MODE_CONNECTOR_eDP)
>   state->abm_level = amdgpu_dm_abm_level;
>   
> @@ -4209,7 +4210,8 @@ amdgpu_dm_connector_atomic_duplicate_state(struct 
> drm_connector *connector)
>   new_state->underscan_enable = state->underscan_enable;
>   new_state->underscan_hborder = state->underscan_hborder;
>   new_state->underscan_vborder = state->underscan_vborder;
> -
> + new_state->vcpi_slots = state->vcpi_slots;
> + new_state->pbn = state->pbn;
>   return &new_state->base;
>   }
>   
> @@ -4606,10 +4608,64 @@ static void dm_encoder_helper_disable(struct 
> drm_encoder *encoder)
>   
>   }
>   
> +static int convert_dc_color_depth_into_bpc (enum dc_color_depth 
> display_color_depth)
> +{
> + switch (display_color_depth) {
> + case COLOR_DEPTH_666:
> + return 6;
> + case COLOR_DEPTH_888:
> + return 8;
> + case COLOR_DEPTH_101010:
> + return 10;
> + case COLOR_DEPTH_121212:
> + return 12;
> + case COLOR_DEPTH_141414:
> + return 14;
> + case COLOR_DEPTH_161616:
> + return 16;
> + default:
> + break;
> + }
> + return 0;
> +}
> +
>   static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder,
> struct drm_crtc_state *crtc_state,
> struct drm_connector_state 
> *conn_state)
>   {
> + struct drm_atomic_state *state = crtc_state->state;
> + struct drm_connector *connector = conn_state->connector;
> + struct amdgpu_dm_connector *aconnector = 
> to_amdgpu_dm_connector(connector);
> + struct dm_connector_state *dm_new_connector_state = 
> to_dm_connector_state(conn_state);
> + const struct drm_display_mode *adjusted_mode = 
> &crtc_state->adjusted_mode;
> + struct drm_dp_mst_topology_mgr *mst_mgr;
> + struct drm_dp_mst_port *mst_port;
> + enum dc_color_depth color_depth;
> + int clock, bpp = 0;
> +
> + if (!aconnector->port || !aconnector->dc_sink)
> + return 0;
> +
> + mst_port = aconnector->port;
> + mst_mgr = &aconnector->mst_port->mst_mgr;
> +
> + if (!c

[PATCH 01/13] drm/amd/display: Add MST atomic routines

2019-10-30 Thread mikita.lipski
From: Mikita Lipski 

- Adding encoder atomic check to find vcpi slots for a connector
- Using DRM helper functions to calculate PBN
- Adding connector atomic check to release vcpi slots if connector
loses CRTC
- Calculate  PBN and VCPI slots only once during atomic
check and store them on crtc_state to eliminate
redundant calculation
- Call drm_dp_mst_atomic_check to verify validity of MST topology
during state atomic check

v2: squashed previous 3 separate patches, removed DSC PBN calculation,
and added PBN and VCPI slots properties to amdgpu connector

v3:
- moved vcpi_slots and pbn properties to dm_crtc_state and dc_stream_state
- updates stream's vcpi_slots and pbn on commit
- separated patch from the DSC MST series

v4:
- set vcpi_slots and pbn properties to dm_connector_state
- copy porperties from connector state on to crtc state

v5:
- keep the pbn and vcpi values only on connnector state
- added a void pointer to the stream state instead on two ints,
because dc_stream_state is OS agnostic. Pointer points to the
current dm_connector_state.

v6:
- Remove new param from stream

v7:
- Fix error with using max capable bpc

Cc: Jun Lei 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Nicholas Kazlauskas 
Cc: Lyude Paul 
Signed-off-by: Mikita Lipski 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 65 ++-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 +
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 51 ---
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   | 32 +
 4 files changed, 109 insertions(+), 41 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 48f5b43e2698..d75726013436 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4180,7 +4180,8 @@ void amdgpu_dm_connector_funcs_reset(struct drm_connector 
*connector)
state->underscan_hborder = 0;
state->underscan_vborder = 0;
state->base.max_requested_bpc = 8;
-
+   state->vcpi_slots = 0;
+   state->pbn = 0;
if (connector->connector_type == DRM_MODE_CONNECTOR_eDP)
state->abm_level = amdgpu_dm_abm_level;
 
@@ -4209,7 +4210,8 @@ amdgpu_dm_connector_atomic_duplicate_state(struct 
drm_connector *connector)
new_state->underscan_enable = state->underscan_enable;
new_state->underscan_hborder = state->underscan_hborder;
new_state->underscan_vborder = state->underscan_vborder;
-
+   new_state->vcpi_slots = state->vcpi_slots;
+   new_state->pbn = state->pbn;
return &new_state->base;
 }
 
@@ -4606,10 +4608,64 @@ static void dm_encoder_helper_disable(struct 
drm_encoder *encoder)
 
 }
 
+static int convert_dc_color_depth_into_bpc (enum dc_color_depth 
display_color_depth)
+{
+   switch (display_color_depth) {
+   case COLOR_DEPTH_666:
+   return 6;
+   case COLOR_DEPTH_888:
+   return 8;
+   case COLOR_DEPTH_101010:
+   return 10;
+   case COLOR_DEPTH_121212:
+   return 12;
+   case COLOR_DEPTH_141414:
+   return 14;
+   case COLOR_DEPTH_161616:
+   return 16;
+   default:
+   break;
+   }
+   return 0;
+}
+
 static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder,
  struct drm_crtc_state *crtc_state,
  struct drm_connector_state 
*conn_state)
 {
+   struct drm_atomic_state *state = crtc_state->state;
+   struct drm_connector *connector = conn_state->connector;
+   struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
+   struct dm_connector_state *dm_new_connector_state = 
to_dm_connector_state(conn_state);
+   const struct drm_display_mode *adjusted_mode = 
&crtc_state->adjusted_mode;
+   struct drm_dp_mst_topology_mgr *mst_mgr;
+   struct drm_dp_mst_port *mst_port;
+   enum dc_color_depth color_depth;
+   int clock, bpp = 0;
+
+   if (!aconnector->port || !aconnector->dc_sink)
+   return 0;
+
+   mst_port = aconnector->port;
+   mst_mgr = &aconnector->mst_port->mst_mgr;
+
+   if (!crtc_state->connectors_changed && !crtc_state->mode_changed)
+   return 0;
+
+   if (!state->duplicated) {
+   color_depth = convert_color_depth_from_display_info(connector, 
conn_state);
+   bpp = convert_dc_color_depth_into_bpc(color_depth) * 3;
+   clock = adjusted_mode->clock;
+   dm_new_connector_state->pbn = drm_dp_calc_pbn_mode(clock, bpp);
+   }
+   dm_new_connector_state->vcpi_slots = 
drm_dp_atomic_find_vcpi_slots(state,
+   

[PATCH 01/13] drm/amd/display: Add MST atomic routines

2019-10-29 Thread mikita.lipski
From: Mikita Lipski 

- Adding encoder atomic check to find vcpi slots for a connector
- Using DRM helper functions to calculate PBN
- Adding connector atomic check to release vcpi slots if connector
loses CRTC
- Calculate  PBN and VCPI slots only once during atomic
check and store them on crtc_state to eliminate
redundant calculation
- Call drm_dp_mst_atomic_check to verify validity of MST topology
during state atomic check

v2: squashed previous 3 separate patches, removed DSC PBN calculation,
and added PBN and VCPI slots properties to amdgpu connector

v3:
- moved vcpi_slots and pbn properties to dm_crtc_state and dc_stream_state
- updates stream's vcpi_slots and pbn on commit
- separated patch from the DSC MST series

v4:
- set vcpi_slots and pbn properties to dm_connector_state
- copy porperties from connector state on to crtc state

v5:
- keep the pbn and vcpi values only on connnector state
- added a void pointer to the stream state instead on two ints,
because dc_stream_state is OS agnostic. Pointer points to the
current dm_connector_state.

v6:
- Remove new param from stream

Cc: Jun Lei 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Nicholas Kazlauskas 
Cc: Lyude Paul 
Signed-off-by: Mikita Lipski 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 42 ++-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 +
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 51 +--
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   | 32 
 4 files changed, 86 insertions(+), 41 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 48f5b43e2698..28f6b93ab371 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4180,7 +4180,8 @@ void amdgpu_dm_connector_funcs_reset(struct drm_connector 
*connector)
state->underscan_hborder = 0;
state->underscan_vborder = 0;
state->base.max_requested_bpc = 8;
-
+   state->vcpi_slots = 0;
+   state->pbn = 0;
if (connector->connector_type == DRM_MODE_CONNECTOR_eDP)
state->abm_level = amdgpu_dm_abm_level;
 
@@ -4209,7 +4210,8 @@ amdgpu_dm_connector_atomic_duplicate_state(struct 
drm_connector *connector)
new_state->underscan_enable = state->underscan_enable;
new_state->underscan_hborder = state->underscan_hborder;
new_state->underscan_vborder = state->underscan_vborder;
-
+   new_state->vcpi_slots = state->vcpi_slots;
+   new_state->pbn = state->pbn;
return &new_state->base;
 }
 
@@ -4610,6 +4612,37 @@ static int dm_encoder_helper_atomic_check(struct 
drm_encoder *encoder,
  struct drm_crtc_state *crtc_state,
  struct drm_connector_state 
*conn_state)
 {
+   struct drm_atomic_state *state = crtc_state->state;
+   struct drm_connector *connector = conn_state->connector;
+   struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
+   struct dm_connector_state *dm_new_connector_state = 
to_dm_connector_state(conn_state);
+   const struct drm_display_mode *adjusted_mode = 
&crtc_state->adjusted_mode;
+   struct drm_dp_mst_topology_mgr *mst_mgr;
+   struct drm_dp_mst_port *mst_port;
+   int clock, bpp = 0;
+
+   if (!aconnector->port || !aconnector->dc_sink)
+   return 0;
+
+   mst_port = aconnector->port;
+   mst_mgr = &aconnector->mst_port->mst_mgr;
+
+   if (!crtc_state->connectors_changed && !crtc_state->mode_changed)
+   return 0;
+
+   if (!state->duplicated) {
+   bpp = (uint8_t)connector->display_info.bpc * 3;
+   clock = adjusted_mode->clock;
+   dm_new_connector_state->pbn = drm_dp_calc_pbn_mode(clock, bpp);
+   }
+   dm_new_connector_state->vcpi_slots = 
drm_dp_atomic_find_vcpi_slots(state,
+  mst_mgr,
+  mst_port,
+  
dm_new_connector_state->pbn);
+   if (dm_new_connector_state->vcpi_slots < 0) {
+   DRM_DEBUG_ATOMIC("failed finding vcpi slots: %d\n", 
dm_new_connector_state->vcpi_slots);
+   return dm_new_connector_state->vcpi_slots;
+   }
return 0;
 }
 
@@ -7651,6 +7684,11 @@ 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
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp