aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_atombios.c
diff options
context:
space:
mode:
authorChristian König <deathsimple@vodafone.de>2013-04-08 06:41:31 -0400
committerAlex Deucher <alexander.deucher@amd.com>2013-04-09 10:31:35 -0400
commit7062ab67d4c6568ec423da39321423721b925fdc (patch)
treef7a1dcf559776d529e90951a9ea9ed0ba540177e /drivers/gpu/drm/radeon/radeon_atombios.c
parent73afc70d1153399b01789ff01e04d2cae49acf52 (diff)
drm/radeon: add radeon_atom_get_clock_dividers helper
Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_atombios.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index f22eb5713528..8c1779cba1f3 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -2654,6 +2654,113 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
2654 rdev->pm.current_vddc = 0; 2654 rdev->pm.current_vddc = 0;
2655} 2655}
2656 2656
2657union get_clock_dividers {
2658 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS v1;
2659 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2 v2;
2660 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 v3;
2661 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 v4;
2662 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5 v5;
2663};
2664
2665int radeon_atom_get_clock_dividers(struct radeon_device *rdev,
2666 u8 clock_type,
2667 u32 clock,
2668 bool strobe_mode,
2669 struct atom_clock_dividers *dividers)
2670{
2671 union get_clock_dividers args;
2672 int index = GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL);
2673 u8 frev, crev;
2674
2675 memset(&args, 0, sizeof(args));
2676 memset(dividers, 0, sizeof(struct atom_clock_dividers));
2677
2678 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
2679 return -EINVAL;
2680
2681 switch (crev) {
2682 case 1:
2683 /* r4xx, r5xx */
2684 args.v1.ucAction = clock_type;
2685 args.v1.ulClock = cpu_to_le32(clock); /* 10 khz */
2686
2687 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2688
2689 dividers->post_div = args.v1.ucPostDiv;
2690 dividers->fb_div = args.v1.ucFbDiv;
2691 dividers->enable_post_div = true;
2692 break;
2693 case 2:
2694 case 3:
2695 /* r6xx, r7xx, evergreen, ni */
2696 if (rdev->family <= CHIP_RV770) {
2697 args.v2.ucAction = clock_type;
2698 args.v2.ulClock = cpu_to_le32(clock); /* 10 khz */
2699
2700 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2701
2702 dividers->post_div = args.v2.ucPostDiv;
2703 dividers->fb_div = le16_to_cpu(args.v2.usFbDiv);
2704 dividers->ref_div = args.v2.ucAction;
2705 if (rdev->family == CHIP_RV770) {
2706 dividers->enable_post_div = (le32_to_cpu(args.v2.ulClock) & (1 << 24)) ?
2707 true : false;
2708 dividers->vco_mode = (le32_to_cpu(args.v2.ulClock) & (1 << 25)) ? 1 : 0;
2709 } else
2710 dividers->enable_post_div = (dividers->fb_div & 1) ? true : false;
2711 } else {
2712 if (clock_type == COMPUTE_ENGINE_PLL_PARAM) {
2713 args.v3.ulClock.ulComputeClockFlag = clock_type;
2714 args.v3.ulClock.ulClockFreq = cpu_to_le32(clock); /* 10 khz */
2715
2716 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2717
2718 dividers->post_div = args.v3.ucPostDiv;
2719 dividers->enable_post_div = (args.v3.ucCntlFlag &
2720 ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false;
2721 dividers->enable_dithen = (args.v3.ucCntlFlag &
2722 ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true;
2723 dividers->fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDiv);
2724 dividers->frac_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDivFrac);
2725 dividers->ref_div = args.v3.ucRefDiv;
2726 dividers->vco_mode = (args.v3.ucCntlFlag &
2727 ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0;
2728 } else {
2729 args.v5.ulClock.ulComputeClockFlag = clock_type;
2730 args.v5.ulClock.ulClockFreq = cpu_to_le32(clock); /* 10 khz */
2731 if (strobe_mode)
2732 args.v5.ucInputFlag = ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN;
2733
2734 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2735
2736 dividers->post_div = args.v5.ucPostDiv;
2737 dividers->enable_post_div = (args.v5.ucCntlFlag &
2738 ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false;
2739 dividers->enable_dithen = (args.v5.ucCntlFlag &
2740 ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true;
2741 dividers->whole_fb_div = le16_to_cpu(args.v5.ulFbDiv.usFbDiv);
2742 dividers->frac_fb_div = le16_to_cpu(args.v5.ulFbDiv.usFbDivFrac);
2743 dividers->ref_div = args.v5.ucRefDiv;
2744 dividers->vco_mode = (args.v5.ucCntlFlag &
2745 ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0;
2746 }
2747 }
2748 break;
2749 case 4:
2750 /* fusion */
2751 args.v4.ulClock = cpu_to_le32(clock); /* 10 khz */
2752
2753 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
2754
2755 dividers->post_div = args.v4.ucPostDiv;
2756 dividers->real_clock = le32_to_cpu(args.v4.ulClock);
2757 break;
2758 default:
2759 return -EINVAL;
2760 }
2761 return 0;
2762}
2763
2657void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable) 2764void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable)
2658{ 2765{
2659 DYNAMIC_CLOCK_GATING_PS_ALLOCATION args; 2766 DYNAMIC_CLOCK_GATING_PS_ALLOCATION args;