diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2009-10-08 13:36:21 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-10-11 23:42:40 -0400 |
commit | 2606c88608122339cbd5c6b5c149a2eb74ccfe9e (patch) | |
tree | a8e113878e3fe0178729af711333873dffb70918 /drivers/gpu | |
parent | 5f9a0eb5af16906cd31fc3e02746aa3d61fd3aa9 (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.c | 36 |
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 | ||