[PATCH 2/4] drm/i915: Add "Automatic" mode for the "Broadcast RGB" property

Paulo Zanoni przanoni at gmail.com
Thu Jan 17 05:41:03 PST 2013


Hi

2013/1/16  <ville.syrjala at linux.intel.com>:
> From: Ville Syrjälä <ville.syrjala at 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 at intel.com>

>
> Signed-off-by: Ville Syrjälä <ville.syrjala at 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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Paulo Zanoni


More information about the dri-devel mailing list