On Fri, Dec 08, 2017 at 12:31:08PM +0000, Russell King wrote:
Add the defacto-standard "iturbt_709" property to the overlay plane to control the YUV to RGB colorspace conversion. This is mutually exclusive with the CSC_YUV CRTC property - the last property to be set determines the resulting colorspace conversion.
See https://patchwork.freedesktop.org/patch/158920/ by Jyri.
For the correspoding i915 implementation I cooked up see: https://patchwork.freedesktop.org/series/25505/
Signed-off-by: Russell King rmk+kernel@armlinux.org.uk
drivers/gpu/drm/armada/armada_crtc.c | 26 +++++++++++++++++++++++--- drivers/gpu/drm/armada/armada_crtc.h | 2 ++ drivers/gpu/drm/armada/armada_drm.h | 1 + drivers/gpu/drm/armada/armada_overlay.c | 25 ++++++++++++++++++++++--- 4 files changed, 48 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 8b66377a4890..1bf632bb8855 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -535,12 +535,30 @@ static irqreturn_t armada_drm_irq(int irq, void *arg) return IRQ_NONE; }
+void armada_drm_crtc_set_yuv_colorimetry(struct armada_crtc *dcrtc, u32 csc) +{
- armada_updatel(csc, CFG_CSC_YUV_CCIR709,
dcrtc->base + LCD_SPU_IOPAD_CONTROL);
- dcrtc->csc_yuv_ovl_mode = csc == CFG_CSC_YUV_CCIR709 ?
CSC_YUV_CCIR709 : CSC_YUV_CCIR601;
+}
static uint32_t armada_drm_crtc_calculate_csc(struct armada_crtc *dcrtc) { struct drm_display_mode *adj = &dcrtc->crtc.mode;
- uint32_t val = 0;
- u32 val = 0;
- u8 csc_yuv_mode;
- /*
* If the iturbt_709 overlay plane property is used, it overrides
* the CSC_YUV crtc property until the CSC_YUV property is set.
*/
- csc_yuv_mode = dcrtc->csc_yuv_ovl_mode;
- if (csc_yuv_mode == CSC_AUTO)
csc_yuv_mode = dcrtc->csc_yuv_mode;
- if (dcrtc->csc_yuv_mode == CSC_YUV_CCIR709)
- if (csc_yuv_mode == CSC_YUV_CCIR709) val |= CFG_CSC_YUV_CCIR709; if (dcrtc->csc_rgb_mode == CSC_RGB_STUDIO) val |= CFG_CSC_RGB_STUDIO;
@@ -555,7 +573,7 @@ static uint32_t armada_drm_crtc_calculate_csc(struct armada_crtc *dcrtc) if ((adj->hdisplay == 1280 && adj->vdisplay == 720 && !(adj->flags & DRM_MODE_FLAG_INTERLACE)) || (adj->hdisplay == 1920 && adj->vdisplay == 1080)) {
if (dcrtc->csc_yuv_mode == CSC_AUTO)
}if (csc_yuv_mode == CSC_AUTO) val |= CFG_CSC_YUV_CCIR709;
@@ -1094,6 +1112,7 @@ armada_drm_crtc_set_property(struct drm_crtc *crtc,
if (property == priv->csc_yuv_prop) { dcrtc->csc_yuv_mode = val;
update_csc = true; } else if (property == priv->csc_rgb_prop) { dcrtc->csc_rgb_mode = val;dcrtc->csc_yuv_ovl_mode = CSC_AUTO;
@@ -1396,6 +1415,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, dcrtc->num = drm->mode_config.num_crtc; dcrtc->clk = ERR_PTR(-EINVAL); dcrtc->csc_yuv_mode = CSC_AUTO;
- dcrtc->csc_yuv_ovl_mode = CSC_AUTO; dcrtc->csc_rgb_mode = CSC_AUTO; dcrtc->cfg_dumb_ctrl = DUMB24_RGB888_0; dcrtc->spu_iopad_ctrl = CFG_VSCALE_LN_EN | CFG_IOPAD_DUMB24;
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h index 445829b8877a..5d70b4af20b7 100644 --- a/drivers/gpu/drm/armada/armada_crtc.h +++ b/drivers/gpu/drm/armada/armada_crtc.h @@ -90,6 +90,7 @@ struct armada_crtc { bool interlaced; bool cursor_update; uint8_t csc_yuv_mode;
uint8_t csc_yuv_ovl_mode; uint8_t csc_rgb_mode;
struct drm_plane *plane;
@@ -113,6 +114,7 @@ struct armada_crtc { #define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)
void armada_drm_crtc_update_regs(struct armada_crtc *, struct armada_regs *); +void armada_drm_crtc_set_yuv_colorimetry(struct armada_crtc *dcrtc, u32 csc);
int armada_drm_plane_disable(struct drm_plane *plane, struct drm_modeset_acquire_ctx *ctx); diff --git a/drivers/gpu/drm/armada/armada_drm.h b/drivers/gpu/drm/armada/armada_drm.h index b064879ecdbd..45d5168d5748 100644 --- a/drivers/gpu/drm/armada/armada_drm.h +++ b/drivers/gpu/drm/armada/armada_drm.h @@ -60,6 +60,7 @@ struct armada_private { struct armada_crtc *dcrtc[2]; struct drm_mm linear; /* protected by linear_lock */ struct mutex linear_lock;
- struct drm_property *iturbt709_prop; struct drm_property *csc_yuv_prop; struct drm_property *csc_rgb_prop; struct drm_property *colorkey_prop;
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c index 853f889e84f5..d7a9c79f0ada 100644 --- a/drivers/gpu/drm/armada/armada_overlay.c +++ b/drivers/gpu/drm/armada/armada_overlay.c @@ -28,6 +28,8 @@ struct armada_ovl_plane_properties { uint16_t contrast; uint16_t saturation; uint32_t colorkey_mode;
- uint32_t csc;
- bool csc_set;
};
struct armada_ovl_plane { @@ -252,6 +254,10 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, if (!dcrtc->plane) { dcrtc->plane = plane; armada_ovl_update_attr(&dplane->prop, dcrtc);
if (dplane->prop.csc_set) {
armada_drm_crtc_set_yuv_colorimetry(dcrtc, dplane->prop.csc);
dplane->prop.csc_set = false;
}
}
/* Queue it for update on the next interrupt if we are enabled */
@@ -332,11 +338,21 @@ static int armada_ovl_plane_set_property(struct drm_plane *plane, } else if (property == priv->saturation_prop) { dplane->prop.saturation = val; update_attr = true;
- } else if (property == priv->iturbt709_prop) {
dplane->prop.csc = val ? CFG_CSC_YUV_CCIR709 :
CFG_CSC_YUV_CCIR601;
}dplane->prop.csc_set = true;
- if (update_attr && dplane->base.base.crtc)
armada_ovl_update_attr(&dplane->prop,
drm_to_armada_crtc(dplane->base.base.crtc));
if (plane->crtc) {
struct armada_crtc *dcrtc = drm_to_armada_crtc(plane->crtc);
if (update_attr)
armada_ovl_update_attr(&dplane->prop, dcrtc);
if (dplane->prop.csc_set) {
armada_drm_crtc_set_yuv_colorimetry(dcrtc, dplane->prop.csc);
dplane->prop.csc_set = false;
}
}
return 0;
} @@ -407,6 +423,8 @@ static int armada_overlay_create_properties(struct drm_device *dev) "contrast", 0, 0x7fff); priv->saturation_prop = drm_property_create_range(dev, 0, "saturation", 0, 0x7fff);
priv->iturbt709_prop = drm_property_create_bool(dev, 0,
"iturbt_709");
if (!priv->colorkey_prop) return -ENOMEM;
@@ -475,6 +493,7 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs) dplane->prop.contrast); drm_object_attach_property(mobj, priv->saturation_prop, dplane->prop.saturation);
drm_object_attach_property(mobj, priv->iturbt709_prop, false);
return 0;
}
2.7.4
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel