Message ID | 1368576511-10675-2-git-send-email-jbarnes@virtuousgeek.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
2013/5/14 Jesse Barnes <jbarnes@virtuousgeek.org>: > We can use this for fetching encoder specific pipe_config state, like > mode flags, adjusted clock, etc. > > Just used for mode flags atm, so we can check the pipe config state at > mode set time. > > v2: get_config when checking hw state too > v3: fix DVO and LVDS mode flags (Ville) > get SDVO DTD for flag fetch (Ville) > v4: use input timings (Ville) > correct command used (Ville) > remove gen4 check (Ville) > v5: get DDI flag config too > > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> > Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> I applied this on my Haswell machine and booted it with both eDP-only and eDP+DP and now I don't see those error messages anymore. > --- > drivers/gpu/drm/i915/intel_crt.c | 23 +++++++++++++++++++ > drivers/gpu/drm/i915/intel_ddi.c | 23 +++++++++++++++++++ > drivers/gpu/drm/i915/intel_display.c | 20 +++++++++++++--- > drivers/gpu/drm/i915/intel_dp.c | 23 +++++++++++++++++++ > drivers/gpu/drm/i915/intel_drv.h | 4 ++++ > drivers/gpu/drm/i915/intel_dvo.c | 21 +++++++++++++++++ > drivers/gpu/drm/i915/intel_hdmi.c | 23 +++++++++++++++++++ > drivers/gpu/drm/i915/intel_lvds.c | 26 +++++++++++++++++++++ > drivers/gpu/drm/i915/intel_sdvo.c | 42 ++++++++++++++++++++++++++++++++++ > 9 files changed, 202 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c > index cc414f1..789c4ef 100644 > --- a/drivers/gpu/drm/i915/intel_crt.c > +++ b/drivers/gpu/drm/i915/intel_crt.c > @@ -81,6 +81,28 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder, > return true; > } > > +static void intel_crt_get_config(struct intel_encoder *encoder, > + struct intel_crtc_config *pipe_config) > +{ > + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; > + struct intel_crt *crt = intel_encoder_to_crt(encoder); > + u32 tmp, flags = 0; > + > + tmp = I915_READ(crt->adpa_reg); > + > + if (tmp & ADPA_HSYNC_ACTIVE_HIGH) > + flags |= DRM_MODE_FLAG_PHSYNC; > + else > + flags |= DRM_MODE_FLAG_NHSYNC; > + > + if (tmp & ADPA_VSYNC_ACTIVE_HIGH) > + flags |= DRM_MODE_FLAG_PVSYNC; > + else > + flags |= DRM_MODE_FLAG_NVSYNC; > + > + pipe_config->adjusted_mode.flags |= flags; > +} > + > static void intel_disable_crt(struct intel_encoder *encoder) > { > struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; > @@ -784,6 +806,7 @@ void intel_crt_init(struct drm_device *dev) > crt->base.compute_config = intel_crt_compute_config; > crt->base.disable = intel_disable_crt; > crt->base.enable = intel_enable_crt; > + crt->base.get_config = intel_crt_get_config; > if (I915_HAS_HOTPLUG(dev)) > crt->base.hpd_pin = HPD_CRT; > if (HAS_DDI(dev)) > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c > index cddcf4a..27a74a9 100644 > --- a/drivers/gpu/drm/i915/intel_ddi.c > +++ b/drivers/gpu/drm/i915/intel_ddi.c > @@ -1254,6 +1254,28 @@ static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder) > intel_dp_check_link_status(intel_dp); > } > > +static void intel_ddi_get_config(struct intel_encoder *encoder, > + struct intel_crtc_config *pipe_config) > +{ > + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; > + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); > + enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; > + u32 temp, flags = 0; > + > + temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); > + if (temp & TRANS_DDI_PHSYNC) > + flags |= DRM_MODE_FLAG_PHSYNC; > + else > + flags |= DRM_MODE_FLAG_NHSYNC; > + if (temp & TRANS_DDI_PVSYNC) > + flags |= DRM_MODE_FLAG_PVSYNC; > + else > + flags |= DRM_MODE_FLAG_NVSYNC; > + > + pipe_config->adjusted_mode.flags |= flags; > + pipe_config->pixel_multiplier = 1; > +} > + > static void intel_ddi_destroy(struct drm_encoder *encoder) > { > /* HDMI has nothing special to destroy, so we can go with this. */ > @@ -1313,6 +1335,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port) > intel_encoder->disable = intel_disable_ddi; > intel_encoder->post_disable = intel_ddi_post_disable; > intel_encoder->get_hw_state = intel_ddi_get_hw_state; > + intel_encoder->get_config = intel_ddi_get_config; > > intel_dig_port->port = port; > intel_dig_port->port_reversal = I915_READ(DDI_BUF_CTL(port)) & > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > index 7358e4e..163b97e 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -8057,6 +8057,15 @@ intel_pipe_config_compare(struct drm_device *dev, > PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, > DRM_MODE_FLAG_INTERLACE); > > + PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, > + DRM_MODE_FLAG_PHSYNC); > + PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, > + DRM_MODE_FLAG_NHSYNC); > + PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, > + DRM_MODE_FLAG_PVSYNC); > + PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, > + DRM_MODE_FLAG_NVSYNC); > + > PIPE_CONF_CHECK_I(requested_mode.hdisplay); > PIPE_CONF_CHECK_I(requested_mode.vdisplay); > > @@ -8149,6 +8158,8 @@ intel_modeset_check_state(struct drm_device *dev) > bool enabled = false; > bool active = false; > > + memset(&pipe_config, 0, sizeof(pipe_config)); > + > DRM_DEBUG_KMS("[CRTC:%d]\n", > crtc->base.base.id); > > @@ -8162,6 +8173,8 @@ intel_modeset_check_state(struct drm_device *dev) > enabled = true; > if (encoder->connectors_active) > active = true; > + if (encoder->get_config) > + encoder->get_config(encoder, &pipe_config); > } > WARN(active != crtc->active, > "crtc's computed active state doesn't match tracked active state " > @@ -8170,7 +8183,6 @@ intel_modeset_check_state(struct drm_device *dev) > "crtc's computed enabled state doesn't match tracked enabled state " > "(expected %i, found %i)\n", enabled, crtc->base.enabled); > > - memset(&pipe_config, 0, sizeof(pipe_config)); > pipe_config.cpu_transcoder = crtc->config.cpu_transcoder; > active = dev_priv->display.get_pipe_config(crtc, > &pipe_config); > @@ -9579,8 +9591,10 @@ setup_pipes: > pipe = 0; > > if (encoder->get_hw_state(encoder, &pipe)) { > - encoder->base.crtc = > - dev_priv->pipe_to_crtc_mapping[pipe]; > + crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); > + encoder->base.crtc = &crtc->base; > + if (encoder->get_config) > + encoder->get_config(encoder, &crtc->config); > } else { > encoder->base.crtc = NULL; > } > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > index 2bb4009..a423256 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -1356,6 +1356,28 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder, > return true; > } > > +static void intel_dp_get_config(struct intel_encoder *encoder, > + struct intel_crtc_config *pipe_config) > +{ > + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); > + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; > + u32 tmp, flags = 0; > + > + tmp = I915_READ(intel_dp->output_reg); > + > + if (tmp & DP_SYNC_HS_HIGH) > + flags |= DRM_MODE_FLAG_PHSYNC; > + else > + flags |= DRM_MODE_FLAG_NHSYNC; > + > + if (tmp & DP_SYNC_VS_HIGH) > + flags |= DRM_MODE_FLAG_PVSYNC; > + else > + flags |= DRM_MODE_FLAG_NVSYNC; > + > + pipe_config->adjusted_mode.flags |= flags; > +} > + > static void intel_disable_dp(struct intel_encoder *encoder) > { > struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); > @@ -3154,6 +3176,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) > intel_encoder->disable = intel_disable_dp; > intel_encoder->post_disable = intel_post_disable_dp; > intel_encoder->get_hw_state = intel_dp_get_hw_state; > + intel_encoder->get_config = intel_dp_get_config; > if (IS_VALLEYVIEW(dev)) > intel_encoder->pre_pll_enable = intel_dp_pre_pll_enable; > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index 0f35545..4802483 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -139,6 +139,10 @@ struct intel_encoder { > * the encoder is active. If the encoder is enabled it also set the pipe > * it is connected to in the pipe parameter. */ > bool (*get_hw_state)(struct intel_encoder *, enum pipe *pipe); > + /* Reconstructs the equivalent mode flags for the current hardware > + * state. */ > + void (*get_config)(struct intel_encoder *, > + struct intel_crtc_config *pipe_config); > int crtc_mask; > enum hpd_pin hpd_pin; > }; > diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c > index 00e70db..91e9905 100644 > --- a/drivers/gpu/drm/i915/intel_dvo.c > +++ b/drivers/gpu/drm/i915/intel_dvo.c > @@ -129,6 +129,26 @@ static bool intel_dvo_get_hw_state(struct intel_encoder *encoder, > return true; > } > > +static void intel_dvo_get_config(struct intel_encoder *encoder, > + struct intel_crtc_config *pipe_config) > +{ > + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; > + struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base); > + u32 tmp, flags = 0; > + > + tmp = I915_READ(intel_dvo->dev.dvo_reg); > + if (tmp & DVO_HSYNC_ACTIVE_HIGH) > + flags |= DRM_MODE_FLAG_PHSYNC; > + else > + flags |= DRM_MODE_FLAG_NHSYNC; > + if (tmp & DVO_VSYNC_ACTIVE_HIGH) > + flags |= DRM_MODE_FLAG_PVSYNC; > + else > + flags |= DRM_MODE_FLAG_NVSYNC; > + > + pipe_config->adjusted_mode.flags |= flags; > +} > + > static void intel_disable_dvo(struct intel_encoder *encoder) > { > struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; > @@ -440,6 +460,7 @@ void intel_dvo_init(struct drm_device *dev) > intel_encoder->disable = intel_disable_dvo; > intel_encoder->enable = intel_enable_dvo; > intel_encoder->get_hw_state = intel_dvo_get_hw_state; > + intel_encoder->get_config = intel_dvo_get_config; > intel_connector->get_hw_state = intel_dvo_connector_get_hw_state; > > /* Now, try to find a controller */ > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c > index 93de5ff..9091655 100644 > --- a/drivers/gpu/drm/i915/intel_hdmi.c > +++ b/drivers/gpu/drm/i915/intel_hdmi.c > @@ -658,6 +658,28 @@ static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder, > return true; > } > > +static void intel_hdmi_get_config(struct intel_encoder *encoder, > + struct intel_crtc_config *pipe_config) > +{ > + struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); > + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; > + u32 tmp, flags = 0; > + > + tmp = I915_READ(intel_hdmi->hdmi_reg); > + > + if (tmp & SDVO_HSYNC_ACTIVE_HIGH) > + flags |= DRM_MODE_FLAG_PHSYNC; > + else > + flags |= DRM_MODE_FLAG_NHSYNC; > + > + if (tmp & SDVO_VSYNC_ACTIVE_HIGH) > + flags |= DRM_MODE_FLAG_PVSYNC; > + else > + flags |= DRM_MODE_FLAG_NVSYNC; > + > + pipe_config->adjusted_mode.flags |= flags; > +} > + > static void intel_enable_hdmi(struct intel_encoder *encoder) > { > struct drm_device *dev = encoder->base.dev; > @@ -1208,6 +1230,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port) > intel_encoder->enable = intel_enable_hdmi; > intel_encoder->disable = intel_disable_hdmi; > intel_encoder->get_hw_state = intel_hdmi_get_hw_state; > + intel_encoder->get_config = intel_hdmi_get_config; > if (IS_VALLEYVIEW(dev)) { > intel_encoder->pre_enable = intel_hdmi_pre_enable; > intel_encoder->pre_pll_enable = intel_hdmi_pre_pll_enable; > diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c > index 36fe291..6554860 100644 > --- a/drivers/gpu/drm/i915/intel_lvds.c > +++ b/drivers/gpu/drm/i915/intel_lvds.c > @@ -86,6 +86,31 @@ static bool intel_lvds_get_hw_state(struct intel_encoder *encoder, > return true; > } > > +static void intel_lvds_get_config(struct intel_encoder *encoder, > + struct intel_crtc_config *pipe_config) > +{ > + struct drm_device *dev = encoder->base.dev; > + struct drm_i915_private *dev_priv = dev->dev_private; > + u32 lvds_reg, tmp, flags = 0; > + > + if (HAS_PCH_SPLIT(dev)) > + lvds_reg = PCH_LVDS; > + else > + lvds_reg = LVDS; > + > + tmp = I915_READ(lvds_reg); > + if (tmp & LVDS_HSYNC_POLARITY) > + flags |= DRM_MODE_FLAG_NHSYNC; > + else > + flags |= DRM_MODE_FLAG_PHSYNC; > + if (tmp & LVDS_VSYNC_POLARITY) > + flags |= DRM_MODE_FLAG_NVSYNC; > + else > + flags |= DRM_MODE_FLAG_PVSYNC; > + > + pipe_config->adjusted_mode.flags |= flags; > +} > + > /* The LVDS pin pair needs to be on before the DPLLs are enabled. > * This is an exception to the general rule that mode_set doesn't turn > * things on. > @@ -921,6 +946,7 @@ bool intel_lvds_init(struct drm_device *dev) > intel_encoder->compute_config = intel_lvds_compute_config; > intel_encoder->disable = intel_disable_lvds; > intel_encoder->get_hw_state = intel_lvds_get_hw_state; > + intel_encoder->get_config = intel_lvds_get_config; > intel_connector->get_hw_state = intel_connector_get_hw_state; > > intel_connector_attach_encoder(intel_connector, intel_encoder); > diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c > index 2f54dc3..416d23c 100644 > --- a/drivers/gpu/drm/i915/intel_sdvo.c > +++ b/drivers/gpu/drm/i915/intel_sdvo.c > @@ -712,6 +712,13 @@ static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd, > intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); > } > > +static bool intel_sdvo_get_timing(struct intel_sdvo *intel_sdvo, u8 cmd, > + struct intel_sdvo_dtd *dtd) > +{ > + return intel_sdvo_get_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) && > + intel_sdvo_get_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); > +} > + > static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo, > struct intel_sdvo_dtd *dtd) > { > @@ -726,6 +733,13 @@ static bool intel_sdvo_set_output_timing(struct intel_sdvo *intel_sdvo, > SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); > } > > +static bool intel_sdvo_get_input_timing(struct intel_sdvo *intel_sdvo, > + struct intel_sdvo_dtd *dtd) > +{ > + return intel_sdvo_get_timing(intel_sdvo, > + SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd); > +} > + > static bool > intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo, > uint16_t clock, > @@ -1295,6 +1309,33 @@ static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder, > return true; > } > > +static void intel_sdvo_get_config(struct intel_encoder *encoder, > + struct intel_crtc_config *pipe_config) > +{ > + struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); > + struct intel_sdvo_dtd dtd; > + u32 flags = 0; > + bool ret; > + > + ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd); > + if (!ret) { > + DRM_DEBUG_DRIVER("failed to retrieve SDVO DTD\n"); > + return; > + } > + > + if (dtd.part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE) > + flags |= DRM_MODE_FLAG_PHSYNC; > + else > + flags |= DRM_MODE_FLAG_NHSYNC; > + > + if (dtd.part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE) > + flags |= DRM_MODE_FLAG_PVSYNC; > + else > + flags |= DRM_MODE_FLAG_NVSYNC; > + > + pipe_config->adjusted_mode.flags |= flags; > +} > + > static void intel_disable_sdvo(struct intel_encoder *encoder) > { > struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; > @@ -2819,6 +2860,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) > intel_encoder->mode_set = intel_sdvo_mode_set; > intel_encoder->enable = intel_enable_sdvo; > intel_encoder->get_hw_state = intel_sdvo_get_hw_state; > + intel_encoder->get_config = intel_sdvo_get_config; > > /* In default case sdvo lvds is false */ > if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) > -- > 1.7.9.5 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
On Wed, May 15, 2013 at 06:45:35PM -0300, Paulo Zanoni wrote: > 2013/5/14 Jesse Barnes <jbarnes@virtuousgeek.org>: > > We can use this for fetching encoder specific pipe_config state, like > > mode flags, adjusted clock, etc. > > > > Just used for mode flags atm, so we can check the pipe config state at > > mode set time. > > > > v2: get_config when checking hw state too > > v3: fix DVO and LVDS mode flags (Ville) > > get SDVO DTD for flag fetch (Ville) > > v4: use input timings (Ville) > > correct command used (Ville) > > remove gen4 check (Ville) > > v5: get DDI flag config too > > > > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> > > Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > > Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> > > I applied this on my Haswell machine and booted it with both eDP-only > and eDP+DP and now I don't see those error messages anymore. Queued for -next, thanks for the patch. -Daniel > > > > --- > > drivers/gpu/drm/i915/intel_crt.c | 23 +++++++++++++++++++ > > drivers/gpu/drm/i915/intel_ddi.c | 23 +++++++++++++++++++ > > drivers/gpu/drm/i915/intel_display.c | 20 +++++++++++++--- > > drivers/gpu/drm/i915/intel_dp.c | 23 +++++++++++++++++++ > > drivers/gpu/drm/i915/intel_drv.h | 4 ++++ > > drivers/gpu/drm/i915/intel_dvo.c | 21 +++++++++++++++++ > > drivers/gpu/drm/i915/intel_hdmi.c | 23 +++++++++++++++++++ > > drivers/gpu/drm/i915/intel_lvds.c | 26 +++++++++++++++++++++ > > drivers/gpu/drm/i915/intel_sdvo.c | 42 ++++++++++++++++++++++++++++++++++ > > 9 files changed, 202 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c > > index cc414f1..789c4ef 100644 > > --- a/drivers/gpu/drm/i915/intel_crt.c > > +++ b/drivers/gpu/drm/i915/intel_crt.c > > @@ -81,6 +81,28 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder, > > return true; > > } > > > > +static void intel_crt_get_config(struct intel_encoder *encoder, > > + struct intel_crtc_config *pipe_config) > > +{ > > + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; > > + struct intel_crt *crt = intel_encoder_to_crt(encoder); > > + u32 tmp, flags = 0; > > + > > + tmp = I915_READ(crt->adpa_reg); > > + > > + if (tmp & ADPA_HSYNC_ACTIVE_HIGH) > > + flags |= DRM_MODE_FLAG_PHSYNC; > > + else > > + flags |= DRM_MODE_FLAG_NHSYNC; > > + > > + if (tmp & ADPA_VSYNC_ACTIVE_HIGH) > > + flags |= DRM_MODE_FLAG_PVSYNC; > > + else > > + flags |= DRM_MODE_FLAG_NVSYNC; > > + > > + pipe_config->adjusted_mode.flags |= flags; > > +} > > + > > static void intel_disable_crt(struct intel_encoder *encoder) > > { > > struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; > > @@ -784,6 +806,7 @@ void intel_crt_init(struct drm_device *dev) > > crt->base.compute_config = intel_crt_compute_config; > > crt->base.disable = intel_disable_crt; > > crt->base.enable = intel_enable_crt; > > + crt->base.get_config = intel_crt_get_config; > > if (I915_HAS_HOTPLUG(dev)) > > crt->base.hpd_pin = HPD_CRT; > > if (HAS_DDI(dev)) > > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c > > index cddcf4a..27a74a9 100644 > > --- a/drivers/gpu/drm/i915/intel_ddi.c > > +++ b/drivers/gpu/drm/i915/intel_ddi.c > > @@ -1254,6 +1254,28 @@ static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder) > > intel_dp_check_link_status(intel_dp); > > } > > > > +static void intel_ddi_get_config(struct intel_encoder *encoder, > > + struct intel_crtc_config *pipe_config) > > +{ > > + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; > > + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); > > + enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; > > + u32 temp, flags = 0; > > + > > + temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); > > + if (temp & TRANS_DDI_PHSYNC) > > + flags |= DRM_MODE_FLAG_PHSYNC; > > + else > > + flags |= DRM_MODE_FLAG_NHSYNC; > > + if (temp & TRANS_DDI_PVSYNC) > > + flags |= DRM_MODE_FLAG_PVSYNC; > > + else > > + flags |= DRM_MODE_FLAG_NVSYNC; > > + > > + pipe_config->adjusted_mode.flags |= flags; > > + pipe_config->pixel_multiplier = 1; > > +} > > + > > static void intel_ddi_destroy(struct drm_encoder *encoder) > > { > > /* HDMI has nothing special to destroy, so we can go with this. */ > > @@ -1313,6 +1335,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port) > > intel_encoder->disable = intel_disable_ddi; > > intel_encoder->post_disable = intel_ddi_post_disable; > > intel_encoder->get_hw_state = intel_ddi_get_hw_state; > > + intel_encoder->get_config = intel_ddi_get_config; > > > > intel_dig_port->port = port; > > intel_dig_port->port_reversal = I915_READ(DDI_BUF_CTL(port)) & > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > > index 7358e4e..163b97e 100644 > > --- a/drivers/gpu/drm/i915/intel_display.c > > +++ b/drivers/gpu/drm/i915/intel_display.c > > @@ -8057,6 +8057,15 @@ intel_pipe_config_compare(struct drm_device *dev, > > PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, > > DRM_MODE_FLAG_INTERLACE); > > > > + PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, > > + DRM_MODE_FLAG_PHSYNC); > > + PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, > > + DRM_MODE_FLAG_NHSYNC); > > + PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, > > + DRM_MODE_FLAG_PVSYNC); > > + PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, > > + DRM_MODE_FLAG_NVSYNC); > > + > > PIPE_CONF_CHECK_I(requested_mode.hdisplay); > > PIPE_CONF_CHECK_I(requested_mode.vdisplay); > > > > @@ -8149,6 +8158,8 @@ intel_modeset_check_state(struct drm_device *dev) > > bool enabled = false; > > bool active = false; > > > > + memset(&pipe_config, 0, sizeof(pipe_config)); > > + > > DRM_DEBUG_KMS("[CRTC:%d]\n", > > crtc->base.base.id); > > > > @@ -8162,6 +8173,8 @@ intel_modeset_check_state(struct drm_device *dev) > > enabled = true; > > if (encoder->connectors_active) > > active = true; > > + if (encoder->get_config) > > + encoder->get_config(encoder, &pipe_config); > > } > > WARN(active != crtc->active, > > "crtc's computed active state doesn't match tracked active state " > > @@ -8170,7 +8183,6 @@ intel_modeset_check_state(struct drm_device *dev) > > "crtc's computed enabled state doesn't match tracked enabled state " > > "(expected %i, found %i)\n", enabled, crtc->base.enabled); > > > > - memset(&pipe_config, 0, sizeof(pipe_config)); > > pipe_config.cpu_transcoder = crtc->config.cpu_transcoder; > > active = dev_priv->display.get_pipe_config(crtc, > > &pipe_config); > > @@ -9579,8 +9591,10 @@ setup_pipes: > > pipe = 0; > > > > if (encoder->get_hw_state(encoder, &pipe)) { > > - encoder->base.crtc = > > - dev_priv->pipe_to_crtc_mapping[pipe]; > > + crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); > > + encoder->base.crtc = &crtc->base; > > + if (encoder->get_config) > > + encoder->get_config(encoder, &crtc->config); > > } else { > > encoder->base.crtc = NULL; > > } > > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > > index 2bb4009..a423256 100644 > > --- a/drivers/gpu/drm/i915/intel_dp.c > > +++ b/drivers/gpu/drm/i915/intel_dp.c > > @@ -1356,6 +1356,28 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder, > > return true; > > } > > > > +static void intel_dp_get_config(struct intel_encoder *encoder, > > + struct intel_crtc_config *pipe_config) > > +{ > > + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); > > + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; > > + u32 tmp, flags = 0; > > + > > + tmp = I915_READ(intel_dp->output_reg); > > + > > + if (tmp & DP_SYNC_HS_HIGH) > > + flags |= DRM_MODE_FLAG_PHSYNC; > > + else > > + flags |= DRM_MODE_FLAG_NHSYNC; > > + > > + if (tmp & DP_SYNC_VS_HIGH) > > + flags |= DRM_MODE_FLAG_PVSYNC; > > + else > > + flags |= DRM_MODE_FLAG_NVSYNC; > > + > > + pipe_config->adjusted_mode.flags |= flags; > > +} > > + > > static void intel_disable_dp(struct intel_encoder *encoder) > > { > > struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); > > @@ -3154,6 +3176,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) > > intel_encoder->disable = intel_disable_dp; > > intel_encoder->post_disable = intel_post_disable_dp; > > intel_encoder->get_hw_state = intel_dp_get_hw_state; > > + intel_encoder->get_config = intel_dp_get_config; > > if (IS_VALLEYVIEW(dev)) > > intel_encoder->pre_pll_enable = intel_dp_pre_pll_enable; > > > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > > index 0f35545..4802483 100644 > > --- a/drivers/gpu/drm/i915/intel_drv.h > > +++ b/drivers/gpu/drm/i915/intel_drv.h > > @@ -139,6 +139,10 @@ struct intel_encoder { > > * the encoder is active. If the encoder is enabled it also set the pipe > > * it is connected to in the pipe parameter. */ > > bool (*get_hw_state)(struct intel_encoder *, enum pipe *pipe); > > + /* Reconstructs the equivalent mode flags for the current hardware > > + * state. */ > > + void (*get_config)(struct intel_encoder *, > > + struct intel_crtc_config *pipe_config); > > int crtc_mask; > > enum hpd_pin hpd_pin; > > }; > > diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c > > index 00e70db..91e9905 100644 > > --- a/drivers/gpu/drm/i915/intel_dvo.c > > +++ b/drivers/gpu/drm/i915/intel_dvo.c > > @@ -129,6 +129,26 @@ static bool intel_dvo_get_hw_state(struct intel_encoder *encoder, > > return true; > > } > > > > +static void intel_dvo_get_config(struct intel_encoder *encoder, > > + struct intel_crtc_config *pipe_config) > > +{ > > + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; > > + struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base); > > + u32 tmp, flags = 0; > > + > > + tmp = I915_READ(intel_dvo->dev.dvo_reg); > > + if (tmp & DVO_HSYNC_ACTIVE_HIGH) > > + flags |= DRM_MODE_FLAG_PHSYNC; > > + else > > + flags |= DRM_MODE_FLAG_NHSYNC; > > + if (tmp & DVO_VSYNC_ACTIVE_HIGH) > > + flags |= DRM_MODE_FLAG_PVSYNC; > > + else > > + flags |= DRM_MODE_FLAG_NVSYNC; > > + > > + pipe_config->adjusted_mode.flags |= flags; > > +} > > + > > static void intel_disable_dvo(struct intel_encoder *encoder) > > { > > struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; > > @@ -440,6 +460,7 @@ void intel_dvo_init(struct drm_device *dev) > > intel_encoder->disable = intel_disable_dvo; > > intel_encoder->enable = intel_enable_dvo; > > intel_encoder->get_hw_state = intel_dvo_get_hw_state; > > + intel_encoder->get_config = intel_dvo_get_config; > > intel_connector->get_hw_state = intel_dvo_connector_get_hw_state; > > > > /* Now, try to find a controller */ > > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c > > index 93de5ff..9091655 100644 > > --- a/drivers/gpu/drm/i915/intel_hdmi.c > > +++ b/drivers/gpu/drm/i915/intel_hdmi.c > > @@ -658,6 +658,28 @@ static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder, > > return true; > > } > > > > +static void intel_hdmi_get_config(struct intel_encoder *encoder, > > + struct intel_crtc_config *pipe_config) > > +{ > > + struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); > > + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; > > + u32 tmp, flags = 0; > > + > > + tmp = I915_READ(intel_hdmi->hdmi_reg); > > + > > + if (tmp & SDVO_HSYNC_ACTIVE_HIGH) > > + flags |= DRM_MODE_FLAG_PHSYNC; > > + else > > + flags |= DRM_MODE_FLAG_NHSYNC; > > + > > + if (tmp & SDVO_VSYNC_ACTIVE_HIGH) > > + flags |= DRM_MODE_FLAG_PVSYNC; > > + else > > + flags |= DRM_MODE_FLAG_NVSYNC; > > + > > + pipe_config->adjusted_mode.flags |= flags; > > +} > > + > > static void intel_enable_hdmi(struct intel_encoder *encoder) > > { > > struct drm_device *dev = encoder->base.dev; > > @@ -1208,6 +1230,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port) > > intel_encoder->enable = intel_enable_hdmi; > > intel_encoder->disable = intel_disable_hdmi; > > intel_encoder->get_hw_state = intel_hdmi_get_hw_state; > > + intel_encoder->get_config = intel_hdmi_get_config; > > if (IS_VALLEYVIEW(dev)) { > > intel_encoder->pre_enable = intel_hdmi_pre_enable; > > intel_encoder->pre_pll_enable = intel_hdmi_pre_pll_enable; > > diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c > > index 36fe291..6554860 100644 > > --- a/drivers/gpu/drm/i915/intel_lvds.c > > +++ b/drivers/gpu/drm/i915/intel_lvds.c > > @@ -86,6 +86,31 @@ static bool intel_lvds_get_hw_state(struct intel_encoder *encoder, > > return true; > > } > > > > +static void intel_lvds_get_config(struct intel_encoder *encoder, > > + struct intel_crtc_config *pipe_config) > > +{ > > + struct drm_device *dev = encoder->base.dev; > > + struct drm_i915_private *dev_priv = dev->dev_private; > > + u32 lvds_reg, tmp, flags = 0; > > + > > + if (HAS_PCH_SPLIT(dev)) > > + lvds_reg = PCH_LVDS; > > + else > > + lvds_reg = LVDS; > > + > > + tmp = I915_READ(lvds_reg); > > + if (tmp & LVDS_HSYNC_POLARITY) > > + flags |= DRM_MODE_FLAG_NHSYNC; > > + else > > + flags |= DRM_MODE_FLAG_PHSYNC; > > + if (tmp & LVDS_VSYNC_POLARITY) > > + flags |= DRM_MODE_FLAG_NVSYNC; > > + else > > + flags |= DRM_MODE_FLAG_PVSYNC; > > + > > + pipe_config->adjusted_mode.flags |= flags; > > +} > > + > > /* The LVDS pin pair needs to be on before the DPLLs are enabled. > > * This is an exception to the general rule that mode_set doesn't turn > > * things on. > > @@ -921,6 +946,7 @@ bool intel_lvds_init(struct drm_device *dev) > > intel_encoder->compute_config = intel_lvds_compute_config; > > intel_encoder->disable = intel_disable_lvds; > > intel_encoder->get_hw_state = intel_lvds_get_hw_state; > > + intel_encoder->get_config = intel_lvds_get_config; > > intel_connector->get_hw_state = intel_connector_get_hw_state; > > > > intel_connector_attach_encoder(intel_connector, intel_encoder); > > diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c > > index 2f54dc3..416d23c 100644 > > --- a/drivers/gpu/drm/i915/intel_sdvo.c > > +++ b/drivers/gpu/drm/i915/intel_sdvo.c > > @@ -712,6 +712,13 @@ static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd, > > intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); > > } > > > > +static bool intel_sdvo_get_timing(struct intel_sdvo *intel_sdvo, u8 cmd, > > + struct intel_sdvo_dtd *dtd) > > +{ > > + return intel_sdvo_get_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) && > > + intel_sdvo_get_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); > > +} > > + > > static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo, > > struct intel_sdvo_dtd *dtd) > > { > > @@ -726,6 +733,13 @@ static bool intel_sdvo_set_output_timing(struct intel_sdvo *intel_sdvo, > > SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); > > } > > > > +static bool intel_sdvo_get_input_timing(struct intel_sdvo *intel_sdvo, > > + struct intel_sdvo_dtd *dtd) > > +{ > > + return intel_sdvo_get_timing(intel_sdvo, > > + SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd); > > +} > > + > > static bool > > intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo, > > uint16_t clock, > > @@ -1295,6 +1309,33 @@ static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder, > > return true; > > } > > > > +static void intel_sdvo_get_config(struct intel_encoder *encoder, > > + struct intel_crtc_config *pipe_config) > > +{ > > + struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); > > + struct intel_sdvo_dtd dtd; > > + u32 flags = 0; > > + bool ret; > > + > > + ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd); > > + if (!ret) { > > + DRM_DEBUG_DRIVER("failed to retrieve SDVO DTD\n"); > > + return; > > + } > > + > > + if (dtd.part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE) > > + flags |= DRM_MODE_FLAG_PHSYNC; > > + else > > + flags |= DRM_MODE_FLAG_NHSYNC; > > + > > + if (dtd.part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE) > > + flags |= DRM_MODE_FLAG_PVSYNC; > > + else > > + flags |= DRM_MODE_FLAG_NVSYNC; > > + > > + pipe_config->adjusted_mode.flags |= flags; > > +} > > + > > static void intel_disable_sdvo(struct intel_encoder *encoder) > > { > > struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; > > @@ -2819,6 +2860,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) > > intel_encoder->mode_set = intel_sdvo_mode_set; > > intel_encoder->enable = intel_enable_sdvo; > > intel_encoder->get_hw_state = intel_sdvo_get_hw_state; > > + intel_encoder->get_config = intel_sdvo_get_config; > > > > /* In default case sdvo lvds is false */ > > if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) > > -- > > 1.7.9.5 > > > > _______________________________________________ > > Intel-gfx mailing list > > Intel-gfx@lists.freedesktop.org > > http://lists.freedesktop.org/mailman/listinfo/intel-gfx > > > > -- > Paulo Zanoni > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
On Wed, May 15, 2013 at 06:45:35PM -0300, Paulo Zanoni wrote: > 2013/5/14 Jesse Barnes <jbarnes@virtuousgeek.org>: > > We can use this for fetching encoder specific pipe_config state, like > > mode flags, adjusted clock, etc. > > > > Just used for mode flags atm, so we can check the pipe config state at > > mode set time. > > > > v2: get_config when checking hw state too > > v3: fix DVO and LVDS mode flags (Ville) > > get SDVO DTD for flag fetch (Ville) > > v4: use input timings (Ville) > > correct command used (Ville) > > remove gen4 check (Ville) > > v5: get DDI flag config too > > > > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> > > Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > > Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> > > I applied this on my Haswell machine and booted it with both eDP-only > and eDP+DP and now I don't see those error messages anymore. Queued for -next, thanks for the patch. -Daniel
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index cc414f1..789c4ef 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -81,6 +81,28 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder, return true; } +static void intel_crt_get_config(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) +{ + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct intel_crt *crt = intel_encoder_to_crt(encoder); + u32 tmp, flags = 0; + + tmp = I915_READ(crt->adpa_reg); + + if (tmp & ADPA_HSYNC_ACTIVE_HIGH) + flags |= DRM_MODE_FLAG_PHSYNC; + else + flags |= DRM_MODE_FLAG_NHSYNC; + + if (tmp & ADPA_VSYNC_ACTIVE_HIGH) + flags |= DRM_MODE_FLAG_PVSYNC; + else + flags |= DRM_MODE_FLAG_NVSYNC; + + pipe_config->adjusted_mode.flags |= flags; +} + static void intel_disable_crt(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; @@ -784,6 +806,7 @@ void intel_crt_init(struct drm_device *dev) crt->base.compute_config = intel_crt_compute_config; crt->base.disable = intel_disable_crt; crt->base.enable = intel_enable_crt; + crt->base.get_config = intel_crt_get_config; if (I915_HAS_HOTPLUG(dev)) crt->base.hpd_pin = HPD_CRT; if (HAS_DDI(dev)) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index cddcf4a..27a74a9 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1254,6 +1254,28 @@ static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder) intel_dp_check_link_status(intel_dp); } +static void intel_ddi_get_config(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) +{ + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); + enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; + u32 temp, flags = 0; + + temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); + if (temp & TRANS_DDI_PHSYNC) + flags |= DRM_MODE_FLAG_PHSYNC; + else + flags |= DRM_MODE_FLAG_NHSYNC; + if (temp & TRANS_DDI_PVSYNC) + flags |= DRM_MODE_FLAG_PVSYNC; + else + flags |= DRM_MODE_FLAG_NVSYNC; + + pipe_config->adjusted_mode.flags |= flags; + pipe_config->pixel_multiplier = 1; +} + static void intel_ddi_destroy(struct drm_encoder *encoder) { /* HDMI has nothing special to destroy, so we can go with this. */ @@ -1313,6 +1335,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port) intel_encoder->disable = intel_disable_ddi; intel_encoder->post_disable = intel_ddi_post_disable; intel_encoder->get_hw_state = intel_ddi_get_hw_state; + intel_encoder->get_config = intel_ddi_get_config; intel_dig_port->port = port; intel_dig_port->port_reversal = I915_READ(DDI_BUF_CTL(port)) & diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7358e4e..163b97e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8057,6 +8057,15 @@ intel_pipe_config_compare(struct drm_device *dev, PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, DRM_MODE_FLAG_INTERLACE); + PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, + DRM_MODE_FLAG_PHSYNC); + PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, + DRM_MODE_FLAG_NHSYNC); + PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, + DRM_MODE_FLAG_PVSYNC); + PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, + DRM_MODE_FLAG_NVSYNC); + PIPE_CONF_CHECK_I(requested_mode.hdisplay); PIPE_CONF_CHECK_I(requested_mode.vdisplay); @@ -8149,6 +8158,8 @@ intel_modeset_check_state(struct drm_device *dev) bool enabled = false; bool active = false; + memset(&pipe_config, 0, sizeof(pipe_config)); + DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.base.id); @@ -8162,6 +8173,8 @@ intel_modeset_check_state(struct drm_device *dev) enabled = true; if (encoder->connectors_active) active = true; + if (encoder->get_config) + encoder->get_config(encoder, &pipe_config); } WARN(active != crtc->active, "crtc's computed active state doesn't match tracked active state " @@ -8170,7 +8183,6 @@ intel_modeset_check_state(struct drm_device *dev) "crtc's computed enabled state doesn't match tracked enabled state " "(expected %i, found %i)\n", enabled, crtc->base.enabled); - memset(&pipe_config, 0, sizeof(pipe_config)); pipe_config.cpu_transcoder = crtc->config.cpu_transcoder; active = dev_priv->display.get_pipe_config(crtc, &pipe_config); @@ -9579,8 +9591,10 @@ setup_pipes: pipe = 0; if (encoder->get_hw_state(encoder, &pipe)) { - encoder->base.crtc = - dev_priv->pipe_to_crtc_mapping[pipe]; + crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); + encoder->base.crtc = &crtc->base; + if (encoder->get_config) + encoder->get_config(encoder, &crtc->config); } else { encoder->base.crtc = NULL; } diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 2bb4009..a423256 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1356,6 +1356,28 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder, return true; } +static void intel_dp_get_config(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) +{ + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + u32 tmp, flags = 0; + + tmp = I915_READ(intel_dp->output_reg); + + if (tmp & DP_SYNC_HS_HIGH) + flags |= DRM_MODE_FLAG_PHSYNC; + else + flags |= DRM_MODE_FLAG_NHSYNC; + + if (tmp & DP_SYNC_VS_HIGH) + flags |= DRM_MODE_FLAG_PVSYNC; + else + flags |= DRM_MODE_FLAG_NVSYNC; + + pipe_config->adjusted_mode.flags |= flags; +} + static void intel_disable_dp(struct intel_encoder *encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); @@ -3154,6 +3176,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) intel_encoder->disable = intel_disable_dp; intel_encoder->post_disable = intel_post_disable_dp; intel_encoder->get_hw_state = intel_dp_get_hw_state; + intel_encoder->get_config = intel_dp_get_config; if (IS_VALLEYVIEW(dev)) intel_encoder->pre_pll_enable = intel_dp_pre_pll_enable; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 0f35545..4802483 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -139,6 +139,10 @@ struct intel_encoder { * the encoder is active. If the encoder is enabled it also set the pipe * it is connected to in the pipe parameter. */ bool (*get_hw_state)(struct intel_encoder *, enum pipe *pipe); + /* Reconstructs the equivalent mode flags for the current hardware + * state. */ + void (*get_config)(struct intel_encoder *, + struct intel_crtc_config *pipe_config); int crtc_mask; enum hpd_pin hpd_pin; }; diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 00e70db..91e9905 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -129,6 +129,26 @@ static bool intel_dvo_get_hw_state(struct intel_encoder *encoder, return true; } +static void intel_dvo_get_config(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) +{ + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base); + u32 tmp, flags = 0; + + tmp = I915_READ(intel_dvo->dev.dvo_reg); + if (tmp & DVO_HSYNC_ACTIVE_HIGH) + flags |= DRM_MODE_FLAG_PHSYNC; + else + flags |= DRM_MODE_FLAG_NHSYNC; + if (tmp & DVO_VSYNC_ACTIVE_HIGH) + flags |= DRM_MODE_FLAG_PVSYNC; + else + flags |= DRM_MODE_FLAG_NVSYNC; + + pipe_config->adjusted_mode.flags |= flags; +} + static void intel_disable_dvo(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; @@ -440,6 +460,7 @@ void intel_dvo_init(struct drm_device *dev) intel_encoder->disable = intel_disable_dvo; intel_encoder->enable = intel_enable_dvo; intel_encoder->get_hw_state = intel_dvo_get_hw_state; + intel_encoder->get_config = intel_dvo_get_config; intel_connector->get_hw_state = intel_dvo_connector_get_hw_state; /* Now, try to find a controller */ diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 93de5ff..9091655 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -658,6 +658,28 @@ static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder, return true; } +static void intel_hdmi_get_config(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) +{ + struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + u32 tmp, flags = 0; + + tmp = I915_READ(intel_hdmi->hdmi_reg); + + if (tmp & SDVO_HSYNC_ACTIVE_HIGH) + flags |= DRM_MODE_FLAG_PHSYNC; + else + flags |= DRM_MODE_FLAG_NHSYNC; + + if (tmp & SDVO_VSYNC_ACTIVE_HIGH) + flags |= DRM_MODE_FLAG_PVSYNC; + else + flags |= DRM_MODE_FLAG_NVSYNC; + + pipe_config->adjusted_mode.flags |= flags; +} + static void intel_enable_hdmi(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; @@ -1208,6 +1230,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port) intel_encoder->enable = intel_enable_hdmi; intel_encoder->disable = intel_disable_hdmi; intel_encoder->get_hw_state = intel_hdmi_get_hw_state; + intel_encoder->get_config = intel_hdmi_get_config; if (IS_VALLEYVIEW(dev)) { intel_encoder->pre_enable = intel_hdmi_pre_enable; intel_encoder->pre_pll_enable = intel_hdmi_pre_pll_enable; diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 36fe291..6554860 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -86,6 +86,31 @@ static bool intel_lvds_get_hw_state(struct intel_encoder *encoder, return true; } +static void intel_lvds_get_config(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) +{ + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 lvds_reg, tmp, flags = 0; + + if (HAS_PCH_SPLIT(dev)) + lvds_reg = PCH_LVDS; + else + lvds_reg = LVDS; + + tmp = I915_READ(lvds_reg); + if (tmp & LVDS_HSYNC_POLARITY) + flags |= DRM_MODE_FLAG_NHSYNC; + else + flags |= DRM_MODE_FLAG_PHSYNC; + if (tmp & LVDS_VSYNC_POLARITY) + flags |= DRM_MODE_FLAG_NVSYNC; + else + flags |= DRM_MODE_FLAG_PVSYNC; + + pipe_config->adjusted_mode.flags |= flags; +} + /* The LVDS pin pair needs to be on before the DPLLs are enabled. * This is an exception to the general rule that mode_set doesn't turn * things on. @@ -921,6 +946,7 @@ bool intel_lvds_init(struct drm_device *dev) intel_encoder->compute_config = intel_lvds_compute_config; intel_encoder->disable = intel_disable_lvds; intel_encoder->get_hw_state = intel_lvds_get_hw_state; + intel_encoder->get_config = intel_lvds_get_config; intel_connector->get_hw_state = intel_connector_get_hw_state; intel_connector_attach_encoder(intel_connector, intel_encoder); diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 2f54dc3..416d23c 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -712,6 +712,13 @@ static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd, intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); } +static bool intel_sdvo_get_timing(struct intel_sdvo *intel_sdvo, u8 cmd, + struct intel_sdvo_dtd *dtd) +{ + return intel_sdvo_get_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) && + intel_sdvo_get_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); +} + static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo, struct intel_sdvo_dtd *dtd) { @@ -726,6 +733,13 @@ static bool intel_sdvo_set_output_timing(struct intel_sdvo *intel_sdvo, SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); } +static bool intel_sdvo_get_input_timing(struct intel_sdvo *intel_sdvo, + struct intel_sdvo_dtd *dtd) +{ + return intel_sdvo_get_timing(intel_sdvo, + SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd); +} + static bool intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo, uint16_t clock, @@ -1295,6 +1309,33 @@ static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder, return true; } +static void intel_sdvo_get_config(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) +{ + struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); + struct intel_sdvo_dtd dtd; + u32 flags = 0; + bool ret; + + ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd); + if (!ret) { + DRM_DEBUG_DRIVER("failed to retrieve SDVO DTD\n"); + return; + } + + if (dtd.part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE) + flags |= DRM_MODE_FLAG_PHSYNC; + else + flags |= DRM_MODE_FLAG_NHSYNC; + + if (dtd.part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE) + flags |= DRM_MODE_FLAG_PVSYNC; + else + flags |= DRM_MODE_FLAG_NVSYNC; + + pipe_config->adjusted_mode.flags |= flags; +} + static void intel_disable_sdvo(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; @@ -2819,6 +2860,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) intel_encoder->mode_set = intel_sdvo_mode_set; intel_encoder->enable = intel_enable_sdvo; intel_encoder->get_hw_state = intel_sdvo_get_hw_state; + intel_encoder->get_config = intel_sdvo_get_config; /* In default case sdvo lvds is false */ if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))