aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-06-05 07:34:20 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-06-12 15:32:56 -0400
commit66e985c035f4554939b8b63a8e21418271160ab0 (patch)
treefd5260bbb53bc04a56062beff336a763ac145963 /drivers/gpu/drm
parent87a875bbffcfac7cb7c9a106fda40f04de1f60a2 (diff)
drm/i915: hw state readout and cross-checking for shared dplls
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. Reviewed-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h3
-rw-r--r--drivers/gpu/drm/i915/intel_display.c38
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h3
3 files changed, 44 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 7b998dcae089..42ef7cb39e62 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -143,6 +143,9 @@ enum intel_dpll_id {
143#define I915_NUM_PLLS 2 143#define I915_NUM_PLLS 2
144 144
145struct intel_dpll_hw_state { 145struct intel_dpll_hw_state {
146 uint32_t dpll;
147 uint32_t fp0;
148 uint32_t fp1;
146}; 149};
147 150
148struct intel_shared_dpll { 151struct intel_shared_dpll {
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index cb724b6f8833..5b2fd9063a2d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3087,7 +3087,11 @@ found:
3087 crtc->config.shared_dpll = i; 3087 crtc->config.shared_dpll = i;
3088 DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name, 3088 DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name,
3089 pipe_name(crtc->pipe)); 3089 pipe_name(crtc->pipe));
3090
3090 if (pll->active == 0) { 3091 if (pll->active == 0) {
3092 memcpy(&pll->hw_state, &crtc->config.dpll_hw_state,
3093 sizeof(pll->hw_state));
3094
3091 DRM_DEBUG_DRIVER("setting up %s\n", pll->name); 3095 DRM_DEBUG_DRIVER("setting up %s\n", pll->name);
3092 WARN_ON(pll->on); 3096 WARN_ON(pll->on);
3093 assert_shared_dpll_disabled(dev_priv, pll); 3097 assert_shared_dpll_disabled(dev_priv, pll);
@@ -5718,6 +5722,13 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
5718 &fp, &reduced_clock, 5722 &fp, &reduced_clock,
5719 has_reduced_clock ? &fp2 : NULL); 5723 has_reduced_clock ? &fp2 : NULL);
5720 5724
5725 intel_crtc->config.dpll_hw_state.dpll = dpll | DPLL_VCO_ENABLE;
5726 intel_crtc->config.dpll_hw_state.fp0 = fp;
5727 if (has_reduced_clock)
5728 intel_crtc->config.dpll_hw_state.fp1 = fp2;
5729 else
5730 intel_crtc->config.dpll_hw_state.fp1 = fp;
5731
5721 pll = intel_get_shared_dpll(intel_crtc, dpll, fp); 5732 pll = intel_get_shared_dpll(intel_crtc, dpll, fp);
5722 if (pll == NULL) { 5733 if (pll == NULL) {
5723 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", 5734 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
@@ -5837,6 +5848,8 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
5837 return false; 5848 return false;
5838 5849
5839 if (I915_READ(PCH_TRANSCONF(crtc->pipe)) & TRANS_ENABLE) { 5850 if (I915_READ(PCH_TRANSCONF(crtc->pipe)) & TRANS_ENABLE) {
5851 struct intel_shared_dpll *pll;
5852
5840 pipe_config->has_pch_encoder = true; 5853 pipe_config->has_pch_encoder = true;
5841 5854
5842 tmp = I915_READ(FDI_RX_CTL(crtc->pipe)); 5855 tmp = I915_READ(FDI_RX_CTL(crtc->pipe));
@@ -5858,6 +5871,11 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
5858 else 5871 else
5859 pipe_config->shared_dpll = DPLL_ID_PCH_PLL_A; 5872 pipe_config->shared_dpll = DPLL_ID_PCH_PLL_A;
5860 } 5873 }
5874
5875 pll = &dev_priv->shared_dplls[pipe_config->shared_dpll];
5876
5877 WARN_ON(!pll->get_hw_state(dev_priv, pll,
5878 &pipe_config->dpll_hw_state));
5861 } else { 5879 } else {
5862 pipe_config->pixel_multiplier = 1; 5880 pipe_config->pixel_multiplier = 1;
5863 } 5881 }
@@ -8054,6 +8072,15 @@ intel_pipe_config_compare(struct drm_device *dev,
8054 struct intel_crtc_config *current_config, 8072 struct intel_crtc_config *current_config,
8055 struct intel_crtc_config *pipe_config) 8073 struct intel_crtc_config *pipe_config)
8056{ 8074{
8075#define PIPE_CONF_CHECK_X(name) \
8076 if (current_config->name != pipe_config->name) { \
8077 DRM_ERROR("mismatch in " #name " " \
8078 "(expected 0x%08x, found 0x%08x)\n", \
8079 current_config->name, \
8080 pipe_config->name); \
8081 return false; \
8082 }
8083
8057#define PIPE_CONF_CHECK_I(name) \ 8084#define PIPE_CONF_CHECK_I(name) \
8058 if (current_config->name != pipe_config->name) { \ 8085 if (current_config->name != pipe_config->name) { \
8059 DRM_ERROR("mismatch in " #name " " \ 8086 DRM_ERROR("mismatch in " #name " " \
@@ -8130,7 +8157,11 @@ intel_pipe_config_compare(struct drm_device *dev,
8130 PIPE_CONF_CHECK_I(ips_enabled); 8157 PIPE_CONF_CHECK_I(ips_enabled);
8131 8158
8132 PIPE_CONF_CHECK_I(shared_dpll); 8159 PIPE_CONF_CHECK_I(shared_dpll);
8160 PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
8161 PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
8162 PIPE_CONF_CHECK_X(dpll_hw_state.fp1);
8133 8163
8164#undef PIPE_CONF_CHECK_X
8134#undef PIPE_CONF_CHECK_I 8165#undef PIPE_CONF_CHECK_I
8135#undef PIPE_CONF_CHECK_FLAGS 8166#undef PIPE_CONF_CHECK_FLAGS
8136#undef PIPE_CONF_QUIRK 8167#undef PIPE_CONF_QUIRK
@@ -8315,6 +8346,10 @@ check_shared_dpll_state(struct drm_device *dev)
8315 WARN(pll->refcount != enabled_crtcs, 8346 WARN(pll->refcount != enabled_crtcs,
8316 "pll enabled crtcs mismatch (expected %i, found %i)\n", 8347 "pll enabled crtcs mismatch (expected %i, found %i)\n",
8317 pll->refcount, enabled_crtcs); 8348 pll->refcount, enabled_crtcs);
8349
8350 WARN(pll->on && memcmp(&pll->hw_state, &dpll_hw_state,
8351 sizeof(dpll_hw_state)),
8352 "pll hw state mismatch\n");
8318 } 8353 }
8319} 8354}
8320 8355
@@ -8755,6 +8790,9 @@ static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv,
8755 uint32_t val; 8790 uint32_t val;
8756 8791
8757 val = I915_READ(PCH_DPLL(pll->id)); 8792 val = I915_READ(PCH_DPLL(pll->id));
8793 hw_state->dpll = val;
8794 hw_state->fp0 = I915_READ(PCH_FP0(pll->id));
8795 hw_state->fp1 = I915_READ(PCH_FP1(pll->id));
8758 8796
8759 return val & DPLL_VCO_ENABLE; 8797 return val & DPLL_VCO_ENABLE;
8760} 8798}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 4a69bdc4f8ca..02e5d6557066 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -256,6 +256,9 @@ struct intel_crtc_config {
256 /* Selected dpll when shared or DPLL_ID_PRIVATE. */ 256 /* Selected dpll when shared or DPLL_ID_PRIVATE. */
257 enum intel_dpll_id shared_dpll; 257 enum intel_dpll_id shared_dpll;
258 258
259 /* Actual register state of the dpll, for shared dpll cross-checking. */
260 struct intel_dpll_hw_state dpll_hw_state;
261
259 int pipe_bpp; 262 int pipe_bpp;
260 struct intel_link_m_n dp_m_n; 263 struct intel_link_m_n dp_m_n;
261 264