[PATCH 1/3] [VPG HSW-A] drm/i915: Add aspect ratio in drm_display_mode
From: vkannan Mode is the video format, which is the information the sink needs to properly display an image. a complete definition of video format includes video timing, picture aspect ratio, color space, quantization range, component depth. video format timing may be associated with more than 1 video format for example, 720x480p formatted in the 4:3 Picture Aspect Ratio or a 720x480p formatted in the 16:9 Picture Aspect Ratio. For HDMI compliance, a set of CEA modes are tested (CEA 861-D table 3). This list has 64 modes. When one of the modes are set, the corresponding fields should show up correctly (as mentioned in Table 3 of CEA spec). For picture aspect ratio, if the mode is found from the CEA mode list, the corresponding PAR is sent as part of infoframe. If the mode to be set is not part of the CEA mode list, PAR is calculated from resolution. CEA modes have a specific picture aspect ratio. Adding this field as part of drm_display_mode. This is required to be sent as part of AVI infoframe for HDMI compliance. Signed-off-by: Vandana Kannan --- drivers/gpu/drm/drm_edid.c | 374 ++- drivers/gpu/drm/gma500/oaktrail_lvds.c | 14 +- drivers/gpu/drm/gma500/psb_intel_sdvo.c | 38 ++-- drivers/gpu/drm/i915/intel_display.c|3 +- drivers/gpu/drm/i915/intel_sdvo.c | 38 ++-- include/drm/drm_crtc.h |7 +- 6 files changed, 265 insertions(+), 209 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index e8d17ee..83e2fda 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -135,378 +135,379 @@ static const struct drm_display_mode drm_dmt_modes[] = { /* 640x350 at 85Hz */ { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 31500, 640, 672, 736, 832, 0, 350, 382, 385, 445, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, 0) }, /* 640x400 at 85Hz */ { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 31500, 640, 672, 736, 832, 0, 400, 401, 404, 445, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC, 0) }, /* 720x400 at 85Hz */ { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 756, 828, 936, 0, 400, 401, 404, 446, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC, 0) }, /* 640x480 at 60Hz */ { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, 752, 800, 0, 480, 489, 492, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, 0) }, /* 640x480 at 72Hz */ { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664, 704, 832, 0, 480, 489, 492, 520, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, 0) }, /* 640x480 at 75Hz */ { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656, 720, 840, 0, 480, 481, 484, 500, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, 0) }, /* 640x480 at 85Hz */ { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 36000, 640, 696, 752, 832, 0, 480, 481, 484, 509, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, 0) }, /* 800x600 at 56Hz */ { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824, 896, 1024, 0, 600, 601, 603, 625, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, 0) }, /* 800x600 at 60Hz */ { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 4, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, 0) }, /* 800x600 at 72Hz */ { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 5, 800, 856, 976, 1040, 0, 600, 637, 643, 666, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, 0) }, /* 800x600 at 75Hz */ { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816, 896, 1056, 0, 600, 601, 604, 625, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, 0) }, /* 800x600 at 85Hz */ { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER,
[PATCH 2/3] [VPG HSW-A] drm/i915: Add PAR support in AVI infoframe
From: vkannan Populate picture aspect ratio field of AVI infoframe. If there is a custom value to be set for aspect ratio, it takes highest priority, followed by a check in the CEA mode list. If the mode is not found in the standard mode list, aspect ratio is calculated based on aspect ratio. Priority of PAR value: 1. custom value, 2. based on CEA mode list, 3. calculate from resolution Signed-off-by: Vandana Kannan --- drivers/gpu/drm/drm_edid.c|7 +++ drivers/gpu/drm/i915/intel_hdmi.c | 25 + include/drm/drm_crtc.h|1 + 3 files changed, 33 insertions(+) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 83e2fda..110a56f 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -2427,6 +2427,13 @@ u8 drm_match_cea_mode(const struct drm_display_mode *to_match) } EXPORT_SYMBOL(drm_match_cea_mode); +enum hdmi_picture_aspect drm_get_cea_aspect_ratio(u8 vic) +{ + /*return Aspect Ratio for VIC-1 to access the right array element*/ + return edid_cea_modes[vic-1].picture_aspect_ratio; +} +EXPORT_SYMBOL(drm_get_cea_aspect_ratio); + static int add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid) { diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 1e6b5cf..7cf6fc5 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -334,10 +335,12 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, { struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); + enum hdmi_picture_aspect PAR; struct dip_infoframe avi_if = { .type = DIP_TYPE_AVI, .ver = DIP_VERSION_AVI, .len = DIP_LEN_AVI, + .body.avi.C_M_R = 8, }; if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) @@ -352,6 +355,28 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, avi_if.body.avi.VIC = drm_match_cea_mode(adjusted_mode); + /*If picture aspect ratio (PAR) is set to custom value, then use that, + else if VIC > 1, then get PAR from CEA mode list, else, calculate + PAR based on resolution */ + if (adjusted_mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_4_3 || + adjusted_mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_16_9) { + avi_if.body.avi.C_M_R |= + adjusted_mode->picture_aspect_ratio << 4; + /*PAR is bit 5:4 of data byte 2 of AVI infoframe */ + } else if (avi_if.body.avi.VIC) { + PAR = drm_get_cea_aspect_ratio(avi_if.body.avi.VIC); + avi_if.body.avi.C_M_R |= PAR << 4; + } else { + if (!(adjusted_mode->vdisplay % 3) && + ((adjusted_mode->vdisplay * 4 / 3) == + adjusted_mode->hdisplay)) + avi_if.body.avi.C_M_R |= HDMI_PICTURE_ASPECT_4_3 << 4; + else if (!(adjusted_mode->vdisplay % 9) && + ((adjusted_mode->vdisplay * 16 / 9) == + adjusted_mode->hdisplay)) + avi_if.body.avi.C_M_R |= HDMI_PICTURE_ASPECT_16_9 << 4; + } + intel_set_infoframe(encoder, &avi_if); } diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 07c0d58..e215bcc 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -1048,6 +1048,7 @@ 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(const struct drm_display_mode *to_match); +extern enum hdmi_picture_aspect drm_get_cea_aspect_ratio(u8 vic); extern bool drm_detect_hdmi_monitor(struct edid *edid); extern bool drm_detect_monitor_audio(struct edid *edid); extern bool drm_rgb_quant_range_selectable(struct edid *edid); -- 1.7.9.5
[PATCH 3/3] [VPG HSW-A] drm/i915: Populate all fields of AVI infoframe
From: vkannan Populate bar information, colorimetry, IT content, quantization range fields of AVI infoframe based on CEA 861-D spec. Signed-off-by: Vandana Kannan --- drivers/gpu/drm/i915/intel_drv.h |4 drivers/gpu/drm/i915/intel_hdmi.c | 39 +++-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 97df85d..e02c442 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -412,6 +412,10 @@ struct cxsr_latency { #define DIP_AVI_RGB_QUANT_RANGE_DEFAULT(0 << 2) #define DIP_AVI_RGB_QUANT_RANGE_LIMITED(1 << 2) #define DIP_AVI_RGB_QUANT_RANGE_FULL (2 << 2) +#define DIP_AVI_IT_CONTENT (1 << 7) +#define DIP_AVI_BAR_BOTH (3 << 2) +#define DIP_AVI_COLOR_ITU601 (1 << 6) +#define DIP_AVI_COLOR_ITU709 (2 << 6) #define DIP_TYPE_SPD 0x83 #define DIP_VERSION_SPD0x1 diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 7cf6fc5..dbbc02b 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -340,9 +340,22 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, .type = DIP_TYPE_AVI, .ver = DIP_VERSION_AVI, .len = DIP_LEN_AVI, + .body.avi.Y_A_B_S = 0, .body.avi.C_M_R = 8, + .body.avi.ITC_EC_Q_SC = 0, + .body.avi.VIC = 0, + .body.avi.YQ_CN_PR = 0, + .body.avi.top_bar_end = 0, + .body.avi.bottom_bar_start = 0, + .body.avi.left_bar_end = 0, + .body.avi.right_bar_start = 0, }; + /* Bar information */ + avi_if.body.avi.Y_A_B_S |= DIP_AVI_BAR_BOTH; + + avi_if.body.avi.VIC = drm_match_cea_mode(adjusted_mode); + if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) avi_if.body.avi.YQ_CN_PR |= DIP_AVI_PR_2; @@ -351,10 +364,17 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_LIMITED; else avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_FULL; + } else { + /* Set full range quantization for non-CEA modes + and 640x480 */ + if ((avi_if.body.avi.VIC == 0) || (avi_if.body.avi.VIC == 1)) + avi_if.body.avi.ITC_EC_Q_SC |= + DIP_AVI_RGB_QUANT_RANGE_FULL; + else + avi_if.body.avi.ITC_EC_Q_SC |= + DIP_AVI_RGB_QUANT_RANGE_LIMITED; } - avi_if.body.avi.VIC = drm_match_cea_mode(adjusted_mode); - /*If picture aspect ratio (PAR) is set to custom value, then use that, else if VIC > 1, then get PAR from CEA mode list, else, calculate PAR based on resolution */ @@ -377,6 +397,21 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, avi_if.body.avi.C_M_R |= HDMI_PICTURE_ASPECT_16_9 << 4; } + if (avi_if.body.avi.VIC) { + /* colorimetry: Sections 5.1 and 5.2 of CEA 861-D spec */ + if ((adjusted_mode->vdisplay == 480) || + (adjusted_mode->vdisplay == 576) || + (adjusted_mode->vdisplay == 240) || + (adjusted_mode->vdisplay == 288)) { + avi_if.body.avi.C_M_R |= DIP_AVI_COLOR_ITU601; + } else if ((adjusted_mode->vdisplay == 720) || + (adjusted_mode->vdisplay == 1080)) { + avi_if.body.avi.C_M_R |= DIP_AVI_COLOR_ITU709; + } + } + + avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_IT_CONTENT; + intel_set_infoframe(encoder, &avi_if); } -- 1.7.9.5