On Tue, 01 Sep 2015, Uma Shankar <uma.shankar@xxxxxxxxx> wrote: > From: Shashank Sharma <shashank.sharma@xxxxxxxxx> > > This patch adds new functions for BXT clock and PLL programming. > They are: > 1. configure_dsi_pll for BXT. > This function does the basic math and generates the divider ratio > based on requested pixclock, and program clock registers. > 2. enable_dsi_pll function. > This function programs the calculated clock values on the PLL. > 3. intel_enable_dsi_pll > Wrapper function to use same code for multiple platforms. It checks the > platform and calls appropriate core pll enable function. > > v2: Fixed Jani's review comments. Macros are adjusted as per convention. > > v3: Removed a redundant change wrt code comment. > > Signed-off-by: Shashank Sharma <shashank.sharma@xxxxxxxxx> > Signed-off-by: Uma Shankar <uma.shankar@xxxxxxxxx> Reviewed-by: Jani Nikula <jani.nikula@xxxxxxxxx> > --- > drivers/gpu/drm/i915/i915_reg.h | 22 ++++++++ > drivers/gpu/drm/i915/intel_dsi.c | 2 +- > drivers/gpu/drm/i915/intel_dsi.h | 2 +- > drivers/gpu/drm/i915/intel_dsi_pll.c | 95 +++++++++++++++++++++++++++++++++- > 4 files changed, 118 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 621151b..06bb2e1 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -7362,6 +7362,28 @@ enum skl_disp_power_wells { > > #define _MIPI_PORT(port, a, c) _PORT3(port, a, 0, c) /* ports A and C only */ > > +#define BXT_DSI_PLL_CTL 0x161000 > +#define BXT_DSI_PLL_PVD_RATIO_SHIFT 16 > +#define BXT_DSI_PLL_PVD_RATIO_MASK (3 << BXT_DSI_PLL_PVD_RATIO_SHIFT) > +#define BXT_DSI_PLL_PVD_RATIO_1 (1 << BXT_DSI_PLL_PVD_RATIO_SHIFT) > +#define BXT_DSIC_16X_BY2 (1 << 10) > +#define BXT_DSIC_16X_BY3 (2 << 10) > +#define BXT_DSIC_16X_BY4 (3 << 10) > +#define BXT_DSIA_16X_BY2 (1 << 8) > +#define BXT_DSIA_16X_BY3 (2 << 8) > +#define BXT_DSIA_16X_BY4 (3 << 8) > +#define BXT_DSI_FREQ_SEL_SHIFT 8 > +#define BXT_DSI_FREQ_SEL_MASK (0xF << BXT_DSI_FREQ_SEL_SHIFT) > + > +#define BXT_DSI_PLL_RATIO_MAX 0x7D > +#define BXT_DSI_PLL_RATIO_MIN 0x22 > +#define BXT_DSI_PLL_RATIO_MASK 0xFF > +#define BXT_REF_CLOCK_KHZ 19500 > + > +#define BXT_DSI_PLL_ENABLE 0x46080 > +#define BXT_DSI_PLL_DO_ENABLE (1 << 31) > +#define BXT_DSI_PLL_LOCKED (1 << 30) > + > #define _MIPIA_PORT_CTRL (VLV_DISPLAY_BASE + 0x61190) > #define _MIPIC_PORT_CTRL (VLV_DISPLAY_BASE + 0x61700) > #define MIPI_PORT_CTRL(port) _MIPI_PORT(port, _MIPIA_PORT_CTRL, _MIPIC_PORT_CTRL) > diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c > index b59b828..fb259fb 100644 > --- a/drivers/gpu/drm/i915/intel_dsi.c > +++ b/drivers/gpu/drm/i915/intel_dsi.c > @@ -903,8 +903,8 @@ static void intel_dsi_pre_pll_enable(struct intel_encoder *encoder) > DRM_DEBUG_KMS("\n"); > > intel_dsi_prepare(encoder); > + intel_enable_dsi_pll(encoder); > > - vlv_enable_dsi_pll(encoder); > } > > static enum drm_connector_status > diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h > index 2784ac4..20cfcf07 100644 > --- a/drivers/gpu/drm/i915/intel_dsi.h > +++ b/drivers/gpu/drm/i915/intel_dsi.h > @@ -121,7 +121,7 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder) > return container_of(encoder, struct intel_dsi, base.base); > } > > -extern void vlv_enable_dsi_pll(struct intel_encoder *encoder); > +extern void intel_enable_dsi_pll(struct intel_encoder *encoder); > extern void vlv_disable_dsi_pll(struct intel_encoder *encoder); > extern u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp); > > diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c > index d20cf37..3830a4f 100644 > --- a/drivers/gpu/drm/i915/intel_dsi_pll.c > +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c > @@ -237,7 +237,7 @@ static void vlv_configure_dsi_pll(struct intel_encoder *encoder) > vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, dsi_mnp.dsi_pll_ctrl); > } > > -void vlv_enable_dsi_pll(struct intel_encoder *encoder) > +static void vlv_enable_dsi_pll(struct intel_encoder *encoder) > { > struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; > u32 tmp; > @@ -368,3 +368,96 @@ u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp) > > return pclk; > } > + > +static bool bxt_configure_dsi_pll(struct intel_encoder *encoder) > +{ > + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; > + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); > + u8 dsi_ratio; > + u32 dsi_clk; > + u32 val; > + > + dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format, > + intel_dsi->lane_count); > + > + /* > + * From clock diagram, to get PLL ratio divider, divide double of DSI > + * link rate (i.e., 2*8x=16x frequency value) by ref clock. Make sure to > + * round 'up' the result > + */ > + dsi_ratio = DIV_ROUND_UP(dsi_clk * 2, BXT_REF_CLOCK_KHZ); > + if (dsi_ratio < BXT_DSI_PLL_RATIO_MIN || > + dsi_ratio > BXT_DSI_PLL_RATIO_MAX) { > + DRM_ERROR("Cant get a suitable ratio from DSI PLL ratios\n"); > + return false; > + } > + > + /* > + * Program DSI ratio and Select MIPIC and MIPIA PLL output as 8x > + * Spec says both have to be programmed, even if one is not getting > + * used. Configure MIPI_CLOCK_CTL dividers in modeset > + */ > + val = I915_READ(BXT_DSI_PLL_CTL); > + val &= ~BXT_DSI_PLL_PVD_RATIO_MASK; > + val &= ~BXT_DSI_FREQ_SEL_MASK; > + val &= ~BXT_DSI_PLL_RATIO_MASK; > + val |= (dsi_ratio | BXT_DSIA_16X_BY2 | BXT_DSIC_16X_BY2); > + > + /* As per recommendation from hardware team, > + * Prog PVD ratio =1 if dsi ratio <= 50 > + */ > + if (dsi_ratio <= 50) { > + val &= ~BXT_DSI_PLL_PVD_RATIO_MASK; > + val |= BXT_DSI_PLL_PVD_RATIO_1; > + } > + > + I915_WRITE(BXT_DSI_PLL_CTL, val); > + POSTING_READ(BXT_DSI_PLL_CTL); > + > + return true; > +} > + > +static void bxt_enable_dsi_pll(struct intel_encoder *encoder) > +{ > + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; > + u32 val; > + > + DRM_DEBUG_KMS("\n"); > + > + val = I915_READ(BXT_DSI_PLL_ENABLE); > + > + if (val & BXT_DSI_PLL_DO_ENABLE) { > + WARN(1, "DSI PLL already enabled. Disabling it.\n"); > + val &= ~BXT_DSI_PLL_DO_ENABLE; > + I915_WRITE(BXT_DSI_PLL_ENABLE, val); > + } > + > + /* Configure PLL vales */ > + if (!bxt_configure_dsi_pll(encoder)) { > + DRM_ERROR("Configure DSI PLL failed, abort PLL enable\n"); > + return; > + } > + > + /* Enable DSI PLL */ > + val = I915_READ(BXT_DSI_PLL_ENABLE); > + val |= BXT_DSI_PLL_DO_ENABLE; > + I915_WRITE(BXT_DSI_PLL_ENABLE, val); > + > + /* Timeout and fail if PLL not locked */ > + if (wait_for(I915_READ(BXT_DSI_PLL_ENABLE) & BXT_DSI_PLL_LOCKED, 1)) { > + DRM_ERROR("Timed out waiting for DSI PLL to lock\n"); > + return; > + } > + > + DRM_DEBUG_KMS("DSI PLL locked\n"); > +} > + > +void intel_enable_dsi_pll(struct intel_encoder *encoder) > +{ > + struct drm_device *dev = encoder->base.dev; > + > + if (IS_VALLEYVIEW(dev)) > + vlv_enable_dsi_pll(encoder); > + else if (IS_BROXTON(dev)) > + bxt_enable_dsi_pll(encoder); > +} > -- > 1.7.9.5 > -- Jani Nikula, Intel Open Source Technology Center _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx