aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2014-06-25 15:01:55 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-07-10 16:08:02 -0400
commit26804afd4b3c7a1ff577db4d70df8055c7901ff4 (patch)
tree06662ef8300581465b500904e3141af170c21ecb /drivers/gpu
parentde7cfc635e4ce20ded5ca4e40328386d9ba81922 (diff)
drm/i915: State readout and cross-checking for ddi_pll_sel
To make things a bit more manageable extract a new function for reading out common ddi port state. This means a bit of duplication between encoders and the core since both look at the same registers, but doesn't seem worth to make a fuzz about. We can also remove the state readout code in intel_ddi_setup_hw_pll_state. That code is only called from the hardware take over and not the cross check code, and only after the crtc state is reconstructed. So we can rely on an accurate value of crtc->config.ddi_pll_sel already. Compared to the old code also trust the hw state more and don't special-case port A - we want to cross-check the actual-state, not bake in our own assumptions about how this is supposed to all be linked up. v2: Make use of the read-out ddi_pll_sel in intel_ddi_clock_get. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Damien Lespiau <damien.lespiau@intel.com> [imre: rebased on patchset version w/o pch/crt/fdi refactoring] Signed-off-by: Imre Deak <imre.deak@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h1
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c40
-rw-r--r--drivers/gpu/drm/i915/intel_display.c48
3 files changed, 34 insertions, 55 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index d829dfcfd550..b2b555c93d43 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5794,6 +5794,7 @@ enum punit_power_well {
5794#define TRANS_DDI_FUNC_ENABLE (1<<31) 5794#define TRANS_DDI_FUNC_ENABLE (1<<31)
5795/* Those bits are ignored by pipe EDP since it can only connect to DDI A */ 5795/* Those bits are ignored by pipe EDP since it can only connect to DDI A */
5796#define TRANS_DDI_PORT_MASK (7<<28) 5796#define TRANS_DDI_PORT_MASK (7<<28)
5797#define TRANS_DDI_PORT_SHIFT 28
5797#define TRANS_DDI_SELECT_PORT(x) ((x)<<28) 5798#define TRANS_DDI_SELECT_PORT(x) ((x)<<28)
5798#define TRANS_DDI_PORT_NONE (0<<28) 5799#define TRANS_DDI_PORT_NONE (0<<28)
5799#define TRANS_DDI_MODE_SELECT_MASK (7<<24) 5800#define TRANS_DDI_MODE_SELECT_MASK (7<<24)
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index c96bc3b6c3d0..1b4748bf56fc 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -612,11 +612,10 @@ static void intel_ddi_clock_get(struct intel_encoder *encoder,
612 struct intel_crtc_config *pipe_config) 612 struct intel_crtc_config *pipe_config)
613{ 613{
614 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; 614 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
615 enum port port = intel_ddi_get_encoder_port(encoder);
616 int link_clock = 0; 615 int link_clock = 0;
617 u32 val, pll; 616 u32 val, pll;
618 617
619 val = I915_READ(PORT_CLK_SEL(port)); 618 val = pipe_config->ddi_pll_sel;
620 switch (val & PORT_CLK_SEL_MASK) { 619 switch (val & PORT_CLK_SEL_MASK) {
621 case PORT_CLK_SEL_LCPLL_810: 620 case PORT_CLK_SEL_LCPLL_810:
622 link_clock = 81000; 621 link_clock = 81000;
@@ -1113,40 +1112,6 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
1113 return false; 1112 return false;
1114} 1113}
1115 1114
1116static uint32_t intel_ddi_get_crtc_pll(struct drm_i915_private *dev_priv,
1117 enum pipe pipe)
1118{
1119 uint32_t temp, ret;
1120 enum port port = I915_MAX_PORTS;
1121 enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
1122 pipe);
1123 int i;
1124
1125 if (cpu_transcoder == TRANSCODER_EDP) {
1126 port = PORT_A;
1127 } else {
1128 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1129 temp &= TRANS_DDI_PORT_MASK;
1130
1131 for (i = PORT_B; i <= PORT_E; i++)
1132 if (temp == TRANS_DDI_SELECT_PORT(i))
1133 port = i;
1134 }
1135
1136 if (port == I915_MAX_PORTS) {
1137 WARN(1, "Pipe %c enabled on an unknown port\n",
1138 pipe_name(pipe));
1139 ret = PORT_CLK_SEL_NONE;
1140 } else {
1141 ret = I915_READ(PORT_CLK_SEL(port));
1142 DRM_DEBUG_KMS("Pipe %c connected to port %c using clock "
1143 "0x%08x\n", pipe_name(pipe), port_name(port),
1144 ret);
1145 }
1146
1147 return ret;
1148}
1149
1150void intel_ddi_setup_hw_pll_state(struct drm_device *dev) 1115void intel_ddi_setup_hw_pll_state(struct drm_device *dev)
1151{ 1116{
1152 struct drm_i915_private *dev_priv = dev->dev_private; 1117 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1165,9 +1130,6 @@ void intel_ddi_setup_hw_pll_state(struct drm_device *dev)
1165 continue; 1130 continue;
1166 } 1131 }
1167 1132
1168 intel_crtc->config.ddi_pll_sel = intel_ddi_get_crtc_pll(dev_priv,
1169 pipe);
1170
1171 switch (intel_crtc->config.ddi_pll_sel) { 1133 switch (intel_crtc->config.ddi_pll_sel) {
1172 case PORT_CLK_SEL_WRPLL1: 1134 case PORT_CLK_SEL_WRPLL1:
1173 dev_priv->ddi_plls.wrpll1_refcount++; 1135 dev_priv->ddi_plls.wrpll1_refcount++;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6332d9dda00f..e26df6783406 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7570,6 +7570,35 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
7570 return 0; 7570 return 0;
7571} 7571}
7572 7572
7573static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
7574 struct intel_crtc_config *pipe_config)
7575{
7576 struct drm_device *dev = crtc->base.dev;
7577 struct drm_i915_private *dev_priv = dev->dev_private;
7578 enum port port;
7579 uint32_t tmp;
7580
7581 tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe_config->cpu_transcoder));
7582
7583 port = (tmp & TRANS_DDI_PORT_MASK) >> TRANS_DDI_PORT_SHIFT;
7584
7585 pipe_config->ddi_pll_sel = I915_READ(PORT_CLK_SEL(port));
7586 /*
7587 * Haswell has only FDI/PCH transcoder A. It is which is connected to
7588 * DDI E. So just check whether this pipe is wired to DDI E and whether
7589 * the PCH transcoder is on.
7590 */
7591 if ((port == PORT_E) && I915_READ(LPT_TRANSCONF) & TRANS_ENABLE) {
7592 pipe_config->has_pch_encoder = true;
7593
7594 tmp = I915_READ(FDI_RX_CTL(PIPE_A));
7595 pipe_config->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >>
7596 FDI_DP_PORT_WIDTH_SHIFT) + 1;
7597
7598 ironlake_get_fdi_m_n_config(crtc, pipe_config);
7599 }
7600}
7601
7573static bool haswell_get_pipe_config(struct intel_crtc *crtc, 7602static bool haswell_get_pipe_config(struct intel_crtc *crtc,
7574 struct intel_crtc_config *pipe_config) 7603 struct intel_crtc_config *pipe_config)
7575{ 7604{
@@ -7615,22 +7644,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
7615 if (!(tmp & PIPECONF_ENABLE)) 7644 if (!(tmp & PIPECONF_ENABLE))
7616 return false; 7645 return false;
7617 7646
7618 /* 7647 haswell_get_ddi_port_state(crtc, pipe_config);
7619 * Haswell has only FDI/PCH transcoder A. It is which is connected to
7620 * DDI E. So just check whether this pipe is wired to DDI E and whether
7621 * the PCH transcoder is on.
7622 */
7623 tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe_config->cpu_transcoder));
7624 if ((tmp & TRANS_DDI_PORT_MASK) == TRANS_DDI_SELECT_PORT(PORT_E) &&
7625 I915_READ(LPT_TRANSCONF) & TRANS_ENABLE) {
7626 pipe_config->has_pch_encoder = true;
7627
7628 tmp = I915_READ(FDI_RX_CTL(PIPE_A));
7629 pipe_config->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >>
7630 FDI_DP_PORT_WIDTH_SHIFT) + 1;
7631
7632 ironlake_get_fdi_m_n_config(crtc, pipe_config);
7633 }
7634 7648
7635 intel_get_pipe_timings(crtc, pipe_config); 7649 intel_get_pipe_timings(crtc, pipe_config);
7636 7650
@@ -10409,6 +10423,8 @@ intel_pipe_config_compare(struct drm_device *dev,
10409 10423
10410 PIPE_CONF_CHECK_I(double_wide); 10424 PIPE_CONF_CHECK_I(double_wide);
10411 10425
10426 PIPE_CONF_CHECK_X(ddi_pll_sel);
10427
10412 PIPE_CONF_CHECK_I(shared_dpll); 10428 PIPE_CONF_CHECK_I(shared_dpll);
10413 PIPE_CONF_CHECK_X(dpll_hw_state.dpll); 10429 PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
10414 PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md); 10430 PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);