#define assert_pll_enabled(d, p) assert_pll(d, p, true)
#define assert_pll_disabled(d, p) assert_pll(d, p, false)
+static struct intel_shared_dpll *
+intel_crtc_to_shared_dpll(struct intel_crtc *crtc)
+{
+ struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+
+ if (crtc->shared_dpll < 0)
+ return NULL;
+
+ return &dev_priv->shared_dplls[crtc->shared_dpll];
+}
+
/* For ILK+ */
static void assert_shared_dpll(struct drm_i915_private *dev_priv,
struct intel_shared_dpll *pll,
* The PCH PLL needs to be enabled before the PCH transcoder, since it
* drives the transcoder clock.
*/
-static void ironlake_enable_shared_dpll(struct intel_crtc *intel_crtc)
+static void ironlake_enable_shared_dpll(struct intel_crtc *crtc)
{
- struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
- struct intel_shared_dpll *pll;
+ struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
int reg;
u32 val;
/* PCH PLLs only available on ILK, SNB and IVB */
BUG_ON(dev_priv->info->gen < 5);
- pll = intel_crtc->shared_dpll;
if (pll == NULL)
return;
DRM_DEBUG_KMS("enable PCH PLL %x (active %d, on? %d)for crtc %d\n",
pll->pll_reg, pll->active, pll->on,
- intel_crtc->base.base.id);
+ crtc->base.base.id);
/* PCH refclock must be enabled first */
assert_pch_refclk_enabled(dev_priv);
pll->on = true;
}
-static void intel_disable_shared_dpll(struct intel_crtc *intel_crtc)
+static void intel_disable_shared_dpll(struct intel_crtc *crtc)
{
- struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
- struct intel_shared_dpll *pll = intel_crtc->shared_dpll;
+ struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
int reg;
u32 val;
DRM_DEBUG_KMS("disable PCH PLL %x (active %d, on? %d) for crtc %d\n",
pll->pll_reg, pll->active, pll->on,
- intel_crtc->base.base.id);
+ crtc->base.base.id);
if (WARN_ON(pll->active == 0)) {
assert_shared_dpll_disabled(dev_priv, pll, NULL);
DRM_DEBUG_KMS("disabling PCH PLL %x\n", pll->pll_reg);
/* Make sure transcoder isn't still depending on us */
- assert_pch_transcoder_disabled(dev_priv, intel_crtc->pipe);
+ assert_pch_transcoder_disabled(dev_priv, crtc->pipe);
reg = pll->pll_reg;
val = I915_READ(reg);
{
struct drm_device *dev = dev_priv->dev;
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
uint32_t reg, val, pipeconf_val;
/* PCH only available on ILK+ */
/* Make sure PCH DPLL is enabled */
assert_shared_dpll_enabled(dev_priv,
- to_intel_crtc(crtc)->shared_dpll,
- to_intel_crtc(crtc));
+ intel_crtc_to_shared_dpll(intel_crtc),
+ intel_crtc);
/* FDI must be feeding us bits for PCH ports */
assert_fdi_tx_enabled(dev_priv, pipe);
sel = TRANSC_DPLLB_SEL;
break;
}
- if (intel_crtc->shared_dpll->pll_reg == _PCH_DPLL_B)
+ if (intel_crtc->shared_dpll == DPLL_ID_PCH_PLL_B)
temp |= sel;
else
temp &= ~sel;
lpt_enable_pch_transcoder(dev_priv, cpu_transcoder);
}
-static void intel_put_shared_dpll(struct intel_crtc *intel_crtc)
+static void intel_put_shared_dpll(struct intel_crtc *crtc)
{
- struct intel_shared_dpll *pll = intel_crtc->shared_dpll;
+ struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
if (pll == NULL)
return;
WARN_ON(pll->active);
}
- intel_crtc->shared_dpll = NULL;
+ crtc->shared_dpll = DPLL_ID_PRIVATE;
}
-static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *intel_crtc, u32 dpll, u32 fp)
+static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, u32 dpll, u32 fp)
{
- struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
- struct intel_shared_dpll *pll;
- int i;
+ struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
+ enum intel_dpll_id i;
- pll = intel_crtc->shared_dpll;
if (pll) {
DRM_DEBUG_KMS("CRTC:%d dropping existing PCH PLL %x\n",
- intel_crtc->base.base.id, pll->pll_reg);
- intel_put_shared_dpll(intel_crtc);
+ crtc->base.base.id, pll->pll_reg);
+ intel_put_shared_dpll(crtc);
}
if (HAS_PCH_IBX(dev_priv->dev)) {
/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
- i = intel_crtc->pipe;
+ i = crtc->pipe;
pll = &dev_priv->shared_dplls[i];
DRM_DEBUG_KMS("CRTC:%d using pre-allocated PCH PLL %x\n",
- intel_crtc->base.base.id, pll->pll_reg);
+ crtc->base.base.id, pll->pll_reg);
goto found;
}
if (dpll == (I915_READ(pll->pll_reg) & 0x7fffffff) &&
fp == I915_READ(pll->fp0_reg)) {
DRM_DEBUG_KMS("CRTC:%d sharing existing PCH PLL %x (refcount %d, ative %d)\n",
- intel_crtc->base.base.id,
+ crtc->base.base.id,
pll->pll_reg, pll->refcount, pll->active);
goto found;
pll = &dev_priv->shared_dplls[i];
if (pll->refcount == 0) {
DRM_DEBUG_KMS("CRTC:%d allocated PCH PLL %x\n",
- intel_crtc->base.base.id, pll->pll_reg);
+ crtc->base.base.id, pll->pll_reg);
goto found;
}
}
return NULL;
found:
- intel_crtc->shared_dpll = pll;
- DRM_DEBUG_DRIVER("using pll %d for pipe %c\n", i, pipe_name(intel_crtc->pipe));
+ crtc->shared_dpll = i;
+ DRM_DEBUG_DRIVER("using pll %d for pipe %c\n", i, pipe_name(crtc->pipe));
if (pll->active == 0) {
DRM_DEBUG_DRIVER("setting up pll %d\n", i);
WARN_ON(pll->on);
bool ok, has_reduced_clock = false;
bool is_lvds = false;
struct intel_encoder *encoder;
+ struct intel_shared_dpll *pll;
int ret;
for_each_encoder_on_crtc(dev, crtc, encoder) {
/* CPU eDP is the only output that doesn't need a PCH PLL of its own. */
if (intel_crtc->config.has_pch_encoder) {
- struct intel_shared_dpll *pll;
-
fp = i9xx_dpll_compute_fp(&intel_crtc->config.dpll);
if (has_reduced_clock)
fp2 = i9xx_dpll_compute_fp(&reduced_clock);
if (encoder->pre_pll_enable)
encoder->pre_pll_enable(encoder);
- if (intel_crtc->shared_dpll) {
- I915_WRITE(intel_crtc->shared_dpll->pll_reg, dpll);
+ intel_crtc->lowfreq_avail = false;
+
+ if (intel_crtc->config.has_pch_encoder) {
+ pll = intel_crtc_to_shared_dpll(intel_crtc);
+
+ I915_WRITE(pll->pll_reg, dpll);
/* Wait for the clocks to stabilize. */
- POSTING_READ(intel_crtc->shared_dpll->pll_reg);
+ POSTING_READ(pll->pll_reg);
udelay(150);
/* The pixel multiplier can only be updated once the
*
* So write it again.
*/
- I915_WRITE(intel_crtc->shared_dpll->pll_reg, dpll);
- }
+ I915_WRITE(pll->pll_reg, dpll);
- intel_crtc->lowfreq_avail = false;
- if (intel_crtc->shared_dpll) {
if (is_lvds && has_reduced_clock && i915_powersave) {
- I915_WRITE(intel_crtc->shared_dpll->fp1_reg, fp2);
+ I915_WRITE(pll->fp1_reg, fp2);
intel_crtc->lowfreq_avail = true;
} else {
- I915_WRITE(intel_crtc->shared_dpll->fp1_reg, fp);
+ I915_WRITE(pll->fp1_reg, fp);
}
}