提交 de13a2e3 编写于 作者: P Paulo Zanoni 提交者: Daniel Vetter

drm/i915: extract compute_dpll from ironlake_crtc_mode_set

Too many lines just to compute the value of a single variable, so
move this to its own function.
Signed-off-by: NPaulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: NRodrigo Vivi <rodrigo.vivi@gmail.com>
Signed-off-by: NDaniel Vetter <daniel.vetter@ffwll.ch>
上级 f48d8f23
...@@ -4783,53 +4783,39 @@ static void ironlake_set_m_n(struct drm_crtc *crtc, ...@@ -4783,53 +4783,39 @@ static void ironlake_set_m_n(struct drm_crtc *crtc,
I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n); I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n);
} }
static int ironlake_crtc_mode_set(struct drm_crtc *crtc, static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode, struct drm_display_mode *adjusted_mode,
int x, int y, intel_clock_t *clock, u32 fp)
struct drm_framebuffer *fb)
{ {
struct drm_crtc *crtc = &intel_crtc->base;
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *intel_encoder;
int pipe = intel_crtc->pipe; uint32_t dpll;
int plane = intel_crtc->plane; int factor, pixel_multiplier, num_connectors = 0;
int num_connectors = 0; bool is_lvds = false, is_sdvo = false, is_tv = false;
intel_clock_t clock, reduced_clock; bool is_dp = false, is_cpu_edp = false;
u32 dpll, fp = 0, fp2 = 0;
bool ok, has_reduced_clock = false, is_sdvo = false;
bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
struct intel_encoder *encoder;
u32 temp;
int ret, factor;
bool dither;
bool is_cpu_edp = false, is_pch_edp = false;
for_each_encoder_on_crtc(dev, crtc, encoder) { for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
switch (encoder->type) { switch (intel_encoder->type) {
case INTEL_OUTPUT_LVDS: case INTEL_OUTPUT_LVDS:
is_lvds = true; is_lvds = true;
break; break;
case INTEL_OUTPUT_SDVO: case INTEL_OUTPUT_SDVO:
case INTEL_OUTPUT_HDMI: case INTEL_OUTPUT_HDMI:
is_sdvo = true; is_sdvo = true;
if (encoder->needs_tv_clock) if (intel_encoder->needs_tv_clock)
is_tv = true; is_tv = true;
break; break;
case INTEL_OUTPUT_TVOUT: case INTEL_OUTPUT_TVOUT:
is_tv = true; is_tv = true;
break; break;
case INTEL_OUTPUT_ANALOG:
is_crt = true;
break;
case INTEL_OUTPUT_DISPLAYPORT: case INTEL_OUTPUT_DISPLAYPORT:
is_dp = true; is_dp = true;
break; break;
case INTEL_OUTPUT_EDP: case INTEL_OUTPUT_EDP:
is_dp = true; is_dp = true;
if (intel_encoder_is_pch_edp(&encoder->base)) if (!intel_encoder_is_pch_edp(&intel_encoder->base))
is_pch_edp = true;
else
is_cpu_edp = true; is_cpu_edp = true;
break; break;
} }
...@@ -4837,26 +4823,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, ...@@ -4837,26 +4823,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
num_connectors++; num_connectors++;
} }
ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock,
&has_reduced_clock, &reduced_clock);
if (!ok) {
DRM_ERROR("Couldn't find PLL settings for mode!\n");
return -EINVAL;
}
/* Ensure that the cursor is valid for the new mode before changing... */
intel_crtc_update_cursor(crtc, true);
/* determine panel color depth */
dither = intel_choose_pipe_bpp_dither(crtc, fb, &intel_crtc->bpp, mode);
if (is_lvds && dev_priv->lvds_dither)
dither = true;
fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
if (has_reduced_clock)
fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 |
reduced_clock.m2;
/* Enable autotuning of the PLL clock (if permissible) */ /* Enable autotuning of the PLL clock (if permissible) */
factor = 21; factor = 21;
if (is_lvds) { if (is_lvds) {
...@@ -4867,7 +4833,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, ...@@ -4867,7 +4833,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
} else if (is_sdvo && is_tv) } else if (is_sdvo && is_tv)
factor = 20; factor = 20;
if (clock.m < factor * clock.n) if (clock->m < factor * clock->n)
fp |= FP_CB_TUNE; fp |= FP_CB_TUNE;
dpll = 0; dpll = 0;
...@@ -4877,7 +4843,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, ...@@ -4877,7 +4843,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
else else
dpll |= DPLLB_MODE_DAC_SERIAL; dpll |= DPLLB_MODE_DAC_SERIAL;
if (is_sdvo) { if (is_sdvo) {
int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
if (pixel_multiplier > 1) { if (pixel_multiplier > 1) {
dpll |= (pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; dpll |= (pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
} }
...@@ -4887,11 +4853,11 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, ...@@ -4887,11 +4853,11 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
dpll |= DPLL_DVO_HIGH_SPEED; dpll |= DPLL_DVO_HIGH_SPEED;
/* compute bitmask from p1 value */ /* compute bitmask from p1 value */
dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
/* also FPA1 */ /* also FPA1 */
dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
switch (clock.p2) { switch (clock->p2) {
case 5: case 5:
dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5; dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
break; break;
...@@ -4917,6 +4883,85 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, ...@@ -4917,6 +4883,85 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
else else
dpll |= PLL_REF_INPUT_DREFCLK; dpll |= PLL_REF_INPUT_DREFCLK;
return dpll;
}
static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode,
int x, int y,
struct drm_framebuffer *fb)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int pipe = intel_crtc->pipe;
int plane = intel_crtc->plane;
int num_connectors = 0;
intel_clock_t clock, reduced_clock;
u32 dpll, fp = 0, fp2 = 0;
bool ok, has_reduced_clock = false, is_sdvo = false;
bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
struct intel_encoder *encoder;
u32 temp;
int ret;
bool dither;
bool is_cpu_edp = false, is_pch_edp = false;
for_each_encoder_on_crtc(dev, crtc, encoder) {
switch (encoder->type) {
case INTEL_OUTPUT_LVDS:
is_lvds = true;
break;
case INTEL_OUTPUT_SDVO:
case INTEL_OUTPUT_HDMI:
is_sdvo = true;
if (encoder->needs_tv_clock)
is_tv = true;
break;
case INTEL_OUTPUT_TVOUT:
is_tv = true;
break;
case INTEL_OUTPUT_ANALOG:
is_crt = true;
break;
case INTEL_OUTPUT_DISPLAYPORT:
is_dp = true;
break;
case INTEL_OUTPUT_EDP:
is_dp = true;
if (intel_encoder_is_pch_edp(&encoder->base))
is_pch_edp = true;
else
is_cpu_edp = true;
break;
}
num_connectors++;
}
ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock,
&has_reduced_clock, &reduced_clock);
if (!ok) {
DRM_ERROR("Couldn't find PLL settings for mode!\n");
return -EINVAL;
}
/* Ensure that the cursor is valid for the new mode before changing... */
intel_crtc_update_cursor(crtc, true);
/* determine panel color depth */
dither = intel_choose_pipe_bpp_dither(crtc, fb, &intel_crtc->bpp, mode);
if (is_lvds && dev_priv->lvds_dither)
dither = true;
fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
if (has_reduced_clock)
fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 |
reduced_clock.m2;
dpll = ironlake_compute_dpll(intel_crtc, adjusted_mode, &clock, fp);
DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe); DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
drm_mode_debug_printmodeline(mode); drm_mode_debug_printmodeline(mode);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册