[PATCH igt v7 1/4] lib/tests: Add igt_assert_*() self-tests

2015-10-29 Thread Thomas Wood
On 29 October 2015 at 10:31, Daniel Stone  wrote:
> Make sure our igt_assert variants are doing something that looks vaguely
> like the right thing.
>
> Signed-off-by: Daniel Stone 
> ---
>  lib/tests/Makefile.sources |   1 +
>  lib/tests/igt_simple.c | 173 
> +
>  2 files changed, 174 insertions(+)
>  create mode 100644 lib/tests/igt_simple.c

The binary name needs to be added to lib/tests/.gitignore.

Also, "igt_assert" might be a more descriptive name for the test.


>
> diff --git a/lib/tests/Makefile.sources b/lib/tests/Makefile.sources
> index 58ae36b..fe5df6e 100644
> --- a/lib/tests/Makefile.sources
> +++ b/lib/tests/Makefile.sources
> @@ -10,6 +10,7 @@ check_PROGRAMS = \
> igt_timeout \
> igt_invalid_subtest_name \
> igt_segfault \
> +   igt_simple \
> $(NULL)
>
>  check_SCRIPTS = \
> diff --git a/lib/tests/igt_simple.c b/lib/tests/igt_simple.c
> new file mode 100644
> index 000..306b1fb
> --- /dev/null
> +++ b/lib/tests/igt_simple.c
> @@ -0,0 +1,173 @@
> +/*
> + * Copyright © 2015 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
> DEALINGS
> + * IN THE SOFTWARE.
> + *
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "igt_core.h"
> +
> +/*
> + * We need to hide assert from the cocci igt test refactor spatch.
> + *
> + * IMPORTANT: Test infrastructure tests are the only valid places where using
> + * assert is allowed.
> + */
> +#define internal_assert assert
> +
> +char test[] = "test";
> +char *argv_run[] = { test };
> +void (*test_to_run)(void) = NULL;
> +
> +/*
> + * A really tedious way of making sure we execute every negative test, and 
> that
> + * they all really fail.
> + */
> +#define CHECK_NEG(x) { \
> +   igt_subtest_f("XFAIL_simple_%d", __LINE__) { \
> +   (*exec_before)++; \
> +   x; \
> +   raise(SIGBUS); \
> +   } \
> +   exec_total++; \
> +}
> +
> +static int do_fork(void)
> +{
> +   int pid, status;
> +   int argc;
> +
> +   switch (pid = fork()) {
> +   case -1:
> +   internal_assert(0);
> +   case 0:
> +   argc = 1;
> +   igt_simple_init(argc, argv_run);
> +   test_to_run();
> +   igt_exit();
> +   default:
> +   while (waitpid(pid, , 0) == -1 &&
> +  errno == EINTR)
> +   ;
> +
> +   if(WIFSIGNALED(status))
> +   return WTERMSIG(status) + 128;
> +
> +   return WEXITSTATUS(status);
> +   }
> +}
> +
> +static void test_cmpint_negative(void)
> +{
> +   int *exec_before = calloc(1, sizeof(int));
> +   int exec_total = 0;
> +
> +   CHECK_NEG(igt_assert_eq(INT_MIN, INT_MAX));
> +
> +   CHECK_NEG(igt_assert_eq_u32(0xfffeUL, 0xUL));
> +
> +   CHECK_NEG(igt_assert_eq_u64(0xfffeULL, 
> 0xULL));
> +   CHECK_NEG(igt_assert_eq_u64(0xfffeULL, 
> 0xULL));
> +   CHECK_NEG(igt_assert_eq_u64(0xfffeULL, 
> 0xULL));
> +
> +   CHECK_NEG(igt_assert_eq_double(0.0, DBL_MAX));
> +   CHECK_NEG(igt_assert_eq_double(DBL_MAX, nexttoward(DBL_MAX, 0.0)));
> +
> +   if (*exec_before != exec_total)
> +   raise(SIGSEGV);
> +}
> +
> +static void test_cmpint(void)
> +{
> +   igt_assert_eq(0, 0);
> +   igt_assert_eq(INT_MAX, INT_MAX);
> +   igt_assert_eq(INT_MAX, INT_MAX);
> +   igt_assert_neq(INT_MIN, INT_MAX);
> +
> +   igt_assert_eq_u32(0, 0);
> +   igt_assert_eq_u32(0xUL, 0xUL);
> +   igt_assert_neq_u32(0xfffeUL, 0xUL);
> +
> +   igt_assert_eq_u64(0, 0);
> +   

[Intel-gfx] [PATCH i-g-t] tests/drm_hw_lock: Tests for hw_lock fixes.

2015-04-27 Thread Thomas Wood
On 23 April 2015 at 15:07, Peter Antoine  wrote:
> There are several issues with the hardware locks functions that stretch
> from kernel crashes to priority escalations. This new test will test the
> the fixes for these features.
>
> This test will cause a driver/kernel crash on un-patched kernels, the
> following patches should be applied to stop the crashes:
>
>   drm: Kernel Crash in drm_unlock
>   drm: Fixes unsafe deference in locks.
>
> Issue: VIZ-5485
> Signed-off-by: Peter Antoine 
> ---
>  lib/ioctl_wrappers.c   |  19 +
>  lib/ioctl_wrappers.h   |   1 +
>  tests/Makefile.sources |   1 +
>  tests/drm_hw_lock.c| 207 
> +
>  4 files changed, 228 insertions(+)
>  create mode 100644 tests/drm_hw_lock.c
>
> diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
> index 000d394..ad8b3d3 100644
> --- a/lib/ioctl_wrappers.c
> +++ b/lib/ioctl_wrappers.c
> @@ -964,6 +964,25 @@ bool gem_has_bsd2(int fd)
>  {
> return gem_has_enable_ring(fd,LOCAL_I915_PARAM_HAS_BSD2);
>  }
> +#define I915_PARAM_HAS_LEGACY_CONTEXT   35


Please add some API documentation for this new function here.

> +bool drm_has_legacy_context(int fd)
> +{
> +   int tmp = 0;
> +   drm_i915_getparam_t gp;
> +
> +   memset(, 0, sizeof(gp));
> +   gp.value = 
> +   gp.param = I915_PARAM_HAS_LEGACY_CONTEXT;
> +
> +   /*
> +* if legacy context param is not supported, then it's old and we
> +* can assume that the HW_LOCKS are supported.
> +*/
> +   if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, ) != 0)
> +   return true;
> +
> +   return tmp == 1;
> +}
>  /**
>   * gem_available_aperture_size:
>   * @fd: open i915 drm file descriptor
> diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
> index ced7ef3..3adc700 100644
> --- a/lib/ioctl_wrappers.h
> +++ b/lib/ioctl_wrappers.h
> @@ -120,6 +120,7 @@ bool gem_has_bsd(int fd);
>  bool gem_has_blt(int fd);
>  bool gem_has_vebox(int fd);
>  bool gem_has_bsd2(int fd);
> +bool drm_has_legacy_context(int fd);
>  bool gem_uses_aliasing_ppgtt(int fd);
>  int gem_available_fences(int fd);
>  uint64_t gem_available_aperture_size(int fd);
> diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> index 71de6de..2f69afc 100644
> --- a/tests/Makefile.sources
> +++ b/tests/Makefile.sources
> @@ -84,6 +84,7 @@ TESTS_progs_M = \
> pm_sseu \
> prime_self_import \
> template \
> +   drm_hw_lock \

Please also add the binary name to .gitignore.

> $(NULL)
>
>  TESTS_progs = \
> diff --git a/tests/drm_hw_lock.c b/tests/drm_hw_lock.c
> new file mode 100644
> index 000..aad50ba
> --- /dev/null
> +++ b/tests/drm_hw_lock.c
> @@ -0,0 +1,207 @@
> +/*
> + * Copyright © 2015 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
> DEALINGS
> + * IN THE SOFTWARE.
> + *
> + * Authors:
> + *Peter Antoine 
> + */
> +
> +/*
> + * Testcase: Test the HW_LOCKs for correct support and non-crashing.

This would be a good sentence to use in the IGT_TEST_DESCRIPTION
macro, to add a description for the test.


> + *
> + * This test will check that he hw_locks are only g_supported for drivers 
> that
> + * require that support. If it is not g_supported then the functions all 
> return
> + * the correct error code.
> + *
> + * If g_supported it will check that the functions do not crash when the 
> crash
> + * tests are used, also that one of the tests is a security level escalation
> + * that should be rejected.
> + */
> +#include 
> +#include 
> +#include 
> +#include 
> +#include "drmtest.h"
> +#include "igt_core.h"
> +#include "ioctl_wrappers.h"
> +
> +#ifndef DRM_KERNEL_CONTEXT
> +#  define DRM_KERNEL_CONTEXT   (0)
> +#endif
> +
> +#ifndef _DRM_LOCK_HELD
> +#  define _DRM_LOCK_HELD   0x8000U /**< Hardware lock is held */
> +#endif
> +
> +#ifndef _DRM_LOCK_CONT
> 

[PATCH libdrm 1/3] intel/skl: Add SKL PCI ids

2014-09-30 Thread Thomas Wood
On 26 September 2014 14:19, Damien Lespiau  wrote:
> v2: Add more PCI IDs (Michael H. Nguyen)
> v3: Synchronize one more with the kernel PCI IDs (Damien)
>
> Signed-off-by: Damien Lespiau 
> Signed-off-by: Ben Widawsky 
> Signed-off-by: Michael H. Nguyen 

Reviewed-by: Thomas Wood 

> ---
>  intel/intel_chipset.h | 43 ++-
>  1 file changed, 42 insertions(+), 1 deletion(-)
>
> diff --git a/intel/intel_chipset.h b/intel/intel_chipset.h
> index 6f9bfad..e22a867 100644
> --- a/intel/intel_chipset.h
> +++ b/intel/intel_chipset.h
> @@ -165,6 +165,22 @@
>  #define PCI_CHIP_CHERRYVIEW_2  0x22b2
>  #define PCI_CHIP_CHERRYVIEW_3  0x22b3
>
> +#define PCI_CHIP_SKYLAKE_ULT_GT2   0x1916
> +#define PCI_CHIP_SKYLAKE_ULT_GT1   0x1906
> +#define PCI_CHIP_SKYLAKE_ULT_GT3   0x1926
> +#define PCI_CHIP_SKYLAKE_ULT_GT2F  0x1921
> +#define PCI_CHIP_SKYLAKE_ULX_GT1   0x190E
> +#define PCI_CHIP_SKYLAKE_ULX_GT2   0x191E
> +#define PCI_CHIP_SKYLAKE_DT_GT20x1912
> +#define PCI_CHIP_SKYLAKE_DT_GT10x1902
> +#define PCI_CHIP_SKYLAKE_HALO_GT2  0x191B
> +#define PCI_CHIP_SKYLAKE_HALO_GT3  0x192B
> +#define PCI_CHIP_SKYLAKE_HALO_GT1  0x190B
> +#define PCI_CHIP_SKYLAKE_SRV_GT2   0x191A
> +#define PCI_CHIP_SKYLAKE_SRV_GT3   0x192A
> +#define PCI_CHIP_SKYLAKE_SRV_GT1   0x190A
> +#define PCI_CHIP_SKYLAKE_WKS_GT2   0x191D
> +
>  #define IS_MOBILE(devid)   ((devid) == PCI_CHIP_I855_GM || \
>  (devid) == PCI_CHIP_I915_GM || \
>  (devid) == PCI_CHIP_I945_GM || \
> @@ -324,12 +340,37 @@
>  #define IS_GEN8(devid) (IS_BROADWELL(devid) || \
>  IS_CHERRYVIEW(devid))
>
> +#define IS_SKL_GT1(devid)  ((devid) == PCI_CHIP_SKYLAKE_ULT_GT1|| \
> +(devid) == PCI_CHIP_SKYLAKE_ULX_GT1|| \
> +(devid) == PCI_CHIP_SKYLAKE_DT_GT1 || \
> +(devid) == PCI_CHIP_SKYLAKE_HALO_GT1   || \
> +(devid) == PCI_CHIP_SKYLAKE_SRV_GT1)
> +
> +#define IS_SKL_GT2(devid)  ((devid) == PCI_CHIP_SKYLAKE_ULT_GT2|| \
> +(devid) == PCI_CHIP_SKYLAKE_ULT_GT2F   || \
> +(devid) == PCI_CHIP_SKYLAKE_ULX_GT2|| \
> +(devid) == PCI_CHIP_SKYLAKE_DT_GT2 || \
> +(devid) == PCI_CHIP_SKYLAKE_HALO_GT2   || \
> +(devid) == PCI_CHIP_SKYLAKE_SRV_GT2|| \
> +(devid) == PCI_CHIP_SKYLAKE_WKS_GT2)
> +
> +#define IS_SKL_GT3(devid)  ((devid) == PCI_CHIP_SKYLAKE_ULT_GT3|| \
> +(devid) == PCI_CHIP_SKYLAKE_HALO_GT3   || \
> +(devid) == PCI_CHIP_SKYLAKE_SRV_GT3)
> +
> +#define IS_SKYLAKE(devid)  (IS_SKL_GT1(devid) || \
> +IS_SKL_GT2(devid) || \
> +IS_SKL_GT3(devid))
> +
> +#define IS_GEN9(devid) IS_SKYLAKE(devid)
> +
>  #define IS_9XX(dev)(IS_GEN3(dev) || \
>  IS_GEN4(dev) || \
>  IS_GEN5(dev) || \
>  IS_GEN6(dev) || \
>  IS_GEN7(dev) || \
> -IS_GEN8(dev))
> +IS_GEN8(dev) || \
> +IS_GEN9(dev))
>
>
>  #endif /* _INTEL_CHIPSET_H */
> --
> 1.8.3.1
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2] drm: fix plane rotation when restoring fbdev configuration

2014-08-20 Thread Thomas Wood
Make sure plane rotation is reset correctly when restoring the fbdev
configuration by using drm_mode_plane_set_obj_prop which calls the
driver's set_property callback.

The rotation reset feature was introduced in commit 9783de2 (drm:
Resetting rotation property) and the callback issue was originally
addressed in a previous version of the patch, but the fix was not
present in the final version.

v2: Fix documentation warning
Add some more details to the commit message (Daniel Vetter)

Testcase: igt/kms_rotation_crc
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82236
Cc: Sonika Jindal 
Cc: Ville Syrj?l? 
Cc: Dave Airlie 
Cc: Daniel Vetter 
Signed-off-by: Thomas Wood 
---
 drivers/gpu/drm/drm_crtc.c  | 25 -
 drivers/gpu/drm/drm_fb_helper.c |  6 +++---
 include/drm/drm_crtc.h  |  3 +++
 3 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index f09b752..7d7c1fd 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -4175,12 +4175,25 @@ static int drm_mode_crtc_set_obj_prop(struct 
drm_mode_object *obj,
return ret;
 }

-static int drm_mode_plane_set_obj_prop(struct drm_mode_object *obj,
- struct drm_property *property,
- uint64_t value)
+/**
+ * drm_mode_plane_set_obj_prop - set the value of a property
+ * @plane: drm plane object to set property value for
+ * @property: property to set
+ * @value: value the property should be set to
+ *
+ * This functions sets a given property on a given plane object. This function
+ * calls the driver's ->set_property callback and changes the software state of
+ * the property if the callback succeeds.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
+   struct drm_property *property,
+   uint64_t value)
 {
int ret = -EINVAL;
-   struct drm_plane *plane = obj_to_plane(obj);
+   struct drm_mode_object *obj = >base;

if (plane->funcs->set_property)
ret = plane->funcs->set_property(plane, property, value);
@@ -4189,6 +4202,7 @@ static int drm_mode_plane_set_obj_prop(struct 
drm_mode_object *obj,

return ret;
 }
+EXPORT_SYMBOL(drm_mode_plane_set_obj_prop);

 /**
  * drm_mode_getproperty_ioctl - get the current value of a object's property
@@ -4327,7 +4341,8 @@ int drm_mode_obj_set_property_ioctl(struct drm_device 
*dev, void *data,
ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value);
break;
case DRM_MODE_OBJECT_PLANE:
-   ret = drm_mode_plane_set_obj_prop(arg_obj, property, 
arg->value);
+   ret = drm_mode_plane_set_obj_prop(obj_to_plane(arg_obj),
+ property, arg->value);
break;
}

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 63d7b8e..0c0c39b 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -296,9 +296,9 @@ static bool restore_fbdev_mode(struct drm_fb_helper 
*fb_helper)
drm_plane_force_disable(plane);

if (dev->mode_config.rotation_property) {
-   drm_object_property_set_value(>base,
-   dev->mode_config.rotation_property,
-   BIT(DRM_ROTATE_0));
+   drm_mode_plane_set_obj_prop(plane,
+   
dev->mode_config.rotation_property,
+   BIT(DRM_ROTATE_0));
}
}

diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 0375d75..31344bf 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1127,6 +1127,9 @@ extern int drm_mode_obj_get_properties_ioctl(struct 
drm_device *dev, void *data,
 struct drm_file *file_priv);
 extern int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file_priv);
+extern int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
+  struct drm_property *property,
+  uint64_t value);

 extern void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth,
 int *bpp);
-- 
1.9.3



[Intel-gfx] [PATCH] drm: fix plane rotation when restoring fbdev configuration

2014-08-15 Thread Thomas Wood
On 15 August 2014 11:22, Daniel Vetter  wrote:
> On Fri, Aug 15, 2014 at 10:48:05AM +0100, Thomas Wood wrote:
>> On 15 August 2014 10:42, Thomas Wood  wrote:
>> > On 14 August 2014 17:02, Daniel Vetter  wrote:
>> >> On Thu, Aug 14, 2014 at 04:33:18PM +0100, Thomas Wood wrote:
>> >>> Make sure plane rotation is reset correctly when restoring the fbdev
>> >>> configuration by using drm_mode_plane_set_obj_prop. This calls the
>> >>> driver's set_property callback and ensures the rotation is actually
>> >>> changed.
>> >>>
>> >>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82236
>> >>> Signed-off-by: Thomas Wood 
>> >>
>> >> Commit message is missing the citation of the offending commit that
>> >> introduced this. With that addressed this is
>> >>
>> >> Reviewed-by: Daniel Vetter 
>> >>
>> >> And please cc all the people involved in the offending commit next time
>> >> around, too.
>> >
>> > The "reset" feature was introduced in commit 9783de2 (drm: Resetting
>> > rotation property), although it also looks like the issue was
>> > originally addressed in a previous version of the patch:
>> >
>> > http://lists.freedesktop.org/archives/dri-devel/2014-July/062981.html
>> >
>> > Although this version calls the driver's set_property directly rather
>> > than exporting drm_mode_plane_set_obj_prop.
>> >
>> > The final version of the patch contains a different change:
>>
>> http://lists.freedesktop.org/archives/dri-devel/2014-August/065728.html
>>
>> So there were actually two different "v2" versions of the patch.
>
> Somehow I've thought this is for -fixes, but the patch is only in dinq. So
> merged, thanks.
> -Daniel

Is there any preference to calling set_property directly (as
originally fixed), as opposed to exporting and using
drm_mode_plane_set_obj_prop?

I have also pushed a patch for igt/kms_rotate_crc to add a testcase
for this issue:

http://lists.freedesktop.org/archives/intel-gfx/2014-August/050775.html

>
>>
>>
>>
>> >
>> >> -Daniel
>> >>> ---
>> >>>  drivers/gpu/drm/drm_crtc.c  | 25 -
>> >>>  drivers/gpu/drm/drm_fb_helper.c |  6 +++---
>> >>>  include/drm/drm_crtc.h  |  3 +++
>> >>>  3 files changed, 26 insertions(+), 8 deletions(-)
>> >>>
>> >>> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
>> >>> index f09b752..95f330a 100644
>> >>> --- a/drivers/gpu/drm/drm_crtc.c
>> >>> +++ b/drivers/gpu/drm/drm_crtc.c
>> >>> @@ -4175,12 +4175,25 @@ static int drm_mode_crtc_set_obj_prop(struct 
>> >>> drm_mode_object *obj,
>> >>>   return ret;
>> >>>  }
>> >>>
>> >>> -static int drm_mode_plane_set_obj_prop(struct drm_mode_object *obj,
>> >>> -   struct drm_property *property,
>> >>> -   uint64_t value)
>> >>> +/**
>> >>> + * drm_mode_plane_set_obj_prop - set the value of a property
>> >>> + * @plane: drm plane object to set property value for
>> >>> + * @property: property to set
>> >>> + * @val: value the property should be set to
>> >>> + *
>> >>> + * This functions sets a given property on a given plane object. This 
>> >>> function
>> >>> + * calls the driver's ->set_property callback and changes the software 
>> >>> state of
>> >>> + * the property if the callback succeeds.
>> >>> + *
>> >>> + * Returns:
>> >>> + * Zero on success, error code on failure.
>> >>> + */
>> >>> +int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
>> >>> + struct drm_property *property,
>> >>> + uint64_t value)
>> >>>  {
>> >>>   int ret = -EINVAL;
>> >>> - struct drm_plane *plane = obj_to_plane(obj);
>> >>> + struct drm_mode_object *obj = >base;
>> >>>
>> >>>   if (plane->funcs->set_property)
>> >>>   ret = plane->funcs->set_property(plane, property, value);
>> >>> @@ -4189,6 +4202,7 @@ static int drm_mode_plane_set_obj_

[Intel-gfx] [PATCH] drm: fix plane rotation when restoring fbdev configuration

2014-08-15 Thread Thomas Wood
On 15 August 2014 10:42, Thomas Wood  wrote:
> On 14 August 2014 17:02, Daniel Vetter  wrote:
>> On Thu, Aug 14, 2014 at 04:33:18PM +0100, Thomas Wood wrote:
>>> Make sure plane rotation is reset correctly when restoring the fbdev
>>> configuration by using drm_mode_plane_set_obj_prop. This calls the
>>> driver's set_property callback and ensures the rotation is actually
>>> changed.
>>>
>>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82236
>>> Signed-off-by: Thomas Wood 
>>
>> Commit message is missing the citation of the offending commit that
>> introduced this. With that addressed this is
>>
>> Reviewed-by: Daniel Vetter 
>>
>> And please cc all the people involved in the offending commit next time
>> around, too.
>
> The "reset" feature was introduced in commit 9783de2 (drm: Resetting
> rotation property), although it also looks like the issue was
> originally addressed in a previous version of the patch:
>
> http://lists.freedesktop.org/archives/dri-devel/2014-July/062981.html
>
> Although this version calls the driver's set_property directly rather
> than exporting drm_mode_plane_set_obj_prop.
>
> The final version of the patch contains a different change:

http://lists.freedesktop.org/archives/dri-devel/2014-August/065728.html

So there were actually two different "v2" versions of the patch.



>
>> -Daniel
>>> ---
>>>  drivers/gpu/drm/drm_crtc.c  | 25 -
>>>  drivers/gpu/drm/drm_fb_helper.c |  6 +++---
>>>  include/drm/drm_crtc.h  |  3 +++
>>>  3 files changed, 26 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
>>> index f09b752..95f330a 100644
>>> --- a/drivers/gpu/drm/drm_crtc.c
>>> +++ b/drivers/gpu/drm/drm_crtc.c
>>> @@ -4175,12 +4175,25 @@ static int drm_mode_crtc_set_obj_prop(struct 
>>> drm_mode_object *obj,
>>>   return ret;
>>>  }
>>>
>>> -static int drm_mode_plane_set_obj_prop(struct drm_mode_object *obj,
>>> -   struct drm_property *property,
>>> -   uint64_t value)
>>> +/**
>>> + * drm_mode_plane_set_obj_prop - set the value of a property
>>> + * @plane: drm plane object to set property value for
>>> + * @property: property to set
>>> + * @val: value the property should be set to
>>> + *
>>> + * This functions sets a given property on a given plane object. This 
>>> function
>>> + * calls the driver's ->set_property callback and changes the software 
>>> state of
>>> + * the property if the callback succeeds.
>>> + *
>>> + * Returns:
>>> + * Zero on success, error code on failure.
>>> + */
>>> +int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
>>> + struct drm_property *property,
>>> + uint64_t value)
>>>  {
>>>   int ret = -EINVAL;
>>> - struct drm_plane *plane = obj_to_plane(obj);
>>> + struct drm_mode_object *obj = >base;
>>>
>>>   if (plane->funcs->set_property)
>>>   ret = plane->funcs->set_property(plane, property, value);
>>> @@ -4189,6 +4202,7 @@ static int drm_mode_plane_set_obj_prop(struct 
>>> drm_mode_object *obj,
>>>
>>>   return ret;
>>>  }
>>> +EXPORT_SYMBOL(drm_mode_plane_set_obj_prop);
>>>
>>>  /**
>>>   * drm_mode_getproperty_ioctl - get the current value of a object's 
>>> property
>>> @@ -4327,7 +4341,8 @@ int drm_mode_obj_set_property_ioctl(struct drm_device 
>>> *dev, void *data,
>>>   ret = drm_mode_crtc_set_obj_prop(arg_obj, property, 
>>> arg->value);
>>>   break;
>>>   case DRM_MODE_OBJECT_PLANE:
>>> - ret = drm_mode_plane_set_obj_prop(arg_obj, property, 
>>> arg->value);
>>> + ret = drm_mode_plane_set_obj_prop(obj_to_plane(arg_obj),
>>> +   property, arg->value);
>>>   break;
>>>   }
>>>
>>> diff --git a/drivers/gpu/drm/drm_fb_helper.c 
>>> b/drivers/gpu/drm/drm_fb_helper.c
>>> index 63d7b8e..0c0c39b 100644
>>> --- a/drivers/gpu/drm/drm_fb_helper.c
>>> +++ b/drivers/gpu/drm/drm_fb_helper.c
>>> @@ -296,9 +296,9 @@ stat

[Intel-gfx] [PATCH] drm: fix plane rotation when restoring fbdev configuration

2014-08-15 Thread Thomas Wood
On 14 August 2014 17:02, Daniel Vetter  wrote:
> On Thu, Aug 14, 2014 at 04:33:18PM +0100, Thomas Wood wrote:
>> Make sure plane rotation is reset correctly when restoring the fbdev
>> configuration by using drm_mode_plane_set_obj_prop. This calls the
>> driver's set_property callback and ensures the rotation is actually
>> changed.
>>
>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82236
>> Signed-off-by: Thomas Wood 
>
> Commit message is missing the citation of the offending commit that
> introduced this. With that addressed this is
>
> Reviewed-by: Daniel Vetter 
>
> And please cc all the people involved in the offending commit next time
> around, too.

The "reset" feature was introduced in commit 9783de2 (drm: Resetting
rotation property), although it also looks like the issue was
originally addressed in a previous version of the patch:

http://lists.freedesktop.org/archives/dri-devel/2014-July/062981.html

Although this version calls the driver's set_property directly rather
than exporting drm_mode_plane_set_obj_prop.

The final version of the patch contains a different change:



> -Daniel
>> ---
>>  drivers/gpu/drm/drm_crtc.c  | 25 -
>>  drivers/gpu/drm/drm_fb_helper.c |  6 +++---
>>  include/drm/drm_crtc.h  |  3 +++
>>  3 files changed, 26 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
>> index f09b752..95f330a 100644
>> --- a/drivers/gpu/drm/drm_crtc.c
>> +++ b/drivers/gpu/drm/drm_crtc.c
>> @@ -4175,12 +4175,25 @@ static int drm_mode_crtc_set_obj_prop(struct 
>> drm_mode_object *obj,
>>   return ret;
>>  }
>>
>> -static int drm_mode_plane_set_obj_prop(struct drm_mode_object *obj,
>> -   struct drm_property *property,
>> -   uint64_t value)
>> +/**
>> + * drm_mode_plane_set_obj_prop - set the value of a property
>> + * @plane: drm plane object to set property value for
>> + * @property: property to set
>> + * @val: value the property should be set to
>> + *
>> + * This functions sets a given property on a given plane object. This 
>> function
>> + * calls the driver's ->set_property callback and changes the software 
>> state of
>> + * the property if the callback succeeds.
>> + *
>> + * Returns:
>> + * Zero on success, error code on failure.
>> + */
>> +int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
>> + struct drm_property *property,
>> + uint64_t value)
>>  {
>>   int ret = -EINVAL;
>> - struct drm_plane *plane = obj_to_plane(obj);
>> + struct drm_mode_object *obj = >base;
>>
>>   if (plane->funcs->set_property)
>>   ret = plane->funcs->set_property(plane, property, value);
>> @@ -4189,6 +4202,7 @@ static int drm_mode_plane_set_obj_prop(struct 
>> drm_mode_object *obj,
>>
>>   return ret;
>>  }
>> +EXPORT_SYMBOL(drm_mode_plane_set_obj_prop);
>>
>>  /**
>>   * drm_mode_getproperty_ioctl - get the current value of a object's property
>> @@ -4327,7 +4341,8 @@ int drm_mode_obj_set_property_ioctl(struct drm_device 
>> *dev, void *data,
>>   ret = drm_mode_crtc_set_obj_prop(arg_obj, property, 
>> arg->value);
>>   break;
>>   case DRM_MODE_OBJECT_PLANE:
>> - ret = drm_mode_plane_set_obj_prop(arg_obj, property, 
>> arg->value);
>> + ret = drm_mode_plane_set_obj_prop(obj_to_plane(arg_obj),
>> +   property, arg->value);
>>   break;
>>   }
>>
>> diff --git a/drivers/gpu/drm/drm_fb_helper.c 
>> b/drivers/gpu/drm/drm_fb_helper.c
>> index 63d7b8e..0c0c39b 100644
>> --- a/drivers/gpu/drm/drm_fb_helper.c
>> +++ b/drivers/gpu/drm/drm_fb_helper.c
>> @@ -296,9 +296,9 @@ static bool restore_fbdev_mode(struct drm_fb_helper 
>> *fb_helper)
>>   drm_plane_force_disable(plane);
>>
>>   if (dev->mode_config.rotation_property) {
>> - drm_object_property_set_value(>base,
>> - dev->mode_config.rotation_property,
>> - BIT(DRM_ROTATE_0));
>> + drm_mode_plane_set_obj_prop(plane,
>> + 
>> dev->mode_config.rotation_property,
>> + 

[PATCH] drm: fix plane rotation when restoring fbdev configuration

2014-08-14 Thread Thomas Wood
Make sure plane rotation is reset correctly when restoring the fbdev
configuration by using drm_mode_plane_set_obj_prop. This calls the
driver's set_property callback and ensures the rotation is actually
changed.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82236
Signed-off-by: Thomas Wood 
---
 drivers/gpu/drm/drm_crtc.c  | 25 -
 drivers/gpu/drm/drm_fb_helper.c |  6 +++---
 include/drm/drm_crtc.h  |  3 +++
 3 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index f09b752..95f330a 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -4175,12 +4175,25 @@ static int drm_mode_crtc_set_obj_prop(struct 
drm_mode_object *obj,
return ret;
 }

-static int drm_mode_plane_set_obj_prop(struct drm_mode_object *obj,
- struct drm_property *property,
- uint64_t value)
+/**
+ * drm_mode_plane_set_obj_prop - set the value of a property
+ * @plane: drm plane object to set property value for
+ * @property: property to set
+ * @val: value the property should be set to
+ *
+ * This functions sets a given property on a given plane object. This function
+ * calls the driver's ->set_property callback and changes the software state of
+ * the property if the callback succeeds.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
+   struct drm_property *property,
+   uint64_t value)
 {
int ret = -EINVAL;
-   struct drm_plane *plane = obj_to_plane(obj);
+   struct drm_mode_object *obj = >base;

if (plane->funcs->set_property)
ret = plane->funcs->set_property(plane, property, value);
@@ -4189,6 +4202,7 @@ static int drm_mode_plane_set_obj_prop(struct 
drm_mode_object *obj,

return ret;
 }
+EXPORT_SYMBOL(drm_mode_plane_set_obj_prop);

 /**
  * drm_mode_getproperty_ioctl - get the current value of a object's property
@@ -4327,7 +4341,8 @@ int drm_mode_obj_set_property_ioctl(struct drm_device 
*dev, void *data,
ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value);
break;
case DRM_MODE_OBJECT_PLANE:
-   ret = drm_mode_plane_set_obj_prop(arg_obj, property, 
arg->value);
+   ret = drm_mode_plane_set_obj_prop(obj_to_plane(arg_obj),
+ property, arg->value);
break;
}

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 63d7b8e..0c0c39b 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -296,9 +296,9 @@ static bool restore_fbdev_mode(struct drm_fb_helper 
*fb_helper)
drm_plane_force_disable(plane);

if (dev->mode_config.rotation_property) {
-   drm_object_property_set_value(>base,
-   dev->mode_config.rotation_property,
-   BIT(DRM_ROTATE_0));
+   drm_mode_plane_set_obj_prop(plane,
+   
dev->mode_config.rotation_property,
+   BIT(DRM_ROTATE_0));
}
}

diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 0375d75..31344bf 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1127,6 +1127,9 @@ extern int drm_mode_obj_get_properties_ioctl(struct 
drm_device *dev, void *data,
 struct drm_file *file_priv);
 extern int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file_priv);
+extern int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
+  struct drm_property *property,
+  uint64_t value);

 extern void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth,
 int *bpp);
-- 
1.9.3



[PATCH 1/1] drm/tilcdc: Fix build breakage

2014-07-10 Thread Thomas Wood
On 10 July 2014 10:16, Dave Airlie  wrote:
> On 10 July 2014 17:09, Daniel Vetter  wrote:
>> On Thu, Jul 10, 2014 at 12:02:15PM +1000, Dave Airlie wrote:
>>> On 9 July 2014 21:42, Sachin Kamat  wrote:
>>> > Commit 34ea3d386347 ("drm: add register and unregister functions
>>> > for connectors") probably missed out converting the
>>> > drm_sysfs_connector_remove instances in the following files.
>>> > Without this patch we get the following compilation error:
>>> > ERROR: "drm_sysfs_connector_remove" [drivers/gpu/drm/tilcdc/tilcdc.ko] 
>>> > undefined!
>>> >
>>> > Signed-off-by: Sachin Kamat 
>>> > CC: Thomas Wood 
>>> > CC: David Herrmann 
>>> > CC: Daniel Vetter 
>>> > ---
>>> > Only compile tested.
>>>
>>> Oops, applied thanks,
>>>
>>> I did an arm build just on the drm dir, forgot to let it run to
>>> completion over the whole tree.
>>
>> Yeah, my apologies for breaking things. Nowadays I rely on the 0-day
>> builder for arm build testing, dunno why it didn't report this one here.
>> Might be good to check with Wu Fengguang that your driver is included - he
>> tends to catch other drm breakage on arm drivers well.

It actually looks like the calls to drm_sysfs_connector_remove were
added after the patch to remove it was applied:

16dcbde drm/tilcdc: tfp410: fix dangling sysfs connector node
daa15b4 drm/tilcdc: slave: fix dangling sysfs connector node
e396900 drm/tilcdc: panel: fix dangling sysfs connector node

This probably explains why it wasn't reported from the builder on the
original patch.


>
> I just got the report now :-) after I fixed it!
>
> Dave.


[PATCH v2 2/2] drm/debugfs: add an "edid_override" file per connector

2014-06-18 Thread Thomas Wood
Add a file to debugfs for each connector to allow the EDID to be
overridden.

v2: Copy ubuf before accessing it and reject invalid length data. (David
Herrmann)
Ensure override_edid is reset when a new EDID value is written.
(David Herrmann)
Fix the debugfs file permissions. (David Herrmann)

Signed-off-by: Thomas Wood 
---
 drivers/gpu/drm/drm_crtc.c |  4 +++
 drivers/gpu/drm/drm_debugfs.c  | 68 ++
 drivers/gpu/drm/drm_probe_helper.c |  9 -
 include/drm/drm_crtc.h |  1 +
 4 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index fdb69f7..4b3bbc4 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3916,6 +3916,10 @@ int drm_mode_connector_update_edid_property(struct 
drm_connector *connector,
struct drm_device *dev = connector->dev;
int ret, size;

+   /* ignore requests to set edid when overridden */
+   if (connector->override_edid)
+   return 0;
+
if (connector->edid_blob_ptr)
drm_property_destroy_blob(dev, connector->edid_blob_ptr);

diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index 8ab3f3e..13bd429 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 

 #if defined(CONFIG_DEBUG_FS)

@@ -304,6 +305,67 @@ static ssize_t connector_write(struct file *file, const 
char __user *ubuf,
return len;
 }

+static int edid_show(struct seq_file *m, void *data)
+{
+   struct drm_connector *connector = m->private;
+   struct drm_property_blob *edid = connector->edid_blob_ptr;
+
+   if (connector->override_edid && edid)
+   seq_write(m, edid->data, edid->length);
+
+   return 0;
+}
+
+static int edid_open(struct inode *inode, struct file *file)
+{
+   struct drm_connector *dev = inode->i_private;
+
+   return single_open(file, edid_show, dev);
+}
+
+static ssize_t edid_write(struct file *file, const char __user *ubuf,
+ size_t len, loff_t *offp)
+{
+   struct seq_file *m = file->private_data;
+   struct drm_connector *connector = m->private;
+   char *buf;
+   struct edid *edid;
+   int ret;
+
+   buf = memdup_user(ubuf, len);
+   if (IS_ERR(buf))
+   return PTR_ERR(buf);
+
+   edid = (struct edid *) buf;
+
+   if (len == 5 && !strncmp(buf, "reset", 5)) {
+   connector->override_edid = false;
+   ret = drm_mode_connector_update_edid_property(connector, NULL);
+   } else if (len < EDID_LENGTH ||
+  EDID_LENGTH * (1 + edid->extensions) > len)
+   ret = -EINVAL;
+   else {
+   connector->override_edid = false;
+   ret = drm_mode_connector_update_edid_property(connector, edid);
+   if (!ret)
+   connector->override_edid = true;
+   }
+
+   kfree(buf);
+
+   return (ret) ? ret : len;
+}
+
+static const struct file_operations drm_edid_fops = {
+   .owner = THIS_MODULE,
+   .open = edid_open,
+   .read = seq_read,
+   .llseek = seq_lseek,
+   .release = single_release,
+   .write = edid_write
+};
+
+
 static const struct file_operations drm_connector_fops = {
.owner = THIS_MODULE,
.open = connector_open,
@@ -333,6 +395,12 @@ int drm_debugfs_connector_add(struct drm_connector 
*connector)
if (!ent)
goto error;

+   /* edid */
+   ent = debugfs_create_file("edid_override", S_IRUGO | S_IWUSR, root,
+ connector, _edid_fops);
+   if (!ent)
+   goto error;
+
return 0;

 error:
diff --git a/drivers/gpu/drm/drm_probe_helper.c 
b/drivers/gpu/drm/drm_probe_helper.c
index d22676b..db7d250 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -130,7 +130,14 @@ static int 
drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
count = drm_load_edid_firmware(connector);
if (count == 0)
 #endif
-   count = (*connector_funcs->get_modes)(connector);
+   {
+   if (connector->override_edid) {
+   struct edid *edid = (struct edid *) 
connector->edid_blob_ptr->data;
+
+   count = drm_add_edid_modes(connector, edid);
+   } else
+   count = (*connector_funcs->get_modes)(connector);
+   }

if (count == 0 && connector->status == connector_status_connected)
count = drm_add_modes_noedid(connector, 1024, 768);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 67a33bc..d09b471 100644
--- a/include/drm/drm_crtc.h
+++

[PATCH v2 1/2] drm/debugfs: add a "force" file per connector

2014-06-18 Thread Thomas Wood
Add a file to debugfs for each connector to enable modification of the
"force" connector attribute. This allows connectors to be enabled or
disabled for testing and debugging purposes.

v2: Add stricter value checking and clean up debugfs_entry if file
creation fails in drm_debugfs_connector_add. (David Herrmann)

Signed-off-by: Thomas Wood 
---
 drivers/gpu/drm/drm_crtc.c|  17 ++-
 drivers/gpu/drm/drm_debugfs.c | 114 ++
 include/drm/drmP.h|  11 
 include/drm/drm_crtc.h|   2 +
 4 files changed, 143 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 365e2c0..fdb69f7 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -888,6 +888,8 @@ int drm_connector_init(struct drm_device *dev,
drm_object_attach_property(>base,
  dev->mode_config.dpms_property, 0);

+   connector->debugfs_entry = NULL;
+
 out_put:
if (ret)
drm_mode_object_put(dev, >base);
@@ -938,7 +940,19 @@ EXPORT_SYMBOL(drm_connector_cleanup);
  */
 int drm_connector_register(struct drm_connector *connector)
 {
-   return drm_sysfs_connector_add(connector);
+   int ret;
+
+   ret = drm_sysfs_connector_add(connector);
+   if (ret)
+   return ret;
+
+   ret = drm_debugfs_connector_add(connector);
+   if (ret) {
+   drm_sysfs_connector_remove(connector);
+   return ret;
+   }
+
+   return 0;
 }
 EXPORT_SYMBOL(drm_connector_register);

@@ -951,6 +965,7 @@ EXPORT_SYMBOL(drm_connector_register);
 void drm_connector_unregister(struct drm_connector *connector)
 {
drm_sysfs_connector_remove(connector);
+   drm_debugfs_connector_remove(connector);
 }
 EXPORT_SYMBOL(drm_connector_unregister);

diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index b4b51d4..8ab3f3e 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -237,5 +237,119 @@ int drm_debugfs_cleanup(struct drm_minor *minor)
return 0;
 }

+static int connector_show(struct seq_file *m, void *data)
+{
+   struct drm_connector *connector = m->private;
+   const char *status;
+
+   switch (connector->force) {
+   case DRM_FORCE_ON:
+   status = "on\n";
+   break;
+
+   case DRM_FORCE_ON_DIGITAL:
+   status = "digital\n";
+   break;
+
+   case DRM_FORCE_OFF:
+   status = "off\n";
+   break;
+
+   case DRM_FORCE_UNSPECIFIED:
+   status = "unspecified\n";
+   break;
+
+   default:
+   return 0;
+   }
+
+   seq_puts(m, status);
+
+   return 0;
+}
+
+static int connector_open(struct inode *inode, struct file *file)
+{
+   struct drm_connector *dev = inode->i_private;
+
+   return single_open(file, connector_show, dev);
+}
+
+static ssize_t connector_write(struct file *file, const char __user *ubuf,
+  size_t len, loff_t *offp)
+{
+   struct seq_file *m = file->private_data;
+   struct drm_connector *connector = m->private;
+   char buf[12];
+
+   if (len > sizeof(buf) - 1)
+   return -EINVAL;
+
+   if (copy_from_user(buf, ubuf, len))
+   return -EFAULT;
+
+   buf[len] = '\0';
+
+   if (!strcmp(buf, "on"))
+   connector->force = DRM_FORCE_ON;
+   else if (!strcmp(buf, "digital"))
+   connector->force = DRM_FORCE_ON_DIGITAL;
+   else if (!strcmp(buf, "off"))
+   connector->force = DRM_FORCE_OFF;
+   else if (!strcmp(buf, "unspecified"))
+   connector->force = DRM_FORCE_UNSPECIFIED;
+   else
+   return -EINVAL;
+
+   return len;
+}
+
+static const struct file_operations drm_connector_fops = {
+   .owner = THIS_MODULE,
+   .open = connector_open,
+   .read = seq_read,
+   .llseek = seq_lseek,
+   .release = single_release,
+   .write = connector_write
+};
+
+int drm_debugfs_connector_add(struct drm_connector *connector)
+{
+   struct drm_minor *minor = connector->dev->primary;
+   struct dentry *root, *ent;
+
+   if (!minor->debugfs_root)
+   return -1;
+
+   root = debugfs_create_dir(connector->name, minor->debugfs_root);
+   if (!root)
+   return -ENOMEM;
+
+   connector->debugfs_entry = root;
+
+   /* force */
+   ent = debugfs_create_file("force", S_IRUGO | S_IWUSR, root, connector,
+ _connector_fops);
+   if (!ent)
+   goto error;
+
+   return 0;
+
+error:
+   debugfs_remove_recursive(connector->debugfs_entry);
+   connect

[PATCH v2 0/2] connector debugfs properties

2014-06-18 Thread Thomas Wood
The following patches update the last two patches in the original series with
the suggested changes from David Herrmann.

Thomas Wood (2):
  drm/debugfs: add a "force" file per connector
  drm/debugfs: add an "edid_override" file per connector

 drivers/gpu/drm/drm_crtc.c |  21 -
 drivers/gpu/drm/drm_debugfs.c  | 182 +
 drivers/gpu/drm/drm_probe_helper.c |   9 +-
 include/drm/drmP.h |  11 +++
 include/drm/drm_crtc.h |   3 +
 5 files changed, 224 insertions(+), 2 deletions(-)

-- 
1.9.3


[PATCH 3/3] drm/debugfs: add an "edid_override" file per connector

2014-05-29 Thread Thomas Wood
Add a file to debugfs for each connector that allows the edid data to be
overridden.

Signed-off-by: Thomas Wood 
---
 drivers/gpu/drm/drm_crtc.c |  4 +++
 drivers/gpu/drm/drm_debugfs.c  | 56 ++
 drivers/gpu/drm/drm_probe_helper.c |  9 +-
 include/drm/drm_crtc.h |  1 +
 4 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 59a2784..8543eac 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3701,6 +3701,10 @@ int drm_mode_connector_update_edid_property(struct 
drm_connector *connector,
struct drm_device *dev = connector->dev;
int ret, size;

+   /* ignore requests to set edid when overridden */
+   if (connector->override_edid)
+   return 0;
+
if (connector->edid_blob_ptr)
drm_property_destroy_blob(dev, connector->edid_blob_ptr);

diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index b57b614..2c666ba 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 

 #if defined(CONFIG_DEBUG_FS)

@@ -295,6 +296,55 @@ static ssize_t connector_write(struct file *file, const 
char __user *ubuf,
return len;
 }

+static int edid_show(struct seq_file *m, void *data)
+{
+   struct drm_connector *connector = m->private;
+   struct drm_property_blob *edid = connector->edid_blob_ptr;
+
+   if (connector->override_edid && edid)
+   seq_write(m, edid->data, edid->length);
+
+   return 0;
+}
+
+static int edid_open(struct inode *inode, struct file *file)
+{
+   struct drm_connector *dev = inode->i_private;
+
+   return single_open(file, edid_show, dev);
+}
+
+static ssize_t edid_write(struct file *file, const char __user *ubuf,
+ size_t len, loff_t *offp)
+{
+   struct seq_file *m = file->private_data;
+   struct drm_connector *connector = m->private;
+
+   if (len >= EDID_LENGTH) {
+   drm_mode_connector_update_edid_property(connector,
+   (struct edid *) ubuf);
+   connector->override_edid = true;
+   } else {
+   if (connector->override_edid) {
+   connector->override_edid = false;
+   drm_mode_connector_update_edid_property(connector,
+   NULL);
+   }
+   }
+
+   return len;
+}
+
+static const struct file_operations drm_edid_fops = {
+   .owner = THIS_MODULE,
+   .open = edid_open,
+   .read = seq_read,
+   .llseek = seq_lseek,
+   .release = single_release,
+   .write = edid_write
+};
+
+
 static const struct file_operations drm_connector_fops = {
.owner = THIS_MODULE,
.open = connector_open,
@@ -325,6 +375,12 @@ int drm_debugfs_connector_add(struct drm_connector 
*connector)
if (!ent)
return -ENOMEM;

+   /* edid */
+   ent = debugfs_create_file("edid_override", S_IRUGO, root, connector,
+ _edid_fops);
+   if (!ent)
+   return -ENOMEM;
+
return 0;
 }

diff --git a/drivers/gpu/drm/drm_probe_helper.c 
b/drivers/gpu/drm/drm_probe_helper.c
index 79f07f2..1f0dc77 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -130,7 +130,14 @@ static int 
drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
count = drm_load_edid_firmware(connector);
if (count == 0)
 #endif
-   count = (*connector_funcs->get_modes)(connector);
+   {
+   if (connector->override_edid) {
+   struct edid *edid = (struct edid *) 
connector->edid_blob_ptr->data;
+
+   count = drm_add_edid_modes(connector, edid);
+   } else
+   count = (*connector_funcs->get_modes)(connector);
+   }

if (count == 0 && connector->status == connector_status_connected)
count = drm_add_modes_noedid(connector, 1024, 768);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index f04f4b9..11fce43 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -513,6 +513,7 @@ struct drm_connector {

/* forced on connector */
enum drm_connector_force force;
+   bool override_edid;
uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];
struct drm_encoder *encoder; /* currently active encoder */

-- 
1.9.0



[PATCH 2/3] drm/debugfs: add a "force" file per connector

2014-05-29 Thread Thomas Wood
Add a file to debugfs for each connector to enable modification of the
"force" connector attribute. This allows connectors to be enabled or
disabled for testing and debugging purposes.

Signed-off-by: Thomas Wood 
---
 drivers/gpu/drm/drm_crtc.c|  17 ++-
 drivers/gpu/drm/drm_debugfs.c | 101 ++
 include/drm/drmP.h|  11 +
 include/drm/drm_crtc.h|   2 +
 4 files changed, 130 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 998663c..59a2784 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -841,6 +841,8 @@ int drm_connector_init(struct drm_device *dev,
drm_object_attach_property(>base,
  dev->mode_config.dpms_property, 0);

+   connector->debugfs_entry = NULL;
+
 out_put:
if (ret)
drm_mode_object_put(dev, >base);
@@ -891,7 +893,19 @@ EXPORT_SYMBOL(drm_connector_cleanup);
  */
 int drm_connector_register(struct drm_connector *connector)
 {
-   return drm_sysfs_connector_add(connector);
+   int ret;
+
+   ret = drm_sysfs_connector_add(connector);
+   if (ret != 0)
+   return ret;
+
+   ret = drm_debugfs_connector_add(connector);
+   if (ret != 0) {
+   drm_sysfs_connector_remove(connector);
+   return ret;
+   }
+
+   return 0;
 }
 EXPORT_SYMBOL(drm_connector_register);

@@ -904,6 +918,7 @@ EXPORT_SYMBOL(drm_connector_register);
 void drm_connector_unregister(struct drm_connector *connector)
 {
drm_sysfs_connector_remove(connector);
+   drm_debugfs_connector_remove(connector);
 }
 EXPORT_SYMBOL(drm_connector_unregister);

diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index b4b51d4..b57b614 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -237,5 +237,106 @@ int drm_debugfs_cleanup(struct drm_minor *minor)
return 0;
 }

+static int connector_show(struct seq_file *m, void *data)
+{
+   struct drm_connector *connector = m->private;
+   const char *status;
+
+   switch (connector->force) {
+   case DRM_FORCE_ON:
+   status = "on\n";
+   break;
+
+   case DRM_FORCE_ON_DIGITAL:
+   status = "digital\n";
+   break;
+
+   case DRM_FORCE_OFF:
+   status = "off\n";
+   break;
+
+   case DRM_FORCE_UNSPECIFIED:
+   status = "unspecified\n";
+   break;
+
+   default:
+   return 0;
+   }
+
+   seq_puts(m, status);
+
+   return 0;
+}
+
+static int connector_open(struct inode *inode, struct file *file)
+{
+   struct drm_connector *dev = inode->i_private;
+
+   return single_open(file, connector_show, dev);
+}
+
+static ssize_t connector_write(struct file *file, const char __user *ubuf,
+  size_t len, loff_t *offp)
+{
+   struct seq_file *m = file->private_data;
+   struct drm_connector *connector = m->private;
+
+   if (strncmp(ubuf, "on", len) == 0)
+   connector->force = DRM_FORCE_ON;
+   else if (strncmp(ubuf, "digital", len) == 0)
+   connector->force = DRM_FORCE_ON_DIGITAL;
+   else if (strncmp(ubuf, "off", len) == 0)
+   connector->force = DRM_FORCE_OFF;
+   else if (strncmp(ubuf, "unspecified", len) == 0)
+   connector->force = DRM_FORCE_UNSPECIFIED;
+   else
+   return -EINVAL;
+
+   return len;
+}
+
+static const struct file_operations drm_connector_fops = {
+   .owner = THIS_MODULE,
+   .open = connector_open,
+   .read = seq_read,
+   .llseek = seq_lseek,
+   .release = single_release,
+   .write = connector_write
+};
+
+int drm_debugfs_connector_add(struct drm_connector *connector)
+{
+   struct drm_minor *minor = connector->dev->primary;
+   struct dentry *root, *ent;
+
+   if (!minor->debugfs_root)
+   return -1;
+
+   root = debugfs_create_dir(drm_get_connector_name(connector),
+ minor->debugfs_root);
+   if (!root)
+   return -ENOMEM;
+
+   connector->debugfs_entry = root;
+
+   /* force */
+   ent = debugfs_create_file("force", S_IRUGO, root, connector,
+ _connector_fops);
+   if (!ent)
+   return -ENOMEM;
+
+   return 0;
+}
+
+void drm_debugfs_connector_remove(struct drm_connector *connector)
+{
+   if (!connector->debugfs_entry)
+   return;
+
+   debugfs_remove_recursive(connector->debugfs_entry);
+
+   connector->debugfs_entry = NULL;
+}
+
 #endif /* CONFIG_DEBUG_FS */

diff --git a/include/drm/drmP.h b/includ

[PATCH 1/3] drm: add register and unregister functions for connectors

2014-05-29 Thread Thomas Wood
Introduce generic functions to register and unregister connectors. This
provides a common place to add and remove associated user space
interfaces.

Signed-off-by: Thomas Wood 
---
 Documentation/DocBook/drm.tmpl|  6 +++---
 drivers/gpu/drm/armada/armada_output.c|  4 ++--
 drivers/gpu/drm/ast/ast_mode.c|  4 ++--
 drivers/gpu/drm/bridge/ptn3460.c  |  2 +-
 drivers/gpu/drm/drm_crtc.c| 30 ++-
 drivers/gpu/drm/drm_sysfs.c   |  2 --
 drivers/gpu/drm/exynos/exynos_dp_core.c   |  2 +-
 drivers/gpu/drm/exynos/exynos_drm_connector.c |  6 +++---
 drivers/gpu/drm/exynos/exynos_drm_dpi.c   |  4 ++--
 drivers/gpu/drm/exynos/exynos_drm_dsi.c   |  2 +-
 drivers/gpu/drm/exynos/exynos_drm_vidi.c  |  2 +-
 drivers/gpu/drm/exynos/exynos_hdmi.c  |  2 +-
 drivers/gpu/drm/gma500/cdv_intel_crt.c|  4 ++--
 drivers/gpu/drm/gma500/cdv_intel_dp.c |  4 ++--
 drivers/gpu/drm/gma500/cdv_intel_hdmi.c   |  4 ++--
 drivers/gpu/drm/gma500/cdv_intel_lvds.c   |  4 ++--
 drivers/gpu/drm/gma500/mdfld_dsi_output.c |  4 ++--
 drivers/gpu/drm/gma500/oaktrail_hdmi.c|  2 +-
 drivers/gpu/drm/gma500/oaktrail_lvds.c|  2 +-
 drivers/gpu/drm/gma500/psb_intel_lvds.c   |  4 ++--
 drivers/gpu/drm/gma500/psb_intel_sdvo.c   |  4 ++--
 drivers/gpu/drm/i915/intel_crt.c  |  2 +-
 drivers/gpu/drm/i915/intel_display.c  |  2 +-
 drivers/gpu/drm/i915/intel_dp.c   |  4 ++--
 drivers/gpu/drm/i915/intel_dsi.c  |  2 +-
 drivers/gpu/drm/i915/intel_dvo.c  |  2 +-
 drivers/gpu/drm/i915/intel_hdmi.c |  2 +-
 drivers/gpu/drm/i915/intel_lvds.c |  2 +-
 drivers/gpu/drm/i915/intel_sdvo.c | 10 -
 drivers/gpu/drm/i915/intel_tv.c   |  2 +-
 drivers/gpu/drm/mgag200/mgag200_mode.c|  2 +-
 drivers/gpu/drm/msm/hdmi/hdmi_connector.c |  4 ++--
 drivers/gpu/drm/nouveau/nouveau_connector.c   |  4 ++--
 drivers/gpu/drm/omapdrm/omap_connector.c  |  4 ++--
 drivers/gpu/drm/qxl/qxl_display.c |  4 ++--
 drivers/gpu/drm/radeon/radeon_connectors.c|  6 +++---
 drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c |  4 ++--
 drivers/gpu/drm/rcar-du/rcar_du_vgacon.c  |  4 ++--
 drivers/gpu/drm/shmobile/shmob_drm_crtc.c |  6 +++---
 drivers/gpu/drm/tegra/output.c|  4 ++--
 drivers/gpu/drm/tilcdc/tilcdc_panel.c |  2 +-
 drivers/gpu/drm/tilcdc/tilcdc_slave.c |  2 +-
 drivers/gpu/drm/tilcdc/tilcdc_tfp410.c|  2 +-
 drivers/gpu/drm/udl/udl_connector.c   |  4 ++--
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c   |  2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c   |  2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c  |  2 +-
 drivers/staging/imx-drm/imx-drm-core.c|  6 +++---
 include/drm/drm_crtc.h|  2 ++
 49 files changed, 110 insertions(+), 82 deletions(-)

diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl
index 00f1c25..0f96b25 100644
--- a/Documentation/DocBook/drm.tmpl
+++ b/Documentation/DocBook/drm.tmpl
@@ -1574,7 +1574,7 @@ int max_width, max_height;
   The connector is then registered with a call to
   drm_connector_init with a pointer to the 
connector
   functions and a connector type, and exposed through sysfs with a 
call to
-  drm_sysfs_connector_add.
+  drm_connector_register.
 
 
   Supported connector types are
@@ -1732,7 +1732,7 @@ int max_width, max_height;
(drm_encoder_cleanup) and connectors
(drm_connector_cleanup). Furthermore, connectors
that have been added to sysfs must be removed by a call to
-   drm_sysfs_connector_remove before calling
+   drm_connector_unregister before calling
drm_connector_cleanup.
   
   
@@ -1777,7 +1777,7 @@ void intel_crt_init(struct drm_device *dev)
drm_encoder_helper_add(_output->enc, _crt_helper_funcs);
drm_connector_helper_add(connector, _crt_connector_helper_funcs);

-   drm_sysfs_connector_add(connector);
+   drm_connector_register(connector);
 }]]>
   
 In the example above (taken from the i915 driver), a CRTC, connector 
and
diff --git a/drivers/gpu/drm/armada/armada_output.c 
b/drivers/gpu/drm/armada/armada_output.c
index d685a54..abbc309 100644
--- a/drivers/gpu/drm/armada/armada_output.c
+++ b/drivers/gpu/drm/armada/armada_output.c
@@ -48,7 +48,7 @@ static void armada_drm_connector_destroy(struct drm_connector 
*conn)
 {
struct armada_connector *dconn = drm_to_armada_conn(conn);

-   drm_sysfs_connector_remove(conn);
+   drm_connector_unregister(conn);
drm_connector_cleanup(conn);
kfree(dconn);
 }
@@ -141,7 +141,7 @@ int armada_output_create(struct drm_device *dev,
if (ret)
goto err_conn;

-

[PATCH 0/3] connector debugfs properties

2014-05-29 Thread Thomas Wood
The following series adds support for exposing various connector features using
debugfs. The first patch refactors the sysfs connector add and remove functions
into generic functions to register and unregister connectors. The remaining
patches add an interface for each connector to debugfs and expose the force
connector attribute and allow the edid value to be overridden.

Thomas Wood (3):
  drm: add register and unregister functions for connectors
  drm/debugfs: add a "force" file per connector
  drm/debugfs: add an "edid_override" file per connector

 Documentation/DocBook/drm.tmpl|   6 +-
 drivers/gpu/drm/armada/armada_output.c|   4 +-
 drivers/gpu/drm/ast/ast_mode.c|   4 +-
 drivers/gpu/drm/bridge/ptn3460.c  |   2 +-
 drivers/gpu/drm/drm_crtc.c|  49 +++-
 drivers/gpu/drm/drm_debugfs.c | 157 ++
 drivers/gpu/drm/drm_probe_helper.c|   9 +-
 drivers/gpu/drm/drm_sysfs.c   |   2 -
 drivers/gpu/drm/exynos/exynos_dp_core.c   |   2 +-
 drivers/gpu/drm/exynos/exynos_drm_connector.c |   6 +-
 drivers/gpu/drm/exynos/exynos_drm_dpi.c   |   4 +-
 drivers/gpu/drm/exynos/exynos_drm_dsi.c   |   2 +-
 drivers/gpu/drm/exynos/exynos_drm_vidi.c  |   2 +-
 drivers/gpu/drm/exynos/exynos_hdmi.c  |   2 +-
 drivers/gpu/drm/gma500/cdv_intel_crt.c|   4 +-
 drivers/gpu/drm/gma500/cdv_intel_dp.c |   4 +-
 drivers/gpu/drm/gma500/cdv_intel_hdmi.c   |   4 +-
 drivers/gpu/drm/gma500/cdv_intel_lvds.c   |   4 +-
 drivers/gpu/drm/gma500/mdfld_dsi_output.c |   4 +-
 drivers/gpu/drm/gma500/oaktrail_hdmi.c|   2 +-
 drivers/gpu/drm/gma500/oaktrail_lvds.c|   2 +-
 drivers/gpu/drm/gma500/psb_intel_lvds.c   |   4 +-
 drivers/gpu/drm/gma500/psb_intel_sdvo.c   |   4 +-
 drivers/gpu/drm/i915/intel_crt.c  |   2 +-
 drivers/gpu/drm/i915/intel_display.c  |   2 +-
 drivers/gpu/drm/i915/intel_dp.c   |   4 +-
 drivers/gpu/drm/i915/intel_dsi.c  |   2 +-
 drivers/gpu/drm/i915/intel_dvo.c  |   2 +-
 drivers/gpu/drm/i915/intel_hdmi.c |   2 +-
 drivers/gpu/drm/i915/intel_lvds.c |   2 +-
 drivers/gpu/drm/i915/intel_sdvo.c |  10 +-
 drivers/gpu/drm/i915/intel_tv.c   |   2 +-
 drivers/gpu/drm/mgag200/mgag200_mode.c|   2 +-
 drivers/gpu/drm/msm/hdmi/hdmi_connector.c |   4 +-
 drivers/gpu/drm/nouveau/nouveau_connector.c   |   4 +-
 drivers/gpu/drm/omapdrm/omap_connector.c  |   4 +-
 drivers/gpu/drm/qxl/qxl_display.c |   4 +-
 drivers/gpu/drm/radeon/radeon_connectors.c|   6 +-
 drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c |   4 +-
 drivers/gpu/drm/rcar-du/rcar_du_vgacon.c  |   4 +-
 drivers/gpu/drm/shmobile/shmob_drm_crtc.c |   6 +-
 drivers/gpu/drm/tegra/output.c|   4 +-
 drivers/gpu/drm/tilcdc/tilcdc_panel.c |   2 +-
 drivers/gpu/drm/tilcdc/tilcdc_slave.c |   2 +-
 drivers/gpu/drm/tilcdc/tilcdc_tfp410.c|   2 +-
 drivers/gpu/drm/udl/udl_connector.c   |   4 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c   |   2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c   |   2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c  |   2 +-
 drivers/staging/imx-drm/imx-drm-core.c|   6 +-
 include/drm/drmP.h|  11 ++
 include/drm/drm_crtc.h|   5 +
 52 files changed, 308 insertions(+), 83 deletions(-)

-- 
1.9.0



[PATCH] drm/sysfs: expose the "force" connector attribute

2014-05-19 Thread Thomas Wood
On 19 May 2014 15:13, David Herrmann  wrote:
> Hi
>
> On Mon, May 19, 2014 at 3:37 PM, Thomas Wood  wrote:
>> Signed-off-by: Thomas Wood 
>
> The commit-msg lacks any discussion why this change is done. What is
> the reason to do that? Isn't the kernel-command-line enough? Why is
> this a regular feature instead of a debugfs attribute?


It was intended as a debug/testing feature to allow tests in
intel-gpu-tools to enable or disable connectors:

http://lists.freedesktop.org/archives/intel-gfx/2014-May/045556.html


I'll update the commit message for the next version of the patch.



>
>> ---
>>  drivers/gpu/drm/drm_sysfs.c | 49 
>> +
>>  1 file changed, 49 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
>> index c22c309..257816e 100644
>> --- a/drivers/gpu/drm/drm_sysfs.c
>> +++ b/drivers/gpu/drm/drm_sysfs.c
>> @@ -338,11 +338,60 @@ static ssize_t select_subconnector_show(struct device 
>> *device,
>> drm_get_dvi_i_select_name((int)subconnector));
>>  }
>>
>> +static ssize_t force_show(struct device *device,
>> + struct device_attribute *attr,
>> + char *buf)
>> +{
>> +   struct drm_connector *connector = to_drm_connector(device);
>> +   char *status;
>
> "const char *" or gcc might warn on string assignments.
>
>> +
>> +   switch (connector->force) {
>> +   case DRM_FORCE_ON:
>> +   status = "on";
>> +   break;
>> +
>> +   case DRM_FORCE_ON_DIGITAL:
>> +   status = "digital";
>> +   break;
>> +
>> +   case DRM_FORCE_OFF:
>> +   status = "off";
>> +   break;
>> +
>> +   case DRM_FORCE_UNSPECIFIED:
>> +   status = "unspecified";
>> +   break;
>> +
>> +   default:
>> +   return 0;
>> +   }
>> +
>> +   return snprintf(buf, PAGE_SIZE, "%s\n", status);
>> +}
>> +
>> +ssize_t force_store(struct device *device, struct device_attribute *attr,
>> +   const char *buf, size_t count)
>> +{
>> +   struct drm_connector *connector = to_drm_connector(device);
>> +
>> +   if (strcmp(buf, "on") == 0)
>> +   connector->force = DRM_FORCE_ON;
>> +   else if (strcmp(buf, "digital") == 0)
>> +   connector->force = DRM_FORCE_ON_DIGITAL;
>> +   else if (strcmp(buf, "off") == 0)
>> +   connector->force = DRM_FORCE_OFF;
>> +   else if (strcmp(buf, "unspecified") == 0)
>> +   connector->force = DRM_FORCE_UNSPECIFIED;
>
> else
> return -EINVAL;
>
>
> This really looks like a debug-feature to me. If it's a real feature,
> we _must_ rescan connectors here, otherwise it seems odd writing "on"
> into that file but nothing happens until the next modeset.
>
> Thanks
> David
>
>> +
>> +   return count;
>> +}
>> +
>>  static struct device_attribute connector_attrs[] = {
>> __ATTR_RO(status),
>> __ATTR_RO(enabled),
>> __ATTR_RO(dpms),
>> __ATTR_RO(modes),
>> +   __ATTR_RW(force),
>>  };
>>
>>  /* These attributes are for both DVI-I connectors and all types of tv-out. 
>> */
>> --
>> 1.9.0
>>
>> ___
>> dri-devel mailing list
>> dri-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/sysfs: expose the "force" connector attribute

2014-05-19 Thread Thomas Wood
Signed-off-by: Thomas Wood 
---
 drivers/gpu/drm/drm_sysfs.c | 49 +
 1 file changed, 49 insertions(+)

diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index c22c309..257816e 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -338,11 +338,60 @@ static ssize_t select_subconnector_show(struct device 
*device,
drm_get_dvi_i_select_name((int)subconnector));
 }

+static ssize_t force_show(struct device *device,
+ struct device_attribute *attr,
+ char *buf)
+{
+   struct drm_connector *connector = to_drm_connector(device);
+   char *status;
+
+   switch (connector->force) {
+   case DRM_FORCE_ON:
+   status = "on";
+   break;
+
+   case DRM_FORCE_ON_DIGITAL:
+   status = "digital";
+   break;
+
+   case DRM_FORCE_OFF:
+   status = "off";
+   break;
+
+   case DRM_FORCE_UNSPECIFIED:
+   status = "unspecified";
+   break;
+
+   default:
+   return 0;
+   }
+
+   return snprintf(buf, PAGE_SIZE, "%s\n", status);
+}
+
+ssize_t force_store(struct device *device, struct device_attribute *attr,
+   const char *buf, size_t count)
+{
+   struct drm_connector *connector = to_drm_connector(device);
+
+   if (strcmp(buf, "on") == 0)
+   connector->force = DRM_FORCE_ON;
+   else if (strcmp(buf, "digital") == 0)
+   connector->force = DRM_FORCE_ON_DIGITAL;
+   else if (strcmp(buf, "off") == 0)
+   connector->force = DRM_FORCE_OFF;
+   else if (strcmp(buf, "unspecified") == 0)
+   connector->force = DRM_FORCE_UNSPECIFIED;
+
+   return count;
+}
+
 static struct device_attribute connector_attrs[] = {
__ATTR_RO(status),
__ATTR_RO(enabled),
__ATTR_RO(dpms),
__ATTR_RO(modes),
+   __ATTR_RW(force),
 };

 /* These attributes are for both DVI-I connectors and all types of tv-out. */
-- 
1.9.0



[PATCH] drm/edid: parse the list of additional 3D modes

2013-11-29 Thread Thomas Wood
Parse 2D_VIC_order_X and 3D_Structure_X from the list at the end of the
HDMI Vendor Specific Data Block.

v2: Use an offset value depending on 3D_Multi_present and add
detail_present. (Ville Syrj?l?)
v3: Make sure the list is parsed even if 3D_Structure_ALL/MASK is not
present. (Ville Syrj?l?)
Fix one length check and remove another. (Ville Syrj?l?)

Signed-off-by: Thomas Wood 
---
 drivers/gpu/drm/drm_edid.c | 94 +++---
 1 file changed, 73 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index f1d6e1e..4c82a80 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2734,7 +2734,7 @@ static int
 do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len,
   const u8 *video_db, u8 video_len)
 {
-   int modes = 0, offset = 0, i, multi_present = 0;
+   int modes = 0, offset = 0, i, multi_present = 0, multi_len;
u8 vic_len, hdmi_3d_len = 0;
u16 mask;
u16 structure_all;
@@ -2780,32 +2780,84 @@ do_hdmi_vsdb_modes(struct drm_connector *connector, 
const u8 *db, u8 len,
}
offset += 1 + vic_len;

-   if (!(multi_present == 1 || multi_present == 2))
-   goto out;
+   if (multi_present == 1)
+   multi_len = 2;
+   else if (multi_present == 2)
+   multi_len = 4;
+   else
+   multi_len = 0;

-   if ((multi_present == 1 && len < (9 + offset)) ||
-   (multi_present == 2 && len < (11 + offset)))
+   if (len < (8 + offset + hdmi_3d_len - 1))
goto out;

-   if ((multi_present == 1 && hdmi_3d_len < 2) ||
-   (multi_present == 2 && hdmi_3d_len < 4))
+   if (hdmi_3d_len < multi_len)
goto out;

-   /* 3D_Structure_ALL */
-   structure_all = (db[8 + offset] << 8) | db[9 + offset];
+   if (multi_present == 1 || multi_present == 2) {
+   /* 3D_Structure_ALL */
+   structure_all = (db[8 + offset] << 8) | db[9 + offset];

-   /* check if 3D_MASK is present */
-   if (multi_present == 2)
-   mask = (db[10 + offset] << 8) | db[11 + offset];
-   else
-   mask = 0x;
-
-   for (i = 0; i < 16; i++) {
-   if (mask & (1 << i))
-   modes += add_3d_struct_modes(connector,
-structure_all,
-video_db,
-video_len, i);
+   /* check if 3D_MASK is present */
+   if (multi_present == 2)
+   mask = (db[10 + offset] << 8) | db[11 + offset];
+   else
+   mask = 0x;
+
+   for (i = 0; i < 16; i++) {
+   if (mask & (1 << i))
+   modes += add_3d_struct_modes(connector,
+   structure_all,
+   video_db,
+   video_len, i);
+   }
+   }
+
+   offset += multi_len;
+
+   for (i = 0; i < (hdmi_3d_len - multi_len); i++) {
+   int vic_index;
+   struct drm_display_mode *newmode = NULL;
+   unsigned int newflag = 0;
+   bool detail_present;
+
+   detail_present = ((db[8 + offset + i] & 0x0f) > 7);
+
+   if (detail_present && (i + 1 == hdmi_3d_len - multi_len))
+   break;
+
+   /* 2D_VIC_order_X */
+   vic_index = db[8 + offset + i] >> 4;
+
+   /* 3D_Structure_X */
+   switch (db[8 + offset + i] & 0x0f) {
+   case 0:
+   newflag = DRM_MODE_FLAG_3D_FRAME_PACKING;
+   break;
+   case 6:
+   newflag = DRM_MODE_FLAG_3D_TOP_AND_BOTTOM;
+   break;
+   case 8:
+   /* 3D_Detail_X */
+   if ((db[9 + offset + i] >> 4) == 1)
+   newflag = DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF;
+   break;
+   }
+
+   if (newflag != 0) {
+   newmode = drm_display_mode_from_vic_index(connector,
+ video_db,
+ video_len,
+ vic_index);
+
+   if (newmode) {
+   newmode->flags |= newflag;
+   drm_mode_probed_add(connector, newmode);
+  

[PATCH 3/3] drm/edid: parse the list of additional 3D modes

2013-11-29 Thread Thomas Wood
Parse 2D_VIC_order_X and 3D_Structure_X from the list at the end of the
HDMI Vendor Specific Data Block.

v2: Use an offset value depending on 3D_Multi_present and add
detail_present. (Ville Syrj?l?)

Signed-off-by: Thomas Wood 
---
 drivers/gpu/drm/drm_edid.c | 64 ++
 1 file changed, 59 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index f1d6e1e..9426563 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2734,7 +2734,7 @@ static int
 do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len,
   const u8 *video_db, u8 video_len)
 {
-   int modes = 0, offset = 0, i, multi_present = 0;
+   int modes = 0, offset = 0, i, multi_present = 0, multi_len;
u8 vic_len, hdmi_3d_len = 0;
u16 mask;
u16 structure_all;
@@ -2783,12 +2783,15 @@ do_hdmi_vsdb_modes(struct drm_connector *connector, 
const u8 *db, u8 len,
if (!(multi_present == 1 || multi_present == 2))
goto out;

-   if ((multi_present == 1 && len < (9 + offset)) ||
-   (multi_present == 2 && len < (11 + offset)))
+   if (multi_present == 1)
+   multi_len = 2;
+   else
+   multi_len = 4;
+
+   if (len < (offset + hdmi_3d_len))
goto out;

-   if ((multi_present == 1 && hdmi_3d_len < 2) ||
-   (multi_present == 2 && hdmi_3d_len < 4))
+   if (hdmi_3d_len < multi_len)
goto out;

/* 3D_Structure_ALL */
@@ -2808,6 +2811,57 @@ do_hdmi_vsdb_modes(struct drm_connector *connector, 
const u8 *db, u8 len,
 video_len, i);
}

+   if (hdmi_3d_len <= multi_len)
+   goto out;
+
+   offset += multi_len;
+
+   for (i = 0; i < (hdmi_3d_len - multi_len); i++) {
+   int vic_index;
+   struct drm_display_mode *newmode = NULL;
+   unsigned int newflag = 0;
+   bool detail_present;
+
+   detail_present = ((db[8 + offset + i] & 0x0f) > 7);
+
+   if (detail_present && (i + 1 == hdmi_3d_len - multi_len))
+   break;
+
+   /* 2D_VIC_order_X */
+   vic_index = db[8 + offset + i] >> 4;
+
+   /* 3D_Structure_X */
+   switch (db[8 + offset + i] & 0x0f) {
+   case 0:
+   newflag = DRM_MODE_FLAG_3D_FRAME_PACKING;
+   break;
+   case 6:
+   newflag = DRM_MODE_FLAG_3D_TOP_AND_BOTTOM;
+   break;
+   case 8:
+   /* 3D_Detail_X */
+   if ((db[9 + offset + i] >> 4) == 1)
+   newflag = DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF;
+   break;
+   }
+
+   if (newflag != 0) {
+   newmode = drm_display_mode_from_vic_index(connector,
+ video_db,
+ video_len,
+ vic_index);
+
+   if (newmode) {
+   newmode->flags |= newflag;
+   drm_mode_probed_add(connector, newmode);
+   modes++;
+   }
+   }
+
+   if (detail_present)
+   i++;
+   }
+
 out:
return modes;
 }
-- 
1.8.4.2



[PATCH 2/3] drm/edid: split VIC display mode lookup into a separate function

2013-11-29 Thread Thomas Wood
Signed-off-by: Thomas Wood 
---
 drivers/gpu/drm/drm_edid.c | 67 +++---
 1 file changed, 39 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 0a1e4a5..f1d6e1e 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2557,25 +2557,40 @@ add_alternate_cea_modes(struct drm_connector 
*connector, struct edid *edid)
return modes;
 }

-static int
-do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len)
+static struct drm_display_mode *
+drm_display_mode_from_vic_index(struct drm_connector *connector,
+   const u8 *video_db, u8 video_len,
+   u8 video_index)
 {
struct drm_device *dev = connector->dev;
-   const u8 *mode;
+   struct drm_display_mode *newmode;
u8 cea_mode;
-   int modes = 0;

-   for (mode = db; mode < db + len; mode++) {
-   cea_mode = (*mode & 127) - 1; /* CEA modes are numbered 1..127 
*/
-   if (cea_mode < ARRAY_SIZE(edid_cea_modes)) {
-   struct drm_display_mode *newmode;
-   newmode = drm_mode_duplicate(dev,
-_cea_modes[cea_mode]);
-   if (newmode) {
-   newmode->vrefresh = 0;
-   drm_mode_probed_add(connector, newmode);
-   modes++;
-   }
+   if (video_db == NULL || video_index >= video_len)
+   return NULL;
+
+   /* CEA modes are numbered 1..127 */
+   cea_mode = (video_db[video_index] & 127) - 1;
+   if (cea_mode >= ARRAY_SIZE(edid_cea_modes))
+   return NULL;
+
+   newmode = drm_mode_duplicate(dev, _cea_modes[cea_mode]);
+   newmode->vrefresh = 0;
+
+   return newmode;
+}
+
+static int
+do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len)
+{
+   int i, modes = 0;
+
+   for (i = 0; i < len; i++) {
+   struct drm_display_mode *mode;
+   mode = drm_display_mode_from_vic_index(connector, db, len, i);
+   if (mode) {
+   drm_mode_probed_add(connector, mode);
+   modes++;
}
}

@@ -2669,21 +2684,13 @@ static int add_hdmi_mode(struct drm_connector 
*connector, u8 vic)
 static int add_3d_struct_modes(struct drm_connector *connector, u16 structure,
   const u8 *video_db, u8 video_len, u8 video_index)
 {
-   struct drm_device *dev = connector->dev;
struct drm_display_mode *newmode;
int modes = 0;
-   u8 cea_mode;
-
-   if (video_db == NULL || video_index >= video_len)
-   return 0;
-
-   /* CEA modes are numbered 1..127 */
-   cea_mode = (video_db[video_index] & 127) - 1;
-   if (cea_mode >= ARRAY_SIZE(edid_cea_modes))
-   return 0;

if (structure & (1 << 0)) {
-   newmode = drm_mode_duplicate(dev, _cea_modes[cea_mode]);
+   newmode = drm_display_mode_from_vic_index(connector, video_db,
+ video_len,
+ video_index);
if (newmode) {
newmode->flags |= DRM_MODE_FLAG_3D_FRAME_PACKING;
drm_mode_probed_add(connector, newmode);
@@ -2691,7 +2698,9 @@ static int add_3d_struct_modes(struct drm_connector 
*connector, u16 structure,
}
}
if (structure & (1 << 6)) {
-   newmode = drm_mode_duplicate(dev, _cea_modes[cea_mode]);
+   newmode = drm_display_mode_from_vic_index(connector, video_db,
+ video_len,
+ video_index);
if (newmode) {
newmode->flags |= DRM_MODE_FLAG_3D_TOP_AND_BOTTOM;
drm_mode_probed_add(connector, newmode);
@@ -2699,7 +2708,9 @@ static int add_3d_struct_modes(struct drm_connector 
*connector, u16 structure,
}
}
if (structure & (1 << 8)) {
-   newmode = drm_mode_duplicate(dev, _cea_modes[cea_mode]);
+   newmode = drm_display_mode_from_vic_index(connector, video_db,
+ video_len,
+ video_index);
if (newmode) {
newmode->flags |= DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF;
drm_mode_probed_add(connector, newmode);
-- 
1.8.4.2



[PATCH 1/3] drm/edid: fix length check when adding extra 3D modes

2013-11-29 Thread Thomas Wood
Signed-off-by: Thomas Wood 
---
 drivers/gpu/drm/drm_edid.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 52e060e..0a1e4a5 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2674,7 +2674,7 @@ static int add_3d_struct_modes(struct drm_connector 
*connector, u16 structure,
int modes = 0;
u8 cea_mode;

-   if (video_db == NULL || video_index > video_len)
+   if (video_db == NULL || video_index >= video_len)
return 0;

/* CEA modes are numbered 1..127 */
-- 
1.8.4.2



Parse the list of additional 3D modes (v2)

2013-11-29 Thread Thomas Wood
Here's an updated series of patches taking into account Ville's review.

Regards,

Thomas



[PATCH 2/2] drm/edid: parse the list of additional 3D modes

2013-11-28 Thread Thomas Wood
Parse 2D_VIC_order_X and 3D_Structure_X from the list at the end of the
HDMI Vendor Specific Data Block.

Signed-off-by: Thomas Wood 
---
 drivers/gpu/drm/drm_edid.c | 50 ++
 1 file changed, 50 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 1dd82cd..eb6b363 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2808,6 +2808,56 @@ do_hdmi_vsdb_modes(struct drm_connector *connector, 
const u8 *db, u8 len,
 video_len, i);
}

+   if (hdmi_3d_len <= 4)
+   goto out;
+
+   offset += 4;
+
+   for (i = 0; i < (hdmi_3d_len - 4); i++) {
+   int vic_index;
+   struct drm_display_mode *newmode = NULL;
+   unsigned int newflag = 0;
+
+   if (((db[8 + offset + i] & 0x0f) > 7)
+   && (i + 1 == hdmi_3d_len - 4))
+   break;
+
+   /* 2D_VIC_order_X */
+   vic_index = db[8 + offset + i] >> 4;
+
+   /* 3D_Structure_X */
+   switch (db[8 + offset + i] & 0x0f) {
+   case 0:
+   newflag = DRM_MODE_FLAG_3D_FRAME_PACKING;
+   break;
+   case 6:
+   newflag = DRM_MODE_FLAG_3D_TOP_AND_BOTTOM;
+   break;
+   case 8:
+   if ((db[9 + offset + i] >> 4) == 1)
+   newflag = DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF;
+   break;
+   }
+
+   if (newflag != 0) {
+   newmode = drm_display_mode_from_vic_index(connector,
+ video_db,
+ video_len,
+ vic_index);
+
+   if (newmode) {
+   newmode->flags |= newflag;
+   drm_mode_probed_add(connector, newmode);
+   modes++;
+   }
+   }
+
+   if ((db[8 + offset + i] & 0x0f) > 7) {
+   /* Optional 3D_Detail_X and reserved */
+   i++;
+   }
+   }
+
 out:
return modes;
 }
-- 
1.8.4.2



[PATCH 1/2] drm/edid: split VIC display mode lookup into a separate function

2013-11-28 Thread Thomas Wood
Signed-off-by: Thomas Wood 
---
 drivers/gpu/drm/drm_edid.c | 67 +++---
 1 file changed, 39 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 52e060e..1dd82cd 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2557,25 +2557,40 @@ add_alternate_cea_modes(struct drm_connector 
*connector, struct edid *edid)
return modes;
 }

-static int
-do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len)
+static struct drm_display_mode *
+drm_display_mode_from_vic_index(struct drm_connector *connector,
+   const u8 *video_db, u8 video_len,
+   u8 video_index)
 {
struct drm_device *dev = connector->dev;
-   const u8 *mode;
+   struct drm_display_mode *newmode;
u8 cea_mode;
-   int modes = 0;

-   for (mode = db; mode < db + len; mode++) {
-   cea_mode = (*mode & 127) - 1; /* CEA modes are numbered 1..127 
*/
-   if (cea_mode < ARRAY_SIZE(edid_cea_modes)) {
-   struct drm_display_mode *newmode;
-   newmode = drm_mode_duplicate(dev,
-_cea_modes[cea_mode]);
-   if (newmode) {
-   newmode->vrefresh = 0;
-   drm_mode_probed_add(connector, newmode);
-   modes++;
-   }
+   if (video_db == NULL || video_index > video_len)
+   return NULL;
+
+   /* CEA modes are numbered 1..127 */
+   cea_mode = (video_db[video_index] & 127) - 1;
+   if (cea_mode >= ARRAY_SIZE(edid_cea_modes))
+   return NULL;
+
+   newmode = drm_mode_duplicate(dev, _cea_modes[cea_mode]);
+   newmode->vrefresh = 0;
+
+   return newmode;
+}
+
+static int
+do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len)
+{
+   int i, modes = 0;
+
+   for (i = 0; i < len; i++) {
+   struct drm_display_mode *mode;
+   mode = drm_display_mode_from_vic_index(connector, db, len, i);
+   if (mode) {
+   drm_mode_probed_add(connector, mode);
+   modes++;
}
}

@@ -2669,21 +2684,13 @@ static int add_hdmi_mode(struct drm_connector 
*connector, u8 vic)
 static int add_3d_struct_modes(struct drm_connector *connector, u16 structure,
   const u8 *video_db, u8 video_len, u8 video_index)
 {
-   struct drm_device *dev = connector->dev;
struct drm_display_mode *newmode;
int modes = 0;
-   u8 cea_mode;
-
-   if (video_db == NULL || video_index > video_len)
-   return 0;
-
-   /* CEA modes are numbered 1..127 */
-   cea_mode = (video_db[video_index] & 127) - 1;
-   if (cea_mode >= ARRAY_SIZE(edid_cea_modes))
-   return 0;

if (structure & (1 << 0)) {
-   newmode = drm_mode_duplicate(dev, _cea_modes[cea_mode]);
+   newmode = drm_display_mode_from_vic_index(connector, video_db,
+ video_len,
+ video_index);
if (newmode) {
newmode->flags |= DRM_MODE_FLAG_3D_FRAME_PACKING;
drm_mode_probed_add(connector, newmode);
@@ -2691,7 +2698,9 @@ static int add_3d_struct_modes(struct drm_connector 
*connector, u16 structure,
}
}
if (structure & (1 << 6)) {
-   newmode = drm_mode_duplicate(dev, _cea_modes[cea_mode]);
+   newmode = drm_display_mode_from_vic_index(connector, video_db,
+ video_len,
+ video_index);
if (newmode) {
newmode->flags |= DRM_MODE_FLAG_3D_TOP_AND_BOTTOM;
drm_mode_probed_add(connector, newmode);
@@ -2699,7 +2708,9 @@ static int add_3d_struct_modes(struct drm_connector 
*connector, u16 structure,
}
}
if (structure & (1 << 8)) {
-   newmode = drm_mode_duplicate(dev, _cea_modes[cea_mode]);
+   newmode = drm_display_mode_from_vic_index(connector, video_db,
+ video_len,
+ video_index);
if (newmode) {
newmode->flags |= DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF;
drm_mode_probed_add(connector, newmode);
-- 
1.8.4.2



Parse the list of additional 3D modes

2013-11-28 Thread Thomas Wood
Hi,

The following two patches add support for parsing the list of additional 3D
modes at the end of the vendor specific data block. The first splits the VIC
display mode lookup into a separate function so that it can be reused. The
second patch parses the list, adding any support modes to the connector.

Regards,

Thomas



[PATCH] drm: fix the addition of the side-by-side (half) flag for extra 3D modes

2013-11-28 Thread Thomas Wood
Ensure the side-by-side (half) flag is added to any existing flags when
adding modes from 3D_Structure_ALL.

Signed-off-by: Thomas Wood 
---
 drivers/gpu/drm/drm_edid.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index fb7cf0e..52e060e 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2701,7 +2701,7 @@ static int add_3d_struct_modes(struct drm_connector 
*connector, u16 structure,
if (structure & (1 << 8)) {
newmode = drm_mode_duplicate(dev, _cea_modes[cea_mode]);
if (newmode) {
-   newmode->flags = DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF;
+   newmode->flags |= DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF;
drm_mode_probed_add(connector, newmode);
modes++;
}
-- 
1.8.4.2



[PATCH v2 edid-decode] Parse the list of additional 3D modes

2013-11-27 Thread Thomas Wood
Parse 2D_VIC_order_X and 3D_Structure_X from the list at the end of the
HDMI Vendor Specific Block.

v2: check 3D_Detail_X indicates horizontal sub-sampling in side-by-side
(half) mode

Signed-off-by: Thomas Wood 
---
 edid-decode.c | 29 -
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/edid-decode.c b/edid-decode.c
index 4265843..3f7e4da 100644
--- a/edid-decode.c
+++ b/edid-decode.c
@@ -851,6 +851,7 @@ cea_hdmi_block(unsigned char *x)
if (x[10 + b] & 0x01)
printf("  3D: Frame-packing\n");
b += 2;
+   len_3d -= 2;
}
if (mask) {
int i;
@@ -864,14 +865,40 @@ cea_hdmi_block(unsigned char *x)
printf(" %d", i + 8);
printf("\n");
b += 2;
+   len_3d -= 2;
}

/*
-* XXX list of nibbles:
+* list of nibbles:
 * 2D_VIC_Order_X
 * 3D_Structure_X
 * (optionally: 3D_Detail_X and reserved)
 */
+   if (len_3d > 0) {
+   int end = b + len_3d;
+
+   while (b < end) {
+   printf("  VIC index %d supports ", x[9 + b] 
>> 4);
+   switch (x[9 + b] & 0x0f) {
+   case 0: printf("frame packing"); break;
+   case 6: printf("top-and-bottom"); break;
+   case 8:
+   if ((x[10 + b] >> 4) == 1) {
+   printf("side-by-side (half, 
horizontal)");
+   break;
+   }
+   default: printf("unknown");
+   }
+   printf("\n");
+
+   if ((x[9 + b] & 0x0f) > 7) {
+   /* Optional 3D_Detail_X and reserved */
+   b++;
+   }
+   b++;
+   }
+   }
+
}

}
-- 
1.8.4.2



[PATCH edid-decode] Parse the list of additional 3D modes

2013-10-16 Thread Thomas Wood
Parse 2D_VIC_order_X and 3D_Structure_X from the list at the end of the
HDMI Vendor Specific Block.

Signed-off-by: Thomas Wood 
---
 edid-decode.c | 24 +++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/edid-decode.c b/edid-decode.c
index 4265843..8441dec 100644
--- a/edid-decode.c
+++ b/edid-decode.c
@@ -851,6 +851,7 @@ cea_hdmi_block(unsigned char *x)
if (x[10 + b] & 0x01)
printf("  3D: Frame-packing\n");
b += 2;
+   len_3d -= 2;
}
if (mask) {
int i;
@@ -864,14 +865,35 @@ cea_hdmi_block(unsigned char *x)
printf(" %d", i + 8);
printf("\n");
b += 2;
+   len_3d -= 2;
}

/*
-* XXX list of nibbles:
+* list of nibbles:
 * 2D_VIC_Order_X
 * 3D_Structure_X
 * (optionally: 3D_Detail_X and reserved)
 */
+   if (len_3d > 0) {
+   int end = b + len_3d;
+
+   while (b < end) {
+   printf("  VIC index %d supports ", x[9 + b] 
>> 4);
+   switch (x[9 + b] & 0x0f) {
+   case 0: printf("frame packing"); break;
+   case 6: printf("top-and-bottom"); break;
+   case 8: printf("side-by-side (half)"); 
break;
+   default: printf("unknown");
+   }
+   if ((x[9 + b] & 0x0f) > 7) {
+   /* XXX Optional 3D_Detail_X and 
reserved */
+   b++;
+   }
+   printf("\n");
+   b++;
+   }
+   }
+
}

}
-- 
1.8.3.1



[PATCH v3] drm: add support for additional stereo 3D modes

2013-10-16 Thread Thomas Wood
Parse the 3D_Structure_ALL and 3D_MASK fields of the HDMI Vendor
Specific Data Block to expose more stereo 3D modes.

v2: Use (1 << 0) for consistency. (Ville Syrj?l?)
Skip adding any modes if 3D_MASK is indicated as being present but
the length only includes 3D_Structure_ALL. (Ville Syrj?l?)
Check that the value of HDMI_3D_LEN is large enough to include
3D_Structure_ALL and 3D_MASK, if they are present. (Ville Syrj?l?)
v3: Increment offset before the length checks. (Ville Syrj?l?)

Signed-off-by: Thomas Wood 
---
 drivers/gpu/drm/drm_edid.c | 103 +
 1 file changed, 94 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 9e81609..f1764ec 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2652,6 +2652,50 @@ static int add_hdmi_mode(struct drm_connector 
*connector, u8 vic)
return 1;
 }

+static int add_3d_struct_modes(struct drm_connector *connector, u16 structure,
+  const u8 *video_db, u8 video_len, u8 video_index)
+{
+   struct drm_device *dev = connector->dev;
+   struct drm_display_mode *newmode;
+   int modes = 0;
+   u8 cea_mode;
+
+   if (video_db == NULL || video_index > video_len)
+   return 0;
+
+   /* CEA modes are numbered 1..127 */
+   cea_mode = (video_db[video_index] & 127) - 1;
+   if (cea_mode >= ARRAY_SIZE(edid_cea_modes))
+   return 0;
+
+   if (structure & (1 << 0)) {
+   newmode = drm_mode_duplicate(dev, _cea_modes[cea_mode]);
+   if (newmode) {
+   newmode->flags |= DRM_MODE_FLAG_3D_FRAME_PACKING;
+   drm_mode_probed_add(connector, newmode);
+   modes++;
+   }
+   }
+   if (structure & (1 << 6)) {
+   newmode = drm_mode_duplicate(dev, _cea_modes[cea_mode]);
+   if (newmode) {
+   newmode->flags |= DRM_MODE_FLAG_3D_TOP_AND_BOTTOM;
+   drm_mode_probed_add(connector, newmode);
+   modes++;
+   }
+   }
+   if (structure & (1 << 8)) {
+   newmode = drm_mode_duplicate(dev, _cea_modes[cea_mode]);
+   if (newmode) {
+   newmode->flags = DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF;
+   drm_mode_probed_add(connector, newmode);
+   modes++;
+   }
+   }
+
+   return modes;
+}
+
 /*
  * do_hdmi_vsdb_modes - Parse the HDMI Vendor Specific data block
  * @connector: connector corresponding to the HDMI sink
@@ -2662,10 +2706,13 @@ static int add_hdmi_mode(struct drm_connector 
*connector, u8 vic)
  * also adds the stereo 3d modes when applicable.
  */
 static int
-do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len)
+do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len,
+  const u8 *video_db, u8 video_len)
 {
-   int modes = 0, offset = 0, i;
-   u8 vic_len;
+   int modes = 0, offset = 0, i, multi_present = 0;
+   u8 vic_len, hdmi_3d_len = 0;
+   u16 mask;
+   u16 structure_all;

if (len < 8)
goto out;
@@ -2689,11 +2736,16 @@ do_hdmi_vsdb_modes(struct drm_connector *connector, 
const u8 *db, u8 len)

/* 3D_Present */
offset++;
-   if (db[8 + offset] & (1 << 7))
+   if (db[8 + offset] & (1 << 7)) {
modes += add_hdmi_mandatory_stereo_modes(connector);

+   /* 3D_Multi_present */
+   multi_present = (db[8 + offset] & 0x60) >> 5;
+   }
+
offset++;
vic_len = db[8 + offset] >> 5;
+   hdmi_3d_len = db[8 + offset] & 0x1f;

for (i = 0; i < vic_len && len >= (9 + offset + i); i++) {
u8 vic;
@@ -2701,6 +2753,35 @@ do_hdmi_vsdb_modes(struct drm_connector *connector, 
const u8 *db, u8 len)
vic = db[9 + offset + i];
modes += add_hdmi_mode(connector, vic);
}
+   offset += 1 + vic_len;
+
+   if (!(multi_present == 1 || multi_present == 2))
+   goto out;
+
+   if ((multi_present == 1 && len < (9 + offset)) ||
+   (multi_present == 2 && len < (11 + offset)))
+   goto out;
+
+   if ((multi_present == 1 && hdmi_3d_len < 2) ||
+   (multi_present == 2 && hdmi_3d_len < 4))
+   goto out;
+
+   /* 3D_Structure_ALL */
+   structure_all = (db[8 + offset] << 8) | db[9 + offset];
+
+   /* check if 3D_MASK is present */
+   if (multi_present == 2)
+   mask = (db[10 + offset] << 8) | db[11 + offset];
+   else
+   mask = 0x;
+
+   for (i = 0; i < 16; 

[PATCH v2] drm: add support for additional stereo 3D modes

2013-10-15 Thread Thomas Wood
Parse the 3D_Structure_ALL and 3D_MASK fields of the HDMI Vendor
Specific Data Block to expose more stereo 3D modes.

Signed-off-by: Thomas Wood 
---
 drivers/gpu/drm/drm_edid.c | 105 +
 1 file changed, 96 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 9e81609..456a694 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2652,6 +2652,50 @@ static int add_hdmi_mode(struct drm_connector 
*connector, u8 vic)
return 1;
 }

+static int add_3d_struct_modes(struct drm_connector *connector, u16 structure,
+  const u8 *video_db, u8 video_len, u8 video_index)
+{
+   struct drm_device *dev = connector->dev;
+   struct drm_display_mode *newmode;
+   int modes = 0;
+   u8 cea_mode;
+
+   if (video_db == NULL || video_index > video_len)
+   return 0;
+
+   /* CEA modes are numbered 1..127 */
+   cea_mode = (video_db[video_index] & 127) - 1;
+   if (cea_mode >= ARRAY_SIZE(edid_cea_modes))
+   return 0;
+
+   if (structure & (1 << 0)) {
+   newmode = drm_mode_duplicate(dev, _cea_modes[cea_mode]);
+   if (newmode) {
+   newmode->flags |= DRM_MODE_FLAG_3D_FRAME_PACKING;
+   drm_mode_probed_add(connector, newmode);
+   modes++;
+   }
+   }
+   if (structure & (1 << 6)) {
+   newmode = drm_mode_duplicate(dev, _cea_modes[cea_mode]);
+   if (newmode) {
+   newmode->flags |= DRM_MODE_FLAG_3D_TOP_AND_BOTTOM;
+   drm_mode_probed_add(connector, newmode);
+   modes++;
+   }
+   }
+   if (structure & (1 << 8)) {
+   newmode = drm_mode_duplicate(dev, _cea_modes[cea_mode]);
+   if (newmode) {
+   newmode->flags = DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF;
+   drm_mode_probed_add(connector, newmode);
+   modes++;
+   }
+   }
+
+   return modes;
+}
+
 /*
  * do_hdmi_vsdb_modes - Parse the HDMI Vendor Specific data block
  * @connector: connector corresponding to the HDMI sink
@@ -2662,10 +2706,13 @@ static int add_hdmi_mode(struct drm_connector 
*connector, u8 vic)
  * also adds the stereo 3d modes when applicable.
  */
 static int
-do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len)
+do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len,
+  const u8 *video_db, u8 video_len)
 {
-   int modes = 0, offset = 0, i;
-   u8 vic_len;
+   int modes = 0, offset = 0, i, multi_present = 0;
+   u8 vic_len, hdmi_3d_len;
+   u16 mask;
+   u16 structure_all;

if (len < 8)
goto out;
@@ -2689,9 +2736,13 @@ do_hdmi_vsdb_modes(struct drm_connector *connector, 
const u8 *db, u8 len)

/* 3D_Present */
offset++;
-   if (db[8 + offset] & (1 << 7))
+   if (db[8 + offset] & (1 << 7)) {
modes += add_hdmi_mandatory_stereo_modes(connector);

+   /* 3D_Multi_present */
+   multi_present = (db[8 + offset] & 0x60) >> 5;
+   }
+
offset++;
vic_len = db[8 + offset] >> 5;

@@ -2702,6 +2753,38 @@ do_hdmi_vsdb_modes(struct drm_connector *connector, 
const u8 *db, u8 len)
modes += add_hdmi_mode(connector, vic);
}

+   if (!(multi_present == 1 || multi_present == 2))
+   goto out;
+
+   if ((multi_present == 1 && len < (9 + offset)) ||
+   (multi_present == 2 && len < (11 + offset)))
+   goto out;
+
+   hdmi_3d_len = db[8 + offset] & 0x1f;
+
+   if ((multi_present == 1 && hdmi_3d_len < 2) ||
+   (multi_present == 2 && hdmi_3d_len < 4))
+   goto out;
+
+   offset += 1 + vic_len;
+
+   /* 3D_Structure_ALL */
+   structure_all = (db[8 + offset] << 8) | db[9 + offset];
+
+   /* check if 3D_MASK is present */
+   if (multi_present == 2)
+   mask = (db[10 + offset] << 8) | db[11 + offset];
+   else
+   mask = 0x;
+
+   for (i = 0; i < 16; i++) {
+   if (mask & (1 << i))
+   modes += add_3d_struct_modes(connector,
+structure_all,
+video_db,
+video_len, i);
+   }
+
 out:
return modes;
 }
@@ -2759,8 +2842,8 @@ static int
 add_cea_modes(struct drm_connector *connector, struct edid *edid)
 {
const u8 *cea = drm_find_cea_extension(edid);
-   const u8 *db, *hdmi =

[PATCH] drm: add support for additional stereo 3D modes

2013-10-15 Thread Thomas Wood
On 11 October 2013 12:12, Ville Syrjälä ville.syrj...@linux.intel.com wrote:
 On Thu, Oct 10, 2013 at 02:19:15PM +0100, Thomas Wood wrote:
 Parse the 3D_Structure_ALL and 3D_MASK fields of the HDMI Vendor
 Specific Data Block to expose more stereo 3D modes.

 Signed-off-by: Thomas Wood thomas.w...@intel.com
 ---
  drivers/gpu/drm/drm_edid.c | 93 
 ++
  1 file changed, 85 insertions(+), 8 deletions(-)

 diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
 index 9e81609..b3949f9 100644
 --- a/drivers/gpu/drm/drm_edid.c
 +++ b/drivers/gpu/drm/drm_edid.c
 @@ -2652,6 +2652,50 @@ static int add_hdmi_mode(struct drm_connector 
 *connector, u8 vic)
   return 1;
  }

 +static int add_3d_struct_modes(struct drm_connector *connector, u16 
 structure,
 +const u8 *video_db, u8 video_len, u8 
 video_index)
 +{
 + struct drm_device *dev = connector-dev;
 + struct drm_display_mode *newmode;
 + int modes = 0;
 + u8 cea_mode;
 +
 + if (video_db == NULL || video_index  video_len)
 + return 0;
 +
 + /* CEA modes are numbered 1..127 */
 + cea_mode = (video_db[video_index]  127) - 1;
 + if (cea_mode = ARRAY_SIZE(edid_cea_modes))
 + return 0;
 +
 + if (structure  1) {

 Could use (1  0) for consistency.

I've updated this for v2.


 I'm also wondering if some displays might include some of the mandatory
 modes in 3D_Structure_ALL, and if so should we filter out the
 duplicates?

As Damien mentioned, duplicates are filtered out later on.


 + if ((multi_present == 1 || multi_present == 2) 
 + len = (9 + offset)) {

 If multi_present==2 and len is too small for the mask, I think we should
 skip adding the modes since the block is clearly incorrect/corrupted.

 So maybe just something like this:
  if ((multi_present == 1  len  (9 + offset)) ||
  (multi_present == 2  len  (11 + offset)))
  goto out;

I've added this check to v2 and also made sure multi_present is either 1 or 2
before continuing.


 I would also add a similar check for HDMI_3D_LEN since that is
 supposed to include the space required by 3D_Structure_ALL and
 3D_MASK. Or you could just check HDMI_3D_LEN against 'len' and bail
 out if that doesn't fit. And then you could just check
 3D_Structure_ALL and 3D_MASK against HDMI_3D_LEN.


I've added a check to ensure the value of HDMI_3D_LEN is large enough to
include 3D_Structure_ALL and 3D_MASK, if they are present.

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm: add support for additional stereo 3D modes

2013-10-10 Thread Thomas Wood
Parse the 3D_Structure_ALL and 3D_MASK fields of the HDMI Vendor
Specific Data Block to expose more stereo 3D modes.

Signed-off-by: Thomas Wood thomas.w...@intel.com
---
 drivers/gpu/drm/drm_edid.c | 93 ++
 1 file changed, 85 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 9e81609..b3949f9 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2652,6 +2652,50 @@ static int add_hdmi_mode(struct drm_connector 
*connector, u8 vic)
return 1;
 }
 
+static int add_3d_struct_modes(struct drm_connector *connector, u16 structure,
+  const u8 *video_db, u8 video_len, u8 video_index)
+{
+   struct drm_device *dev = connector-dev;
+   struct drm_display_mode *newmode;
+   int modes = 0;
+   u8 cea_mode;
+
+   if (video_db == NULL || video_index  video_len)
+   return 0;
+
+   /* CEA modes are numbered 1..127 */
+   cea_mode = (video_db[video_index]  127) - 1;
+   if (cea_mode = ARRAY_SIZE(edid_cea_modes))
+   return 0;
+
+   if (structure  1) {
+   newmode = drm_mode_duplicate(dev, edid_cea_modes[cea_mode]);
+   if (newmode) {
+   newmode-flags |= DRM_MODE_FLAG_3D_FRAME_PACKING;
+   drm_mode_probed_add(connector, newmode);
+   modes++;
+   }
+   }
+   if (structure  (1  6)) {
+   newmode = drm_mode_duplicate(dev, edid_cea_modes[cea_mode]);
+   if (newmode) {
+   newmode-flags |= DRM_MODE_FLAG_3D_TOP_AND_BOTTOM;
+   drm_mode_probed_add(connector, newmode);
+   modes++;
+   }
+   }
+   if (structure  (1  8)) {
+   newmode = drm_mode_duplicate(dev, edid_cea_modes[cea_mode]);
+   if (newmode) {
+   newmode-flags = DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF;
+   drm_mode_probed_add(connector, newmode);
+   modes++;
+   }
+   }
+
+   return modes;
+}
+
 /*
  * do_hdmi_vsdb_modes - Parse the HDMI Vendor Specific data block
  * @connector: connector corresponding to the HDMI sink
@@ -2662,10 +2706,13 @@ static int add_hdmi_mode(struct drm_connector 
*connector, u8 vic)
  * also adds the stereo 3d modes when applicable.
  */
 static int
-do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len)
+do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len,
+  const u8 *video_db, u8 video_len)
 {
-   int modes = 0, offset = 0, i;
+   int modes = 0, offset = 0, i, multi_present = 0;
u8 vic_len;
+   u16 mask;
+   u16 structure_all;
 
if (len  8)
goto out;
@@ -2689,9 +2736,13 @@ do_hdmi_vsdb_modes(struct drm_connector *connector, 
const u8 *db, u8 len)
 
/* 3D_Present */
offset++;
-   if (db[8 + offset]  (1  7))
+   if (db[8 + offset]  (1  7)) {
modes += add_hdmi_mandatory_stereo_modes(connector);
 
+   /* 3D_Multi_present */
+   multi_present = (db[8 + offset]  0x60)  5;
+   }
+
offset++;
vic_len = db[8 + offset]  5;
 
@@ -2702,6 +2753,28 @@ do_hdmi_vsdb_modes(struct drm_connector *connector, 
const u8 *db, u8 len)
modes += add_hdmi_mode(connector, vic);
}
 
+   offset += 1 + vic_len;
+
+   if ((multi_present == 1 || multi_present == 2) 
+   len = (9 + offset)) {
+   /* 3D_Structure_ALL */
+   structure_all = (db[8 + offset]  8) | db[9 + offset];
+
+   /* check if 3D_MASK is present */
+   if (multi_present == 2  len = 11 + offset)
+   mask = (db[10 + offset]  8) | db[11 + offset];
+   else
+   mask = 0x;
+
+   for (i = 0; i  16; i++) {
+   if (mask  (1  i))
+   modes += add_3d_struct_modes(connector,
+structure_all,
+video_db,
+video_len, i);
+   }
+   }
+
 out:
return modes;
 }
@@ -2759,8 +2832,8 @@ static int
 add_cea_modes(struct drm_connector *connector, struct edid *edid)
 {
const u8 *cea = drm_find_cea_extension(edid);
-   const u8 *db, *hdmi = NULL;
-   u8 dbl, hdmi_len;
+   const u8 *db, *hdmi = NULL, *video = NULL;
+   u8 dbl, hdmi_len, video_len = 0;
int modes = 0;
 
if (cea  cea_revision(cea) = 3) {
@@ -2773,8 +2846,11 @@ add_cea_modes(struct drm_connector *connector, struct 
edid *edid)
db = cea[i];
dbl = cea_db_payload_len(db

[PATCH edid-decode 2/3] Include the last VIC in the CEA video block

2013-09-27 Thread Thomas Wood
Signed-off-by: Thomas Wood thomas.w...@intel.com
---
 edid-decode.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/edid-decode.c b/edid-decode.c
index 3830e0c..b710bb5 100644
--- a/edid-decode.c
+++ b/edid-decode.c
@@ -711,7 +711,7 @@ cea_video_block(unsigned char *x)
 int i;
 int length = x[0]  0x1f;
 
-for (i = 1; i  length; i++)  {
+for (i = 1; i = length; i++)  {
unsigned char vic = x[i]  0x7f;
unsigned char native = x[i]  0x80;
const char *mode;
-- 
1.8.3.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH edid-decode 1/3] Add a missing comma to the list of CEA VICs

2013-09-27 Thread Thomas Wood
Signed-off-by: Thomas Wood thomas.w...@intel.com
---
 edid-decode.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/edid-decode.c b/edid-decode.c
index d3e3118..3830e0c 100644
--- a/edid-decode.c
+++ b/edid-decode.c
@@ -649,7 +649,7 @@ static const char *edid_cea_modes[] = {
 1440x240@60Hz,
 1440x240@60Hz,
 2880x480i@60Hz,
-2880x480i@60Hz
+2880x480i@60Hz,
 2880x240@60Hz,
 2880x240@60Hz,
 1440x480@60Hz,
-- 
1.8.3.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH edid-decode 3/3] Print the correct VIC number next to the mode

2013-09-27 Thread Thomas Wood
Signed-off-by: Thomas Wood thomas.w...@intel.com
---
 edid-decode.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/edid-decode.c b/edid-decode.c
index b710bb5..4265843 100644
--- a/edid-decode.c
+++ b/edid-decode.c
@@ -715,10 +715,11 @@ cea_video_block(unsigned char *x)
unsigned char vic = x[i]  0x7f;
unsigned char native = x[i]  0x80;
const char *mode;
+   int index;
 
-   vic--;
-   if (vic  ARRAY_SIZE(edid_cea_modes))
-   mode = edid_cea_modes[vic];
+   index = vic - 1;
+   if (index  ARRAY_SIZE(edid_cea_modes))
+   mode = edid_cea_modes[index];
else
mode = Unknown mode;
 
-- 
1.8.3.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel