@@ -654,6 +654,53 @@ intel_attach_pipe_color_correction(struct intel_crtc *intel_crtc)
kfree(features);
}
+bool intel_clrmgr_set_plane_property(struct intel_plane *intel_plane,
+ struct clrmgr_regd_prop *cp, uint64_t value)
+{
+ bool ret = false;
+ uint64_t *data;
+ struct drm_property *property;
+
+ /* Sanity */
+ if (!cp->property) {
+ DRM_ERROR("NULL input to set_property\n");
+ return false;
+ }
+
+ property = cp->property;
+ DRM_DEBUG_DRIVER("Property %s len:%d\n",
+ cp->property->name, cp->property->num_values);
+ data = kmalloc(sizeof(uint64_t) * (property->num_values), GFP_KERNEL);
+ if (!data) {
+ DRM_ERROR("Out of memory\n");
+ return false;
+ }
+
+ if (copy_from_user((void *)data, (const void __user *)value,
+ property->num_values * sizeof(uint64_t))) {
+ DRM_ERROR("Failed to copy all data\n");
+ ret = false;
+ goto free_and_return;
+ }
+
+ /* Now do the actual work */
+ if (cp->set_property) {
+ if (!cp->set_property((void *)intel_plane, cp, data)) {
+ DRM_ERROR("Set property for %s failed\n",
+ cp->property->name);
+ ret = false;
+ } else {
+ ret = true;
+ cp->enabled = true;
+ DRM_DEBUG_DRIVER("Set property %s successful\n",
+ cp->property->name);
+ }
+ }
+free_and_return:
+ kfree(data);
+ return ret;
+}
+
bool intel_clrmgr_set_pipe_property(struct intel_crtc *intel_crtc,
struct clrmgr_regd_prop *cp, uint64_t value)
{
@@ -212,6 +212,17 @@ bool intel_clrmgr_set_csc(void *crtc,
struct clrmgr_regd_prop *csc, u64 *data);
/*
+* intel_clrmgr_set_plane_property
+* Set value of a registered plane property
+* input:
+* - intel_plane: the plane with which the property is attached
+* - cp: registered color property
+* - value: value to be set
+*/
+bool intel_clrmgr_set_plane_property(struct intel_plane *intel_plane,
+ struct clrmgr_regd_prop *cp, uint64_t value);
+
+/*
* intel_clrmgr_set_pipe_property
* Set value of a registered CRTC property
* input:
@@ -36,6 +36,7 @@
#include "intel_drv.h"
#include <drm/i915_drm.h>
#include "i915_drv.h"
+#include "intel_clrmgr.h"
static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs)
{
@@ -1180,6 +1181,45 @@ out_unlock:
return ret;
}
+int intel_plane_set_property(struct drm_plane *plane,
+ struct drm_property *property, uint64_t val)
+{
+ int ret = 0;
+ int count = 0;
+ struct clrmgr_regd_prop *cp;
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ struct clrmgr_status *status = intel_plane->color_status;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ /* Is this color property ?*/
+ if (!status) {
+ DRM_DEBUG_DRIVER("Color manager not initialized\n");
+ ret = -1;
+ goto skip_color;
+ }
+
+ /* Color manager property */
+ while (count < status->no_of_properties) {
+ cp = status->cp[count++];
+ if (property == cp->property) {
+ /* Found it, now set it */
+ if (intel_clrmgr_set_plane_property(intel_plane,
+ cp, val)) {
+ DRM_DEBUG_DRIVER("Set property %s successful\n",
+ property->name);
+ return 0;
+ } else {
+ DRM_ERROR("Set CRTC property %s failed\n",
+ property->name);
+ return -1;
+ }
+ }
+ }
+skip_color:
+ return ret;
+}
+
void intel_plane_restore(struct drm_plane *plane)
{
struct intel_plane *intel_plane = to_intel_plane(plane);
@@ -1206,6 +1246,7 @@ static const struct drm_plane_funcs intel_plane_funcs = {
.update_plane = intel_update_plane,
.disable_plane = intel_disable_plane,
.destroy = intel_destroy_plane,
+ .set_property = intel_plane_set_property
};
static uint32_t ilk_plane_formats[] = {