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@xxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/Kconfig | 7 +++ drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/drm_hdmi.c | 107 +++++++++++++++++++++++++++++++++++++++++++++ include/drm/drm_hdmi.h | 18 ++++++++ 4 files changed, 133 insertions(+) create mode 100644 drivers/gpu/drm/drm_hdmi.c create mode 100644 include/drm/drm_hdmi.h diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 983201b..94a4623 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -69,6 +69,13 @@ config DRM_KMS_CMA_HELPER help Choose this if you need the KMS CMA helper functions +config DRM_HDMI + bool + depends on DRM + select HDMI + help + Choose this if you need the HDMI helper functions + config DRM_TDFX tristate "3dfx Banshee/Voodoo3+" depends on DRM && PCI diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 0bfda06..330451b 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -16,6 +16,7 @@ drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ drm-$(CONFIG_COMPAT) += drm_ioc32.o drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o +drm-$(CONFIG_DRM_HDMI) += drm_hdmi.o drm-usb-y := drm_usb.o diff --git a/drivers/gpu/drm/drm_hdmi.c b/drivers/gpu/drm/drm_hdmi.c new file mode 100644 index 0000000..1a8d914 --- /dev/null +++ b/drivers/gpu/drm/drm_hdmi.c @@ -0,0 +1,107 @@ +/* + * 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/hdmi.h> + +#include <drm/drm_crtc.h> +#include <drm/drm_hdmi.h> + +struct hdmi_cea_mode { + unsigned char vic; + unsigned int width; + unsigned int height; + unsigned int refresh; + enum hdmi_picture_aspect aspect; + bool interlaced; + unsigned int repeat_min; + unsigned int repeat_max; +}; + +static const struct hdmi_cea_mode hdmi_cea_modes[] = { + { 1, 640, 480, 60, HDMI_PICTURE_ASPECT_4_3, false, 0, 0 }, + { 2, 720, 480, 60, HDMI_PICTURE_ASPECT_NONE, false, 0, 0 }, + { 4, 1280, 720, 60, HDMI_PICTURE_ASPECT_16_9, false, 0, 0 }, + { 5, 1920, 1080, 60, HDMI_PICTURE_ASPECT_16_9, true, 0, 0 }, + { 6, 720, 480, 60, HDMI_PICTURE_ASPECT_NONE, true, 1, 1 }, + { 8, 720, 240, 60, HDMI_PICTURE_ASPECT_NONE, false, 1, 1 }, + { 10, 2880, 480, 60, HDMI_PICTURE_ASPECT_NONE, true, 0, 9 }, + { 12, 2880, 240, 60, HDMI_PICTURE_ASPECT_NONE, false, 0, 9 }, + { 14, 1440, 480, 60, HDMI_PICTURE_ASPECT_NONE, false, 0, 1 }, + { 16, 1920, 1080, 60, HDMI_PICTURE_ASPECT_16_9, false, 0, 0 }, + { 17, 720, 576, 50, HDMI_PICTURE_ASPECT_NONE, false, 0, 0 }, + { 19, 1280, 720, 50, HDMI_PICTURE_ASPECT_16_9, false, 0, 0 }, + { 20, 1920, 1080, 50, HDMI_PICTURE_ASPECT_16_9, true, 0, 0 }, + { 21, 720, 576, 50, HDMI_PICTURE_ASPECT_NONE, true, 1, 1 }, + { 23, 720, 288, 50, HDMI_PICTURE_ASPECT_NONE, false, 1, 1 }, + { 25, 2880, 576, 50, HDMI_PICTURE_ASPECT_NONE, true, 0, 9 }, + { 27, 2880, 288, 50, HDMI_PICTURE_ASPECT_NONE, false, 0, 9 }, + { 29, 1440, 576, 50, HDMI_PICTURE_ASPECT_NONE, false, 0, 1 }, + { 31, 1920, 1080, 50, HDMI_PICTURE_ASPECT_16_9, false, 0, 0 }, + { 32, 1920, 1080, 24, HDMI_PICTURE_ASPECT_16_9, false, 0, 0 }, + { 33, 1920, 1080, 25, HDMI_PICTURE_ASPECT_16_9, false, 0, 0 }, + { 34, 1920, 1080, 30, HDMI_PICTURE_ASPECT_16_9, false, 0, 0 }, + { 35, 2880, 480, 60, HDMI_PICTURE_ASPECT_NONE, false, 0, 3 }, + { 37, 2880, 576, 50, HDMI_PICTURE_ASPECT_NONE, false, 0, 3 }, + { 39, 1920, 1080, 50, HDMI_PICTURE_ASPECT_16_9, true, 0, 0 }, + { 40, 1920, 1080, 100, HDMI_PICTURE_ASPECT_16_9, true, 0, 0 }, + { 41, 1280, 720, 100, HDMI_PICTURE_ASPECT_16_9, false, 0, 0 }, + { 42, 720, 576, 100, HDMI_PICTURE_ASPECT_NONE, false, 0, 0 }, + { 43, 720, 576, 100, HDMI_PICTURE_ASPECT_NONE, false, 0, 0 }, + { 44, 720, 576, 100, HDMI_PICTURE_ASPECT_NONE, true, 1, 1 }, + { 45, 720, 576, 100, HDMI_PICTURE_ASPECT_NONE, true, 1, 1 }, + { 46, 1920, 1080, 120, HDMI_PICTURE_ASPECT_16_9, true, 0, 0 }, + { 47, 1280, 720, 120, HDMI_PICTURE_ASPECT_16_9, false, 0, 0 }, + { 48, 720, 480, 120, HDMI_PICTURE_ASPECT_NONE, false, 0, 0 }, + { 49, 720, 480, 120, HDMI_PICTURE_ASPECT_NONE, false, 0, 0 }, + { 50, 720, 480, 120, HDMI_PICTURE_ASPECT_NONE, true, 1, 1 }, + { 51, 720, 480, 120, HDMI_PICTURE_ASPECT_NONE, true, 1, 1 }, + { 52, 720, 576, 200, HDMI_PICTURE_ASPECT_NONE, false, 0, 0 }, + { 53, 720, 576, 200, HDMI_PICTURE_ASPECT_NONE, false, 0, 0 }, + { 54, 720, 576, 200, HDMI_PICTURE_ASPECT_NONE, true, 1, 1 }, + { 55, 720, 576, 200, HDMI_PICTURE_ASPECT_NONE, true, 1, 1 }, + { 56, 720, 480, 240, HDMI_PICTURE_ASPECT_NONE, false, 0, 0 }, + { 57, 720, 480, 240, HDMI_PICTURE_ASPECT_NONE, false, 0, 0 }, + { 58, 720, 480, 240, HDMI_PICTURE_ASPECT_NONE, true, 1, 1 }, + { 59, 720, 480, 240, HDMI_PICTURE_ASPECT_NONE, true, 1, 1 }, + { 60, 1280, 720, 24, HDMI_PICTURE_ASPECT_16_9, false, 0, 0 }, + { 61, 1280, 720, 25, HDMI_PICTURE_ASPECT_16_9, false, 0, 0 }, + { 62, 1280, 720, 30, HDMI_PICTURE_ASPECT_16_9, false, 0, 0 }, + { 63, 1920, 1080, 120, HDMI_PICTURE_ASPECT_16_9, false, 0, 0 }, + { 64, 1920, 1080, 100, HDMI_PICTURE_ASPECT_16_9, false, 0, 0 }, +}; + +int drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, + struct drm_display_mode *mode) +{ + unsigned int i; + + memset(frame, 0, sizeof(*frame)); + + frame->type = HDMI_INFOFRAME_TYPE_AVI; + frame->version = 2; + frame->length = 13; + + for (i = 0; i < ARRAY_SIZE(hdmi_cea_modes); i++) { + const struct hdmi_cea_mode *cea = &hdmi_cea_modes[i]; + + if (mode->hdisplay != cea->width || + mode->vdisplay != cea->height) + continue; + + if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && !cea->interlaced) + continue; + + frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE; + frame->picture_aspect = cea->aspect; + frame->video_code = cea->vic; + break; + } + + return 0; +} +EXPORT_SYMBOL_GPL(drm_hdmi_avi_infoframe_from_display_mode); diff --git a/include/drm/drm_hdmi.h b/include/drm/drm_hdmi.h new file mode 100644 index 0000000..07ce049 --- /dev/null +++ b/include/drm/drm_hdmi.h @@ -0,0 +1,18 @@ +/* + * 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 _DRM_HDMI_H_ +#define _DRM_HDMI_H_ + +struct hdmi_avi_infoframe; +struct drm_display_mode; + +int drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, + struct drm_display_mode *mode); + +#endif -- 1.8.0 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel