aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2009-10-08 13:36:21 -0400
committerDave Airlie <airlied@redhat.com>2009-10-11 23:42:40 -0400
commit2606c88608122339cbd5c6b5c149a2eb74ccfe9e (patch)
treea8e113878e3fe0178729af711333873dffb70918 /drivers/gpu
parent5f9a0eb5af16906cd31fc3e02746aa3d61fd3aa9 (diff)
drm/radeon/kms/atom: add support for AdjustDisplayPll
DCE3+ has an AdjustDisplayPll that will adjust the pixel clock accordingly based on the encoder/transmitter to handle special hw requirements. Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 0a5082af3cd3..d5e6f3da116c 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -333,12 +333,13 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
333 struct drm_encoder *encoder = NULL; 333 struct drm_encoder *encoder = NULL;
334 struct radeon_encoder *radeon_encoder = NULL; 334 struct radeon_encoder *radeon_encoder = NULL;
335 uint8_t frev, crev; 335 uint8_t frev, crev;
336 int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); 336 int index;
337 SET_PIXEL_CLOCK_PS_ALLOCATION args; 337 SET_PIXEL_CLOCK_PS_ALLOCATION args;
338 PIXEL_CLOCK_PARAMETERS *spc1_ptr; 338 PIXEL_CLOCK_PARAMETERS *spc1_ptr;
339 PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr; 339 PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr;
340 PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr; 340 PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr;
341 uint32_t sclock = mode->clock; 341 uint32_t pll_clock = mode->clock;
342 uint32_t adjusted_clock;
342 uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; 343 uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
343 struct radeon_pll *pll; 344 struct radeon_pll *pll;
344 int pll_flags = 0; 345 int pll_flags = 0;
@@ -393,12 +394,34 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
393 } 394 }
394 } 395 }
395 396
397 /* DCE3+ has an AdjustDisplayPll that will adjust the pixel clock
398 * accordingly based on the encoder/transmitter to work around
399 * special hw requirements.
400 */
401 if (ASIC_IS_DCE3(rdev)) {
402 ADJUST_DISPLAY_PLL_PS_ALLOCATION adjust_pll_args;
403
404 if (!encoder)
405 return;
406
407 memset(&adjust_pll_args, 0, sizeof(adjust_pll_args));
408 adjust_pll_args.usPixelClock = cpu_to_le16(mode->clock / 10);
409 adjust_pll_args.ucTransmitterID = radeon_encoder->encoder_id;
410 adjust_pll_args.ucEncodeMode = atombios_get_encoder_mode(encoder);
411
412 index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
413 atom_execute_table(rdev->mode_info.atom_context,
414 index, (uint32_t *)&adjust_pll_args);
415 adjusted_clock = le16_to_cpu(adjust_pll_args.usPixelClock) * 10;
416 } else
417 adjusted_clock = mode->clock;
418
396 if (radeon_crtc->crtc_id == 0) 419 if (radeon_crtc->crtc_id == 0)
397 pll = &rdev->clock.p1pll; 420 pll = &rdev->clock.p1pll;
398 else 421 else
399 pll = &rdev->clock.p2pll; 422 pll = &rdev->clock.p2pll;
400 423
401 radeon_compute_pll(pll, mode->clock, &sclock, &fb_div, &frac_fb_div, 424 radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
402 &ref_div, &post_div, pll_flags); 425 &ref_div, &post_div, pll_flags);
403 426
404 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, 427 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
@@ -409,7 +432,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
409 switch (crev) { 432 switch (crev) {
410 case 1: 433 case 1:
411 spc1_ptr = (PIXEL_CLOCK_PARAMETERS *) & args.sPCLKInput; 434 spc1_ptr = (PIXEL_CLOCK_PARAMETERS *) & args.sPCLKInput;
412 spc1_ptr->usPixelClock = cpu_to_le16(sclock); 435 spc1_ptr->usPixelClock = cpu_to_le16(mode->clock / 10);
413 spc1_ptr->usRefDiv = cpu_to_le16(ref_div); 436 spc1_ptr->usRefDiv = cpu_to_le16(ref_div);
414 spc1_ptr->usFbDiv = cpu_to_le16(fb_div); 437 spc1_ptr->usFbDiv = cpu_to_le16(fb_div);
415 spc1_ptr->ucFracFbDiv = frac_fb_div; 438 spc1_ptr->ucFracFbDiv = frac_fb_div;
@@ -422,7 +445,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
422 case 2: 445 case 2:
423 spc2_ptr = 446 spc2_ptr =
424 (PIXEL_CLOCK_PARAMETERS_V2 *) & args.sPCLKInput; 447 (PIXEL_CLOCK_PARAMETERS_V2 *) & args.sPCLKInput;
425 spc2_ptr->usPixelClock = cpu_to_le16(sclock); 448 spc2_ptr->usPixelClock = cpu_to_le16(mode->clock / 10);
426 spc2_ptr->usRefDiv = cpu_to_le16(ref_div); 449 spc2_ptr->usRefDiv = cpu_to_le16(ref_div);
427 spc2_ptr->usFbDiv = cpu_to_le16(fb_div); 450 spc2_ptr->usFbDiv = cpu_to_le16(fb_div);
428 spc2_ptr->ucFracFbDiv = frac_fb_div; 451 spc2_ptr->ucFracFbDiv = frac_fb_div;
@@ -437,7 +460,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
437 return; 460 return;
438 spc3_ptr = 461 spc3_ptr =
439 (PIXEL_CLOCK_PARAMETERS_V3 *) & args.sPCLKInput; 462 (PIXEL_CLOCK_PARAMETERS_V3 *) & args.sPCLKInput;
440 spc3_ptr->usPixelClock = cpu_to_le16(sclock); 463 spc3_ptr->usPixelClock = cpu_to_le16(mode->clock / 10);
441 spc3_ptr->usRefDiv = cpu_to_le16(ref_div); 464 spc3_ptr->usRefDiv = cpu_to_le16(ref_div);
442 spc3_ptr->usFbDiv = cpu_to_le16(fb_div); 465 spc3_ptr->usFbDiv = cpu_to_le16(fb_div);
443 spc3_ptr->ucFracFbDiv = frac_fb_div; 466 spc3_ptr->ucFracFbDiv = frac_fb_div;
@@ -460,6 +483,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
460 } 483 }
461 484
462 printk("executing set pll\n"); 485 printk("executing set pll\n");
486 index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
463 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 487 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
464} 488}
465 489