blob: a3b8d78b3eaf186ed7d82a841337d68bc407f008 [file] [log] [blame]
From ecf1997ca311a1f0a871631dab31ee149c16779b Mon Sep 17 00:00:00 2001
From: Daniel Vetter <daniel.vetter@ffwll.ch>
Date: Fri, 7 Jun 2013 23:11:08 +0200
Subject: drm/i915: hw state readout for shared pch plls
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
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ä <ville.syrjala@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
(cherry picked from commit c0d43d62233b3d4523a62fe88896bfc7a609e572)
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
---
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 887b7e6f5025..c0a40063dded 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;
@@ -7844,6 +7858,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
@@ -8163,6 +8178,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
--
1.8.5.rc3