drm/i915: extract compute_clocks from ironlake_crtc_mode_set
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> [danvet: resolved conflicts due to missing some earlier patches.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
Родитель
a1f9e77e1f
Коммит
6591c6e4d7
|
@ -4692,6 +4692,69 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc,
|
||||||
POSTING_READ(PIPECONF(pipe));
|
POSTING_READ(PIPECONF(pipe));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ironlake_compute_clocks(struct drm_crtc *crtc,
|
||||||
|
struct drm_display_mode *adjusted_mode,
|
||||||
|
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;
|
||||||
|
struct intel_encoder *intel_encoder;
|
||||||
|
int refclk;
|
||||||
|
const intel_limit_t *limit;
|
||||||
|
bool ret, is_sdvo = false, is_tv = false, is_lvds = false;
|
||||||
|
|
||||||
|
for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
|
||||||
|
switch (intel_encoder->type) {
|
||||||
|
case INTEL_OUTPUT_LVDS:
|
||||||
|
is_lvds = true;
|
||||||
|
break;
|
||||||
|
case INTEL_OUTPUT_SDVO:
|
||||||
|
case INTEL_OUTPUT_HDMI:
|
||||||
|
is_sdvo = true;
|
||||||
|
if (intel_encoder->needs_tv_clock)
|
||||||
|
is_tv = true;
|
||||||
|
break;
|
||||||
|
case INTEL_OUTPUT_TVOUT:
|
||||||
|
is_tv = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
refclk = ironlake_get_refclk(crtc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
limit = intel_limit(crtc, refclk);
|
||||||
|
ret = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL,
|
||||||
|
clock);
|
||||||
|
if (!ret)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (is_lvds && dev_priv->lvds_downclock_avail) {
|
||||||
|
/*
|
||||||
|
* Ensure we match the reduced clock's P to the target clock.
|
||||||
|
* If the clocks don't match, we can't switch the display clock
|
||||||
|
* by using the FP0/FP1. In such case we will disable the LVDS
|
||||||
|
* downclock feature.
|
||||||
|
*/
|
||||||
|
*has_reduced_clock = limit->find_pll(limit, crtc,
|
||||||
|
dev_priv->lvds_downclock,
|
||||||
|
refclk,
|
||||||
|
clock,
|
||||||
|
reduced_clock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_sdvo && is_tv)
|
||||||
|
i9xx_adjust_sdvo_tv_clock(adjusted_mode, clock);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
|
static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
|
||||||
struct drm_display_mode *mode,
|
struct drm_display_mode *mode,
|
||||||
struct drm_display_mode *adjusted_mode,
|
struct drm_display_mode *adjusted_mode,
|
||||||
|
@ -4703,13 +4766,12 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
|
||||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||||
int pipe = intel_crtc->pipe;
|
int pipe = intel_crtc->pipe;
|
||||||
int plane = intel_crtc->plane;
|
int plane = intel_crtc->plane;
|
||||||
int refclk, num_connectors = 0;
|
int num_connectors = 0;
|
||||||
intel_clock_t clock, reduced_clock;
|
intel_clock_t clock, reduced_clock;
|
||||||
u32 dpll, fp = 0, fp2 = 0;
|
u32 dpll, fp = 0, fp2 = 0;
|
||||||
bool ok, has_reduced_clock = false, is_sdvo = false;
|
bool ok, has_reduced_clock = false, is_sdvo = false;
|
||||||
bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
|
bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
|
||||||
struct intel_encoder *encoder, *edp_encoder = NULL;
|
struct intel_encoder *encoder, *edp_encoder = NULL;
|
||||||
const intel_limit_t *limit;
|
|
||||||
int ret;
|
int ret;
|
||||||
struct fdi_m_n m_n = {0};
|
struct fdi_m_n m_n = {0};
|
||||||
u32 temp;
|
u32 temp;
|
||||||
|
@ -4751,16 +4813,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
|
||||||
num_connectors++;
|
num_connectors++;
|
||||||
}
|
}
|
||||||
|
|
||||||
refclk = ironlake_get_refclk(crtc);
|
ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock,
|
||||||
|
&has_reduced_clock, &reduced_clock);
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
limit = intel_limit(crtc, refclk);
|
|
||||||
ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL,
|
|
||||||
&clock);
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
DRM_ERROR("Couldn't find PLL settings for mode!\n");
|
DRM_ERROR("Couldn't find PLL settings for mode!\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -4769,24 +4823,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
|
||||||
/* Ensure that the cursor is valid for the new mode before changing... */
|
/* Ensure that the cursor is valid for the new mode before changing... */
|
||||||
intel_crtc_update_cursor(crtc, true);
|
intel_crtc_update_cursor(crtc, true);
|
||||||
|
|
||||||
if (is_lvds && dev_priv->lvds_downclock_avail) {
|
|
||||||
/*
|
|
||||||
* Ensure we match the reduced clock's P to the target clock.
|
|
||||||
* If the clocks don't match, we can't switch the display clock
|
|
||||||
* by using the FP0/FP1. In such case we will disable the LVDS
|
|
||||||
* downclock feature.
|
|
||||||
*/
|
|
||||||
has_reduced_clock = limit->find_pll(limit, crtc,
|
|
||||||
dev_priv->lvds_downclock,
|
|
||||||
refclk,
|
|
||||||
&clock,
|
|
||||||
&reduced_clock);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_sdvo && is_tv)
|
|
||||||
i9xx_adjust_sdvo_tv_clock(adjusted_mode, &clock);
|
|
||||||
|
|
||||||
|
|
||||||
/* FDI link */
|
/* FDI link */
|
||||||
pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
|
pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
|
||||||
lane = 0;
|
lane = 0;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче