Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8106ddbd authored by Ander Conselvan de Oliveira's avatar Ander Conselvan de Oliveira
Browse files

drm/i915: Store a direct pointer to shared dpll in intel_crtc_state



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: default avatarAnder Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Reviewed-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1457451987-17466-5-git-send-email-ander.conselvan.de.oliveira@intel.com
parent a4780b77
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -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;
	}
+72 −36
Original line number Diff line number Diff line
@@ -1843,8 +1843,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);
@@ -4147,7 +4146,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;
@@ -4883,7 +4883,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)
@@ -8052,7 +8052,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;

@@ -9256,7 +9256,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));
@@ -9285,6 +9285,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;

@@ -9295,17 +9296,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));
@@ -9741,28 +9743,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);
@@ -9777,36 +9785,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,
@@ -9829,9 +9854,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));
	}
@@ -9871,7 +9895,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) {
@@ -11868,7 +11892,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)
@@ -12213,7 +12237,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;

@@ -12483,6 +12507,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,\
@@ -12650,7 +12683,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);
@@ -12669,6 +12702,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
@@ -12892,7 +12926,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;

@@ -12914,9 +12949,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,
@@ -12995,20 +13030,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);
	}
}

@@ -15655,7 +15691,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;
			}
+40 −11
Original line number Diff line number Diff line
@@ -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);
	}

+16 −3
Original line number Diff line number Diff line
@@ -483,8 +483,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.
@@ -1204,7 +1204,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);
+1 −1
Original line number Diff line number Diff line
@@ -145,7 +145,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);
	}