|
@@ -467,12 +467,14 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
|
|
struct drm_framebuffer *fb = state->fb;
|
|
struct drm_framebuffer *fb = state->fb;
|
|
u32 ctl0_offset = vc4_state->dlist_count;
|
|
u32 ctl0_offset = vc4_state->dlist_count;
|
|
const struct hvs_format *format = vc4_get_hvs_format(fb->format->format);
|
|
const struct hvs_format *format = vc4_get_hvs_format(fb->format->format);
|
|
|
|
+ u64 base_format_mod = fourcc_mod_broadcom_mod(fb->modifier);
|
|
int num_planes = drm_format_num_planes(format->drm);
|
|
int num_planes = drm_format_num_planes(format->drm);
|
|
bool mix_plane_alpha;
|
|
bool mix_plane_alpha;
|
|
bool covers_screen;
|
|
bool covers_screen;
|
|
u32 scl0, scl1, pitch0;
|
|
u32 scl0, scl1, pitch0;
|
|
u32 lbm_size, tiling;
|
|
u32 lbm_size, tiling;
|
|
unsigned long irqflags;
|
|
unsigned long irqflags;
|
|
|
|
+ u32 hvs_format = format->hvs;
|
|
int ret, i;
|
|
int ret, i;
|
|
|
|
|
|
ret = vc4_plane_setup_clipping_and_scaling(state);
|
|
ret = vc4_plane_setup_clipping_and_scaling(state);
|
|
@@ -512,7 +514,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
|
|
scl1 = vc4_get_scl_field(state, 0);
|
|
scl1 = vc4_get_scl_field(state, 0);
|
|
}
|
|
}
|
|
|
|
|
|
- switch (fb->modifier) {
|
|
|
|
|
|
+ switch (base_format_mod) {
|
|
case DRM_FORMAT_MOD_LINEAR:
|
|
case DRM_FORMAT_MOD_LINEAR:
|
|
tiling = SCALER_CTL0_TILING_LINEAR;
|
|
tiling = SCALER_CTL0_TILING_LINEAR;
|
|
pitch0 = VC4_SET_FIELD(fb->pitches[0], SCALER_SRC_PITCH);
|
|
pitch0 = VC4_SET_FIELD(fb->pitches[0], SCALER_SRC_PITCH);
|
|
@@ -535,6 +537,49 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ case DRM_FORMAT_MOD_BROADCOM_SAND64:
|
|
|
|
+ case DRM_FORMAT_MOD_BROADCOM_SAND128:
|
|
|
|
+ case DRM_FORMAT_MOD_BROADCOM_SAND256: {
|
|
|
|
+ uint32_t param = fourcc_mod_broadcom_param(fb->modifier);
|
|
|
|
+
|
|
|
|
+ /* Column-based NV12 or RGBA.
|
|
|
|
+ */
|
|
|
|
+ if (fb->format->num_planes > 1) {
|
|
|
|
+ if (hvs_format != HVS_PIXEL_FORMAT_YCBCR_YUV420_2PLANE) {
|
|
|
|
+ DRM_DEBUG_KMS("SAND format only valid for NV12/21");
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+ hvs_format = HVS_PIXEL_FORMAT_H264;
|
|
|
|
+ } else {
|
|
|
|
+ if (base_format_mod == DRM_FORMAT_MOD_BROADCOM_SAND256) {
|
|
|
|
+ DRM_DEBUG_KMS("SAND256 format only valid for H.264");
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ switch (base_format_mod) {
|
|
|
|
+ case DRM_FORMAT_MOD_BROADCOM_SAND64:
|
|
|
|
+ tiling = SCALER_CTL0_TILING_64B;
|
|
|
|
+ break;
|
|
|
|
+ case DRM_FORMAT_MOD_BROADCOM_SAND128:
|
|
|
|
+ tiling = SCALER_CTL0_TILING_128B;
|
|
|
|
+ break;
|
|
|
|
+ case DRM_FORMAT_MOD_BROADCOM_SAND256:
|
|
|
|
+ tiling = SCALER_CTL0_TILING_256B_OR_T;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (param > SCALER_TILE_HEIGHT_MASK) {
|
|
|
|
+ DRM_DEBUG_KMS("SAND height too large (%d)\n", param);
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pitch0 = VC4_SET_FIELD(param, SCALER_TILE_HEIGHT);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
default:
|
|
default:
|
|
DRM_DEBUG_KMS("Unsupported FB tiling flag 0x%16llx",
|
|
DRM_DEBUG_KMS("Unsupported FB tiling flag 0x%16llx",
|
|
(long long)fb->modifier);
|
|
(long long)fb->modifier);
|
|
@@ -546,7 +591,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
|
|
SCALER_CTL0_VALID |
|
|
SCALER_CTL0_VALID |
|
|
VC4_SET_FIELD(SCALER_CTL0_RGBA_EXPAND_ROUND, SCALER_CTL0_RGBA_EXPAND) |
|
|
VC4_SET_FIELD(SCALER_CTL0_RGBA_EXPAND_ROUND, SCALER_CTL0_RGBA_EXPAND) |
|
|
(format->pixel_order << SCALER_CTL0_ORDER_SHIFT) |
|
|
(format->pixel_order << SCALER_CTL0_ORDER_SHIFT) |
|
|
- (format->hvs << SCALER_CTL0_PIXEL_FORMAT_SHIFT) |
|
|
|
|
|
|
+ (hvs_format << SCALER_CTL0_PIXEL_FORMAT_SHIFT) |
|
|
VC4_SET_FIELD(tiling, SCALER_CTL0_TILING) |
|
|
VC4_SET_FIELD(tiling, SCALER_CTL0_TILING) |
|
|
(vc4_state->is_unity ? SCALER_CTL0_UNITY : 0) |
|
|
(vc4_state->is_unity ? SCALER_CTL0_UNITY : 0) |
|
|
VC4_SET_FIELD(scl0, SCALER_CTL0_SCL0) |
|
|
VC4_SET_FIELD(scl0, SCALER_CTL0_SCL0) |
|
|
@@ -608,8 +653,13 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
|
|
|
|
|
|
/* Pitch word 1/2 */
|
|
/* Pitch word 1/2 */
|
|
for (i = 1; i < num_planes; i++) {
|
|
for (i = 1; i < num_planes; i++) {
|
|
- vc4_dlist_write(vc4_state,
|
|
|
|
- VC4_SET_FIELD(fb->pitches[i], SCALER_SRC_PITCH));
|
|
|
|
|
|
+ if (hvs_format != HVS_PIXEL_FORMAT_H264) {
|
|
|
|
+ vc4_dlist_write(vc4_state,
|
|
|
|
+ VC4_SET_FIELD(fb->pitches[i],
|
|
|
|
+ SCALER_SRC_PITCH));
|
|
|
|
+ } else {
|
|
|
|
+ vc4_dlist_write(vc4_state, pitch0);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/* Colorspace conversion words */
|
|
/* Colorspace conversion words */
|
|
@@ -867,13 +917,30 @@ static bool vc4_format_mod_supported(struct drm_plane *plane,
|
|
case DRM_FORMAT_BGR565:
|
|
case DRM_FORMAT_BGR565:
|
|
case DRM_FORMAT_ARGB1555:
|
|
case DRM_FORMAT_ARGB1555:
|
|
case DRM_FORMAT_XRGB1555:
|
|
case DRM_FORMAT_XRGB1555:
|
|
- return true;
|
|
|
|
|
|
+ switch (fourcc_mod_broadcom_mod(modifier)) {
|
|
|
|
+ case DRM_FORMAT_MOD_LINEAR:
|
|
|
|
+ case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED:
|
|
|
|
+ case DRM_FORMAT_MOD_BROADCOM_SAND64:
|
|
|
|
+ case DRM_FORMAT_MOD_BROADCOM_SAND128:
|
|
|
|
+ return true;
|
|
|
|
+ default:
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ case DRM_FORMAT_NV12:
|
|
|
|
+ case DRM_FORMAT_NV21:
|
|
|
|
+ switch (fourcc_mod_broadcom_mod(modifier)) {
|
|
|
|
+ case DRM_FORMAT_MOD_LINEAR:
|
|
|
|
+ case DRM_FORMAT_MOD_BROADCOM_SAND64:
|
|
|
|
+ case DRM_FORMAT_MOD_BROADCOM_SAND128:
|
|
|
|
+ case DRM_FORMAT_MOD_BROADCOM_SAND256:
|
|
|
|
+ return true;
|
|
|
|
+ default:
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
case DRM_FORMAT_YUV422:
|
|
case DRM_FORMAT_YUV422:
|
|
case DRM_FORMAT_YVU422:
|
|
case DRM_FORMAT_YVU422:
|
|
case DRM_FORMAT_YUV420:
|
|
case DRM_FORMAT_YUV420:
|
|
case DRM_FORMAT_YVU420:
|
|
case DRM_FORMAT_YVU420:
|
|
- case DRM_FORMAT_NV12:
|
|
|
|
- case DRM_FORMAT_NV21:
|
|
|
|
case DRM_FORMAT_NV16:
|
|
case DRM_FORMAT_NV16:
|
|
case DRM_FORMAT_NV61:
|
|
case DRM_FORMAT_NV61:
|
|
default:
|
|
default:
|
|
@@ -903,6 +970,9 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
|
|
unsigned i;
|
|
unsigned i;
|
|
static const uint64_t modifiers[] = {
|
|
static const uint64_t modifiers[] = {
|
|
DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED,
|
|
DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED,
|
|
|
|
+ DRM_FORMAT_MOD_BROADCOM_SAND128,
|
|
|
|
+ DRM_FORMAT_MOD_BROADCOM_SAND64,
|
|
|
|
+ DRM_FORMAT_MOD_BROADCOM_SAND256,
|
|
DRM_FORMAT_MOD_LINEAR,
|
|
DRM_FORMAT_MOD_LINEAR,
|
|
DRM_FORMAT_MOD_INVALID
|
|
DRM_FORMAT_MOD_INVALID
|
|
};
|
|
};
|