From: Shashank Sharma <shashank.sha...@intel.com>

In valleyview we have two pipe level color correction
properties:
1. CSC correction (wide gamut)
2. Gamma correction

What this patch does:
1. This patch adds software infrastructure to register pipe level
   color correction properties per CRTC. Adding a new function,
   intel_attach_pipe_color_correction to register the pipe level
   color correction properties with the given CRTC.
2. Adding a pointer in intel_crtc structure to store this property.
3. Adding structure gen6_pipe_color_corrections, which contains different
   pipe level correction values for VLV.

Signed-off-by: Shashank Sharma <shashank.sha...@intel.com>
---
 drivers/gpu/drm/i915/intel_clrmgr.c | 148 ++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_clrmgr.h |  64 ++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h    |   3 +
 3 files changed, 215 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_clrmgr.c 
b/drivers/gpu/drm/i915/intel_clrmgr.c
index 09a168d..8d02a62 100644
--- a/drivers/gpu/drm/i915/intel_clrmgr.c
+++ b/drivers/gpu/drm/i915/intel_clrmgr.c
@@ -33,6 +33,154 @@
 #include "i915_reg.h"
 #include "intel_clrmgr.h"
 
+/*
+  * Gen 6 SOC allows following color correction values:
+  *    - CSC(wide gamut) with 3x3 matrix = 9 csc correction values.
+  *    - Gamma correction with 128 gamma values.
+  */
+struct clrmgr_property gen6_pipe_color_corrections[] = {
+       {
+               .tweak_id = csc,
+               .type = DRM_MODE_PROP_BLOB,
+               .len = VLV_CSC_MATRIX_MAX_VALS,
+               .name = "csc-correction",
+       },
+       {
+               .tweak_id = gamma,
+               .type = DRM_MODE_PROP_BLOB,
+               .len = VLV_10BIT_GAMMA_MAX_VALS,
+               .name = "gamma-correction",
+       },
+};
+
+struct drm_property *intel_clrmgr_register(struct drm_device *dev,
+       struct drm_mode_object *obj, struct clrmgr_property *cp)
+{
+       struct drm_property *property;
+
+       /* Create drm property */
+       switch (cp->type) {
+       case DRM_MODE_PROP_BLOB:
+               property = drm_property_create(dev, DRM_MODE_PROP_BLOB,
+                       cp->name, cp->len);
+               if (!property) {
+                       DRM_ERROR("Failed to create property %s\n", cp->name);
+                       goto error;
+               }
+               break;
+
+       case DRM_MODE_PROP_RANGE:
+               property = drm_property_create_range(dev, DRM_MODE_PROP_RANGE,
+                       cp->name, cp->min, cp->max);
+               if (!property) {
+                       DRM_ERROR("Failed to create property %s\n", cp->name);
+                       goto error;
+               }
+               break;
+
+       default:
+               DRM_ERROR("Unsupported type for property %s\n", cp->name);
+               goto error;
+       }
+       /* Attach property to object */
+       drm_object_attach_property(obj, property, 0);
+       DRM_DEBUG_DRIVER("Registered property %s\n", property->name);
+       return property;
+
+error:
+       DRM_ERROR("Failed to create property %s\n", cp->name);
+       return NULL;
+}
+
+bool intel_clrmgr_register_pipe_property(struct intel_crtc *intel_crtc,
+               struct clrmgr_reg_request *features)
+
+{
+       u32 count = 0;
+       struct clrmgr_property *cp;
+       struct clrmgr_regd_prop *regd_property;
+       struct drm_property *property;
+       struct drm_device *dev = intel_crtc->base.dev;
+       struct drm_mode_object *obj = &intel_crtc->base.base;
+       struct clrmgr_status *status = intel_crtc->color_status;
+
+       /* Color manager initialized? */
+       if (!status) {
+               DRM_ERROR("Register request without pipe init ?\n");
+               return false;
+       }
+
+       /* Validate input */
+       if (!features || !features->no_of_properties) {
+               DRM_ERROR("Invalid input to color manager register\n");
+               return false;
+       }
+
+       /* Create drm property */
+       while (count < features->no_of_properties) {
+               cp = &features->cp[count++];
+               property = intel_clrmgr_register(dev, obj, cp);
+               if (!property) {
+                       DRM_ERROR("Failed to register property %s\n",
+                               property->name);
+                       goto error;
+               }
+
+               /* Add the property in global pipe status */
+               regd_property = kzalloc(sizeof(struct clrmgr_regd_prop),
+                                                       GFP_KERNEL);
+               regd_property->property = property;
+               regd_property->enabled = false;
+               regd_property->set_property = cp->set_property;
+               status->cp[status->no_of_properties++] = regd_property;
+       }
+       /* Successfully registered all */
+       DRM_DEBUG_DRIVER("Registered color properties on pipe %c\n",
+               pipe_name(intel_crtc->pipe));
+       return true;
+
+error:
+       if (--count) {
+               DRM_ERROR("Partial register, can only register:\n");
+               while (count--)
+                       DRM_ERROR("%s", status->cp[count]->property->name);
+       } else
+               DRM_ERROR("Can not register any property\n");
+       return false;
+}
+
+void
+intel_attach_pipe_color_correction(struct intel_crtc *intel_crtc)
+{
+       struct clrmgr_reg_request *features;
+
+       /* Color manager initialized? */
+       if (!intel_crtc->color_status) {
+               DRM_ERROR("Color manager not initialized for PIPE %d\n",
+                       intel_crtc->pipe);
+               return;
+       }
+
+       features = kzalloc(sizeof(struct clrmgr_reg_request), GFP_KERNEL);
+       if (!features) {
+               DRM_ERROR("No memory for pipe color features\n");
+               return;
+       }
+
+       features->no_of_properties = ARRAY_SIZE(gen6_pipe_color_corrections);
+       memcpy(features->cp, gen6_pipe_color_corrections,
+                       features->no_of_properties *
+                               sizeof(struct clrmgr_property));
+
+       /* Register pipe level color properties */
+       if (!intel_clrmgr_register_pipe_property(intel_crtc, features))
+               DRM_ERROR("Register pipe color property failed\n");
+       else
+               DRM_DEBUG_DRIVER("Attached colot corrections for pipe %d\n",
+               intel_crtc->pipe);
+       kfree(features);
+}
+
 struct clrmgr_status *intel_clrmgr_init(struct drm_device *dev)
 {
        struct clrmgr_status *status;
diff --git a/drivers/gpu/drm/i915/intel_clrmgr.h 
b/drivers/gpu/drm/i915/intel_clrmgr.h
index 6a36c8d..7cb2798 100644
--- a/drivers/gpu/drm/i915/intel_clrmgr.h
+++ b/drivers/gpu/drm/i915/intel_clrmgr.h
@@ -37,6 +37,25 @@
 
 /* Framework defs */
 #define CLRMGR_PROP_MAX                                10
+#define CLRMGR_PROP_NAME_MAX                           128
+
+/* CSC / Wide gamut */
+#define VLV_CSC_MATRIX_MAX_VALS                        9
+
+/* VLV specific gamma correction defines */
+#define VLV_10BIT_GAMMA_MAX_INDEX                      128
+#define CLRMGR_GAMMA_GCMAX_VAL                         1
+#define VLV_10BIT_GAMMA_MAX_VALS               (VLV_10BIT_GAMMA_MAX_INDEX + \
+                                               CLRMGR_GAMMA_GCMAX_VAL)
+
+/* Color manager features */
+enum clrmgr_tweaks {
+       csc = 0,
+       gamma,
+       contrast,
+       brightness,
+       hue_saturation,
+};
 
 /*
 * clrmgr_regd_propery structure
@@ -55,12 +74,57 @@ struct clrmgr_regd_prop {
                struct clrmgr_regd_prop *prop, u64 *data);
 };
 
+/*
+* clrmgr_propery structure
+* This structure encapsulates drm_property with other
+* values required during the property registration time.
+*/
+struct clrmgr_property {
+       enum clrmgr_tweaks tweak_id;
+       u32 type;
+       u32 len;
+       u64 min;
+       u64 max;
+       char name[CLRMGR_PROP_NAME_MAX];
+
+       bool (*set_property)(void *,
+               struct clrmgr_regd_prop *, u64 *);
+};
+
 /* Status of color properties on pipe at any time */
 struct clrmgr_status {
        u32 no_of_properties;
        struct clrmgr_regd_prop *cp[CLRMGR_PROP_MAX];
 };
 
+/*
+* Request to register a color property
+* This contains array of properties to be registered
+* and one count for no of properties
+*/
+struct clrmgr_reg_request {
+       u32 no_of_properties;
+       struct clrmgr_property cp[CLRMGR_PROP_MAX];
+};
+
+/*
+* intel_clrmgr_register_pipe_property
+* register set of properties with a CRTC
+* input:
+* - intel_crtc: the CRTC to register properies with
+* - features: set of color correction features to register
+*/
+bool intel_clrmgr_register_pipe_property(struct intel_crtc *intel_crtc,
+               struct clrmgr_reg_request *features);
+
+/*
+* intel_attach_pipe_color_correction:
+* Register color correction properties as DRM CRTC properties
+* input:
+* - intel_crtc : CRTC to attach color correcection with
+*/
+void
+intel_attach_pipe_color_correction(struct intel_crtc *intel_crtc);
 
 /*
 * intel_clrmgr_init:
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index fada887..698801a 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -428,6 +428,9 @@ struct intel_crtc {
 
        int scanline_offset;
        struct intel_mmio_flip mmio_flip;
+
+       /* color-correction */
+       struct clrmgr_status *color_status;
 };
 
 struct intel_plane_wm_parameters {
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to