@@ -1293,7 +1293,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
12931293 u32 v_subsample = fb -> format -> vsub ;
12941294 bool mix_plane_alpha ;
12951295 bool covers_screen ;
1296- u32 scl0 , scl1 , pitch0 ;
1296+ u32 scl0 , scl1 , pitch [ 2 ] ;
12971297 u32 tiling , src_x , src_y ;
12981298 u32 width , height ;
12991299 u32 hvs_format = format -> hvs ;
@@ -1347,7 +1347,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
13471347 switch (base_format_mod ) {
13481348 case DRM_FORMAT_MOD_LINEAR :
13491349 tiling = SCALER_CTL0_TILING_LINEAR ;
1350- pitch0 = VC4_SET_FIELD (fb -> pitches [0 ], SCALER_SRC_PITCH );
1350+ pitch [ 0 ] = VC4_SET_FIELD (fb -> pitches [0 ], SCALER_SRC_PITCH );
13511351
13521352 /* Adjust the base pointer to the first pixel to be scanned
13531353 * out.
@@ -1399,23 +1399,23 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
13991399 */
14001400 if (rotation & DRM_MODE_REFLECT_Y ) {
14011401 y_off = tile_h_mask - y_off ;
1402- pitch0 = SCALER_PITCH0_TILE_LINE_DIR ;
1402+ pitch [ 0 ] = SCALER_PITCH0_TILE_LINE_DIR ;
14031403 } else {
1404- pitch0 = 0 ;
1404+ pitch [ 0 ] = 0 ;
14051405 }
14061406
14071407 tiling = SCALER_CTL0_TILING_256B_OR_T ;
1408- pitch0 |= (VC4_SET_FIELD (x_off , SCALER_PITCH0_SINK_PIX ) |
1409- VC4_SET_FIELD (y_off , SCALER_PITCH0_TILE_Y_OFFSET ) |
1410- VC4_SET_FIELD (tiles_l , SCALER_PITCH0_TILE_WIDTH_L ) |
1411- VC4_SET_FIELD (tiles_r , SCALER_PITCH0_TILE_WIDTH_R ));
1408+ pitch [ 0 ] |= (VC4_SET_FIELD (x_off , SCALER_PITCH0_SINK_PIX ) |
1409+ VC4_SET_FIELD (y_off , SCALER_PITCH0_TILE_Y_OFFSET ) |
1410+ VC4_SET_FIELD (tiles_l , SCALER_PITCH0_TILE_WIDTH_L ) |
1411+ VC4_SET_FIELD (tiles_r , SCALER_PITCH0_TILE_WIDTH_R ));
14121412 offsets [0 ] += tiles_t * (tiles_w << tile_size_shift );
14131413 offsets [0 ] += subtile_y << 8 ;
14141414 offsets [0 ] += utile_y << 4 ;
14151415
14161416 /* Rows of tiles alternate left-to-right and right-to-left. */
14171417 if (tiles_t & 1 ) {
1418- pitch0 |= SCALER_PITCH0_TILE_INITIAL_LINE_DIR ;
1418+ pitch [ 0 ] |= SCALER_PITCH0_TILE_INITIAL_LINE_DIR ;
14191419 offsets [0 ] += (tiles_w - tiles_l ) << tile_size_shift ;
14201420 offsets [0 ] -= (1 + !tile_y ) << 10 ;
14211421 } else {
@@ -1430,6 +1430,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
14301430 case DRM_FORMAT_MOD_BROADCOM_SAND128 :
14311431 case DRM_FORMAT_MOD_BROADCOM_SAND256 : {
14321432 uint32_t param = fourcc_mod_broadcom_param (fb -> modifier );
1433+ unsigned int tile_width = 0 ;
14331434
14341435 if (param > SCALER_TILE_HEIGHT_MASK ) {
14351436 DRM_DEBUG_KMS ("SAND height too large (%d)\n" ,
@@ -1440,18 +1441,22 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
14401441 if (fb -> format -> format == DRM_FORMAT_P030 ) {
14411442 hvs_format = HVS_PIXEL_FORMAT_YCBCR_10BIT ;
14421443 tiling = SCALER_CTL0_TILING_128B ;
1444+ tile_width = 128 ;
14431445 } else {
14441446 hvs_format = HVS_PIXEL_FORMAT_H264 ;
14451447
14461448 switch (base_format_mod ) {
14471449 case DRM_FORMAT_MOD_BROADCOM_SAND64 :
14481450 tiling = SCALER_CTL0_TILING_64B ;
1451+ tile_width = 64 ;
14491452 break ;
14501453 case DRM_FORMAT_MOD_BROADCOM_SAND128 :
14511454 tiling = SCALER_CTL0_TILING_128B ;
1455+ tile_width = 128 ;
14521456 break ;
14531457 case DRM_FORMAT_MOD_BROADCOM_SAND256 :
14541458 tiling = SCALER_CTL0_TILING_256B_OR_T ;
1459+ tile_width = 256 ;
14551460 break ;
14561461 default :
14571462 return - EINVAL ;
@@ -1469,7 +1474,21 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
14691474 * should be 6.
14701475 */
14711476 for (i = 0 ; i < num_planes ; i ++ ) {
1472- u32 tile_w , tile , x_off , pix_per_tile ;
1477+ u32 tile , x_off , pix_per_tile ;
1478+
1479+ switch (param ) {
1480+ case 0 :
1481+ /* Compute column stride from buffer size and
1482+ * padded width
1483+ */
1484+ pitch [i ] = drm_format_info_plane_height (fb -> format ,
1485+ fb -> height ,
1486+ i );
1487+ break ;
1488+ default :
1489+ pitch [i ] = VC4_SET_FIELD (param , SCALER_TILE_HEIGHT );
1490+ break ;
1491+ }
14731492
14741493 if (fb -> format -> format == DRM_FORMAT_P030 ) {
14751494 /*
@@ -1485,36 +1504,20 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
14851504 u32 last_bits = remaining_pixels % 12 ;
14861505
14871506 x_off = aligned * 16 + last_bits ;
1488- tile_w = 128 ;
14891507 pix_per_tile = 96 ;
14901508 } else {
1491- switch (base_format_mod ) {
1492- case DRM_FORMAT_MOD_BROADCOM_SAND64 :
1493- tile_w = 64 ;
1494- break ;
1495- case DRM_FORMAT_MOD_BROADCOM_SAND128 :
1496- tile_w = 128 ;
1497- break ;
1498- case DRM_FORMAT_MOD_BROADCOM_SAND256 :
1499- tile_w = 256 ;
1500- break ;
1501- default :
1502- return - EINVAL ;
1503- }
1504- pix_per_tile = tile_w / fb -> format -> cpp [0 ];
1509+ pix_per_tile = tile_width / fb -> format -> cpp [0 ];
15051510 x_off = (src_x % pix_per_tile ) /
15061511 (i ? h_subsample : 1 ) *
15071512 fb -> format -> cpp [i ];
15081513 }
15091514
15101515 tile = src_x / pix_per_tile ;
15111516
1512- offsets [i ] += param * tile_w * tile ;
1513- offsets [i ] += src_y / (i ? v_subsample : 1 ) * tile_w ;
1517+ offsets [i ] += pitch [ i ] * tile ;
1518+ offsets [i ] += src_y / (i ? v_subsample : 1 ) * tile_width ;
15141519 offsets [i ] += x_off & ~(i ? 1 : 0 );
15151520 }
1516-
1517- pitch0 = VC4_SET_FIELD (param , SCALER_TILE_HEIGHT );
15181521 break ;
15191522 }
15201523
@@ -1669,7 +1672,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
16691672 vc4_dlist_write (vc4_state , 0xc0c0c0c0 );
16701673
16711674 /* Pitch word 0 */
1672- vc4_dlist_write (vc4_state , pitch0 );
1675+ vc4_dlist_write (vc4_state , pitch [ 0 ] );
16731676
16741677 /* Pitch word 1/2 */
16751678 for (i = 1 ; i < num_planes ; i ++ ) {
@@ -1679,7 +1682,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
16791682 VC4_SET_FIELD (fb -> pitches [i ],
16801683 SCALER_SRC_PITCH ));
16811684 } else {
1682- vc4_dlist_write (vc4_state , pitch0 );
1685+ vc4_dlist_write (vc4_state , pitch [ 1 ] );
16831686 }
16841687 }
16851688
@@ -1834,7 +1837,7 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
18341837 u32 v_subsample = fb -> format -> vsub ;
18351838 bool mix_plane_alpha ;
18361839 bool covers_screen ;
1837- u32 scl0 , scl1 , pitch0 ;
1840+ u32 scl0 , scl1 , pitch [ 2 ] ;
18381841 u32 tiling , src_x , src_y ;
18391842 u32 width , height ;
18401843 u32 hvs_format = format -> hvs ;
@@ -1904,6 +1907,7 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
19041907 case DRM_FORMAT_MOD_BROADCOM_SAND128 :
19051908 case DRM_FORMAT_MOD_BROADCOM_SAND256 : {
19061909 uint32_t param = fourcc_mod_broadcom_param (fb -> modifier );
1910+ unsigned int tile_width = 0 ;
19071911 u32 components_per_word ;
19081912 u32 starting_offset ;
19091913 u32 fetch_count ;
@@ -1917,21 +1921,29 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
19171921 if (fb -> format -> format == DRM_FORMAT_P030 ) {
19181922 hvs_format = HVS_PIXEL_FORMAT_YCBCR_10BIT ;
19191923 tiling = SCALER6_CTL0_ADDR_MODE_128B ;
1924+ tile_width = 128 ;
19201925 } else {
19211926 hvs_format = HVS_PIXEL_FORMAT_YCBCR_YUV420_2PLANE ;
19221927
19231928 switch (base_format_mod ) {
19241929 case DRM_FORMAT_MOD_BROADCOM_SAND128 :
19251930 tiling = SCALER6_CTL0_ADDR_MODE_128B ;
1931+ tile_width = 128 ;
19261932 break ;
19271933 case DRM_FORMAT_MOD_BROADCOM_SAND256 :
19281934 tiling = SCALER6_CTL0_ADDR_MODE_256B ;
1935+ tile_width = 256 ;
19291936 break ;
19301937 default :
19311938 return - EINVAL ;
19321939 }
19331940 }
19341941
1942+ components_per_word = fb -> format -> format == DRM_FORMAT_P030 ? 24 : 32 ;
1943+ starting_offset = src_x % components_per_word ;
1944+ fetch_count = (width + starting_offset + components_per_word - 1 ) /
1945+ components_per_word ;
1946+
19351947 /* Adjust the base pointer to the first pixel to be scanned
19361948 * out.
19371949 *
@@ -1943,7 +1955,21 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
19431955 * should be 6.
19441956 */
19451957 for (i = 0 ; i < num_planes ; i ++ ) {
1946- u32 tile_w , tile , x_off , pix_per_tile ;
1958+ u32 tile , x_off , pix_per_tile ;
1959+
1960+ switch (param ) {
1961+ case 0 :
1962+ /* Compute column stride from buffer size and
1963+ * padded width
1964+ */
1965+ pitch [i ] = drm_format_info_plane_height (fb -> format ,
1966+ fb -> height ,
1967+ i );
1968+ break ;
1969+ default :
1970+ pitch [i ] = VC4_SET_FIELD (param , SCALER_TILE_HEIGHT );
1971+ break ;
1972+ }
19471973
19481974 if (fb -> format -> format == DRM_FORMAT_P030 ) {
19491975 /*
@@ -1959,39 +1985,28 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
19591985 u32 last_bits = remaining_pixels % 12 ;
19601986
19611987 x_off = aligned * 16 + last_bits ;
1962- tile_w = 128 ;
19631988 pix_per_tile = 96 ;
19641989 } else {
1965- switch (base_format_mod ) {
1966- case DRM_FORMAT_MOD_BROADCOM_SAND128 :
1967- tile_w = 128 ;
1968- break ;
1969- case DRM_FORMAT_MOD_BROADCOM_SAND256 :
1970- tile_w = 256 ;
1971- break ;
1972- default :
1973- return - EINVAL ;
1974- }
1975- pix_per_tile = tile_w / fb -> format -> cpp [0 ];
1990+ pix_per_tile = tile_width / fb -> format -> cpp [0 ];
19761991 x_off = (src_x % pix_per_tile ) /
19771992 (i ? h_subsample : 1 ) *
19781993 fb -> format -> cpp [i ];
19791994 }
19801995
19811996 tile = src_x / pix_per_tile ;
19821997
1983- offsets [i ] += param * tile_w * tile ;
1984- offsets [i ] += src_y / (i ? v_subsample : 1 ) * tile_w ;
1998+ offsets [i ] += pitch [ i ] * tile ;
1999+ offsets [i ] += src_y / (i ? v_subsample : 1 ) * tile_width ;
19852000 offsets [i ] += x_off & ~(i ? 1 : 0 );
1986- }
19872001
1988- components_per_word = fb -> format -> format == DRM_FORMAT_P030 ? 24 : 32 ;
1989- starting_offset = src_x % components_per_word ;
1990- fetch_count = (width + starting_offset + components_per_word - 1 ) /
1991- components_per_word ;
2002+ /*
2003+ * Finished using the pitch as a pitch, so pack it as the
2004+ * register value.
2005+ */
2006+ pitch [i ] = VC4_SET_FIELD (pitch [i ], SCALER6_PTR2_PITCH ) |
2007+ VC4_SET_FIELD (fetch_count - 1 , SCALER6_PTR2_FETCH_COUNT );
2008+ }
19922009
1993- pitch0 = VC4_SET_FIELD (param , SCALER6_PTR2_PITCH ) |
1994- VC4_SET_FIELD (fetch_count - 1 , SCALER6_PTR2_FETCH_COUNT );
19952010 break ;
19962011 }
19972012
@@ -2104,7 +2119,7 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
21042119 VC4_SET_FIELD (fb -> pitches [i ],
21052120 SCALER6_PTR2_PITCH ));
21062121 } else {
2107- vc4_dlist_write (vc4_state , pitch0 );
2122+ vc4_dlist_write (vc4_state , pitch [ i ] );
21082123 }
21092124 }
21102125
@@ -2613,9 +2628,9 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
26132628 unsigned i ;
26142629 static const uint64_t modifiers [] = {
26152630 DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED ,
2616- DRM_FORMAT_MOD_BROADCOM_SAND128 ,
2617- DRM_FORMAT_MOD_BROADCOM_SAND64 ,
2618- DRM_FORMAT_MOD_BROADCOM_SAND256 ,
2631+ DRM_FORMAT_MOD_BROADCOM_SAND128_COL_HEIGHT ( 0 ) ,
2632+ DRM_FORMAT_MOD_BROADCOM_SAND64_COL_HEIGHT ( 0 ) ,
2633+ DRM_FORMAT_MOD_BROADCOM_SAND256_COL_HEIGHT ( 0 ) ,
26192634 DRM_FORMAT_MOD_LINEAR ,
26202635 DRM_FORMAT_MOD_INVALID
26212636 };
0 commit comments