Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 55bc60db authored by Ville Syrjälä's avatar Ville Syrjälä Committed by Daniel Vetter
Browse files

drm/i915: Add "Automatic" mode for the "Broadcast RGB" property



Add a new "Automatic" mode to the "Broadcast RGB" range property.
When selected the driver automagically selects between full range and
limited range output.

Based on CEA-861 [1] guidelines, limited range output is selected if the
mode is a CEA mode, except 640x480. Otherwise full range output is used.
Additionally DVI monitors should most likely default to full range
always.

As per DP1.2a [2] DisplayPort should always use full range for 18bpp, and
otherwise will follow CEA-861 rules.

NOTE: The default value for the property will now be "Automatic"
so some people may be affected in case they're relying on the
current full range default.

[1] CEA-861-E - 5.1 Default Encoding Parameters
[2] VESA DisplayPort Ver.1.2a - 5.1.1.1 Video Colorimetry

v2: Use has_hdmi_sink to check if a HDMI monitor is present
v3: Add information about relevant spec chapters

Reviewed-by: default avatarPaulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 3685a8f3
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1811,5 +1811,9 @@ __i915_write(64, q)
#define POSTING_READ(reg)	(void)I915_READ_NOTRACE(reg)
#define POSTING_READ16(reg)	(void)I915_READ16_NOTRACE(reg)

/* "Broadcast RGB" property */
#define INTEL_BROADCAST_RGB_AUTO 0
#define INTEL_BROADCAST_RGB_FULL 1
#define INTEL_BROADCAST_RGB_LIMITED 2

#endif
+28 −4
Original line number Diff line number Diff line
@@ -764,6 +764,18 @@ intel_dp_mode_fixup(struct drm_encoder *encoder,

	bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;

	if (intel_dp->color_range_auto) {
		/*
		 * See:
		 * CEA-861-E - 5.1 Default Encoding Parameters
		 * VESA DisplayPort Ver.1.2a - 5.1.1.1 Video Colorimetry
		 */
		if (bpp != 18 && drm_mode_cea_vic(adjusted_mode) > 1)
			intel_dp->color_range = DP_COLOR_RANGE_16_235;
		else
			intel_dp->color_range = 0;
	}

	if (intel_dp->color_range)
		adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE;

@@ -2462,10 +2474,21 @@ intel_dp_set_property(struct drm_connector *connector,
	}

	if (property == dev_priv->broadcast_rgb_property) {
		if (val == !!intel_dp->color_range)
			return 0;

		intel_dp->color_range = val ? DP_COLOR_RANGE_16_235 : 0;
		switch (val) {
		case INTEL_BROADCAST_RGB_AUTO:
			intel_dp->color_range_auto = true;
			break;
		case INTEL_BROADCAST_RGB_FULL:
			intel_dp->color_range_auto = false;
			intel_dp->color_range = 0;
			break;
		case INTEL_BROADCAST_RGB_LIMITED:
			intel_dp->color_range_auto = false;
			intel_dp->color_range = DP_COLOR_RANGE_16_235;
			break;
		default:
			return -EINVAL;
		}
		goto done;
	}

@@ -2606,6 +2629,7 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect

	intel_attach_force_audio_property(connector);
	intel_attach_broadcast_rgb_property(connector);
	intel_dp->color_range_auto = true;

	if (is_edp(intel_dp)) {
		drm_mode_create_scaling_mode_property(connector->dev);
+2 −0
Original line number Diff line number Diff line
@@ -343,6 +343,7 @@ struct intel_hdmi {
	u32 sdvox_reg;
	int ddc_bus;
	uint32_t color_range;
	bool color_range_auto;
	bool has_hdmi_sink;
	bool has_audio;
	enum hdmi_force_audio force_audio;
@@ -362,6 +363,7 @@ struct intel_dp {
	bool has_audio;
	enum hdmi_force_audio force_audio;
	uint32_t color_range;
	bool color_range_auto;
	uint8_t link_bw;
	uint8_t lane_count;
	uint8_t dpcd[DP_RECEIVER_CAP_SIZE];
+25 −4
Original line number Diff line number Diff line
@@ -768,6 +768,15 @@ bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
{
	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);

	if (intel_hdmi->color_range_auto) {
		/* See CEA-861-E - 5.1 Default Encoding Parameters */
		if (intel_hdmi->has_hdmi_sink &&
		    drm_mode_cea_vic(adjusted_mode) > 1)
			intel_hdmi->color_range = SDVO_COLOR_RANGE_16_235;
		else
			intel_hdmi->color_range = 0;
	}

	if (intel_hdmi->color_range)
		adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE;

@@ -912,10 +921,21 @@ intel_hdmi_set_property(struct drm_connector *connector,
	}

	if (property == dev_priv->broadcast_rgb_property) {
		if (val == !!intel_hdmi->color_range)
			return 0;

		intel_hdmi->color_range = val ? SDVO_COLOR_RANGE_16_235 : 0;
		switch (val) {
		case INTEL_BROADCAST_RGB_AUTO:
			intel_hdmi->color_range_auto = true;
			break;
		case INTEL_BROADCAST_RGB_FULL:
			intel_hdmi->color_range_auto = false;
			intel_hdmi->color_range = 0;
			break;
		case INTEL_BROADCAST_RGB_LIMITED:
			intel_hdmi->color_range_auto = false;
			intel_hdmi->color_range = SDVO_COLOR_RANGE_16_235;
			break;
		default:
			return -EINVAL;
		}
		goto done;
	}

@@ -964,6 +984,7 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *c
{
	intel_attach_force_audio_property(connector);
	intel_attach_broadcast_rgb_property(connector);
	intel_hdmi->color_range_auto = true;
}

void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
+3 −2
Original line number Diff line number Diff line
@@ -100,8 +100,9 @@ intel_attach_force_audio_property(struct drm_connector *connector)
}

static const struct drm_prop_enum_list broadcast_rgb_names[] = {
	{ 0, "Full" },
	{ 1, "Limited 16:235" },
	{ INTEL_BROADCAST_RGB_AUTO, "Automatic" },
	{ INTEL_BROADCAST_RGB_FULL, "Full" },
	{ INTEL_BROADCAST_RGB_LIMITED, "Limited 16:235" },
};

void
Loading