@@ -915,10 +915,9 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
915915 return 0 ;
916916}
917917
918- static int dpu_plane_is_multirect_parallel_capable (struct dpu_hw_sspp * sspp ,
919- struct dpu_sw_pipe_cfg * pipe_cfg ,
920- const struct msm_format * fmt ,
921- uint32_t max_linewidth )
918+ static int dpu_plane_is_multirect_capable (struct dpu_hw_sspp * sspp ,
919+ struct dpu_sw_pipe_cfg * pipe_cfg ,
920+ const struct msm_format * fmt )
922921{
923922 if (drm_rect_width (& pipe_cfg -> src_rect ) != drm_rect_width (& pipe_cfg -> dst_rect ) ||
924923 drm_rect_height (& pipe_cfg -> src_rect ) != drm_rect_height (& pipe_cfg -> dst_rect ))
@@ -930,17 +929,34 @@ static int dpu_plane_is_multirect_parallel_capable(struct dpu_hw_sspp *sspp,
930929 if (MSM_FORMAT_IS_YUV (fmt ))
931930 return false;
932931
933- if (MSM_FORMAT_IS_UBWC (fmt ) &&
934- drm_rect_width (& pipe_cfg -> src_rect ) > max_linewidth / 2 )
935- return false;
936-
937932 if (!test_bit (DPU_SSPP_SMART_DMA_V1 , & sspp -> cap -> features ) &&
938933 !test_bit (DPU_SSPP_SMART_DMA_V2 , & sspp -> cap -> features ))
939934 return false;
940935
941936 return true;
942937}
943938
939+ static int dpu_plane_is_parallel_capable (struct dpu_sw_pipe_cfg * pipe_cfg ,
940+ const struct msm_format * fmt ,
941+ uint32_t max_linewidth )
942+ {
943+ if (MSM_FORMAT_IS_UBWC (fmt ) &&
944+ drm_rect_width (& pipe_cfg -> src_rect ) > max_linewidth / 2 )
945+ return false;
946+
947+ return true;
948+ }
949+
950+ static int dpu_plane_is_multirect_parallel_capable (struct dpu_hw_sspp * sspp ,
951+ struct dpu_sw_pipe_cfg * pipe_cfg ,
952+ const struct msm_format * fmt ,
953+ uint32_t max_linewidth )
954+ {
955+ return dpu_plane_is_multirect_capable (sspp , pipe_cfg , fmt ) &&
956+ dpu_plane_is_parallel_capable (pipe_cfg , fmt , max_linewidth );
957+ }
958+
959+
944960static int dpu_plane_atomic_check_sspp (struct drm_plane * plane ,
945961 struct drm_atomic_state * state ,
946962 const struct drm_crtc_state * crtc_state )
@@ -1002,6 +1018,69 @@ static bool dpu_plane_try_multirect_parallel(struct dpu_sw_pipe *pipe, struct dp
10021018 return true;
10031019}
10041020
1021+ static int dpu_plane_try_multirect_shared (struct dpu_plane_state * pstate ,
1022+ struct dpu_plane_state * prev_adjacent_pstate ,
1023+ const struct msm_format * fmt ,
1024+ uint32_t max_linewidth )
1025+ {
1026+ struct dpu_sw_pipe * pipe = & pstate -> pipe ;
1027+ struct dpu_sw_pipe * r_pipe = & pstate -> r_pipe ;
1028+ struct dpu_sw_pipe_cfg * pipe_cfg = & pstate -> pipe_cfg ;
1029+ struct dpu_sw_pipe * prev_pipe = & prev_adjacent_pstate -> pipe ;
1030+ struct dpu_sw_pipe_cfg * prev_pipe_cfg = & prev_adjacent_pstate -> pipe_cfg ;
1031+ const struct msm_format * prev_fmt = msm_framebuffer_format (prev_adjacent_pstate -> base .fb );
1032+ u16 max_tile_height = 1 ;
1033+
1034+ if (prev_adjacent_pstate -> r_pipe .sspp != NULL ||
1035+ prev_pipe -> multirect_mode != DPU_SSPP_MULTIRECT_NONE )
1036+ return false;
1037+
1038+ if (!dpu_plane_is_multirect_capable (pipe -> sspp , pipe_cfg , fmt ) ||
1039+ !dpu_plane_is_multirect_capable (prev_pipe -> sspp , prev_pipe_cfg , prev_fmt ))
1040+ return false;
1041+
1042+ if (MSM_FORMAT_IS_UBWC (fmt ))
1043+ max_tile_height = max (max_tile_height , fmt -> tile_height );
1044+
1045+ if (MSM_FORMAT_IS_UBWC (prev_fmt ))
1046+ max_tile_height = max (max_tile_height , prev_fmt -> tile_height );
1047+
1048+ r_pipe -> multirect_index = DPU_SSPP_RECT_SOLO ;
1049+ r_pipe -> multirect_mode = DPU_SSPP_MULTIRECT_NONE ;
1050+
1051+ r_pipe -> sspp = NULL ;
1052+
1053+ if (dpu_plane_is_parallel_capable (pipe_cfg , fmt , max_linewidth ) &&
1054+ dpu_plane_is_parallel_capable (prev_pipe_cfg , prev_fmt , max_linewidth ) &&
1055+ (pipe_cfg -> dst_rect .x1 >= prev_pipe_cfg -> dst_rect .x2 ||
1056+ prev_pipe_cfg -> dst_rect .x1 >= pipe_cfg -> dst_rect .x2 )) {
1057+ pipe -> sspp = prev_pipe -> sspp ;
1058+
1059+ pipe -> multirect_index = DPU_SSPP_RECT_1 ;
1060+ pipe -> multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL ;
1061+
1062+ prev_pipe -> multirect_index = DPU_SSPP_RECT_0 ;
1063+ prev_pipe -> multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL ;
1064+
1065+ return true;
1066+ }
1067+
1068+ if (pipe_cfg -> dst_rect .y1 >= prev_pipe_cfg -> dst_rect .y2 + 2 * max_tile_height ||
1069+ prev_pipe_cfg -> dst_rect .y1 >= pipe_cfg -> dst_rect .y2 + 2 * max_tile_height ) {
1070+ pipe -> sspp = prev_pipe -> sspp ;
1071+
1072+ pipe -> multirect_index = DPU_SSPP_RECT_1 ;
1073+ pipe -> multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX ;
1074+
1075+ prev_pipe -> multirect_index = DPU_SSPP_RECT_0 ;
1076+ prev_pipe -> multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX ;
1077+
1078+ return true;
1079+ }
1080+
1081+ return false;
1082+ }
1083+
10051084static int dpu_plane_atomic_check (struct drm_plane * plane ,
10061085 struct drm_atomic_state * state )
10071086{
@@ -1102,13 +1181,14 @@ static int dpu_plane_virtual_atomic_check(struct drm_plane *plane,
11021181static int dpu_plane_virtual_assign_resources (struct drm_crtc * crtc ,
11031182 struct dpu_global_state * global_state ,
11041183 struct drm_atomic_state * state ,
1105- struct drm_plane_state * plane_state )
1184+ struct drm_plane_state * plane_state ,
1185+ struct drm_plane_state * prev_adjacent_plane_state )
11061186{
11071187 const struct drm_crtc_state * crtc_state = NULL ;
11081188 struct drm_plane * plane = plane_state -> plane ;
11091189 struct dpu_kms * dpu_kms = _dpu_plane_get_kms (plane );
11101190 struct dpu_rm_sspp_requirements reqs ;
1111- struct dpu_plane_state * pstate ;
1191+ struct dpu_plane_state * pstate , * prev_adjacent_pstate ;
11121192 struct dpu_sw_pipe * pipe ;
11131193 struct dpu_sw_pipe * r_pipe ;
11141194 struct dpu_sw_pipe_cfg * pipe_cfg ;
@@ -1120,6 +1200,8 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
11201200 plane_state -> crtc );
11211201
11221202 pstate = to_dpu_plane_state (plane_state );
1203+ prev_adjacent_pstate = prev_adjacent_plane_state ?
1204+ to_dpu_plane_state (prev_adjacent_plane_state ) : NULL ;
11231205 pipe = & pstate -> pipe ;
11241206 r_pipe = & pstate -> r_pipe ;
11251207 pipe_cfg = & pstate -> pipe_cfg ;
@@ -1138,24 +1220,42 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
11381220
11391221 reqs .rot90 = drm_rotation_90_or_270 (plane_state -> rotation );
11401222
1141- pipe -> sspp = dpu_rm_reserve_sspp (& dpu_kms -> rm , global_state , crtc , & reqs );
1142- if (!pipe -> sspp )
1143- return - ENODEV ;
1223+ if (drm_rect_width (& r_pipe_cfg -> src_rect ) == 0 ) {
1224+ if (!prev_adjacent_pstate ||
1225+ !dpu_plane_try_multirect_shared (pstate , prev_adjacent_pstate , fmt ,
1226+ dpu_kms -> catalog -> caps -> max_linewidth )) {
1227+ pipe -> sspp = dpu_rm_reserve_sspp (& dpu_kms -> rm , global_state , crtc , & reqs );
1228+ if (!pipe -> sspp )
1229+ return - ENODEV ;
11441230
1145- if (!dpu_plane_try_multirect_parallel (pipe , pipe_cfg , r_pipe , r_pipe_cfg ,
1146- pipe -> sspp ,
1147- msm_framebuffer_format (plane_state -> fb ),
1148- dpu_kms -> catalog -> caps -> max_linewidth )) {
1149- /* multirect is not possible, use two SSPP blocks */
1150- r_pipe -> sspp = dpu_rm_reserve_sspp (& dpu_kms -> rm , global_state , crtc , & reqs );
1151- if (!r_pipe -> sspp )
1231+ r_pipe -> sspp = NULL ;
1232+
1233+ pipe -> multirect_index = DPU_SSPP_RECT_SOLO ;
1234+ pipe -> multirect_mode = DPU_SSPP_MULTIRECT_NONE ;
1235+
1236+ r_pipe -> multirect_index = DPU_SSPP_RECT_SOLO ;
1237+ r_pipe -> multirect_mode = DPU_SSPP_MULTIRECT_NONE ;
1238+ }
1239+ } else {
1240+ pipe -> sspp = dpu_rm_reserve_sspp (& dpu_kms -> rm , global_state , crtc , & reqs );
1241+ if (!pipe -> sspp )
11521242 return - ENODEV ;
11531243
1154- pipe -> multirect_index = DPU_SSPP_RECT_SOLO ;
1155- pipe -> multirect_mode = DPU_SSPP_MULTIRECT_NONE ;
1244+ if (!dpu_plane_try_multirect_parallel (pipe , pipe_cfg , r_pipe , r_pipe_cfg ,
1245+ pipe -> sspp ,
1246+ msm_framebuffer_format (plane_state -> fb ),
1247+ dpu_kms -> catalog -> caps -> max_linewidth )) {
1248+ /* multirect is not possible, use two SSPP blocks */
1249+ r_pipe -> sspp = dpu_rm_reserve_sspp (& dpu_kms -> rm , global_state , crtc , & reqs );
1250+ if (!r_pipe -> sspp )
1251+ return - ENODEV ;
11561252
1157- r_pipe -> multirect_index = DPU_SSPP_RECT_SOLO ;
1158- r_pipe -> multirect_mode = DPU_SSPP_MULTIRECT_NONE ;
1253+ pipe -> multirect_index = DPU_SSPP_RECT_SOLO ;
1254+ pipe -> multirect_mode = DPU_SSPP_MULTIRECT_NONE ;
1255+
1256+ r_pipe -> multirect_index = DPU_SSPP_RECT_SOLO ;
1257+ r_pipe -> multirect_mode = DPU_SSPP_MULTIRECT_NONE ;
1258+ }
11591259 }
11601260
11611261 return dpu_plane_atomic_check_sspp (plane , state , crtc_state );
@@ -1168,6 +1268,7 @@ int dpu_assign_plane_resources(struct dpu_global_state *global_state,
11681268 unsigned int num_planes )
11691269{
11701270 unsigned int i ;
1271+ struct drm_plane_state * prev_adjacent_plane_state = NULL ;
11711272
11721273 for (i = 0 ; i < num_planes ; i ++ ) {
11731274 struct drm_plane_state * plane_state = states [i ];
@@ -1177,9 +1278,12 @@ int dpu_assign_plane_resources(struct dpu_global_state *global_state,
11771278 continue ;
11781279
11791280 int ret = dpu_plane_virtual_assign_resources (crtc , global_state ,
1180- state , plane_state );
1281+ state , plane_state ,
1282+ prev_adjacent_plane_state );
11811283 if (ret )
1182- return ret ;
1284+ break ;
1285+
1286+ prev_adjacent_plane_state = plane_state ;
11831287 }
11841288
11851289 return 0 ;
0 commit comments