All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Vetter <daniel@ffwll.ch>
To: Dave Airlie <airlied@gmail.com>
Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
Subject: Re: [Intel-gfx] [PATCH 3/4] drm/i915: refactor pll code out into intel_clock.c
Date: Wed, 9 Dec 2020 11:55:44 +0100	[thread overview]
Message-ID: <CAKMK7uH-NiwDabhJa6nkQdgBLjWzEwbOkaJ1vPHQZgUSf=Z2FQ@mail.gmail.com> (raw)
In-Reply-To: <20201209042144.2281-4-airlied@gmail.com>

On Wed, Dec 9, 2020 at 5:22 AM Dave Airlie <airlied@gmail.com> wrote:
>
> From: Dave Airlie <airlied@redhat.com>
>
> This pulls a large chunk of the pll calculation code out of
> intel_display.c to a new file.
>
> One function makse sense to be an inline, otherwise this
> is pretty much a straight copy cover. also all the
> remaining hooks for g45 and older end up the same now.
>
> Fixed one , instead of ; error in chv_find_best_dpll.

Maybe split that one out?

> Signed-off-by: Dave Airlie <airlied@redhat.com>
> ---
>  drivers/gpu/drm/i915/Makefile                 |    1 +
>  drivers/gpu/drm/i915/display/intel_clock.c    | 1370 ++++++++++++++++
>  drivers/gpu/drm/i915/display/intel_display.c  | 1392 +----------------
>  drivers/gpu/drm/i915/display/intel_display.h  |   13 +-
>  .../drm/i915/display/intel_display_types.h    |    5 +
>  5 files changed, 1398 insertions(+), 1383 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/display/intel_clock.c
>
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index ffec257702af..8b357c212ae2 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -193,6 +193,7 @@ i915-y += \
>         display/intel_bios.o \
>         display/intel_bw.o \
>         display/intel_cdclk.o \
> +       display/intel_clock.o \

I'd call this intel_dpll_legacy.c, to be more in line with the new
generation stuff which is in intel_dpll_mgr.c which is where all the
new code since hsw hangs out (except for chv, that's still derived
from the old ones).

Aside from the repaint looks reasonable to me.
-Daniel

>         display/intel_color.o \
>         display/intel_combo_phy.o \
>         display/intel_connector.o \
> diff --git a/drivers/gpu/drm/i915/display/intel_clock.c b/drivers/gpu/drm/i915/display/intel_clock.c
> new file mode 100644
> index 000000000000..75819c1da039
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/display/intel_clock.c
> @@ -0,0 +1,1370 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2020 Intel Corporation
> + */
> +#include <linux/kernel.h>
> +#include "intel_display_types.h"
> +#include "intel_display.h"
> +#include "intel_lvds.h"
> +#include "intel_panel.h"
> +
> +static bool intel_panel_use_ssc(struct drm_i915_private *dev_priv)
> +{
> +       if (dev_priv->params.panel_use_ssc >= 0)
> +               return dev_priv->params.panel_use_ssc != 0;
> +       return dev_priv->vbt.lvds_use_ssc
> +               && !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE);
> +}
> +
> +struct intel_limit {
> +       struct {
> +               int min, max;
> +       } dot, vco, n, m, m1, m2, p, p1;
> +
> +       struct {
> +               int dot_limit;
> +               int p2_slow, p2_fast;
> +       } p2;
> +};
> +static const struct intel_limit intel_limits_i8xx_dac = {
> +       .dot = { .min = 25000, .max = 350000 },
> +       .vco = { .min = 908000, .max = 1512000 },
> +       .n = { .min = 2, .max = 16 },
> +       .m = { .min = 96, .max = 140 },
> +       .m1 = { .min = 18, .max = 26 },
> +       .m2 = { .min = 6, .max = 16 },
> +       .p = { .min = 4, .max = 128 },
> +       .p1 = { .min = 2, .max = 33 },
> +       .p2 = { .dot_limit = 165000,
> +               .p2_slow = 4, .p2_fast = 2 },
> +};
> +
> +static const struct intel_limit intel_limits_i8xx_dvo = {
> +       .dot = { .min = 25000, .max = 350000 },
> +       .vco = { .min = 908000, .max = 1512000 },
> +       .n = { .min = 2, .max = 16 },
> +       .m = { .min = 96, .max = 140 },
> +       .m1 = { .min = 18, .max = 26 },
> +       .m2 = { .min = 6, .max = 16 },
> +       .p = { .min = 4, .max = 128 },
> +       .p1 = { .min = 2, .max = 33 },
> +       .p2 = { .dot_limit = 165000,
> +               .p2_slow = 4, .p2_fast = 4 },
> +};
> +
> +static const struct intel_limit intel_limits_i8xx_lvds = {
> +       .dot = { .min = 25000, .max = 350000 },
> +       .vco = { .min = 908000, .max = 1512000 },
> +       .n = { .min = 2, .max = 16 },
> +       .m = { .min = 96, .max = 140 },
> +       .m1 = { .min = 18, .max = 26 },
> +       .m2 = { .min = 6, .max = 16 },
> +       .p = { .min = 4, .max = 128 },
> +       .p1 = { .min = 1, .max = 6 },
> +       .p2 = { .dot_limit = 165000,
> +               .p2_slow = 14, .p2_fast = 7 },
> +};
> +
> +static const struct intel_limit intel_limits_i9xx_sdvo = {
> +       .dot = { .min = 20000, .max = 400000 },
> +       .vco = { .min = 1400000, .max = 2800000 },
> +       .n = { .min = 1, .max = 6 },
> +       .m = { .min = 70, .max = 120 },
> +       .m1 = { .min = 8, .max = 18 },
> +       .m2 = { .min = 3, .max = 7 },
> +       .p = { .min = 5, .max = 80 },
> +       .p1 = { .min = 1, .max = 8 },
> +       .p2 = { .dot_limit = 200000,
> +               .p2_slow = 10, .p2_fast = 5 },
> +};
> +
> +static const struct intel_limit intel_limits_i9xx_lvds = {
> +       .dot = { .min = 20000, .max = 400000 },
> +       .vco = { .min = 1400000, .max = 2800000 },
> +       .n = { .min = 1, .max = 6 },
> +       .m = { .min = 70, .max = 120 },
> +       .m1 = { .min = 8, .max = 18 },
> +       .m2 = { .min = 3, .max = 7 },
> +       .p = { .min = 7, .max = 98 },
> +       .p1 = { .min = 1, .max = 8 },
> +       .p2 = { .dot_limit = 112000,
> +               .p2_slow = 14, .p2_fast = 7 },
> +};
> +
> +
> +static const struct intel_limit intel_limits_g4x_sdvo = {
> +       .dot = { .min = 25000, .max = 270000 },
> +       .vco = { .min = 1750000, .max = 3500000},
> +       .n = { .min = 1, .max = 4 },
> +       .m = { .min = 104, .max = 138 },
> +       .m1 = { .min = 17, .max = 23 },
> +       .m2 = { .min = 5, .max = 11 },
> +       .p = { .min = 10, .max = 30 },
> +       .p1 = { .min = 1, .max = 3},
> +       .p2 = { .dot_limit = 270000,
> +               .p2_slow = 10,
> +               .p2_fast = 10
> +       },
> +};
> +
> +static const struct intel_limit intel_limits_g4x_hdmi = {
> +       .dot = { .min = 22000, .max = 400000 },
> +       .vco = { .min = 1750000, .max = 3500000},
> +       .n = { .min = 1, .max = 4 },
> +       .m = { .min = 104, .max = 138 },
> +       .m1 = { .min = 16, .max = 23 },
> +       .m2 = { .min = 5, .max = 11 },
> +       .p = { .min = 5, .max = 80 },
> +       .p1 = { .min = 1, .max = 8},
> +       .p2 = { .dot_limit = 165000,
> +               .p2_slow = 10, .p2_fast = 5 },
> +};
> +
> +static const struct intel_limit intel_limits_g4x_single_channel_lvds = {
> +       .dot = { .min = 20000, .max = 115000 },
> +       .vco = { .min = 1750000, .max = 3500000 },
> +       .n = { .min = 1, .max = 3 },
> +       .m = { .min = 104, .max = 138 },
> +       .m1 = { .min = 17, .max = 23 },
> +       .m2 = { .min = 5, .max = 11 },
> +       .p = { .min = 28, .max = 112 },
> +       .p1 = { .min = 2, .max = 8 },
> +       .p2 = { .dot_limit = 0,
> +               .p2_slow = 14, .p2_fast = 14
> +       },
> +};
> +
> +static const struct intel_limit intel_limits_g4x_dual_channel_lvds = {
> +       .dot = { .min = 80000, .max = 224000 },
> +       .vco = { .min = 1750000, .max = 3500000 },
> +       .n = { .min = 1, .max = 3 },
> +       .m = { .min = 104, .max = 138 },
> +       .m1 = { .min = 17, .max = 23 },
> +       .m2 = { .min = 5, .max = 11 },
> +       .p = { .min = 14, .max = 42 },
> +       .p1 = { .min = 2, .max = 6 },
> +       .p2 = { .dot_limit = 0,
> +               .p2_slow = 7, .p2_fast = 7
> +       },
> +};
> +
> +static const struct intel_limit pnv_limits_sdvo = {
> +       .dot = { .min = 20000, .max = 400000},
> +       .vco = { .min = 1700000, .max = 3500000 },
> +       /* Pineview's Ncounter is a ring counter */
> +       .n = { .min = 3, .max = 6 },
> +       .m = { .min = 2, .max = 256 },
> +       /* Pineview only has one combined m divider, which we treat as m2. */
> +       .m1 = { .min = 0, .max = 0 },
> +       .m2 = { .min = 0, .max = 254 },
> +       .p = { .min = 5, .max = 80 },
> +       .p1 = { .min = 1, .max = 8 },
> +       .p2 = { .dot_limit = 200000,
> +               .p2_slow = 10, .p2_fast = 5 },
> +};
> +
> +static const struct intel_limit pnv_limits_lvds = {
> +       .dot = { .min = 20000, .max = 400000 },
> +       .vco = { .min = 1700000, .max = 3500000 },
> +       .n = { .min = 3, .max = 6 },
> +       .m = { .min = 2, .max = 256 },
> +       .m1 = { .min = 0, .max = 0 },
> +       .m2 = { .min = 0, .max = 254 },
> +       .p = { .min = 7, .max = 112 },
> +       .p1 = { .min = 1, .max = 8 },
> +       .p2 = { .dot_limit = 112000,
> +               .p2_slow = 14, .p2_fast = 14 },
> +};
> +
> +/* Ironlake / Sandybridge
> + *
> + * We calculate clock using (register_value + 2) for N/M1/M2, so here
> + * the range value for them is (actual_value - 2).
> + */
> +static const struct intel_limit ilk_limits_dac = {
> +       .dot = { .min = 25000, .max = 350000 },
> +       .vco = { .min = 1760000, .max = 3510000 },
> +       .n = { .min = 1, .max = 5 },
> +       .m = { .min = 79, .max = 127 },
> +       .m1 = { .min = 12, .max = 22 },
> +       .m2 = { .min = 5, .max = 9 },
> +       .p = { .min = 5, .max = 80 },
> +       .p1 = { .min = 1, .max = 8 },
> +       .p2 = { .dot_limit = 225000,
> +               .p2_slow = 10, .p2_fast = 5 },
> +};
> +
> +static const struct intel_limit ilk_limits_single_lvds = {
> +       .dot = { .min = 25000, .max = 350000 },
> +       .vco = { .min = 1760000, .max = 3510000 },
> +       .n = { .min = 1, .max = 3 },
> +       .m = { .min = 79, .max = 118 },
> +       .m1 = { .min = 12, .max = 22 },
> +       .m2 = { .min = 5, .max = 9 },
> +       .p = { .min = 28, .max = 112 },
> +       .p1 = { .min = 2, .max = 8 },
> +       .p2 = { .dot_limit = 225000,
> +               .p2_slow = 14, .p2_fast = 14 },
> +};
> +
> +static const struct intel_limit ilk_limits_dual_lvds = {
> +       .dot = { .min = 25000, .max = 350000 },
> +       .vco = { .min = 1760000, .max = 3510000 },
> +       .n = { .min = 1, .max = 3 },
> +       .m = { .min = 79, .max = 127 },
> +       .m1 = { .min = 12, .max = 22 },
> +       .m2 = { .min = 5, .max = 9 },
> +       .p = { .min = 14, .max = 56 },
> +       .p1 = { .min = 2, .max = 8 },
> +       .p2 = { .dot_limit = 225000,
> +               .p2_slow = 7, .p2_fast = 7 },
> +};
> +
> +/* LVDS 100mhz refclk limits. */
> +static const struct intel_limit ilk_limits_single_lvds_100m = {
> +       .dot = { .min = 25000, .max = 350000 },
> +       .vco = { .min = 1760000, .max = 3510000 },
> +       .n = { .min = 1, .max = 2 },
> +       .m = { .min = 79, .max = 126 },
> +       .m1 = { .min = 12, .max = 22 },
> +       .m2 = { .min = 5, .max = 9 },
> +       .p = { .min = 28, .max = 112 },
> +       .p1 = { .min = 2, .max = 8 },
> +       .p2 = { .dot_limit = 225000,
> +               .p2_slow = 14, .p2_fast = 14 },
> +};
> +
> +static const struct intel_limit ilk_limits_dual_lvds_100m = {
> +       .dot = { .min = 25000, .max = 350000 },
> +       .vco = { .min = 1760000, .max = 3510000 },
> +       .n = { .min = 1, .max = 3 },
> +       .m = { .min = 79, .max = 126 },
> +       .m1 = { .min = 12, .max = 22 },
> +       .m2 = { .min = 5, .max = 9 },
> +       .p = { .min = 14, .max = 42 },
> +       .p1 = { .min = 2, .max = 6 },
> +       .p2 = { .dot_limit = 225000,
> +               .p2_slow = 7, .p2_fast = 7 },
> +};
> +
> +static const struct intel_limit intel_limits_vlv = {
> +        /*
> +         * These are the data rate limits (measured in fast clocks)
> +         * since those are the strictest limits we have. The fast
> +         * clock and actual rate limits are more relaxed, so checking
> +         * them would make no difference.
> +         */
> +       .dot = { .min = 25000 * 5, .max = 270000 * 5 },
> +       .vco = { .min = 4000000, .max = 6000000 },
> +       .n = { .min = 1, .max = 7 },
> +       .m1 = { .min = 2, .max = 3 },
> +       .m2 = { .min = 11, .max = 156 },
> +       .p1 = { .min = 2, .max = 3 },
> +       .p2 = { .p2_slow = 2, .p2_fast = 20 }, /* slow=min, fast=max */
> +};
> +
> +static const struct intel_limit intel_limits_chv = {
> +       /*
> +        * These are the data rate limits (measured in fast clocks)
> +        * since those are the strictest limits we have.  The fast
> +        * clock and actual rate limits are more relaxed, so checking
> +        * them would make no difference.
> +        */
> +       .dot = { .min = 25000 * 5, .max = 540000 * 5},
> +       .vco = { .min = 4800000, .max = 6480000 },
> +       .n = { .min = 1, .max = 1 },
> +       .m1 = { .min = 2, .max = 2 },
> +       .m2 = { .min = 24 << 22, .max = 175 << 22 },
> +       .p1 = { .min = 2, .max = 4 },
> +       .p2 = { .p2_slow = 1, .p2_fast = 14 },
> +};
> +
> +static const struct intel_limit intel_limits_bxt = {
> +       /* FIXME: find real dot limits */
> +       .dot = { .min = 0, .max = INT_MAX },
> +       .vco = { .min = 4800000, .max = 6700000 },
> +       .n = { .min = 1, .max = 1 },
> +       .m1 = { .min = 2, .max = 2 },
> +       /* FIXME: find real m2 limits */
> +       .m2 = { .min = 2 << 22, .max = 255 << 22 },
> +       .p1 = { .min = 2, .max = 4 },
> +       .p2 = { .p2_slow = 1, .p2_fast = 20 },
> +};
> +
> +/*
> + * Platform specific helpers to calculate the port PLL loopback- (clock.m),
> + * and post-divider (clock.p) values, pre- (clock.vco) and post-divided fast
> + * (clock.dot) clock rates. This fast dot clock is fed to the port's IO logic.
> + * The helpers' return value is the rate of the clock that is fed to the
> + * display engine's pipe which can be the above fast dot clock rate or a
> + * divided-down version of it.
> + */
> +/* m1 is reserved as 0 in Pineview, n is a ring counter */
> +int pnv_calc_dpll_params(int refclk, struct dpll *clock)
> +{
> +       clock->m = clock->m2 + 2;
> +       clock->p = clock->p1 * clock->p2;
> +       if (WARN_ON(clock->n == 0 || clock->p == 0))
> +               return 0;
> +       clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n);
> +       clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
> +
> +       return clock->dot;
> +}
> +
> +static u32 i9xx_dpll_compute_m(struct dpll *dpll)
> +{
> +       return 5 * (dpll->m1 + 2) + (dpll->m2 + 2);
> +}
> +
> +int i9xx_calc_dpll_params(int refclk, struct dpll *clock)
> +{
> +       clock->m = i9xx_dpll_compute_m(clock);
> +       clock->p = clock->p1 * clock->p2;
> +       if (WARN_ON(clock->n + 2 == 0 || clock->p == 0))
> +               return 0;
> +       clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n + 2);
> +       clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
> +
> +       return clock->dot;
> +}
> +
> +int vlv_calc_dpll_params(int refclk, struct dpll *clock)
> +{
> +       clock->m = clock->m1 * clock->m2;
> +       clock->p = clock->p1 * clock->p2;
> +       if (WARN_ON(clock->n == 0 || clock->p == 0))
> +               return 0;
> +       clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n);
> +       clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
> +
> +       return clock->dot / 5;
> +}
> +
> +int chv_calc_dpll_params(int refclk, struct dpll *clock)
> +{
> +       clock->m = clock->m1 * clock->m2;
> +       clock->p = clock->p1 * clock->p2;
> +       if (WARN_ON(clock->n == 0 || clock->p == 0))
> +               return 0;
> +       clock->vco = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(refclk, clock->m),
> +                                          clock->n << 22);
> +       clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
> +
> +       return clock->dot / 5;
> +}
> +
> +/*
> + * Returns whether the given set of divisors are valid for a given refclk with
> + * the given connectors.
> + */
> +static bool intel_pll_is_valid(struct drm_i915_private *dev_priv,
> +                              const struct intel_limit *limit,
> +                              const struct dpll *clock)
> +{
> +       if (clock->n < limit->n.min || limit->n.max < clock->n)
> +               return false;
> +       if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
> +               return false;
> +       if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2)
> +               return false;
> +       if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
> +               return false;
> +
> +       if (!IS_PINEVIEW(dev_priv) && !IS_VALLEYVIEW(dev_priv) &&
> +           !IS_CHERRYVIEW(dev_priv) && !IS_GEN9_LP(dev_priv))
> +               if (clock->m1 <= clock->m2)
> +                       return false;
> +
> +       if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) &&
> +           !IS_GEN9_LP(dev_priv)) {
> +               if (clock->p < limit->p.min || limit->p.max < clock->p)
> +                       return false;
> +               if (clock->m < limit->m.min || limit->m.max < clock->m)
> +                       return false;
> +       }
> +
> +       if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
> +               return false;
> +       /* XXX: We may need to be checking "Dot clock" depending on the multiplier,
> +        * connector, etc., rather than just a single range.
> +        */
> +       if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
> +               return false;
> +
> +       return true;
> +}
> +
> +static int
> +i9xx_select_p2_div(const struct intel_limit *limit,
> +                  const struct intel_crtc_state *crtc_state,
> +                  int target)
> +{
> +       struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> +
> +       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> +               /*
> +                * For LVDS just rely on its current settings for dual-channel.
> +                * We haven't figured out how to reliably set up different
> +                * single/dual channel state, if we even can.
> +                */
> +               if (intel_is_dual_link_lvds(dev_priv))
> +                       return limit->p2.p2_fast;
> +               else
> +                       return limit->p2.p2_slow;
> +       } else {
> +               if (target < limit->p2.dot_limit)
> +                       return limit->p2.p2_slow;
> +               else
> +                       return limit->p2.p2_fast;
> +       }
> +}
> +
> +/*
> + * Returns a set of divisors for the desired target clock with the given
> + * refclk, or FALSE.  The returned values represent the clock equation:
> + * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
> + *
> + * Target and reference clocks are specified in kHz.
> + *
> + * If match_clock is provided, then best_clock P divider must match the P
> + * divider from @match_clock used for LVDS downclocking.
> + */
> +static bool
> +i9xx_find_best_dpll(const struct intel_limit *limit,
> +                   struct intel_crtc_state *crtc_state,
> +                   int target, int refclk, struct dpll *match_clock,
> +                   struct dpll *best_clock)
> +{
> +       struct drm_device *dev = crtc_state->uapi.crtc->dev;
> +       struct dpll clock;
> +       int err = target;
> +
> +       memset(best_clock, 0, sizeof(*best_clock));
> +
> +       clock.p2 = i9xx_select_p2_div(limit, crtc_state, target);
> +
> +       for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
> +            clock.m1++) {
> +               for (clock.m2 = limit->m2.min;
> +                    clock.m2 <= limit->m2.max; clock.m2++) {
> +                       if (clock.m2 >= clock.m1)
> +                               break;
> +                       for (clock.n = limit->n.min;
> +                            clock.n <= limit->n.max; clock.n++) {
> +                               for (clock.p1 = limit->p1.min;
> +                                       clock.p1 <= limit->p1.max; clock.p1++) {
> +                                       int this_err;
> +
> +                                       i9xx_calc_dpll_params(refclk, &clock);
> +                                       if (!intel_pll_is_valid(to_i915(dev),
> +                                                               limit,
> +                                                               &clock))
> +                                               continue;
> +                                       if (match_clock &&
> +                                           clock.p != match_clock->p)
> +                                               continue;
> +
> +                                       this_err = abs(clock.dot - target);
> +                                       if (this_err < err) {
> +                                               *best_clock = clock;
> +                                               err = this_err;
> +                                       }
> +                               }
> +                       }
> +               }
> +       }
> +
> +       return (err != target);
> +}
> +
> +/*
> + * Returns a set of divisors for the desired target clock with the given
> + * refclk, or FALSE.  The returned values represent the clock equation:
> + * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
> + *
> + * Target and reference clocks are specified in kHz.
> + *
> + * If match_clock is provided, then best_clock P divider must match the P
> + * divider from @match_clock used for LVDS downclocking.
> + */
> +static bool
> +pnv_find_best_dpll(const struct intel_limit *limit,
> +                  struct intel_crtc_state *crtc_state,
> +                  int target, int refclk, struct dpll *match_clock,
> +                  struct dpll *best_clock)
> +{
> +       struct drm_device *dev = crtc_state->uapi.crtc->dev;
> +       struct dpll clock;
> +       int err = target;
> +
> +       memset(best_clock, 0, sizeof(*best_clock));
> +
> +       clock.p2 = i9xx_select_p2_div(limit, crtc_state, target);
> +
> +       for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
> +            clock.m1++) {
> +               for (clock.m2 = limit->m2.min;
> +                    clock.m2 <= limit->m2.max; clock.m2++) {
> +                       for (clock.n = limit->n.min;
> +                            clock.n <= limit->n.max; clock.n++) {
> +                               for (clock.p1 = limit->p1.min;
> +                                       clock.p1 <= limit->p1.max; clock.p1++) {
> +                                       int this_err;
> +
> +                                       pnv_calc_dpll_params(refclk, &clock);
> +                                       if (!intel_pll_is_valid(to_i915(dev),
> +                                                               limit,
> +                                                               &clock))
> +                                               continue;
> +                                       if (match_clock &&
> +                                           clock.p != match_clock->p)
> +                                               continue;
> +
> +                                       this_err = abs(clock.dot - target);
> +                                       if (this_err < err) {
> +                                               *best_clock = clock;
> +                                               err = this_err;
> +                                       }
> +                               }
> +                       }
> +               }
> +       }
> +
> +       return (err != target);
> +}
> +
> +/*
> + * Returns a set of divisors for the desired target clock with the given
> + * refclk, or FALSE.  The returned values represent the clock equation:
> + * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
> + *
> + * Target and reference clocks are specified in kHz.
> + *
> + * If match_clock is provided, then best_clock P divider must match the P
> + * divider from @match_clock used for LVDS downclocking.
> + */
> +static bool
> +g4x_find_best_dpll(const struct intel_limit *limit,
> +                  struct intel_crtc_state *crtc_state,
> +                  int target, int refclk, struct dpll *match_clock,
> +                  struct dpll *best_clock)
> +{
> +       struct drm_device *dev = crtc_state->uapi.crtc->dev;
> +       struct dpll clock;
> +       int max_n;
> +       bool found = false;
> +       /* approximately equals target * 0.00585 */
> +       int err_most = (target >> 8) + (target >> 9);
> +
> +       memset(best_clock, 0, sizeof(*best_clock));
> +
> +       clock.p2 = i9xx_select_p2_div(limit, crtc_state, target);
> +
> +       max_n = limit->n.max;
> +       /* based on hardware requirement, prefer smaller n to precision */
> +       for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
> +               /* based on hardware requirement, prefere larger m1,m2 */
> +               for (clock.m1 = limit->m1.max;
> +                    clock.m1 >= limit->m1.min; clock.m1--) {
> +                       for (clock.m2 = limit->m2.max;
> +                            clock.m2 >= limit->m2.min; clock.m2--) {
> +                               for (clock.p1 = limit->p1.max;
> +                                    clock.p1 >= limit->p1.min; clock.p1--) {
> +                                       int this_err;
> +
> +                                       i9xx_calc_dpll_params(refclk, &clock);
> +                                       if (!intel_pll_is_valid(to_i915(dev),
> +                                                               limit,
> +                                                               &clock))
> +                                               continue;
> +
> +                                       this_err = abs(clock.dot - target);
> +                                       if (this_err < err_most) {
> +                                               *best_clock = clock;
> +                                               err_most = this_err;
> +                                               max_n = clock.n;
> +                                               found = true;
> +                                       }
> +                               }
> +                       }
> +               }
> +       }
> +       return found;
> +}
> +
> +/*
> + * Check if the calculated PLL configuration is more optimal compared to the
> + * best configuration and error found so far. Return the calculated error.
> + */
> +static bool vlv_PLL_is_optimal(struct drm_device *dev, int target_freq,
> +                              const struct dpll *calculated_clock,
> +                              const struct dpll *best_clock,
> +                              unsigned int best_error_ppm,
> +                              unsigned int *error_ppm)
> +{
> +       /*
> +        * For CHV ignore the error and consider only the P value.
> +        * Prefer a bigger P value based on HW requirements.
> +        */
> +       if (IS_CHERRYVIEW(to_i915(dev))) {
> +               *error_ppm = 0;
> +
> +               return calculated_clock->p > best_clock->p;
> +       }
> +
> +       if (drm_WARN_ON_ONCE(dev, !target_freq))
> +               return false;
> +
> +       *error_ppm = div_u64(1000000ULL *
> +                               abs(target_freq - calculated_clock->dot),
> +                            target_freq);
> +       /*
> +        * Prefer a better P value over a better (smaller) error if the error
> +        * is small. Ensure this preference for future configurations too by
> +        * setting the error to 0.
> +        */
> +       if (*error_ppm < 100 && calculated_clock->p > best_clock->p) {
> +               *error_ppm = 0;
> +
> +               return true;
> +       }
> +
> +       return *error_ppm + 10 < best_error_ppm;
> +}
> +
> +/*
> + * Returns a set of divisors for the desired target clock with the given
> + * refclk, or FALSE.  The returned values represent the clock equation:
> + * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
> + */
> +static bool
> +vlv_find_best_dpll(const struct intel_limit *limit,
> +                  struct intel_crtc_state *crtc_state,
> +                  int target, int refclk, struct dpll *match_clock,
> +                  struct dpll *best_clock)
> +{
> +       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +       struct drm_device *dev = crtc->base.dev;
> +       struct dpll clock;
> +       unsigned int bestppm = 1000000;
> +       /* min update 19.2 MHz */
> +       int max_n = min(limit->n.max, refclk / 19200);
> +       bool found = false;
> +
> +       target *= 5; /* fast clock */
> +
> +       memset(best_clock, 0, sizeof(*best_clock));
> +
> +       /* based on hardware requirement, prefer smaller n to precision */
> +       for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
> +               for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
> +                       for (clock.p2 = limit->p2.p2_fast; clock.p2 >= limit->p2.p2_slow;
> +                            clock.p2 -= clock.p2 > 10 ? 2 : 1) {
> +                               clock.p = clock.p1 * clock.p2;
> +                               /* based on hardware requirement, prefer bigger m1,m2 values */
> +                               for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
> +                                       unsigned int ppm;
> +
> +                                       clock.m2 = DIV_ROUND_CLOSEST(target * clock.p * clock.n,
> +                                                                    refclk * clock.m1);
> +
> +                                       vlv_calc_dpll_params(refclk, &clock);
> +
> +                                       if (!intel_pll_is_valid(to_i915(dev),
> +                                                               limit,
> +                                                               &clock))
> +                                               continue;
> +
> +                                       if (!vlv_PLL_is_optimal(dev, target,
> +                                                               &clock,
> +                                                               best_clock,
> +                                                               bestppm, &ppm))
> +                                               continue;
> +
> +                                       *best_clock = clock;
> +                                       bestppm = ppm;
> +                                       found = true;
> +                               }
> +                       }
> +               }
> +       }
> +
> +       return found;
> +}
> +
> +/*
> + * Returns a set of divisors for the desired target clock with the given
> + * refclk, or FALSE.  The returned values represent the clock equation:
> + * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
> + */
> +static bool
> +chv_find_best_dpll(const struct intel_limit *limit,
> +                  struct intel_crtc_state *crtc_state,
> +                  int target, int refclk, struct dpll *match_clock,
> +                  struct dpll *best_clock)
> +{
> +       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +       struct drm_device *dev = crtc->base.dev;
> +       unsigned int best_error_ppm;
> +       struct dpll clock;
> +       u64 m2;
> +       int found = false;
> +
> +       memset(best_clock, 0, sizeof(*best_clock));
> +       best_error_ppm = 1000000;
> +
> +       /*
> +        * Based on hardware doc, the n always set to 1, and m1 always
> +        * set to 2.  If requires to support 200Mhz refclk, we need to
> +        * revisit this because n may not 1 anymore.
> +        */
> +       clock.n = 1;
> +       clock.m1 = 2;
> +       target *= 5;    /* fast clock */
> +
> +       for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
> +               for (clock.p2 = limit->p2.p2_fast;
> +                               clock.p2 >= limit->p2.p2_slow;
> +                               clock.p2 -= clock.p2 > 10 ? 2 : 1) {
> +                       unsigned int error_ppm;
> +
> +                       clock.p = clock.p1 * clock.p2;
> +
> +                       m2 = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(target, clock.p * clock.n) << 22,
> +                                                  refclk * clock.m1);
> +
> +                       if (m2 > INT_MAX/clock.m1)
> +                               continue;
> +
> +                       clock.m2 = m2;
> +
> +                       chv_calc_dpll_params(refclk, &clock);
> +
> +                       if (!intel_pll_is_valid(to_i915(dev), limit, &clock))
> +                               continue;
> +
> +                       if (!vlv_PLL_is_optimal(dev, target, &clock, best_clock,
> +                                               best_error_ppm, &error_ppm))
> +                               continue;
> +
> +                       *best_clock = clock;
> +                       best_error_ppm = error_ppm;
> +                       found = true;
> +               }
> +       }
> +
> +       return found;
> +}
> +
> +bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state,
> +                       struct dpll *best_clock)
> +{
> +       int refclk = 100000;
> +       const struct intel_limit *limit = &intel_limits_bxt;
> +
> +       return chv_find_best_dpll(limit, crtc_state,
> +                                 crtc_state->port_clock, refclk,
> +                                 NULL, best_clock);
> +}
> +
> +static u32 pnv_dpll_compute_fp(struct dpll *dpll)
> +{
> +       return (1 << dpll->n) << 16 | dpll->m2;
> +}
> +
> +static void i9xx_update_pll_dividers(struct intel_crtc *crtc,
> +                                    struct intel_crtc_state *crtc_state,
> +                                    struct dpll *reduced_clock)
> +{
> +       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +       u32 fp, fp2 = 0;
> +
> +       if (IS_PINEVIEW(dev_priv)) {
> +               fp = pnv_dpll_compute_fp(&crtc_state->dpll);
> +               if (reduced_clock)
> +                       fp2 = pnv_dpll_compute_fp(reduced_clock);
> +       } else {
> +               fp = i9xx_dpll_compute_fp(&crtc_state->dpll);
> +               if (reduced_clock)
> +                       fp2 = i9xx_dpll_compute_fp(reduced_clock);
> +       }
> +
> +       crtc_state->dpll_hw_state.fp0 = fp;
> +
> +       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) &&
> +           reduced_clock) {
> +               crtc_state->dpll_hw_state.fp1 = fp2;
> +       } else {
> +               crtc_state->dpll_hw_state.fp1 = fp;
> +       }
> +}
> +
> +static void i9xx_compute_dpll(struct intel_crtc *crtc,
> +                             struct intel_crtc_state *crtc_state,
> +                             struct dpll *reduced_clock)
> +{
> +       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +       u32 dpll;
> +       struct dpll *clock = &crtc_state->dpll;
> +
> +       i9xx_update_pll_dividers(crtc, crtc_state, reduced_clock);
> +
> +       dpll = DPLL_VGA_MODE_DIS;
> +
> +       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS))
> +               dpll |= DPLLB_MODE_LVDS;
> +       else
> +               dpll |= DPLLB_MODE_DAC_SERIAL;
> +
> +       if (IS_I945G(dev_priv) || IS_I945GM(dev_priv) ||
> +           IS_G33(dev_priv) || IS_PINEVIEW(dev_priv)) {
> +               dpll |= (crtc_state->pixel_multiplier - 1)
> +                       << SDVO_MULTIPLIER_SHIFT_HIRES;
> +       }
> +
> +       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO) ||
> +           intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
> +               dpll |= DPLL_SDVO_HIGH_SPEED;
> +
> +       if (intel_crtc_has_dp_encoder(crtc_state))
> +               dpll |= DPLL_SDVO_HIGH_SPEED;
> +
> +       /* compute bitmask from p1 value */
> +       if (IS_PINEVIEW(dev_priv))
> +               dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW;
> +       else {
> +               dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
> +               if (IS_G4X(dev_priv) && reduced_clock)
> +                       dpll |= (1 << (reduced_clock->p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
> +       }
> +       switch (clock->p2) {
> +       case 5:
> +               dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
> +               break;
> +       case 7:
> +               dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
> +               break;
> +       case 10:
> +               dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
> +               break;
> +       case 14:
> +               dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
> +               break;
> +       }
> +       if (INTEL_GEN(dev_priv) >= 4)
> +               dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
> +
> +       if (crtc_state->sdvo_tv_clock)
> +               dpll |= PLL_REF_INPUT_TVCLKINBC;
> +       else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) &&
> +                intel_panel_use_ssc(dev_priv))
> +               dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
> +       else
> +               dpll |= PLL_REF_INPUT_DREFCLK;
> +
> +       dpll |= DPLL_VCO_ENABLE;
> +       crtc_state->dpll_hw_state.dpll = dpll;
> +
> +       if (INTEL_GEN(dev_priv) >= 4) {
> +               u32 dpll_md = (crtc_state->pixel_multiplier - 1)
> +                       << DPLL_MD_UDI_MULTIPLIER_SHIFT;
> +               crtc_state->dpll_hw_state.dpll_md = dpll_md;
> +       }
> +}
> +
> +static void i8xx_compute_dpll(struct intel_crtc *crtc,
> +                             struct intel_crtc_state *crtc_state,
> +                             struct dpll *reduced_clock)
> +{
> +       struct drm_device *dev = crtc->base.dev;
> +       struct drm_i915_private *dev_priv = to_i915(dev);
> +       u32 dpll;
> +       struct dpll *clock = &crtc_state->dpll;
> +
> +       i9xx_update_pll_dividers(crtc, crtc_state, reduced_clock);
> +
> +       dpll = DPLL_VGA_MODE_DIS;
> +
> +       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> +               dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
> +       } else {
> +               if (clock->p1 == 2)
> +                       dpll |= PLL_P1_DIVIDE_BY_TWO;
> +               else
> +                       dpll |= (clock->p1 - 2) << DPLL_FPA01_P1_POST_DIV_SHIFT;
> +               if (clock->p2 == 4)
> +                       dpll |= PLL_P2_DIVIDE_BY_4;
> +       }
> +
> +       /*
> +        * Bspec:
> +        * "[Almador Errata}: For the correct operation of the muxed DVO pins
> +        *  (GDEVSELB/I2Cdata, GIRDBY/I2CClk) and (GFRAMEB/DVI_Data,
> +        *  GTRDYB/DVI_Clk): Bit 31 (DPLL VCO Enable) and Bit 30 (2X Clock
> +        *  Enable) must be set to “1” in both the DPLL A Control Register
> +        *  (06014h-06017h) and DPLL B Control Register (06018h-0601Bh)."
> +        *
> +        * For simplicity We simply keep both bits always enabled in
> +        * both DPLLS. The spec says we should disable the DVO 2X clock
> +        * when not needed, but this seems to work fine in practice.
> +        */
> +       if (IS_I830(dev_priv) ||
> +           intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DVO))
> +               dpll |= DPLL_DVO_2X_MODE;
> +
> +       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) &&
> +           intel_panel_use_ssc(dev_priv))
> +               dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
> +       else
> +               dpll |= PLL_REF_INPUT_DREFCLK;
> +
> +       dpll |= DPLL_VCO_ENABLE;
> +       crtc_state->dpll_hw_state.dpll = dpll;
> +}
> +
> +static int hsw_crtc_compute_clock(struct intel_crtc *crtc,
> +                                 struct intel_crtc_state *crtc_state)
> +{
> +       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +       struct intel_atomic_state *state =
> +               to_intel_atomic_state(crtc_state->uapi.state);
> +
> +       if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI) ||
> +           INTEL_GEN(dev_priv) >= 11) {
> +               struct intel_encoder *encoder =
> +                       intel_get_crtc_new_encoder(state, crtc_state);
> +
> +               if (!intel_reserve_shared_dplls(state, crtc, encoder)) {
> +                       drm_dbg_kms(&dev_priv->drm,
> +                                   "failed to find PLL for pipe %c\n",
> +                                   pipe_name(crtc->pipe));
> +                       return -EINVAL;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +static bool ilk_needs_fb_cb_tune(struct dpll *dpll, int factor)
> +{
> +       return i9xx_dpll_compute_m(dpll) < factor * dpll->n;
> +}
> +
> +
> +static void ilk_compute_dpll(struct intel_crtc *crtc,
> +                            struct intel_crtc_state *crtc_state,
> +                            struct dpll *reduced_clock)
> +{
> +       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +       u32 dpll, fp, fp2;
> +       int factor;
> +
> +       /* Enable autotuning of the PLL clock (if permissible) */
> +       factor = 21;
> +       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> +               if ((intel_panel_use_ssc(dev_priv) &&
> +                    dev_priv->vbt.lvds_ssc_freq == 100000) ||
> +                   (HAS_PCH_IBX(dev_priv) &&
> +                    intel_is_dual_link_lvds(dev_priv)))
> +                       factor = 25;
> +       } else if (crtc_state->sdvo_tv_clock) {
> +               factor = 20;
> +       }
> +
> +       fp = i9xx_dpll_compute_fp(&crtc_state->dpll);
> +
> +       if (ilk_needs_fb_cb_tune(&crtc_state->dpll, factor))
> +               fp |= FP_CB_TUNE;
> +
> +       if (reduced_clock) {
> +               fp2 = i9xx_dpll_compute_fp(reduced_clock);
> +
> +               if (reduced_clock->m < factor * reduced_clock->n)
> +                       fp2 |= FP_CB_TUNE;
> +       } else {
> +               fp2 = fp;
> +       }
> +
> +       dpll = 0;
> +
> +       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS))
> +               dpll |= DPLLB_MODE_LVDS;
> +       else
> +               dpll |= DPLLB_MODE_DAC_SERIAL;
> +
> +       dpll |= (crtc_state->pixel_multiplier - 1)
> +               << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
> +
> +       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO) ||
> +           intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
> +               dpll |= DPLL_SDVO_HIGH_SPEED;
> +
> +       if (intel_crtc_has_dp_encoder(crtc_state))
> +               dpll |= DPLL_SDVO_HIGH_SPEED;
> +
> +       /*
> +        * The high speed IO clock is only really required for
> +        * SDVO/HDMI/DP, but we also enable it for CRT to make it
> +        * possible to share the DPLL between CRT and HDMI. Enabling
> +        * the clock needlessly does no real harm, except use up a
> +        * bit of power potentially.
> +        *
> +        * We'll limit this to IVB with 3 pipes, since it has only two
> +        * DPLLs and so DPLL sharing is the only way to get three pipes
> +        * driving PCH ports at the same time. On SNB we could do this,
> +        * and potentially avoid enabling the second DPLL, but it's not
> +        * clear if it''s a win or loss power wise. No point in doing
> +        * this on ILK at all since it has a fixed DPLL<->pipe mapping.
> +        */
> +       if (INTEL_NUM_PIPES(dev_priv) == 3 &&
> +           intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG))
> +               dpll |= DPLL_SDVO_HIGH_SPEED;
> +
> +       /* compute bitmask from p1 value */
> +       dpll |= (1 << (crtc_state->dpll.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
> +       /* also FPA1 */
> +       dpll |= (1 << (crtc_state->dpll.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
> +
> +       switch (crtc_state->dpll.p2) {
> +       case 5:
> +               dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
> +               break;
> +       case 7:
> +               dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
> +               break;
> +       case 10:
> +               dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
> +               break;
> +       case 14:
> +               dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
> +               break;
> +       }
> +
> +       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) &&
> +           intel_panel_use_ssc(dev_priv))
> +               dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
> +       else
> +               dpll |= PLL_REF_INPUT_DREFCLK;
> +
> +       dpll |= DPLL_VCO_ENABLE;
> +
> +       crtc_state->dpll_hw_state.dpll = dpll;
> +       crtc_state->dpll_hw_state.fp0 = fp;
> +       crtc_state->dpll_hw_state.fp1 = fp2;
> +}
> +
> +static int ilk_crtc_compute_clock(struct intel_crtc *crtc,
> +                                 struct intel_crtc_state *crtc_state)
> +{
> +       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +       struct intel_atomic_state *state =
> +               to_intel_atomic_state(crtc_state->uapi.state);
> +       const struct intel_limit *limit;
> +       int refclk = 120000;
> +
> +       memset(&crtc_state->dpll_hw_state, 0,
> +              sizeof(crtc_state->dpll_hw_state));
> +
> +       /* CPU eDP is the only output that doesn't need a PCH PLL of its own. */
> +       if (!crtc_state->has_pch_encoder)
> +               return 0;
> +
> +       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> +               if (intel_panel_use_ssc(dev_priv)) {
> +                       drm_dbg_kms(&dev_priv->drm,
> +                                   "using SSC reference clock of %d kHz\n",
> +                                   dev_priv->vbt.lvds_ssc_freq);
> +                       refclk = dev_priv->vbt.lvds_ssc_freq;
> +               }
> +
> +               if (intel_is_dual_link_lvds(dev_priv)) {
> +                       if (refclk == 100000)
> +                               limit = &ilk_limits_dual_lvds_100m;
> +                       else
> +                               limit = &ilk_limits_dual_lvds;
> +               } else {
> +                       if (refclk == 100000)
> +                               limit = &ilk_limits_single_lvds_100m;
> +                       else
> +                               limit = &ilk_limits_single_lvds;
> +               }
> +       } else {
> +               limit = &ilk_limits_dac;
> +       }
> +
> +       if (!crtc_state->clock_set &&
> +           !g4x_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
> +                               refclk, NULL, &crtc_state->dpll)) {
> +               drm_err(&dev_priv->drm,
> +                       "Couldn't find PLL settings for mode!\n");
> +               return -EINVAL;
> +       }
> +
> +       ilk_compute_dpll(crtc, crtc_state, NULL);
> +
> +       if (!intel_reserve_shared_dplls(state, crtc, NULL)) {
> +               drm_dbg_kms(&dev_priv->drm,
> +                           "failed to find PLL for pipe %c\n",
> +                           pipe_name(crtc->pipe));
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +void vlv_compute_dpll(struct intel_crtc *crtc,
> +                     struct intel_crtc_state *pipe_config)
> +{
> +       pipe_config->dpll_hw_state.dpll = DPLL_INTEGRATED_REF_CLK_VLV |
> +               DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
> +       if (crtc->pipe != PIPE_A)
> +               pipe_config->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV;
> +
> +       /* DPLL not used with DSI, but still need the rest set up */
> +       if (!intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DSI))
> +               pipe_config->dpll_hw_state.dpll |= DPLL_VCO_ENABLE |
> +                       DPLL_EXT_BUFFER_ENABLE_VLV;
> +
> +       pipe_config->dpll_hw_state.dpll_md =
> +               (pipe_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
> +}
> +
> +void chv_compute_dpll(struct intel_crtc *crtc,
> +                     struct intel_crtc_state *pipe_config)
> +{
> +       pipe_config->dpll_hw_state.dpll = DPLL_SSC_REF_CLK_CHV |
> +               DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
> +       if (crtc->pipe != PIPE_A)
> +               pipe_config->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV;
> +
> +       /* DPLL not used with DSI, but still need the rest set up */
> +       if (!intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DSI))
> +               pipe_config->dpll_hw_state.dpll |= DPLL_VCO_ENABLE;
> +
> +       pipe_config->dpll_hw_state.dpll_md =
> +               (pipe_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
> +}
> +
> +static int chv_crtc_compute_clock(struct intel_crtc *crtc,
> +                                 struct intel_crtc_state *crtc_state)
> +{
> +       int refclk = 100000;
> +       const struct intel_limit *limit = &intel_limits_chv;
> +       struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
> +
> +       memset(&crtc_state->dpll_hw_state, 0,
> +              sizeof(crtc_state->dpll_hw_state));
> +
> +       if (!crtc_state->clock_set &&
> +           !chv_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
> +                               refclk, NULL, &crtc_state->dpll)) {
> +               drm_err(&i915->drm, "Couldn't find PLL settings for mode!\n");
> +               return -EINVAL;
> +       }
> +
> +       chv_compute_dpll(crtc, crtc_state);
> +
> +       return 0;
> +}
> +
> +static int vlv_crtc_compute_clock(struct intel_crtc *crtc,
> +                                 struct intel_crtc_state *crtc_state)
> +{
> +       int refclk = 100000;
> +       const struct intel_limit *limit = &intel_limits_vlv;
> +       struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
> +
> +       memset(&crtc_state->dpll_hw_state, 0,
> +              sizeof(crtc_state->dpll_hw_state));
> +
> +       if (!crtc_state->clock_set &&
> +           !vlv_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
> +                               refclk, NULL, &crtc_state->dpll)) {
> +               drm_err(&i915->drm,  "Couldn't find PLL settings for mode!\n");
> +               return -EINVAL;
> +       }
> +
> +       vlv_compute_dpll(crtc, crtc_state);
> +
> +       return 0;
> +}
> +
> +static int g4x_crtc_compute_clock(struct intel_crtc *crtc,
> +                                 struct intel_crtc_state *crtc_state)
> +{
> +       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +       const struct intel_limit *limit;
> +       int refclk = 96000;
> +
> +       memset(&crtc_state->dpll_hw_state, 0,
> +              sizeof(crtc_state->dpll_hw_state));
> +
> +       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> +               if (intel_panel_use_ssc(dev_priv)) {
> +                       refclk = dev_priv->vbt.lvds_ssc_freq;
> +                       drm_dbg_kms(&dev_priv->drm,
> +                                   "using SSC reference clock of %d kHz\n",
> +                                   refclk);
> +               }
> +
> +               if (intel_is_dual_link_lvds(dev_priv))
> +                       limit = &intel_limits_g4x_dual_channel_lvds;
> +               else
> +                       limit = &intel_limits_g4x_single_channel_lvds;
> +       } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) ||
> +                  intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) {
> +               limit = &intel_limits_g4x_hdmi;
> +       } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO)) {
> +               limit = &intel_limits_g4x_sdvo;
> +       } else {
> +               /* The option is for other outputs */
> +               limit = &intel_limits_i9xx_sdvo;
> +       }
> +
> +       if (!crtc_state->clock_set &&
> +           !g4x_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
> +                               refclk, NULL, &crtc_state->dpll)) {
> +               drm_err(&dev_priv->drm,
> +                       "Couldn't find PLL settings for mode!\n");
> +               return -EINVAL;
> +       }
> +
> +       i9xx_compute_dpll(crtc, crtc_state, NULL);
> +
> +       return 0;
> +}
> +
> +static int pnv_crtc_compute_clock(struct intel_crtc *crtc,
> +                                 struct intel_crtc_state *crtc_state)
> +{
> +       struct drm_device *dev = crtc->base.dev;
> +       struct drm_i915_private *dev_priv = to_i915(dev);
> +       const struct intel_limit *limit;
> +       int refclk = 96000;
> +
> +       memset(&crtc_state->dpll_hw_state, 0,
> +              sizeof(crtc_state->dpll_hw_state));
> +
> +       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> +               if (intel_panel_use_ssc(dev_priv)) {
> +                       refclk = dev_priv->vbt.lvds_ssc_freq;
> +                       drm_dbg_kms(&dev_priv->drm,
> +                                   "using SSC reference clock of %d kHz\n",
> +                                   refclk);
> +               }
> +
> +               limit = &pnv_limits_lvds;
> +       } else {
> +               limit = &pnv_limits_sdvo;
> +       }
> +
> +       if (!crtc_state->clock_set &&
> +           !pnv_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
> +                               refclk, NULL, &crtc_state->dpll)) {
> +               drm_err(&dev_priv->drm,
> +                       "Couldn't find PLL settings for mode!\n");
> +               return -EINVAL;
> +       }
> +
> +       i9xx_compute_dpll(crtc, crtc_state, NULL);
> +
> +       return 0;
> +}
> +
> +static int i9xx_crtc_compute_clock(struct intel_crtc *crtc,
> +                                  struct intel_crtc_state *crtc_state)
> +{
> +       struct drm_device *dev = crtc->base.dev;
> +       struct drm_i915_private *dev_priv = to_i915(dev);
> +       const struct intel_limit *limit;
> +       int refclk = 96000;
> +
> +       memset(&crtc_state->dpll_hw_state, 0,
> +              sizeof(crtc_state->dpll_hw_state));
> +
> +       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> +               if (intel_panel_use_ssc(dev_priv)) {
> +                       refclk = dev_priv->vbt.lvds_ssc_freq;
> +                       drm_dbg_kms(&dev_priv->drm,
> +                                   "using SSC reference clock of %d kHz\n",
> +                                   refclk);
> +               }
> +
> +               limit = &intel_limits_i9xx_lvds;
> +       } else {
> +               limit = &intel_limits_i9xx_sdvo;
> +       }
> +
> +       if (!crtc_state->clock_set &&
> +           !i9xx_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
> +                                refclk, NULL, &crtc_state->dpll)) {
> +               drm_err(&dev_priv->drm,
> +                       "Couldn't find PLL settings for mode!\n");
> +               return -EINVAL;
> +       }
> +
> +       i9xx_compute_dpll(crtc, crtc_state, NULL);
> +
> +       return 0;
> +}
> +
> +static int i8xx_crtc_compute_clock(struct intel_crtc *crtc,
> +                                  struct intel_crtc_state *crtc_state)
> +{
> +       struct drm_device *dev = crtc->base.dev;
> +       struct drm_i915_private *dev_priv = to_i915(dev);
> +       const struct intel_limit *limit;
> +       int refclk = 48000;
> +
> +       memset(&crtc_state->dpll_hw_state, 0,
> +              sizeof(crtc_state->dpll_hw_state));
> +
> +       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> +               if (intel_panel_use_ssc(dev_priv)) {
> +                       refclk = dev_priv->vbt.lvds_ssc_freq;
> +                       drm_dbg_kms(&dev_priv->drm,
> +                                   "using SSC reference clock of %d kHz\n",
> +                                   refclk);
> +               }
> +
> +               limit = &intel_limits_i8xx_lvds;
> +       } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DVO)) {
> +               limit = &intel_limits_i8xx_dvo;
> +       } else {
> +               limit = &intel_limits_i8xx_dac;
> +       }
> +
> +       if (!crtc_state->clock_set &&
> +           !i9xx_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
> +                                refclk, NULL, &crtc_state->dpll)) {
> +               drm_err(&dev_priv->drm,
> +                       "Couldn't find PLL settings for mode!\n");
> +               return -EINVAL;
> +       }
> +
> +       i8xx_compute_dpll(crtc, crtc_state, NULL);
> +
> +       return 0;
> +}
> +
> +void
> +intel_init_clock_hook(struct drm_i915_private *dev_priv)
> +{
> +       if (INTEL_GEN(dev_priv) >= 9 || HAS_DDI(dev_priv))
> +               dev_priv->display.crtc_compute_clock = hsw_crtc_compute_clock;
> +       else if (HAS_PCH_SPLIT(dev_priv))
> +               dev_priv->display.crtc_compute_clock = ilk_crtc_compute_clock;
> +       else if (IS_CHERRYVIEW(dev_priv))
> +               dev_priv->display.crtc_compute_clock = chv_crtc_compute_clock;
> +       else if (IS_VALLEYVIEW(dev_priv))
> +               dev_priv->display.crtc_compute_clock = vlv_crtc_compute_clock;
> +       else if (IS_G4X(dev_priv))
> +               dev_priv->display.crtc_compute_clock = g4x_crtc_compute_clock;
> +       else if (IS_PINEVIEW(dev_priv))
> +               dev_priv->display.crtc_compute_clock = pnv_crtc_compute_clock;
> +       else if (!IS_GEN(dev_priv, 2))
> +               dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock;
> +       else
> +               dev_priv->display.crtc_compute_clock = i8xx_crtc_compute_clock;
> +}
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index c6f30e4ec51e..788b1def61ee 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -113,17 +113,6 @@ static void ilk_pfit_enable(const struct intel_crtc_state *crtc_state);
>  static void intel_modeset_setup_hw_state(struct drm_device *dev,
>                                          struct drm_modeset_acquire_ctx *ctx);
>
> -struct intel_limit {
> -       struct {
> -               int min, max;
> -       } dot, vco, n, m, m1, m2, p, p1;
> -
> -       struct {
> -               int dot_limit;
> -               int p2_slow, p2_fast;
> -       } p2;
> -};
> -
>  /* returns HPLL frequency in kHz */
>  int vlv_get_hpll_vco(struct drm_i915_private *dev_priv)
>  {
> @@ -191,271 +180,6 @@ static u32 intel_fdi_link_freq(struct drm_i915_private *dev_priv,
>                 return dev_priv->fdi_pll_freq;
>  }
>
> -static const struct intel_limit intel_limits_i8xx_dac = {
> -       .dot = { .min = 25000, .max = 350000 },
> -       .vco = { .min = 908000, .max = 1512000 },
> -       .n = { .min = 2, .max = 16 },
> -       .m = { .min = 96, .max = 140 },
> -       .m1 = { .min = 18, .max = 26 },
> -       .m2 = { .min = 6, .max = 16 },
> -       .p = { .min = 4, .max = 128 },
> -       .p1 = { .min = 2, .max = 33 },
> -       .p2 = { .dot_limit = 165000,
> -               .p2_slow = 4, .p2_fast = 2 },
> -};
> -
> -static const struct intel_limit intel_limits_i8xx_dvo = {
> -       .dot = { .min = 25000, .max = 350000 },
> -       .vco = { .min = 908000, .max = 1512000 },
> -       .n = { .min = 2, .max = 16 },
> -       .m = { .min = 96, .max = 140 },
> -       .m1 = { .min = 18, .max = 26 },
> -       .m2 = { .min = 6, .max = 16 },
> -       .p = { .min = 4, .max = 128 },
> -       .p1 = { .min = 2, .max = 33 },
> -       .p2 = { .dot_limit = 165000,
> -               .p2_slow = 4, .p2_fast = 4 },
> -};
> -
> -static const struct intel_limit intel_limits_i8xx_lvds = {
> -       .dot = { .min = 25000, .max = 350000 },
> -       .vco = { .min = 908000, .max = 1512000 },
> -       .n = { .min = 2, .max = 16 },
> -       .m = { .min = 96, .max = 140 },
> -       .m1 = { .min = 18, .max = 26 },
> -       .m2 = { .min = 6, .max = 16 },
> -       .p = { .min = 4, .max = 128 },
> -       .p1 = { .min = 1, .max = 6 },
> -       .p2 = { .dot_limit = 165000,
> -               .p2_slow = 14, .p2_fast = 7 },
> -};
> -
> -static const struct intel_limit intel_limits_i9xx_sdvo = {
> -       .dot = { .min = 20000, .max = 400000 },
> -       .vco = { .min = 1400000, .max = 2800000 },
> -       .n = { .min = 1, .max = 6 },
> -       .m = { .min = 70, .max = 120 },
> -       .m1 = { .min = 8, .max = 18 },
> -       .m2 = { .min = 3, .max = 7 },
> -       .p = { .min = 5, .max = 80 },
> -       .p1 = { .min = 1, .max = 8 },
> -       .p2 = { .dot_limit = 200000,
> -               .p2_slow = 10, .p2_fast = 5 },
> -};
> -
> -static const struct intel_limit intel_limits_i9xx_lvds = {
> -       .dot = { .min = 20000, .max = 400000 },
> -       .vco = { .min = 1400000, .max = 2800000 },
> -       .n = { .min = 1, .max = 6 },
> -       .m = { .min = 70, .max = 120 },
> -       .m1 = { .min = 8, .max = 18 },
> -       .m2 = { .min = 3, .max = 7 },
> -       .p = { .min = 7, .max = 98 },
> -       .p1 = { .min = 1, .max = 8 },
> -       .p2 = { .dot_limit = 112000,
> -               .p2_slow = 14, .p2_fast = 7 },
> -};
> -
> -
> -static const struct intel_limit intel_limits_g4x_sdvo = {
> -       .dot = { .min = 25000, .max = 270000 },
> -       .vco = { .min = 1750000, .max = 3500000},
> -       .n = { .min = 1, .max = 4 },
> -       .m = { .min = 104, .max = 138 },
> -       .m1 = { .min = 17, .max = 23 },
> -       .m2 = { .min = 5, .max = 11 },
> -       .p = { .min = 10, .max = 30 },
> -       .p1 = { .min = 1, .max = 3},
> -       .p2 = { .dot_limit = 270000,
> -               .p2_slow = 10,
> -               .p2_fast = 10
> -       },
> -};
> -
> -static const struct intel_limit intel_limits_g4x_hdmi = {
> -       .dot = { .min = 22000, .max = 400000 },
> -       .vco = { .min = 1750000, .max = 3500000},
> -       .n = { .min = 1, .max = 4 },
> -       .m = { .min = 104, .max = 138 },
> -       .m1 = { .min = 16, .max = 23 },
> -       .m2 = { .min = 5, .max = 11 },
> -       .p = { .min = 5, .max = 80 },
> -       .p1 = { .min = 1, .max = 8},
> -       .p2 = { .dot_limit = 165000,
> -               .p2_slow = 10, .p2_fast = 5 },
> -};
> -
> -static const struct intel_limit intel_limits_g4x_single_channel_lvds = {
> -       .dot = { .min = 20000, .max = 115000 },
> -       .vco = { .min = 1750000, .max = 3500000 },
> -       .n = { .min = 1, .max = 3 },
> -       .m = { .min = 104, .max = 138 },
> -       .m1 = { .min = 17, .max = 23 },
> -       .m2 = { .min = 5, .max = 11 },
> -       .p = { .min = 28, .max = 112 },
> -       .p1 = { .min = 2, .max = 8 },
> -       .p2 = { .dot_limit = 0,
> -               .p2_slow = 14, .p2_fast = 14
> -       },
> -};
> -
> -static const struct intel_limit intel_limits_g4x_dual_channel_lvds = {
> -       .dot = { .min = 80000, .max = 224000 },
> -       .vco = { .min = 1750000, .max = 3500000 },
> -       .n = { .min = 1, .max = 3 },
> -       .m = { .min = 104, .max = 138 },
> -       .m1 = { .min = 17, .max = 23 },
> -       .m2 = { .min = 5, .max = 11 },
> -       .p = { .min = 14, .max = 42 },
> -       .p1 = { .min = 2, .max = 6 },
> -       .p2 = { .dot_limit = 0,
> -               .p2_slow = 7, .p2_fast = 7
> -       },
> -};
> -
> -static const struct intel_limit pnv_limits_sdvo = {
> -       .dot = { .min = 20000, .max = 400000},
> -       .vco = { .min = 1700000, .max = 3500000 },
> -       /* Pineview's Ncounter is a ring counter */
> -       .n = { .min = 3, .max = 6 },
> -       .m = { .min = 2, .max = 256 },
> -       /* Pineview only has one combined m divider, which we treat as m2. */
> -       .m1 = { .min = 0, .max = 0 },
> -       .m2 = { .min = 0, .max = 254 },
> -       .p = { .min = 5, .max = 80 },
> -       .p1 = { .min = 1, .max = 8 },
> -       .p2 = { .dot_limit = 200000,
> -               .p2_slow = 10, .p2_fast = 5 },
> -};
> -
> -static const struct intel_limit pnv_limits_lvds = {
> -       .dot = { .min = 20000, .max = 400000 },
> -       .vco = { .min = 1700000, .max = 3500000 },
> -       .n = { .min = 3, .max = 6 },
> -       .m = { .min = 2, .max = 256 },
> -       .m1 = { .min = 0, .max = 0 },
> -       .m2 = { .min = 0, .max = 254 },
> -       .p = { .min = 7, .max = 112 },
> -       .p1 = { .min = 1, .max = 8 },
> -       .p2 = { .dot_limit = 112000,
> -               .p2_slow = 14, .p2_fast = 14 },
> -};
> -
> -/* Ironlake / Sandybridge
> - *
> - * We calculate clock using (register_value + 2) for N/M1/M2, so here
> - * the range value for them is (actual_value - 2).
> - */
> -static const struct intel_limit ilk_limits_dac = {
> -       .dot = { .min = 25000, .max = 350000 },
> -       .vco = { .min = 1760000, .max = 3510000 },
> -       .n = { .min = 1, .max = 5 },
> -       .m = { .min = 79, .max = 127 },
> -       .m1 = { .min = 12, .max = 22 },
> -       .m2 = { .min = 5, .max = 9 },
> -       .p = { .min = 5, .max = 80 },
> -       .p1 = { .min = 1, .max = 8 },
> -       .p2 = { .dot_limit = 225000,
> -               .p2_slow = 10, .p2_fast = 5 },
> -};
> -
> -static const struct intel_limit ilk_limits_single_lvds = {
> -       .dot = { .min = 25000, .max = 350000 },
> -       .vco = { .min = 1760000, .max = 3510000 },
> -       .n = { .min = 1, .max = 3 },
> -       .m = { .min = 79, .max = 118 },
> -       .m1 = { .min = 12, .max = 22 },
> -       .m2 = { .min = 5, .max = 9 },
> -       .p = { .min = 28, .max = 112 },
> -       .p1 = { .min = 2, .max = 8 },
> -       .p2 = { .dot_limit = 225000,
> -               .p2_slow = 14, .p2_fast = 14 },
> -};
> -
> -static const struct intel_limit ilk_limits_dual_lvds = {
> -       .dot = { .min = 25000, .max = 350000 },
> -       .vco = { .min = 1760000, .max = 3510000 },
> -       .n = { .min = 1, .max = 3 },
> -       .m = { .min = 79, .max = 127 },
> -       .m1 = { .min = 12, .max = 22 },
> -       .m2 = { .min = 5, .max = 9 },
> -       .p = { .min = 14, .max = 56 },
> -       .p1 = { .min = 2, .max = 8 },
> -       .p2 = { .dot_limit = 225000,
> -               .p2_slow = 7, .p2_fast = 7 },
> -};
> -
> -/* LVDS 100mhz refclk limits. */
> -static const struct intel_limit ilk_limits_single_lvds_100m = {
> -       .dot = { .min = 25000, .max = 350000 },
> -       .vco = { .min = 1760000, .max = 3510000 },
> -       .n = { .min = 1, .max = 2 },
> -       .m = { .min = 79, .max = 126 },
> -       .m1 = { .min = 12, .max = 22 },
> -       .m2 = { .min = 5, .max = 9 },
> -       .p = { .min = 28, .max = 112 },
> -       .p1 = { .min = 2, .max = 8 },
> -       .p2 = { .dot_limit = 225000,
> -               .p2_slow = 14, .p2_fast = 14 },
> -};
> -
> -static const struct intel_limit ilk_limits_dual_lvds_100m = {
> -       .dot = { .min = 25000, .max = 350000 },
> -       .vco = { .min = 1760000, .max = 3510000 },
> -       .n = { .min = 1, .max = 3 },
> -       .m = { .min = 79, .max = 126 },
> -       .m1 = { .min = 12, .max = 22 },
> -       .m2 = { .min = 5, .max = 9 },
> -       .p = { .min = 14, .max = 42 },
> -       .p1 = { .min = 2, .max = 6 },
> -       .p2 = { .dot_limit = 225000,
> -               .p2_slow = 7, .p2_fast = 7 },
> -};
> -
> -static const struct intel_limit intel_limits_vlv = {
> -        /*
> -         * These are the data rate limits (measured in fast clocks)
> -         * since those are the strictest limits we have. The fast
> -         * clock and actual rate limits are more relaxed, so checking
> -         * them would make no difference.
> -         */
> -       .dot = { .min = 25000 * 5, .max = 270000 * 5 },
> -       .vco = { .min = 4000000, .max = 6000000 },
> -       .n = { .min = 1, .max = 7 },
> -       .m1 = { .min = 2, .max = 3 },
> -       .m2 = { .min = 11, .max = 156 },
> -       .p1 = { .min = 2, .max = 3 },
> -       .p2 = { .p2_slow = 2, .p2_fast = 20 }, /* slow=min, fast=max */
> -};
> -
> -static const struct intel_limit intel_limits_chv = {
> -       /*
> -        * These are the data rate limits (measured in fast clocks)
> -        * since those are the strictest limits we have.  The fast
> -        * clock and actual rate limits are more relaxed, so checking
> -        * them would make no difference.
> -        */
> -       .dot = { .min = 25000 * 5, .max = 540000 * 5},
> -       .vco = { .min = 4800000, .max = 6480000 },
> -       .n = { .min = 1, .max = 1 },
> -       .m1 = { .min = 2, .max = 2 },
> -       .m2 = { .min = 24 << 22, .max = 175 << 22 },
> -       .p1 = { .min = 2, .max = 4 },
> -       .p2 = { .p2_slow = 1, .p2_fast = 14 },
> -};
> -
> -static const struct intel_limit intel_limits_bxt = {
> -       /* FIXME: find real dot limits */
> -       .dot = { .min = 0, .max = INT_MAX },
> -       .vco = { .min = 4800000, .max = 6700000 },
> -       .n = { .min = 1, .max = 1 },
> -       .m1 = { .min = 2, .max = 2 },
> -       /* FIXME: find real m2 limits */
> -       .m2 = { .min = 2 << 22, .max = 255 << 22 },
> -       .p1 = { .min = 2, .max = 4 },
> -       .p2 = { .p2_slow = 1, .p2_fast = 20 },
> -};
> -
>  /* WA Display #0827: Gen9:all */
>  static void
>  skl_wa_827(struct drm_i915_private *dev_priv, enum pipe pipe, bool enable)
> @@ -506,482 +230,6 @@ is_trans_port_sync_mode(const struct intel_crtc_state *crtc_state)
>                 is_trans_port_sync_slave(crtc_state);
>  }
>
> -/*
> - * Platform specific helpers to calculate the port PLL loopback- (clock.m),
> - * and post-divider (clock.p) values, pre- (clock.vco) and post-divided fast
> - * (clock.dot) clock rates. This fast dot clock is fed to the port's IO logic.
> - * The helpers' return value is the rate of the clock that is fed to the
> - * display engine's pipe which can be the above fast dot clock rate or a
> - * divided-down version of it.
> - */
> -/* m1 is reserved as 0 in Pineview, n is a ring counter */
> -static int pnv_calc_dpll_params(int refclk, struct dpll *clock)
> -{
> -       clock->m = clock->m2 + 2;
> -       clock->p = clock->p1 * clock->p2;
> -       if (WARN_ON(clock->n == 0 || clock->p == 0))
> -               return 0;
> -       clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n);
> -       clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
> -
> -       return clock->dot;
> -}
> -
> -static u32 i9xx_dpll_compute_m(struct dpll *dpll)
> -{
> -       return 5 * (dpll->m1 + 2) + (dpll->m2 + 2);
> -}
> -
> -static int i9xx_calc_dpll_params(int refclk, struct dpll *clock)
> -{
> -       clock->m = i9xx_dpll_compute_m(clock);
> -       clock->p = clock->p1 * clock->p2;
> -       if (WARN_ON(clock->n + 2 == 0 || clock->p == 0))
> -               return 0;
> -       clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n + 2);
> -       clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
> -
> -       return clock->dot;
> -}
> -
> -static int vlv_calc_dpll_params(int refclk, struct dpll *clock)
> -{
> -       clock->m = clock->m1 * clock->m2;
> -       clock->p = clock->p1 * clock->p2;
> -       if (WARN_ON(clock->n == 0 || clock->p == 0))
> -               return 0;
> -       clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n);
> -       clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
> -
> -       return clock->dot / 5;
> -}
> -
> -int chv_calc_dpll_params(int refclk, struct dpll *clock)
> -{
> -       clock->m = clock->m1 * clock->m2;
> -       clock->p = clock->p1 * clock->p2;
> -       if (WARN_ON(clock->n == 0 || clock->p == 0))
> -               return 0;
> -       clock->vco = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(refclk, clock->m),
> -                                          clock->n << 22);
> -       clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
> -
> -       return clock->dot / 5;
> -}
> -
> -/*
> - * Returns whether the given set of divisors are valid for a given refclk with
> - * the given connectors.
> - */
> -static bool intel_pll_is_valid(struct drm_i915_private *dev_priv,
> -                              const struct intel_limit *limit,
> -                              const struct dpll *clock)
> -{
> -       if (clock->n < limit->n.min || limit->n.max < clock->n)
> -               return false;
> -       if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
> -               return false;
> -       if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2)
> -               return false;
> -       if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
> -               return false;
> -
> -       if (!IS_PINEVIEW(dev_priv) && !IS_VALLEYVIEW(dev_priv) &&
> -           !IS_CHERRYVIEW(dev_priv) && !IS_GEN9_LP(dev_priv))
> -               if (clock->m1 <= clock->m2)
> -                       return false;
> -
> -       if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) &&
> -           !IS_GEN9_LP(dev_priv)) {
> -               if (clock->p < limit->p.min || limit->p.max < clock->p)
> -                       return false;
> -               if (clock->m < limit->m.min || limit->m.max < clock->m)
> -                       return false;
> -       }
> -
> -       if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
> -               return false;
> -       /* XXX: We may need to be checking "Dot clock" depending on the multiplier,
> -        * connector, etc., rather than just a single range.
> -        */
> -       if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
> -               return false;
> -
> -       return true;
> -}
> -
> -static int
> -i9xx_select_p2_div(const struct intel_limit *limit,
> -                  const struct intel_crtc_state *crtc_state,
> -                  int target)
> -{
> -       struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> -
> -       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> -               /*
> -                * For LVDS just rely on its current settings for dual-channel.
> -                * We haven't figured out how to reliably set up different
> -                * single/dual channel state, if we even can.
> -                */
> -               if (intel_is_dual_link_lvds(dev_priv))
> -                       return limit->p2.p2_fast;
> -               else
> -                       return limit->p2.p2_slow;
> -       } else {
> -               if (target < limit->p2.dot_limit)
> -                       return limit->p2.p2_slow;
> -               else
> -                       return limit->p2.p2_fast;
> -       }
> -}
> -
> -/*
> - * Returns a set of divisors for the desired target clock with the given
> - * refclk, or FALSE.  The returned values represent the clock equation:
> - * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
> - *
> - * Target and reference clocks are specified in kHz.
> - *
> - * If match_clock is provided, then best_clock P divider must match the P
> - * divider from @match_clock used for LVDS downclocking.
> - */
> -static bool
> -i9xx_find_best_dpll(const struct intel_limit *limit,
> -                   struct intel_crtc_state *crtc_state,
> -                   int target, int refclk, struct dpll *match_clock,
> -                   struct dpll *best_clock)
> -{
> -       struct drm_device *dev = crtc_state->uapi.crtc->dev;
> -       struct dpll clock;
> -       int err = target;
> -
> -       memset(best_clock, 0, sizeof(*best_clock));
> -
> -       clock.p2 = i9xx_select_p2_div(limit, crtc_state, target);
> -
> -       for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
> -            clock.m1++) {
> -               for (clock.m2 = limit->m2.min;
> -                    clock.m2 <= limit->m2.max; clock.m2++) {
> -                       if (clock.m2 >= clock.m1)
> -                               break;
> -                       for (clock.n = limit->n.min;
> -                            clock.n <= limit->n.max; clock.n++) {
> -                               for (clock.p1 = limit->p1.min;
> -                                       clock.p1 <= limit->p1.max; clock.p1++) {
> -                                       int this_err;
> -
> -                                       i9xx_calc_dpll_params(refclk, &clock);
> -                                       if (!intel_pll_is_valid(to_i915(dev),
> -                                                               limit,
> -                                                               &clock))
> -                                               continue;
> -                                       if (match_clock &&
> -                                           clock.p != match_clock->p)
> -                                               continue;
> -
> -                                       this_err = abs(clock.dot - target);
> -                                       if (this_err < err) {
> -                                               *best_clock = clock;
> -                                               err = this_err;
> -                                       }
> -                               }
> -                       }
> -               }
> -       }
> -
> -       return (err != target);
> -}
> -
> -/*
> - * Returns a set of divisors for the desired target clock with the given
> - * refclk, or FALSE.  The returned values represent the clock equation:
> - * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
> - *
> - * Target and reference clocks are specified in kHz.
> - *
> - * If match_clock is provided, then best_clock P divider must match the P
> - * divider from @match_clock used for LVDS downclocking.
> - */
> -static bool
> -pnv_find_best_dpll(const struct intel_limit *limit,
> -                  struct intel_crtc_state *crtc_state,
> -                  int target, int refclk, struct dpll *match_clock,
> -                  struct dpll *best_clock)
> -{
> -       struct drm_device *dev = crtc_state->uapi.crtc->dev;
> -       struct dpll clock;
> -       int err = target;
> -
> -       memset(best_clock, 0, sizeof(*best_clock));
> -
> -       clock.p2 = i9xx_select_p2_div(limit, crtc_state, target);
> -
> -       for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
> -            clock.m1++) {
> -               for (clock.m2 = limit->m2.min;
> -                    clock.m2 <= limit->m2.max; clock.m2++) {
> -                       for (clock.n = limit->n.min;
> -                            clock.n <= limit->n.max; clock.n++) {
> -                               for (clock.p1 = limit->p1.min;
> -                                       clock.p1 <= limit->p1.max; clock.p1++) {
> -                                       int this_err;
> -
> -                                       pnv_calc_dpll_params(refclk, &clock);
> -                                       if (!intel_pll_is_valid(to_i915(dev),
> -                                                               limit,
> -                                                               &clock))
> -                                               continue;
> -                                       if (match_clock &&
> -                                           clock.p != match_clock->p)
> -                                               continue;
> -
> -                                       this_err = abs(clock.dot - target);
> -                                       if (this_err < err) {
> -                                               *best_clock = clock;
> -                                               err = this_err;
> -                                       }
> -                               }
> -                       }
> -               }
> -       }
> -
> -       return (err != target);
> -}
> -
> -/*
> - * Returns a set of divisors for the desired target clock with the given
> - * refclk, or FALSE.  The returned values represent the clock equation:
> - * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
> - *
> - * Target and reference clocks are specified in kHz.
> - *
> - * If match_clock is provided, then best_clock P divider must match the P
> - * divider from @match_clock used for LVDS downclocking.
> - */
> -static bool
> -g4x_find_best_dpll(const struct intel_limit *limit,
> -                  struct intel_crtc_state *crtc_state,
> -                  int target, int refclk, struct dpll *match_clock,
> -                  struct dpll *best_clock)
> -{
> -       struct drm_device *dev = crtc_state->uapi.crtc->dev;
> -       struct dpll clock;
> -       int max_n;
> -       bool found = false;
> -       /* approximately equals target * 0.00585 */
> -       int err_most = (target >> 8) + (target >> 9);
> -
> -       memset(best_clock, 0, sizeof(*best_clock));
> -
> -       clock.p2 = i9xx_select_p2_div(limit, crtc_state, target);
> -
> -       max_n = limit->n.max;
> -       /* based on hardware requirement, prefer smaller n to precision */
> -       for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
> -               /* based on hardware requirement, prefere larger m1,m2 */
> -               for (clock.m1 = limit->m1.max;
> -                    clock.m1 >= limit->m1.min; clock.m1--) {
> -                       for (clock.m2 = limit->m2.max;
> -                            clock.m2 >= limit->m2.min; clock.m2--) {
> -                               for (clock.p1 = limit->p1.max;
> -                                    clock.p1 >= limit->p1.min; clock.p1--) {
> -                                       int this_err;
> -
> -                                       i9xx_calc_dpll_params(refclk, &clock);
> -                                       if (!intel_pll_is_valid(to_i915(dev),
> -                                                               limit,
> -                                                               &clock))
> -                                               continue;
> -
> -                                       this_err = abs(clock.dot - target);
> -                                       if (this_err < err_most) {
> -                                               *best_clock = clock;
> -                                               err_most = this_err;
> -                                               max_n = clock.n;
> -                                               found = true;
> -                                       }
> -                               }
> -                       }
> -               }
> -       }
> -       return found;
> -}
> -
> -/*
> - * Check if the calculated PLL configuration is more optimal compared to the
> - * best configuration and error found so far. Return the calculated error.
> - */
> -static bool vlv_PLL_is_optimal(struct drm_device *dev, int target_freq,
> -                              const struct dpll *calculated_clock,
> -                              const struct dpll *best_clock,
> -                              unsigned int best_error_ppm,
> -                              unsigned int *error_ppm)
> -{
> -       /*
> -        * For CHV ignore the error and consider only the P value.
> -        * Prefer a bigger P value based on HW requirements.
> -        */
> -       if (IS_CHERRYVIEW(to_i915(dev))) {
> -               *error_ppm = 0;
> -
> -               return calculated_clock->p > best_clock->p;
> -       }
> -
> -       if (drm_WARN_ON_ONCE(dev, !target_freq))
> -               return false;
> -
> -       *error_ppm = div_u64(1000000ULL *
> -                               abs(target_freq - calculated_clock->dot),
> -                            target_freq);
> -       /*
> -        * Prefer a better P value over a better (smaller) error if the error
> -        * is small. Ensure this preference for future configurations too by
> -        * setting the error to 0.
> -        */
> -       if (*error_ppm < 100 && calculated_clock->p > best_clock->p) {
> -               *error_ppm = 0;
> -
> -               return true;
> -       }
> -
> -       return *error_ppm + 10 < best_error_ppm;
> -}
> -
> -/*
> - * Returns a set of divisors for the desired target clock with the given
> - * refclk, or FALSE.  The returned values represent the clock equation:
> - * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
> - */
> -static bool
> -vlv_find_best_dpll(const struct intel_limit *limit,
> -                  struct intel_crtc_state *crtc_state,
> -                  int target, int refclk, struct dpll *match_clock,
> -                  struct dpll *best_clock)
> -{
> -       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> -       struct drm_device *dev = crtc->base.dev;
> -       struct dpll clock;
> -       unsigned int bestppm = 1000000;
> -       /* min update 19.2 MHz */
> -       int max_n = min(limit->n.max, refclk / 19200);
> -       bool found = false;
> -
> -       target *= 5; /* fast clock */
> -
> -       memset(best_clock, 0, sizeof(*best_clock));
> -
> -       /* based on hardware requirement, prefer smaller n to precision */
> -       for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
> -               for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
> -                       for (clock.p2 = limit->p2.p2_fast; clock.p2 >= limit->p2.p2_slow;
> -                            clock.p2 -= clock.p2 > 10 ? 2 : 1) {
> -                               clock.p = clock.p1 * clock.p2;
> -                               /* based on hardware requirement, prefer bigger m1,m2 values */
> -                               for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
> -                                       unsigned int ppm;
> -
> -                                       clock.m2 = DIV_ROUND_CLOSEST(target * clock.p * clock.n,
> -                                                                    refclk * clock.m1);
> -
> -                                       vlv_calc_dpll_params(refclk, &clock);
> -
> -                                       if (!intel_pll_is_valid(to_i915(dev),
> -                                                               limit,
> -                                                               &clock))
> -                                               continue;
> -
> -                                       if (!vlv_PLL_is_optimal(dev, target,
> -                                                               &clock,
> -                                                               best_clock,
> -                                                               bestppm, &ppm))
> -                                               continue;
> -
> -                                       *best_clock = clock;
> -                                       bestppm = ppm;
> -                                       found = true;
> -                               }
> -                       }
> -               }
> -       }
> -
> -       return found;
> -}
> -
> -/*
> - * Returns a set of divisors for the desired target clock with the given
> - * refclk, or FALSE.  The returned values represent the clock equation:
> - * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
> - */
> -static bool
> -chv_find_best_dpll(const struct intel_limit *limit,
> -                  struct intel_crtc_state *crtc_state,
> -                  int target, int refclk, struct dpll *match_clock,
> -                  struct dpll *best_clock)
> -{
> -       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> -       struct drm_device *dev = crtc->base.dev;
> -       unsigned int best_error_ppm;
> -       struct dpll clock;
> -       u64 m2;
> -       int found = false;
> -
> -       memset(best_clock, 0, sizeof(*best_clock));
> -       best_error_ppm = 1000000;
> -
> -       /*
> -        * Based on hardware doc, the n always set to 1, and m1 always
> -        * set to 2.  If requires to support 200Mhz refclk, we need to
> -        * revisit this because n may not 1 anymore.
> -        */
> -       clock.n = 1, clock.m1 = 2;
> -       target *= 5;    /* fast clock */
> -
> -       for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
> -               for (clock.p2 = limit->p2.p2_fast;
> -                               clock.p2 >= limit->p2.p2_slow;
> -                               clock.p2 -= clock.p2 > 10 ? 2 : 1) {
> -                       unsigned int error_ppm;
> -
> -                       clock.p = clock.p1 * clock.p2;
> -
> -                       m2 = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(target, clock.p * clock.n) << 22,
> -                                                  refclk * clock.m1);
> -
> -                       if (m2 > INT_MAX/clock.m1)
> -                               continue;
> -
> -                       clock.m2 = m2;
> -
> -                       chv_calc_dpll_params(refclk, &clock);
> -
> -                       if (!intel_pll_is_valid(to_i915(dev), limit, &clock))
> -                               continue;
> -
> -                       if (!vlv_PLL_is_optimal(dev, target, &clock, best_clock,
> -                                               best_error_ppm, &error_ppm))
> -                               continue;
> -
> -                       *best_clock = clock;
> -                       best_error_ppm = error_ppm;
> -                       found = true;
> -               }
> -       }
> -
> -       return found;
> -}
> -
> -bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state,
> -                       struct dpll *best_clock)
> -{
> -       int refclk = 100000;
> -       const struct intel_limit *limit = &intel_limits_bxt;
> -
> -       return chv_find_best_dpll(limit, crtc_state,
> -                                 crtc_state->port_clock, refclk,
> -                                 NULL, best_clock);
> -}
> -
>  static bool pipe_scanline_is_moving(struct drm_i915_private *dev_priv,
>                                     enum pipe pipe)
>  {
> @@ -5284,7 +4532,7 @@ static void ivb_update_fdi_bc_bifurcation(const struct intel_crtc_state *crtc_st
>   * Finds the encoder associated with the given CRTC. This can only be
>   * used when we know that the CRTC isn't feeding multiple encoders!
>   */
> -static struct intel_encoder *
> +struct intel_encoder *
>  intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
>                            const struct intel_crtc_state *crtc_state)
>  {
> @@ -7960,43 +7208,6 @@ static bool intel_panel_use_ssc(struct drm_i915_private *dev_priv)
>                 && !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE);
>  }
>
> -static u32 pnv_dpll_compute_fp(struct dpll *dpll)
> -{
> -       return (1 << dpll->n) << 16 | dpll->m2;
> -}
> -
> -static u32 i9xx_dpll_compute_fp(struct dpll *dpll)
> -{
> -       return dpll->n << 16 | dpll->m1 << 8 | dpll->m2;
> -}
> -
> -static void i9xx_update_pll_dividers(struct intel_crtc *crtc,
> -                                    struct intel_crtc_state *crtc_state,
> -                                    struct dpll *reduced_clock)
> -{
> -       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -       u32 fp, fp2 = 0;
> -
> -       if (IS_PINEVIEW(dev_priv)) {
> -               fp = pnv_dpll_compute_fp(&crtc_state->dpll);
> -               if (reduced_clock)
> -                       fp2 = pnv_dpll_compute_fp(reduced_clock);
> -       } else {
> -               fp = i9xx_dpll_compute_fp(&crtc_state->dpll);
> -               if (reduced_clock)
> -                       fp2 = i9xx_dpll_compute_fp(reduced_clock);
> -       }
> -
> -       crtc_state->dpll_hw_state.fp0 = fp;
> -
> -       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) &&
> -           reduced_clock) {
> -               crtc_state->dpll_hw_state.fp1 = fp2;
> -       } else {
> -               crtc_state->dpll_hw_state.fp1 = fp;
> -       }
> -}
> -
>  static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv, enum pipe
>                 pipe)
>  {
> @@ -8121,39 +7332,6 @@ void intel_dp_set_m_n(const struct intel_crtc_state *crtc_state, enum link_m_n_s
>                 intel_cpu_transcoder_set_m_n(crtc_state, dp_m_n, dp_m2_n2);
>  }
>
> -static void vlv_compute_dpll(struct intel_crtc *crtc,
> -                            struct intel_crtc_state *pipe_config)
> -{
> -       pipe_config->dpll_hw_state.dpll = DPLL_INTEGRATED_REF_CLK_VLV |
> -               DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
> -       if (crtc->pipe != PIPE_A)
> -               pipe_config->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV;
> -
> -       /* DPLL not used with DSI, but still need the rest set up */
> -       if (!intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DSI))
> -               pipe_config->dpll_hw_state.dpll |= DPLL_VCO_ENABLE |
> -                       DPLL_EXT_BUFFER_ENABLE_VLV;
> -
> -       pipe_config->dpll_hw_state.dpll_md =
> -               (pipe_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
> -}
> -
> -static void chv_compute_dpll(struct intel_crtc *crtc,
> -                            struct intel_crtc_state *pipe_config)
> -{
> -       pipe_config->dpll_hw_state.dpll = DPLL_SSC_REF_CLK_CHV |
> -               DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
> -       if (crtc->pipe != PIPE_A)
> -               pipe_config->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV;
> -
> -       /* DPLL not used with DSI, but still need the rest set up */
> -       if (!intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DSI))
> -               pipe_config->dpll_hw_state.dpll |= DPLL_VCO_ENABLE;
> -
> -       pipe_config->dpll_hw_state.dpll_md =
> -               (pipe_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
> -}
> -
>  static void vlv_prepare_pll(struct intel_crtc *crtc,
>                             const struct intel_crtc_state *pipe_config)
>  {
> @@ -8413,128 +7591,7 @@ void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe)
>                 vlv_disable_pll(dev_priv, pipe);
>  }
>
> -static void i9xx_compute_dpll(struct intel_crtc *crtc,
> -                             struct intel_crtc_state *crtc_state,
> -                             struct dpll *reduced_clock)
> -{
> -       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -       u32 dpll;
> -       struct dpll *clock = &crtc_state->dpll;
> -
> -       i9xx_update_pll_dividers(crtc, crtc_state, reduced_clock);
> -
> -       dpll = DPLL_VGA_MODE_DIS;
> -
> -       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS))
> -               dpll |= DPLLB_MODE_LVDS;
> -       else
> -               dpll |= DPLLB_MODE_DAC_SERIAL;
> -
> -       if (IS_I945G(dev_priv) || IS_I945GM(dev_priv) ||
> -           IS_G33(dev_priv) || IS_PINEVIEW(dev_priv)) {
> -               dpll |= (crtc_state->pixel_multiplier - 1)
> -                       << SDVO_MULTIPLIER_SHIFT_HIRES;
> -       }
> -
> -       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO) ||
> -           intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
> -               dpll |= DPLL_SDVO_HIGH_SPEED;
> -
> -       if (intel_crtc_has_dp_encoder(crtc_state))
> -               dpll |= DPLL_SDVO_HIGH_SPEED;
> -
> -       /* compute bitmask from p1 value */
> -       if (IS_PINEVIEW(dev_priv))
> -               dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW;
> -       else {
> -               dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
> -               if (IS_G4X(dev_priv) && reduced_clock)
> -                       dpll |= (1 << (reduced_clock->p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
> -       }
> -       switch (clock->p2) {
> -       case 5:
> -               dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
> -               break;
> -       case 7:
> -               dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
> -               break;
> -       case 10:
> -               dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
> -               break;
> -       case 14:
> -               dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
> -               break;
> -       }
> -       if (INTEL_GEN(dev_priv) >= 4)
> -               dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
> -
> -       if (crtc_state->sdvo_tv_clock)
> -               dpll |= PLL_REF_INPUT_TVCLKINBC;
> -       else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) &&
> -                intel_panel_use_ssc(dev_priv))
> -               dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
> -       else
> -               dpll |= PLL_REF_INPUT_DREFCLK;
> -
> -       dpll |= DPLL_VCO_ENABLE;
> -       crtc_state->dpll_hw_state.dpll = dpll;
> -
> -       if (INTEL_GEN(dev_priv) >= 4) {
> -               u32 dpll_md = (crtc_state->pixel_multiplier - 1)
> -                       << DPLL_MD_UDI_MULTIPLIER_SHIFT;
> -               crtc_state->dpll_hw_state.dpll_md = dpll_md;
> -       }
> -}
> -
> -static void i8xx_compute_dpll(struct intel_crtc *crtc,
> -                             struct intel_crtc_state *crtc_state,
> -                             struct dpll *reduced_clock)
> -{
> -       struct drm_device *dev = crtc->base.dev;
> -       struct drm_i915_private *dev_priv = to_i915(dev);
> -       u32 dpll;
> -       struct dpll *clock = &crtc_state->dpll;
> -
> -       i9xx_update_pll_dividers(crtc, crtc_state, reduced_clock);
> -
> -       dpll = DPLL_VGA_MODE_DIS;
> -
> -       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> -               dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
> -       } else {
> -               if (clock->p1 == 2)
> -                       dpll |= PLL_P1_DIVIDE_BY_TWO;
> -               else
> -                       dpll |= (clock->p1 - 2) << DPLL_FPA01_P1_POST_DIV_SHIFT;
> -               if (clock->p2 == 4)
> -                       dpll |= PLL_P2_DIVIDE_BY_4;
> -       }
> -
> -       /*
> -        * Bspec:
> -        * "[Almador Errata}: For the correct operation of the muxed DVO pins
> -        *  (GDEVSELB/I2Cdata, GIRDBY/I2CClk) and (GFRAMEB/DVI_Data,
> -        *  GTRDYB/DVI_Clk): Bit 31 (DPLL VCO Enable) and Bit 30 (2X Clock
> -        *  Enable) must be set to “1” in both the DPLL A Control Register
> -        *  (06014h-06017h) and DPLL B Control Register (06018h-0601Bh)."
> -        *
> -        * For simplicity We simply keep both bits always enabled in
> -        * both DPLLS. The spec says we should disable the DVO 2X clock
> -        * when not needed, but this seems to work fine in practice.
> -        */
> -       if (IS_I830(dev_priv) ||
> -           intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DVO))
> -               dpll |= DPLL_DVO_2X_MODE;
> -
> -       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) &&
> -           intel_panel_use_ssc(dev_priv))
> -               dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
> -       else
> -               dpll |= PLL_REF_INPUT_DREFCLK;
>
> -       dpll |= DPLL_VCO_ENABLE;
> -       crtc_state->dpll_hw_state.dpll = dpll;
> -}
>
>  static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state)
>  {
> @@ -8740,207 +7797,6 @@ static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state)
>         intel_de_posting_read(dev_priv, PIPECONF(crtc->pipe));
>  }
>
> -static int i8xx_crtc_compute_clock(struct intel_crtc *crtc,
> -                                  struct intel_crtc_state *crtc_state)
> -{
> -       struct drm_device *dev = crtc->base.dev;
> -       struct drm_i915_private *dev_priv = to_i915(dev);
> -       const struct intel_limit *limit;
> -       int refclk = 48000;
> -
> -       memset(&crtc_state->dpll_hw_state, 0,
> -              sizeof(crtc_state->dpll_hw_state));
> -
> -       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> -               if (intel_panel_use_ssc(dev_priv)) {
> -                       refclk = dev_priv->vbt.lvds_ssc_freq;
> -                       drm_dbg_kms(&dev_priv->drm,
> -                                   "using SSC reference clock of %d kHz\n",
> -                                   refclk);
> -               }
> -
> -               limit = &intel_limits_i8xx_lvds;
> -       } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DVO)) {
> -               limit = &intel_limits_i8xx_dvo;
> -       } else {
> -               limit = &intel_limits_i8xx_dac;
> -       }
> -
> -       if (!crtc_state->clock_set &&
> -           !i9xx_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
> -                                refclk, NULL, &crtc_state->dpll)) {
> -               drm_err(&dev_priv->drm,
> -                       "Couldn't find PLL settings for mode!\n");
> -               return -EINVAL;
> -       }
> -
> -       i8xx_compute_dpll(crtc, crtc_state, NULL);
> -
> -       return 0;
> -}
> -
> -static int g4x_crtc_compute_clock(struct intel_crtc *crtc,
> -                                 struct intel_crtc_state *crtc_state)
> -{
> -       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -       const struct intel_limit *limit;
> -       int refclk = 96000;
> -
> -       memset(&crtc_state->dpll_hw_state, 0,
> -              sizeof(crtc_state->dpll_hw_state));
> -
> -       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> -               if (intel_panel_use_ssc(dev_priv)) {
> -                       refclk = dev_priv->vbt.lvds_ssc_freq;
> -                       drm_dbg_kms(&dev_priv->drm,
> -                                   "using SSC reference clock of %d kHz\n",
> -                                   refclk);
> -               }
> -
> -               if (intel_is_dual_link_lvds(dev_priv))
> -                       limit = &intel_limits_g4x_dual_channel_lvds;
> -               else
> -                       limit = &intel_limits_g4x_single_channel_lvds;
> -       } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) ||
> -                  intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) {
> -               limit = &intel_limits_g4x_hdmi;
> -       } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO)) {
> -               limit = &intel_limits_g4x_sdvo;
> -       } else {
> -               /* The option is for other outputs */
> -               limit = &intel_limits_i9xx_sdvo;
> -       }
> -
> -       if (!crtc_state->clock_set &&
> -           !g4x_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
> -                               refclk, NULL, &crtc_state->dpll)) {
> -               drm_err(&dev_priv->drm,
> -                       "Couldn't find PLL settings for mode!\n");
> -               return -EINVAL;
> -       }
> -
> -       i9xx_compute_dpll(crtc, crtc_state, NULL);
> -
> -       return 0;
> -}
> -
> -static int pnv_crtc_compute_clock(struct intel_crtc *crtc,
> -                                 struct intel_crtc_state *crtc_state)
> -{
> -       struct drm_device *dev = crtc->base.dev;
> -       struct drm_i915_private *dev_priv = to_i915(dev);
> -       const struct intel_limit *limit;
> -       int refclk = 96000;
> -
> -       memset(&crtc_state->dpll_hw_state, 0,
> -              sizeof(crtc_state->dpll_hw_state));
> -
> -       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> -               if (intel_panel_use_ssc(dev_priv)) {
> -                       refclk = dev_priv->vbt.lvds_ssc_freq;
> -                       drm_dbg_kms(&dev_priv->drm,
> -                                   "using SSC reference clock of %d kHz\n",
> -                                   refclk);
> -               }
> -
> -               limit = &pnv_limits_lvds;
> -       } else {
> -               limit = &pnv_limits_sdvo;
> -       }
> -
> -       if (!crtc_state->clock_set &&
> -           !pnv_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
> -                               refclk, NULL, &crtc_state->dpll)) {
> -               drm_err(&dev_priv->drm,
> -                       "Couldn't find PLL settings for mode!\n");
> -               return -EINVAL;
> -       }
> -
> -       i9xx_compute_dpll(crtc, crtc_state, NULL);
> -
> -       return 0;
> -}
> -
> -static int i9xx_crtc_compute_clock(struct intel_crtc *crtc,
> -                                  struct intel_crtc_state *crtc_state)
> -{
> -       struct drm_device *dev = crtc->base.dev;
> -       struct drm_i915_private *dev_priv = to_i915(dev);
> -       const struct intel_limit *limit;
> -       int refclk = 96000;
> -
> -       memset(&crtc_state->dpll_hw_state, 0,
> -              sizeof(crtc_state->dpll_hw_state));
> -
> -       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> -               if (intel_panel_use_ssc(dev_priv)) {
> -                       refclk = dev_priv->vbt.lvds_ssc_freq;
> -                       drm_dbg_kms(&dev_priv->drm,
> -                                   "using SSC reference clock of %d kHz\n",
> -                                   refclk);
> -               }
> -
> -               limit = &intel_limits_i9xx_lvds;
> -       } else {
> -               limit = &intel_limits_i9xx_sdvo;
> -       }
> -
> -       if (!crtc_state->clock_set &&
> -           !i9xx_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
> -                                refclk, NULL, &crtc_state->dpll)) {
> -               drm_err(&dev_priv->drm,
> -                       "Couldn't find PLL settings for mode!\n");
> -               return -EINVAL;
> -       }
> -
> -       i9xx_compute_dpll(crtc, crtc_state, NULL);
> -
> -       return 0;
> -}
> -
> -static int chv_crtc_compute_clock(struct intel_crtc *crtc,
> -                                 struct intel_crtc_state *crtc_state)
> -{
> -       int refclk = 100000;
> -       const struct intel_limit *limit = &intel_limits_chv;
> -       struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
> -
> -       memset(&crtc_state->dpll_hw_state, 0,
> -              sizeof(crtc_state->dpll_hw_state));
> -
> -       if (!crtc_state->clock_set &&
> -           !chv_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
> -                               refclk, NULL, &crtc_state->dpll)) {
> -               drm_err(&i915->drm, "Couldn't find PLL settings for mode!\n");
> -               return -EINVAL;
> -       }
> -
> -       chv_compute_dpll(crtc, crtc_state);
> -
> -       return 0;
> -}
> -
> -static int vlv_crtc_compute_clock(struct intel_crtc *crtc,
> -                                 struct intel_crtc_state *crtc_state)
> -{
> -       int refclk = 100000;
> -       const struct intel_limit *limit = &intel_limits_vlv;
> -       struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
> -
> -       memset(&crtc_state->dpll_hw_state, 0,
> -              sizeof(crtc_state->dpll_hw_state));
> -
> -       if (!crtc_state->clock_set &&
> -           !vlv_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
> -                               refclk, NULL, &crtc_state->dpll)) {
> -               drm_err(&i915->drm,  "Couldn't find PLL settings for mode!\n");
> -               return -EINVAL;
> -       }
> -
> -       vlv_compute_dpll(crtc, crtc_state);
> -
> -       return 0;
> -}
>
>  static bool i9xx_has_pfit(struct drm_i915_private *dev_priv)
>  {
> @@ -9951,172 +8807,6 @@ int ilk_get_lanes_required(int target_clock, int link_bw, int bpp)
>         return DIV_ROUND_UP(bps, link_bw * 8);
>  }
>
> -static bool ilk_needs_fb_cb_tune(struct dpll *dpll, int factor)
> -{
> -       return i9xx_dpll_compute_m(dpll) < factor * dpll->n;
> -}
> -
> -static void ilk_compute_dpll(struct intel_crtc *crtc,
> -                            struct intel_crtc_state *crtc_state,
> -                            struct dpll *reduced_clock)
> -{
> -       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -       u32 dpll, fp, fp2;
> -       int factor;
> -
> -       /* Enable autotuning of the PLL clock (if permissible) */
> -       factor = 21;
> -       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> -               if ((intel_panel_use_ssc(dev_priv) &&
> -                    dev_priv->vbt.lvds_ssc_freq == 100000) ||
> -                   (HAS_PCH_IBX(dev_priv) &&
> -                    intel_is_dual_link_lvds(dev_priv)))
> -                       factor = 25;
> -       } else if (crtc_state->sdvo_tv_clock) {
> -               factor = 20;
> -       }
> -
> -       fp = i9xx_dpll_compute_fp(&crtc_state->dpll);
> -
> -       if (ilk_needs_fb_cb_tune(&crtc_state->dpll, factor))
> -               fp |= FP_CB_TUNE;
> -
> -       if (reduced_clock) {
> -               fp2 = i9xx_dpll_compute_fp(reduced_clock);
> -
> -               if (reduced_clock->m < factor * reduced_clock->n)
> -                       fp2 |= FP_CB_TUNE;
> -       } else {
> -               fp2 = fp;
> -       }
> -
> -       dpll = 0;
> -
> -       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS))
> -               dpll |= DPLLB_MODE_LVDS;
> -       else
> -               dpll |= DPLLB_MODE_DAC_SERIAL;
> -
> -       dpll |= (crtc_state->pixel_multiplier - 1)
> -               << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
> -
> -       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO) ||
> -           intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
> -               dpll |= DPLL_SDVO_HIGH_SPEED;
> -
> -       if (intel_crtc_has_dp_encoder(crtc_state))
> -               dpll |= DPLL_SDVO_HIGH_SPEED;
> -
> -       /*
> -        * The high speed IO clock is only really required for
> -        * SDVO/HDMI/DP, but we also enable it for CRT to make it
> -        * possible to share the DPLL between CRT and HDMI. Enabling
> -        * the clock needlessly does no real harm, except use up a
> -        * bit of power potentially.
> -        *
> -        * We'll limit this to IVB with 3 pipes, since it has only two
> -        * DPLLs and so DPLL sharing is the only way to get three pipes
> -        * driving PCH ports at the same time. On SNB we could do this,
> -        * and potentially avoid enabling the second DPLL, but it's not
> -        * clear if it''s a win or loss power wise. No point in doing
> -        * this on ILK at all since it has a fixed DPLL<->pipe mapping.
> -        */
> -       if (INTEL_NUM_PIPES(dev_priv) == 3 &&
> -           intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG))
> -               dpll |= DPLL_SDVO_HIGH_SPEED;
> -
> -       /* compute bitmask from p1 value */
> -       dpll |= (1 << (crtc_state->dpll.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
> -       /* also FPA1 */
> -       dpll |= (1 << (crtc_state->dpll.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
> -
> -       switch (crtc_state->dpll.p2) {
> -       case 5:
> -               dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
> -               break;
> -       case 7:
> -               dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
> -               break;
> -       case 10:
> -               dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
> -               break;
> -       case 14:
> -               dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
> -               break;
> -       }
> -
> -       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) &&
> -           intel_panel_use_ssc(dev_priv))
> -               dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
> -       else
> -               dpll |= PLL_REF_INPUT_DREFCLK;
> -
> -       dpll |= DPLL_VCO_ENABLE;
> -
> -       crtc_state->dpll_hw_state.dpll = dpll;
> -       crtc_state->dpll_hw_state.fp0 = fp;
> -       crtc_state->dpll_hw_state.fp1 = fp2;
> -}
> -
> -static int ilk_crtc_compute_clock(struct intel_crtc *crtc,
> -                                 struct intel_crtc_state *crtc_state)
> -{
> -       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -       struct intel_atomic_state *state =
> -               to_intel_atomic_state(crtc_state->uapi.state);
> -       const struct intel_limit *limit;
> -       int refclk = 120000;
> -
> -       memset(&crtc_state->dpll_hw_state, 0,
> -              sizeof(crtc_state->dpll_hw_state));
> -
> -       /* CPU eDP is the only output that doesn't need a PCH PLL of its own. */
> -       if (!crtc_state->has_pch_encoder)
> -               return 0;
> -
> -       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> -               if (intel_panel_use_ssc(dev_priv)) {
> -                       drm_dbg_kms(&dev_priv->drm,
> -                                   "using SSC reference clock of %d kHz\n",
> -                                   dev_priv->vbt.lvds_ssc_freq);
> -                       refclk = dev_priv->vbt.lvds_ssc_freq;
> -               }
> -
> -               if (intel_is_dual_link_lvds(dev_priv)) {
> -                       if (refclk == 100000)
> -                               limit = &ilk_limits_dual_lvds_100m;
> -                       else
> -                               limit = &ilk_limits_dual_lvds;
> -               } else {
> -                       if (refclk == 100000)
> -                               limit = &ilk_limits_single_lvds_100m;
> -                       else
> -                               limit = &ilk_limits_single_lvds;
> -               }
> -       } else {
> -               limit = &ilk_limits_dac;
> -       }
> -
> -       if (!crtc_state->clock_set &&
> -           !g4x_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
> -                               refclk, NULL, &crtc_state->dpll)) {
> -               drm_err(&dev_priv->drm,
> -                       "Couldn't find PLL settings for mode!\n");
> -               return -EINVAL;
> -       }
> -
> -       ilk_compute_dpll(crtc, crtc_state, NULL);
> -
> -       if (!intel_reserve_shared_dplls(state, crtc, NULL)) {
> -               drm_dbg_kms(&dev_priv->drm,
> -                           "failed to find PLL for pipe %c\n",
> -                           pipe_name(crtc->pipe));
> -               return -EINVAL;
> -       }
> -
> -       return 0;
> -}
> -
>  static void intel_pch_transcoder_get_m_n(struct intel_crtc *crtc,
>                                          struct intel_link_m_n *m_n)
>  {
> @@ -10529,29 +9219,6 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc,
>         return ret;
>  }
>
> -static int hsw_crtc_compute_clock(struct intel_crtc *crtc,
> -                                 struct intel_crtc_state *crtc_state)
> -{
> -       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -       struct intel_atomic_state *state =
> -               to_intel_atomic_state(crtc_state->uapi.state);
> -
> -       if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI) ||
> -           INTEL_GEN(dev_priv) >= 11) {
> -               struct intel_encoder *encoder =
> -                       intel_get_crtc_new_encoder(state, crtc_state);
> -
> -               if (!intel_reserve_shared_dplls(state, crtc, encoder)) {
> -                       drm_dbg_kms(&dev_priv->drm,
> -                                   "failed to find PLL for pipe %c\n",
> -                                   pipe_name(crtc->pipe));
> -                       return -EINVAL;
> -               }
> -       }
> -
> -       return 0;
> -}
> -
>  static void dg1_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port,
>                             struct intel_crtc_state *pipe_config)
>  {
> @@ -16486,69 +15153,27 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv)
>  {
>         intel_init_cdclk_hooks(dev_priv);
>
> +       intel_init_clock_hook(dev_priv);
> +
>         if (INTEL_GEN(dev_priv) >= 9) {
>                 dev_priv->display.get_pipe_config = hsw_get_pipe_config;
> -               dev_priv->display.get_initial_plane_config =
> -                       skl_get_initial_plane_config;
> -               dev_priv->display.crtc_compute_clock = hsw_crtc_compute_clock;
>                 dev_priv->display.crtc_enable = hsw_crtc_enable;
>                 dev_priv->display.crtc_disable = hsw_crtc_disable;
>         } else if (HAS_DDI(dev_priv)) {
>                 dev_priv->display.get_pipe_config = hsw_get_pipe_config;
> -               dev_priv->display.get_initial_plane_config =
> -                       i9xx_get_initial_plane_config;
> -               dev_priv->display.crtc_compute_clock =
> -                       hsw_crtc_compute_clock;
>                 dev_priv->display.crtc_enable = hsw_crtc_enable;
>                 dev_priv->display.crtc_disable = hsw_crtc_disable;
>         } else if (HAS_PCH_SPLIT(dev_priv)) {
>                 dev_priv->display.get_pipe_config = ilk_get_pipe_config;
> -               dev_priv->display.get_initial_plane_config =
> -                       i9xx_get_initial_plane_config;
> -               dev_priv->display.crtc_compute_clock =
> -                       ilk_crtc_compute_clock;
>                 dev_priv->display.crtc_enable = ilk_crtc_enable;
>                 dev_priv->display.crtc_disable = ilk_crtc_disable;
> -       } else if (IS_CHERRYVIEW(dev_priv)) {
> -               dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
> -               dev_priv->display.get_initial_plane_config =
> -                       i9xx_get_initial_plane_config;
> -               dev_priv->display.crtc_compute_clock = chv_crtc_compute_clock;
> -               dev_priv->display.crtc_enable = valleyview_crtc_enable;
> -               dev_priv->display.crtc_disable = i9xx_crtc_disable;
> -       } else if (IS_VALLEYVIEW(dev_priv)) {
> +       } else if (IS_CHERRYVIEW(dev_priv) ||
> +                  IS_VALLEYVIEW(dev_priv)) {
>                 dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
> -               dev_priv->display.get_initial_plane_config =
> -                       i9xx_get_initial_plane_config;
> -               dev_priv->display.crtc_compute_clock = vlv_crtc_compute_clock;
>                 dev_priv->display.crtc_enable = valleyview_crtc_enable;
>                 dev_priv->display.crtc_disable = i9xx_crtc_disable;
> -       } else if (IS_G4X(dev_priv)) {
> -               dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
> -               dev_priv->display.get_initial_plane_config =
> -                       i9xx_get_initial_plane_config;
> -               dev_priv->display.crtc_compute_clock = g4x_crtc_compute_clock;
> -               dev_priv->display.crtc_enable = i9xx_crtc_enable;
> -               dev_priv->display.crtc_disable = i9xx_crtc_disable;
> -       } else if (IS_PINEVIEW(dev_priv)) {
> -               dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
> -               dev_priv->display.get_initial_plane_config =
> -                       i9xx_get_initial_plane_config;
> -               dev_priv->display.crtc_compute_clock = pnv_crtc_compute_clock;
> -               dev_priv->display.crtc_enable = i9xx_crtc_enable;
> -               dev_priv->display.crtc_disable = i9xx_crtc_disable;
> -       } else if (!IS_GEN(dev_priv, 2)) {
> -               dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
> -               dev_priv->display.get_initial_plane_config =
> -                       i9xx_get_initial_plane_config;
> -               dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock;
> -               dev_priv->display.crtc_enable = i9xx_crtc_enable;
> -               dev_priv->display.crtc_disable = i9xx_crtc_disable;
>         } else {
>                 dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
> -               dev_priv->display.get_initial_plane_config =
> -                       i9xx_get_initial_plane_config;
> -               dev_priv->display.crtc_compute_clock = i8xx_crtc_compute_clock;
>                 dev_priv->display.crtc_enable = i9xx_crtc_enable;
>                 dev_priv->display.crtc_disable = i9xx_crtc_disable;
>         }
> @@ -16562,10 +15187,13 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv)
>                 dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train;
>         }
>
> -       if (INTEL_GEN(dev_priv) >= 9)
> +       if (INTEL_GEN(dev_priv) >= 9) {
>                 dev_priv->display.commit_modeset_enables = skl_commit_modeset_enables;
> -       else
> +               dev_priv->display.get_initial_plane_config = skl_get_initial_plane_config;
> +       } else {
>                 dev_priv->display.commit_modeset_enables = intel_commit_modeset_enables;
> +               dev_priv->display.get_initial_plane_config = i9xx_get_initial_plane_config;
> +       }
>
>  }
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> index 0eba91d18e96..f1e36cca86c1 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.h
> +++ b/drivers/gpu/drm/i915/display/intel_display.h
> @@ -653,7 +653,9 @@ u32 intel_plane_compute_aligned_offset(int *x, int *y,
>                                        int color_plane);
>  int intel_plane_pin_fb(struct intel_plane_state *plane_state);
>  void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state);
> -
> +struct intel_encoder *
> +intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
> +                          const struct intel_crtc_state *crtc_state);
>  /* cursor */
>  struct intel_plane *
>  intel_cursor_plane_create(struct drm_i915_private *dev_priv,
> @@ -665,6 +667,15 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe);
>  struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc);
>  void intel_crtc_state_reset(struct intel_crtc_state *crtc_state,
>                             struct intel_crtc *crtc);
> +/* clock */
> +void intel_init_clock_hook(struct drm_i915_private *dev_priv);
> +int vlv_calc_dpll_params(int refclk, struct dpll *clock);
> +int pnv_calc_dpll_params(int refclk, struct dpll *clock);
> +int i9xx_calc_dpll_params(int refclk, struct dpll *clock);
> +void vlv_compute_dpll(struct intel_crtc *crtc,
> +                     struct intel_crtc_state *pipe_config);
> +void chv_compute_dpll(struct intel_crtc *crtc,
> +                     struct intel_crtc_state *pipe_config);
>
>  /* modesetting */
>  void intel_modeset_init_hw(struct drm_i915_private *i915);
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 5bc5bfbc4551..823083b231bc 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1799,4 +1799,9 @@ static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state)
>         return i915_ggtt_offset(state->vma);
>  }
>
> +static inline u32 i9xx_dpll_compute_fp(struct dpll *dpll)
> +{
> +       return dpll->n << 16 | dpll->m1 << 8 | dpll->m2;
> +}
> +
>  #endif /*  __INTEL_DISPLAY_TYPES_H__ */
> --
> 2.27.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2020-12-09 10:55 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-09  4:21 [Intel-gfx] [rfc] start slimming down intel_display.c Dave Airlie
2020-12-09  4:21 ` [Intel-gfx] [PATCH 1/4] drm/i915: refactor cursor code out of i915_display.c Dave Airlie
2020-12-09 11:07   ` Daniel Vetter
2020-12-09  4:21 ` [Intel-gfx] [PATCH 2/4] drm/i915: refactor some crtc code out of intel display Dave Airlie
2020-12-09 11:03   ` Daniel Vetter
2020-12-09  4:21 ` [Intel-gfx] [PATCH 3/4] drm/i915: refactor pll code out into intel_clock.c Dave Airlie
2020-12-09 10:55   ` Daniel Vetter [this message]
2020-12-09  4:21 ` [Intel-gfx] [PATCH 4/4] drm/i915: split fdi code out from intel_display.c Dave Airlie
2020-12-09 10:48   ` Daniel Vetter
2020-12-10  1:32     ` Dave Airlie
2020-12-09  4:56 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [1/4] drm/i915: refactor cursor code out of i915_display.c Patchwork
2020-12-09  5:26 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-12-09  6:41 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAKMK7uH-NiwDabhJa6nkQdgBLjWzEwbOkaJ1vPHQZgUSf=Z2FQ@mail.gmail.com' \
    --to=daniel@ffwll.ch \
    --cc=airlied@gmail.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.