int intel_configure_dsi_pll(struct intel_dsi *intel_dsi, struct drm_display_mode *mode) { struct drm_i915_private *dev_priv = intel_dsi->base.base.dev->dev_private; int ret; struct dsi_mnp dsi_mnp; u32 dsi_clk; DRM_DEBUG_KMS("\n"); if (intel_dsi->dsi_clock_freq) dsi_clk = intel_dsi->dsi_clock_freq; else get_dsi_clk(intel_dsi, mode, &dsi_clk); ret = dsi_calc_mnp(dsi_clk, &dsi_mnp); /*ret = mnp_from_clk_table(dsi_clk, &dsi_mnp);*/ if (ret != 0) return ret; dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI0_DSIPLL; DRM_DEBUG_KMS("dsi pll div %08x, ctrl %08x\n", dsi_mnp.dsi_pll_div, dsi_mnp.dsi_pll_ctrl); vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, 0); vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_DIVIDER, dsi_mnp.dsi_pll_div); vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, dsi_mnp.dsi_pll_ctrl); return 0; }
void vlv_dsi_pll_enable(struct intel_encoder *encoder, const struct intel_crtc_state *config) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); DRM_DEBUG_KMS("\n"); mutex_lock(&dev_priv->sb_lock); vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, 0); vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_DIVIDER, config->dsi_pll.div); vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, config->dsi_pll.ctrl & ~DSI_PLL_VCO_EN); /* wait at least 0.5 us after ungating before enabling VCO, * allow hrtimer subsystem optimization by relaxing timing */ usleep_range(10, 50); vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, config->dsi_pll.ctrl); if (wait_for(vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL) & DSI_PLL_LOCK, 20)) { mutex_unlock(&dev_priv->sb_lock); DRM_ERROR("DSI PLL lock failed\n"); return; } mutex_unlock(&dev_priv->sb_lock); DRM_DEBUG_KMS("DSI PLL locked\n"); }
static void intel_configure_dsi_pll_reg(struct drm_i915_private *dev_priv, struct intel_dsi_mnp *intel_dsi_mnp, struct intel_dsi *intel_dsi, bool divider_update_only) { u32 dsi_pll_ctrl = 0, dsi_pll_div = 0; if (divider_update_only) { dsi_pll_ctrl = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL); dsi_pll_ctrl &= ~DSI_PLL_P1_POST_DIV_MASK; } else { vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, 0); dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI0_DSIPLL; } if (intel_dsi->dual_link) dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI1_DSIPLL; dsi_pll_ctrl |= (1 << (DSI_PLL_P1_POST_DIV_SHIFT + intel_dsi_mnp->p - 2)); dsi_pll_div = ((intel_dsi_mnp->n - 1) << DSI_PLL_N1_DIV_SHIFT) | intel_dsi_mnp->m; DRM_DEBUG_KMS("dsi pll div %08x, ctrl %08x\n", dsi_pll_div, dsi_pll_ctrl); vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_DIVIDER, dsi_pll_div); vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, dsi_pll_ctrl); }
int intel_drrs_configure_dsi_pll(struct intel_dsi *intel_dsi, struct intel_dsi_mnp *intel_dsi_mnp) { struct drm_i915_private *dev_priv = intel_dsi->base.base.dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(intel_dsi->base.base.crtc); struct intel_mipi_drrs_work *work = dev_priv->drrs.mipi_drrs_work; u32 dsi_pll_ctrl, vactive; u32 dsl_offset = PIPEDSL(intel_crtc->pipe), dsl; unsigned long timeout; intel_configure_dsi_pll_reg(dev_priv, intel_dsi_mnp, intel_dsi, true); dsi_pll_ctrl = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL); dsi_pll_ctrl &= (~DSI_PLL_VCO_EN); vactive = (I915_READ(VTOTAL(intel_crtc->pipe)) & VERTICAL_ACTIVE_DISPLAY_MASK) + 1; timeout = jiffies + msecs_to_jiffies(50); do { if (atomic_read(&work->abort_wait_loop) == 1) { DRM_DEBUG_KMS("Aborting the pll update\n"); return -EPERM; } dsl = (I915_READ(dsl_offset) & DSL_LINEMASK_GEN3); if (jiffies >= timeout) { DRM_ERROR("Timeout at waiting for Vblank\n"); return -ETIMEDOUT; } } while (dsl <= vactive); mutex_lock(&dev_priv->dpio_lock); /* Toggle the VCO_EN to bring in the new dividers values */ vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, dsi_pll_ctrl); dsi_pll_ctrl |= DSI_PLL_VCO_EN; vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, dsi_pll_ctrl); mutex_unlock(&dev_priv->dpio_lock); DRM_DEBUG_KMS("PLL Changed between DSL: %d, %d\n", dsl, I915_READ(dsl_offset) & DSL_LINEMASK_GEN3); if (wait_for(I915_READ(PIPECONF(PIPE_A)) & PIPECONF_DSI_PLL_LOCKED, 20)) { DRM_ERROR("DSI PLL lock failed\n"); return -EACCES; } return 0; }
static void vlv_cck_modify(struct drm_i915_private *dev_priv, u32 reg, u32 val, u32 mask) { u32 tmp = vlv_cck_read(dev_priv, reg); tmp &= ~mask; tmp |= val; vlv_cck_write(dev_priv, reg, tmp); }
void vlv_dsi_pll_disable(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); u32 tmp; DRM_DEBUG_KMS("\n"); mutex_lock(&dev_priv->sb_lock); tmp = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL); tmp &= ~DSI_PLL_VCO_EN; tmp |= DSI_PLL_LDO_GATE; vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, tmp); mutex_unlock(&dev_priv->sb_lock); }
int intel_disable_dsi_pll(struct intel_dsi *intel_dsi) { struct drm_i915_private *dev_priv = intel_dsi->base.base.dev->dev_private; u32 tmp; DRM_DEBUG_KMS("\n"); mutex_lock(&dev_priv->dpio_lock); tmp = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL); tmp &= ~DSI_PLL_VCO_EN; tmp |= DSI_PLL_LDO_GATE; vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, tmp); if ((I915_READ(PIPECONF(PIPE_A)) & (PIPECONF_ENABLE == 0)) && (I915_READ(PIPECONF(PIPE_B)) & (PIPECONF_ENABLE == 0))) I915_WRITE_BITS(_DPLL_A, 0x00000000, DPLL_REFA_CLK_ENABLE_VLV); mutex_unlock(&dev_priv->dpio_lock); return 0; }
int intel_enable_dsi_pll(struct intel_dsi *intel_dsi) { struct drm_encoder *encoder = &(intel_dsi->base.base); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); struct drm_display_mode *mode = &intel_crtc->config.adjusted_mode; struct drm_i915_private *dev_priv = intel_dsi->base.base.dev->dev_private; u32 tmp; DRM_DEBUG_KMS("\n"); if ((I915_READ(PIPECONF(PIPE_A)) & PIPECONF_DSI_PLL_LOCKED)) { DRM_DEBUG_KMS("DSI PLL Already locked\n"); return 0; } mutex_lock(&dev_priv->dpio_lock); intel_configure_dsi_pll(intel_dsi, mode); /* wait at least 0.5 us after ungating before enabling VCO */ usleep_range(1, 10); tmp = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL); tmp |= DSI_PLL_VCO_EN; /* enable DPLL ref clock */ I915_WRITE_BITS(_DPLL_A, DPLL_REFA_CLK_ENABLE_VLV, DPLL_REFA_CLK_ENABLE_VLV); udelay(1000); vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, tmp); mutex_unlock(&dev_priv->dpio_lock); if (wait_for(I915_READ(PIPECONF(PIPE_A)) & PIPECONF_DSI_PLL_LOCKED, 20)) { DRM_ERROR("DSI PLL lock failed\n"); return -1; } DRM_DEBUG_KMS("DSI PLL locked\n"); return 0; }