mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	drm/edid: Don't send non-zero YQ in AVI infoframe for HDMI 1.x sinks
Apparently some sinks look at the YQ bits even when receiving RGB,
and they get somehow confused when they see a non-zero YQ value.
So we can't just blindly follow CEA-861-F and set YQ to match the
RGB range.
Unfortunately there is no good way to tell whether the sink
designer claims to have read CEA-861-F. The CEA extension block
revision number has generally been stuck at 3 since forever,
and even a very recently manufactured sink might be based on
an old design so the manufacturing date doesn't seem like
something we can use. In lieu of better information let's
follow CEA-861-F only for HDMI 2.0 sinks, since HDMI 2.0 is
based on CEA-861-F. For HDMI 1.x sinks we'll always set YQ=0.
The alternative would of course be to always set YQ=0. And if
we ever encounter a HDMI 2.0+ sink with this bug that's what
we'll probably have to do.
Cc: stable@vger.kernel.org
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Eric Anholt <eric@anholt.net>
Cc: Neil Kownacki <njkkow@gmail.com>
Reported-by: Neil Kownacki <njkkow@gmail.com>
Tested-by: Neil Kownacki <njkkow@gmail.com>
Fixes: fcc8a22cc9 ("drm/edid: Set YQ bits in the AVI infoframe according to CEA-861-F")
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101639
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20171108152504.12596-1-ville.syrjala@linux.intel.com
Acked-by: Eric Anholt <eric@anholt.net>
			
			
This commit is contained in:
		
							parent
							
								
									253696ccd6
								
							
						
					
					
						commit
						9271c0ca57
					
				
					 4 changed files with 16 additions and 5 deletions
				
			
		| 
						 | 
				
			
			@ -4809,7 +4809,8 @@ void
 | 
			
		|||
drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
 | 
			
		||||
				   const struct drm_display_mode *mode,
 | 
			
		||||
				   enum hdmi_quantization_range rgb_quant_range,
 | 
			
		||||
				   bool rgb_quant_range_selectable)
 | 
			
		||||
				   bool rgb_quant_range_selectable,
 | 
			
		||||
				   bool is_hdmi2_sink)
 | 
			
		||||
{
 | 
			
		||||
	/*
 | 
			
		||||
	 * CEA-861:
 | 
			
		||||
| 
						 | 
				
			
			@ -4833,8 +4834,15 @@ drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
 | 
			
		|||
	 *  YQ-field to match the RGB Quantization Range being transmitted
 | 
			
		||||
	 *  (e.g., when Limited Range RGB, set YQ=0 or when Full Range RGB,
 | 
			
		||||
	 *  set YQ=1) and the Sink shall ignore the YQ-field."
 | 
			
		||||
	 *
 | 
			
		||||
	 * Unfortunate certain sinks (eg. VIZ Model 67/E261VA) get confused
 | 
			
		||||
	 * by non-zero YQ when receiving RGB. There doesn't seem to be any
 | 
			
		||||
	 * good way to tell which version of CEA-861 the sink supports, so
 | 
			
		||||
	 * we limit non-zero YQ to HDMI 2.0 sinks only as HDMI 2.0 is based
 | 
			
		||||
	 * on on CEA-861-F.
 | 
			
		||||
	 */
 | 
			
		||||
	if (rgb_quant_range == HDMI_QUANTIZATION_RANGE_LIMITED)
 | 
			
		||||
	if (!is_hdmi2_sink ||
 | 
			
		||||
	    rgb_quant_range == HDMI_QUANTIZATION_RANGE_LIMITED)
 | 
			
		||||
		frame->ycc_quantization_range =
 | 
			
		||||
			HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
 | 
			
		||||
	else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -481,7 +481,8 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
 | 
			
		|||
					   crtc_state->limited_color_range ?
 | 
			
		||||
					   HDMI_QUANTIZATION_RANGE_LIMITED :
 | 
			
		||||
					   HDMI_QUANTIZATION_RANGE_FULL,
 | 
			
		||||
					   intel_hdmi->rgb_quant_range_selectable);
 | 
			
		||||
					   intel_hdmi->rgb_quant_range_selectable,
 | 
			
		||||
					   is_hdmi2_sink);
 | 
			
		||||
 | 
			
		||||
	/* TODO: handle pixel repetition for YCBCR420 outputs */
 | 
			
		||||
	intel_write_infoframe(encoder, crtc_state, &frame);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -433,7 +433,8 @@ static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
 | 
			
		|||
					   vc4_encoder->limited_rgb_range ?
 | 
			
		||||
					   HDMI_QUANTIZATION_RANGE_LIMITED :
 | 
			
		||||
					   HDMI_QUANTIZATION_RANGE_FULL,
 | 
			
		||||
					   vc4_encoder->rgb_range_selectable);
 | 
			
		||||
					   vc4_encoder->rgb_range_selectable,
 | 
			
		||||
					   false);
 | 
			
		||||
 | 
			
		||||
	vc4_hdmi_write_infoframe(encoder, &frame);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -360,7 +360,8 @@ void
 | 
			
		|||
drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
 | 
			
		||||
				   const struct drm_display_mode *mode,
 | 
			
		||||
				   enum hdmi_quantization_range rgb_quant_range,
 | 
			
		||||
				   bool rgb_quant_range_selectable);
 | 
			
		||||
				   bool rgb_quant_range_selectable,
 | 
			
		||||
				   bool is_hdmi2_sink);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * drm_eld_mnl - Get ELD monitor name length in bytes.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue