Message ID | 1478791400-21756-13-git-send-email-ander.conselvan.de.oliveira@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> On Thu, Nov 10, 2016 at 05:23:17PM +0200, Ander Conselvan de Oliveira wrote: > Geminilake has the same register layout, reference clock and programming > sequence as broxton. The difference is that it doesn't support the 1.5 > divider and has different ratios, but a lot of code can be shared > between the two platforms. > > v2: Rebase (s/broxton/bxt). > > v3: Fix vco calculation in glk_de_pll_vco(). > > Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> > --- > drivers/gpu/drm/i915/intel_display.c | 73 ++++++++++++++++++++++++++++++++---- > 1 file changed, 65 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > index 4069a6e..62cc390 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -124,6 +124,7 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc); > static void intel_modeset_setup_hw_state(struct drm_device *dev); > static void intel_pre_disable_primary_noatomic(struct drm_crtc *crtc); > static int ilk_max_pixel_rate(struct drm_atomic_state *state); > +static int glk_calc_cdclk(int max_pixclk); > static int bxt_calc_cdclk(int max_pixclk); > > struct intel_limit { > @@ -5866,6 +5867,8 @@ static void intel_update_max_cdclk(struct drm_i915_private *dev_priv) > max_cdclk = 308571; > > dev_priv->max_cdclk_freq = skl_calc_cdclk(max_cdclk, vco); > + } else if (IS_GEMINILAKE(dev_priv)) { > + dev_priv->max_cdclk_freq = 316800; > } else if (IS_BROXTON(dev_priv)) { > dev_priv->max_cdclk_freq = 624000; > } else if (IS_BROADWELL(dev_priv)) { > @@ -5953,6 +5956,26 @@ static int bxt_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk) > return dev_priv->cdclk_pll.ref * ratio; > } > > +static int glk_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk) > +{ > + int ratio; > + > + if (cdclk == dev_priv->cdclk_pll.ref) > + return 0; > + > + switch (cdclk) { > + default: > + MISSING_CASE(cdclk); > + case 79200: > + case 158400: > + case 316800: > + ratio = 33; > + break; > + } > + > + return dev_priv->cdclk_pll.ref * ratio; > +} > + > static void bxt_de_pll_disable(struct drm_i915_private *dev_priv) > { > I915_WRITE(BXT_DE_PLL_ENABLE, 0); > @@ -5994,7 +6017,10 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, int cdclk) > u32 val, divider; > int vco, ret; > > - vco = bxt_de_pll_vco(dev_priv, cdclk); > + if (IS_GEMINILAKE(dev_priv)) > + vco = glk_de_pll_vco(dev_priv, cdclk); > + else > + vco = bxt_de_pll_vco(dev_priv, cdclk); > > DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz (VCO %d kHz)\n", cdclk, vco); > > @@ -6007,6 +6033,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, int cdclk) > divider = BXT_CDCLK_CD2X_DIV_SEL_2; > break; > case 3: > + WARN(IS_GEMINILAKE(dev_priv), "Unsupported divider\n"); > divider = BXT_CDCLK_CD2X_DIV_SEL_1_5; > break; > case 2: > @@ -6116,6 +6143,8 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv) > > void bxt_init_cdclk(struct drm_i915_private *dev_priv) > { > + int cdclk; > + > bxt_sanitize_cdclk(dev_priv); > > if (dev_priv->cdclk_freq != 0 && dev_priv->cdclk_pll.vco != 0) > @@ -6126,7 +6155,12 @@ void bxt_init_cdclk(struct drm_i915_private *dev_priv) > * - The initial CDCLK needs to be read from VBT. > * Need to make this change after VBT has changes for BXT. > */ > - bxt_set_cdclk(dev_priv, bxt_calc_cdclk(0)); > + if (IS_GEMINILAKE(dev_priv)) > + cdclk = glk_calc_cdclk(0); > + else > + cdclk = bxt_calc_cdclk(0); > + > + bxt_set_cdclk(dev_priv, cdclk); > } > > void bxt_uninit_cdclk(struct drm_i915_private *dev_priv) > @@ -6552,6 +6586,16 @@ static int valleyview_calc_cdclk(struct drm_i915_private *dev_priv, > return 200000; > } > > +static int glk_calc_cdclk(int max_pixclk) > +{ > + if (max_pixclk > 158400) > + return 316800; > + else if (max_pixclk > 79200) > + return 158400; > + else > + return 79200; > +} > + > static int bxt_calc_cdclk(int max_pixclk) > { > if (max_pixclk > 576000) > @@ -6614,15 +6658,27 @@ static int valleyview_modeset_calc_cdclk(struct drm_atomic_state *state) > > static int bxt_modeset_calc_cdclk(struct drm_atomic_state *state) > { > + struct drm_i915_private *dev_priv = to_i915(state->dev); > int max_pixclk = ilk_max_pixel_rate(state); > struct intel_atomic_state *intel_state = > to_intel_atomic_state(state); > + int cdclk; > > - intel_state->cdclk = intel_state->dev_cdclk = > - bxt_calc_cdclk(max_pixclk); > + if (IS_GEMINILAKE(dev_priv)) > + cdclk = glk_calc_cdclk(max_pixclk); > + else > + cdclk = bxt_calc_cdclk(max_pixclk); > > - if (!intel_state->active_crtcs) > - intel_state->dev_cdclk = bxt_calc_cdclk(0); > + intel_state->cdclk = intel_state->dev_cdclk = cdclk; > + > + if (!intel_state->active_crtcs) { > + if (IS_GEMINILAKE(dev_priv)) > + cdclk = glk_calc_cdclk(0); > + else > + cdclk = bxt_calc_cdclk(0); > + > + intel_state->dev_cdclk = cdclk; > + } > > return 0; > } > @@ -7324,6 +7380,7 @@ static int broxton_get_display_clock_speed(struct drm_i915_private *dev_priv) > div = 2; > break; > case BXT_CDCLK_CD2X_DIV_SEL_1_5: > + WARN(IS_GEMINILAKE(dev_priv), "Unsupported divider\n"); > div = 3; > break; > case BXT_CDCLK_CD2X_DIV_SEL_2: > @@ -16022,7 +16079,7 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv) > if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) > dev_priv->display.get_display_clock_speed = > skylake_get_display_clock_speed; > - else if (IS_BROXTON(dev_priv)) > + else if (IS_GEN9_LP(dev_priv)) > dev_priv->display.get_display_clock_speed = > broxton_get_display_clock_speed; > else if (IS_BROADWELL(dev_priv)) > @@ -16095,7 +16152,7 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv) > valleyview_modeset_commit_cdclk; > dev_priv->display.modeset_calc_cdclk = > valleyview_modeset_calc_cdclk; > - } else if (IS_BROXTON(dev_priv)) { > + } else if (IS_GEN9_LP(dev_priv)) { > dev_priv->display.modeset_commit_cdclk = > bxt_modeset_commit_cdclk; > dev_priv->display.modeset_calc_cdclk = > -- > 2.5.5 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4069a6e..62cc390 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -124,6 +124,7 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc); static void intel_modeset_setup_hw_state(struct drm_device *dev); static void intel_pre_disable_primary_noatomic(struct drm_crtc *crtc); static int ilk_max_pixel_rate(struct drm_atomic_state *state); +static int glk_calc_cdclk(int max_pixclk); static int bxt_calc_cdclk(int max_pixclk); struct intel_limit { @@ -5866,6 +5867,8 @@ static void intel_update_max_cdclk(struct drm_i915_private *dev_priv) max_cdclk = 308571; dev_priv->max_cdclk_freq = skl_calc_cdclk(max_cdclk, vco); + } else if (IS_GEMINILAKE(dev_priv)) { + dev_priv->max_cdclk_freq = 316800; } else if (IS_BROXTON(dev_priv)) { dev_priv->max_cdclk_freq = 624000; } else if (IS_BROADWELL(dev_priv)) { @@ -5953,6 +5956,26 @@ static int bxt_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk) return dev_priv->cdclk_pll.ref * ratio; } +static int glk_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk) +{ + int ratio; + + if (cdclk == dev_priv->cdclk_pll.ref) + return 0; + + switch (cdclk) { + default: + MISSING_CASE(cdclk); + case 79200: + case 158400: + case 316800: + ratio = 33; + break; + } + + return dev_priv->cdclk_pll.ref * ratio; +} + static void bxt_de_pll_disable(struct drm_i915_private *dev_priv) { I915_WRITE(BXT_DE_PLL_ENABLE, 0); @@ -5994,7 +6017,10 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, int cdclk) u32 val, divider; int vco, ret; - vco = bxt_de_pll_vco(dev_priv, cdclk); + if (IS_GEMINILAKE(dev_priv)) + vco = glk_de_pll_vco(dev_priv, cdclk); + else + vco = bxt_de_pll_vco(dev_priv, cdclk); DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz (VCO %d kHz)\n", cdclk, vco); @@ -6007,6 +6033,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, int cdclk) divider = BXT_CDCLK_CD2X_DIV_SEL_2; break; case 3: + WARN(IS_GEMINILAKE(dev_priv), "Unsupported divider\n"); divider = BXT_CDCLK_CD2X_DIV_SEL_1_5; break; case 2: @@ -6116,6 +6143,8 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv) void bxt_init_cdclk(struct drm_i915_private *dev_priv) { + int cdclk; + bxt_sanitize_cdclk(dev_priv); if (dev_priv->cdclk_freq != 0 && dev_priv->cdclk_pll.vco != 0) @@ -6126,7 +6155,12 @@ void bxt_init_cdclk(struct drm_i915_private *dev_priv) * - The initial CDCLK needs to be read from VBT. * Need to make this change after VBT has changes for BXT. */ - bxt_set_cdclk(dev_priv, bxt_calc_cdclk(0)); + if (IS_GEMINILAKE(dev_priv)) + cdclk = glk_calc_cdclk(0); + else + cdclk = bxt_calc_cdclk(0); + + bxt_set_cdclk(dev_priv, cdclk); } void bxt_uninit_cdclk(struct drm_i915_private *dev_priv) @@ -6552,6 +6586,16 @@ static int valleyview_calc_cdclk(struct drm_i915_private *dev_priv, return 200000; } +static int glk_calc_cdclk(int max_pixclk) +{ + if (max_pixclk > 158400) + return 316800; + else if (max_pixclk > 79200) + return 158400; + else + return 79200; +} + static int bxt_calc_cdclk(int max_pixclk) { if (max_pixclk > 576000) @@ -6614,15 +6658,27 @@ static int valleyview_modeset_calc_cdclk(struct drm_atomic_state *state) static int bxt_modeset_calc_cdclk(struct drm_atomic_state *state) { + struct drm_i915_private *dev_priv = to_i915(state->dev); int max_pixclk = ilk_max_pixel_rate(state); struct intel_atomic_state *intel_state = to_intel_atomic_state(state); + int cdclk; - intel_state->cdclk = intel_state->dev_cdclk = - bxt_calc_cdclk(max_pixclk); + if (IS_GEMINILAKE(dev_priv)) + cdclk = glk_calc_cdclk(max_pixclk); + else + cdclk = bxt_calc_cdclk(max_pixclk); - if (!intel_state->active_crtcs) - intel_state->dev_cdclk = bxt_calc_cdclk(0); + intel_state->cdclk = intel_state->dev_cdclk = cdclk; + + if (!intel_state->active_crtcs) { + if (IS_GEMINILAKE(dev_priv)) + cdclk = glk_calc_cdclk(0); + else + cdclk = bxt_calc_cdclk(0); + + intel_state->dev_cdclk = cdclk; + } return 0; } @@ -7324,6 +7380,7 @@ static int broxton_get_display_clock_speed(struct drm_i915_private *dev_priv) div = 2; break; case BXT_CDCLK_CD2X_DIV_SEL_1_5: + WARN(IS_GEMINILAKE(dev_priv), "Unsupported divider\n"); div = 3; break; case BXT_CDCLK_CD2X_DIV_SEL_2: @@ -16022,7 +16079,7 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv) if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) dev_priv->display.get_display_clock_speed = skylake_get_display_clock_speed; - else if (IS_BROXTON(dev_priv)) + else if (IS_GEN9_LP(dev_priv)) dev_priv->display.get_display_clock_speed = broxton_get_display_clock_speed; else if (IS_BROADWELL(dev_priv)) @@ -16095,7 +16152,7 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv) valleyview_modeset_commit_cdclk; dev_priv->display.modeset_calc_cdclk = valleyview_modeset_calc_cdclk; - } else if (IS_BROXTON(dev_priv)) { + } else if (IS_GEN9_LP(dev_priv)) { dev_priv->display.modeset_commit_cdclk = bxt_modeset_commit_cdclk; dev_priv->display.modeset_calc_cdclk =
Geminilake has the same register layout, reference clock and programming sequence as broxton. The difference is that it doesn't support the 1.5 divider and has different ratios, but a lot of code can be shared between the two platforms. v2: Rebase (s/broxton/bxt). v3: Fix vco calculation in glk_de_pll_vco(). Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> --- drivers/gpu/drm/i915/intel_display.c | 73 ++++++++++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 8 deletions(-)