aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/arm/malidp_planes.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/arm/malidp_planes.c')
-rw-r--r--drivers/gpu/drm/arm/malidp_planes.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c
index 5e64060cc8fc..7a44897c50fe 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -266,6 +266,60 @@ static void malidp_de_set_plane_pitches(struct malidp_plane *mp,
mp->layer->stride_offset + i * 4);
}
+static const s16
+malidp_yuv2rgb_coeffs[][DRM_COLOR_RANGE_MAX][MALIDP_COLORADJ_NUM_COEFFS] = {
+ [DRM_COLOR_YCBCR_BT601][DRM_COLOR_YCBCR_LIMITED_RANGE] = {
+ 1192, 0, 1634,
+ 1192, -401, -832,
+ 1192, 2066, 0,
+ 64, 512, 512
+ },
+ [DRM_COLOR_YCBCR_BT601][DRM_COLOR_YCBCR_FULL_RANGE] = {
+ 1024, 0, 1436,
+ 1024, -352, -731,
+ 1024, 1815, 0,
+ 0, 512, 512
+ },
+ [DRM_COLOR_YCBCR_BT709][DRM_COLOR_YCBCR_LIMITED_RANGE] = {
+ 1192, 0, 1836,
+ 1192, -218, -546,
+ 1192, 2163, 0,
+ 64, 512, 512
+ },
+ [DRM_COLOR_YCBCR_BT709][DRM_COLOR_YCBCR_FULL_RANGE] = {
+ 1024, 0, 1613,
+ 1024, -192, -479,
+ 1024, 1900, 0,
+ 0, 512, 512
+ },
+ [DRM_COLOR_YCBCR_BT2020][DRM_COLOR_YCBCR_LIMITED_RANGE] = {
+ 1024, 0, 1476,
+ 1024, -165, -572,
+ 1024, 1884, 0,
+ 0, 512, 512
+ },
+ [DRM_COLOR_YCBCR_BT2020][DRM_COLOR_YCBCR_FULL_RANGE] = {
+ 1024, 0, 1510,
+ 1024, -168, -585,
+ 1024, 1927, 0,
+ 0, 512, 512
+ }
+};
+
+static void malidp_de_set_color_encoding(struct malidp_plane *plane,
+ enum drm_color_encoding enc,
+ enum drm_color_range range)
+{
+ unsigned int i;
+
+ for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; i++) {
+ /* coefficients are signed, two's complement values */
+ malidp_hw_write(plane->hwdev, malidp_yuv2rgb_coeffs[enc][range][i],
+ plane->layer->base + plane->layer->yuv2rgb_offset +
+ i * 4);
+ }
+}
+
static void malidp_de_plane_update(struct drm_plane *plane,
struct drm_plane_state *old_state)
{
@@ -297,6 +351,11 @@ static void malidp_de_plane_update(struct drm_plane *plane,
malidp_de_set_plane_pitches(mp, ms->n_planes,
plane->state->fb->pitches);
+ if ((plane->state->color_encoding != old_state->color_encoding) ||
+ (plane->state->color_range != old_state->color_range))
+ malidp_de_set_color_encoding(mp, plane->state->color_encoding,
+ plane->state->color_range);
+
malidp_hw_write(mp->hwdev, LAYER_H_VAL(src_w) | LAYER_V_VAL(src_h),
mp->layer->base + MALIDP_LAYER_SIZE);
@@ -438,6 +497,26 @@ int malidp_de_planes_init(struct drm_device *drm)
drm_plane_create_rotation_property(&plane->base, DRM_MODE_ROTATE_0, flags);
malidp_hw_write(malidp->dev, MALIDP_ALPHA_LUT,
plane->layer->base + MALIDP_LAYER_COMPOSE);
+
+ /* Attach the YUV->RGB property only to video layers */
+ if (id & (DE_VIDEO1 | DE_VIDEO2)) {
+ /* default encoding for YUV->RGB is BT601 NARROW */
+ enum drm_color_encoding enc = DRM_COLOR_YCBCR_BT601;
+ enum drm_color_range range = DRM_COLOR_YCBCR_LIMITED_RANGE;
+
+ ret = drm_plane_create_color_properties(&plane->base,
+ BIT(DRM_COLOR_YCBCR_BT601) | \
+ BIT(DRM_COLOR_YCBCR_BT709) | \
+ BIT(DRM_COLOR_YCBCR_BT2020),
+ BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | \
+ BIT(DRM_COLOR_YCBCR_FULL_RANGE),
+ enc, range);
+ if (!ret)
+ /* program the HW registers */
+ malidp_de_set_color_encoding(plane, enc, range);
+ else
+ DRM_WARN("Failed to create video layer %d color properties\n", id);
+ }
}
kfree(formats);