Message ID | 1367859400-3699-1-git-send-email-jbarnes@virtuousgeek.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Mon, May 06, 2013 at 09:56:40AM -0700, Jesse Barnes wrote: > 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 > > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> > --- > drivers/gpu/drm/i915/intel_crt.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 | 17 +++++++++++++++++ > drivers/gpu/drm/i915/intel_hdmi.c | 23 +++++++++++++++++++++++ > drivers/gpu/drm/i915/intel_lvds.c | 22 ++++++++++++++++++++++ > drivers/gpu/drm/i915/intel_sdvo.c | 24 ++++++++++++++++++++++++ > 8 files changed, 153 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c > index 991e530..1370870 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_display.c b/drivers/gpu/drm/i915/intel_display.c > index de8be75..924932f 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -8060,6 +8060,15 @@ intel_pipe_config_compare(struct intel_crtc_config *current_config, > 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); > > @@ -8144,6 +8153,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); > > @@ -8157,6 +8168,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 " > @@ -8165,7 +8178,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); > @@ -9575,8 +9587,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]); > + if (encoder->get_config) > + encoder->get_config(encoder, &crtc->config); > + encoder->base.crtc = &crtc->base; > } else { > encoder->base.crtc = NULL; > } > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > index a293523..889ce46 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -1383,6 +1383,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); > @@ -3170,6 +3192,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 dfcf546..abc4aa8 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -140,6 +140,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..7e54a28 100644 > --- a/drivers/gpu/drm/i915/intel_dvo.c > +++ b/drivers/gpu/drm/i915/intel_dvo.c > @@ -129,6 +129,22 @@ 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; > + if (tmp & DVO_VSYNC_ACTIVE_HIGH) > + flags |= DRM_MODE_FLAG_PVSYNC; If not positive, then negative? > + > + 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 +456,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 d256fe4..c836314 100644 > --- a/drivers/gpu/drm/i915/intel_lvds.c > +++ b/drivers/gpu/drm/i915/intel_lvds.c > @@ -86,6 +86,27 @@ 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; > + if (tmp & LVDS_VSYNC_POLARITY) > + flags |= DRM_MODE_FLAG_NVSYNC; If not negative, then positive? > + > + 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. > @@ -920,6 +941,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 a618a6a..75284ae 100644 > --- a/drivers/gpu/drm/i915/intel_sdvo.c > +++ b/drivers/gpu/drm/i915/intel_sdvo.c > @@ -1264,6 +1264,28 @@ 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 drm_i915_private *dev_priv = encoder->base.dev->dev_private; > + u32 tmp, flags = 0; > + > + tmp = I915_READ(intel_sdvo->sdvo_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; I'm guessing this guy should actually ask the SDVO chip for these instead. Well, assuming that's even possible. > + > + 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; > @@ -2793,6 +2815,8 @@ 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; > + if (INTEL_INFO(dev)->gen >= 4) > + 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 Tue, May 7, 2013 at 7:44 PM, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote: >> +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 drm_i915_private *dev_priv = encoder->base.dev->dev_private; >> + u32 tmp, flags = 0; >> + >> + tmp = I915_READ(intel_sdvo->sdvo_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; > > I'm guessing this guy should actually ask the SDVO chip for these > instead. Well, assuming that's even possible. The important part is that it matches up with the adjusted_mode we do when modesetting. That way the hw checker is happy and for fastboot we can just compare what we'd put into hw registers with the newly computed state (and fully skip the modeset dance if it matches). Or just forget about fastboot on sdvo. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch
On Tue, May 7, 2013 at 7:59 PM, Daniel Vetter <daniel@ffwll.ch> wrote: > On Tue, May 7, 2013 at 7:44 PM, Ville Syrjälä > <ville.syrjala@linux.intel.com> wrote: >>> +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 drm_i915_private *dev_priv = encoder->base.dev->dev_private; >>> + u32 tmp, flags = 0; >>> + >>> + tmp = I915_READ(intel_sdvo->sdvo_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; >> >> I'm guessing this guy should actually ask the SDVO chip for these >> instead. Well, assuming that's even possible. > > The important part is that it matches up with the adjusted_mode we do > when modesetting. That way the hw checker is happy and for fastboot we > can just compare what we'd put into hw registers with the newly > computed state (and fully skip the modeset dance if it matches). Or > just forget about fastboot on sdvo. I should read code before I write a mail next time around ... Ville is right. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 991e530..1370870 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_display.c b/drivers/gpu/drm/i915/intel_display.c index de8be75..924932f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8060,6 +8060,15 @@ intel_pipe_config_compare(struct intel_crtc_config *current_config, 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); @@ -8144,6 +8153,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); @@ -8157,6 +8168,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 " @@ -8165,7 +8178,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); @@ -9575,8 +9587,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]); + if (encoder->get_config) + encoder->get_config(encoder, &crtc->config); + encoder->base.crtc = &crtc->base; } else { encoder->base.crtc = NULL; } diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a293523..889ce46 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1383,6 +1383,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); @@ -3170,6 +3192,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 dfcf546..abc4aa8 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -140,6 +140,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..7e54a28 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -129,6 +129,22 @@ 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; + if (tmp & DVO_VSYNC_ACTIVE_HIGH) + flags |= DRM_MODE_FLAG_PVSYNC; + + 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 +456,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 d256fe4..c836314 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -86,6 +86,27 @@ 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; + if (tmp & LVDS_VSYNC_POLARITY) + flags |= DRM_MODE_FLAG_NVSYNC; + + 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. @@ -920,6 +941,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 a618a6a..75284ae 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1264,6 +1264,28 @@ 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 drm_i915_private *dev_priv = encoder->base.dev->dev_private; + u32 tmp, flags = 0; + + tmp = I915_READ(intel_sdvo->sdvo_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_disable_sdvo(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; @@ -2793,6 +2815,8 @@ 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; + if (INTEL_INFO(dev)->gen >= 4) + 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))
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 Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> --- drivers/gpu/drm/i915/intel_crt.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 | 17 +++++++++++++++++ drivers/gpu/drm/i915/intel_hdmi.c | 23 +++++++++++++++++++++++ drivers/gpu/drm/i915/intel_lvds.c | 22 ++++++++++++++++++++++ drivers/gpu/drm/i915/intel_sdvo.c | 24 ++++++++++++++++++++++++ 8 files changed, 153 insertions(+), 3 deletions(-)