From patchwork Fri Mar 30 01:02:45 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 7523 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 003FC23E00 for ; Fri, 30 Mar 2012 01:02:55 +0000 (UTC) Received: from mail-iy0-f180.google.com (mail-iy0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id 8A61AA186BA for ; Fri, 30 Mar 2012 01:02:55 +0000 (UTC) Received: by iage36 with SMTP id e36so301148iag.11 for ; Thu, 29 Mar 2012 18:02:55 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:x-forwarded-to:x-forwarded-for:delivered-to :received-spf:dkim-signature:sender:from:to:cc:subject:date :message-id:x-mailer:x-gm-message-state; bh=8nXHGi7wXPhG3mzRMGWlr/BSrTaiLlZ4Vbd90KyQlDw=; b=L3Z/twFFl4n5/YQgDZKLydg1BJj2A6nA23sv3g4RQ1gqz4dL/+eSuw/AfjBctfm5mz 5U5ls0ZK26MpIOINYCOYl75cFArzzdRM8YZRs9lz6Es42Ym3KI6OIr9t26QOBwyFakjX tF48HbSF5vvndcIrtZz02qyWlE7XV/GETpffAq7qsttj+6dTpLvh2W4fijTuqJyzhd7P bbmEUP+oSVqWaREp9MTjXXYw0B/xSsRoepNahbY57ovqde6ZkdWfhM08K89ZM4B5jGnf OSyNympPzM8GArxIVtwjma9ecb0hbzAKV/ORPCvwzb3kNPE05050EjvW496vtweHt4wS lcaw== MIME-Version: 1.0 Received: by 10.42.137.67 with SMTP id x3mr100538ict.52.1333069374975; Thu, 29 Mar 2012 18:02:54 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.5.205 with SMTP id 13csp1655ibw; Thu, 29 Mar 2012 18:02:54 -0700 (PDT) Received: by 10.182.154.5 with SMTP id vk5mr293606obb.24.1333069374203; Thu, 29 Mar 2012 18:02:54 -0700 (PDT) Received: from mail-ob0-f178.google.com (mail-ob0-f178.google.com [209.85.214.178]) by mx.google.com with ESMTPS id v6si5050200obc.103.2012.03.29.18.02.53 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 29 Mar 2012 18:02:54 -0700 (PDT) Received-SPF: pass (google.com: domain of robdclark@gmail.com designates 209.85.214.178 as permitted sender) client-ip=209.85.214.178; Authentication-Results: mx.google.com; spf=pass (google.com: domain of robdclark@gmail.com designates 209.85.214.178 as permitted sender) smtp.mail=robdclark@gmail.com; dkim=pass header.i=@gmail.com Received: by obbtb18 with SMTP id tb18so258501obb.37 for ; Thu, 29 Mar 2012 18:02:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer; bh=8nXHGi7wXPhG3mzRMGWlr/BSrTaiLlZ4Vbd90KyQlDw=; b=zdjLXo1oyww+oO+MouLe+LxTAPRgFYkygWC8clJdcui9uIWasj0N3PAKU5BpPKqZLG v/GczAqOqaoYk4bBY6V3J9imLt8cvbFZ0tYg7PexCkfIh8y8+WAPihuEmssjlAjpE+pR blHNxL2IX+6kziCQWYEwVI2fU85iOpP+EHGsM3/VkIiiC+Wceclj++Mlk5Sp33QL4lbE 1BQTyEhzlkn2xtJC4wj2tbxwnUWG5vzEKOhgpBy61PILdHrvqcU+1DjnOg58+dQIEPO0 563MbP8xvYWOXmHKXXy8UAJEeF1YB3tJJX7FpLtKZiaDEKi0YUAyRjzb0Fb0bCyfSBxB Kupg== Received: by 10.182.162.38 with SMTP id xx6mr260598obb.39.1333069373319; Thu, 29 Mar 2012 18:02:53 -0700 (PDT) Received: from localhost (ppp-70-129-134-19.dsl.rcsntx.swbell.net. [70.129.134.19]) by mx.google.com with ESMTPS id n10sm7765544obu.23.2012.03.29.18.02.51 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 29 Mar 2012 18:02:52 -0700 (PDT) Sender: Rob Clark From: Rob Clark To: dri-devel@lists.freedesktop.org Cc: patches@linaro.org, Rob Clark Subject: [PATCH RFC 1/2] drm: add bitmask property type Date: Thu, 29 Mar 2012 20:02:45 -0500 Message-Id: <1333069366-2774-1-git-send-email-rob.clark@linaro.org> X-Mailer: git-send-email 1.7.9.1 X-Gm-Message-State: ALoCoQn3KNFY/d8Q4wY9qLImF0FUwhb2byOJL9sVz1GNkKbpeiDQvI6ZU6uG9lfqve5UbuJa4srW From: Rob Clark A bitmask property is similar to an enum. The enum value is a bit position (0-63), and valid property values consist of a mask of zero or more of (1 << enum_val[n]). TODO: word commit msg better TODO: maybe "flags" would be a better name for the property type? --- See https://github.com/robclark/kernel-omap4/commit/970b7bb95993fc43b4977976bf8005dc2e1a4ad3#L6R411 for an example usage. In this case combinations of "x-invert", "y-invert" and "xy-flip" can express all possible combinations of rotations of multiples of 90 degrees plus mirroring. Which is sufficient for an xrandr v1.2 rotation support. For arbitrary transforms in xrandr v1.3 a different property with a transform matrix (if supported by the driver) should be used. Note: I've not finished updating libdrm and ddx driver to use this yet, so other than compile and boot test, you can consider this as untested. But I figure that it is at least worthwhile to send as an RFC at this point to get feedback. drivers/gpu/drm/drm_crtc.c | 46 +++++++++++++++++++++++++++++++++++++++++-- include/drm/drm_crtc.h | 3 ++ include/drm/drm_mode.h | 1 + 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 95c7ab2..2b462f6 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2713,6 +2713,33 @@ struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, } EXPORT_SYMBOL(drm_property_create_enum); +struct drm_property *drm_property_create_bitmask(struct drm_device *dev, + int flags, const char *name, + const struct drm_prop_enum_list *props, int num_values) +{ + struct drm_property *property; + int i, ret; + + flags |= DRM_MODE_PROP_BITMASK; + + property = drm_property_create(dev, flags, name, num_values); + if (!property) + return NULL; + + for (i = 0; i < num_values; i++) { + ret = drm_property_add_enum(property, i, + props[i].type, + props[i].name); + if (ret) { + drm_property_destroy(dev, property); + return NULL; + } + } + + return property; +} +EXPORT_SYMBOL(drm_property_create_bitmask); + struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, const char *name, uint64_t min, uint64_t max) @@ -2737,7 +2764,14 @@ int drm_property_add_enum(struct drm_property *property, int index, { struct drm_property_enum *prop_enum; - if (!(property->flags & DRM_MODE_PROP_ENUM)) + if (!(property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK))) + return -EINVAL; + + /* + * Bitmask enum properties have the additional constraint of values + * from 0 to 63 + */ + if ((property->flags & DRM_MODE_PROP_BITMASK) && (value > 63)) return -EINVAL; if (!list_empty(&property->enum_blob_list)) { @@ -2881,7 +2915,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, } property = obj_to_property(obj); - if (property->flags & DRM_MODE_PROP_ENUM) { + if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { list_for_each_entry(prop_enum, &property->enum_blob_list, head) enum_count++; } else if (property->flags & DRM_MODE_PROP_BLOB) { @@ -2906,7 +2940,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, } out_resp->count_values = value_count; - if (property->flags & DRM_MODE_PROP_ENUM) { + if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { if ((out_resp->count_enum_blobs >= enum_count) && enum_count) { copied = 0; enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr; @@ -3063,6 +3097,12 @@ static bool drm_property_change_is_valid(struct drm_property *property, if (value > property->values[1]) return false; return true; + } else if (property->flags & DRM_MODE_PROP_BITMASK) { + int i; + __u64 valid_mask = 0; + for (i = 0; i < property->num_values; i++) + valid_mask |= (1 << property->values[i]); + return !(value & ~valid_mask); } else { int i; for (i = 0; i < property->num_values; i++) diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 32e9c51..28e9a78 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -940,6 +940,9 @@ extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int const char *name, const struct drm_prop_enum_list *props, int num_values); +struct drm_property *drm_property_create_bitmask(struct drm_device *dev, + int flags, const char *name, + const struct drm_prop_enum_list *props, int num_values); struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, const char *name, uint64_t min, uint64_t max); diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index de5de2a..3190dfe 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h @@ -228,6 +228,7 @@ struct drm_mode_get_connector { #define DRM_MODE_PROP_IMMUTABLE (1<<2) #define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */ #define DRM_MODE_PROP_BLOB (1<<4) +#define DRM_MODE_PROP_BITMASK (1<<5) /* bitmask of enumerated types */ struct drm_mode_property_enum { __u64 value;