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: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
3685a8f38f
commit
55bc60db59
@ -1811,5 +1811,9 @@ __i915_write(64, q)
|
|||||||
#define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg)
|
#define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg)
|
||||||
#define POSTING_READ16(reg) (void)I915_READ16_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
|
#endif
|
||||||
|
@ -764,6 +764,18 @@ intel_dp_mode_fixup(struct drm_encoder *encoder,
|
|||||||
|
|
||||||
bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
|
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)
|
if (intel_dp->color_range)
|
||||||
adjusted_mode->private_flags |= INTEL_MODE_LIMITED_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 (property == dev_priv->broadcast_rgb_property) {
|
||||||
if (val == !!intel_dp->color_range)
|
switch (val) {
|
||||||
return 0;
|
case INTEL_BROADCAST_RGB_AUTO:
|
||||||
|
intel_dp->color_range_auto = true;
|
||||||
intel_dp->color_range = val ? DP_COLOR_RANGE_16_235 : 0;
|
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;
|
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_force_audio_property(connector);
|
||||||
intel_attach_broadcast_rgb_property(connector);
|
intel_attach_broadcast_rgb_property(connector);
|
||||||
|
intel_dp->color_range_auto = true;
|
||||||
|
|
||||||
if (is_edp(intel_dp)) {
|
if (is_edp(intel_dp)) {
|
||||||
drm_mode_create_scaling_mode_property(connector->dev);
|
drm_mode_create_scaling_mode_property(connector->dev);
|
||||||
|
@ -343,6 +343,7 @@ struct intel_hdmi {
|
|||||||
u32 sdvox_reg;
|
u32 sdvox_reg;
|
||||||
int ddc_bus;
|
int ddc_bus;
|
||||||
uint32_t color_range;
|
uint32_t color_range;
|
||||||
|
bool color_range_auto;
|
||||||
bool has_hdmi_sink;
|
bool has_hdmi_sink;
|
||||||
bool has_audio;
|
bool has_audio;
|
||||||
enum hdmi_force_audio force_audio;
|
enum hdmi_force_audio force_audio;
|
||||||
@ -362,6 +363,7 @@ struct intel_dp {
|
|||||||
bool has_audio;
|
bool has_audio;
|
||||||
enum hdmi_force_audio force_audio;
|
enum hdmi_force_audio force_audio;
|
||||||
uint32_t color_range;
|
uint32_t color_range;
|
||||||
|
bool color_range_auto;
|
||||||
uint8_t link_bw;
|
uint8_t link_bw;
|
||||||
uint8_t lane_count;
|
uint8_t lane_count;
|
||||||
uint8_t dpcd[DP_RECEIVER_CAP_SIZE];
|
uint8_t dpcd[DP_RECEIVER_CAP_SIZE];
|
||||||
|
@ -768,6 +768,15 @@ bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
|
|||||||
{
|
{
|
||||||
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(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)
|
if (intel_hdmi->color_range)
|
||||||
adjusted_mode->private_flags |= INTEL_MODE_LIMITED_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 (property == dev_priv->broadcast_rgb_property) {
|
||||||
if (val == !!intel_hdmi->color_range)
|
switch (val) {
|
||||||
return 0;
|
case INTEL_BROADCAST_RGB_AUTO:
|
||||||
|
intel_hdmi->color_range_auto = true;
|
||||||
intel_hdmi->color_range = val ? SDVO_COLOR_RANGE_16_235 : 0;
|
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;
|
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_force_audio_property(connector);
|
||||||
intel_attach_broadcast_rgb_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,
|
void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
|
||||||
|
@ -100,8 +100,9 @@ intel_attach_force_audio_property(struct drm_connector *connector)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct drm_prop_enum_list broadcast_rgb_names[] = {
|
static const struct drm_prop_enum_list broadcast_rgb_names[] = {
|
||||||
{ 0, "Full" },
|
{ INTEL_BROADCAST_RGB_AUTO, "Automatic" },
|
||||||
{ 1, "Limited 16:235" },
|
{ INTEL_BROADCAST_RGB_FULL, "Full" },
|
||||||
|
{ INTEL_BROADCAST_RGB_LIMITED, "Limited 16:235" },
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -103,6 +103,7 @@ struct intel_sdvo {
|
|||||||
* It is only valid when using TMDS encoding and 8 bit per color mode.
|
* It is only valid when using TMDS encoding and 8 bit per color mode.
|
||||||
*/
|
*/
|
||||||
uint32_t color_range;
|
uint32_t color_range;
|
||||||
|
bool color_range_auto;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is set if we're going to treat the device as TV-out.
|
* This is set if we're going to treat the device as TV-out.
|
||||||
@ -1064,6 +1065,15 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
|
|||||||
multiplier = intel_sdvo_get_pixel_multiplier(adjusted_mode);
|
multiplier = intel_sdvo_get_pixel_multiplier(adjusted_mode);
|
||||||
intel_mode_set_pixel_multiplier(adjusted_mode, multiplier);
|
intel_mode_set_pixel_multiplier(adjusted_mode, multiplier);
|
||||||
|
|
||||||
|
if (intel_sdvo->color_range_auto) {
|
||||||
|
/* See CEA-861-E - 5.1 Default Encoding Parameters */
|
||||||
|
if (intel_sdvo->has_hdmi_monitor &&
|
||||||
|
drm_mode_cea_vic(adjusted_mode) > 1)
|
||||||
|
intel_sdvo->color_range = SDVO_COLOR_RANGE_16_235;
|
||||||
|
else
|
||||||
|
intel_sdvo->color_range = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (intel_sdvo->color_range)
|
if (intel_sdvo->color_range)
|
||||||
adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE;
|
adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE;
|
||||||
|
|
||||||
@ -1900,10 +1910,21 @@ intel_sdvo_set_property(struct drm_connector *connector,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (property == dev_priv->broadcast_rgb_property) {
|
if (property == dev_priv->broadcast_rgb_property) {
|
||||||
if (val == !!intel_sdvo->color_range)
|
switch (val) {
|
||||||
return 0;
|
case INTEL_BROADCAST_RGB_AUTO:
|
||||||
|
intel_sdvo->color_range_auto = true;
|
||||||
intel_sdvo->color_range = val ? SDVO_COLOR_RANGE_16_235 : 0;
|
break;
|
||||||
|
case INTEL_BROADCAST_RGB_FULL:
|
||||||
|
intel_sdvo->color_range_auto = false;
|
||||||
|
intel_sdvo->color_range = 0;
|
||||||
|
break;
|
||||||
|
case INTEL_BROADCAST_RGB_LIMITED:
|
||||||
|
intel_sdvo->color_range_auto = false;
|
||||||
|
intel_sdvo->color_range = SDVO_COLOR_RANGE_16_235;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2200,13 +2221,16 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
intel_sdvo_add_hdmi_properties(struct intel_sdvo_connector *connector)
|
intel_sdvo_add_hdmi_properties(struct intel_sdvo *intel_sdvo,
|
||||||
|
struct intel_sdvo_connector *connector)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = connector->base.base.dev;
|
struct drm_device *dev = connector->base.base.dev;
|
||||||
|
|
||||||
intel_attach_force_audio_property(&connector->base.base);
|
intel_attach_force_audio_property(&connector->base.base);
|
||||||
if (INTEL_INFO(dev)->gen >= 4 && IS_MOBILE(dev))
|
if (INTEL_INFO(dev)->gen >= 4 && IS_MOBILE(dev)) {
|
||||||
intel_attach_broadcast_rgb_property(&connector->base.base);
|
intel_attach_broadcast_rgb_property(&connector->base.base);
|
||||||
|
intel_sdvo->color_range_auto = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -2254,7 +2278,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
|
|||||||
|
|
||||||
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
|
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
|
||||||
if (intel_sdvo->is_hdmi)
|
if (intel_sdvo->is_hdmi)
|
||||||
intel_sdvo_add_hdmi_properties(intel_sdvo_connector);
|
intel_sdvo_add_hdmi_properties(intel_sdvo, intel_sdvo_connector);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user