diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_clocks.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_clocks.c | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c index a81354167621..f64936cc4dd9 100644 --- a/drivers/gpu/drm/radeon/radeon_clocks.c +++ b/drivers/gpu/drm/radeon/radeon_clocks.c | |||
@@ -44,6 +44,10 @@ uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev) | |||
44 | 44 | ||
45 | ref_div = | 45 | ref_div = |
46 | RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK; | 46 | RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK; |
47 | |||
48 | if (ref_div == 0) | ||
49 | return 0; | ||
50 | |||
47 | sclk = fb_div / ref_div; | 51 | sclk = fb_div / ref_div; |
48 | 52 | ||
49 | post_div = RREG32_PLL(RADEON_SCLK_CNTL) & RADEON_SCLK_SRC_SEL_MASK; | 53 | post_div = RREG32_PLL(RADEON_SCLK_CNTL) & RADEON_SCLK_SRC_SEL_MASK; |
@@ -52,13 +56,13 @@ uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev) | |||
52 | else if (post_div == 3) | 56 | else if (post_div == 3) |
53 | sclk >>= 2; | 57 | sclk >>= 2; |
54 | else if (post_div == 4) | 58 | else if (post_div == 4) |
55 | sclk >>= 4; | 59 | sclk >>= 3; |
56 | 60 | ||
57 | return sclk; | 61 | return sclk; |
58 | } | 62 | } |
59 | 63 | ||
60 | /* 10 khz */ | 64 | /* 10 khz */ |
61 | static uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev) | 65 | uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev) |
62 | { | 66 | { |
63 | struct radeon_pll *mpll = &rdev->clock.mpll; | 67 | struct radeon_pll *mpll = &rdev->clock.mpll; |
64 | uint32_t fb_div, ref_div, post_div, mclk; | 68 | uint32_t fb_div, ref_div, post_div, mclk; |
@@ -70,6 +74,10 @@ static uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev) | |||
70 | 74 | ||
71 | ref_div = | 75 | ref_div = |
72 | RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK; | 76 | RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK; |
77 | |||
78 | if (ref_div == 0) | ||
79 | return 0; | ||
80 | |||
73 | mclk = fb_div / ref_div; | 81 | mclk = fb_div / ref_div; |
74 | 82 | ||
75 | post_div = RREG32_PLL(RADEON_MCLK_CNTL) & 0x7; | 83 | post_div = RREG32_PLL(RADEON_MCLK_CNTL) & 0x7; |
@@ -78,7 +86,7 @@ static uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev) | |||
78 | else if (post_div == 3) | 86 | else if (post_div == 3) |
79 | mclk >>= 2; | 87 | mclk >>= 2; |
80 | else if (post_div == 4) | 88 | else if (post_div == 4) |
81 | mclk >>= 4; | 89 | mclk >>= 3; |
82 | 90 | ||
83 | return mclk; | 91 | return mclk; |
84 | } | 92 | } |
@@ -88,6 +96,7 @@ void radeon_get_clock_info(struct drm_device *dev) | |||
88 | struct radeon_device *rdev = dev->dev_private; | 96 | struct radeon_device *rdev = dev->dev_private; |
89 | struct radeon_pll *p1pll = &rdev->clock.p1pll; | 97 | struct radeon_pll *p1pll = &rdev->clock.p1pll; |
90 | struct radeon_pll *p2pll = &rdev->clock.p2pll; | 98 | struct radeon_pll *p2pll = &rdev->clock.p2pll; |
99 | struct radeon_pll *dcpll = &rdev->clock.dcpll; | ||
91 | struct radeon_pll *spll = &rdev->clock.spll; | 100 | struct radeon_pll *spll = &rdev->clock.spll; |
92 | struct radeon_pll *mpll = &rdev->clock.mpll; | 101 | struct radeon_pll *mpll = &rdev->clock.mpll; |
93 | int ret; | 102 | int ret; |
@@ -98,8 +107,19 @@ void radeon_get_clock_info(struct drm_device *dev) | |||
98 | ret = radeon_combios_get_clock_info(dev); | 107 | ret = radeon_combios_get_clock_info(dev); |
99 | 108 | ||
100 | if (ret) { | 109 | if (ret) { |
101 | if (p1pll->reference_div < 2) | 110 | if (p1pll->reference_div < 2) { |
102 | p1pll->reference_div = 12; | 111 | if (!ASIC_IS_AVIVO(rdev)) { |
112 | u32 tmp = RREG32_PLL(RADEON_PPLL_REF_DIV); | ||
113 | if (ASIC_IS_R300(rdev)) | ||
114 | p1pll->reference_div = | ||
115 | (tmp & R300_PPLL_REF_DIV_ACC_MASK) >> R300_PPLL_REF_DIV_ACC_SHIFT; | ||
116 | else | ||
117 | p1pll->reference_div = tmp & RADEON_PPLL_REF_DIV_MASK; | ||
118 | if (p1pll->reference_div < 2) | ||
119 | p1pll->reference_div = 12; | ||
120 | } else | ||
121 | p1pll->reference_div = 12; | ||
122 | } | ||
103 | if (p2pll->reference_div < 2) | 123 | if (p2pll->reference_div < 2) |
104 | p2pll->reference_div = 12; | 124 | p2pll->reference_div = 12; |
105 | if (rdev->family < CHIP_RS600) { | 125 | if (rdev->family < CHIP_RS600) { |
@@ -185,6 +205,17 @@ void radeon_get_clock_info(struct drm_device *dev) | |||
185 | p2pll->max_frac_feedback_div = 0; | 205 | p2pll->max_frac_feedback_div = 0; |
186 | } | 206 | } |
187 | 207 | ||
208 | /* dcpll is DCE4 only */ | ||
209 | dcpll->min_post_div = 2; | ||
210 | dcpll->max_post_div = 0x7f; | ||
211 | dcpll->min_frac_feedback_div = 0; | ||
212 | dcpll->max_frac_feedback_div = 9; | ||
213 | dcpll->min_ref_div = 2; | ||
214 | dcpll->max_ref_div = 0x3ff; | ||
215 | dcpll->min_feedback_div = 4; | ||
216 | dcpll->max_feedback_div = 0xfff; | ||
217 | dcpll->best_vco = 0; | ||
218 | |||
188 | p1pll->min_ref_div = 2; | 219 | p1pll->min_ref_div = 2; |
189 | p1pll->max_ref_div = 0x3ff; | 220 | p1pll->max_ref_div = 0x3ff; |
190 | p1pll->min_feedback_div = 4; | 221 | p1pll->min_feedback_div = 4; |
@@ -827,8 +858,10 @@ int radeon_static_clocks_init(struct drm_device *dev) | |||
827 | /* XXX make sure engine is idle */ | 858 | /* XXX make sure engine is idle */ |
828 | 859 | ||
829 | if (radeon_dynclks != -1) { | 860 | if (radeon_dynclks != -1) { |
830 | if (radeon_dynclks) | 861 | if (radeon_dynclks) { |
831 | radeon_set_clock_gating(rdev, 1); | 862 | if (rdev->asic->set_clock_gating) |
863 | radeon_set_clock_gating(rdev, 1); | ||
864 | } | ||
832 | } | 865 | } |
833 | radeon_apply_clock_quirks(rdev); | 866 | radeon_apply_clock_quirks(rdev); |
834 | return 0; | 867 | return 0; |