[Intel-gfx] [PATCH 18/31] drm/i915: hw state readout and cross-checking for shared dplls
Damien Lespiau
damien.lespiau at intel.com
Wed Jun 12 17:04:54 CEST 2013
On Wed, Jun 05, 2013 at 01:34:20PM +0200, Daniel Vetter wrote:
> Just the plumbing, all the modeset and enable code has not yet been
> switched over to use the new state. It seems to be decently broken
> anyway, at least wrt to handling of the special pixel mutliplier
> enabling sequence. Follow-up patches will clean up that mess.
>
> Another missing piece is more careful handling (and fixup) of the fp1
> alternate divisor state. The BIOS most likely doesn't bother to
> program that one to what we expect. So we need to be more careful with
> comparing that state, both for cross checking but also when checking
> for dpll sharing when acquiring shared dpll. Otherwise fastboot will
> deny a few shared dpll configurations which would otherwise work.
>
> v2: We need to memcpy the pipe config dpll hw state into the pll, for
> otherwise the cross-check code will get angry.
>
> v3: Don't forget to read the pch pll state in the crtc get_pipe_config
> function for ibx/ilk platforms.
>
> Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
Reviewed-by: Damien Lespiau <damien.lespiau at intel.com>
--
Damien
> ---
> drivers/gpu/drm/i915/i915_drv.h | 3 +++
> drivers/gpu/drm/i915/intel_display.c | 38 ++++++++++++++++++++++++++++++++++++
> drivers/gpu/drm/i915/intel_drv.h | 3 +++
> 3 files changed, 44 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index f23b033..4dc94ed 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -144,6 +144,9 @@ enum intel_dpll_id {
> #define I915_NUM_PLLS 2
>
> struct intel_dpll_hw_state {
> + uint32_t dpll;
> + uint32_t fp0;
> + uint32_t fp1;
> };
>
> struct intel_shared_dpll {
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 388ac54..a30e27a 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3055,7 +3055,11 @@ found:
> crtc->config.shared_dpll = i;
> DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name,
> pipe_name(crtc->pipe));
> +
> if (pll->active == 0) {
> + memcpy(&pll->hw_state, &crtc->config.dpll_hw_state,
> + sizeof(pll->hw_state));
> +
> DRM_DEBUG_DRIVER("setting up %s\n", pll->name);
> WARN_ON(pll->on);
> assert_shared_dpll_disabled(dev_priv, pll);
> @@ -5659,6 +5663,13 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> &fp, &reduced_clock,
> has_reduced_clock ? &fp2 : NULL);
>
> + intel_crtc->config.dpll_hw_state.dpll = dpll | DPLL_VCO_ENABLE;
> + intel_crtc->config.dpll_hw_state.fp0 = fp;
> + if (has_reduced_clock)
> + intel_crtc->config.dpll_hw_state.fp1 = fp2;
> + else
> + intel_crtc->config.dpll_hw_state.fp1 = fp;
> +
> pll = intel_get_shared_dpll(intel_crtc, dpll, fp);
> if (pll == NULL) {
> DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
> @@ -5778,6 +5789,8 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
> return false;
>
> if (I915_READ(PCH_TRANSCONF(crtc->pipe)) & TRANS_ENABLE) {
> + struct intel_shared_dpll *pll;
> +
> pipe_config->has_pch_encoder = true;
>
> tmp = I915_READ(FDI_RX_CTL(crtc->pipe));
> @@ -5799,6 +5812,11 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
> else
> pipe_config->shared_dpll = DPLL_ID_PCH_PLL_A;
> }
> +
> + pll = &dev_priv->shared_dplls[pipe_config->shared_dpll];
> +
> + WARN_ON(!pll->get_hw_state(dev_priv, pll,
> + &pipe_config->dpll_hw_state));
> } else {
> pipe_config->pixel_multiplier = 1;
> }
> @@ -7987,6 +8005,15 @@ intel_pipe_config_compare(struct drm_device *dev,
> struct intel_crtc_config *current_config,
> struct intel_crtc_config *pipe_config)
> {
> +#define PIPE_CONF_CHECK_X(name) \
> + if (current_config->name != pipe_config->name) { \
> + DRM_ERROR("mismatch in " #name " " \
> + "(expected 0x%08x, found 0x%08x)\n", \
> + current_config->name, \
> + pipe_config->name); \
> + return false; \
> + }
> +
> #define PIPE_CONF_CHECK_I(name) \
> if (current_config->name != pipe_config->name) { \
> DRM_ERROR("mismatch in " #name " " \
> @@ -8055,7 +8082,11 @@ intel_pipe_config_compare(struct drm_device *dev,
> PIPE_CONF_CHECK_I(ips_enabled);
>
> PIPE_CONF_CHECK_I(shared_dpll);
> + PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
> + PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
> + PIPE_CONF_CHECK_X(dpll_hw_state.fp1);
>
> +#undef PIPE_CONF_CHECK_X
> #undef PIPE_CONF_CHECK_I
> #undef PIPE_CONF_CHECK_FLAGS
>
> @@ -8237,6 +8268,10 @@ check_shared_dpll_state(struct drm_device *dev)
> WARN(pll->refcount != enabled_crtcs,
> "pll enabled crtcs mismatch (expected %i, found %i)\n",
> pll->refcount, enabled_crtcs);
> +
> + WARN(pll->on && memcmp(&pll->hw_state, &dpll_hw_state,
> + sizeof(dpll_hw_state)),
> + "pll hw state mismatch\n");
> }
> }
>
> @@ -8692,6 +8727,9 @@ static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv,
> uint32_t val;
>
> val = I915_READ(PCH_DPLL(pll->id));
> + hw_state->dpll = val;
> + hw_state->fp0 = I915_READ(PCH_FP0(pll->id));
> + hw_state->fp1 = I915_READ(PCH_FP1(pll->id));
>
> return val & DPLL_VCO_ENABLE;
> }
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index e0e5d55..6f28375 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -244,6 +244,9 @@ struct intel_crtc_config {
> /* Selected dpll when shared or DPLL_ID_PRIVATE. */
> enum intel_dpll_id shared_dpll;
>
> + /* Actual register state of the dpll, for shared dpll cross-checking. */
> + struct intel_dpll_hw_state dpll_hw_state;
> +
> int pipe_bpp;
> struct intel_link_m_n dp_m_n;
>
> --
> 1.7.11.7
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
More information about the Intel-gfx
mailing list