From c0d43d62233b3d4523a62fe88896bfc7a609e572 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 7 Jun 2013 23:11:08 +0200 Subject: [PATCH] drm/i915: hw state readout for shared pch plls MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Well, the first step of a long road at least, it only reads out the pipe -> shared dpll association thus far. Other state which needs to follow: - hw state of the dpll (on/off + dpll registers). Currently we just read that out from the hw state, but that doesn't work too well when the dpll is in use, but not yet fully enabled. We get away since most likely it already has been enabled and so the correct state is left behind in the registers. But that doesn't hold for atomic modesets when we want to enable all pipes at once. - Refcount reconstruction for each dpll. - Cross-checking of all the above. For that we need to keep the dpll register state both in the pipe and in the shared_dpll struct, so that we can check that every pipe is still connected to a correctly configured dpll. Note that since the refcount resconstruction isn't done yet this will spill a few WARNs at boot-up while trying to disable pch plls which have bogus refcounts. But since there's still a pile of refactoring to do I'd like to lock down the state handling as soon as possible hence decided against reordering the patches to quiet these WARNs - after all the issues they're complaining about have existed since forever, as Jesse can testify by having pch pll states blow up consistently in his fastboot patches ... v2: We need to preserve the old shared_dpll since currently the shared dpll refcount dropping/getting is done in ->mode_set. With the usual pipe_config infrastructure the old dpll id is already lost at that point, hence preserve it in the new config. v3: Rebase on top of the ips patch from Paulo. v4: We need to unconditionally take over the shared_dpll id from the old pipe config when e.g. doing a direct pch port -> cpu edp transition. v5: Move the saving of the old shared_dpll id to an ealier patch. Cc: Ville Syrjälä Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d5932ef76cde..51670ba56611 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4998,6 +4998,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, uint32_t tmp; pipe_config->cpu_transcoder = crtc->pipe; + pipe_config->shared_dpll = DPLL_ID_PRIVATE; tmp = I915_READ(PIPECONF(crtc->pipe)); if (!(tmp & PIPECONF_ENABLE)) @@ -5874,6 +5875,7 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, uint32_t tmp; pipe_config->cpu_transcoder = crtc->pipe; + pipe_config->shared_dpll = DPLL_ID_PRIVATE; tmp = I915_READ(PIPECONF(crtc->pipe)); if (!(tmp & PIPECONF_ENABLE)) @@ -5891,6 +5893,16 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, /* XXX: Can't properly read out the pch dpll pixel multiplier * since we don't have state tracking for pch clocks yet. */ pipe_config->pixel_multiplier = 1; + + if (HAS_PCH_IBX(dev_priv->dev)) { + pipe_config->shared_dpll = crtc->pipe; + } else { + tmp = I915_READ(PCH_DPLL_SEL); + if (tmp & TRANS_DPLLB_SEL(crtc->pipe)) + pipe_config->shared_dpll = DPLL_ID_PCH_PLL_B; + else + pipe_config->shared_dpll = DPLL_ID_PCH_PLL_A; + } } else { pipe_config->pixel_multiplier = 1; } @@ -5971,6 +5983,8 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, uint32_t tmp; pipe_config->cpu_transcoder = crtc->pipe; + pipe_config->shared_dpll = DPLL_ID_PRIVATE; + tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); if (tmp & TRANS_DDI_FUNC_ENABLE) { enum pipe trans_edp_pipe; @@ -7840,6 +7854,7 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, drm_mode_copy(&pipe_config->adjusted_mode, mode); drm_mode_copy(&pipe_config->requested_mode, mode); pipe_config->cpu_transcoder = to_intel_crtc(crtc)->pipe; + pipe_config->shared_dpll = DPLL_ID_PRIVATE; /* Compute a starting value for pipe_config->pipe_bpp taking the source * plane pixel format and any sink constraints into account. Returns the @@ -8159,6 +8174,8 @@ intel_pipe_config_compare(struct drm_device *dev, PIPE_CONF_CHECK_I(ips_enabled); + PIPE_CONF_CHECK_I(shared_dpll); + #undef PIPE_CONF_CHECK_I #undef PIPE_CONF_CHECK_FLAGS #undef PIPE_CONF_QUIRK -- 2.39.5