aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-05-07 17:34:16 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-05-14 19:20:28 -0400
commit2fa2fe9a142cf8c8a30916ccf7ca6a27019fd6d2 (patch)
tree97a8db0f03d4a4a28523afb4c0d0b8544e318f1e
parent0a790cdbfc526890af7dc41515a563f09e427129 (diff)
drm/i915: panel fitter hw state readout&check support
Pfit state readout is a bit ugly on gen2/3 due to the intermingling with the lvds state, but alas. Also note that since state is always cleared to zero we can unconditonally compare all the state and completely neglect the actual platform we're running on. v2: Properly check for the pfit power domain on haswell. v3: Don't check pgm_ratios on gen4+, they're auto-computed by the hw. v4: Properly clear the lvds border bits, upset the state checker a bit. v5: Unconditionally read out panel dither settings on gen2/3. Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/intel_display.c67
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c1
2 files changed, 66 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e9d01e5d6ccb..12a92edbdd1a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4976,6 +4976,36 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
4976 return ret; 4976 return ret;
4977} 4977}
4978 4978
4979static void i9xx_get_pfit_config(struct intel_crtc *crtc,
4980 struct intel_crtc_config *pipe_config)
4981{
4982 struct drm_device *dev = crtc->base.dev;
4983 struct drm_i915_private *dev_priv = dev->dev_private;
4984 uint32_t tmp;
4985
4986 tmp = I915_READ(PFIT_CONTROL);
4987
4988 if (INTEL_INFO(dev)->gen < 4) {
4989 if (crtc->pipe != PIPE_B)
4990 return;
4991
4992 /* gen2/3 store dither state in pfit control, needs to match */
4993 pipe_config->gmch_pfit.control = tmp & PANEL_8TO6_DITHER_ENABLE;
4994 } else {
4995 if ((tmp & PFIT_PIPE_MASK) != (crtc->pipe << PFIT_PIPE_SHIFT))
4996 return;
4997 }
4998
4999 if (!(tmp & PFIT_ENABLE))
5000 return;
5001
5002 pipe_config->gmch_pfit.control = I915_READ(PFIT_CONTROL);
5003 pipe_config->gmch_pfit.pgm_ratios = I915_READ(PFIT_PGM_RATIOS);
5004 if (INTEL_INFO(dev)->gen < 5)
5005 pipe_config->gmch_pfit.lvds_border_bits =
5006 I915_READ(LVDS) & LVDS_BORDER_ENABLE;
5007}
5008
4979static bool i9xx_get_pipe_config(struct intel_crtc *crtc, 5009static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
4980 struct intel_crtc_config *pipe_config) 5010 struct intel_crtc_config *pipe_config)
4981{ 5011{
@@ -4989,6 +5019,8 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
4989 5019
4990 intel_get_pipe_timings(crtc, pipe_config); 5020 intel_get_pipe_timings(crtc, pipe_config);
4991 5021
5022 i9xx_get_pfit_config(crtc, pipe_config);
5023
4992 return true; 5024 return true;
4993} 5025}
4994 5026
@@ -5820,6 +5852,21 @@ static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc,
5820 & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1; 5852 & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
5821} 5853}
5822 5854
5855static void ironlake_get_pfit_config(struct intel_crtc *crtc,
5856 struct intel_crtc_config *pipe_config)
5857{
5858 struct drm_device *dev = crtc->base.dev;
5859 struct drm_i915_private *dev_priv = dev->dev_private;
5860 uint32_t tmp;
5861
5862 tmp = I915_READ(PF_CTL(crtc->pipe));
5863
5864 if (tmp & PF_ENABLE) {
5865 pipe_config->pch_pfit.pos = I915_READ(PF_WIN_POS(crtc->pipe));
5866 pipe_config->pch_pfit.size = I915_READ(PF_WIN_SZ(crtc->pipe));
5867 }
5868}
5869
5823static bool ironlake_get_pipe_config(struct intel_crtc *crtc, 5870static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
5824 struct intel_crtc_config *pipe_config) 5871 struct intel_crtc_config *pipe_config)
5825{ 5872{
@@ -5843,6 +5890,8 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
5843 5890
5844 intel_get_pipe_timings(crtc, pipe_config); 5891 intel_get_pipe_timings(crtc, pipe_config);
5845 5892
5893 ironlake_get_pfit_config(crtc, pipe_config);
5894
5846 return true; 5895 return true;
5847} 5896}
5848 5897
@@ -5962,6 +6011,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
5962 struct drm_device *dev = crtc->base.dev; 6011 struct drm_device *dev = crtc->base.dev;
5963 struct drm_i915_private *dev_priv = dev->dev_private; 6012 struct drm_i915_private *dev_priv = dev->dev_private;
5964 enum transcoder cpu_transcoder = crtc->config.cpu_transcoder; 6013 enum transcoder cpu_transcoder = crtc->config.cpu_transcoder;
6014 enum intel_display_power_domain pfit_domain;
5965 uint32_t tmp; 6015 uint32_t tmp;
5966 6016
5967 if (!intel_display_power_enabled(dev, 6017 if (!intel_display_power_enabled(dev,
@@ -5991,6 +6041,10 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
5991 6041
5992 intel_get_pipe_timings(crtc, pipe_config); 6042 intel_get_pipe_timings(crtc, pipe_config);
5993 6043
6044 pfit_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
6045 if (intel_display_power_enabled(dev, pfit_domain))
6046 ironlake_get_pfit_config(crtc, pipe_config);
6047
5994 return true; 6048 return true;
5995} 6049}
5996 6050
@@ -7956,7 +8010,8 @@ intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes)
7956 if (mask & (1 <<(intel_crtc)->pipe)) 8010 if (mask & (1 <<(intel_crtc)->pipe))
7957 8011
7958static bool 8012static bool
7959intel_pipe_config_compare(struct intel_crtc_config *current_config, 8013intel_pipe_config_compare(struct drm_device *dev,
8014 struct intel_crtc_config *current_config,
7960 struct intel_crtc_config *pipe_config) 8015 struct intel_crtc_config *pipe_config)
7961{ 8016{
7962#define PIPE_CONF_CHECK_I(name) \ 8017#define PIPE_CONF_CHECK_I(name) \
@@ -8005,6 +8060,14 @@ intel_pipe_config_compare(struct intel_crtc_config *current_config,
8005 PIPE_CONF_CHECK_I(requested_mode.hdisplay); 8060 PIPE_CONF_CHECK_I(requested_mode.hdisplay);
8006 PIPE_CONF_CHECK_I(requested_mode.vdisplay); 8061 PIPE_CONF_CHECK_I(requested_mode.vdisplay);
8007 8062
8063 PIPE_CONF_CHECK_I(gmch_pfit.control);
8064 /* pfit ratios are autocomputed by the hw on gen4+ */
8065 if (INTEL_INFO(dev)->gen < 4)
8066 PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios);
8067 PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits);
8068 PIPE_CONF_CHECK_I(pch_pfit.pos);
8069 PIPE_CONF_CHECK_I(pch_pfit.size);
8070
8008#undef PIPE_CONF_CHECK_I 8071#undef PIPE_CONF_CHECK_I
8009#undef PIPE_CONF_CHECK_FLAGS 8072#undef PIPE_CONF_CHECK_FLAGS
8010 8073
@@ -8116,7 +8179,7 @@ intel_modeset_check_state(struct drm_device *dev)
8116 "(expected %i, found %i)\n", crtc->active, active); 8179 "(expected %i, found %i)\n", crtc->active, active);
8117 8180
8118 WARN(active && 8181 WARN(active &&
8119 !intel_pipe_config_compare(&crtc->config, &pipe_config), 8182 !intel_pipe_config_compare(dev, &crtc->config, &pipe_config),
8120 "pipe state doesn't match!\n"); 8183 "pipe state doesn't match!\n");
8121 } 8184 }
8122} 8185}
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index e34e290c29eb..36fe291172ee 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -116,6 +116,7 @@ static void intel_pre_pll_enable_lvds(struct intel_encoder *encoder)
116 } 116 }
117 117
118 /* set the corresponsding LVDS_BORDER bit */ 118 /* set the corresponsding LVDS_BORDER bit */
119 temp &= ~LVDS_BORDER_ENABLE;
119 temp |= intel_crtc->config.gmch_pfit.lvds_border_bits; 120 temp |= intel_crtc->config.gmch_pfit.lvds_border_bits;
120 /* Set the B0-B3 data pairs corresponding to whether we're going to 121 /* Set the B0-B3 data pairs corresponding to whether we're going to
121 * set the DPLLs for dual-channel mode or not. 122 * set the DPLLs for dual-channel mode or not.