diff options
| author | Alex Deucher <alexander.deucher@amd.com> | 2012-09-13 10:56:16 -0400 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2012-09-20 13:10:44 -0400 |
| commit | 19eca43e5a52a8e47fdd40e940912b2417c7c055 (patch) | |
| tree | 9ca6f599f97728f13be6f4abe81829973d1c302a | |
| parent | 2f454cf1261ba913e2f660b7555864b340502c60 (diff) | |
drm/radeon: rework crtc pll setup to better support PPLL sharing
We need the calculate the pixel clock before allocating a PPLL
in order to insure the clocks really match.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
| -rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 221 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 32 |
2 files changed, 150 insertions, 103 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 2f7cc9e3b175..cf8ac5a5d8ca 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
| @@ -533,11 +533,9 @@ union adjust_pixel_clock { | |||
| 533 | }; | 533 | }; |
| 534 | 534 | ||
| 535 | static u32 atombios_adjust_pll(struct drm_crtc *crtc, | 535 | static u32 atombios_adjust_pll(struct drm_crtc *crtc, |
| 536 | struct drm_display_mode *mode, | 536 | struct drm_display_mode *mode) |
| 537 | struct radeon_pll *pll, | ||
| 538 | bool ss_enabled, | ||
| 539 | struct radeon_atom_ss *ss) | ||
| 540 | { | 537 | { |
| 538 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
| 541 | struct drm_device *dev = crtc->dev; | 539 | struct drm_device *dev = crtc->dev; |
| 542 | struct radeon_device *rdev = dev->dev_private; | 540 | struct radeon_device *rdev = dev->dev_private; |
| 543 | struct drm_encoder *encoder = NULL; | 541 | struct drm_encoder *encoder = NULL; |
| @@ -550,32 +548,32 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 550 | bool is_duallink = false; | 548 | bool is_duallink = false; |
| 551 | 549 | ||
| 552 | /* reset the pll flags */ | 550 | /* reset the pll flags */ |
| 553 | pll->flags = 0; | 551 | radeon_crtc->pll_flags = 0; |
| 554 | 552 | ||
| 555 | if (ASIC_IS_AVIVO(rdev)) { | 553 | if (ASIC_IS_AVIVO(rdev)) { |
| 556 | if ((rdev->family == CHIP_RS600) || | 554 | if ((rdev->family == CHIP_RS600) || |
| 557 | (rdev->family == CHIP_RS690) || | 555 | (rdev->family == CHIP_RS690) || |
| 558 | (rdev->family == CHIP_RS740)) | 556 | (rdev->family == CHIP_RS740)) |
| 559 | pll->flags |= (/*RADEON_PLL_USE_FRAC_FB_DIV |*/ | 557 | radeon_crtc->pll_flags |= (/*RADEON_PLL_USE_FRAC_FB_DIV |*/ |
| 560 | RADEON_PLL_PREFER_CLOSEST_LOWER); | 558 | RADEON_PLL_PREFER_CLOSEST_LOWER); |
| 561 | 559 | ||
| 562 | if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */ | 560 | if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */ |
| 563 | pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; | 561 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; |
| 564 | else | 562 | else |
| 565 | pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; | 563 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
| 566 | 564 | ||
| 567 | if (rdev->family < CHIP_RV770) | 565 | if (rdev->family < CHIP_RV770) |
| 568 | pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; | 566 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; |
| 569 | /* use frac fb div on APUs */ | 567 | /* use frac fb div on APUs */ |
| 570 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) | 568 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) |
| 571 | pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; | 569 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
| 572 | } else { | 570 | } else { |
| 573 | pll->flags |= RADEON_PLL_LEGACY; | 571 | radeon_crtc->pll_flags |= RADEON_PLL_LEGACY; |
| 574 | 572 | ||
| 575 | if (mode->clock > 200000) /* range limits??? */ | 573 | if (mode->clock > 200000) /* range limits??? */ |
| 576 | pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; | 574 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; |
| 577 | else | 575 | else |
| 578 | pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; | 576 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
| 579 | } | 577 | } |
| 580 | 578 | ||
| 581 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 579 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
| @@ -598,12 +596,12 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 598 | 596 | ||
| 599 | /* use recommended ref_div for ss */ | 597 | /* use recommended ref_div for ss */ |
| 600 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 598 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
| 601 | if (ss_enabled) { | 599 | if (radeon_crtc->ss_enabled) { |
| 602 | if (ss->refdiv) { | 600 | if (radeon_crtc->ss.refdiv) { |
| 603 | pll->flags |= RADEON_PLL_USE_REF_DIV; | 601 | radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV; |
| 604 | pll->reference_div = ss->refdiv; | 602 | radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv; |
| 605 | if (ASIC_IS_AVIVO(rdev)) | 603 | if (ASIC_IS_AVIVO(rdev)) |
| 606 | pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; | 604 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
| 607 | } | 605 | } |
| 608 | } | 606 | } |
| 609 | } | 607 | } |
| @@ -613,14 +611,14 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 613 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) | 611 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) |
| 614 | adjusted_clock = mode->clock * 2; | 612 | adjusted_clock = mode->clock * 2; |
| 615 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | 613 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
| 616 | pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; | 614 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; |
| 617 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | 615 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) |
| 618 | pll->flags |= RADEON_PLL_IS_LCD; | 616 | radeon_crtc->pll_flags |= RADEON_PLL_IS_LCD; |
| 619 | } else { | 617 | } else { |
| 620 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) | 618 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) |
| 621 | pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; | 619 | radeon_crtc->pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; |
| 622 | if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) | 620 | if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) |
| 623 | pll->flags |= RADEON_PLL_USE_REF_DIV; | 621 | radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV; |
| 624 | } | 622 | } |
| 625 | break; | 623 | break; |
| 626 | } | 624 | } |
| @@ -650,7 +648,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 650 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); | 648 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); |
| 651 | args.v1.ucTransmitterID = radeon_encoder->encoder_id; | 649 | args.v1.ucTransmitterID = radeon_encoder->encoder_id; |
| 652 | args.v1.ucEncodeMode = encoder_mode; | 650 | args.v1.ucEncodeMode = encoder_mode; |
| 653 | if (ss_enabled && ss->percentage) | 651 | if (radeon_crtc->ss_enabled && radeon_crtc->ss.percentage) |
| 654 | args.v1.ucConfig |= | 652 | args.v1.ucConfig |= |
| 655 | ADJUST_DISPLAY_CONFIG_SS_ENABLE; | 653 | ADJUST_DISPLAY_CONFIG_SS_ENABLE; |
| 656 | 654 | ||
| @@ -663,7 +661,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 663 | args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id; | 661 | args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id; |
| 664 | args.v3.sInput.ucEncodeMode = encoder_mode; | 662 | args.v3.sInput.ucEncodeMode = encoder_mode; |
| 665 | args.v3.sInput.ucDispPllConfig = 0; | 663 | args.v3.sInput.ucDispPllConfig = 0; |
| 666 | if (ss_enabled && ss->percentage) | 664 | if (radeon_crtc->ss_enabled && radeon_crtc->ss.percentage) |
| 667 | args.v3.sInput.ucDispPllConfig |= | 665 | args.v3.sInput.ucDispPllConfig |= |
| 668 | DISPPLL_CONFIG_SS_ENABLE; | 666 | DISPPLL_CONFIG_SS_ENABLE; |
| 669 | if (ENCODER_MODE_IS_DP(encoder_mode)) { | 667 | if (ENCODER_MODE_IS_DP(encoder_mode)) { |
| @@ -695,14 +693,14 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 695 | index, (uint32_t *)&args); | 693 | index, (uint32_t *)&args); |
| 696 | adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10; | 694 | adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10; |
| 697 | if (args.v3.sOutput.ucRefDiv) { | 695 | if (args.v3.sOutput.ucRefDiv) { |
| 698 | pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; | 696 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
| 699 | pll->flags |= RADEON_PLL_USE_REF_DIV; | 697 | radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV; |
| 700 | pll->reference_div = args.v3.sOutput.ucRefDiv; | 698 | radeon_crtc->pll_reference_div = args.v3.sOutput.ucRefDiv; |
| 701 | } | 699 | } |
| 702 | if (args.v3.sOutput.ucPostDiv) { | 700 | if (args.v3.sOutput.ucPostDiv) { |
| 703 | pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; | 701 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
| 704 | pll->flags |= RADEON_PLL_USE_POST_DIV; | 702 | radeon_crtc->pll_flags |= RADEON_PLL_USE_POST_DIV; |
| 705 | pll->post_div = args.v3.sOutput.ucPostDiv; | 703 | radeon_crtc->pll_post_div = args.v3.sOutput.ucPostDiv; |
| 706 | } | 704 | } |
| 707 | break; | 705 | break; |
| 708 | default: | 706 | default: |
| @@ -910,21 +908,17 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc, | |||
| 910 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 908 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
| 911 | } | 909 | } |
