@@ -2264,22 +2264,29 @@ static int vop2_plane_init(struct vop2 *vop2, struct vop2_win *win,
22642264 return 0 ;
22652265}
22662266
2267- static struct vop2_video_port * find_vp_without_primary (struct vop2 * vop2 )
2267+ /*
2268+ * On RK3566 these windows don't have an independent
2269+ * framebuffer. They can only share/mirror the framebuffer
2270+ * with smart0, esmart0 and cluster0 respectively.
2271+ * And RK3566 share the same vop version with Rk3568, so we
2272+ * need to use soc_id for identification here.
2273+ */
2274+ static bool vop2_is_mirror_win (struct vop2_win * win )
22682275{
2269- int i ;
2270-
2271- for (i = 0 ; i < vop2 -> data -> nr_vps ; i ++ ) {
2272- struct vop2_video_port * vp = & vop2 -> vps [i ];
2273-
2274- if (!vp -> crtc .port )
2275- continue ;
2276- if (vp -> primary_plane )
2277- continue ;
2276+ struct vop2 * vop2 = win -> vop2 ;
22782277
2279- return vp ;
2278+ if (vop2 -> data -> soc_id == 3566 ) {
2279+ switch (win -> data -> phys_id ) {
2280+ case ROCKCHIP_VOP2_SMART1 :
2281+ case ROCKCHIP_VOP2_ESMART1 :
2282+ case ROCKCHIP_VOP2_CLUSTER1 :
2283+ return true;
2284+ default :
2285+ return false;
2286+ }
2287+ } else {
2288+ return false;
22802289 }
2281-
2282- return NULL ;
22832290}
22842291
22852292static int vop2_create_crtcs (struct vop2 * vop2 )
@@ -2290,7 +2297,9 @@ static int vop2_create_crtcs(struct vop2 *vop2)
22902297 struct drm_plane * plane ;
22912298 struct device_node * port ;
22922299 struct vop2_video_port * vp ;
2293- int i , nvp , nvps = 0 ;
2300+ struct vop2_win * win ;
2301+ u32 possible_crtcs ;
2302+ int i , j , nvp , nvps = 0 ;
22942303 int ret ;
22952304
22962305 for (i = 0 ; i < vop2_data -> nr_vps ; i ++ ) {
@@ -2326,42 +2335,54 @@ static int vop2_create_crtcs(struct vop2 *vop2)
23262335 }
23272336
23282337 nvp = 0 ;
2329- for (i = 0 ; i < vop2 -> registered_num_wins ; i ++ ) {
2330- struct vop2_win * win = & vop2 -> win [i ];
2331- u32 possible_crtcs = 0 ;
2332-
2333- if (vop2 -> data -> soc_id == 3566 ) {
2334- /*
2335- * On RK3566 these windows don't have an independent
2336- * framebuffer. They share the framebuffer with smart0,
2337- * esmart0 and cluster0 respectively.
2338- */
2339- switch (win -> data -> phys_id ) {
2340- case ROCKCHIP_VOP2_SMART1 :
2341- case ROCKCHIP_VOP2_ESMART1 :
2342- case ROCKCHIP_VOP2_CLUSTER1 :
2338+ /* Register a primary plane for every crtc */
2339+ for (i = 0 ; i < vop2_data -> nr_vps ; i ++ ) {
2340+ vp = & vop2 -> vps [i ];
2341+
2342+ if (!vp -> crtc .port )
2343+ continue ;
2344+
2345+ for (j = 0 ; j < vop2 -> registered_num_wins ; j ++ ) {
2346+ win = & vop2 -> win [j ];
2347+
2348+ /* Aready registered as primary plane */
2349+ if (win -> base .type == DRM_PLANE_TYPE_PRIMARY )
2350+ continue ;
2351+
2352+ if (vop2_is_mirror_win (win ))
23432353 continue ;
2344- }
2345- }
23462354
2347- if (win -> type == DRM_PLANE_TYPE_PRIMARY ) {
2348- vp = find_vp_without_primary (vop2 );
2349- if (vp ) {
2355+ if (win -> type == DRM_PLANE_TYPE_PRIMARY ) {
23502356 possible_crtcs = BIT (nvp );
23512357 vp -> primary_plane = win ;
2358+ ret = vop2_plane_init (vop2 , win , possible_crtcs );
2359+ if (ret )
2360+ return dev_err_probe (drm -> dev , ret ,
2361+ "failed to init primary plane %s\n" ,
2362+ win -> data -> name );
23522363 nvp ++ ;
2353- } else {
2354- /* change the unused primary window to overlay window */
2355- win -> type = DRM_PLANE_TYPE_OVERLAY ;
2364+ break ;
23562365 }
23572366 }
2367+ }
2368+
2369+ /* Register all unused window as overlay plane */
2370+ for (i = 0 ; i < vop2 -> registered_num_wins ; i ++ ) {
2371+ win = & vop2 -> win [i ];
2372+
2373+ /* Aready registered as primary plane */
2374+ if (win -> base .type == DRM_PLANE_TYPE_PRIMARY )
2375+ continue ;
2376+
2377+ if (vop2_is_mirror_win (win ))
2378+ continue ;
23582379
2359- if (win -> type == DRM_PLANE_TYPE_OVERLAY )
2360- possible_crtcs = (1 << nvps ) - 1 ;
2380+ win -> type = DRM_PLANE_TYPE_OVERLAY ;
23612381
2382+ possible_crtcs = (1 << nvps ) - 1 ;
23622383 ret = vop2_plane_init (vop2 , win , possible_crtcs );
23632384 if (ret )
2364- return dev_err_probe (drm -> dev , ret , "failed to init plane %s\n" ,
2385+ return dev_err_probe (drm -> dev , ret , "failed to init overlay plane %s\n" ,
23652386 win -> data -> name );
23662387 }
23672388
0 commit comments