@@ -1293,7 +1293,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
1293
1293
u32 v_subsample = fb -> format -> vsub ;
1294
1294
bool mix_plane_alpha ;
1295
1295
bool covers_screen ;
1296
- u32 scl0 , scl1 , pitch0 ;
1296
+ u32 scl0 , scl1 , pitch [ 2 ] ;
1297
1297
u32 tiling , src_x , src_y ;
1298
1298
u32 width , height ;
1299
1299
u32 hvs_format = format -> hvs ;
@@ -1347,7 +1347,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
1347
1347
switch (base_format_mod ) {
1348
1348
case DRM_FORMAT_MOD_LINEAR :
1349
1349
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 );
1351
1351
1352
1352
/* Adjust the base pointer to the first pixel to be scanned
1353
1353
* out.
@@ -1399,23 +1399,23 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
1399
1399
*/
1400
1400
if (rotation & DRM_MODE_REFLECT_Y ) {
1401
1401
y_off = tile_h_mask - y_off ;
1402
- pitch0 = SCALER_PITCH0_TILE_LINE_DIR ;
1402
+ pitch [ 0 ] = SCALER_PITCH0_TILE_LINE_DIR ;
1403
1403
} else {
1404
- pitch0 = 0 ;
1404
+ pitch [ 0 ] = 0 ;
1405
1405
}
1406
1406
1407
1407
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 ));
1412
1412
offsets [0 ] += tiles_t * (tiles_w << tile_size_shift );
1413
1413
offsets [0 ] += subtile_y << 8 ;
1414
1414
offsets [0 ] += utile_y << 4 ;
1415
1415
1416
1416
/* Rows of tiles alternate left-to-right and right-to-left. */
1417
1417
if (tiles_t & 1 ) {
1418
- pitch0 |= SCALER_PITCH0_TILE_INITIAL_LINE_DIR ;
1418
+ pitch [ 0 ] |= SCALER_PITCH0_TILE_INITIAL_LINE_DIR ;
1419
1419
offsets [0 ] += (tiles_w - tiles_l ) << tile_size_shift ;
1420
1420
offsets [0 ] -= (1 + !tile_y ) << 10 ;
1421
1421
} else {
@@ -1430,6 +1430,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
1430
1430
case DRM_FORMAT_MOD_BROADCOM_SAND128 :
1431
1431
case DRM_FORMAT_MOD_BROADCOM_SAND256 : {
1432
1432
uint32_t param = fourcc_mod_broadcom_param (fb -> modifier );
1433
+ unsigned int tile_width = 0 ;
1433
1434
1434
1435
if (param > SCALER_TILE_HEIGHT_MASK ) {
1435
1436
DRM_DEBUG_KMS ("SAND height too large (%d)\n" ,
@@ -1440,18 +1441,22 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
1440
1441
if (fb -> format -> format == DRM_FORMAT_P030 ) {
1441
1442
hvs_format = HVS_PIXEL_FORMAT_YCBCR_10BIT ;
1442
1443
tiling = SCALER_CTL0_TILING_128B ;
1444
+ tile_width = 128 ;
1443
1445
} else {
1444
1446
hvs_format = HVS_PIXEL_FORMAT_H264 ;
1445
1447
1446
1448
switch (base_format_mod ) {
1447
1449
case DRM_FORMAT_MOD_BROADCOM_SAND64 :
1448
1450
tiling = SCALER_CTL0_TILING_64B ;
1451
+ tile_width = 64 ;
1449
1452
break ;
1450
1453
case DRM_FORMAT_MOD_BROADCOM_SAND128 :
1451
1454
tiling = SCALER_CTL0_TILING_128B ;
1455
+ tile_width = 128 ;
1452
1456
break ;
1453
1457
case DRM_FORMAT_MOD_BROADCOM_SAND256 :
1454
1458
tiling = SCALER_CTL0_TILING_256B_OR_T ;
1459
+ tile_width = 256 ;
1455
1460
break ;
1456
1461
default :
1457
1462
return - EINVAL ;
@@ -1469,7 +1474,16 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
1469
1474
* should be 6.
1470
1475
*/
1471
1476
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
+ }
1473
1487
1474
1488
if (fb -> format -> format == DRM_FORMAT_P030 ) {
1475
1489
/*
@@ -1485,36 +1499,20 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
1485
1499
u32 last_bits = remaining_pixels % 12 ;
1486
1500
1487
1501
x_off = aligned * 16 + last_bits ;
1488
- tile_w = 128 ;
1489
1502
pix_per_tile = 96 ;
1490
1503
} 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 ];
1505
1505
x_off = (src_x % pix_per_tile ) /
1506
1506
(i ? h_subsample : 1 ) *
1507
1507
fb -> format -> cpp [i ];
1508
1508
}
1509
1509
1510
1510
tile = src_x / pix_per_tile ;
1511
1511
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 ;
1514
1514
offsets [i ] += x_off & ~(i ? 1 : 0 );
1515
1515
}
1516
-
1517
- pitch0 = VC4_SET_FIELD (param , SCALER_TILE_HEIGHT );
1518
1516
break ;
1519
1517
}
1520
1518
@@ -1669,7 +1667,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
1669
1667
vc4_dlist_write (vc4_state , 0xc0c0c0c0 );
1670
1668
1671
1669
/* Pitch word 0 */
1672
- vc4_dlist_write (vc4_state , pitch0 );
1670
+ vc4_dlist_write (vc4_state , pitch [ 0 ] );
1673
1671
1674
1672
/* Pitch word 1/2 */
1675
1673
for (i = 1 ; i < num_planes ; i ++ ) {
@@ -1679,7 +1677,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
1679
1677
VC4_SET_FIELD (fb -> pitches [i ],
1680
1678
SCALER_SRC_PITCH ));
1681
1679
} else {
1682
- vc4_dlist_write (vc4_state , pitch0 );
1680
+ vc4_dlist_write (vc4_state , pitch [ 1 ] );
1683
1681
}
1684
1682
}
1685
1683
@@ -1834,7 +1832,7 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
1834
1832
u32 v_subsample = fb -> format -> vsub ;
1835
1833
bool mix_plane_alpha ;
1836
1834
bool covers_screen ;
1837
- u32 scl0 , scl1 , pitch0 ;
1835
+ u32 scl0 , scl1 , pitch [ 2 ] ;
1838
1836
u32 tiling , src_x , src_y ;
1839
1837
u32 width , height ;
1840
1838
u32 hvs_format = format -> hvs ;
@@ -1904,6 +1902,7 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
1904
1902
case DRM_FORMAT_MOD_BROADCOM_SAND128 :
1905
1903
case DRM_FORMAT_MOD_BROADCOM_SAND256 : {
1906
1904
uint32_t param = fourcc_mod_broadcom_param (fb -> modifier );
1905
+ unsigned int tile_width = 0 ;
1907
1906
u32 components_per_word ;
1908
1907
u32 starting_offset ;
1909
1908
u32 fetch_count ;
@@ -1917,21 +1916,29 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
1917
1916
if (fb -> format -> format == DRM_FORMAT_P030 ) {
1918
1917
hvs_format = HVS_PIXEL_FORMAT_YCBCR_10BIT ;
1919
1918
tiling = SCALER6_CTL0_ADDR_MODE_128B ;
1919
+ tile_width = 128 ;
1920
1920
} else {
1921
1921
hvs_format = HVS_PIXEL_FORMAT_YCBCR_YUV420_2PLANE ;
1922
1922
1923
1923
switch (base_format_mod ) {
1924
1924
case DRM_FORMAT_MOD_BROADCOM_SAND128 :
1925
1925
tiling = SCALER6_CTL0_ADDR_MODE_128B ;
1926
+ tile_width = 128 ;
1926
1927
break ;
1927
1928
case DRM_FORMAT_MOD_BROADCOM_SAND256 :
1928
1929
tiling = SCALER6_CTL0_ADDR_MODE_256B ;
1930
+ tile_width = 256 ;
1929
1931
break ;
1930
1932
default :
1931
1933
return - EINVAL ;
1932
1934
}
1933
1935
}
1934
1936
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
+
1935
1942
/* Adjust the base pointer to the first pixel to be scanned
1936
1943
* out.
1937
1944
*
@@ -1943,7 +1950,16 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
1943
1950
* should be 6.
1944
1951
*/
1945
1952
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
+ }
1947
1963
1948
1964
if (fb -> format -> format == DRM_FORMAT_P030 ) {
1949
1965
/*
@@ -1959,39 +1975,28 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
1959
1975
u32 last_bits = remaining_pixels % 12 ;
1960
1976
1961
1977
x_off = aligned * 16 + last_bits ;
1962
- tile_w = 128 ;
1963
1978
pix_per_tile = 96 ;
1964
1979
} 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 ];
1976
1981
x_off = (src_x % pix_per_tile ) /
1977
1982
(i ? h_subsample : 1 ) *
1978
1983
fb -> format -> cpp [i ];
1979
1984
}
1980
1985
1981
1986
tile = src_x / pix_per_tile ;
1982
1987
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 ;
1985
1990
offsets [i ] += x_off & ~(i ? 1 : 0 );
1986
- }
1987
1991
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
+ }
1992
1999
1993
- pitch0 = VC4_SET_FIELD (param , SCALER6_PTR2_PITCH ) |
1994
- VC4_SET_FIELD (fetch_count - 1 , SCALER6_PTR2_FETCH_COUNT );
1995
2000
break ;
1996
2001
}
1997
2002
@@ -2104,7 +2109,7 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
2104
2109
VC4_SET_FIELD (fb -> pitches [i ],
2105
2110
SCALER6_PTR2_PITCH ));
2106
2111
} else {
2107
- vc4_dlist_write (vc4_state , pitch0 );
2112
+ vc4_dlist_write (vc4_state , pitch [ i ] );
2108
2113
}
2109
2114
}
2110
2115
@@ -2613,9 +2618,9 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
2613
2618
unsigned i ;
2614
2619
static const uint64_t modifiers [] = {
2615
2620
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 ) ,
2619
2624
DRM_FORMAT_MOD_LINEAR ,
2620
2625
DRM_FORMAT_MOD_INVALID
2621
2626
};
0 commit comments