aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhao Yakui <yakui.zhao@intel.com>2010-01-06 09:05:56 -0500
committerEric Anholt <eric@anholt.net>2010-01-07 13:26:44 -0500
commitddc9003c357d1ce10be6ec91bdb8df8ea836087d (patch)
tree722961e309fa96fc55dae6a5438cf299685c3505
parent40f33a92100f4d9b6e85ad642100cfe42d7ff57d (diff)
drm/i915: Use find_pll function to calculate DPLL setting for LVDS downclock
For any given clock we can use the find_pll to get the corresponding DPLL setting. It is unnecessary to use the find_reduce_pll callback function to calculate the DPLL parameter for LVDS downclock in order to get the same divider factor(P) for the normal and downclock. In theory when the LVDS downclock is supported by LVDS panel, we should get the same DPLL divider factor(P) for the normal clock and reduced downclock. If we get the diferent divider factor(P) for normal clock and reduced downclock, it means that the found downclock is incorrect and should be discarded. So we should use find_pll callback to calculate the DPLL parameter for the LVDS reduced downclock as for the normal clock. Then we can do the cleanup about find_reduced_pll. Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> cc: Jesse Barnes <jbarnes@virtuousgeek.org> cc: Matthew Garrett <mjg@redhat.com> Signed-off-by: Eric Anholt <eric@anholt.net>
-rw-r--r--drivers/gpu/drm/i915/intel_display.c61
1 files changed, 2 insertions, 59 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 002612fae717..0cf44d6e9deb 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -70,8 +70,6 @@ struct intel_limit {
70 intel_p2_t p2; 70 intel_p2_t p2;
71 bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, 71 bool (* find_pll)(const intel_limit_t *, struct drm_crtc *,
72 int, int, intel_clock_t *); 72 int, int, intel_clock_t *);
73 bool (* find_reduced_pll)(const intel_limit_t *, struct drm_crtc *,
74 int, int, intel_clock_t *);
75}; 73};
76 74
77#define I8XX_DOT_MIN 25000 75#define I8XX_DOT_MIN 25000
@@ -274,9 +272,6 @@ static bool
274intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, 272intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
275 int target, int refclk, intel_clock_t *best_clock); 273 int target, int refclk, intel_clock_t *best_clock);
276static bool 274static bool
277intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
278 int target, int refclk, intel_clock_t *best_clock);
279static bool
280intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, 275intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
281 int target, int refclk, intel_clock_t *best_clock); 276 int target, int refclk, intel_clock_t *best_clock);
282 277
@@ -299,7 +294,6 @@ static const intel_limit_t intel_limits_i8xx_dvo = {
299 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, 294 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
300 .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, 295 .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST },
301 .find_pll = intel_find_best_PLL, 296 .find_pll = intel_find_best_PLL,
302 .find_reduced_pll = intel_find_best_reduced_PLL,
303}; 297};
304 298
305static const intel_limit_t intel_limits_i8xx_lvds = { 299static const intel_limit_t intel_limits_i8xx_lvds = {
@@ -314,7 +308,6 @@ static const intel_limit_t intel_limits_i8xx_lvds = {
314 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, 308 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
315 .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, 309 .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST },
316 .find_pll = intel_find_best_PLL, 310 .find_pll = intel_find_best_PLL,
317 .find_reduced_pll = intel_find_best_reduced_PLL,
318}; 311};
319 312
320static const intel_limit_t intel_limits_i9xx_sdvo = { 313static const intel_limit_t intel_limits_i9xx_sdvo = {
@@ -329,7 +322,6 @@ static const intel_limit_t intel_limits_i9xx_sdvo = {
329 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, 322 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
330 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, 323 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
331 .find_pll = intel_find_best_PLL, 324 .find_pll = intel_find_best_PLL,
332 .find_reduced_pll = intel_find_best_reduced_PLL,
333}; 325};
334 326
335static const intel_limit_t intel_limits_i9xx_lvds = { 327static const intel_limit_t intel_limits_i9xx_lvds = {
@@ -347,7 +339,6 @@ static const intel_limit_t intel_limits_i9xx_lvds = {
347 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, 339 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
348 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, 340 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST },
349 .find_pll = intel_find_best_PLL, 341 .find_pll = intel_find_best_PLL,
350 .find_reduced_pll = intel_find_best_reduced_PLL,
351}; 342};
352 343
353 /* below parameter and function is for G4X Chipset Family*/ 344 /* below parameter and function is for G4X Chipset Family*/
@@ -365,7 +356,6 @@ static const intel_limit_t intel_limits_g4x_sdvo = {
365 .p2_fast = G4X_P2_SDVO_FAST 356 .p2_fast = G4X_P2_SDVO_FAST
366 }, 357 },
367 .find_pll = intel_g4x_find_best_PLL, 358 .find_pll = intel_g4x_find_best_PLL,
368 .find_reduced_pll = intel_g4x_find_best_PLL,
369}; 359};
370 360
371static const intel_limit_t intel_limits_g4x_hdmi = { 361static const intel_limit_t intel_limits_g4x_hdmi = {
@@ -382,7 +372,6 @@ static const intel_limit_t intel_limits_g4x_hdmi = {
382 .p2_fast = G4X_P2_HDMI_DAC_FAST 372 .p2_fast = G4X_P2_HDMI_DAC_FAST
383 }, 373 },
384 .find_pll = intel_g4x_find_best_PLL, 374 .find_pll = intel_g4x_find_best_PLL,
385 .find_reduced_pll = intel_g4x_find_best_PLL,
386}; 375};
387 376
388static const intel_limit_t intel_limits_g4x_single_channel_lvds = { 377static const intel_limit_t intel_limits_g4x_single_channel_lvds = {
@@ -407,7 +396,6 @@ static const intel_limit_t intel_limits_g4x_single_channel_lvds = {
407 .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST 396 .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST
408 }, 397 },
409 .find_pll = intel_g4x_find_best_PLL, 398 .find_pll = intel_g4x_find_best_PLL,
410 .find_reduced_pll = intel_g4x_find_best_PLL,
411}; 399};
412 400
413static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { 401static const intel_limit_t intel_limits_g4x_dual_channel_lvds = {
@@ -432,7 +420,6 @@ static const intel_limit_t intel_limits_g4x_dual_channel_lvds = {
432 .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST 420 .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST
433 }, 421 },
434 .find_pll = intel_g4x_find_best_PLL, 422 .find_pll = intel_g4x_find_best_PLL,
435 .find_reduced_pll = intel_g4x_find_best_PLL,
436}; 423};
437 424
438static const intel_limit_t intel_limits_g4x_display_port = { 425static const intel_limit_t intel_limits_g4x_display_port = {
@@ -470,7 +457,6 @@ static const intel_limit_t intel_limits_pineview_sdvo = {
470 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, 457 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
471 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, 458 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
472 .find_pll = intel_find_best_PLL, 459 .find_pll = intel_find_best_PLL,
473 .find_reduced_pll = intel_find_best_reduced_PLL,
474}; 460};
475 461
476static const intel_limit_t intel_limits_pineview_lvds = { 462static const intel_limit_t intel_limits_pineview_lvds = {
@@ -486,7 +472,6 @@ static const intel_limit_t intel_limits_pineview_lvds = {
486 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, 472 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
487 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, 473 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW },
488 .find_pll = intel_find_best_PLL, 474 .find_pll = intel_find_best_PLL,
489 .find_reduced_pll = intel_find_best_reduced_PLL,
490}; 475};
491 476
492static const intel_limit_t intel_limits_ironlake_sdvo = { 477static const intel_limit_t intel_limits_ironlake_sdvo = {
@@ -768,46 +753,6 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
768 return (err != target); 753 return (err != target);
769} 754}
770 755
771
772static bool
773intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
774 int target, int refclk, intel_clock_t *best_clock)
775
776{
777 struct drm_device *dev = crtc->dev;
778 intel_clock_t clock;
779 int err = target;
780 bool found = false;
781
782 memcpy(&clock, best_clock, sizeof(intel_clock_t));
783
784 for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
785 for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) {
786 /* m1 is always 0 in Pineview */
787 if (clock.m2 >= clock.m1 && !IS_PINEVIEW(dev))
788 break;
789 for (clock.n = limit->n.min; clock.n <= limit->n.max;
790 clock.n++) {
791 int this_err;
792
793 intel_clock(dev, refclk, &clock);
794
795 if (!intel_PLL_is_valid(crtc, &clock))
796 continue;
797
798 this_err = abs(clock.dot - target);
799 if (this_err < err) {
800 *best_clock = clock;
801 err = this_err;
802 found = true;
803 }
804 }
805 }
806 }
807
808 return found;
809}
810
811static bool 756static bool
812intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, 757intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
813 int target, int refclk, intel_clock_t *best_clock) 758 int target, int refclk, intel_clock_t *best_clock)
@@ -2910,10 +2855,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
2910 return -EINVAL; 2855 return -EINVAL;
2911 } 2856 }
2912 2857
2913 if (is_lvds && limit->find_reduced_pll && 2858 if (is_lvds && dev_priv->lvds_downclock_avail) {
2914 dev_priv->lvds_downclock_avail) { 2859 has_reduced_clock = limit->find_pll(limit, crtc,
2915 memcpy(&reduced_clock, &clock, sizeof(intel_clock_t));
2916 has_reduced_clock = limit->find_reduced_pll(limit, crtc,
2917 dev_priv->lvds_downclock, 2860 dev_priv->lvds_downclock,
2918 refclk, 2861 refclk,
2919 &reduced_clock); 2862 &reduced_clock);