@@ -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,16 @@ 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+ pitch [i ] = fb -> pitches [i ];
1482+ break ;
1483+ default :
1484+ pitch [i ] = VC4_SET_FIELD (param , SCALER_TILE_HEIGHT );
1485+ break ;
1486+ }
14731487
14741488 if (fb -> format -> format == DRM_FORMAT_P030 ) {
14751489 /*
@@ -1485,36 +1499,20 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
14851499 u32 last_bits = remaining_pixels % 12 ;
14861500
14871501 x_off = aligned * 16 + last_bits ;
1488- tile_w = 128 ;
14891502 pix_per_tile = 96 ;
14901503 } 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 ];
1504+ pix_per_tile = tile_width / fb -> format -> cpp [0 ];
15051505 x_off = (src_x % pix_per_tile ) /
15061506 (i ? h_subsample : 1 ) *
15071507 fb -> format -> cpp [i ];
15081508 }
15091509
15101510 tile = src_x / pix_per_tile ;
15111511
1512- offsets [i ] += param * tile_w * tile ;
1513- offsets [i ] += src_y / (i ? v_subsample : 1 ) * tile_w ;
1512+ offsets [i ] += pitch [ i ] * tile ;
1513+ offsets [i ] += src_y / (i ? v_subsample : 1 ) * tile_width ;
15141514 offsets [i ] += x_off & ~(i ? 1 : 0 );
15151515 }
1516-
1517- pitch0 = VC4_SET_FIELD (param , SCALER_TILE_HEIGHT );
15181516 break ;
15191517 }
15201518
@@ -1669,7 +1667,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
16691667 vc4_dlist_write (vc4_state , 0xc0c0c0c0 );
16701668
16711669 /* Pitch word 0 */
1672- vc4_dlist_write (vc4_state , pitch0 );
1670+ vc4_dlist_write (vc4_state , pitch [ 0 ] );
16731671
16741672 /* Pitch word 1/2 */
16751673 for (i = 1 ; i < num_planes ; i ++ ) {
@@ -1679,7 +1677,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
16791677 VC4_SET_FIELD (fb -> pitches [i ],
16801678 SCALER_SRC_PITCH ));
16811679 } else {
1682- vc4_dlist_write (vc4_state , pitch0 );
1680+ vc4_dlist_write (vc4_state , pitch [ 1 ] );
16831681 }
16841682 }
16851683
@@ -1834,7 +1832,7 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
18341832 u32 v_subsample = fb -> format -> vsub ;
18351833 bool mix_plane_alpha ;
18361834 bool covers_screen ;
1837- u32 scl0 , scl1 , pitch0 ;
1835+ u32 scl0 , scl1 , pitch [ 2 ] ;
18381836 u32 tiling , src_x , src_y ;
18391837 u32 width , height ;
18401838 u32 hvs_format = format -> hvs ;
@@ -1904,6 +1902,7 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
19041902 case DRM_FORMAT_MOD_BROADCOM_SAND128 :
19051903 case DRM_FORMAT_MOD_BROADCOM_SAND256 : {
19061904 uint32_t param = fourcc_mod_broadcom_param (fb -> modifier );
1905+ unsigned int tile_width = 0 ;
19071906 u32 components_per_word ;
19081907 u32 starting_offset ;
19091908 u32 fetch_count ;
@@ -1917,21 +1916,29 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
19171916 if (fb -> format -> format == DRM_FORMAT_P030 ) {
19181917 hvs_format = HVS_PIXEL_FORMAT_YCBCR_10BIT ;
19191918 tiling = SCALER6_CTL0_ADDR_MODE_128B ;
1919+ tile_width = 128 ;
19201920 } else {
19211921 hvs_format = HVS_PIXEL_FORMAT_YCBCR_YUV420_2PLANE ;
19221922
19231923 switch (base_format_mod ) {
19241924 case DRM_FORMAT_MOD_BROADCOM_SAND128 :
19251925 tiling = SCALER6_CTL0_ADDR_MODE_128B ;
1926+ tile_width = 128 ;
19261927 break ;
19271928 case DRM_FORMAT_MOD_BROADCOM_SAND256 :
19281929 tiling = SCALER6_CTL0_ADDR_MODE_256B ;
1930+ tile_width = 256 ;
19291931 break ;
19301932 default :
19311933 return - EINVAL ;
19321934 }
19331935 }
19341936
1937+ components_per_word = fb -> format -> format == DRM_FORMAT_P030 ? 24 : 32 ;
1938+ starting_offset = src_x % components_per_word ;
1939+ fetch_count = (width + starting_offset + components_per_word - 1 ) /
1940+ components_per_word ;
1941+
19351942 /* Adjust the base pointer to the first pixel to be scanned
19361943 * out.
19371944 *
@@ -1943,7 +1950,16 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
19431950 * should be 6.
19441951 */
19451952 for (i = 0 ; i < num_planes ; i ++ ) {
1946- u32 tile_w , tile , x_off , pix_per_tile ;
1953+ u32 tile , x_off , pix_per_tile ;
1954+
1955+ switch (param ) {
1956+ case 0 :
1957+ pitch [i ] = fb -> pitches [i ];
1958+ break ;
1959+ default :
1960+ pitch [i ] = VC4_SET_FIELD (param , SCALER_TILE_HEIGHT );
1961+ break ;
1962+ }
19471963
19481964 if (fb -> format -> format == DRM_FORMAT_P030 ) {
19491965 /*
@@ -1959,39 +1975,28 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
19591975 u32 last_bits = remaining_pixels % 12 ;
19601976
19611977 x_off = aligned * 16 + last_bits ;
1962- tile_w = 128 ;
19631978 pix_per_tile = 96 ;
19641979 } 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 ];
1980+ pix_per_tile = tile_width / fb -> format -> cpp [0 ];
19761981 x_off = (src_x % pix_per_tile ) /
19771982 (i ? h_subsample : 1 ) *
19781983 fb -> format -> cpp [i ];
19791984 }
19801985
19811986 tile = src_x / pix_per_tile ;
19821987
1983- offsets [i ] += param * tile_w * tile ;
1984- offsets [i ] += src_y / (i ? v_subsample : 1 ) * tile_w ;
1988+ offsets [i ] += pitch [ i ] * tile ;
1989+ offsets [i ] += src_y / (i ? v_subsample : 1 ) * tile_width ;
19851990 offsets [i ] += x_off & ~(i ? 1 : 0 );
1986- }
19871991
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 ;
1992+ /*
1993+ * Finished using the pitch as a pitch, so pack it as the
1994+ * register value.
1995+ */
1996+ pitch [i ] = VC4_SET_FIELD (pitch [i ], SCALER6_PTR2_PITCH ) |
1997+ VC4_SET_FIELD (fetch_count - 1 , SCALER6_PTR2_FETCH_COUNT );
1998+ }
19921999
1993- pitch0 = VC4_SET_FIELD (param , SCALER6_PTR2_PITCH ) |
1994- VC4_SET_FIELD (fetch_count - 1 , SCALER6_PTR2_FETCH_COUNT );
19952000 break ;
19962001 }
19972002
@@ -2104,7 +2109,7 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
21042109 VC4_SET_FIELD (fb -> pitches [i ],
21052110 SCALER6_PTR2_PITCH ));
21062111 } else {
2107- vc4_dlist_write (vc4_state , pitch0 );
2112+ vc4_dlist_write (vc4_state , pitch [ i ] );
21082113 }
21092114 }
21102115
@@ -2613,9 +2618,9 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
26132618 unsigned i ;
26142619 static const uint64_t modifiers [] = {
26152620 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 ,
2621+ DRM_FORMAT_MOD_BROADCOM_SAND128_COL_HEIGHT ( 0 ) ,
2622+ DRM_FORMAT_MOD_BROADCOM_SAND64_COL_HEIGHT ( 0 ) ,
2623+ DRM_FORMAT_MOD_BROADCOM_SAND256_COL_HEIGHT ( 0 ) ,
26192624 DRM_FORMAT_MOD_LINEAR ,
26202625 DRM_FORMAT_MOD_INVALID
26212626 };
0 commit comments