From patchwork Fri Apr 21 09:51:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jyri Sarha X-Patchwork-Id: 9692301 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E18BA60383 for ; Fri, 21 Apr 2017 09:51:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D977E223A6 for ; Fri, 21 Apr 2017 09:51:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CE28A28614; Fri, 21 Apr 2017 09:51:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0F36F223A6 for ; Fri, 21 Apr 2017 09:51:42 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5F1156E40D; Fri, 21 Apr 2017 09:51:42 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from lelnx194.ext.ti.com (lelnx194.ext.ti.com [198.47.27.80]) by gabe.freedesktop.org (Postfix) with ESMTPS id 315316E40D for ; Fri, 21 Apr 2017 09:51:41 +0000 (UTC) Received: from dflxv15.itg.ti.com ([128.247.5.124]) by lelnx194.ext.ti.com (8.15.1/8.15.1) with ESMTP id v3L9pYTL014730; Fri, 21 Apr 2017 04:51:34 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ti.com; s=ti-com-17Q1; t=1492768294; bh=gZ9cQmuc45aPhvMvjgGVFI3+U1Aj1ixk9nptvg9ekBA=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=TWNKmTeRPXrNN5QLDluCPPTI6x+2nLesl0sNmXSwo6fjt5Pg0IhdZahhBOtlDjk3G DTsy4u6IDJwJ7M5acg8fhZgrJPKWZOZ43Sq0M4rusBCn8MTzoUJgOJJ7c6A/eE4r9I DDlPTmAYReRZg+wlm/oF5j5QZcJkpN9P95y7I2a8= Received: from DFLE73.ent.ti.com (dfle73.ent.ti.com [128.247.5.110]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id v3L9pYZc015242; Fri, 21 Apr 2017 04:51:34 -0500 Received: from dlep33.itg.ti.com (157.170.170.75) by DFLE73.ent.ti.com (128.247.5.110) with Microsoft SMTP Server id 14.3.294.0; Fri, 21 Apr 2017 04:51:33 -0500 Received: from jadmar.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep33.itg.ti.com (8.14.3/8.13.8) with ESMTP id v3L9pNAx015129; Fri, 21 Apr 2017 04:51:31 -0500 From: Jyri Sarha To: Subject: [PATCH RFC 3/6] drm: Plane YCbCr to RGB conversion related properties Date: Fri, 21 Apr 2017 12:51:14 +0300 Message-ID: <3f25532ae9b05c34996fc9657261b204c627e232.1492768073.git.jsarha@ti.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: References: MIME-Version: 1.0 Cc: Liviu.Dudau@arm.com, Jyri Sarha , tomi.valkeinen@ti.com, laurent.pinchart@ideasonboard.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add standard properties to control YCbCr to RGB conversion in DRM planes. The created properties are stored to drm_plane object to allow different set of supported conversion modes for different planes on the device. For simplicity the related property blobs for CSC matrix and YCbCr preoffsets are also stored in the same place. The blob contents are defined in the uapi/drm/drm_mode.h header. Signed-off-by: Jyri Sarha --- drivers/gpu/drm/drm_atomic.c | 26 +++++++ drivers/gpu/drm/drm_atomic_helper.c | 9 +++ drivers/gpu/drm/drm_color_mgmt.c | 136 +++++++++++++++++++++++++++++++++++- drivers/gpu/drm/drm_plane.c | 10 +++ include/drm/drm_color_mgmt.h | 23 ++++++ include/drm/drm_plane.h | 10 +++ include/uapi/drm/drm_mode.h | 12 ++++ 7 files changed, 223 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index f881319..d1512aa 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -732,6 +732,8 @@ int drm_atomic_plane_set_property(struct drm_plane *plane, { struct drm_device *dev = plane->dev; struct drm_mode_config *config = &dev->mode_config; + int ret; + bool dummy; if (property == config->prop_fb_id) { struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, val); @@ -774,6 +776,22 @@ int drm_atomic_plane_set_property(struct drm_plane *plane, state->rotation = val; } else if (property == plane->zpos_property) { state->zpos = val; + } else if (property == plane->ycbcr_to_rgb_mode_property) { + state->ycbcr_to_rgb_mode = val; + } else if (property == plane->ycbcr_to_rgb_csc_property) { + ret = drm_atomic_replace_property_blob_from_id(dev, + &state->ycbcr_to_rgb_csc, + val, + sizeof(struct drm_ycbcr_to_rgb_csc), + &dummy); + return ret; + } else if (property == plane->ycbcr_to_rgb_preoffset_property) { + ret = drm_atomic_replace_property_blob_from_id(dev, + &state->ycbcr_to_rgb_preoffset, + val, + sizeof(struct drm_ycbcr_to_rgb_preoffset), + &dummy); + return ret; } else if (plane->funcs->atomic_set_property) { return plane->funcs->atomic_set_property(plane, state, property, val); @@ -834,6 +852,14 @@ int drm_atomic_plane_set_property(struct drm_plane *plane, *val = state->rotation; } else if (property == plane->zpos_property) { *val = state->zpos; + } else if (property == plane->ycbcr_to_rgb_mode_property) { + *val = state->ycbcr_to_rgb_mode; + } else if (property == plane->ycbcr_to_rgb_csc_property) { + *val = state->ycbcr_to_rgb_csc ? + state->ycbcr_to_rgb_csc->base.id : 0; + } else if (property == plane->ycbcr_to_rgb_preoffset_property) { + *val = state->ycbcr_to_rgb_preoffset ? + state->ycbcr_to_rgb_preoffset->base.id : 0; } else if (plane->funcs->atomic_get_property) { return plane->funcs->atomic_get_property(plane, state, property, val); } else { diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index c3994b4..89fd826 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3196,6 +3196,12 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, { memcpy(state, plane->state, sizeof(*state)); + if (state->ycbcr_to_rgb_csc) + drm_property_blob_get(state->ycbcr_to_rgb_csc); + + if (state->ycbcr_to_rgb_preoffset) + drm_property_blob_get(state->ycbcr_to_rgb_preoffset); + if (state->fb) drm_framebuffer_get(state->fb); @@ -3236,6 +3242,9 @@ struct drm_plane_state * */ void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state) { + drm_property_blob_put(state->ycbcr_to_rgb_csc); + drm_property_blob_put(state->ycbcr_to_rgb_preoffset); + if (state->fb) drm_framebuffer_put(state->fb); diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index cc23b9a..badaddd 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -29,9 +29,14 @@ /** * DOC: overview * - * Color management or color space adjustments is supported through a set of 5 - * properties on the &drm_crtc object. They are set up by calling - * drm_crtc_enable_color_mgmt(). + * Color management or color space adjustments in CRTCs is supported + * through a set of 5 properties on the &drm_crtc object. They are set + * up by calling drm_crtc_enable_color_mgmt(). + * + * Color space conversions from YCbCr to RGB color space in planes is + * supporter trough 3 optional properties in &drm_plane object. + * + * The &drm_crtc object's properties are: * * "DEGAMMA_LUT”: * Blob property to set the degamma lookup table (LUT) mapping pixel data @@ -85,6 +90,28 @@ * drm_mode_crtc_set_gamma_size(). Drivers which support both should use * drm_atomic_helper_legacy_gamma_set() to alias the legacy gamma ramp with the * "GAMMA_LUT" property above. + * + * The &drm_plane object's properties are: + * + * "YCBCR_TO_RGB_MODE" + * Optional plane enum property to configure YCbCr to RGB + * conversion. The possible modes include a number of standard + * conversions and a possibility to select custom conversion + * matrix and preoffset vector. The driver should select the + * supported subset of of the modes. + * + * "YCBCR_TO_RGB_CSC" + * Optional plane property blob to set YCbCr to RGB conversion + * matrix. The blob contains struct drm_ycbcr_to_rgb_csc which is + * defined in uapi/drm/drm_mode.h. Whether this property is + * active dependent on YCBCR_TO_RGB_MODE property. + * + * "YCBCR_TO_RGB_PREOFFSET" + * Optional plane property blob to configure YCbCr offset before + * YCbCr to RGB CSC is applied. The blob contains struct + * drm_ycbcr_to_rgb_preoffset which is defined in + * uapi/drm/drm_mode.h. Whether this property is active dependent + * on YCBCR_TO_RGB_MODE property. */ /** @@ -330,3 +357,106 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev, drm_modeset_unlock_all(dev); return ret; } + +static char *ycbcr_to_rgb_mode_name[] = { + [DRM_PLANE_YCBCR_BT601_LIM_TO_RGB_BT601_FULL] = + "YCbCr BT.601 limited range TO RGB BT.601 full range", + [DRM_PLANE_YCBCR_BT601_FULL_TO_RGB_BT601_FULL] = + "YCbCr BT.601 full range TO RGB BT.601 full range", + [DRM_PLANE_YCBCR_BT709_LIM_TO_RGB_BT709_FULL] = + "YCbCr BT.709 limited range TO RGB BT.709 full range", + [DRM_PLANE_YCBCR_BT2020_LIM_TO_RGB_BT2020_FULL] = + "YCbCr BT.2020 limited range TO RGB BT.2020 full range", + [DRM_PLANE_YCBCR_BT601_LIM_TO_RGB_BT709_FULL] = + "YCbCr BT.601 limited range TO RGB BT.709 full range", + [DRM_PLANE_YCBCR_BT601_LIM_TO_RGB_BT2020_FULL] = + "YCbCr BT.601 limited range TO RGB BT.2020 full range", + [DRM_PLANE_YCBCR_BT709_LIM_TO_RGB_BT601_FULL] = + "YCbCr BT.709 limited range TO RGB BT.601 full range", + [DRM_PLANE_YCBCR_BT709_LIM_TO_RGB_BT2020_FULL] = + "YCbCr BT.709 limited range TO RGB BT.2020 full range", + [DRM_PLANE_YCBCR_BT2020_LIM_TO_RGB_BT601_FULL] = + "YCbCr BT.2020 limited range TO RGB BT.601 full range", + [DRM_PLANE_YCBCR_BT2020_LIM_TO_RGB_BT709_FULL] = + "YCbCr BT.2020 limited range TO RGB BT.709 full range", + [DRM_PLANE_YCBCR_TO_RGB_CSC_LIM_PREOFFSET] = + "YCbCr TO RGB CSC limited range preoffset", + [DRM_PLANE_YCBCR_TO_RGB_CSC_FULL_PREOFFSET] = + "YCbCr TO RGB CSC full range preoffset", + [DRM_PLANE_YCBCR_TO_RGB_CSC_PREOFFSET_VECTOR] = + "YCBCR TO RGB CSC preoffset vector", +}; + +/** + * drm_plane_create_ycbcr_to_rgb_properties - ycbcr to rgb related properties + * @enum_list: drm_prop_enum_list array of supported modes without names + * @enum_list_len: length of enum_list array + * @default_mode: default csc mode + * + * Create and attach plane specific YCbCr to RGB conversion related + * properties to to the drm_plane object. The YCBCR_TO_RGB_MODE propety + * created and an the supported modes should be provided the enum_list + * parameter. YCBCR_TO_RGB_CSC and YCBCR_TO_RGB_PREOFFSET properties are + * created based on supported conversion modes. The enum_list parameter + * should not contain the enum names, because the standard names are + * added by this function. + */ +int drm_plane_create_ycbcr_to_rgb_properties(struct drm_plane *plane, + struct drm_prop_enum_list *enum_list, + unsigned int enum_list_len, + enum drm_plane_ycbcr_to_rgb_mode default_mode) +{ + struct drm_device *dev = plane->dev; + struct drm_property *prop; + bool ycbcr_to_rgb_csc_create = false; + bool ycbcr_to_rgb_preoffset_create = false; + int i; + + if (WARN_ON(plane->ycbcr_to_rgb_mode_property != NULL)) + return -EEXIST; + + for (i = 0; i < enum_list_len; i++) { + enum drm_plane_ycbcr_to_rgb_mode mode = enum_list[i].type; + + enum_list[i].name = ycbcr_to_rgb_mode_name[mode]; + + if (mode == DRM_PLANE_YCBCR_TO_RGB_CSC_LIM_PREOFFSET || + mode == DRM_PLANE_YCBCR_TO_RGB_CSC_FULL_PREOFFSET) + ycbcr_to_rgb_csc_create = true; + + if (mode == DRM_PLANE_YCBCR_TO_RGB_CSC_PREOFFSET_VECTOR) { + ycbcr_to_rgb_csc_create = true; + ycbcr_to_rgb_preoffset_create = true; + } + } + + prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, + "YCBCR_TO_RGB_MODE", + enum_list, enum_list_len); + if (!prop) + return -ENOMEM; + plane->ycbcr_to_rgb_mode_property = prop; + drm_object_attach_property(&plane->base, prop, default_mode); + + if (ycbcr_to_rgb_csc_create) { + prop = drm_property_create(dev, DRM_MODE_PROP_ATOMIC | + DRM_MODE_PROP_BLOB, + "YCBCR_TO_RGB_CSC", 0); + if (!prop) + return -ENOMEM; + plane->ycbcr_to_rgb_csc_property = prop; + drm_object_attach_property(&plane->base, prop, 0); + } + + if (ycbcr_to_rgb_preoffset_create) { + prop = drm_property_create(dev, DRM_MODE_PROP_ATOMIC | + DRM_MODE_PROP_BLOB, + "YCBCR_TO_RGB_PREOFFSET", 0); + if (!prop) + return -ENOMEM; + plane->ycbcr_to_rgb_preoffset_property = prop; + drm_object_attach_property(&plane->base, prop, 0); + } + + return 0; +} diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index bc71aa2..4c7e827 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -244,6 +244,16 @@ void drm_plane_cleanup(struct drm_plane *plane) kfree(plane->name); + if (plane->ycbcr_to_rgb_mode_property) + drm_property_destroy(dev, plane->ycbcr_to_rgb_mode_property); + + if (plane->ycbcr_to_rgb_csc_property) + drm_property_destroy(dev, plane->ycbcr_to_rgb_csc_property); + + if (plane->ycbcr_to_rgb_preoffset_property) + drm_property_destroy(dev, + plane->ycbcr_to_rgb_preoffset_property); + memset(plane, 0, sizeof(*plane)); } EXPORT_SYMBOL(drm_plane_cleanup); diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index 03a59cb..a20b3ff 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -26,6 +26,8 @@ #include struct drm_crtc; +struct drm_plane; +struct drm_prop_enum_list; uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision); @@ -37,4 +39,25 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size); +enum drm_plane_ycbcr_to_rgb_mode { + DRM_PLANE_YCBCR_BT601_LIM_TO_RGB_BT601_FULL = 0, + DRM_PLANE_YCBCR_BT601_FULL_TO_RGB_BT601_FULL, + DRM_PLANE_YCBCR_BT709_LIM_TO_RGB_BT709_FULL, + DRM_PLANE_YCBCR_BT2020_LIM_TO_RGB_BT2020_FULL, + DRM_PLANE_YCBCR_BT601_LIM_TO_RGB_BT709_FULL, + DRM_PLANE_YCBCR_BT601_LIM_TO_RGB_BT2020_FULL, + DRM_PLANE_YCBCR_BT709_LIM_TO_RGB_BT601_FULL, + DRM_PLANE_YCBCR_BT709_LIM_TO_RGB_BT2020_FULL, + DRM_PLANE_YCBCR_BT2020_LIM_TO_RGB_BT601_FULL, + DRM_PLANE_YCBCR_BT2020_LIM_TO_RGB_BT709_FULL, + DRM_PLANE_YCBCR_TO_RGB_CSC_LIM_PREOFFSET, + DRM_PLANE_YCBCR_TO_RGB_CSC_FULL_PREOFFSET, + DRM_PLANE_YCBCR_TO_RGB_CSC_PREOFFSET_VECTOR, +}; + +int drm_plane_create_ycbcr_to_rgb_properties(struct drm_plane *plane, + struct drm_prop_enum_list *enum_list, + unsigned int enum_list_len, + enum drm_plane_ycbcr_to_rgb_mode default_mode); + #endif diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 9ab3e70..41dcde2 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -26,6 +26,7 @@ #include #include #include +#include struct drm_crtc; struct drm_printer; @@ -112,6 +113,11 @@ struct drm_plane_state { unsigned int zpos; unsigned int normalized_zpos; + /* YCbCr to RGB conversion */ + enum drm_plane_ycbcr_to_rgb_mode ycbcr_to_rgb_mode; + struct drm_property_blob *ycbcr_to_rgb_csc; + struct drm_property_blob *ycbcr_to_rgb_preoffset; + /* Clipped coordinates */ struct drm_rect src, dst; @@ -523,6 +529,10 @@ struct drm_plane { struct drm_property *zpos_property; struct drm_property *rotation_property; + + struct drm_property *ycbcr_to_rgb_mode_property; + struct drm_property *ycbcr_to_rgb_csc_property; + struct drm_property *ycbcr_to_rgb_preoffset_property; }; #define obj_to_plane(x) container_of(x, struct drm_plane, base) diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 8c67fc0..27e0bee 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -543,6 +543,18 @@ struct drm_color_lut { __u16 reserved; }; +struct drm_ycbcr_to_rgb_csc { + /* Conversion matrix in 2-complement s32.32 format. */ + __s64 ry, rcb, rcr; + __s64 gy, gcb, gcr; + __s64 by, bcb, bcr; +}; + +struct drm_ycbcr_to_rgb_preoffset { + /* Offset vector in 2-complement s.32 format. */ + __s32 y, cb, cr; +}; + #define DRM_MODE_PAGE_FLIP_EVENT 0x01 #define DRM_MODE_PAGE_FLIP_ASYNC 0x02 #define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4