summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/armada
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2018-07-30 11:52:34 +0100
committerRussell King <rmk+kernel@armlinux.org.uk>2018-07-30 11:52:34 +0100
commitc29277d4e56388e805acc3ba428c9cff7df99fa7 (patch)
treee3b49fe656394e4e9c1ce18c1547fe8e5f19ffe6 /drivers/gpu/drm/armada
parent240cf2b58eb0bdd3c59387ca0cfbd5657708b996 (diff)
drm/armada: add plane colorspace properties
Use the DRM standard plane properties for specifying the YUV colour encoding parameter. Our colour range is fixed at limited range. Since we are transitioning to atomic modeset, we need to explicitly add handling of these properties to our atomic_set_property() method, but once the transition is complete, these will be removed. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Diffstat (limited to 'drivers/gpu/drm/armada')
-rw-r--r--drivers/gpu/drm/armada/armada_overlay.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 7f75df4f8390..bc1b5b860141 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -23,6 +23,7 @@
#define DEFAULT_BRIGHTNESS 0
#define DEFAULT_CONTRAST 0x4000
#define DEFAULT_SATURATION 0x4000
+#define DEFAULT_ENCODING DRM_COLOR_YCBCR_BT601
struct armada_ovl_plane {
struct armada_plane base;
@@ -59,6 +60,19 @@ static inline u32 armada_spu_saturation(struct drm_plane_state *state)
return drm_to_overlay_state(state)->saturation << 16;
}
+static inline u32 armada_csc(struct drm_plane_state *state)
+{
+ /*
+ * The CFG_CSC_RGB_* settings control the output of the colour space
+ * converter, setting the range of output values it produces. Since
+ * we will be blending with the full-range graphics, we need to
+ * produce full-range RGB output from the conversion.
+ */
+ return CFG_CSC_RGB_COMPUTER |
+ (state->color_encoding == DRM_COLOR_YCBCR_BT709 ?
+ CFG_CSC_YUV_CCIR709 : CFG_CSC_YUV_CCIR601);
+}
+
/* === Plane support === */
static void armada_ovl_plane_work(struct armada_crtc *dcrtc,
struct armada_plane_work *work)
@@ -189,6 +203,11 @@ static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane,
armada_reg_queue_set(regs, idx, val, LCD_SPU_SATURATION);
if (!old_state->visible && state->visible)
armada_reg_queue_set(regs, idx, 0x00002000, LCD_SPU_CBSH_HUE);
+ val = armada_csc(state);
+ if ((!old_state->visible && state->visible) ||
+ armada_csc(old_state) != val)
+ armada_reg_queue_mod(regs, idx, val, CFG_CSC_MASK,
+ LCD_SPU_IOPAD_CONTROL);
val = drm_to_overlay_state(state)->colorkey_yr;
if ((!old_state->visible && state->visible) ||
drm_to_overlay_state(old_state)->colorkey_yr != val)
@@ -399,6 +418,8 @@ static void armada_overlay_reset(struct drm_plane *plane)
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (state) {
state->base.plane = plane;
+ state->base.color_encoding = DEFAULT_ENCODING;
+ state->base.color_range = DRM_COLOR_YCBCR_LIMITED_RANGE;
state->base.rotation = DRM_MODE_ROTATE_0;
state->colorkey_yr = 0xfefefe00;
state->colorkey_ug = 0x01010100;
@@ -489,6 +510,9 @@ static int armada_overlay_set_property(struct drm_plane *plane,
drm_to_overlay_state(state)->contrast = val;
} else if (property == priv->saturation_prop) {
drm_to_overlay_state(state)->saturation = val;
+ } else if (property == plane->color_encoding_property) {
+ /* transitional only */
+ state->color_encoding = val;
} else {
return -EINVAL;
}
@@ -685,5 +709,12 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
drm_object_attach_property(mobj, priv->saturation_prop,
DEFAULT_SATURATION);
- return 0;
+ ret = drm_plane_create_color_properties(&dplane->base.base,
+ BIT(DRM_COLOR_YCBCR_BT601) |
+ BIT(DRM_COLOR_YCBCR_BT709),
+ BIT(DRM_COLOR_YCBCR_LIMITED_RANGE),
+ DEFAULT_ENCODING,
+ DRM_COLOR_YCBCR_LIMITED_RANGE);
+
+ return ret;
}