* [PATCH v3 1/9] drm: Make drm_num_cea_modes unsigned
2013-01-14 14:30 [PATCH v3 0/9] Add HDMI infoframe helpers Thierry Reding
@ 2013-01-14 14:30 ` Thierry Reding
2013-01-14 14:42 ` Ville Syrjälä
2013-01-14 14:30 ` [PATCH v3 2/9] drm: Add some missing forward declarations Thierry Reding
` (7 subsequent siblings)
8 siblings, 1 reply; 21+ messages in thread
From: Thierry Reding @ 2013-01-14 14:30 UTC (permalink / raw)
To: dri-devel; +Cc: Paulo Zanoni
Since the variable's value is the size of an array, we can assume that
it will never be negative.
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
drivers/gpu/drm/drm_edid_modes.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_edid_modes.h b/drivers/gpu/drm/drm_edid_modes.h
index 5dbf7d2..d65d863 100644
--- a/drivers/gpu/drm/drm_edid_modes.h
+++ b/drivers/gpu/drm/drm_edid_modes.h
@@ -771,4 +771,4 @@ static const struct drm_display_mode edid_cea_modes[] = {
2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
};
-static const int drm_num_cea_modes = ARRAY_SIZE(edid_cea_modes);
+static const unsigned int drm_num_cea_modes = ARRAY_SIZE(edid_cea_modes);
--
1.8.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH v3 1/9] drm: Make drm_num_cea_modes unsigned
2013-01-14 14:30 ` [PATCH v3 1/9] drm: Make drm_num_cea_modes unsigned Thierry Reding
@ 2013-01-14 14:42 ` Ville Syrjälä
2013-01-14 15:06 ` Thierry Reding
0 siblings, 1 reply; 21+ messages in thread
From: Ville Syrjälä @ 2013-01-14 14:42 UTC (permalink / raw)
To: Thierry Reding; +Cc: Paulo Zanoni, dri-devel
On Mon, Jan 14, 2013 at 03:30:20PM +0100, Thierry Reding wrote:
> Since the variable's value is the size of an array, we can assume that
> it will never be negative.
>
> Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
> ---
> drivers/gpu/drm/drm_edid_modes.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/drm_edid_modes.h b/drivers/gpu/drm/drm_edid_modes.h
> index 5dbf7d2..d65d863 100644
> --- a/drivers/gpu/drm/drm_edid_modes.h
> +++ b/drivers/gpu/drm/drm_edid_modes.h
> @@ -771,4 +771,4 @@ static const struct drm_display_mode edid_cea_modes[] = {
> 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
> DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
> };
> -static const int drm_num_cea_modes = ARRAY_SIZE(edid_cea_modes);
> +static const unsigned int drm_num_cea_modes = ARRAY_SIZE(edid_cea_modes);
Why do we even have these num_foo things? I think it would be clearer to
use ARRAY_SIZE(foo) directly where appropriate.
--
Ville Syrjälä
Intel OTC
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v3 1/9] drm: Make drm_num_cea_modes unsigned
2013-01-14 14:42 ` Ville Syrjälä
@ 2013-01-14 15:06 ` Thierry Reding
2013-01-14 15:47 ` Ville Syrjälä
0 siblings, 1 reply; 21+ messages in thread
From: Thierry Reding @ 2013-01-14 15:06 UTC (permalink / raw)
To: Ville Syrjälä; +Cc: Paulo Zanoni, dri-devel
[-- Attachment #1.1: Type: text/plain, Size: 1395 bytes --]
On Mon, Jan 14, 2013 at 04:42:39PM +0200, Ville Syrjälä wrote:
> On Mon, Jan 14, 2013 at 03:30:20PM +0100, Thierry Reding wrote:
> > Since the variable's value is the size of an array, we can assume that
> > it will never be negative.
> >
> > Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
> > ---
> > drivers/gpu/drm/drm_edid_modes.h | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/drm_edid_modes.h b/drivers/gpu/drm/drm_edid_modes.h
> > index 5dbf7d2..d65d863 100644
> > --- a/drivers/gpu/drm/drm_edid_modes.h
> > +++ b/drivers/gpu/drm/drm_edid_modes.h
> > @@ -771,4 +771,4 @@ static const struct drm_display_mode edid_cea_modes[] = {
> > 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
> > DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
> > };
> > -static const int drm_num_cea_modes = ARRAY_SIZE(edid_cea_modes);
> > +static const unsigned int drm_num_cea_modes = ARRAY_SIZE(edid_cea_modes);
>
> Why do we even have these num_foo things? I think it would be clearer to
> use ARRAY_SIZE(foo) directly where appropriate.
Actually I was thinking about maybe writing a patch to move the table
out of the header and into drm_edid.c (or drm_cea.c?) to make it less
easy to create duplicates of the table. In that case, using the
ARRAY_SIZE macro directly wouldn't be an option.
Thierry
[-- Attachment #1.2: Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v3 1/9] drm: Make drm_num_cea_modes unsigned
2013-01-14 15:06 ` Thierry Reding
@ 2013-01-14 15:47 ` Ville Syrjälä
2013-01-18 10:30 ` Thierry Reding
0 siblings, 1 reply; 21+ messages in thread
From: Ville Syrjälä @ 2013-01-14 15:47 UTC (permalink / raw)
To: Thierry Reding; +Cc: Paulo Zanoni, dri-devel
On Mon, Jan 14, 2013 at 04:06:13PM +0100, Thierry Reding wrote:
> On Mon, Jan 14, 2013 at 04:42:39PM +0200, Ville Syrjälä wrote:
> > On Mon, Jan 14, 2013 at 03:30:20PM +0100, Thierry Reding wrote:
> > > Since the variable's value is the size of an array, we can assume that
> > > it will never be negative.
> > >
> > > Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
> > > ---
> > > drivers/gpu/drm/drm_edid_modes.h | 2 +-
> > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpu/drm/drm_edid_modes.h b/drivers/gpu/drm/drm_edid_modes.h
> > > index 5dbf7d2..d65d863 100644
> > > --- a/drivers/gpu/drm/drm_edid_modes.h
> > > +++ b/drivers/gpu/drm/drm_edid_modes.h
> > > @@ -771,4 +771,4 @@ static const struct drm_display_mode edid_cea_modes[] = {
> > > 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
> > > DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
> > > };
> > > -static const int drm_num_cea_modes = ARRAY_SIZE(edid_cea_modes);
> > > +static const unsigned int drm_num_cea_modes = ARRAY_SIZE(edid_cea_modes);
> >
> > Why do we even have these num_foo things? I think it would be clearer to
> > use ARRAY_SIZE(foo) directly where appropriate.
>
> Actually I was thinking about maybe writing a patch to move the table
> out of the header and into drm_edid.c (or drm_cea.c?) to make it less
> easy to create duplicates of the table. In that case, using the
> ARRAY_SIZE macro directly wouldn't be an option.
Well drm_edid.c is the only one accessing these tables anyway, so it
they would be in drm_edid.c and static, you could still use
ARRAY_SIZE().
Not that I really like the idea of polluting drm_edid.c with all these
massive tables.
Too bad cpp doesn't support this kind of thing:
#if __BASE_FILE__ != "drm_edid.c"
#error ...
#endif
--
Ville Syrjälä
Intel OTC
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v3 1/9] drm: Make drm_num_cea_modes unsigned
2013-01-14 15:47 ` Ville Syrjälä
@ 2013-01-18 10:30 ` Thierry Reding
2013-01-18 10:51 ` Ville Syrjälä
0 siblings, 1 reply; 21+ messages in thread
From: Thierry Reding @ 2013-01-18 10:30 UTC (permalink / raw)
To: Ville Syrjälä; +Cc: Paulo Zanoni, dri-devel
[-- Attachment #1.1: Type: text/plain, Size: 2288 bytes --]
On Mon, Jan 14, 2013 at 05:47:13PM +0200, Ville Syrjälä wrote:
> On Mon, Jan 14, 2013 at 04:06:13PM +0100, Thierry Reding wrote:
> > On Mon, Jan 14, 2013 at 04:42:39PM +0200, Ville Syrjälä wrote:
> > > On Mon, Jan 14, 2013 at 03:30:20PM +0100, Thierry Reding wrote:
> > > > Since the variable's value is the size of an array, we can assume that
> > > > it will never be negative.
> > > >
> > > > Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
> > > > ---
> > > > drivers/gpu/drm/drm_edid_modes.h | 2 +-
> > > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/drm_edid_modes.h b/drivers/gpu/drm/drm_edid_modes.h
> > > > index 5dbf7d2..d65d863 100644
> > > > --- a/drivers/gpu/drm/drm_edid_modes.h
> > > > +++ b/drivers/gpu/drm/drm_edid_modes.h
> > > > @@ -771,4 +771,4 @@ static const struct drm_display_mode edid_cea_modes[] = {
> > > > 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
> > > > DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
> > > > };
> > > > -static const int drm_num_cea_modes = ARRAY_SIZE(edid_cea_modes);
> > > > +static const unsigned int drm_num_cea_modes = ARRAY_SIZE(edid_cea_modes);
> > >
> > > Why do we even have these num_foo things? I think it would be clearer to
> > > use ARRAY_SIZE(foo) directly where appropriate.
> >
> > Actually I was thinking about maybe writing a patch to move the table
> > out of the header and into drm_edid.c (or drm_cea.c?) to make it less
> > easy to create duplicates of the table. In that case, using the
> > ARRAY_SIZE macro directly wouldn't be an option.
>
> Well drm_edid.c is the only one accessing these tables anyway, so it
> they would be in drm_edid.c and static, you could still use
> ARRAY_SIZE().
>
> Not that I really like the idea of polluting drm_edid.c with all these
> massive tables.
There's also the possibility to put the tables along with the functions
that access them into a drm_edid_modes.c.
> Too bad cpp doesn't support this kind of thing:
> #if __BASE_FILE__ != "drm_edid.c"
> #error ...
> #endif
We could fake that by protecting the tables using #ifdef NEED_CEA_MODES
and define NEED_CEA_MODES in drm_edid.c before the drm_edid_modes.h file
is included.
Thierry
[-- Attachment #1.2: Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v3 1/9] drm: Make drm_num_cea_modes unsigned
2013-01-18 10:30 ` Thierry Reding
@ 2013-01-18 10:51 ` Ville Syrjälä
2013-01-18 11:08 ` Thierry Reding
0 siblings, 1 reply; 21+ messages in thread
From: Ville Syrjälä @ 2013-01-18 10:51 UTC (permalink / raw)
To: Thierry Reding; +Cc: Paulo Zanoni, dri-devel
On Fri, Jan 18, 2013 at 11:30:04AM +0100, Thierry Reding wrote:
> On Mon, Jan 14, 2013 at 05:47:13PM +0200, Ville Syrjälä wrote:
> > On Mon, Jan 14, 2013 at 04:06:13PM +0100, Thierry Reding wrote:
> > > On Mon, Jan 14, 2013 at 04:42:39PM +0200, Ville Syrjälä wrote:
> > > > On Mon, Jan 14, 2013 at 03:30:20PM +0100, Thierry Reding wrote:
> > > > > Since the variable's value is the size of an array, we can assume that
> > > > > it will never be negative.
> > > > >
> > > > > Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
> > > > > ---
> > > > > drivers/gpu/drm/drm_edid_modes.h | 2 +-
> > > > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/drm_edid_modes.h b/drivers/gpu/drm/drm_edid_modes.h
> > > > > index 5dbf7d2..d65d863 100644
> > > > > --- a/drivers/gpu/drm/drm_edid_modes.h
> > > > > +++ b/drivers/gpu/drm/drm_edid_modes.h
> > > > > @@ -771,4 +771,4 @@ static const struct drm_display_mode edid_cea_modes[] = {
> > > > > 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
> > > > > DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
> > > > > };
> > > > > -static const int drm_num_cea_modes = ARRAY_SIZE(edid_cea_modes);
> > > > > +static const unsigned int drm_num_cea_modes = ARRAY_SIZE(edid_cea_modes);
> > > >
> > > > Why do we even have these num_foo things? I think it would be clearer to
> > > > use ARRAY_SIZE(foo) directly where appropriate.
> > >
> > > Actually I was thinking about maybe writing a patch to move the table
> > > out of the header and into drm_edid.c (or drm_cea.c?) to make it less
> > > easy to create duplicates of the table. In that case, using the
> > > ARRAY_SIZE macro directly wouldn't be an option.
> >
> > Well drm_edid.c is the only one accessing these tables anyway, so it
> > they would be in drm_edid.c and static, you could still use
> > ARRAY_SIZE().
> >
> > Not that I really like the idea of polluting drm_edid.c with all these
> > massive tables.
>
> There's also the possibility to put the tables along with the functions
> that access them into a drm_edid_modes.c.
>
> > Too bad cpp doesn't support this kind of thing:
> > #if __BASE_FILE__ != "drm_edid.c"
> > #error ...
> > #endif
>
> We could fake that by protecting the tables using #ifdef NEED_CEA_MODES
> and define NEED_CEA_MODES in drm_edid.c before the drm_edid_modes.h file
> is included.
Yeah, I suppose there's no better way to do that. It's a bit ugly
though.
--
Ville Syrjälä
Intel OTC
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v3 1/9] drm: Make drm_num_cea_modes unsigned
2013-01-18 10:51 ` Ville Syrjälä
@ 2013-01-18 11:08 ` Thierry Reding
0 siblings, 0 replies; 21+ messages in thread
From: Thierry Reding @ 2013-01-18 11:08 UTC (permalink / raw)
To: Ville Syrjälä; +Cc: Paulo Zanoni, dri-devel
[-- Attachment #1.1: Type: text/plain, Size: 2894 bytes --]
On Fri, Jan 18, 2013 at 12:51:11PM +0200, Ville Syrjälä wrote:
> On Fri, Jan 18, 2013 at 11:30:04AM +0100, Thierry Reding wrote:
> > On Mon, Jan 14, 2013 at 05:47:13PM +0200, Ville Syrjälä wrote:
> > > On Mon, Jan 14, 2013 at 04:06:13PM +0100, Thierry Reding wrote:
> > > > On Mon, Jan 14, 2013 at 04:42:39PM +0200, Ville Syrjälä wrote:
> > > > > On Mon, Jan 14, 2013 at 03:30:20PM +0100, Thierry Reding wrote:
> > > > > > Since the variable's value is the size of an array, we can assume that
> > > > > > it will never be negative.
> > > > > >
> > > > > > Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
> > > > > > ---
> > > > > > drivers/gpu/drm/drm_edid_modes.h | 2 +-
> > > > > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > > > > >
> > > > > > diff --git a/drivers/gpu/drm/drm_edid_modes.h b/drivers/gpu/drm/drm_edid_modes.h
> > > > > > index 5dbf7d2..d65d863 100644
> > > > > > --- a/drivers/gpu/drm/drm_edid_modes.h
> > > > > > +++ b/drivers/gpu/drm/drm_edid_modes.h
> > > > > > @@ -771,4 +771,4 @@ static const struct drm_display_mode edid_cea_modes[] = {
> > > > > > 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
> > > > > > DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
> > > > > > };
> > > > > > -static const int drm_num_cea_modes = ARRAY_SIZE(edid_cea_modes);
> > > > > > +static const unsigned int drm_num_cea_modes = ARRAY_SIZE(edid_cea_modes);
> > > > >
> > > > > Why do we even have these num_foo things? I think it would be clearer to
> > > > > use ARRAY_SIZE(foo) directly where appropriate.
> > > >
> > > > Actually I was thinking about maybe writing a patch to move the table
> > > > out of the header and into drm_edid.c (or drm_cea.c?) to make it less
> > > > easy to create duplicates of the table. In that case, using the
> > > > ARRAY_SIZE macro directly wouldn't be an option.
> > >
> > > Well drm_edid.c is the only one accessing these tables anyway, so it
> > > they would be in drm_edid.c and static, you could still use
> > > ARRAY_SIZE().
> > >
> > > Not that I really like the idea of polluting drm_edid.c with all these
> > > massive tables.
> >
> > There's also the possibility to put the tables along with the functions
> > that access them into a drm_edid_modes.c.
> >
> > > Too bad cpp doesn't support this kind of thing:
> > > #if __BASE_FILE__ != "drm_edid.c"
> > > #error ...
> > > #endif
> >
> > We could fake that by protecting the tables using #ifdef NEED_CEA_MODES
> > and define NEED_CEA_MODES in drm_edid.c before the drm_edid_modes.h file
> > is included.
>
> Yeah, I suppose there's no better way to do that. It's a bit ugly
> though.
What about moving them to a separate file altogether? It would involve
moving the do_cea_modes() as well, but that would need to be called from
drm_edid.c, so it isn't very pretty either.
Thierry
[-- Attachment #1.2: Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v3 2/9] drm: Add some missing forward declarations
2013-01-14 14:30 [PATCH v3 0/9] Add HDMI infoframe helpers Thierry Reding
2013-01-14 14:30 ` [PATCH v3 1/9] drm: Make drm_num_cea_modes unsigned Thierry Reding
@ 2013-01-14 14:30 ` Thierry Reding
2013-01-14 14:30 ` [PATCH v3 3/9] video: Add generic HDMI infoframe helpers Thierry Reding
` (6 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Thierry Reding @ 2013-01-14 14:30 UTC (permalink / raw)
To: dri-devel; +Cc: Paulo Zanoni
The drm_file and drm_clip_rect structures are used throughout the file
but they are never declared nor pulled in through an include. Add
forward declarations to make them available.
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
include/drm/drm_crtc.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 00d78b5..dd62ca0 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -38,7 +38,8 @@ struct drm_device;
struct drm_mode_set;
struct drm_framebuffer;
struct drm_object_properties;
-
+struct drm_file;
+struct drm_clip_rect;
#define DRM_MODE_OBJECT_CRTC 0xcccccccc
#define DRM_MODE_OBJECT_CONNECTOR 0xc0c0c0c0
--
1.8.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 3/9] video: Add generic HDMI infoframe helpers
2013-01-14 14:30 [PATCH v3 0/9] Add HDMI infoframe helpers Thierry Reding
2013-01-14 14:30 ` [PATCH v3 1/9] drm: Make drm_num_cea_modes unsigned Thierry Reding
2013-01-14 14:30 ` [PATCH v3 2/9] drm: Add some missing forward declarations Thierry Reding
@ 2013-01-14 14:30 ` Thierry Reding
2013-01-16 13:27 ` Ville Syrjälä
2013-01-14 14:30 ` [PATCH v3 4/9] drm: Add " Thierry Reding
` (5 subsequent siblings)
8 siblings, 1 reply; 21+ messages in thread
From: Thierry Reding @ 2013-01-14 14:30 UTC (permalink / raw)
To: dri-devel; +Cc: Paulo Zanoni
Add generic helpers to pack HDMI infoframes into binary buffers.
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
Changes in v2:
- add support for audio, vendor-specific and SPD infoframes
- add various validity checks on infoframes
- factor out checksum computation
Changes in v3:
- introduce HDMI_INFOFRAME_HEADER_SIZE
- fix SPD infoframe SDI field offset
drivers/video/Kconfig | 3 +
drivers/video/Makefile | 1 +
drivers/video/hdmi.c | 332 +++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/hdmi.h | 221 ++++++++++++++++++++++++++++++++
4 files changed, 557 insertions(+)
create mode 100644 drivers/video/hdmi.c
create mode 100644 include/linux/hdmi.h
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 807c7fa..baa3f90 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -54,6 +54,9 @@ config OF_VIDEOMODE
help
helper to get videomodes from the devicetree
+config HDMI
+ bool
+
menuconfig FB
tristate "Support for frame buffer devices"
---help---
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index f592f3b..0b50082 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -5,6 +5,7 @@
# Each configuration option enables a list of files.
obj-$(CONFIG_VGASTATE) += vgastate.o
+obj-$(CONFIG_HDMI) += hdmi.o
obj-y += fb_notify.o
obj-$(CONFIG_FB) += fb.o
fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
new file mode 100644
index 0000000..a84e606
--- /dev/null
+++ b/drivers/video/hdmi.c
@@ -0,0 +1,332 @@
+/*
+ * Copyright (C) 2012 Avionic Design GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/hdmi.h>
+#include <linux/string.h>
+
+static void hdmi_infoframe_checksum(void *buffer, size_t size)
+{
+ u8 *ptr = buffer;
+ u8 csum = 0;
+ size_t i;
+
+ /* compute checksum */
+ for (i = 0; i < size; i++)
+ csum += ptr[i];
+
+ ptr[3] = 256 - csum;
+}
+
+/**
+ * hdmi_avi_infoframe_init() - initialize an HDMI AVI infoframe
+ * @frame: HDMI AVI infoframe
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
+{
+ if (!frame)
+ return -EINVAL;
+
+ memset(frame, 0, sizeof(*frame));
+
+ frame->type = HDMI_INFOFRAME_TYPE_AVI;
+ frame->version = 2;
+ frame->length = 13;
+
+ return 0;
+}
+EXPORT_SYMBOL(hdmi_avi_infoframe_init);
+
+/**
+ * hdmi_avi_infoframe_pack() - write HDMI AVI infoframe to binary buffer
+ * @frame: HDMI AVI infoframe
+ * @buffer: destination buffer
+ * @size: size of buffer
+ *
+ * Packs the information contained in the @frame structure into a binary
+ * representation that can be written into the corresponding controller
+ * registers. Also computes the checksum as required by section 5.3.5 of
+ * the HDMI 1.4 specification.
+ *
+ * Returns the number of bytes packed into the binary buffer or a negative
+ * error code on failure.
+ */
+ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
+ size_t size)
+{
+ u8 *ptr = buffer;
+ size_t length;
+
+ if (!frame || !buffer)
+ return -EINVAL;
+
+ length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
+
+ if (size < length)
+ return -ENOSPC;
+
+ memset(buffer, 0, length);
+
+ ptr[0] = frame->type;
+ ptr[1] = frame->version;
+ ptr[2] = frame->length;
+ ptr[3] = 0; /* checksum */
+
+ /* start infoframe payload */
+ ptr += HDMI_INFOFRAME_HEADER_SIZE;
+
+ ptr[0] = ((frame->colorspace & 0x3) << 5) | (frame->scan_mode & 0x3);
+
+ if (frame->active_info_valid)
+ ptr[0] |= BIT(4);
+
+ if (frame->horizontal_bar_valid)
+ ptr[0] |= BIT(3);
+
+ if (frame->vertical_bar_valid)
+ ptr[0] |= BIT(2);
+
+ ptr[1] = ((frame->colorimetry & 0x3) << 6) |
+ ((frame->picture_aspect & 0x3) << 4) |
+ (frame->active_aspect & 0xf);
+
+ ptr[2] = ((frame->extended_colorimetry & 0x7) << 4) |
+ ((frame->quantization_range & 0x3) << 2) |
+ (frame->nups & 0x3);
+
+ if (frame->itc)
+ ptr[2] |= BIT(7);
+
+ ptr[3] = frame->video_code & 0x7f;
+
+ ptr[4] = ((frame->ycc_quantization_range & 0x3) << 6) |
+ ((frame->content_type & 0x3) << 4) |
+ (frame->pixel_repeat & 0xf);
+
+ ptr[5] = frame->top_bar & 0xff;
+ ptr[6] = (frame->top_bar >> 8) & 0xff;
+ ptr[7] = frame->bottom_bar & 0xff;
+ ptr[8] = (frame->bottom_bar >> 8) & 0xff;
+ ptr[9] = frame->left_bar & 0xff;
+ ptr[10] = (frame->left_bar >> 8) & 0xff;
+ ptr[11] = frame->right_bar & 0xff;
+ ptr[12] = (frame->right_bar >> 8) & 0xff;
+
+ hdmi_infoframe_checksum(buffer, length);
+
+ return length;
+}
+EXPORT_SYMBOL(hdmi_avi_infoframe_pack);
+
+/**
+ * hdmi_spd_infoframe_init() - initialize an HDMI SPD infoframe
+ * @frame: HDMI SPD infoframe
+ * @vendor: vendor string
+ * @product: product string
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
+ const char *vendor, const char *product)
+{
+ if (!frame)
+ return -EINVAL;
+
+ memset(frame, 0, sizeof(*frame));
+
+ frame->type = HDMI_INFOFRAME_TYPE_SPD;
+ frame->version = 1;
+ frame->length = 25;
+
+ strncpy(frame->vendor, vendor, sizeof(frame->vendor));
+ strncpy(frame->product, product, sizeof(frame->product));
+
+ return 0;
+}
+EXPORT_SYMBOL(hdmi_spd_infoframe_init);
+
+/**
+ * hdmi_spd_infoframe_pack() - write HDMI SPD infoframe to binary buffer
+ * @frame: HDMI SPD infoframe
+ * @buffer: destination buffer
+ * @size: size of buffer
+ *
+ * Packs the information contained in the @frame structure into a binary
+ * representation that can be written into the corresponding controller
+ * registers. Also computes the checksum as required by section 5.3.5 of
+ * the HDMI 1.4 specification.
+ *
+ * Returns the number of bytes packed into the binary buffer or a negative
+ * error code on failure.
+ */
+ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
+ size_t size)
+{
+ u8 *ptr = buffer;
+ size_t length, i;
+
+ if (!frame || !buffer)
+ return -EINVAL;
+
+ length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
+
+ if (size < length)
+ return -ENOSPC;
+
+ memset(buffer, 0, length);
+
+ ptr[0] = frame->type;
+ ptr[1] = frame->version;
+ ptr[2] = frame->length;
+ ptr[3] = 0; /* checksum */
+
+ /* start infoframe payload */
+ ptr += HDMI_INFOFRAME_HEADER_SIZE;
+
+ for (i = 0; i < sizeof(frame->vendor); i++)
+ ptr[i] = frame->vendor[i];
+
+ for (i = 0; i < sizeof(frame->product); i++)
+ ptr[8 + i] = frame->product[i];
+
+ ptr[24] = frame->sdi;
+
+ hdmi_infoframe_checksum(buffer, length);
+
+ return length;
+}
+EXPORT_SYMBOL(hdmi_spd_infoframe_pack);
+
+/**
+ * hdmi_audio_infoframe_init() - initialize an HDMI audio infoframe
+ * @frame: HDMI audio infoframe
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame)
+{
+ if (!frame)
+ return -EINVAL;
+
+ memset(frame, 0, sizeof(*frame));
+
+ frame->type = HDMI_INFOFRAME_TYPE_AUDIO;
+ frame->version = 1;
+ frame->length = 10;
+
+ return 0;
+}
+EXPORT_SYMBOL(hdmi_audio_infoframe_init);
+
+/**
+ * hdmi_audio_infoframe_pack() - write HDMI audio infoframe to binary buffer
+ * @frame: HDMI audio infoframe
+ * @buffer: destination buffer
+ * @size: size of buffer
+ *
+ * Packs the information contained in the @frame structure into a binary
+ * representation that can be written into the corresponding controller
+ * registers. Also computes the checksum as required by section 5.3.5 of
+ * the HDMI 1.4 specification.
+ *
+ * Returns the number of bytes packed into the binary buffer or a negative
+ * error code on failure.
+ */
+ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
+ void *buffer, size_t size)
+{
+ unsigned char channels;
+ u8 *ptr = buffer;
+ size_t length;
+
+ if (!frame || !buffer)
+ return -EINVAL;
+
+ length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
+
+ if (size < length)
+ return -ENOSPC;
+
+ memset(buffer, 0, length);
+
+ if (frame->channels >= 2)
+ channels = frame->channels - 1;
+ else
+ channels = 0;
+
+ ptr[0] = frame->type;
+ ptr[1] = frame->version;
+ ptr[2] = frame->length;
+ ptr[3] = 0; /* checksum */
+
+ /* start infoframe payload */
+ ptr += HDMI_INFOFRAME_HEADER_SIZE;
+
+ ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
+ ptr[1] = ((frame->sample_frequency & 0x7) << 2) |
+ (frame->sample_size & 0x3);
+ ptr[2] = 0;
+ ptr[3] = frame->channel_allocation;
+ ptr[4] = (frame->level_shift_value & 0xf) << 3;
+
+ if (frame->downmix_inhibit)
+ ptr[4] |= BIT(7);
+
+ hdmi_infoframe_checksum(buffer, length);
+
+ return length;
+}
+EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
+
+/**
+ * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary
+ * buffer
+ * @frame: HDMI vendor infoframe
+ * @buffer: destination buffer
+ * @size: size of buffer
+ *
+ * Packs the information contained in the @frame structure into a binary
+ * representation that can be written into the corresponding controller
+ * registers. Also computes the checksum as required by section 5.3.5 of
+ * the HDMI 1.4 specification.
+ *
+ * Returns the number of bytes packed into the binary buffer or a negative
+ * error code on failure.
+ */
+ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
+ void *buffer, size_t size)
+{
+ u8 *ptr = buffer;
+ size_t length;
+
+ if (!frame || !buffer)
+ return -EINVAL;
+
+ length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
+
+ if (size < length)
+ return -ENOSPC;
+
+ memset(buffer, 0, length);
+
+ ptr[0] = frame->type;
+ ptr[1] = frame->version;
+ ptr[2] = frame->length;
+ ptr[3] = 0; /* checksum */
+
+ memcpy(&ptr[HDMI_INFOFRAME_HEADER_SIZE], frame->data, frame->length);
+
+ hdmi_infoframe_checksum(buffer, length);
+
+ return length;
+}
+EXPORT_SYMBOL(hdmi_vendor_infoframe_pack);
diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
new file mode 100644
index 0000000..47d59b1
--- /dev/null
+++ b/include/linux/hdmi.h
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2012 Avionic Design GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_HDMI_H_
+#define __LINUX_HDMI_H_
+
+#include <linux/types.h>
+
+enum hdmi_infoframe_type {
+ HDMI_INFOFRAME_TYPE_VENDOR = 0x81,
+ HDMI_INFOFRAME_TYPE_AVI = 0x82,
+ HDMI_INFOFRAME_TYPE_SPD = 0x83,
+ HDMI_INFOFRAME_TYPE_AUDIO = 0x84,
+};
+
+#define HDMI_INFOFRAME_HEADER_SIZE 4
+#define HDMI_AVI_INFOFRAME_SIZE 13
+#define HDMI_SPD_INFOFRAME_SIZE 25
+#define HDMI_AUDIO_INFOFRAME_SIZE 10
+
+enum hdmi_colorspace {
+ HDMI_COLORSPACE_RGB,
+ HDMI_COLORSPACE_YUV422,
+ HDMI_COLORSPACE_YUV444,
+};
+
+enum hdmi_scan_mode {
+ HDMI_SCAN_MODE_NONE,
+ HDMI_SCAN_MODE_OVERSCAN,
+ HDMI_SCAN_MODE_UNDERSCAN,
+};
+
+enum hdmi_colorimetry {
+ HDMI_COLORIMETRY_NONE,
+ HDMI_COLORIMETRY_ITU_601,
+ HDMI_COLORIMETRY_ITU_709,
+ HDMI_COLORIMETRY_EXTENDED,
+};
+
+enum hdmi_picture_aspect {
+ HDMI_PICTURE_ASPECT_NONE,
+ HDMI_PICTURE_ASPECT_4_3,
+ HDMI_PICTURE_ASPECT_16_9,
+};
+
+enum hdmi_active_aspect {
+ HDMI_ACTIVE_ASPECT_16_9_TOP = 2,
+ HDMI_ACTIVE_ASPECT_14_9_TOP = 3,
+ HDMI_ACTIVE_ASPECT_16_9_CENTER = 4,
+ HDMI_ACTIVE_ASPECT_PICTURE = 8,
+ HDMI_ACTIVE_ASPECT_4_3 = 9,
+ HDMI_ACTIVE_ASPECT_16_9 = 10,
+ HDMI_ACTIVE_ASPECT_14_9 = 11,
+ HDMI_ACTIVE_ASPECT_4_3_SP_14_9 = 13,
+ HDMI_ACTIVE_ASPECT_16_9_SP_14_9 = 14,
+ HDMI_ACTIVE_ASPECT_16_9_SP_4_3 = 15,
+};
+
+enum hdmi_extended_colorimetry {
+ HDMI_EXTENDED_COLORIMETRY_XV_YCC_601,
+ HDMI_EXTENDED_COLORIMETRY_XV_YCC_709,
+ HDMI_EXTENDED_COLORIMETRY_S_YCC_601,
+ HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601,
+ HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB,
+};
+
+enum hdmi_quantization_range {
+ HDMI_QUANTIZATION_RANGE_DEFAULT,
+ HDMI_QUANTIZATION_RANGE_LIMITED,
+ HDMI_QUANTIZATION_RANGE_FULL,
+};
+
+/* non-uniform picture scaling */
+enum hdmi_nups {
+ HDMI_NUPS_UNKNOWN,
+ HDMI_NUPS_HORIZONTAL,
+ HDMI_NUPS_VERTICAL,
+ HDMI_NUPS_BOTH,
+};
+
+enum hdmi_ycc_quantization_range {
+ HDMI_YCC_QUANTIZATION_RANGE_LIMITED,
+ HDMI_YCC_QUANTIZATION_RANGE_FULL,
+};
+
+enum hdmi_content_type {
+ HDMI_CONTENT_TYPE_NONE,
+ HDMI_CONTENT_TYPE_PHOTO,
+ HDMI_CONTENT_TYPE_CINEMA,
+ HDMI_CONTENT_TYPE_GAME,
+};
+
+struct hdmi_avi_infoframe {
+ enum hdmi_infoframe_type type;
+ unsigned char version;
+ unsigned char length;
+ enum hdmi_colorspace colorspace;
+ bool active_info_valid;
+ bool horizontal_bar_valid;
+ bool vertical_bar_valid;
+ enum hdmi_scan_mode scan_mode;
+ enum hdmi_colorimetry colorimetry;
+ enum hdmi_picture_aspect picture_aspect;
+ enum hdmi_active_aspect active_aspect;
+ bool itc;
+ enum hdmi_extended_colorimetry extended_colorimetry;
+ enum hdmi_quantization_range quantization_range;
+ enum hdmi_nups nups;
+ unsigned char video_code;
+ enum hdmi_ycc_quantization_range ycc_quantization_range;
+ enum hdmi_content_type content_type;
+ unsigned char pixel_repeat;
+ unsigned short top_bar;
+ unsigned short bottom_bar;
+ unsigned short left_bar;
+ unsigned short right_bar;
+};
+
+int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame);
+ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
+ size_t size);
+
+enum hdmi_spd_sdi {
+ HDMI_SPD_SDI_UNKNOWN,
+ HDMI_SPD_SDI_DSTB,
+ HDMI_SPD_SDI_DVDP,
+ HDMI_SPD_SDI_DVHS,
+ HDMI_SPD_SDI_HDDVR,
+ HDMI_SPD_SDI_DVC,
+ HDMI_SPD_SDI_DSC,
+ HDMI_SPD_SDI_VCD,
+ HDMI_SPD_SDI_GAME,
+ HDMI_SPD_SDI_PC,
+ HDMI_SPD_SDI_BD,
+ HDMI_SPD_SDI_SCD,
+};
+
+struct hdmi_spd_infoframe {
+ enum hdmi_infoframe_type type;
+ unsigned char version;
+ unsigned char length;
+ char vendor[8];
+ char product[16];
+ enum hdmi_spd_sdi sdi;
+};
+
+int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
+ const char *vendor, const char *product);
+ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
+ size_t size);
+
+enum hdmi_audio_coding_type {
+ HDMI_AUDIO_CODING_TYPE_STREAM,
+ HDMI_AUDIO_CODING_TYPE_IEC_60958,
+ HDMI_AUDIO_CODING_TYPE_AC3,
+ HDMI_AUDIO_CODING_TYPE_MPEG1,
+ HDMI_AUDIO_CODING_TYPE_MP3,
+ HDMI_AUDIO_CODING_TYPE_MPEG2,
+ HDMI_AUDIO_CODING_TYPE_AAC,
+ HDMI_AUDIO_CODING_TYPE_DTS,
+ HDMI_AUDIO_CODING_TYPE_ATRAC,
+ HDMI_AUDIO_CODING_TYPE_ONE_BIT_AUDIO,
+ HDMI_AUDIO_CODING_TYPE_DOLBY_DIGITAL_PLUS,
+ HDMI_AUDIO_CODING_TYPE_DTS_HD,
+ HDMI_AUDIO_CODING_TYPE_MAT_MLP,
+ HDMI_AUDIO_CODING_TYPE_DST,
+ HDMI_AUDIO_CODING_TYPE_WMPRO,
+};
+
+enum hdmi_audio_sample_size {
+ HDMI_AUDIO_SAMPLE_SIZE_STREAM,
+ HDMI_AUDIO_SAMPLE_SIZE_16,
+ HDMI_AUDIO_SAMPLE_SIZE_20,
+ HDMI_AUDIO_SAMPLE_SIZE_24,
+};
+
+enum hdmi_audio_sample_frequency {
+ HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM,
+ HDMI_AUDIO_SAMPLE_FREQUENCY_32000,
+ HDMI_AUDIO_SAMPLE_FREQUENCY_44100,
+ HDMI_AUDIO_SAMPLE_FREQUENCY_48000,
+ HDMI_AUDIO_SAMPLE_FREQUENCY_88200,
+ HDMI_AUDIO_SAMPLE_FREQUENCY_96000,
+ HDMI_AUDIO_SAMPLE_FREQUENCY_176400,
+ HDMI_AUDIO_SAMPLE_FREQUENCY_192000,
+};
+
+struct hdmi_audio_infoframe {
+ enum hdmi_infoframe_type type;
+ unsigned char version;
+ unsigned char length;
+ unsigned char channels;
+ enum hdmi_audio_coding_type coding_type;
+ enum hdmi_audio_sample_size sample_size;
+ enum hdmi_audio_sample_frequency sample_frequency;
+ unsigned char channel_allocation;
+ unsigned char level_shift_value;
+ bool downmix_inhibit;
+
+};
+
+int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame);
+ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
+ void *buffer, size_t size);
+
+struct hdmi_vendor_infoframe {
+ enum hdmi_infoframe_type type;
+ unsigned char version;
+ unsigned char length;
+ u8 data[27];
+};
+
+ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
+ void *buffer, size_t size);
+
+#endif /* _DRM_HDMI_H */
--
1.8.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH v3 3/9] video: Add generic HDMI infoframe helpers
2013-01-14 14:30 ` [PATCH v3 3/9] video: Add generic HDMI infoframe helpers Thierry Reding
@ 2013-01-16 13:27 ` Ville Syrjälä
2013-01-18 8:56 ` Thierry Reding
0 siblings, 1 reply; 21+ messages in thread
From: Ville Syrjälä @ 2013-01-16 13:27 UTC (permalink / raw)
To: Thierry Reding; +Cc: Paulo Zanoni, dri-devel
On Mon, Jan 14, 2013 at 03:30:22PM +0100, Thierry Reding wrote:
> Add generic helpers to pack HDMI infoframes into binary buffers.
>
> Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
> ---
> Changes in v2:
> - add support for audio, vendor-specific and SPD infoframes
> - add various validity checks on infoframes
> - factor out checksum computation
>
> Changes in v3:
> - introduce HDMI_INFOFRAME_HEADER_SIZE
> - fix SPD infoframe SDI field offset
>
> drivers/video/Kconfig | 3 +
> drivers/video/Makefile | 1 +
> drivers/video/hdmi.c | 332 +++++++++++++++++++++++++++++++++++++++++++++++++
> include/linux/hdmi.h | 221 ++++++++++++++++++++++++++++++++
> 4 files changed, 557 insertions(+)
> create mode 100644 drivers/video/hdmi.c
> create mode 100644 include/linux/hdmi.h
>
> diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
> index 807c7fa..baa3f90 100644
> --- a/drivers/video/Kconfig
> +++ b/drivers/video/Kconfig
> @@ -54,6 +54,9 @@ config OF_VIDEOMODE
> help
> helper to get videomodes from the devicetree
>
> +config HDMI
> + bool
> +
> menuconfig FB
> tristate "Support for frame buffer devices"
> ---help---
> diff --git a/drivers/video/Makefile b/drivers/video/Makefile
> index f592f3b..0b50082 100644
> --- a/drivers/video/Makefile
> +++ b/drivers/video/Makefile
> @@ -5,6 +5,7 @@
> # Each configuration option enables a list of files.
>
> obj-$(CONFIG_VGASTATE) += vgastate.o
> +obj-$(CONFIG_HDMI) += hdmi.o
> obj-y += fb_notify.o
> obj-$(CONFIG_FB) += fb.o
> fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
> diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
> new file mode 100644
> index 0000000..a84e606
> --- /dev/null
> +++ b/drivers/video/hdmi.c
> @@ -0,0 +1,332 @@
> +/*
> + * Copyright (C) 2012 Avionic Design GmbH
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/errno.h>
> +#include <linux/export.h>
> +#include <linux/hdmi.h>
> +#include <linux/string.h>
> +
> +static void hdmi_infoframe_checksum(void *buffer, size_t size)
> +{
> + u8 *ptr = buffer;
> + u8 csum = 0;
> + size_t i;
> +
> + /* compute checksum */
> + for (i = 0; i < size; i++)
> + csum += ptr[i];
> +
> + ptr[3] = 256 - csum;
> +}
> +
> +/**
> + * hdmi_avi_infoframe_init() - initialize an HDMI AVI infoframe
> + * @frame: HDMI AVI infoframe
> + *
> + * Returns 0 on success or a negative error code on failure.
> + */
> +int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
> +{
> + if (!frame)
> + return -EINVAL;
There's quite a bit of error checking all around which seems a bit
pointless since this is all internal stuff. Any errors are bugs in
some driver code, so just letting the thing oops would be fine in my
opinion.
> + memset(frame, 0, sizeof(*frame));
> +
> + frame->type = HDMI_INFOFRAME_TYPE_AVI;
> + frame->version = 2;
> + frame->length = 13;
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(hdmi_avi_infoframe_init);
> +
> +/**
> + * hdmi_avi_infoframe_pack() - write HDMI AVI infoframe to binary buffer
> + * @frame: HDMI AVI infoframe
> + * @buffer: destination buffer
> + * @size: size of buffer
> + *
> + * Packs the information contained in the @frame structure into a binary
> + * representation that can be written into the corresponding controller
> + * registers. Also computes the checksum as required by section 5.3.5 of
> + * the HDMI 1.4 specification.
> + *
> + * Returns the number of bytes packed into the binary buffer or a negative
> + * error code on failure.
> + */
> +ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
> + size_t size)
> +{
> + u8 *ptr = buffer;
> + size_t length;
> +
> + if (!frame || !buffer)
> + return -EINVAL;
> +
> + length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
> +
> + if (size < length)
> + return -ENOSPC;
> +
> + memset(buffer, 0, length);
> +
> + ptr[0] = frame->type;
> + ptr[1] = frame->version;
> + ptr[2] = frame->length;
> + ptr[3] = 0; /* checksum */
> +
> + /* start infoframe payload */
> + ptr += HDMI_INFOFRAME_HEADER_SIZE;
> +
> + ptr[0] = ((frame->colorspace & 0x3) << 5) | (frame->scan_mode & 0x3);
> +
> + if (frame->active_info_valid)
> + ptr[0] |= BIT(4);
> +
> + if (frame->horizontal_bar_valid)
> + ptr[0] |= BIT(3);
> +
> + if (frame->vertical_bar_valid)
> + ptr[0] |= BIT(2);
> +
> + ptr[1] = ((frame->colorimetry & 0x3) << 6) |
> + ((frame->picture_aspect & 0x3) << 4) |
> + (frame->active_aspect & 0xf);
> +
> + ptr[2] = ((frame->extended_colorimetry & 0x7) << 4) |
> + ((frame->quantization_range & 0x3) << 2) |
> + (frame->nups & 0x3);
> +
> + if (frame->itc)
> + ptr[2] |= BIT(7);
> +
> + ptr[3] = frame->video_code & 0x7f;
> +
> + ptr[4] = ((frame->ycc_quantization_range & 0x3) << 6) |
> + ((frame->content_type & 0x3) << 4) |
> + (frame->pixel_repeat & 0xf);
> +
> + ptr[5] = frame->top_bar & 0xff;
> + ptr[6] = (frame->top_bar >> 8) & 0xff;
> + ptr[7] = frame->bottom_bar & 0xff;
> + ptr[8] = (frame->bottom_bar >> 8) & 0xff;
> + ptr[9] = frame->left_bar & 0xff;
> + ptr[10] = (frame->left_bar >> 8) & 0xff;
> + ptr[11] = frame->right_bar & 0xff;
> + ptr[12] = (frame->right_bar >> 8) & 0xff;
> +
> + hdmi_infoframe_checksum(buffer, length);
> +
> + return length;
> +}
> +EXPORT_SYMBOL(hdmi_avi_infoframe_pack);
> +
> +/**
> + * hdmi_spd_infoframe_init() - initialize an HDMI SPD infoframe
> + * @frame: HDMI SPD infoframe
> + * @vendor: vendor string
> + * @product: product string
> + *
> + * Returns 0 on success or a negative error code on failure.
> + */
> +int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
> + const char *vendor, const char *product)
> +{
> + if (!frame)
> + return -EINVAL;
> +
> + memset(frame, 0, sizeof(*frame));
> +
> + frame->type = HDMI_INFOFRAME_TYPE_SPD;
> + frame->version = 1;
> + frame->length = 25;
> +
> + strncpy(frame->vendor, vendor, sizeof(frame->vendor));
> + strncpy(frame->product, product, sizeof(frame->product));
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(hdmi_spd_infoframe_init);
> +
> +/**
> + * hdmi_spd_infoframe_pack() - write HDMI SPD infoframe to binary buffer
> + * @frame: HDMI SPD infoframe
> + * @buffer: destination buffer
> + * @size: size of buffer
> + *
> + * Packs the information contained in the @frame structure into a binary
> + * representation that can be written into the corresponding controller
> + * registers. Also computes the checksum as required by section 5.3.5 of
> + * the HDMI 1.4 specification.
> + *
> + * Returns the number of bytes packed into the binary buffer or a negative
> + * error code on failure.
> + */
> +ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
> + size_t size)
> +{
> + u8 *ptr = buffer;
> + size_t length, i;
> +
> + if (!frame || !buffer)
> + return -EINVAL;
> +
> + length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
> +
> + if (size < length)
> + return -ENOSPC;
> +
> + memset(buffer, 0, length);
> +
> + ptr[0] = frame->type;
> + ptr[1] = frame->version;
> + ptr[2] = frame->length;
> + ptr[3] = 0; /* checksum */
> +
> + /* start infoframe payload */
> + ptr += HDMI_INFOFRAME_HEADER_SIZE;
> +
> + for (i = 0; i < sizeof(frame->vendor); i++)
> + ptr[i] = frame->vendor[i];
> +
> + for (i = 0; i < sizeof(frame->product); i++)
> + ptr[8 + i] = frame->product[i];
memcpy()
> +
> + ptr[24] = frame->sdi;
> +
> + hdmi_infoframe_checksum(buffer, length);
> +
> + return length;
> +}
> +EXPORT_SYMBOL(hdmi_spd_infoframe_pack);
> +
> +/**
> + * hdmi_audio_infoframe_init() - initialize an HDMI audio infoframe
> + * @frame: HDMI audio infoframe
> + *
> + * Returns 0 on success or a negative error code on failure.
> + */
> +int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame)
> +{
> + if (!frame)
> + return -EINVAL;
> +
> + memset(frame, 0, sizeof(*frame));
> +
> + frame->type = HDMI_INFOFRAME_TYPE_AUDIO;
> + frame->version = 1;
> + frame->length = 10;
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(hdmi_audio_infoframe_init);
> +
> +/**
> + * hdmi_audio_infoframe_pack() - write HDMI audio infoframe to binary buffer
> + * @frame: HDMI audio infoframe
> + * @buffer: destination buffer
> + * @size: size of buffer
> + *
> + * Packs the information contained in the @frame structure into a binary
> + * representation that can be written into the corresponding controller
> + * registers. Also computes the checksum as required by section 5.3.5 of
> + * the HDMI 1.4 specification.
> + *
> + * Returns the number of bytes packed into the binary buffer or a negative
> + * error code on failure.
> + */
> +ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
> + void *buffer, size_t size)
> +{
> + unsigned char channels;
> + u8 *ptr = buffer;
> + size_t length;
> +
> + if (!frame || !buffer)
> + return -EINVAL;
> +
> + length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
> +
> + if (size < length)
> + return -ENOSPC;
> +
> + memset(buffer, 0, length);
> +
> + if (frame->channels >= 2)
> + channels = frame->channels - 1;
> + else
> + channels = 0;
> +
> + ptr[0] = frame->type;
> + ptr[1] = frame->version;
> + ptr[2] = frame->length;
> + ptr[3] = 0; /* checksum */
> +
> + /* start infoframe payload */
> + ptr += HDMI_INFOFRAME_HEADER_SIZE;
> +
> + ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
> + ptr[1] = ((frame->sample_frequency & 0x7) << 2) |
> + (frame->sample_size & 0x3);
> + ptr[2] = 0;
> + ptr[3] = frame->channel_allocation;
> + ptr[4] = (frame->level_shift_value & 0xf) << 3;
> +
> + if (frame->downmix_inhibit)
> + ptr[4] |= BIT(7);
> +
> + hdmi_infoframe_checksum(buffer, length);
> +
> + return length;
> +}
> +EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
> +
> +/**
> + * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary
> + * buffer
> + * @frame: HDMI vendor infoframe
> + * @buffer: destination buffer
> + * @size: size of buffer
> + *
> + * Packs the information contained in the @frame structure into a binary
> + * representation that can be written into the corresponding controller
> + * registers. Also computes the checksum as required by section 5.3.5 of
> + * the HDMI 1.4 specification.
> + *
> + * Returns the number of bytes packed into the binary buffer or a negative
> + * error code on failure.
> + */
> +ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
> + void *buffer, size_t size)
> +{
> + u8 *ptr = buffer;
> + size_t length;
> +
> + if (!frame || !buffer)
> + return -EINVAL;
> +
> + length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
> +
> + if (size < length)
> + return -ENOSPC;
> +
> + memset(buffer, 0, length);
> +
> + ptr[0] = frame->type;
> + ptr[1] = frame->version;
> + ptr[2] = frame->length;
> + ptr[3] = 0; /* checksum */
> +
> + memcpy(&ptr[HDMI_INFOFRAME_HEADER_SIZE], frame->data, frame->length);
> +
> + hdmi_infoframe_checksum(buffer, length);
> +
> + return length;
> +}
> +EXPORT_SYMBOL(hdmi_vendor_infoframe_pack);
> diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
> new file mode 100644
> index 0000000..47d59b1
> --- /dev/null
> +++ b/include/linux/hdmi.h
> @@ -0,0 +1,221 @@
> +/*
> + * Copyright (C) 2012 Avionic Design GmbH
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef __LINUX_HDMI_H_
> +#define __LINUX_HDMI_H_
> +
> +#include <linux/types.h>
> +
> +enum hdmi_infoframe_type {
> + HDMI_INFOFRAME_TYPE_VENOR = 0x81,
> + HDMI_INFOFRAME_TYPE_AVI = 0x82,
> + HDMI_INFOFRAME_TYPE_SPD = 0x83,
> + HDMI_INFOFRAME_TYPE_AUDIO = 0x84,
> +};
> +
> +#define HDMI_INFOFRAME_HEADER_SIZE 4
> +#define HDMI_AVI_INFOFRAME_SIZE 13
> +#define HDMI_SPD_INFOFRAME_SIZE 25
> +#define HDMI_AUDIO_INFOFRAME_SIZE 10
> +
> +enum hdmi_colorspace {
> + HDMI_COLORSPACE_RGB,
> + HDMI_COLORSPACE_YUV422,
> + HDMI_COLORSPACE_YUV444,
> +};
> +
> +enum hdmi_scan_mode {
> + HDMI_SCAN_MODE_NONE,
> + HDMI_SCAN_MODE_OVERSCAN,
> + HDMI_SCAN_MODE_UNDERSCAN,
> +};
> +
> +enum hdmi_colorimetry {
> + HDMI_COLORIMETRY_NONE,
> + HDMI_COLORIMETRY_ITU_601,
> + HDMI_COLORIMETRY_ITU_709,
> + HDMI_COLORIMETRY_EXTENDED,
> +};
> +
> +enum hdmi_picture_aspect {
> + HDMI_PICTURE_ASPECT_NONE,
> + HDMI_PICTURE_ASPECT_4_3,
> + HDMI_PICTURE_ASPECT_16_9,
> +};
> +
> +enum hdmi_active_aspect {
> + HDMI_ACTIVE_ASPECT_16_9_TOP = 2,
> + HDMI_ACTIVE_ASPECT_14_9_TOP = 3,
> + HDMI_ACTIVE_ASPECT_16_9_CENTER = 4,
> + HDMI_ACTIVE_ASPECT_PICTURE = 8,
> + HDMI_ACTIVE_ASPECT_4_3 = 9,
> + HDMI_ACTIVE_ASPECT_16_9 = 10,
> + HDMI_ACTIVE_ASPECT_14_9 = 11,
> + HDMI_ACTIVE_ASPECT_4_3_SP_14_9 = 13,
> + HDMI_ACTIVE_ASPECT_16_9_SP_14_9 = 14,
> + HDMI_ACTIVE_ASPECT_16_9_SP_4_3 = 15,
> +};
> +
> +enum hdmi_extended_colorimetry {
> + HDMI_EXTENDED_COLORIMETRY_XV_YCC_601,
> + HDMI_EXTENDED_COLORIMETRY_XV_YCC_709,
> + HDMI_EXTENDED_COLORIMETRY_S_YCC_601,
> + HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601,
> + HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB,
> +};
> +
> +enum hdmi_quantization_range {
> + HDMI_QUANTIZATION_RANGE_DEFAULT,
> + HDMI_QUANTIZATION_RANGE_LIMITED,
> + HDMI_QUANTIZATION_RANGE_FULL,
> +};
> +
> +/* non-uniform picture scaling */
> +enum hdmi_nups {
> + HDMI_NUPS_UNKNOWN,
> + HDMI_NUPS_HORIZONTAL,
> + HDMI_NUPS_VERTICAL,
> + HDMI_NUPS_BOTH,
> +};
> +
> +enum hdmi_ycc_quantization_range {
> + HDMI_YCC_QUANTIZATION_RANGE_LIMITED,
> + HDMI_YCC_QUANTIZATION_RANGE_FULL,
> +};
> +
> +enum hdmi_content_type {
> + HDMI_CONTENT_TYPE_NONE,
> + HDMI_CONTENT_TYPE_PHOTO,
> + HDMI_CONTENT_TYPE_CINEMA,
> + HDMI_CONTENT_TYPE_GAME,
> +};
> +
> +struct hdmi_avi_infoframe {
> + enum hdmi_infoframe_type type;
> + unsigned char version;
> + unsigned char length;
> + enum hdmi_colorspace colorspace;
> + bool active_info_valid;
> + bool horizontal_bar_valid;
> + bool vertical_bar_valid;
> + enum hdmi_scan_mode scan_mode;
> + enum hdmi_colorimetry colorimetry;
> + enum hdmi_picture_aspect picture_aspect;
> + enum hdmi_active_aspect active_aspect;
> + bool itc;
> + enum hdmi_extended_colorimetry extended_colorimetry;
> + enum hdmi_quantization_range quantization_range;
> + enum hdmi_nups nups;
> + unsigned char video_code;
> + enum hdmi_ycc_quantization_range ycc_quantization_range;
> + enum hdmi_content_type content_type;
> + unsigned char pixel_repeat;
> + unsigned short top_bar;
> + unsigned short bottom_bar;
> + unsigned short left_bar;
> + unsigned short right_bar;
> +};
> +
> +int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame);
> +ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
> + size_t size);
> +
> +enum hdmi_spd_sdi {
> + HDMI_SPD_SDI_UNKNOWN,
> + HDMI_SPD_SDI_DSTB,
> + HDMI_SPD_SDI_DVDP,
> + HDMI_SPD_SDI_DVHS,
> + HDMI_SPD_SDI_HDDVR,
> + HDMI_SPD_SDI_DVC,
> + HDMI_SPD_SDI_DSC,
> + HDMI_SPD_SDI_VCD,
> + HDMI_SPD_SDI_GAME,
> + HDMI_SPD_SDI_PC,
> + HDMI_SPD_SDI_BD,
> + HDMI_SPD_SDI_SCD,
I believe SACD is a more correct name.
HD DVD and PMP are missing from this list.
> +};
> +
> +struct hdmi_spd_infoframe {
> + enum hdmi_infoframe_type type;
> + unsigned char version;
> + unsigned char length;
> + char vendor[8];
> + char product[16];
> + enum hdmi_spd_sdi sdi;
> +};
> +
> +int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
> + const char *vendor, const char *product);
> +ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
> + size_t size);
> +
> +enum hdmi_audio_coding_type {
> + HDMI_AUDIO_CODING_TYPE_STREAM,
> + HDMI_AUDIO_CODING_TYPE_IEC_60958,
> + HDMI_AUDIO_CODING_TYPE_AC3,
> + HDMI_AUDIO_CODING_TYPE_MPEG1,
> + HDMI_AUDIO_CODING_TYPE_MP3,
> + HDMI_AUDIO_CODING_TYPE_MPEG2,
> + HDMI_AUDIO_CODING_TYPE_AAC,
> + HDMI_AUDIO_CODING_TYPE_DTS,
> + HDMI_AUDIO_CODING_TYPE_ATRAC,
> + HDMI_AUDIO_CODING_TYPE_ONE_BIT_AUDIO,
> + HDMI_AUDIO_CODING_TYPE_DOLBY_DIGITAL_PLUS,
> + HDMI_AUDIO_CODING_TYPE_DTS_HD,
> + HDMI_AUDIO_CODING_TYPE_MAT_MLP,
> + HDMI_AUDIO_CODING_TYPE_DST,
> + HDMI_AUDIO_CODING_TYPE_WMPRO,
These don't always quite match the names in CEA-861-E. Wouldn't it
be better to use matching names?
Also the audio coding extension type is missing.
> +};
> +
> +enum hdmi_audio_sample_size {
> + HDMI_AUDIO_SAMPLE_SIZE_STREAM,
> + HDMI_AUDIO_SAMPLE_SIZE_16,
> + HDMI_AUDIO_SAMPLE_SIZE_20,
> + HDMI_AUDIO_SAMPLE_SIZE_24,
> +};
> +
> +enum hdmi_audio_sample_frequency {
> + HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM,
> + HDMI_AUDIO_SAMPLE_FREQUENCY_32000,
> + HDMI_AUDIO_SAMPLE_FREQUENCY_44100,
> + HDMI_AUDIO_SAMPLE_FREQUENCY_48000,
> + HDMI_AUDIO_SAMPLE_FREQUENCY_88200,
> + HDMI_AUDIO_SAMPLE_FREQUENCY_96000,
> + HDMI_AUDIO_SAMPLE_FREQUENCY_176400,
> + HDMI_AUDIO_SAMPLE_FREQUENCY_192000,
> +};
> +
> +struct hdmi_audio_infoframe {
> + enum hdmi_infoframe_type type;
> + unsigned char version;
> + unsigned char length;
> + unsigned char channels;
> + enum hdmi_audio_coding_type coding_type;
> + enum hdmi_audio_sample_size sample_size;
> + enum hdmi_audio_sample_frequency sample_frequency;
> + unsigned char channel_allocation;
> + unsigned char level_shift_value;
> + bool downmix_inhibit;
> +
> +};
> +
> +int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame);
> +ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
> + void *buffer, size_t size);
> +
> +struct hdmi_vendor_infoframe {
> + enum hdmi_infoframe_type type;
> + unsigned char version;
> + unsigned char length;
> + u8 data[27];
> +};
> +
> +ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
> + void *buffer, size_t size);
> +
> +#endif /* _DRM_HDMI_H */
> --
> 1.8.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
--
Ville Syrjälä
Intel OTC
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v3 3/9] video: Add generic HDMI infoframe helpers
2013-01-16 13:27 ` Ville Syrjälä
@ 2013-01-18 8:56 ` Thierry Reding
2013-01-18 10:50 ` Ville Syrjälä
0 siblings, 1 reply; 21+ messages in thread
From: Thierry Reding @ 2013-01-18 8:56 UTC (permalink / raw)
To: Ville Syrjälä; +Cc: Paulo Zanoni, dri-devel
[-- Attachment #1.1: Type: text/plain, Size: 2824 bytes --]
On Wed, Jan 16, 2013 at 03:27:14PM +0200, Ville Syrjälä wrote:
> On Mon, Jan 14, 2013 at 03:30:22PM +0100, Thierry Reding wrote:
> > Add generic helpers to pack HDMI infoframes into binary buffers.
[...]
> > +/**
> > + * hdmi_avi_infoframe_init() - initialize an HDMI AVI infoframe
> > + * @frame: HDMI AVI infoframe
> > + *
> > + * Returns 0 on success or a negative error code on failure.
> > + */
> > +int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
> > +{
> > + if (!frame)
> > + return -EINVAL;
>
> There's quite a bit of error checking all around which seems a bit
> pointless since this is all internal stuff. Any errors are bugs in
> some driver code, so just letting the thing oops would be fine in my
> opinion.
Okay, I can remove some of the more obvious checks. Checking for space
requirements might still be useful, so I'll leave that in.
> > +ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
> > + size_t size)
[...]
> > + for (i = 0; i < sizeof(frame->vendor); i++)
> > + ptr[i] = frame->vendor[i];
> > +
> > + for (i = 0; i < sizeof(frame->product); i++)
> > + ptr[8 + i] = frame->product[i];
>
> memcpy()
Done.
> > +enum hdmi_spd_sdi {
> > + HDMI_SPD_SDI_UNKNOWN,
> > + HDMI_SPD_SDI_DSTB,
> > + HDMI_SPD_SDI_DVDP,
> > + HDMI_SPD_SDI_DVHS,
> > + HDMI_SPD_SDI_HDDVR,
> > + HDMI_SPD_SDI_DVC,
> > + HDMI_SPD_SDI_DSC,
> > + HDMI_SPD_SDI_VCD,
> > + HDMI_SPD_SDI_GAME,
> > + HDMI_SPD_SDI_PC,
> > + HDMI_SPD_SDI_BD,
> > + HDMI_SPD_SDI_SCD,
>
> I believe SACD is a more correct name.
Done.
> HD DVD and PMP are missing from this list.
I can't find any reference to those in CEA-861-D. HDMI 1.4 doesn't have
them either. Can you provide any pointers?
> > +enum hdmi_audio_coding_type {
> > + HDMI_AUDIO_CODING_TYPE_STREAM,
> > + HDMI_AUDIO_CODING_TYPE_IEC_60958,
> > + HDMI_AUDIO_CODING_TYPE_AC3,
> > + HDMI_AUDIO_CODING_TYPE_MPEG1,
> > + HDMI_AUDIO_CODING_TYPE_MP3,
> > + HDMI_AUDIO_CODING_TYPE_MPEG2,
> > + HDMI_AUDIO_CODING_TYPE_AAC,
> > + HDMI_AUDIO_CODING_TYPE_DTS,
> > + HDMI_AUDIO_CODING_TYPE_ATRAC,
> > + HDMI_AUDIO_CODING_TYPE_ONE_BIT_AUDIO,
> > + HDMI_AUDIO_CODING_TYPE_DOLBY_DIGITAL_PLUS,
> > + HDMI_AUDIO_CODING_TYPE_DTS_HD,
> > + HDMI_AUDIO_CODING_TYPE_MAT_MLP,
> > + HDMI_AUDIO_CODING_TYPE_DST,
> > + HDMI_AUDIO_CODING_TYPE_WMPRO,
>
> These don't always quite match the names in CEA-861-E. Wouldn't it
> be better to use matching names?
Are HD-DVD and PMP above listed in CEA-861-E? I'll need to find a copy
of it and will go over this again and match the names to those in the
document.
> Also the audio coding extension type is missing.
I assume this is also part of CEA-861-E as I can't find a reference in
-D?
Thanks for reviewing,
Thierry
[-- Attachment #1.2: Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v3 3/9] video: Add generic HDMI infoframe helpers
2013-01-18 8:56 ` Thierry Reding
@ 2013-01-18 10:50 ` Ville Syrjälä
0 siblings, 0 replies; 21+ messages in thread
From: Ville Syrjälä @ 2013-01-18 10:50 UTC (permalink / raw)
To: Thierry Reding; +Cc: Paulo Zanoni, dri-devel
On Fri, Jan 18, 2013 at 09:56:36AM +0100, Thierry Reding wrote:
> On Wed, Jan 16, 2013 at 03:27:14PM +0200, Ville Syrjälä wrote:
> > On Mon, Jan 14, 2013 at 03:30:22PM +0100, Thierry Reding wrote:
> > > Add generic helpers to pack HDMI infoframes into binary buffers.
> [...]
> > > +/**
> > > + * hdmi_avi_infoframe_init() - initialize an HDMI AVI infoframe
> > > + * @frame: HDMI AVI infoframe
> > > + *
> > > + * Returns 0 on success or a negative error code on failure.
> > > + */
> > > +int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
> > > +{
> > > + if (!frame)
> > > + return -EINVAL;
> >
> > There's quite a bit of error checking all around which seems a bit
> > pointless since this is all internal stuff. Any errors are bugs in
> > some driver code, so just letting the thing oops would be fine in my
> > opinion.
>
> Okay, I can remove some of the more obvious checks. Checking for space
> requirements might still be useful, so I'll leave that in.
>
> > > +ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
> > > + size_t size)
> [...]
> > > + for (i = 0; i < sizeof(frame->vendor); i++)
> > > + ptr[i] = frame->vendor[i];
> > > +
> > > + for (i = 0; i < sizeof(frame->product); i++)
> > > + ptr[8 + i] = frame->product[i];
> >
> > memcpy()
>
> Done.
>
> > > +enum hdmi_spd_sdi {
> > > + HDMI_SPD_SDI_UNKNOWN,
> > > + HDMI_SPD_SDI_DSTB,
> > > + HDMI_SPD_SDI_DVDP,
> > > + HDMI_SPD_SDI_DVHS,
> > > + HDMI_SPD_SDI_HDDVR,
> > > + HDMI_SPD_SDI_DVC,
> > > + HDMI_SPD_SDI_DSC,
> > > + HDMI_SPD_SDI_VCD,
> > > + HDMI_SPD_SDI_GAME,
> > > + HDMI_SPD_SDI_PC,
> > > + HDMI_SPD_SDI_BD,
> > > + HDMI_SPD_SDI_SCD,
> >
> > I believe SACD is a more correct name.
>
> Done.
>
> > HD DVD and PMP are missing from this list.
>
> I can't find any reference to those in CEA-861-D. HDMI 1.4 doesn't have
> them either. Can you provide any pointers?
CEA-861-E has them.
>
> > > +enum hdmi_audio_coding_type {
> > > + HDMI_AUDIO_CODING_TYPE_STREAM,
> > > + HDMI_AUDIO_CODING_TYPE_IEC_60958,
> > > + HDMI_AUDIO_CODING_TYPE_AC3,
> > > + HDMI_AUDIO_CODING_TYPE_MPEG1,
> > > + HDMI_AUDIO_CODING_TYPE_MP3,
> > > + HDMI_AUDIO_CODING_TYPE_MPEG2,
> > > + HDMI_AUDIO_CODING_TYPE_AAC,
> > > + HDMI_AUDIO_CODING_TYPE_DTS,
> > > + HDMI_AUDIO_CODING_TYPE_ATRAC,
> > > + HDMI_AUDIO_CODING_TYPE_ONE_BIT_AUDIO,
> > > + HDMI_AUDIO_CODING_TYPE_DOLBY_DIGITAL_PLUS,
> > > + HDMI_AUDIO_CODING_TYPE_DTS_HD,
> > > + HDMI_AUDIO_CODING_TYPE_MAT_MLP,
> > > + HDMI_AUDIO_CODING_TYPE_DST,
> > > + HDMI_AUDIO_CODING_TYPE_WMPRO,
> >
> > These don't always quite match the names in CEA-861-E. Wouldn't it
> > be better to use matching names?
>
> Are HD-DVD and PMP above listed in CEA-861-E? I'll need to find a copy
> of it and will go over this again and match the names to those in the
> document.
Great.
> > Also the audio coding extension type is missing.
>
> I assume this is also part of CEA-861-E as I can't find a reference in
> -D?
Yeah, I only checked against CEA-861-E.
--
Ville Syrjälä
Intel OTC
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v3 4/9] drm: Add HDMI infoframe helpers
2013-01-14 14:30 [PATCH v3 0/9] Add HDMI infoframe helpers Thierry Reding
` (2 preceding siblings ...)
2013-01-14 14:30 ` [PATCH v3 3/9] video: Add generic HDMI infoframe helpers Thierry Reding
@ 2013-01-14 14:30 ` Thierry Reding
2013-01-14 14:30 ` [PATCH v3 5/9] drm: Add EDID helper documentation Thierry Reding
` (4 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Thierry Reding @ 2013-01-14 14:30 UTC (permalink / raw)
To: dri-devel; +Cc: Paulo Zanoni
Add a generic helper to fill in an HDMI AVI infoframe with data
extracted from a DRM display mode.
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
Changes in v2:
- reuse CEA modes defined in drm_edid_modes.h
- don't use pixel aspect ratio for picture aspect
Changes in v3:
- move implementation into drm_edid.[ch]
drivers/gpu/drm/Kconfig | 1 +
drivers/gpu/drm/drm_edid.c | 33 +++++++++++++++++++++++++++++++++
include/drm/drm_edid.h | 6 ++++++
3 files changed, 40 insertions(+)
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 983201b..92d2294 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -7,6 +7,7 @@
menuconfig DRM
tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU
+ select HDMI
select I2C
select I2C_ALGOBIT
select DMA_SHARED_BUFFER
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 5a3770f..1cfafc0 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -29,6 +29,7 @@
*/
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <linux/hdmi.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <drm/drmP.h>
@@ -2098,3 +2099,35 @@ uint8_t drm_mode_cea_vic(const struct drm_display_mode *mode)
return 0;
}
EXPORT_SYMBOL(drm_mode_cea_vic);
+
+/**
+ * drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with
+ * data from a DRM display mode
+ * @frame: HDMI AVI infoframe
+ * @mode: DRM display mode
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int
+drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
+ const struct drm_display_mode *mode)
+{
+ int err;
+
+ if (!frame || !mode)
+ return -EINVAL;
+
+ err = hdmi_avi_infoframe_init(frame);
+ if (err < 0)
+ return err;
+
+ frame->video_code = drm_match_cea_mode(mode);
+ if (!frame->video_code)
+ return 0;
+
+ frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE;
+ frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_hdmi_avi_infoframe_from_display_mode);
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 0cac551..5da1b4a 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -247,6 +247,8 @@ struct edid {
struct drm_encoder;
struct drm_connector;
struct drm_display_mode;
+struct hdmi_avi_infoframe;
+
void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid);
int drm_av_sync_delay(struct drm_connector *connector,
struct drm_display_mode *mode);
@@ -254,4 +256,8 @@ struct drm_connector *drm_select_eld(struct drm_encoder *encoder,
struct drm_display_mode *mode);
int drm_load_edid_firmware(struct drm_connector *connector);
+int
+drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
+ const struct drm_display_mode *mode);
+
#endif /* __DRM_EDID_H__ */
--
1.8.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 5/9] drm: Add EDID helper documentation
2013-01-14 14:30 [PATCH v3 0/9] Add HDMI infoframe helpers Thierry Reding
` (3 preceding siblings ...)
2013-01-14 14:30 ` [PATCH v3 4/9] drm: Add " Thierry Reding
@ 2013-01-14 14:30 ` Thierry Reding
2013-01-14 14:30 ` [PATCH v3 6/9] drm/tegra: Use generic HDMI infoframe helpers Thierry Reding
` (3 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Thierry Reding @ 2013-01-14 14:30 UTC (permalink / raw)
To: dri-devel; +Cc: Paulo Zanoni
Add a reference section about the EDID helper functions to the DRM
documentation.
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
Documentation/DocBook/drm.tmpl | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl
index 4ee2304..34249bb 100644
--- a/Documentation/DocBook/drm.tmpl
+++ b/Documentation/DocBook/drm.tmpl
@@ -2111,6 +2111,10 @@ void intel_crt_init(struct drm_device *dev)
!Iinclude/drm/drm_dp_helper.h
!Edrivers/gpu/drm/drm_dp_helper.c
</sect2>
+ <sect2>
+ <title>EDID Helper Functions Reference</title>
+!Edrivers/gpu/drm/drm_edid.c
+ </sect2>
</sect1>
<!-- Internals: vertical blanking -->
--
1.8.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 6/9] drm/tegra: Use generic HDMI infoframe helpers
2013-01-14 14:30 [PATCH v3 0/9] Add HDMI infoframe helpers Thierry Reding
` (4 preceding siblings ...)
2013-01-14 14:30 ` [PATCH v3 5/9] drm: Add EDID helper documentation Thierry Reding
@ 2013-01-14 14:30 ` Thierry Reding
2013-01-14 14:30 ` [PATCH v3 7/9] drm/i915: " Thierry Reding
` (2 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Thierry Reding @ 2013-01-14 14:30 UTC (permalink / raw)
To: dri-devel; +Cc: Paulo Zanoni
Use the generic HDMI infoframe helpers to get rid of the NVIDIA Tegra
reimplementation.
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
drivers/gpu/drm/tegra/Kconfig | 1 +
drivers/gpu/drm/tegra/hdmi.c | 226 ++++++++++++++++++++----------------------
drivers/gpu/drm/tegra/hdmi.h | 189 -----------------------------------
3 files changed, 110 insertions(+), 306 deletions(-)
diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig
index 721483b..50d9c94 100644
--- a/drivers/gpu/drm/tegra/Kconfig
+++ b/drivers/gpu/drm/tegra/Kconfig
@@ -4,6 +4,7 @@ config DRM_TEGRA
select DRM_KMS_HELPER
select DRM_GEM_CMA_HELPER
select DRM_KMS_CMA_HELPER
+ select DRM_HDMI
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
index e060c7e..0daee8e 100644
--- a/drivers/gpu/drm/tegra/hdmi.c
+++ b/drivers/gpu/drm/tegra/hdmi.c
@@ -10,6 +10,7 @@
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/gpio.h>
+#include <linux/hdmi.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
@@ -17,6 +18,8 @@
#include <mach/clk.h>
+#include <drm/drm_edid.h>
+
#include "hdmi.h"
#include "drm.h"
#include "dc.h"
@@ -401,54 +404,65 @@ static int tegra_hdmi_setup_audio(struct tegra_hdmi *hdmi, unsigned int pclk)
return 0;
}
-static void tegra_hdmi_write_infopack(struct tegra_hdmi *hdmi,
- unsigned int offset, u8 type,
- u8 version, void *data, size_t size)
+static inline unsigned long tegra_hdmi_subpack(const u8 *ptr, size_t size)
{
- unsigned long value;
- u8 *ptr = data;
- u32 subpack[2];
+ unsigned long value = 0;
size_t i;
- u8 csum;
- /* first byte of data is the checksum */
- csum = type + version + size - 1;
+ for (i = size; i > 0; i--)
+ value = (value << 8) | ptr[i - 1];
- for (i = 1; i < size; i++)
- csum += ptr[i];
+ return value;
+}
- ptr[0] = 0x100 - csum;
+static void tegra_hdmi_write_infopack(struct tegra_hdmi *hdmi, const void *data,
+ size_t size)
+{
+ const u8 *ptr = data;
+ unsigned long offset;
+ unsigned long value;
+ size_t i, j;
- value = INFOFRAME_HEADER_TYPE(type) |
- INFOFRAME_HEADER_VERSION(version) |
- INFOFRAME_HEADER_LEN(size - 1);
- tegra_hdmi_writel(hdmi, value, offset);
+ switch (ptr[0]) {
+ case HDMI_INFOFRAME_TYPE_AVI:
+ offset = HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_HEADER;
+ break;
- /* The audio inforame only has one set of subpack registers. The hdmi
- * block pads the rest of the data as per the spec so we have to fixup
- * the length before filling in the subpacks.
- */
- if (offset == HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_HEADER)
- size = 6;
+ case HDMI_INFOFRAME_TYPE_AUDIO:
+ offset = HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_HEADER;
+ break;
- /* each subpack 7 bytes devided into:
- * subpack_low - bytes 0 - 3
- * subpack_high - bytes 4 - 6 (with byte 7 padded to 0x00)
- */
- for (i = 0; i < size; i++) {
- size_t index = i % 7;
+ case HDMI_INFOFRAME_TYPE_VENDOR:
+ offset = HDMI_NV_PDISP_HDMI_GENERIC_HEADER;
+ break;
+
+ default:
+ dev_err(hdmi->dev, "unsupported infoframe type: %02x\n",
+ ptr[0]);
+ return;
+ }
+
+ value = INFOFRAME_HEADER_TYPE(ptr[0]) |
+ INFOFRAME_HEADER_VERSION(ptr[1]) |
+ INFOFRAME_HEADER_LEN(ptr[2]);
+ tegra_hdmi_writel(hdmi, value, offset);
+ offset++;
- if (index == 0)
- memset(subpack, 0x0, sizeof(subpack));
+ /*
+ * Each subpack contains 7 bytes, divided into:
+ * - subpack_low: bytes 0 - 3
+ * - subpack_high: bytes 4 - 6 (with byte 7 padded to 0x00)
+ */
+ for (i = 3, j = 0; i < size; i += 7, j += 8) {
+ size_t rem = size - i, num = min_t(size_t, rem, 4);
- ((u8 *)subpack)[index] = ptr[i];
+ value = tegra_hdmi_subpack(&ptr[i], num);
+ tegra_hdmi_writel(hdmi, value, offset++);
- if (index == 6 || (i + 1 == size)) {
- unsigned int reg = offset + 1 + (i / 7) * 2;
+ num = min_t(size_t, rem - num, 3);
- tegra_hdmi_writel(hdmi, subpack[0], reg);
- tegra_hdmi_writel(hdmi, subpack[1], reg + 1);
- }
+ value = tegra_hdmi_subpack(&ptr[i + 4], num);
+ tegra_hdmi_writel(hdmi, value, offset++);
}
}
@@ -456,9 +470,8 @@ static void tegra_hdmi_setup_avi_infoframe(struct tegra_hdmi *hdmi,
struct drm_display_mode *mode)
{
struct hdmi_avi_infoframe frame;
- unsigned int h_front_porch;
- unsigned int hsize = 16;
- unsigned int vsize = 9;
+ u8 buffer[17];
+ ssize_t err;
if (hdmi->dvi) {
tegra_hdmi_writel(hdmi, 0,
@@ -466,69 +479,19 @@ static void tegra_hdmi_setup_avi_infoframe(struct tegra_hdmi *hdmi,
return;
}
- h_front_porch = mode->hsync_start - mode->hdisplay;
- memset(&frame, 0, sizeof(frame));
- frame.r = HDMI_AVI_R_SAME;
-
- switch (mode->vdisplay) {
- case 480:
- if (mode->hdisplay == 640) {
- frame.m = HDMI_AVI_M_4_3;
- frame.vic = 1;
- } else {
- frame.m = HDMI_AVI_M_16_9;
- frame.vic = 3;
- }
- break;
-
- case 576:
- if (((hsize * 10) / vsize) > 14) {
- frame.m = HDMI_AVI_M_16_9;
- frame.vic = 18;
- } else {
- frame.m = HDMI_AVI_M_4_3;
- frame.vic = 17;
- }
- break;
-
- case 720:
- case 1470: /* stereo mode */
- frame.m = HDMI_AVI_M_16_9;
-
- if (h_front_porch == 110)
- frame.vic = 4;
- else
- frame.vic = 19;
- break;
-
- case 1080:
- case 2205: /* stereo mode */
- frame.m = HDMI_AVI_M_16_9;
-
- switch (h_front_porch) {
- case 88:
- frame.vic = 16;
- break;
-
- case 528:
- frame.vic = 31;
- break;
-
- default:
- frame.vic = 32;
- break;
- }
- break;
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ if (err < 0) {
+ dev_err(hdmi->dev, "failed to setup AVI infoframe: %zd\n", err);
+ return;
+ }
- default:
- frame.m = HDMI_AVI_M_16_9;
- frame.vic = 0;
- break;
+ err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
+ if (err < 0) {
+ dev_err(hdmi->dev, "failed to pack AVI infoframe: %zd\n", err);
+ return;
}
- tegra_hdmi_write_infopack(hdmi, HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_HEADER,
- HDMI_INFOFRAME_TYPE_AVI, HDMI_AVI_VERSION,
- &frame, sizeof(frame));
+ tegra_hdmi_write_infopack(hdmi, buffer, err);
tegra_hdmi_writel(hdmi, INFOFRAME_CTRL_ENABLE,
HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL);
@@ -537,6 +500,8 @@ static void tegra_hdmi_setup_avi_infoframe(struct tegra_hdmi *hdmi,
static void tegra_hdmi_setup_audio_infoframe(struct tegra_hdmi *hdmi)
{
struct hdmi_audio_infoframe frame;
+ u8 buffer[14];
+ ssize_t err;
if (hdmi->dvi) {
tegra_hdmi_writel(hdmi, 0,
@@ -544,14 +509,29 @@ static void tegra_hdmi_setup_audio_infoframe(struct tegra_hdmi *hdmi)
return;
}
- memset(&frame, 0, sizeof(frame));
- frame.cc = HDMI_AUDIO_CC_2;
+ err = hdmi_audio_infoframe_init(&frame);
+ if (err < 0) {
+ dev_err(hdmi->dev, "failed to initialize audio infoframe: %d\n",
+ err);
+ return;
+ }
+
+ frame.channels = 2;
+
+ err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
+ if (err < 0) {
+ dev_err(hdmi->dev, "failed to pack audio infoframe: %zd\n",
+ err);
+ return;
+ }
- tegra_hdmi_write_infopack(hdmi,
- HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_HEADER,
- HDMI_INFOFRAME_TYPE_AUDIO,
- HDMI_AUDIO_VERSION,
- &frame, sizeof(frame));
+ /*
+ * The audio infoframe has only one set of subpack registers, so the
+ * infoframe needs to be truncated. One set of subpack registers can
+ * contain 7 bytes. Including the 3 byte header only the first 10
+ * bytes can be programmed.
+ */
+ tegra_hdmi_write_infopack(hdmi, buffer, min(10, err));
tegra_hdmi_writel(hdmi, INFOFRAME_CTRL_ENABLE,
HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL);
@@ -559,8 +539,10 @@ static void tegra_hdmi_setup_audio_infoframe(struct tegra_hdmi *hdmi)
static void tegra_hdmi_setup_stereo_infoframe(struct tegra_hdmi *hdmi)
{
- struct hdmi_stereo_infoframe frame;
+ struct hdmi_vendor_infoframe frame;
unsigned long value;
+ u8 buffer[10];
+ ssize_t err;
if (!hdmi->stereo) {
value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
@@ -570,22 +552,32 @@ static void tegra_hdmi_setup_stereo_infoframe(struct tegra_hdmi *hdmi)
}
memset(&frame, 0, sizeof(frame));
- frame.regid0 = 0x03;
- frame.regid1 = 0x0c;
- frame.regid2 = 0x00;
- frame.hdmi_video_format = 2;
+
+ frame.type = HDMI_INFOFRAME_TYPE_VENDOR;
+ frame.version = 0x01;
+ frame.length = 6;
+
+ frame.data[0] = 0x03; /* regid0 */
+ frame.data[1] = 0x0c; /* regid1 */
+ frame.data[2] = 0x00; /* regid2 */
+ frame.data[3] = 0x02 << 5; /* video format */
/* TODO: 74 MHz limit? */
if (1) {
- frame._3d_structure = 0;
+ frame.data[4] = 0x00 << 4; /* 3D structure */
} else {
- frame._3d_structure = 8;
- frame._3d_ext_data = 0;
+ frame.data[4] = 0x08 << 4; /* 3D structure */
+ frame.data[5] = 0x00 << 4; /* 3D ext. data */
+ }
+
+ err = hdmi_vendor_infoframe_pack(&frame, buffer, sizeof(buffer));
+ if (err < 0) {
+ dev_err(hdmi->dev, "failed to pack vendor infoframe: %zd\n",
+ err);
+ return;
}
- tegra_hdmi_write_infopack(hdmi, HDMI_NV_PDISP_HDMI_GENERIC_HEADER,
- HDMI_INFOFRAME_TYPE_VENDOR,
- HDMI_VENDOR_VERSION, &frame, 6);
+ tegra_hdmi_write_infopack(hdmi, buffer, err);
value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
value |= GENERIC_CTRL_ENABLE;
diff --git a/drivers/gpu/drm/tegra/hdmi.h b/drivers/gpu/drm/tegra/hdmi.h
index 1477f36..52ac36e 100644
--- a/drivers/gpu/drm/tegra/hdmi.h
+++ b/drivers/gpu/drm/tegra/hdmi.h
@@ -10,195 +10,6 @@
#ifndef TEGRA_HDMI_H
#define TEGRA_HDMI_H 1
-#define HDMI_INFOFRAME_TYPE_VENDOR 0x81
-#define HDMI_INFOFRAME_TYPE_AVI 0x82
-#define HDMI_INFOFRAME_TYPE_SPD 0x83
-#define HDMI_INFOFRAME_TYPE_AUDIO 0x84
-#define HDMI_INFOFRAME_TYPE_MPEG_SRC 0x85
-#define HDMI_INFOFRAME_TYPE_NTSC_VBI 0x86
-
-/* all fields little endian */
-struct hdmi_avi_infoframe {
- /* PB0 */
- u8 csum;
-
- /* PB1 */
- unsigned s:2; /* scan information */
- unsigned b:2; /* bar info data valid */
- unsigned a:1; /* active info present */
- unsigned y:2; /* RGB or YCbCr */
- unsigned res1:1;
-
- /* PB2 */
- unsigned r:4; /* active format aspect ratio */
- unsigned m:2; /* picture aspect ratio */
- unsigned c:2; /* colorimetry */
-
- /* PB3 */
- unsigned sc:2; /* scan information */
- unsigned q:2; /* quantization range */
- unsigned ec:3; /* extended colorimetry */
- unsigned itc:1; /* it content */
-
- /* PB4 */
- unsigned vic:7; /* video format id code */
- unsigned res4:1;
-
- /* PB5 */
- unsigned pr:4; /* pixel repetition factor */
- unsigned cn:2; /* it content type*/
- unsigned yq:2; /* ycc quantization range */
-
- /* PB6-7 */
- u16 top_bar_end_line;
-
- /* PB8-9 */
- u16 bot_bar_start_line;
-
- /* PB10-11 */
- u16 left_bar_end_pixel;
-
- /* PB12-13 */
- u16 right_bar_start_pixel;
-} __packed;
-
-#define HDMI_AVI_VERSION 0x02
-
-#define HDMI_AVI_Y_RGB 0x0
-#define HDMI_AVI_Y_YCBCR_422 0x1
-#define HDMI_AVI_Y_YCBCR_444 0x2
-
-#define HDMI_AVI_B_VERT 0x1
-#define HDMI_AVI_B_HORIZ 0x2
-
-#define HDMI_AVI_S_NONE 0x0
-#define HDMI_AVI_S_OVERSCAN 0x1
-#define HDMI_AVI_S_UNDERSCAN 0x2
-
-#define HDMI_AVI_C_NONE 0x0
-#define HDMI_AVI_C_SMPTE 0x1
-#define HDMI_AVI_C_ITU_R 0x2
-#define HDMI_AVI_C_EXTENDED 0x4
-
-#define HDMI_AVI_M_4_3 0x1
-#define HDMI_AVI_M_16_9 0x2
-
-#define HDMI_AVI_R_SAME 0x8
-#define HDMI_AVI_R_4_3_CENTER 0x9
-#define HDMI_AVI_R_16_9_CENTER 0xa
-#define HDMI_AVI_R_14_9_CENTER 0xb
-
-/* all fields little endian */
-struct hdmi_audio_infoframe {
- /* PB0 */
- u8 csum;
-
- /* PB1 */
- unsigned cc:3; /* channel count */
- unsigned res1:1;
- unsigned ct:4; /* coding type */
-
- /* PB2 */
- unsigned ss:2; /* sample size */
- unsigned sf:3; /* sample frequency */
- unsigned res2:3;
-
- /* PB3 */
- unsigned cxt:5; /* coding extention type */
- unsigned res3:3;
-
- /* PB4 */
- u8 ca; /* channel/speaker allocation */
-
- /* PB5 */
- unsigned res5:3;
- unsigned lsv:4; /* level shift value */
- unsigned dm_inh:1; /* downmix inhibit */
-
- /* PB6-10 reserved */
- u8 res6;
- u8 res7;
- u8 res8;
- u8 res9;
- u8 res10;
-} __packed;
-
-#define HDMI_AUDIO_VERSION 0x01
-
-#define HDMI_AUDIO_CC_STREAM 0x0 /* specified by audio stream */
-#define HDMI_AUDIO_CC_2 0x1
-#define HDMI_AUDIO_CC_3 0x2
-#define HDMI_AUDIO_CC_4 0x3
-#define HDMI_AUDIO_CC_5 0x4
-#define HDMI_AUDIO_CC_6 0x5
-#define HDMI_AUDIO_CC_7 0x6
-#define HDMI_AUDIO_CC_8 0x7
-
-#define HDMI_AUDIO_CT_STREAM 0x0 /* specified by audio stream */
-#define HDMI_AUDIO_CT_PCM 0x1
-#define HDMI_AUDIO_CT_AC3 0x2
-#define HDMI_AUDIO_CT_MPEG1 0x3
-#define HDMI_AUDIO_CT_MP3 0x4
-#define HDMI_AUDIO_CT_MPEG2 0x5
-#define HDMI_AUDIO_CT_AAC_LC 0x6
-#define HDMI_AUDIO_CT_DTS 0x7
-#define HDMI_AUDIO_CT_ATRAC 0x8
-#define HDMI_AUDIO_CT_DSD 0x9
-#define HDMI_AUDIO_CT_E_AC3 0xa
-#define HDMI_AUDIO_CT_DTS_HD 0xb
-#define HDMI_AUDIO_CT_MLP 0xc
-#define HDMI_AUDIO_CT_DST 0xd
-#define HDMI_AUDIO_CT_WMA_PRO 0xe
-#define HDMI_AUDIO_CT_CXT 0xf
-
-#define HDMI_AUDIO_SF_STREAM 0x0 /* specified by audio stream */
-#define HDMI_AUIDO_SF_32K 0x1
-#define HDMI_AUDIO_SF_44_1K 0x2
-#define HDMI_AUDIO_SF_48K 0x3
-#define HDMI_AUDIO_SF_88_2K 0x4
-#define HDMI_AUDIO_SF_96K 0x5
-#define HDMI_AUDIO_SF_176_4K 0x6
-#define HDMI_AUDIO_SF_192K 0x7
-
-#define HDMI_AUDIO_SS_STREAM 0x0 /* specified by audio stream */
-#define HDMI_AUDIO_SS_16BIT 0x1
-#define HDMI_AUDIO_SS_20BIT 0x2
-#define HDMI_AUDIO_SS_24BIT 0x3
-
-#define HDMI_AUDIO_CXT_CT 0x0 /* refer to coding in CT */
-#define HDMI_AUDIO_CXT_HE_AAC 0x1
-#define HDMI_AUDIO_CXT_HE_AAC_V2 0x2
-#define HDMI_AUDIO_CXT_MPEG_SURROUND 0x3
-
-/* all fields little endian */
-struct hdmi_stereo_infoframe {
- /* PB0 */
- u8 csum;
-
- /* PB1 */
- u8 regid0;
-
- /* PB2 */
- u8 regid1;
-
- /* PB3 */
- u8 regid2;
-
- /* PB4 */
- unsigned res1:5;
- unsigned hdmi_video_format:3;
-
- /* PB5 */
- unsigned res2:4;
- unsigned _3d_structure:4;
-
- /* PB6*/
- unsigned res3:4;
- unsigned _3d_ext_data:4;
-} __packed;
-
-#define HDMI_VENDOR_VERSION 0x01
-
/* register definitions */
#define HDMI_CTXSW 0x00
--
1.8.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 7/9] drm/i915: Use generic HDMI infoframe helpers
2013-01-14 14:30 [PATCH v3 0/9] Add HDMI infoframe helpers Thierry Reding
` (5 preceding siblings ...)
2013-01-14 14:30 ` [PATCH v3 6/9] drm/tegra: Use generic HDMI infoframe helpers Thierry Reding
@ 2013-01-14 14:30 ` Thierry Reding
2013-01-14 14:30 ` [PATCH v3 8/9] drm/radeon: " Thierry Reding
2013-01-14 14:30 ` [PATCH v3 9/9] drm: Remove duplicate drm_mode_cea_vic() Thierry Reding
8 siblings, 0 replies; 21+ messages in thread
From: Thierry Reding @ 2013-01-14 14:30 UTC (permalink / raw)
To: dri-devel; +Cc: Paulo Zanoni
From: Paulo Zanoni <paulo.r.zanoni@intel.com>
Use the generic HDMI infoframe helpers to get rid of the duplicate
implementation in the i915 driver.
This patch is based on the initial patch by Thierry Reding, but with a
different approach.
TODO:
- The SDVO part is totally untested. I am not sure if the buffer
size on the SDVO code must be a multiple of 4.
- The HDMI part was tested only on SNB/CPT.
- The patch is forcing pixel_repeat to 1 so I can properly test the
patch. Remove this before the final version.
- The correctnes of this patch depends on a fix on patch "video: add
Generic HDMI infoframe helpers"
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
drivers/gpu/drm/i915/intel_drv.h | 62 +------------
drivers/gpu/drm/i915/intel_hdmi.c | 186 ++++++++++++++++++++------------------
drivers/gpu/drm/i915/intel_sdvo.c | 21 ++---
3 files changed, 112 insertions(+), 157 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 8a1bd4a..f7c237d 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -26,6 +26,7 @@
#define __INTEL_DRV_H__
#include <linux/i2c.h>
+#include <linux/hdmi.h>
#include <drm/i915_drm.h>
#include "i915_drv.h"
#include <drm/drm_crtc.h>
@@ -276,63 +277,6 @@ struct cxsr_latency {
#define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
#define to_intel_plane(x) container_of(x, struct intel_plane, base)
-#define DIP_HEADER_SIZE 5
-
-#define DIP_TYPE_AVI 0x82
-#define DIP_VERSION_AVI 0x2
-#define DIP_LEN_AVI 13
-#define DIP_AVI_PR_1 0
-#define DIP_AVI_PR_2 1
-
-#define DIP_TYPE_SPD 0x83
-#define DIP_VERSION_SPD 0x1
-#define DIP_LEN_SPD 25
-#define DIP_SPD_UNKNOWN 0
-#define DIP_SPD_DSTB 0x1
-#define DIP_SPD_DVDP 0x2
-#define DIP_SPD_DVHS 0x3
-#define DIP_SPD_HDDVR 0x4
-#define DIP_SPD_DVC 0x5
-#define DIP_SPD_DSC 0x6
-#define DIP_SPD_VCD 0x7
-#define DIP_SPD_GAME 0x8
-#define DIP_SPD_PC 0x9
-#define DIP_SPD_BD 0xa
-#define DIP_SPD_SCD 0xb
-
-struct dip_infoframe {
- uint8_t type; /* HB0 */
- uint8_t ver; /* HB1 */
- uint8_t len; /* HB2 - body len, not including checksum */
- uint8_t ecc; /* Header ECC */
- uint8_t checksum; /* PB0 */
- union {
- struct {
- /* PB1 - Y 6:5, A 4:4, B 3:2, S 1:0 */
- uint8_t Y_A_B_S;
- /* PB2 - C 7:6, M 5:4, R 3:0 */
- uint8_t C_M_R;
- /* PB3 - ITC 7:7, EC 6:4, Q 3:2, SC 1:0 */
- uint8_t ITC_EC_Q_SC;
- /* PB4 - VIC 6:0 */
- uint8_t VIC;
- /* PB5 - YQ 7:6, CN 5:4, PR 3:0 */
- uint8_t YQ_CN_PR;
- /* PB6 to PB13 */
- uint16_t top_bar_end;
- uint16_t bottom_bar_start;
- uint16_t left_bar_end;
- uint16_t right_bar_start;
- } __attribute__ ((packed)) avi;
- struct {
- uint8_t vn[8];
- uint8_t pd[16];
- uint8_t sdi;
- } __attribute__ ((packed)) spd;
- uint8_t payload[27];
- } __attribute__ ((packed)) body;
-} __attribute__((packed));
-
struct intel_hdmi {
u32 sdvox_reg;
int ddc_bus;
@@ -341,7 +285,8 @@ struct intel_hdmi {
bool has_audio;
enum hdmi_force_audio force_audio;
void (*write_infoframe)(struct drm_encoder *encoder,
- struct dip_infoframe *frame);
+ uint8_t *frame, ssize_t len,
+ enum hdmi_infoframe_type type);
void (*set_infoframes)(struct drm_encoder *encoder,
struct drm_display_mode *adjusted_mode);
};
@@ -433,7 +378,6 @@ extern struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder);
extern bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
-extern void intel_dip_infoframe_csum(struct dip_infoframe *avi_if);
extern bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg,
bool is_sdvob);
extern void intel_dvo_init(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 2ee9821..b49df1b 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -29,6 +29,7 @@
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/delay.h>
+#include <linux/hdmi.h>
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
@@ -66,88 +67,75 @@ static struct intel_hdmi *intel_attached_hdmi(struct drm_connector *connector)
return enc_to_intel_hdmi(&intel_attached_encoder(connector)->base);
}
-void intel_dip_infoframe_csum(struct dip_infoframe *frame)
+static u32 g4x_infoframe_index(enum hdmi_infoframe_type type)
{
- uint8_t *data = (uint8_t *)frame;
- uint8_t sum = 0;
- unsigned i;
-
- frame->checksum = 0;
- frame->ecc = 0;
-
- for (i = 0; i < frame->len + DIP_HEADER_SIZE; i++)
- sum += data[i];
-
- frame->checksum = 0x100 - sum;
-}
-
-static u32 g4x_infoframe_index(struct dip_infoframe *frame)
-{
- switch (frame->type) {
- case DIP_TYPE_AVI:
+ switch (type) {
+ case HDMI_INFOFRAME_TYPE_AVI:
return VIDEO_DIP_SELECT_AVI;
- case DIP_TYPE_SPD:
+ case HDMI_INFOFRAME_TYPE_SPD:
return VIDEO_DIP_SELECT_SPD;
default:
- DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type);
+ DRM_DEBUG_DRIVER("unknown info frame type %d\n", type);
return 0;
}
}
-static u32 g4x_infoframe_enable(struct dip_infoframe *frame)
+static u32 g4x_infoframe_enable(enum hdmi_infoframe_type type)
{
- switch (frame->type) {
- case DIP_TYPE_AVI:
+ switch (type) {
+ case HDMI_INFOFRAME_TYPE_AVI:
return VIDEO_DIP_ENABLE_AVI;
- case DIP_TYPE_SPD:
+ case HDMI_INFOFRAME_TYPE_SPD:
return VIDEO_DIP_ENABLE_SPD;
default:
- DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type);
+ DRM_DEBUG_DRIVER("unknown info frame type %d\n", type);
return 0;
}
}
-static u32 hsw_infoframe_enable(struct dip_infoframe *frame)
+static u32 hsw_infoframe_enable(enum hdmi_infoframe_type type)
{
- switch (frame->type) {
- case DIP_TYPE_AVI:
+ switch (type) {
+ case HDMI_INFOFRAME_TYPE_AVI:
return VIDEO_DIP_ENABLE_AVI_HSW;
- case DIP_TYPE_SPD:
+ case HDMI_INFOFRAME_TYPE_SPD:
return VIDEO_DIP_ENABLE_SPD_HSW;
default:
- DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type);
+ DRM_DEBUG_DRIVER("unknown info frame type %d\n", type);
return 0;
}
}
-static u32 hsw_infoframe_data_reg(struct dip_infoframe *frame, enum pipe pipe)
+static u32 hsw_infoframe_data_reg(enum hdmi_infoframe_type type, enum pipe pipe)
{
- switch (frame->type) {
- case DIP_TYPE_AVI:
+ switch (type) {
+ case HDMI_INFOFRAME_TYPE_AVI:
return HSW_TVIDEO_DIP_AVI_DATA(pipe);
- case DIP_TYPE_SPD:
+ case HDMI_INFOFRAME_TYPE_SPD:
return HSW_TVIDEO_DIP_SPD_DATA(pipe);
default:
- DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type);
+ DRM_DEBUG_DRIVER("unknown info frame type %d\n", type);
return 0;
}
}
static void g4x_write_infoframe(struct drm_encoder *encoder,
- struct dip_infoframe *frame)
+ uint8_t *frame,
+ ssize_t len,
+ enum hdmi_infoframe_type type)
{
uint32_t *data = (uint32_t *)frame;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 val = I915_READ(VIDEO_DIP_CTL);
- unsigned i, len = DIP_HEADER_SIZE + frame->len;
+ unsigned int i;
WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n");
val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
- val |= g4x_infoframe_index(frame);
+ val |= g4x_infoframe_index(type);
- val &= ~g4x_infoframe_enable(frame);
+ val &= ~g4x_infoframe_enable(type);
I915_WRITE(VIDEO_DIP_CTL, val);
@@ -161,7 +149,7 @@ static void g4x_write_infoframe(struct drm_encoder *encoder,
I915_WRITE(VIDEO_DIP_DATA, 0);
mmiowb();
- val |= g4x_infoframe_enable(frame);
+ val |= g4x_infoframe_enable(type);
val &= ~VIDEO_DIP_FREQ_MASK;
val |= VIDEO_DIP_FREQ_VSYNC;
@@ -170,22 +158,24 @@ static void g4x_write_infoframe(struct drm_encoder *encoder,
}
static void ibx_write_infoframe(struct drm_encoder *encoder,
- struct dip_infoframe *frame)
+ uint8_t *frame,
+ ssize_t len,
+ enum hdmi_infoframe_type type)
{
uint32_t *data = (uint32_t *)frame;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
int reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
- unsigned i, len = DIP_HEADER_SIZE + frame->len;
+ unsigned int i;
u32 val = I915_READ(reg);
WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n");
val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
- val |= g4x_infoframe_index(frame);
+ val |= g4x_infoframe_index(type);
- val &= ~g4x_infoframe_enable(frame);
+ val &= ~g4x_infoframe_enable(type);
I915_WRITE(reg, val);
@@ -199,7 +189,7 @@ static void ibx_write_infoframe(struct drm_encoder *encoder,
I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
mmiowb();
- val |= g4x_infoframe_enable(frame);
+ val |= g4x_infoframe_enable(type);
val &= ~VIDEO_DIP_FREQ_MASK;
val |= VIDEO_DIP_FREQ_VSYNC;
@@ -208,25 +198,27 @@ static void ibx_write_infoframe(struct drm_encoder *encoder,
}
static void cpt_write_infoframe(struct drm_encoder *encoder,
- struct dip_infoframe *frame)
+ uint8_t *frame,
+ ssize_t len,
+ enum hdmi_infoframe_type type)
{
uint32_t *data = (uint32_t *)frame;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
int reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
- unsigned i, len = DIP_HEADER_SIZE + frame->len;
+ unsigned int i;
u32 val = I915_READ(reg);
WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n");
val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
- val |= g4x_infoframe_index(frame);
+ val |= g4x_infoframe_index(type);
/* The DIP control register spec says that we need to update the AVI
* infoframe without clearing its enable bit */
- if (frame->type != DIP_TYPE_AVI)
- val &= ~g4x_infoframe_enable(frame);
+ if (type != HDMI_INFOFRAME_TYPE_AVI)
+ val &= ~g4x_infoframe_enable(type);
I915_WRITE(reg, val);
@@ -240,31 +232,34 @@ static void cpt_write_infoframe(struct drm_encoder *encoder,
I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
mmiowb();
- val |= g4x_infoframe_enable(frame);
+ val |= g4x_infoframe_enable(type);
val &= ~VIDEO_DIP_FREQ_MASK;
val |= VIDEO_DIP_FREQ_VSYNC;
I915_WRITE(reg, val);
POSTING_READ(reg);
+
}
static void vlv_write_infoframe(struct drm_encoder *encoder,
- struct dip_infoframe *frame)
+ uint8_t *frame,
+ ssize_t len,
+ enum hdmi_infoframe_type type)
{
uint32_t *data = (uint32_t *)frame;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
int reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
- unsigned i, len = DIP_HEADER_SIZE + frame->len;
+ unsigned int i;
u32 val = I915_READ(reg);
WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n");
val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
- val |= g4x_infoframe_index(frame);
+ val |= g4x_infoframe_index(type);
- val &= ~g4x_infoframe_enable(frame);
+ val &= ~g4x_infoframe_enable(type);
I915_WRITE(reg, val);
@@ -278,7 +273,7 @@ static void vlv_write_infoframe(struct drm_encoder *encoder,
I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
mmiowb();
- val |= g4x_infoframe_enable(frame);
+ val |= g4x_infoframe_enable(type);
val &= ~VIDEO_DIP_FREQ_MASK;
val |= VIDEO_DIP_FREQ_VSYNC;
@@ -287,21 +282,23 @@ static void vlv_write_infoframe(struct drm_encoder *encoder,
}
static void hsw_write_infoframe(struct drm_encoder *encoder,
- struct dip_infoframe *frame)
+ uint8_t *frame,
+ ssize_t len,
+ enum hdmi_infoframe_type type)
{
uint32_t *data = (uint32_t *)frame;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->pipe);
- u32 data_reg = hsw_infoframe_data_reg(frame, intel_crtc->pipe);
- unsigned int i, len = DIP_HEADER_SIZE + frame->len;
+ u32 data_reg = hsw_infoframe_data_reg(type, intel_crtc->pipe);
+ unsigned int i;
u32 val = I915_READ(ctl_reg);
if (data_reg == 0)
return;
- val &= ~hsw_infoframe_enable(frame);
+ val &= ~hsw_infoframe_enable(type);
I915_WRITE(ctl_reg, val);
mmiowb();
@@ -314,50 +311,67 @@ static void hsw_write_infoframe(struct drm_encoder *encoder,
I915_WRITE(data_reg + i, 0);
mmiowb();
- val |= hsw_infoframe_enable(frame);
+ val |= hsw_infoframe_enable(type);
I915_WRITE(ctl_reg, val);
POSTING_READ(ctl_reg);
}
-static void intel_set_infoframe(struct drm_encoder *encoder,
- struct dip_infoframe *frame)
+static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
+ struct drm_display_mode *adjusted_mode)
{
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+ struct hdmi_avi_infoframe frame;
+ uint8_t buffer[20]; /* will be read as uin32_t, so 20 not 18 */
+ ssize_t len;
- intel_dip_infoframe_csum(frame);
- intel_hdmi->write_infoframe(encoder, frame);
-}
+ memset(buffer, 0, sizeof(buffer));
-static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
- struct drm_display_mode *adjusted_mode)
-{
- struct dip_infoframe avi_if = {
- .type = DIP_TYPE_AVI,
- .ver = DIP_VERSION_AVI,
- .len = DIP_LEN_AVI,
- };
+ len = drm_hdmi_avi_infoframe_from_display_mode(&frame, adjusted_mode);
+ WARN(len < 0, "drm_hdmi_avi_infoframe_from_display_mode failed\n");
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
- avi_if.body.avi.YQ_CN_PR |= DIP_AVI_PR_2;
+ frame.pixel_repeat = 1;
- avi_if.body.avi.VIC = drm_mode_cea_vic(adjusted_mode);
+ len = hdmi_avi_infoframe_pack(&frame, buffer + 1, sizeof(buffer) - 1);
+ WARN(len < 0, "hdmi_avi_infoframe_pack failed\n");
- intel_set_infoframe(encoder, &avi_if);
+ /* Insert the ECC */
+ buffer[0] = buffer[1];
+ buffer[1] = buffer[2];
+ buffer[2] = buffer[3];
+ buffer[3] = 0;
+ len++;
+
+ intel_hdmi->write_infoframe(encoder, buffer, len,
+ HDMI_INFOFRAME_TYPE_AVI);
}
static void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder)
{
- struct dip_infoframe spd_if;
+ struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+ struct hdmi_spd_infoframe frame;
+ uint8_t buffer[32]; /* will be read as uint32_t, so 32, not 30 */
+ ssize_t len;
+
+ memset(buffer, 0, sizeof(buffer));
+
+ len = hdmi_spd_infoframe_init(&frame, "Intel", "Integrated gfx");
+ WARN(len < 0, "hdmi_spd_infoframe_init failed\n");
+
+ frame.sdi = HDMI_SPD_SDI_PC;
+
+ len = hdmi_spd_infoframe_pack(&frame, buffer + 1, sizeof(buffer) - 1);
+ WARN(len < 0, "hdmi_spd_infoframe_pack failed\n");
- memset(&spd_if, 0, sizeof(spd_if));
- spd_if.type = DIP_TYPE_SPD;
- spd_if.ver = DIP_VERSION_SPD;
- spd_if.len = DIP_LEN_SPD;
- strcpy(spd_if.body.spd.vn, "Intel");
- strcpy(spd_if.body.spd.pd, "Integrated gfx");
- spd_if.body.spd.sdi = DIP_SPD_PC;
+ /* Insert the ECC */
+ buffer[0] = buffer[1];
+ buffer[1] = buffer[2];
+ buffer[2] = buffer[3];
+ buffer[3] = 0;
+ len++;
- intel_set_infoframe(encoder, &spd_if);
+ intel_hdmi->write_infoframe(encoder, buffer, len,
+ HDMI_INFOFRAME_TYPE_SPD);
}
static void g4x_set_infoframes(struct drm_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index c275bf0..e4abb55 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -29,6 +29,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/export.h>
+#include <linux/hdmi.h>
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
@@ -948,20 +949,16 @@ static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo,
static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo)
{
- struct dip_infoframe avi_if = {
- .type = DIP_TYPE_AVI,
- .ver = DIP_VERSION_AVI,
- .len = DIP_LEN_AVI,
- };
- uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)];
+ uint8_t sdvo_data[HDMI_AVI_INFOFRAME_SIZE +
+ HDMI_INFOFRAME_HEADER_SIZE];
+ struct hdmi_avi_infoframe frame;
+ ssize_t len;
- intel_dip_infoframe_csum(&avi_if);
+ len = hdmi_avi_infoframe_init(&frame);
+ WARN(len < 0, "hdmi_avi_infoframe_init failed!\n");
- /* sdvo spec says that the ecc is handled by the hw, and it looks like
- * we must not send the ecc field, either. */
- memcpy(sdvo_data, &avi_if, 3);
- sdvo_data[3] = avi_if.checksum;
- memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi));
+ len = hdmi_avi_infoframe_pack(&frame, sdvo_data, sizeof(sdvo_data));
+ WARN(len < 0, "hdmi_avi_infoframe_pack failed!\n");
return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF,
SDVO_HBUF_TX_VSYNC,
--
1.8.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 8/9] drm/radeon: Use generic HDMI infoframe helpers
2013-01-14 14:30 [PATCH v3 0/9] Add HDMI infoframe helpers Thierry Reding
` (6 preceding siblings ...)
2013-01-14 14:30 ` [PATCH v3 7/9] drm/i915: " Thierry Reding
@ 2013-01-14 14:30 ` Thierry Reding
2013-01-14 14:30 ` [PATCH v3 9/9] drm: Remove duplicate drm_mode_cea_vic() Thierry Reding
8 siblings, 0 replies; 21+ messages in thread
From: Thierry Reding @ 2013-01-14 14:30 UTC (permalink / raw)
To: dri-devel; +Cc: Paulo Zanoni
Use the generic HDMI infoframe helpers to get rid of the duplicate
implementation in the radeon driver.
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
drivers/gpu/drm/radeon/evergreen_hdmi.c | 85 +++++---------------
drivers/gpu/drm/radeon/r600_hdmi.c | 134 ++++++++++----------------------
2 files changed, 58 insertions(+), 161 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c
index 327c08b..4fdecc2 100644
--- a/drivers/gpu/drm/radeon/evergreen_hdmi.c
+++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c
@@ -24,6 +24,7 @@
* Authors: Christian König
* Rafał Miłecki
*/
+#include <linux/hdmi.h>
#include <drm/drmP.h>
#include <drm/radeon_drm.h>
#include "radeon.h"
@@ -54,79 +55,18 @@ static void evergreen_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t cloc
}
/*
- * calculate the crc for a given info frame
- */
-static void evergreen_hdmi_infoframe_checksum(uint8_t packetType,
- uint8_t versionNumber,
- uint8_t length,
- uint8_t *frame)
-{
- int i;
- frame[0] = packetType + versionNumber + length;
- for (i = 1; i <= length; i++)
- frame[0] += frame[i];
- frame[0] = 0x100 - frame[0];
-}
-
-/*
* build a HDMI Video Info Frame
*/
-static void evergreen_hdmi_videoinfoframe(
- struct drm_encoder *encoder,
- uint8_t color_format,
- int active_information_present,
- uint8_t active_format_aspect_ratio,
- uint8_t scan_information,
- uint8_t colorimetry,
- uint8_t ex_colorimetry,
- uint8_t quantization,
- int ITC,
- uint8_t picture_aspect_ratio,
- uint8_t video_format_identification,
- uint8_t pixel_repetition,
- uint8_t non_uniform_picture_scaling,
- uint8_t bar_info_data_valid,
- uint16_t top_bar,
- uint16_t bottom_bar,
- uint16_t left_bar,
- uint16_t right_bar
-)
+static void evergreen_hdmi_update_avi_infoframe(struct drm_encoder *encoder,
+ void *buffer, size_t size)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
uint32_t offset = dig->afmt->offset;
+ uint8_t *frame = buffer + 3;
- uint8_t frame[14];
-
- frame[0x0] = 0;
- frame[0x1] =
- (scan_information & 0x3) |
- ((bar_info_data_valid & 0x3) << 2) |
- ((active_information_present & 0x1) << 4) |
- ((color_format & 0x3) << 5);
- frame[0x2] =
- (active_format_aspect_ratio & 0xF) |
- ((picture_aspect_ratio & 0x3) << 4) |
- ((colorimetry & 0x3) << 6);
- frame[0x3] =
- (non_uniform_picture_scaling & 0x3) |
- ((quantization & 0x3) << 2) |
- ((ex_colorimetry & 0x7) << 4) |
- ((ITC & 0x1) << 7);
- frame[0x4] = (video_format_identification & 0x7F);
- frame[0x5] = (pixel_repetition & 0xF);
- frame[0x6] = (top_bar & 0xFF);
- frame[0x7] = (top_bar >> 8);
- frame[0x8] = (bottom_bar & 0xFF);
- frame[0x9] = (bottom_bar >> 8);
- frame[0xA] = (left_bar & 0xFF);
- frame[0xB] = (left_bar >> 8);
- frame[0xC] = (right_bar & 0xFF);
- frame[0xD] = (right_bar >> 8);
-
- evergreen_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame);
/* Our header values (type, version, length) should be alright, Intel
* is using the same. Checksum function also seems to be OK, it works
* fine for audio infoframe. However calculated value is always lower
@@ -154,7 +94,10 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
+ struct hdmi_avi_infoframe frame;
uint32_t offset;
+ ssize_t err;
/* Silent, r600_hdmi_enable will raise WARN for us */
if (!dig->afmt->enabled)
@@ -200,9 +143,19 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
WREG32(HDMI_GC + offset, 0); /* unset HDMI_GC_AVMUTE */
- evergreen_hdmi_videoinfoframe(encoder, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0);
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ if (err < 0) {
+ DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
+ return;
+ }
+
+ err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
+ if (err < 0) {
+ DRM_ERROR("failed to pack AVI infoframe: %zd\n", err);
+ return;
+ }
+ evergreen_hdmi_update_avi_infoframe(encoder, buffer, sizeof(buffer));
evergreen_hdmi_update_ACR(encoder, mode->clock);
/* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
index ff80efe..f35f148 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -23,6 +23,7 @@
*
* Authors: Christian König
*/
+#include <linux/hdmi.h>
#include <drm/drmP.h>
#include <drm/radeon_drm.h>
#include "radeon.h"
@@ -121,79 +122,18 @@ static void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock)
}
/*
- * calculate the crc for a given info frame
- */
-static void r600_hdmi_infoframe_checksum(uint8_t packetType,
- uint8_t versionNumber,
- uint8_t length,
- uint8_t *frame)
-{
- int i;
- frame[0] = packetType + versionNumber + length;
- for (i = 1; i <= length; i++)
- frame[0] += frame[i];
- frame[0] = 0x100 - frame[0];
-}
-
-/*
* build a HDMI Video Info Frame
*/
-static void r600_hdmi_videoinfoframe(
- struct drm_encoder *encoder,
- enum r600_hdmi_color_format color_format,
- int active_information_present,
- uint8_t active_format_aspect_ratio,
- uint8_t scan_information,
- uint8_t colorimetry,
- uint8_t ex_colorimetry,
- uint8_t quantization,
- int ITC,
- uint8_t picture_aspect_ratio,
- uint8_t video_format_identification,
- uint8_t pixel_repetition,
- uint8_t non_uniform_picture_scaling,
- uint8_t bar_info_data_valid,
- uint16_t top_bar,
- uint16_t bottom_bar,
- uint16_t left_bar,
- uint16_t right_bar
-)
+static void r600_hdmi_update_avi_infoframe(struct drm_encoder *encoder,
+ void *buffer, size_t size)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
uint32_t offset = dig->afmt->offset;
+ uint8_t *frame = buffer + 3;
- uint8_t frame[14];
-
- frame[0x0] = 0;
- frame[0x1] =
- (scan_information & 0x3) |
- ((bar_info_data_valid & 0x3) << 2) |
- ((active_information_present & 0x1) << 4) |
- ((color_format & 0x3) << 5);
- frame[0x2] =
- (active_format_aspect_ratio & 0xF) |
- ((picture_aspect_ratio & 0x3) << 4) |
- ((colorimetry & 0x3) << 6);
- frame[0x3] =
- (non_uniform_picture_scaling & 0x3) |
- ((quantization & 0x3) << 2) |
- ((ex_colorimetry & 0x7) << 4) |
- ((ITC & 0x1) << 7);
- frame[0x4] = (video_format_identification & 0x7F);
- frame[0x5] = (pixel_repetition & 0xF);
- frame[0x6] = (top_bar & 0xFF);
- frame[0x7] = (top_bar >> 8);
- frame[0x8] = (bottom_bar & 0xFF);
- frame[0x9] = (bottom_bar >> 8);
- frame[0xA] = (left_bar & 0xFF);
- frame[0xB] = (left_bar >> 8);
- frame[0xC] = (right_bar & 0xFF);
- frame[0xD] = (right_bar >> 8);
-
- r600_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame);
/* Our header values (type, version, length) should be alright, Intel
* is using the same. Checksum function also seems to be OK, it works
* fine for audio infoframe. However calculated value is always lower
@@ -215,39 +155,15 @@ static void r600_hdmi_videoinfoframe(
/*
* build a Audio Info Frame
*/
-static void r600_hdmi_audioinfoframe(
- struct drm_encoder *encoder,
- uint8_t channel_count,
- uint8_t coding_type,
- uint8_t sample_size,
- uint8_t sample_frequency,
- uint8_t format,
- uint8_t channel_allocation,
- uint8_t level_shift,
- int downmix_inhibit
-)
+static void r600_hdmi_update_audio_infoframe(struct drm_encoder *encoder,
+ const void *buffer, size_t size)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
uint32_t offset = dig->afmt->offset;
-
- uint8_t frame[11];
-
- frame[0x0] = 0;
- frame[0x1] = (channel_count & 0x7) | ((coding_type & 0xF) << 4);
- frame[0x2] = (sample_size & 0x3) | ((sample_frequency & 0x7) << 2);
- frame[0x3] = format;
- frame[0x4] = channel_allocation;
- frame[0x5] = ((level_shift & 0xF) << 3) | ((downmix_inhibit & 0x1) << 7);
- frame[0x6] = 0;
- frame[0x7] = 0;
- frame[0x8] = 0;
- frame[0x9] = 0;
- frame[0xA] = 0;
-
- r600_hdmi_infoframe_checksum(0x84, 0x01, 0x0A, frame);
+ const u8 *frame = buffer + 3;
WREG32(HDMI0_AUDIO_INFO0 + offset,
frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
@@ -320,7 +236,10 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
+ struct hdmi_avi_infoframe frame;
uint32_t offset;
+ ssize_t err;
/* Silent, r600_hdmi_enable will raise WARN for us */
if (!dig->afmt->enabled)
@@ -371,9 +290,19 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
WREG32(HDMI0_GC + offset, 0); /* unset HDMI0_GC_AVMUTE */
- r600_hdmi_videoinfoframe(encoder, RGB, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ if (err < 0) {
+ DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
+ return;
+ }
+ err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
+ if (err < 0) {
+ DRM_ERROR("failed to pack AVI infoframe: %zd\n", err);
+ return;
+ }
+
+ r600_hdmi_update_avi_infoframe(encoder, buffer, sizeof(buffer));
r600_hdmi_update_ACR(encoder, mode->clock);
/* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */
@@ -395,8 +324,11 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder)
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
struct r600_audio audio = r600_audio_status(rdev);
+ uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];
+ struct hdmi_audio_infoframe frame;
uint32_t offset;
uint32_t iec;
+ ssize_t err;
if (!dig->afmt || !dig->afmt->enabled)
return;
@@ -462,9 +394,21 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder)
iec |= 0x5 << 16;
WREG32_P(HDMI0_60958_1 + offset, iec, ~0x5000f);
- r600_hdmi_audioinfoframe(encoder, audio.channels - 1, 0, 0, 0, 0, 0, 0,
- 0);
+ err = hdmi_audio_infoframe_init(&frame);
+ if (err < 0) {
+ DRM_ERROR("failed to setup audio infoframe\n");
+ return;
+ }
+
+ frame.channels = audio.channels;
+
+ err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
+ if (err < 0) {
+ DRM_ERROR("failed to pack audio infoframe\n");
+ return;
+ }
+ r600_hdmi_update_audio_infoframe(encoder, buffer, sizeof(buffer));
r600_hdmi_audio_workaround(encoder);
}
--
1.8.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 9/9] drm: Remove duplicate drm_mode_cea_vic()
2013-01-14 14:30 [PATCH v3 0/9] Add HDMI infoframe helpers Thierry Reding
` (7 preceding siblings ...)
2013-01-14 14:30 ` [PATCH v3 8/9] drm/radeon: " Thierry Reding
@ 2013-01-14 14:30 ` Thierry Reding
2013-01-14 14:57 ` Ville Syrjälä
8 siblings, 1 reply; 21+ messages in thread
From: Thierry Reding @ 2013-01-14 14:30 UTC (permalink / raw)
To: dri-devel; +Cc: Paulo Zanoni
The same function had already been merged with a different name. Remove
the duplicate one but reuse some of its kerneldoc fragments for the
existing implementation.
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
drivers/gpu/drm/drm_edid.c | 30 +++++++-----------------------
include/drm/drm_crtc.h | 3 +--
2 files changed, 8 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 1cfafc0..0acd6f3 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1514,11 +1514,14 @@ u8 *drm_find_cea_extension(struct edid *edid)
}
EXPORT_SYMBOL(drm_find_cea_extension);
-/*
- * Looks for a CEA mode matching given drm_display_mode.
- * Returns its CEA Video ID code, or 0 if not found.
+/**
+ * drm_match_cea_mode - look for a CEA mode matching given mode
+ * @mode: display mode
+ *
+ * Returns the CEA Video ID (VIC) of the mode or 0 if it isn't a CEA-861
+ * mode.
*/
-u8 drm_match_cea_mode(struct drm_display_mode *to_match)
+u8 drm_match_cea_mode(const struct drm_display_mode *to_match)
{
struct drm_display_mode *cea_mode;
u8 mode;
@@ -2082,25 +2085,6 @@ int drm_add_modes_noedid(struct drm_connector *connector,
EXPORT_SYMBOL(drm_add_modes_noedid);
/**
- * drm_mode_cea_vic - return the CEA-861 VIC of a given mode
- * @mode: mode
- *
- * RETURNS:
- * The VIC number, 0 in case it's not a CEA-861 mode.
- */
-uint8_t drm_mode_cea_vic(const struct drm_display_mode *mode)
-{
- uint8_t i;
-
- for (i = 0; i < drm_num_cea_modes; i++)
- if (drm_mode_equal(mode, &edid_cea_modes[i]))
- return i + 1;
-
- return 0;
-}
-EXPORT_SYMBOL(drm_mode_cea_vic);
-
-/**
* drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with
* data from a DRM display mode
* @frame: HDMI AVI infoframe
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index dd62ca0..d0f3927 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1031,7 +1031,7 @@ extern int drm_mode_gamma_get_ioctl(struct drm_device *dev,
extern int drm_mode_gamma_set_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
extern u8 *drm_find_cea_extension(struct edid *edid);
-extern u8 drm_match_cea_mode(struct drm_display_mode *to_match);
+extern u8 drm_match_cea_mode(const struct drm_display_mode *to_match);
extern bool drm_detect_hdmi_monitor(struct edid *edid);
extern bool drm_detect_monitor_audio(struct edid *edid);
extern int drm_mode_page_flip_ioctl(struct drm_device *dev,
@@ -1048,7 +1048,6 @@ extern struct drm_display_mode *drm_gtf_mode_complex(struct drm_device *dev,
int GTF_2C, int GTF_K, int GTF_2J);
extern int drm_add_modes_noedid(struct drm_connector *connector,
int hdisplay, int vdisplay);
-extern uint8_t drm_mode_cea_vic(const struct drm_display_mode *mode);
extern int drm_edid_header_is_valid(const u8 *raw_edid);
extern bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid);
--
1.8.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH v3 9/9] drm: Remove duplicate drm_mode_cea_vic()
2013-01-14 14:30 ` [PATCH v3 9/9] drm: Remove duplicate drm_mode_cea_vic() Thierry Reding
@ 2013-01-14 14:57 ` Ville Syrjälä
2013-01-14 15:03 ` Thierry Reding
0 siblings, 1 reply; 21+ messages in thread
From: Ville Syrjälä @ 2013-01-14 14:57 UTC (permalink / raw)
To: Thierry Reding; +Cc: Paulo Zanoni, dri-devel
On Mon, Jan 14, 2013 at 03:30:28PM +0100, Thierry Reding wrote:
> The same function had already been merged with a different name. Remove
> the duplicate one but reuse some of its kerneldoc fragments for the
> existing implementation.
And I just used that function. Oh well ;)
Personally I would have kept the other function instead since it has a
more descriptive name, but I can't be bothered to care enough to
complain too much.
The patch could be moved to the beginning of the series, so it can be
merged w/o being blocked by the more invasive stuff. Well, assuming that
the more invasive stuff still needs discussing.
> Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
> ---
> drivers/gpu/drm/drm_edid.c | 30 +++++++-----------------------
> include/drm/drm_crtc.h | 3 +--
> 2 files changed, 8 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 1cfafc0..0acd6f3 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1514,11 +1514,14 @@ u8 *drm_find_cea_extension(struct edid *edid)
> }
> EXPORT_SYMBOL(drm_find_cea_extension);
>
> -/*
> - * Looks for a CEA mode matching given drm_display_mode.
> - * Returns its CEA Video ID code, or 0 if not found.
> +/**
> + * drm_match_cea_mode - look for a CEA mode matching given mode
> + * @mode: display mode
> + *
> + * Returns the CEA Video ID (VIC) of the mode or 0 if it isn't a CEA-861
> + * mode.
> */
> -u8 drm_match_cea_mode(struct drm_display_mode *to_match)
> +u8 drm_match_cea_mode(const struct drm_display_mode *to_match)
> {
> struct drm_display_mode *cea_mode;
> u8 mode;
> @@ -2082,25 +2085,6 @@ int drm_add_modes_noedid(struct drm_connector *connector,
> EXPORT_SYMBOL(drm_add_modes_noedid);
>
> /**
> - * drm_mode_cea_vic - return the CEA-861 VIC of a given mode
> - * @mode: mode
> - *
> - * RETURNS:
> - * The VIC number, 0 in case it's not a CEA-861 mode.
> - */
> -uint8_t drm_mode_cea_vic(const struct drm_display_mode *mode)
> -{
> - uint8_t i;
> -
> - for (i = 0; i < drm_num_cea_modes; i++)
> - if (drm_mode_equal(mode, &edid_cea_modes[i]))
> - return i + 1;
> -
> - return 0;
> -}
> -EXPORT_SYMBOL(drm_mode_cea_vic);
> -
> -/**
> * drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with
> * data from a DRM display mode
> * @frame: HDMI AVI infoframe
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index dd62ca0..d0f3927 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -1031,7 +1031,7 @@ extern int drm_mode_gamma_get_ioctl(struct drm_device *dev,
> extern int drm_mode_gamma_set_ioctl(struct drm_device *dev,
> void *data, struct drm_file *file_priv);
> extern u8 *drm_find_cea_extension(struct edid *edid);
> -extern u8 drm_match_cea_mode(struct drm_display_mode *to_match);
> +extern u8 drm_match_cea_mode(const struct drm_display_mode *to_match);
> extern bool drm_detect_hdmi_monitor(struct edid *edid);
> extern bool drm_detect_monitor_audio(struct edid *edid);
> extern int drm_mode_page_flip_ioctl(struct drm_device *dev,
> @@ -1048,7 +1048,6 @@ extern struct drm_display_mode *drm_gtf_mode_complex(struct drm_device *dev,
> int GTF_2C, int GTF_K, int GTF_2J);
> extern int drm_add_modes_noedid(struct drm_connector *connector,
> int hdisplay, int vdisplay);
> -extern uint8_t drm_mode_cea_vic(const struct drm_display_mode *mode);
>
> extern int drm_edid_header_is_valid(const u8 *raw_edid);
> extern bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid);
> --
> 1.8.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
--
Ville Syrjälä
Intel OTC
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v3 9/9] drm: Remove duplicate drm_mode_cea_vic()
2013-01-14 14:57 ` Ville Syrjälä
@ 2013-01-14 15:03 ` Thierry Reding
0 siblings, 0 replies; 21+ messages in thread
From: Thierry Reding @ 2013-01-14 15:03 UTC (permalink / raw)
To: Ville Syrjälä; +Cc: Paulo Zanoni, dri-devel
[-- Attachment #1.1: Type: text/plain, Size: 1159 bytes --]
On Mon, Jan 14, 2013 at 04:57:56PM +0200, Ville Syrjälä wrote:
> On Mon, Jan 14, 2013 at 03:30:28PM +0100, Thierry Reding wrote:
> > The same function had already been merged with a different name. Remove
> > the duplicate one but reuse some of its kerneldoc fragments for the
> > existing implementation.
>
> And I just used that function. Oh well ;)
>
> Personally I would have kept the other function instead since it has a
> more descriptive name, but I can't be bothered to care enough to
> complain too much.
drm_mode_cea_vic() was introduced later, so I preferred the older
variant.
> The patch could be moved to the beginning of the series, so it can be
> merged w/o being blocked by the more invasive stuff. Well, assuming that
> the more invasive stuff still needs discussing.
I had it at the beginning of the series, then realized that I hadn't
updated the i915 driver properly. So I cheated a bit and just moved the
patch instead of updating i915 and then resolving the conflict in the
subsequent i915 HDMI helper patch. =)
If the series can't be merged as-is, I can work this in for the next
version.
Thierry
[-- Attachment #1.2: Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 21+ messages in thread