Message ID | 1358356365-23191-3-git-send-email-ville.syrjala@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi 2013/1/16 <ville.syrjala@linux.intel.com>: > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > 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 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 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. > > v2: Use has_hdmi_sink to check if a HDMI monitor is present Looks correct. And let's hope this patches fixes even more "my screen is black" or "my screen has weird colors" bugs. Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > --- > drivers/gpu/drm/i915/i915_drv.h | 4 +++ > drivers/gpu/drm/i915/intel_dp.c | 28 ++++++++++++++++++++++--- > drivers/gpu/drm/i915/intel_drv.h | 2 + > drivers/gpu/drm/i915/intel_hdmi.c | 29 +++++++++++++++++++++++--- > drivers/gpu/drm/i915/intel_modes.c | 5 ++- > drivers/gpu/drm/i915/intel_sdvo.c | 38 +++++++++++++++++++++++++++++------ > 6 files changed, 89 insertions(+), 17 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index d0f051b..449bbe0 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -1803,5 +1803,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 > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > index 64824d0..633a4db 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -764,6 +764,14 @@ 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) { > + /* as per DP1.2a and CEA-861 */ > + 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 +2470,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 +2625,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); > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index 4df47be..1a698c6 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -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]; > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c > index f194d75..58b072e 100644 > --- a/drivers/gpu/drm/i915/intel_hdmi.c > +++ b/drivers/gpu/drm/i915/intel_hdmi.c > @@ -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) { > + /* as per CEA-861 */ > + 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, > diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c > index 49249bb..0e860f3 100644 > --- a/drivers/gpu/drm/i915/intel_modes.c > +++ b/drivers/gpu/drm/i915/intel_modes.c > @@ -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 > diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c > index 3b8491a..b422109 100644 > --- a/drivers/gpu/drm/i915/intel_sdvo.c > +++ b/drivers/gpu/drm/i915/intel_sdvo.c > @@ -103,6 +103,7 @@ struct intel_sdvo { > * It is only valid when using TMDS encoding and 8 bit per color mode. > */ > uint32_t color_range; > + bool color_range_auto; > > /** > * 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); > intel_mode_set_pixel_multiplier(adjusted_mode, multiplier); > > + if (intel_sdvo->color_range_auto) { > + /* as per CEA-861 */ > + 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) > 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 (val == !!intel_sdvo->color_range) > - return 0; > - > - intel_sdvo->color_range = val ? SDVO_COLOR_RANGE_16_235 : 0; > + switch (val) { > + case INTEL_BROADCAST_RGB_AUTO: > + intel_sdvo->color_range_auto = true; > + 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; > } > > @@ -2200,13 +2221,16 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector, > } > > 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; > > 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_sdvo->color_range_auto = true; > + } > } > > 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); > 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; > } > -- > 1.7.8.6 > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d0f051b..449bbe0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1803,5 +1803,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 diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 64824d0..633a4db 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -764,6 +764,14 @@ 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) { + /* as per DP1.2a and CEA-861 */ + 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 +2470,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 +2625,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); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 4df47be..1a698c6 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -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]; diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index f194d75..58b072e 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -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) { + /* as per CEA-861 */ + 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, diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index 49249bb..0e860f3 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c @@ -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 diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 3b8491a..b422109 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -103,6 +103,7 @@ struct intel_sdvo { * It is only valid when using TMDS encoding and 8 bit per color mode. */ uint32_t color_range; + bool color_range_auto; /** * 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); intel_mode_set_pixel_multiplier(adjusted_mode, multiplier); + if (intel_sdvo->color_range_auto) { + /* as per CEA-861 */ + 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) 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 (val == !!intel_sdvo->color_range) - return 0; - - intel_sdvo->color_range = val ? SDVO_COLOR_RANGE_16_235 : 0; + switch (val) { + case INTEL_BROADCAST_RGB_AUTO: + intel_sdvo->color_range_auto = true; + 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; } @@ -2200,13 +2221,16 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector, } 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; 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_sdvo->color_range_auto = true; + } } 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); 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; }