|
@@ -846,6 +846,11 @@ pnv_find_best_dpll(const intel_limit_t *limit,
|
|
return (err != target);
|
|
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.
|
|
|
|
+ */
|
|
static bool
|
|
static bool
|
|
g4x_find_best_dpll(const intel_limit_t *limit,
|
|
g4x_find_best_dpll(const intel_limit_t *limit,
|
|
struct intel_crtc_state *crtc_state,
|
|
struct intel_crtc_state *crtc_state,
|
|
@@ -8628,55 +8633,6 @@ static void haswell_set_pipemisc(struct drm_crtc *crtc)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-static bool ironlake_compute_clocks(struct drm_crtc *crtc,
|
|
|
|
- struct intel_crtc_state *crtc_state,
|
|
|
|
- intel_clock_t *clock,
|
|
|
|
- bool *has_reduced_clock,
|
|
|
|
- intel_clock_t *reduced_clock)
|
|
|
|
-{
|
|
|
|
- struct drm_device *dev = crtc->dev;
|
|
|
|
- struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
- int refclk;
|
|
|
|
- const intel_limit_t *limit;
|
|
|
|
- bool ret;
|
|
|
|
-
|
|
|
|
- refclk = 120000;
|
|
|
|
-
|
|
|
|
- if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
|
|
|
|
- if (intel_panel_use_ssc(dev_priv)) {
|
|
|
|
- DRM_DEBUG_KMS("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)) {
|
|
|
|
- if (refclk == 100000)
|
|
|
|
- limit = &intel_limits_ironlake_dual_lvds_100m;
|
|
|
|
- else
|
|
|
|
- limit = &intel_limits_ironlake_dual_lvds;
|
|
|
|
- } else {
|
|
|
|
- if (refclk == 100000)
|
|
|
|
- limit = &intel_limits_ironlake_single_lvds_100m;
|
|
|
|
- else
|
|
|
|
- limit = &intel_limits_ironlake_single_lvds;
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- limit = &intel_limits_ironlake_dac;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * 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.
|
|
|
|
- */
|
|
|
|
- ret = g4x_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
|
|
|
|
- refclk, NULL, clock);
|
|
|
|
- if (!ret)
|
|
|
|
- return false;
|
|
|
|
-
|
|
|
|
- return true;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp)
|
|
int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp)
|
|
{
|
|
{
|
|
/*
|
|
/*
|
|
@@ -8801,9 +8757,13 @@ static void ironlake_compute_dpll(struct intel_crtc *intel_crtc,
|
|
static int ironlake_crtc_compute_clock(struct intel_crtc *crtc,
|
|
static int ironlake_crtc_compute_clock(struct intel_crtc *crtc,
|
|
struct intel_crtc_state *crtc_state)
|
|
struct intel_crtc_state *crtc_state)
|
|
{
|
|
{
|
|
|
|
+ struct drm_device *dev = crtc->base.dev;
|
|
|
|
+ struct drm_i915_private *dev_priv = dev->dev_private;
|
|
intel_clock_t reduced_clock;
|
|
intel_clock_t reduced_clock;
|
|
bool has_reduced_clock = false;
|
|
bool has_reduced_clock = false;
|
|
struct intel_shared_dpll *pll;
|
|
struct intel_shared_dpll *pll;
|
|
|
|
+ const intel_limit_t *limit;
|
|
|
|
+ int refclk = 120000;
|
|
|
|
|
|
memset(&crtc_state->dpll_hw_state, 0,
|
|
memset(&crtc_state->dpll_hw_state, 0,
|
|
sizeof(crtc_state->dpll_hw_state));
|
|
sizeof(crtc_state->dpll_hw_state));
|
|
@@ -8814,11 +8774,31 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc,
|
|
if (!crtc_state->has_pch_encoder)
|
|
if (!crtc_state->has_pch_encoder)
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
|
|
+ if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
|
|
|
|
+ if (intel_panel_use_ssc(dev_priv)) {
|
|
|
|
+ DRM_DEBUG_KMS("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)) {
|
|
|
|
+ if (refclk == 100000)
|
|
|
|
+ limit = &intel_limits_ironlake_dual_lvds_100m;
|
|
|
|
+ else
|
|
|
|
+ limit = &intel_limits_ironlake_dual_lvds;
|
|
|
|
+ } else {
|
|
|
|
+ if (refclk == 100000)
|
|
|
|
+ limit = &intel_limits_ironlake_single_lvds_100m;
|
|
|
|
+ else
|
|
|
|
+ limit = &intel_limits_ironlake_single_lvds;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ limit = &intel_limits_ironlake_dac;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (!crtc_state->clock_set &&
|
|
if (!crtc_state->clock_set &&
|
|
- !ironlake_compute_clocks(&crtc->base, crtc_state,
|
|
|
|
- &crtc_state->dpll,
|
|
|
|
- &has_reduced_clock,
|
|
|
|
- &reduced_clock)) {
|
|
|
|
|
|
+ !g4x_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
|
|
|
|
+ refclk, NULL, &crtc_state->dpll)) {
|
|
DRM_ERROR("Couldn't find PLL settings for mode!\n");
|
|
DRM_ERROR("Couldn't find PLL settings for mode!\n");
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
}
|
|
}
|