From: "NĂcolas F. R. A. Prado" <[email protected]> Introduce DRM_CLIENT_CAP_CRTC_COLOR_PIPELINE which a DRM client can set to enable the usage of CRTC (post-blend) color pipelines instead of the now deprecated CRTC color management properties: "GAMMA_LUT", "DEGAMMA_LUT" and "CTM".
Signed-off-by: NĂcolas F. R. A. Prado <[email protected]> Co-developed-by: Ariel D'Alessandro <[email protected]> Signed-off-by: Ariel D'Alessandro <[email protected]> Reviewed-by: Louis Chauvet <[email protected]> --- drivers/gpu/drm/drm_atomic_uapi.c | 20 ++++++++++++++++++++ drivers/gpu/drm/drm_connector.c | 1 + drivers/gpu/drm/drm_crtc_internal.h | 1 + drivers/gpu/drm/drm_ioctl.c | 9 +++++++++ drivers/gpu/drm/drm_mode_object.c | 9 +++++++++ include/drm/drm_file.h | 7 +++++++ include/uapi/drm/drm.h | 19 +++++++++++++++++++ 7 files changed, 66 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 07d0d224fe58c..d1bc78b2567a9 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -433,6 +433,11 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, if (property == config->prop_active) state->active = val; else if (property == crtc->color_pipeline_property) { + if (!file_priv->crtc_color_pipeline) { + drm_dbg_atomic(dev, + "Setting COLOR_PIPELINE CRTC property not permitted without DRM_CLIENT_CAP_CRTC_COLOR_PIPELINE client cap\n"); + return -EINVAL; + } /* find DRM colorop object */ struct drm_colorop *colorop = NULL; @@ -451,6 +456,11 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, } else if (property == config->prop_vrr_enabled) { state->vrr_enabled = val; } else if (property == config->degamma_lut_property) { + if (file_priv->crtc_color_pipeline) { + drm_dbg_atomic(dev, + "Setting DEGAMMA_LUT CRTC property not permitted with DRM_CLIENT_CAP_CRTC_COLOR_PIPELINE client cap\n"); + return -EINVAL; + } ret = drm_property_replace_blob_from_id(dev, &state->degamma_lut, val, @@ -459,6 +469,11 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, state->color_mgmt_changed |= replaced; return ret; } else if (property == config->ctm_property) { + if (file_priv->crtc_color_pipeline) { + drm_dbg_atomic(dev, + "Setting CTM CRTC property not permitted with DRM_CLIENT_CAP_CRTC_COLOR_PIPELINE client cap\n"); + return -EINVAL; + } ret = drm_property_replace_blob_from_id(dev, &state->ctm, val, @@ -467,6 +482,11 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, state->color_mgmt_changed |= replaced; return ret; } else if (property == config->gamma_lut_property) { + if (file_priv->crtc_color_pipeline) { + drm_dbg_atomic(dev, + "Setting GAMMA_LUT CRTC property not permitted with DRM_CLIENT_CAP_CRTC_COLOR_PIPELINE client cap\n"); + return -EINVAL; + } ret = drm_property_replace_blob_from_id(dev, &state->gamma_lut, val, diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 4d6dc9ebfdb5b..aec8a5c0d593a 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -3440,6 +3440,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data, */ ret = drm_mode_object_get_properties(&connector->base, file_priv->atomic, file_priv->plane_color_pipeline, + file_priv->crtc_color_pipeline, (uint32_t __user *)(unsigned long)(out_resp->props_ptr), (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr), &out_resp->count_props); diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index c094092296448..ab02e6295271d 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -164,6 +164,7 @@ void drm_mode_object_unregister(struct drm_device *dev, struct drm_mode_object *object); int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic, bool plane_color_pipeline, + bool crtc_color_pipeline, uint32_t __user *prop_ptr, uint64_t __user *prop_values, uint32_t *arg_count_props); diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 2884075660ddd..14746afd82783 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -383,6 +383,15 @@ drm_setclientcap(struct drm_device *dev, void *data, struct drm_file *file_priv) return -EINVAL; file_priv->plane_color_pipeline = req->value; break; + case DRM_CLIENT_CAP_CRTC_COLOR_PIPELINE: + if (!file_priv->atomic) + return -EINVAL; + if (req->value > 1) + return -EINVAL; + if (!drm_core_check_feature(dev, DRIVER_CRTC_COLOR_PIPELINE)) + return -EINVAL; + file_priv->crtc_color_pipeline = req->value; + break; default: return -EINVAL; } diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c index b45d501b10c86..ea4508f6a09a6 100644 --- a/drivers/gpu/drm/drm_mode_object.c +++ b/drivers/gpu/drm/drm_mode_object.c @@ -388,6 +388,7 @@ EXPORT_SYMBOL(drm_object_property_get_default_value); /* helper for getconnector and getproperties ioctls */ int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic, bool plane_color_pipeline, + bool crtc_color_pipeline, uint32_t __user *prop_ptr, uint64_t __user *prop_values, uint32_t *arg_count_props) @@ -416,6 +417,13 @@ int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic, continue; } + if (!crtc_color_pipeline && obj->type == DRM_MODE_OBJECT_CRTC) { + struct drm_crtc *crtc = obj_to_crtc(obj); + + if (prop == crtc->color_pipeline_property) + continue; + } + if (*arg_count_props > count) { ret = __drm_object_property_get_value(obj, prop, &val); if (ret) @@ -475,6 +483,7 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data, ret = drm_mode_object_get_properties(obj, file_priv->atomic, file_priv->plane_color_pipeline, + file_priv->crtc_color_pipeline, (uint32_t __user *)(unsigned long)(arg->props_ptr), (uint64_t __user *)(unsigned long)(arg->prop_values_ptr), &arg->count_props); diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h index 6ee70ad65e1fd..d0c323378ae46 100644 --- a/include/drm/drm_file.h +++ b/include/drm/drm_file.h @@ -214,6 +214,13 @@ struct drm_file { */ bool plane_color_pipeline; + /** + * @crtc_color_pipeline: + * + * True if client understands CRTC (post-blend) color pipelines + */ + bool crtc_color_pipeline; + /** * @was_master: * diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index d726828bdf408..991ef14c5377c 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -927,6 +927,25 @@ struct drm_get_cap { */ #define DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE 7 +/** + * DRM_CLIENT_CAP_CRTC_COLOR_PIPELINE + * + * If set to 1 the DRM core will allow setting the COLOR_PIPELINE + * property on a &drm_crtc, as well as drm_colorop properties. + * + * Setting of these crtc properties will be rejected when this client + * cap is set: + * - GAMMA_LUT + * - DEGAMMA_LUT + * - CTM + * + * The client must enable &DRM_CLIENT_CAP_ATOMIC first. + * + * This client cap can only be set if the driver sets the corresponding driver + * cap &DRM_CAP_CRTC_COLOR_PIPELINE. + */ +#define DRM_CLIENT_CAP_CRTC_COLOR_PIPELINE 8 + /* DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */ struct drm_set_client_cap { __u64 capability; -- 2.51.0
