diff mbox

[U-Boot,1/5] edid: add function to convert edid to fb_videomode

Message ID 1389165866-17509-1-git-send-email-christian.gmeiner@gmail.com
State Changes Requested
Delegated to: Anatolij Gustschin
Headers show

Commit Message

Christian Gmeiner Jan. 8, 2014, 7:24 a.m. UTC
There may be some custom boards in the field which have
an seperate eeprom chip to store edid informations in it.
To make use of those edid information in the board code
this patch add a function to convert edid to fb_videomode.

Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
---
 common/edid.c  |   29 +++++++++++++++++++++++++++++
 include/edid.h |    3 +++
 2 files changed, 32 insertions(+)

Comments

Stefano Babic Jan. 8, 2014, 10:40 a.m. UTC | #1
CC to Anatolij as video custodian

On 08/01/2014 08:24, Christian Gmeiner wrote:
> There may be some custom boards in the field which have
> an seperate eeprom chip to store edid informations in it.
> To make use of those edid information in the board code
> this patch add a function to convert edid to fb_videomode.
> 
> Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
> ---
>  common/edid.c  |   29 +++++++++++++++++++++++++++++
>  include/edid.h |    3 +++
>  2 files changed, 32 insertions(+)
> 
> diff --git a/common/edid.c b/common/edid.c
> index e66108f..8841c25 100644
> --- a/common/edid.c
> +++ b/common/edid.c
> @@ -12,6 +12,7 @@
>  
>  #include <common.h>
>  #include <edid.h>
> +#include <linux/fb.h>
>  #include <linux/ctype.h>
>  #include <linux/string.h>
>  
> @@ -288,3 +289,31 @@ void edid_print_info(struct edid1_info *edid_info)
>  	if (!have_timing)
>  		printf("\tNone\n");
>  }
> +
> +void edid_to_fb_videomode(struct edid1_info *edid, struct fb_videomode *mode)
> +{
> +        struct edid_monitor_descriptor *monitor = &edid->monitor_details.descriptor[0];
> +        unsigned char *bytes = (unsigned char *)monitor;
> +        struct edid_detailed_timing *timing = (struct edid_detailed_timing *)monitor;
> +
> +        uint32_t pixclock = EDID_DETAILED_TIMING_PIXEL_CLOCK(*timing);
> +        uint32_t h_blanking = EDID_DETAILED_TIMING_HORIZONTAL_BLANKING(*timing);
> +        uint32_t h_active = EDID_DETAILED_TIMING_HORIZONTAL_ACTIVE(*timing);
> +        uint32_t h_sync_offset = EDID_DETAILED_TIMING_HSYNC_OFFSET(*timing);
> +        uint32_t h_sync_width = EDID_DETAILED_TIMING_HSYNC_PULSE_WIDTH(*timing);
> +        uint32_t v_blanking = EDID_DETAILED_TIMING_VERTICAL_BLANKING(*timing);
> +        uint32_t v_active = EDID_DETAILED_TIMING_VERTICAL_ACTIVE(*timing);
> +        uint32_t v_sync_offset = EDID_DETAILED_TIMING_VSYNC_OFFSET(*timing);
> +        uint32_t v_sync_width = EDID_DETAILED_TIMING_VSYNC_PULSE_WIDTH(*timing);
> +
> +        mode->name = "EDID";
> +        mode->pixclock = pixclock;
> +        mode->yres = v_active;
> +        mode->xres = h_active;
> +        mode->left_margin = h_blanking - h_sync_offset - h_sync_width;
> +        mode->right_margin = h_sync_offset;
> +        mode->upper_margin = v_blanking - v_sync_offset - v_sync_width;
> +        mode->lower_margin = v_sync_offset;
> +        mode->hsync_len = h_sync_width;
> +        mode->vsync_len = v_sync_width;
> +}
> diff --git a/include/edid.h b/include/edid.h
> index 480a773..4423062 100644
> --- a/include/edid.h
> +++ b/include/edid.h
> @@ -233,6 +233,9 @@ struct edid1_info {
>   */
>  void edid_print_info(struct edid1_info *edid_info);
>  
> +struct fb_videomode;
> +void edid_to_fb_videomode(struct edid1_info *edid, struct fb_videomode *mode);
> +
>  /**
>   * Check the EDID info.
>   *
>
Eric Nelson Jan. 10, 2014, 9:36 p.m. UTC | #2
Hi Christian,

On 01/08/2014 12:24 AM, Christian Gmeiner wrote:
> There may be some custom boards in the field which have
> an seperate eeprom chip to store edid informations in it.
> To make use of those edid information in the board code
> this patch add a function to convert edid to fb_videomode.
>
> Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
> ---
>   common/edid.c  |   29 +++++++++++++++++++++++++++++
>   include/edid.h |    3 +++
>   2 files changed, 32 insertions(+)
>
> diff --git a/common/edid.c b/common/edid.c
> index e66108f..8841c25 100644
> --- a/common/edid.c
> +++ b/common/edid.c
> @@ -12,6 +12,7 @@
>
>   #include <common.h>
>   #include <edid.h>
> +#include <linux/fb.h>
>   #include <linux/ctype.h>
>   #include <linux/string.h>
>
> @@ -288,3 +289,31 @@ void edid_print_info(struct edid1_info *edid_info)
>   	if (!have_timing)
>   		printf("\tNone\n");
>   }
> +
> +void edid_to_fb_videomode(struct edid1_info *edid, struct fb_videomode *mode)
> +{
> +        struct edid_monitor_descriptor *monitor = &edid->monitor_details.descriptor[0];
> +        unsigned char *bytes = (unsigned char *)monitor;
> +        struct edid_detailed_timing *timing = (struct edid_detailed_timing *)monitor;
> +
> +        uint32_t pixclock = EDID_DETAILED_TIMING_PIXEL_CLOCK(*timing);
> +        uint32_t h_blanking = EDID_DETAILED_TIMING_HORIZONTAL_BLANKING(*timing);
> +        uint32_t h_active = EDID_DETAILED_TIMING_HORIZONTAL_ACTIVE(*timing);
> +        uint32_t h_sync_offset = EDID_DETAILED_TIMING_HSYNC_OFFSET(*timing);
> +        uint32_t h_sync_width = EDID_DETAILED_TIMING_HSYNC_PULSE_WIDTH(*timing);
> +        uint32_t v_blanking = EDID_DETAILED_TIMING_VERTICAL_BLANKING(*timing);
> +        uint32_t v_active = EDID_DETAILED_TIMING_VERTICAL_ACTIVE(*timing);
> +        uint32_t v_sync_offset = EDID_DETAILED_TIMING_VSYNC_OFFSET(*timing);
> +        uint32_t v_sync_width = EDID_DETAILED_TIMING_VSYNC_PULSE_WIDTH(*timing);
> +
> +        mode->name = "EDID";

I think this wants to be KHZTOPICOS((pixclock/1000)), since the pixclock
returned above seems to be in Hz.

> +        mode->pixclock = pixclock;
> +        mode->yres = v_active;
> +        mode->xres = h_active;
> +        mode->left_margin = h_blanking - h_sync_offset - h_sync_width;
> +        mode->right_margin = h_sync_offset;
> +        mode->upper_margin = v_blanking - v_sync_offset - v_sync_width;
> +        mode->lower_margin = v_sync_offset;
> +        mode->hsync_len = h_sync_width;
> +        mode->vsync_len = v_sync_width;
> +}

I just tried gluing this up for use in the Nitrogen6X HDMI channel,
but found that this is more difficult than expected.

Apparently the i.MX6 clock tree doesn't (yet) support use with
the 1080P monitor I have connected.

Everything else looks okay though.

Regards,


Eric
Anatolij Gustschin Jan. 12, 2014, 8:34 p.m. UTC | #3
On Wed,  8 Jan 2014 08:24:21 +0100
Christian Gmeiner <christian.gmeiner@gmail.com> wrote:

> There may be some custom boards in the field which have
> an seperate eeprom chip to store edid informations in it.
> To make use of those edid information in the board code
> this patch add a function to convert edid to fb_videomode.
> 
> Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
> ---
>  common/edid.c  |   29 +++++++++++++++++++++++++++++
>  include/edid.h |    3 +++
>  2 files changed, 32 insertions(+)

Please check your patches with tools/checkpatch.pl and fix the
reported errors/warnings. Thanks!

> diff --git a/common/edid.c b/common/edid.c
> index e66108f..8841c25 100644
> --- a/common/edid.c
> +++ b/common/edid.c
> @@ -12,6 +12,7 @@
>  
>  #include <common.h>
>  #include <edid.h>
> +#include <linux/fb.h>
>  #include <linux/ctype.h>
>  #include <linux/string.h>
>  
> @@ -288,3 +289,31 @@ void edid_print_info(struct edid1_info *edid_info)
>  	if (!have_timing)
>  		printf("\tNone\n");
>  }
> +
> +void edid_to_fb_videomode(struct edid1_info *edid, struct fb_videomode *mode)
> +{
> +        struct edid_monitor_descriptor *monitor = &edid->monitor_details.descriptor[0];
> +        unsigned char *bytes = (unsigned char *)monitor;
> +        struct edid_detailed_timing *timing = (struct edid_detailed_timing *)monitor;
> +
> +        uint32_t pixclock = EDID_DETAILED_TIMING_PIXEL_CLOCK(*timing);
> +        uint32_t h_blanking = EDID_DETAILED_TIMING_HORIZONTAL_BLANKING(*timing);
> +        uint32_t h_active = EDID_DETAILED_TIMING_HORIZONTAL_ACTIVE(*timing);
> +        uint32_t h_sync_offset = EDID_DETAILED_TIMING_HSYNC_OFFSET(*timing);
> +        uint32_t h_sync_width = EDID_DETAILED_TIMING_HSYNC_PULSE_WIDTH(*timing);
> +        uint32_t v_blanking = EDID_DETAILED_TIMING_VERTICAL_BLANKING(*timing);
> +        uint32_t v_active = EDID_DETAILED_TIMING_VERTICAL_ACTIVE(*timing);
> +        uint32_t v_sync_offset = EDID_DETAILED_TIMING_VSYNC_OFFSET(*timing);
> +        uint32_t v_sync_width = EDID_DETAILED_TIMING_VSYNC_PULSE_WIDTH(*timing);
> +
> +        mode->name = "EDID";
> +        mode->pixclock = pixclock;

as Eric already noticed, please use 

	mode->pixclock = KHZ2PICOS(pixclock/1000);

The unit for fb_videomode.pixclock is picoseconds, the EDID macro
returned the value in Hz. And when converting to device tree timing
node in patch 3/5 please use PICOS2KHZ(mode->pixclock) * 1000 when
setting the clock-frequency property.

Thanks,

Anatolij
Fabio Estevam Jan. 14, 2014, 12:36 a.m. UTC | #4
Hi Eric,

On Fri, Jan 10, 2014 at 7:36 PM, Eric Nelson
<eric.nelson@boundarydevices.com> wrote:

> I just tried gluing this up for use in the Nitrogen6X HDMI channel,
> but found that this is more difficult than expected.
>
> Apparently the i.MX6 clock tree doesn't (yet) support use with
> the 1080P monitor I have connected.

Yes, that's true.

Should we try adding the common clock framework driver from the kernel
into U-boot?

Regards,

Fabio Estevam
Eric Nelson Jan. 14, 2014, 2:55 a.m. UTC | #5
Hi Fabio,

On 01/13/2014 05:36 PM, Fabio Estevam wrote:
> Hi Eric,
>
> On Fri, Jan 10, 2014 at 7:36 PM, Eric Nelson
> <eric.nelson@boundarydevices.com> wrote:
>
>> I just tried gluing this up for use in the Nitrogen6X HDMI channel,
>> but found that this is more difficult than expected.
>>
>> Apparently the i.MX6 clock tree doesn't (yet) support use with
>> the 1080P monitor I have connected.
>
> Yes, that's true.
>
> Should we try adding the common clock framework driver from the kernel
> into U-boot?
>

I think if we don't do it all at once, we'll end up doing it in
pieces...

Regards


Eric
Christian Gmeiner Jan. 14, 2014, 7:56 a.m. UTC | #6
2014/1/12 Anatolij Gustschin <agust@denx.de>:
> On Wed,  8 Jan 2014 08:24:21 +0100
> Christian Gmeiner <christian.gmeiner@gmail.com> wrote:
>
>> There may be some custom boards in the field which have
>> an seperate eeprom chip to store edid informations in it.
>> To make use of those edid information in the board code
>> this patch add a function to convert edid to fb_videomode.
>>
>> Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
>> ---
>>  common/edid.c  |   29 +++++++++++++++++++++++++++++
>>  include/edid.h |    3 +++
>>  2 files changed, 32 insertions(+)
>
> Please check your patches with tools/checkpatch.pl and fix the
> reported errors/warnings. Thanks!
>
>> diff --git a/common/edid.c b/common/edid.c
>> index e66108f..8841c25 100644
>> --- a/common/edid.c
>> +++ b/common/edid.c
>> @@ -12,6 +12,7 @@
>>
>>  #include <common.h>
>>  #include <edid.h>
>> +#include <linux/fb.h>
>>  #include <linux/ctype.h>
>>  #include <linux/string.h>
>>
>> @@ -288,3 +289,31 @@ void edid_print_info(struct edid1_info *edid_info)
>>       if (!have_timing)
>>               printf("\tNone\n");
>>  }
>> +
>> +void edid_to_fb_videomode(struct edid1_info *edid, struct fb_videomode *mode)
>> +{
>> +        struct edid_monitor_descriptor *monitor = &edid->monitor_details.descriptor[0];
>> +        unsigned char *bytes = (unsigned char *)monitor;
>> +        struct edid_detailed_timing *timing = (struct edid_detailed_timing *)monitor;
>> +
>> +        uint32_t pixclock = EDID_DETAILED_TIMING_PIXEL_CLOCK(*timing);
>> +        uint32_t h_blanking = EDID_DETAILED_TIMING_HORIZONTAL_BLANKING(*timing);
>> +        uint32_t h_active = EDID_DETAILED_TIMING_HORIZONTAL_ACTIVE(*timing);
>> +        uint32_t h_sync_offset = EDID_DETAILED_TIMING_HSYNC_OFFSET(*timing);
>> +        uint32_t h_sync_width = EDID_DETAILED_TIMING_HSYNC_PULSE_WIDTH(*timing);
>> +        uint32_t v_blanking = EDID_DETAILED_TIMING_VERTICAL_BLANKING(*timing);
>> +        uint32_t v_active = EDID_DETAILED_TIMING_VERTICAL_ACTIVE(*timing);
>> +        uint32_t v_sync_offset = EDID_DETAILED_TIMING_VSYNC_OFFSET(*timing);
>> +        uint32_t v_sync_width = EDID_DETAILED_TIMING_VSYNC_PULSE_WIDTH(*timing);
>> +
>> +        mode->name = "EDID";
>> +        mode->pixclock = pixclock;
>
> as Eric already noticed, please use
>
>         mode->pixclock = KHZ2PICOS(pixclock/1000);
>
> The unit for fb_videomode.pixclock is picoseconds, the EDID macro
> returned the value in Hz. And when converting to device tree timing
> node in patch 3/5 please use PICOS2KHZ(mode->pixclock) * 1000 when
> setting the clock-frequency property.
>

Fine... will fix this in the next version of the patch set.

thanks
--
Christian Gmeiner, MSc
diff mbox

Patch

diff --git a/common/edid.c b/common/edid.c
index e66108f..8841c25 100644
--- a/common/edid.c
+++ b/common/edid.c
@@ -12,6 +12,7 @@ 
 
 #include <common.h>
 #include <edid.h>
+#include <linux/fb.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 
@@ -288,3 +289,31 @@  void edid_print_info(struct edid1_info *edid_info)
 	if (!have_timing)
 		printf("\tNone\n");
 }
+
+void edid_to_fb_videomode(struct edid1_info *edid, struct fb_videomode *mode)
+{
+        struct edid_monitor_descriptor *monitor = &edid->monitor_details.descriptor[0];
+        unsigned char *bytes = (unsigned char *)monitor;
+        struct edid_detailed_timing *timing = (struct edid_detailed_timing *)monitor;
+
+        uint32_t pixclock = EDID_DETAILED_TIMING_PIXEL_CLOCK(*timing);
+        uint32_t h_blanking = EDID_DETAILED_TIMING_HORIZONTAL_BLANKING(*timing);
+        uint32_t h_active = EDID_DETAILED_TIMING_HORIZONTAL_ACTIVE(*timing);
+        uint32_t h_sync_offset = EDID_DETAILED_TIMING_HSYNC_OFFSET(*timing);
+        uint32_t h_sync_width = EDID_DETAILED_TIMING_HSYNC_PULSE_WIDTH(*timing);
+        uint32_t v_blanking = EDID_DETAILED_TIMING_VERTICAL_BLANKING(*timing);
+        uint32_t v_active = EDID_DETAILED_TIMING_VERTICAL_ACTIVE(*timing);
+        uint32_t v_sync_offset = EDID_DETAILED_TIMING_VSYNC_OFFSET(*timing);
+        uint32_t v_sync_width = EDID_DETAILED_TIMING_VSYNC_PULSE_WIDTH(*timing);
+
+        mode->name = "EDID";
+        mode->pixclock = pixclock;
+        mode->yres = v_active;
+        mode->xres = h_active;
+        mode->left_margin = h_blanking - h_sync_offset - h_sync_width;
+        mode->right_margin = h_sync_offset;
+        mode->upper_margin = v_blanking - v_sync_offset - v_sync_width;
+        mode->lower_margin = v_sync_offset;
+        mode->hsync_len = h_sync_width;
+        mode->vsync_len = v_sync_width;
+}
diff --git a/include/edid.h b/include/edid.h
index 480a773..4423062 100644
--- a/include/edid.h
+++ b/include/edid.h
@@ -233,6 +233,9 @@  struct edid1_info {
  */
 void edid_print_info(struct edid1_info *edid_info);
 
+struct fb_videomode;
+void edid_to_fb_videomode(struct edid1_info *edid, struct fb_videomode *mode);
+
 /**
  * Check the EDID info.
  *