[PATCH 04/13] drm/i915: Store a direct pointer to shared dpll in intel_crtc_state

Ander Conselvan de Oliveira
2016-02-26T13:54:38Z

Change the type of intel_crtc_state->shared_dpll to be a pointer to a
shared dpll. With this there is no need to first convert the id stored
in the crtc state to a pointer in order to use it. It does introduce a
bit of hassle on doing the opposite.

The long term objective is to hide details about dpll ids behind the
shared dpll interface.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
drivers/gpu/drm/i915/intel_ddi.c | 4 +-
drivers/gpu/drm/i915/intel_display.c | 108 ++++++++++++++++++++++------------
drivers/gpu/drm/i915/intel_dpll_mgr.c | 51 ++++++++++++----
drivers/gpu/drm/i915/intel_drv.h | 19 +++++-
drivers/gpu/drm/i915/intel_lvds.c | 2 +-
5 files changed, 132 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index eb6b55c..a2b33d0 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1209,6 +1209,7 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
struct intel_crtc_state *crtc_state,
struct intel_encoder *intel_encoder)
{
+ struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
int clock = crtc_state->port_clock;

if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
@@ -1244,7 +1245,8 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
WARN_ON(spll->hw_state.spll != crtc_state->dpll_hw_state.spll))
return false;

- crtc_state->shared_dpll = DPLL_ID_SPLL;
+ crtc_state->shared_dpll =
+ intel_get_shared_dpll_by_id(dev_priv, DPLL_ID_SPLL);
spll->hw_state.spll = crtc_state->dpll_hw_state.spll;
spll->crtc_mask |= 1 << intel_crtc->pipe;
}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index df49324..e723323 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1828,8 +1828,7 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv,
BUG_ON(!HAS_PCH_SPLIT(dev));

/* Make sure PCH DPLL is enabled */
- assert_shared_dpll_enabled(dev_priv,
- intel_crtc_to_shared_dpll(intel_crtc));
+ assert_shared_dpll_enabled(dev_priv, intel_crtc->config->shared_dpll);

/* FDI must be feeding us bits for PCH ports */
assert_fdi_tx_enabled(dev_priv, pipe);
@@ -4024,7 +4023,8 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
temp = I915_READ(PCH_DPLL_SEL);
temp |= TRANS_DPLL_ENABLE(pipe);
sel = TRANS_DPLLB_SEL(pipe);
- if (intel_crtc->config->shared_dpll == DPLL_ID_PCH_PLL_B)
+ if (intel_crtc->config->shared_dpll ==
+ intel_get_shared_dpll_by_id(dev_priv, DPLL_ID_PCH_PLL_B))
temp |= sel;
else
temp &= ~sel;
@@ -4724,7 +4724,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
false);

- if (intel_crtc_to_shared_dpll(intel_crtc))
+ if (intel_crtc->config->shared_dpll)
intel_enable_shared_dpll(intel_crtc);

if (intel_crtc->config->has_dp_encoder)
@@ -7891,7 +7891,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
return false;

pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
- pipe_config->shared_dpll = DPLL_ID_PRIVATE;
+ pipe_config->shared_dpll = NULL;

ret = false;

@@ -9095,7 +9095,7 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
return false;

pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
- pipe_config->shared_dpll = DPLL_ID_PRIVATE;
+ pipe_config->shared_dpll = NULL;

ret = false;
tmp = I915_READ(PIPECONF(crtc->pipe));
@@ -9124,6 +9124,7 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,

if (I915_READ(PCH_TRANSCONF(crtc->pipe)) & TRANS_ENABLE) {
struct intel_shared_dpll *pll;
+ enum intel_dpll_id pll_id;

pipe_config->has_pch_encoder = true;

@@ -9134,17 +9135,18 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
ironlake_get_fdi_m_n_config(crtc, pipe_config);

if (HAS_PCH_IBX(dev_priv->dev)) {
- pipe_config->shared_dpll =
- (enum intel_dpll_id) crtc->pipe;
+ pll_id = (enum intel_dpll_id) 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;
+ pll_id = DPLL_ID_PCH_PLL_B;
else
- pipe_config->shared_dpll = DPLL_ID_PCH_PLL_A;
+ pll_id= DPLL_ID_PCH_PLL_A;
}

- pll = &dev_priv->shared_dplls[pipe_config->shared_dpll];
+ pipe_config->shared_dpll =
+ intel_get_shared_dpll_by_id(dev_priv, pll_id);
+ pll = pipe_config->shared_dpll;

WARN_ON(!pll->get_hw_state(dev_priv, pll,
&pipe_config->dpll_hw_state));
@@ -9580,28 +9582,34 @@ static void bxt_get_ddi_pll(struct drm_i915_private *dev_priv,
enum port port,
struct intel_crtc_state *pipe_config)
{
+ enum intel_dpll_id id;
+
switch (port) {
case PORT_A:
pipe_config->ddi_pll_sel = SKL_DPLL0;
- pipe_config->shared_dpll = DPLL_ID_SKL_DPLL1;
+ id = DPLL_ID_SKL_DPLL1;
break;
case PORT_B:
pipe_config->ddi_pll_sel = SKL_DPLL1;
- pipe_config->shared_dpll = DPLL_ID_SKL_DPLL2;
+ id = DPLL_ID_SKL_DPLL2;
break;
case PORT_C:
pipe_config->ddi_pll_sel = SKL_DPLL2;
- pipe_config->shared_dpll = DPLL_ID_SKL_DPLL3;
+ id = DPLL_ID_SKL_DPLL3;
break;
default:
DRM_ERROR("Incorrect port type\n");
+ return;
}
+
+ pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id);
}

static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv,
enum port port,
struct intel_crtc_state *pipe_config)
{
+ enum intel_dpll_id id;
u32 temp, dpll_ctl1;

temp = I915_READ(DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_SEL_MASK(port);
@@ -9616,36 +9624,53 @@ static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv,
*/
dpll_ctl1 = I915_READ(DPLL_CTRL1);
pipe_config->dpll_hw_state.ctrl1 = dpll_ctl1 & 0x3f;
- break;
+ return;
case SKL_DPLL1:
- pipe_config->shared_dpll = DPLL_ID_SKL_DPLL1;
+ id = DPLL_ID_SKL_DPLL1;
break;
case SKL_DPLL2:
- pipe_config->shared_dpll = DPLL_ID_SKL_DPLL2;
+ id = DPLL_ID_SKL_DPLL2;
break;
case SKL_DPLL3:
- pipe_config->shared_dpll = DPLL_ID_SKL_DPLL3;
+ id = DPLL_ID_SKL_DPLL3;
break;
+ default:
+ MISSING_CASE(pipe_config->ddi_pll_sel);
+ return;
}
+
+ pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id);
}

static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv,
enum port port,
struct intel_crtc_state *pipe_config)
{
+ enum intel_dpll_id id;
+
pipe_config->ddi_pll_sel = I915_READ(PORT_CLK_SEL(port));

switch (pipe_config->ddi_pll_sel) {
case PORT_CLK_SEL_WRPLL1:
- pipe_config->shared_dpll = DPLL_ID_WRPLL1;
+ id = DPLL_ID_WRPLL1;
break;
case PORT_CLK_SEL_WRPLL2:
- pipe_config->shared_dpll = DPLL_ID_WRPLL2;
+ id = DPLL_ID_WRPLL2;
break;
case PORT_CLK_SEL_SPLL:
- pipe_config->shared_dpll = DPLL_ID_SPLL;
+ id = DPLL_ID_SPLL;
break;
+ default:
+ MISSING_CASE(pipe_config->ddi_pll_sel);
+ /* fall through */
+ case PORT_CLK_SEL_NONE:
+ case PORT_CLK_SEL_LCPLL_810:
+ case PORT_CLK_SEL_LCPLL_1350:
+ case PORT_CLK_SEL_LCPLL_2700:
+ return;
}
+
+ pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id);
}

static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
@@ -9668,9 +9693,8 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
else
haswell_get_ddi_pll(dev_priv, port, pipe_config);

- if (pipe_config->shared_dpll >= 0) {
- pll = &dev_priv->shared_dplls[pipe_config->shared_dpll];
-
+ pll = pipe_config->shared_dpll;
+ if (pll) {
WARN_ON(!pll->get_hw_state(dev_priv, pll,
&pipe_config->dpll_hw_state));
}
@@ -9710,7 +9734,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
ret = false;

pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
- pipe_config->shared_dpll = DPLL_ID_PRIVATE;
+ pipe_config->shared_dpll = NULL;

tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
if (tmp & TRANS_DDI_FUNC_ENABLE) {
@@ -11702,7 +11726,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,

if (mode_changed && crtc_state->enable &&
dev_priv->display.crtc_compute_clock &&
- !WARN_ON(pipe_config->shared_dpll != DPLL_ID_PRIVATE)) {
+ !WARN_ON(pipe_config->shared_dpll)) {
ret = dev_priv->display.crtc_compute_clock(intel_crtc,
pipe_config);
if (ret)
@@ -12026,7 +12050,7 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
struct drm_crtc_state tmp_state;
struct intel_crtc_scaler_state scaler_state;
struct intel_dpll_hw_state dpll_hw_state;
- enum intel_dpll_id shared_dpll;
+ struct intel_shared_dpll *shared_dpll;
uint32_t ddi_pll_sel;
bool force_thru;

@@ -12296,6 +12320,15 @@ intel_pipe_config_compare(struct drm_device *dev,
ret = false; \
}

+#define PIPE_CONF_CHECK_P(name) \
+ if (current_config->name != pipe_config->name) { \
+ INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
+ "(expected %p, found %p)\n", \
+ current_config->name, \
+ pipe_config->name); \
+ ret = false; \
+ }
+
#define PIPE_CONF_CHECK_M_N(name) \
if (!intel_compare_link_m_n(&current_config->name, \
&pipe_config->name,\
@@ -12463,7 +12496,7 @@ intel_pipe_config_compare(struct drm_device *dev,

PIPE_CONF_CHECK_X(ddi_pll_sel);

- PIPE_CONF_CHECK_I(shared_dpll);
+ PIPE_CONF_CHECK_P(shared_dpll);
PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
@@ -12482,6 +12515,7 @@ intel_pipe_config_compare(struct drm_device *dev,

#undef PIPE_CONF_CHECK_X
#undef PIPE_CONF_CHECK_I
+#undef PIPE_CONF_CHECK_P
#undef PIPE_CONF_CHECK_I_ALT
#undef PIPE_CONF_CHECK_FLAGS
#undef PIPE_CONF_CHECK_CLOCK_FUZZY
@@ -12685,7 +12719,8 @@ check_shared_dpll_state(struct drm_device *dev)
int i;

for (i = 0; i < dev_priv->num_shared_dpll; i++) {
- struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
+ struct intel_shared_dpll *pll =
+ intel_get_shared_dpll_by_id(dev_priv, i);
int enabled_crtcs = 0, active_crtcs = 0;
bool active;

@@ -12707,9 +12742,9 @@ check_shared_dpll_state(struct drm_device *dev)
pll->on, active);

for_each_intel_crtc(dev, crtc) {
- if (crtc->base.state->enable && intel_crtc_to_shared_dpll(crtc) == pll)
+ if (crtc->base.state->enable && crtc->config->shared_dpll == pll)
enabled_crtcs++;
- if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll)
+ if (crtc->active && crtc->config->shared_dpll == pll)
active_crtcs++;
}
I915_STATE_WARN(pll->active != active_crtcs,
@@ -12800,20 +12835,21 @@ static void intel_modeset_clear_plls(struct drm_atomic_state *state)

for_each_crtc_in_state(state, crtc, crtc_state, i) {
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- int old_dpll = to_intel_crtc_state(crtc->state)->shared_dpll;
+ struct intel_shared_dpll *old_dpll =
+ to_intel_crtc_state(crtc->state)->shared_dpll;

if (!needs_modeset(crtc_state))
continue;

- to_intel_crtc_state(crtc_state)->shared_dpll = DPLL_ID_PRIVATE;
+ to_intel_crtc_state(crtc_state)->shared_dpll = NULL;

- if (old_dpll == DPLL_ID_PRIVATE)
+ if (!old_dpll)
continue;

if (!shared_dpll)
shared_dpll = intel_atomic_get_shared_dpll_state(state);

- shared_dpll[old_dpll].crtc_mask &= ~(1 << intel_crtc->pipe);
+ intel_shared_dpll_config_put(shared_dpll, old_dpll, intel_crtc);
}
}

@@ -15435,7 +15471,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
pll->active = 0;
pll->config.crtc_mask = 0;
for_each_intel_crtc(dev, crtc) {
- if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll) {
+ if (crtc->active && crtc->config->shared_dpll == pll) {
pll->active++;
pll->config.crtc_mask |= 1 << crtc->pipe;
}
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 11effe3..889ceed 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -24,14 +24,43 @@
#include "intel_drv.h"

struct intel_shared_dpll *
-intel_crtc_to_shared_dpll(struct intel_crtc *crtc)
+intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv,
+ enum intel_dpll_id id)
{
- struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ return &dev_priv->shared_dplls[id];
+}

- if (crtc->config->shared_dpll < 0)
- return NULL;
+enum intel_dpll_id
+intel_get_shared_dpll_id(struct drm_i915_private *dev_priv,
+ struct intel_shared_dpll *pll)
+{
+ if (WARN_ON(pll < dev_priv->shared_dplls||
+ pll > &dev_priv->shared_dplls[dev_priv->num_shared_dpll]))
+ return -1;
+
+ return (enum intel_dpll_id) (pll - dev_priv->shared_dplls);
+}
+
+void
+intel_shared_dpll_config_get(struct intel_shared_dpll_config *config,
+ struct intel_shared_dpll *pll,
+ struct intel_crtc *crtc)
+{
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ enum intel_dpll_id id = intel_get_shared_dpll_id(dev_priv, pll);
+
+ config[id].crtc_mask |= 1 << crtc->pipe;
+}
+
+void
+intel_shared_dpll_config_put(struct intel_shared_dpll_config *config,
+ struct intel_shared_dpll *pll,
+ struct intel_crtc *crtc)
+{
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ enum intel_dpll_id id = intel_get_shared_dpll_id(dev_priv, pll);

- return &dev_priv->shared_dplls[crtc->config->shared_dpll];
+ config[id].crtc_mask &= ~(1 << crtc->pipe);
}

/* For ILK+ */
@@ -55,7 +84,7 @@ void intel_prepare_shared_dpll(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
+ struct intel_shared_dpll *pll = crtc->config->shared_dpll;

if (WARN_ON(pll == NULL))
return;
@@ -82,7 +111,7 @@ void intel_enable_shared_dpll(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
+ struct intel_shared_dpll *pll = crtc->config->shared_dpll;

if (WARN_ON(pll == NULL))
return;
@@ -112,7 +141,7 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
+ struct intel_shared_dpll *pll = crtc->config->shared_dpll;

/* PCH only available on ILK+ */
if (INTEL_INFO(dev)->gen < 5)
@@ -265,11 +294,11 @@ intel_get_shared_dpll(struct intel_crtc *crtc,
shared_dpll[i].hw_state =
crtc_state->dpll_hw_state;

- crtc_state->shared_dpll = i;
+ crtc_state->shared_dpll = pll;
DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name,
pipe_name(crtc->pipe));

- shared_dpll[i].crtc_mask |= 1 << crtc->pipe;
+ intel_shared_dpll_config_get(shared_dpll, pll, crtc);

return pll;
}
@@ -360,7 +389,7 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,

/* Make sure no transcoder isn't still depending on us. */
for_each_intel_crtc(dev, crtc) {
- if (intel_crtc_to_shared_dpll(crtc) == pll)
+ if (crtc->config->shared_dpll == pll)
assert_pch_transcoder_disabled(dev_priv, crtc->pipe);
}

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 96e84d3..0a929c1 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -441,8 +441,8 @@ struct intel_crtc_state {
* haswell. */
struct dpll dpll;

- /* Selected dpll when shared or DPLL_ID_PRIVATE. */
- enum intel_dpll_id shared_dpll;
+ /* Selected dpll when shared or NULL. */
+ struct intel_shared_dpll *shared_dpll;

/*
* - PORT_CLK_SEL for DDI ports on HSW/BDW.
@@ -1147,7 +1147,20 @@ void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
enum pipe pipe);

/* shared dpll functions */
-struct intel_shared_dpll *intel_crtc_to_shared_dpll(struct intel_crtc *crtc);
+struct intel_shared_dpll *
+intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv,
+ enum intel_dpll_id id);
+enum intel_dpll_id
+intel_get_shared_dpll_id(struct drm_i915_private *dev_priv,
+ struct intel_shared_dpll *pll);
+void
+intel_shared_dpll_config_get(struct intel_shared_dpll_config *config,
+ struct intel_shared_dpll *pll,
+ struct intel_crtc *crtc);
+void
+intel_shared_dpll_config_put(struct intel_shared_dpll_config *config,
+ struct intel_shared_dpll *pll,
+ struct intel_crtc *crtc);
void assert_shared_dpll(struct drm_i915_private *dev_priv,
struct intel_shared_dpll *pll,
bool state);
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 30a8403..a042a6f28 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -151,7 +151,7 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder)
if (HAS_PCH_SPLIT(dev)) {
assert_fdi_rx_pll_disabled(dev_priv, pipe);
assert_shared_dpll_disabled(dev_priv,
- intel_crtc_to_shared_dpll(crtc));
+ crtc->config->shared_dpll);
} else {
assert_pll_disabled(dev_priv, pipe);
}