diff options
Diffstat (limited to 'drivers/gpu/drm/drm_edid.c')
| -rw-r--r-- | drivers/gpu/drm/drm_edid.c | 222 | 
1 files changed, 172 insertions, 50 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 6b0177112e18..474ac04d5600 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -1278,6 +1278,106 @@ static const struct drm_display_mode edid_cea_modes[] = {  		   4104, 4400, 0, 2160, 2168, 2178, 2250, 0,  		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),  	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, }, +	/* 108 - 1280x720@48Hz 16:9 */ +	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 90000, 1280, 2240, +		   2280, 2500, 0, 720, 725, 730, 750, 0, +		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, +	/* 109 - 1280x720@48Hz 64:27 */ +	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 90000, 1280, 2240, +		   2280, 2500, 0, 720, 725, 730, 750, 0, +		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, }, +	/* 110 - 1680x720@48Hz 64:27 */ +	{ DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 99000, 1680, 2490, +		   2530, 2750, 0, 720, 725, 730, 750, 0, +		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, }, +	/* 111 - 1920x1080@48Hz 16:9 */ +	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2558, +		   2602, 2750, 0, 1080, 1084, 1089, 1125, 0, +		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, +	/* 112 - 1920x1080@48Hz 64:27 */ +	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2558, +		   2602, 2750, 0, 1080, 1084, 1089, 1125, 0, +		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, }, +	/* 113 - 2560x1080@48Hz 64:27 */ +	{ DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 198000, 2560, 3558, +		   3602, 3750, 0, 1080, 1084, 1089, 1100, 0, +		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, }, +	/* 114 - 3840x2160@48Hz 16:9 */ +	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 5116, +		   5204, 5500, 0, 2160, 2168, 2178, 2250, 0, +		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, +	/* 115 - 4096x2160@48Hz 256:135 */ +	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 5116, +		   5204, 5500, 0, 2160, 2168, 2178, 2250, 0, +		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, }, +	/* 116 - 3840x2160@48Hz 64:27 */ +	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 5116, +		   5204, 5500, 0, 2160, 2168, 2178, 2250, 0, +		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, }, +	/* 117 - 3840x2160@100Hz 16:9 */ +	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4896, +		   4984, 5280, 0, 2160, 2168, 2178, 2250, 0, +		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, +	/* 118 - 3840x2160@120Hz 16:9 */ +	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4016, +		   4104, 4400, 0, 2160, 2168, 2178, 2250, 0, +		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +	  .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, +	/* 119 - 3840x2160@100Hz 64:27 */ +	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4896, +		   4984, 5280, 0, 2160, 2168, 2178, 2250, 0, +		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, }, +	/* 120 - 3840x2160@120Hz 64:27 */ +	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4016, +		   4104, 4400, 0, 2160, 2168, 2178, 2250, 0, +		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +	  .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, }, +	/* 121 - 5120x2160@24Hz 64:27 */ +	{ DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 396000, 5120, 7116, +		   7204, 7500, 0, 2160, 2168, 2178, 2200, 0, +		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +	  .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, }, +	/* 122 - 5120x2160@25Hz 64:27 */ +	{ DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 396000, 5120, 6816, +		   6904, 7200, 0, 2160, 2168, 2178, 2200, 0, +		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +	  .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, }, +	/* 123 - 5120x2160@30Hz 64:27 */ +	{ DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 396000, 5120, 5784, +		   5872, 6000, 0, 2160, 2168, 2178, 2200, 0, +		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +	  .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, }, +	/* 124 - 5120x2160@48Hz 64:27 */ +	{ DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 742500, 5120, 5866, +		   5954, 6250, 0, 2160, 2168, 2178, 2475, 0, +		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, }, +	/* 125 - 5120x2160@50Hz 64:27 */ +	{ DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 742500, 5120, 6216, +		   6304, 6600, 0, 2160, 2168, 2178, 2250, 0, +		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, }, +	/* 126 - 5120x2160@60Hz 64:27 */ +	{ DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 742500, 5120, 5284, +		   5372, 5500, 0, 2160, 2168, 2178, 2250, 0, +		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, }, +	/* 127 - 5120x2160@100Hz 64:27 */ +	{ DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 1485000, 5120, 6216, +		   6304, 6600, 0, 2160, 2168, 2178, 2250, 0, +		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), +	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },  };  /* @@ -1554,7 +1654,7 @@ static void connector_bad_edid(struct drm_connector *connector,  {  	int i; -	if (connector->bad_edid_counter++ && !(drm_debug & DRM_UT_KMS)) +	if (connector->bad_edid_counter++ && !drm_debug_enabled(DRM_UT_KMS))  		return;  	dev_warn(connector->dev->dev, @@ -2092,7 +2192,8 @@ static int standard_timing_level(struct edid *edid)  			return LEVEL_CVT;  		if (drm_gtf2_hbreak(edid))  			return LEVEL_GTF2; -		return LEVEL_GTF; +		if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF) +			return LEVEL_GTF;  	}  	return LEVEL_DMT;  } @@ -3108,18 +3209,10 @@ static bool drm_valid_cea_vic(u8 vic)  	return vic > 0 && vic < ARRAY_SIZE(edid_cea_modes);  } -/** - * drm_get_cea_aspect_ratio - get the picture aspect ratio corresponding to - * the input VIC from the CEA mode list - * @video_code: ID given to each of the CEA modes - * - * Returns picture aspect ratio - */ -enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code) +static enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code)  {  	return edid_cea_modes[video_code].picture_aspect_ratio;  } -EXPORT_SYMBOL(drm_get_cea_aspect_ratio);  /*   * Calculate the alternate clock for HDMI modes (those from the HDMI vendor @@ -3722,7 +3815,7 @@ cea_db_offsets(const u8 *cea, int *start, int *end)  		if (*end < 4 || *end > 127)  			return -ERANGE;  	} else { -		return -ENOTSUPP; +		return -EOPNOTSUPP;  	}  	return 0; @@ -4191,7 +4284,7 @@ int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads)  	if (cea_revision(cea) < 3) {  		DRM_DEBUG_KMS("SAD: wrong CEA revision\n"); -		return -ENOTSUPP; +		return -EOPNOTSUPP;  	}  	if (cea_db_offsets(cea, &start, &end)) { @@ -4252,7 +4345,7 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb)  	if (cea_revision(cea) < 3) {  		DRM_DEBUG_KMS("SAD: wrong CEA revision\n"); -		return -ENOTSUPP; +		return -EOPNOTSUPP;  	}  	if (cea_db_offsets(cea, &start, &end)) { @@ -5071,6 +5164,49 @@ drm_hdmi_infoframe_set_hdr_metadata(struct hdmi_drm_infoframe *frame,  }  EXPORT_SYMBOL(drm_hdmi_infoframe_set_hdr_metadata); +static u8 drm_mode_hdmi_vic(struct drm_connector *connector, +			    const struct drm_display_mode *mode) +{ +	bool has_hdmi_infoframe = connector ? +		connector->display_info.has_hdmi_infoframe : false; + +	if (!has_hdmi_infoframe) +		return 0; + +	/* No HDMI VIC when signalling 3D video format */ +	if (mode->flags & DRM_MODE_FLAG_3D_MASK) +		return 0; + +	return drm_match_hdmi_mode(mode); +} + +static u8 drm_mode_cea_vic(struct drm_connector *connector, +			   const struct drm_display_mode *mode) +{ +	u8 vic; + +	/* +	 * HDMI spec says if a mode is found in HDMI 1.4b 4K modes +	 * we should send its VIC in vendor infoframes, else send the +	 * VIC in AVI infoframes. Lets check if this mode is present in +	 * HDMI 1.4b 4K modes +	 */ +	if (drm_mode_hdmi_vic(connector, mode)) +		return 0; + +	vic = drm_match_cea_mode(mode); + +	/* +	 * HDMI 1.4 VIC range: 1 <= VIC <= 64 (CEA-861-D) but +	 * HDMI 2.0 VIC range: 1 <= VIC <= 107 (CEA-861-F). So we +	 * have to make sure we dont break HDMI 1.4 sinks. +	 */ +	if (!is_hdmi2_sink(connector) && vic > 64) +		return 0; + +	return vic; +} +  /**   * drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with   *                                              data from a DRM display mode @@ -5098,29 +5234,7 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,  	if (mode->flags & DRM_MODE_FLAG_DBLCLK)  		frame->pixel_repeat = 1; -	frame->video_code = drm_match_cea_mode(mode); - -	/* -	 * HDMI 1.4 VIC range: 1 <= VIC <= 64 (CEA-861-D) but -	 * HDMI 2.0 VIC range: 1 <= VIC <= 107 (CEA-861-F). So we -	 * have to make sure we dont break HDMI 1.4 sinks. -	 */ -	if (!is_hdmi2_sink(connector) && frame->video_code > 64) -		frame->video_code = 0; - -	/* -	 * HDMI spec says if a mode is found in HDMI 1.4b 4K modes -	 * we should send its VIC in vendor infoframes, else send the -	 * VIC in AVI infoframes. Lets check if this mode is present in -	 * HDMI 1.4b 4K modes -	 */ -	if (frame->video_code) { -		u8 vendor_if_vic = drm_match_hdmi_mode(mode); -		bool is_s3d = mode->flags & DRM_MODE_FLAG_3D_MASK; - -		if (drm_valid_hdmi_vic(vendor_if_vic) && !is_s3d) -			frame->video_code = 0; -	} +	frame->video_code = drm_mode_cea_vic(connector, mode);  	frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE; @@ -5285,6 +5399,23 @@ drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,  }  EXPORT_SYMBOL(drm_hdmi_avi_infoframe_quant_range); +/** + * drm_hdmi_avi_infoframe_bars() - fill the HDMI AVI infoframe + *                                 bar information + * @frame: HDMI AVI infoframe + * @conn_state: connector state + */ +void +drm_hdmi_avi_infoframe_bars(struct hdmi_avi_infoframe *frame, +			    const struct drm_connector_state *conn_state) +{ +	frame->right_bar = conn_state->tv.margins.right; +	frame->left_bar = conn_state->tv.margins.left; +	frame->top_bar = conn_state->tv.margins.top; +	frame->bottom_bar = conn_state->tv.margins.bottom; +} +EXPORT_SYMBOL(drm_hdmi_avi_infoframe_bars); +  static enum hdmi_3d_structure  s3d_structure_from_display_mode(const struct drm_display_mode *mode)  { @@ -5337,8 +5468,6 @@ drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,  	bool has_hdmi_infoframe = connector ?  		connector->display_info.has_hdmi_infoframe : false;  	int err; -	u32 s3d_flags; -	u8 vic;  	if (!frame || !mode)  		return -EINVAL; @@ -5346,8 +5475,9 @@ drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,  	if (!has_hdmi_infoframe)  		return -EINVAL; -	vic = drm_match_hdmi_mode(mode); -	s3d_flags = mode->flags & DRM_MODE_FLAG_3D_MASK; +	err = hdmi_vendor_infoframe_init(frame); +	if (err < 0) +		return err;  	/*  	 * Even if it's not absolutely necessary to send the infoframe @@ -5358,15 +5488,7 @@ drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,  	 * mode if the source simply stops sending the infoframe when  	 * it wants to switch from 3D to 2D.  	 */ - -	if (vic && s3d_flags) -		return -EINVAL; - -	err = hdmi_vendor_infoframe_init(frame); -	if (err < 0) -		return err; - -	frame->vic = vic; +	frame->vic = drm_mode_hdmi_vic(connector, mode);  	frame->s3d_struct = s3d_structure_from_display_mode(mode);  	return 0;  |