Rev 5078 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5078 | serge | 1 | /* |
2 | * Copyright 2011 Advanced Micro Devices, Inc. |
||
3 | * |
||
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
5 | * copy of this software and associated documentation files (the "Software"), |
||
6 | * to deal in the Software without restriction, including without limitation |
||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||
8 | * and/or sell copies of the Software, and to permit persons to whom the |
||
9 | * Software is furnished to do so, subject to the following conditions: |
||
10 | * |
||
11 | * The above copyright notice and this permission notice shall be included in |
||
12 | * all copies or substantial portions of the Software. |
||
13 | * |
||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR |
||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||
20 | * OTHER DEALINGS IN THE SOFTWARE. |
||
21 | * |
||
22 | * Authors: Alex Deucher |
||
23 | */ |
||
24 | |||
25 | #include "drmP.h" |
||
26 | #include "radeon.h" |
||
27 | #include "rv740d.h" |
||
28 | #include "r600_dpm.h" |
||
29 | #include "rv770_dpm.h" |
||
30 | #include "atom.h" |
||
31 | |||
32 | struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev); |
||
33 | |||
34 | u32 rv740_get_decoded_reference_divider(u32 encoded_ref) |
||
35 | { |
||
36 | u32 ref = 0; |
||
37 | |||
38 | switch (encoded_ref) { |
||
7146 | serge | 39 | case 0: |
5078 | serge | 40 | ref = 1; |
41 | break; |
||
7146 | serge | 42 | case 16: |
5078 | serge | 43 | ref = 2; |
44 | break; |
||
7146 | serge | 45 | case 17: |
5078 | serge | 46 | ref = 3; |
47 | break; |
||
7146 | serge | 48 | case 18: |
5078 | serge | 49 | ref = 2; |
50 | break; |
||
7146 | serge | 51 | case 19: |
5078 | serge | 52 | ref = 3; |
53 | break; |
||
7146 | serge | 54 | case 20: |
5078 | serge | 55 | ref = 4; |
56 | break; |
||
7146 | serge | 57 | case 21: |
5078 | serge | 58 | ref = 5; |
59 | break; |
||
7146 | serge | 60 | default: |
5078 | serge | 61 | DRM_ERROR("Invalid encoded Reference Divider\n"); |
62 | ref = 0; |
||
63 | break; |
||
64 | } |
||
65 | |||
66 | return ref; |
||
67 | } |
||
68 | |||
69 | struct dll_speed_setting { |
||
70 | u16 min; |
||
71 | u16 max; |
||
72 | u32 dll_speed; |
||
73 | }; |
||
74 | |||
75 | static struct dll_speed_setting dll_speed_table[16] = |
||
76 | { |
||
77 | { 270, 320, 0x0f }, |
||
78 | { 240, 270, 0x0e }, |
||
79 | { 200, 240, 0x0d }, |
||
80 | { 180, 200, 0x0c }, |
||
81 | { 160, 180, 0x0b }, |
||
82 | { 140, 160, 0x0a }, |
||
83 | { 120, 140, 0x09 }, |
||
84 | { 110, 120, 0x08 }, |
||
85 | { 95, 110, 0x07 }, |
||
86 | { 85, 95, 0x06 }, |
||
87 | { 78, 85, 0x05 }, |
||
88 | { 70, 78, 0x04 }, |
||
89 | { 65, 70, 0x03 }, |
||
90 | { 60, 65, 0x02 }, |
||
91 | { 42, 60, 0x01 }, |
||
92 | { 00, 42, 0x00 } |
||
93 | }; |
||
94 | |||
95 | u32 rv740_get_dll_speed(bool is_gddr5, u32 memory_clock) |
||
96 | { |
||
97 | int i; |
||
98 | u32 factor; |
||
99 | u16 data_rate; |
||
100 | |||
101 | if (is_gddr5) |
||
102 | factor = 4; |
||
103 | else |
||
104 | factor = 2; |
||
105 | |||
106 | data_rate = (u16)(memory_clock * factor / 1000); |
||
107 | |||
108 | if (data_rate < dll_speed_table[0].max) { |
||
109 | for (i = 0; i < 16; i++) { |
||
110 | if (data_rate > dll_speed_table[i].min && |
||
111 | data_rate <= dll_speed_table[i].max) |
||
112 | return dll_speed_table[i].dll_speed; |
||
113 | } |
||
114 | } |
||
115 | |||
116 | DRM_DEBUG_KMS("Target MCLK greater than largest MCLK in DLL speed table\n"); |
||
117 | |||
118 | return 0x0f; |
||
119 | } |
||
120 | |||
121 | int rv740_populate_sclk_value(struct radeon_device *rdev, u32 engine_clock, |
||
122 | RV770_SMC_SCLK_VALUE *sclk) |
||
123 | { |
||
124 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
||
125 | struct atom_clock_dividers dividers; |
||
126 | u32 spll_func_cntl = pi->clk_regs.rv770.cg_spll_func_cntl; |
||
127 | u32 spll_func_cntl_2 = pi->clk_regs.rv770.cg_spll_func_cntl_2; |
||
128 | u32 spll_func_cntl_3 = pi->clk_regs.rv770.cg_spll_func_cntl_3; |
||
129 | u32 cg_spll_spread_spectrum = pi->clk_regs.rv770.cg_spll_spread_spectrum; |
||
130 | u32 cg_spll_spread_spectrum_2 = pi->clk_regs.rv770.cg_spll_spread_spectrum_2; |
||
131 | u64 tmp; |
||
132 | u32 reference_clock = rdev->clock.spll.reference_freq; |
||
133 | u32 reference_divider; |
||
134 | u32 fbdiv; |
||
135 | int ret; |
||
136 | |||
137 | ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM, |
||
138 | engine_clock, false, ÷rs); |
||
139 | if (ret) |
||
140 | return ret; |
||
141 | |||
142 | reference_divider = 1 + dividers.ref_div; |
||
143 | |||
144 | tmp = (u64) engine_clock * reference_divider * dividers.post_div * 16384; |
||
145 | do_div(tmp, reference_clock); |
||
146 | fbdiv = (u32) tmp; |
||
147 | |||
148 | spll_func_cntl &= ~(SPLL_PDIV_A_MASK | SPLL_REF_DIV_MASK); |
||
149 | spll_func_cntl |= SPLL_REF_DIV(dividers.ref_div); |
||
150 | spll_func_cntl |= SPLL_PDIV_A(dividers.post_div); |
||
151 | |||
152 | spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK; |
||
153 | spll_func_cntl_2 |= SCLK_MUX_SEL(2); |
||
154 | |||
155 | spll_func_cntl_3 &= ~SPLL_FB_DIV_MASK; |
||
156 | spll_func_cntl_3 |= SPLL_FB_DIV(fbdiv); |
||
157 | spll_func_cntl_3 |= SPLL_DITHEN; |
||
158 | |||
159 | if (pi->sclk_ss) { |
||
160 | struct radeon_atom_ss ss; |
||
161 | u32 vco_freq = engine_clock * dividers.post_div; |
||
162 | |||
163 | if (radeon_atombios_get_asic_ss_info(rdev, &ss, |
||
164 | ASIC_INTERNAL_ENGINE_SS, vco_freq)) { |
||
165 | u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate); |
||
166 | u32 clk_v = 4 * ss.percentage * fbdiv / (clk_s * 10000); |
||
167 | |||
168 | cg_spll_spread_spectrum &= ~CLK_S_MASK; |
||
169 | cg_spll_spread_spectrum |= CLK_S(clk_s); |
||
170 | cg_spll_spread_spectrum |= SSEN; |
||
171 | |||
172 | cg_spll_spread_spectrum_2 &= ~CLK_V_MASK; |
||
173 | cg_spll_spread_spectrum_2 |= CLK_V(clk_v); |
||
174 | } |
||
175 | } |
||
176 | |||
177 | sclk->sclk_value = cpu_to_be32(engine_clock); |
||
178 | sclk->vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl); |
||
179 | sclk->vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2); |
||
180 | sclk->vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3); |
||
181 | sclk->vCG_SPLL_SPREAD_SPECTRUM = cpu_to_be32(cg_spll_spread_spectrum); |
||
182 | sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cpu_to_be32(cg_spll_spread_spectrum_2); |
||
183 | |||
184 | return 0; |
||
185 | } |
||
186 | |||
187 | int rv740_populate_mclk_value(struct radeon_device *rdev, |
||
188 | u32 engine_clock, u32 memory_clock, |
||
189 | RV7XX_SMC_MCLK_VALUE *mclk) |
||
190 | { |
||
191 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
||
192 | u32 mpll_ad_func_cntl = pi->clk_regs.rv770.mpll_ad_func_cntl; |
||
193 | u32 mpll_ad_func_cntl_2 = pi->clk_regs.rv770.mpll_ad_func_cntl_2; |
||
194 | u32 mpll_dq_func_cntl = pi->clk_regs.rv770.mpll_dq_func_cntl; |
||
195 | u32 mpll_dq_func_cntl_2 = pi->clk_regs.rv770.mpll_dq_func_cntl_2; |
||
196 | u32 mclk_pwrmgt_cntl = pi->clk_regs.rv770.mclk_pwrmgt_cntl; |
||
197 | u32 dll_cntl = pi->clk_regs.rv770.dll_cntl; |
||
198 | u32 mpll_ss1 = pi->clk_regs.rv770.mpll_ss1; |
||
199 | u32 mpll_ss2 = pi->clk_regs.rv770.mpll_ss2; |
||
200 | struct atom_clock_dividers dividers; |
||
201 | u32 ibias; |
||
202 | u32 dll_speed; |
||
203 | int ret; |
||
204 | |||
205 | ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_MEMORY_PLL_PARAM, |
||
206 | memory_clock, false, ÷rs); |
||
207 | if (ret) |
||
208 | return ret; |
||
209 | |||
210 | ibias = rv770_map_clkf_to_ibias(rdev, dividers.whole_fb_div); |
||
211 | |||
212 | mpll_ad_func_cntl &= ~(CLKR_MASK | |
||
213 | YCLK_POST_DIV_MASK | |
||
214 | CLKF_MASK | |
||
215 | CLKFRAC_MASK | |
||
216 | IBIAS_MASK); |
||
217 | mpll_ad_func_cntl |= CLKR(dividers.ref_div); |
||
218 | mpll_ad_func_cntl |= YCLK_POST_DIV(dividers.post_div); |
||
219 | mpll_ad_func_cntl |= CLKF(dividers.whole_fb_div); |
||
220 | mpll_ad_func_cntl |= CLKFRAC(dividers.frac_fb_div); |
||
221 | mpll_ad_func_cntl |= IBIAS(ibias); |
||
222 | |||
223 | if (dividers.vco_mode) |
||
224 | mpll_ad_func_cntl_2 |= VCO_MODE; |
||
225 | else |
||
226 | mpll_ad_func_cntl_2 &= ~VCO_MODE; |
||
227 | |||
228 | if (pi->mem_gddr5) { |
||
229 | mpll_dq_func_cntl &= ~(CLKR_MASK | |
||
230 | YCLK_POST_DIV_MASK | |
||
231 | CLKF_MASK | |
||
232 | CLKFRAC_MASK | |
||
233 | IBIAS_MASK); |
||
234 | mpll_dq_func_cntl |= CLKR(dividers.ref_div); |
||
235 | mpll_dq_func_cntl |= YCLK_POST_DIV(dividers.post_div); |
||
236 | mpll_dq_func_cntl |= CLKF(dividers.whole_fb_div); |
||
237 | mpll_dq_func_cntl |= CLKFRAC(dividers.frac_fb_div); |
||
238 | mpll_dq_func_cntl |= IBIAS(ibias); |
||
239 | |||
240 | if (dividers.vco_mode) |
||
241 | mpll_dq_func_cntl_2 |= VCO_MODE; |
||
242 | else |
||
243 | mpll_dq_func_cntl_2 &= ~VCO_MODE; |
||
244 | } |
||
245 | |||
246 | if (pi->mclk_ss) { |
||
247 | struct radeon_atom_ss ss; |
||
248 | u32 vco_freq = memory_clock * dividers.post_div; |
||
249 | |||
250 | if (radeon_atombios_get_asic_ss_info(rdev, &ss, |
||
251 | ASIC_INTERNAL_MEMORY_SS, vco_freq)) { |
||
252 | u32 reference_clock = rdev->clock.mpll.reference_freq; |
||
253 | u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div); |
||
254 | u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate); |
||
255 | u32 clk_v = 0x40000 * ss.percentage * |
||
256 | (dividers.whole_fb_div + (dividers.frac_fb_div / 8)) / (clk_s * 10000); |
||
257 | |||
258 | mpll_ss1 &= ~CLKV_MASK; |
||
259 | mpll_ss1 |= CLKV(clk_v); |
||
260 | |||
261 | mpll_ss2 &= ~CLKS_MASK; |
||
262 | mpll_ss2 |= CLKS(clk_s); |
||
263 | } |
||
264 | } |
||
265 | |||
266 | dll_speed = rv740_get_dll_speed(pi->mem_gddr5, |
||
267 | memory_clock); |
||
268 | |||
269 | mclk_pwrmgt_cntl &= ~DLL_SPEED_MASK; |
||
270 | mclk_pwrmgt_cntl |= DLL_SPEED(dll_speed); |
||
271 | |||
272 | mclk->mclk770.mclk_value = cpu_to_be32(memory_clock); |
||
273 | mclk->mclk770.vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl); |
||
274 | mclk->mclk770.vMPLL_AD_FUNC_CNTL_2 = cpu_to_be32(mpll_ad_func_cntl_2); |
||
275 | mclk->mclk770.vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl); |
||
276 | mclk->mclk770.vMPLL_DQ_FUNC_CNTL_2 = cpu_to_be32(mpll_dq_func_cntl_2); |
||
277 | mclk->mclk770.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl); |
||
278 | mclk->mclk770.vDLL_CNTL = cpu_to_be32(dll_cntl); |
||
279 | mclk->mclk770.vMPLL_SS = cpu_to_be32(mpll_ss1); |
||
280 | mclk->mclk770.vMPLL_SS2 = cpu_to_be32(mpll_ss2); |
||
281 | |||
282 | return 0; |
||
283 | } |
||
284 | |||
285 | void rv740_read_clock_registers(struct radeon_device *rdev) |
||
286 | { |
||
287 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
||
288 | |||
289 | pi->clk_regs.rv770.cg_spll_func_cntl = |
||
290 | RREG32(CG_SPLL_FUNC_CNTL); |
||
291 | pi->clk_regs.rv770.cg_spll_func_cntl_2 = |
||
292 | RREG32(CG_SPLL_FUNC_CNTL_2); |
||
293 | pi->clk_regs.rv770.cg_spll_func_cntl_3 = |
||
294 | RREG32(CG_SPLL_FUNC_CNTL_3); |
||
295 | pi->clk_regs.rv770.cg_spll_spread_spectrum = |
||
296 | RREG32(CG_SPLL_SPREAD_SPECTRUM); |
||
297 | pi->clk_regs.rv770.cg_spll_spread_spectrum_2 = |
||
298 | RREG32(CG_SPLL_SPREAD_SPECTRUM_2); |
||
299 | |||
300 | pi->clk_regs.rv770.mpll_ad_func_cntl = |
||
301 | RREG32(MPLL_AD_FUNC_CNTL); |
||
302 | pi->clk_regs.rv770.mpll_ad_func_cntl_2 = |
||
303 | RREG32(MPLL_AD_FUNC_CNTL_2); |
||
304 | pi->clk_regs.rv770.mpll_dq_func_cntl = |
||
305 | RREG32(MPLL_DQ_FUNC_CNTL); |
||
306 | pi->clk_regs.rv770.mpll_dq_func_cntl_2 = |
||
307 | RREG32(MPLL_DQ_FUNC_CNTL_2); |
||
308 | pi->clk_regs.rv770.mclk_pwrmgt_cntl = |
||
309 | RREG32(MCLK_PWRMGT_CNTL); |
||
310 | pi->clk_regs.rv770.dll_cntl = RREG32(DLL_CNTL); |
||
311 | pi->clk_regs.rv770.mpll_ss1 = RREG32(MPLL_SS1); |
||
312 | pi->clk_regs.rv770.mpll_ss2 = RREG32(MPLL_SS2); |
||
313 | } |
||
314 | |||
315 | int rv740_populate_smc_acpi_state(struct radeon_device *rdev, |
||
316 | RV770_SMC_STATETABLE *table) |
||
317 | { |
||
318 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
||
319 | u32 mpll_ad_func_cntl = pi->clk_regs.rv770.mpll_ad_func_cntl; |
||
320 | u32 mpll_ad_func_cntl_2 = pi->clk_regs.rv770.mpll_ad_func_cntl_2; |
||
321 | u32 mpll_dq_func_cntl = pi->clk_regs.rv770.mpll_dq_func_cntl; |
||
322 | u32 mpll_dq_func_cntl_2 = pi->clk_regs.rv770.mpll_dq_func_cntl_2; |
||
323 | u32 spll_func_cntl = pi->clk_regs.rv770.cg_spll_func_cntl; |
||
324 | u32 spll_func_cntl_2 = pi->clk_regs.rv770.cg_spll_func_cntl_2; |
||
325 | u32 spll_func_cntl_3 = pi->clk_regs.rv770.cg_spll_func_cntl_3; |
||
326 | u32 mclk_pwrmgt_cntl = pi->clk_regs.rv770.mclk_pwrmgt_cntl; |
||
327 | u32 dll_cntl = pi->clk_regs.rv770.dll_cntl; |
||
328 | |||
329 | table->ACPIState = table->initialState; |
||
330 | |||
331 | table->ACPIState.flags &= ~PPSMC_SWSTATE_FLAG_DC; |
||
332 | |||
333 | if (pi->acpi_vddc) { |
||
334 | rv770_populate_vddc_value(rdev, pi->acpi_vddc, |
||
335 | &table->ACPIState.levels[0].vddc); |
||
336 | table->ACPIState.levels[0].gen2PCIE = |
||
337 | pi->pcie_gen2 ? |
||
338 | pi->acpi_pcie_gen2 : 0; |
||
339 | table->ACPIState.levels[0].gen2XSP = |
||
340 | pi->acpi_pcie_gen2; |
||
341 | } else { |
||
342 | rv770_populate_vddc_value(rdev, pi->min_vddc_in_table, |
||
343 | &table->ACPIState.levels[0].vddc); |
||
344 | table->ACPIState.levels[0].gen2PCIE = 0; |
||
345 | } |
||
346 | |||
347 | mpll_ad_func_cntl_2 |= BIAS_GEN_PDNB | RESET_EN; |
||
348 | |||
349 | mpll_dq_func_cntl_2 |= BYPASS | BIAS_GEN_PDNB | RESET_EN; |
||
350 | |||
351 | mclk_pwrmgt_cntl |= (MRDCKA0_RESET | |
||
352 | MRDCKA1_RESET | |
||
353 | MRDCKB0_RESET | |
||
354 | MRDCKB1_RESET | |
||
355 | MRDCKC0_RESET | |
||
356 | MRDCKC1_RESET | |
||
357 | MRDCKD0_RESET | |
||
358 | MRDCKD1_RESET); |
||
359 | |||
360 | dll_cntl |= (MRDCKA0_BYPASS | |
||
361 | MRDCKA1_BYPASS | |
||
362 | MRDCKB0_BYPASS | |
||
363 | MRDCKB1_BYPASS | |
||
364 | MRDCKC0_BYPASS | |
||
365 | MRDCKC1_BYPASS | |
||
366 | MRDCKD0_BYPASS | |
||
367 | MRDCKD1_BYPASS); |
||
368 | |||
369 | spll_func_cntl |= SPLL_RESET | SPLL_SLEEP | SPLL_BYPASS_EN; |
||
370 | |||
371 | spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK; |
||
372 | spll_func_cntl_2 |= SCLK_MUX_SEL(4); |
||
373 | |||
374 | table->ACPIState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl); |
||
375 | table->ACPIState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL_2 = cpu_to_be32(mpll_ad_func_cntl_2); |
||
376 | table->ACPIState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl); |
||
377 | table->ACPIState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL_2 = cpu_to_be32(mpll_dq_func_cntl_2); |
||
378 | table->ACPIState.levels[0].mclk.mclk770.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl); |
||
379 | table->ACPIState.levels[0].mclk.mclk770.vDLL_CNTL = cpu_to_be32(dll_cntl); |
||
380 | |||
381 | table->ACPIState.levels[0].mclk.mclk770.mclk_value = 0; |
||
382 | |||
383 | table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl); |
||
384 | table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2); |
||
385 | table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3); |
||
386 | |||
387 | table->ACPIState.levels[0].sclk.sclk_value = 0; |
||
388 | |||
389 | table->ACPIState.levels[1] = table->ACPIState.levels[0]; |
||
390 | table->ACPIState.levels[2] = table->ACPIState.levels[0]; |
||
391 | |||
392 | rv770_populate_mvdd_value(rdev, 0, &table->ACPIState.levels[0].mvdd); |
||
393 | |||
394 | return 0; |
||
395 | } |
||
396 | |||
397 | void rv740_enable_mclk_spread_spectrum(struct radeon_device *rdev, |
||
398 | bool enable) |
||
399 | { |
||
400 | if (enable) |
||
401 | WREG32_P(MPLL_CNTL_MODE, SS_SSEN, ~SS_SSEN); |
||
402 | else |
||
403 | WREG32_P(MPLL_CNTL_MODE, 0, ~SS_SSEN); |
||
404 | } |
||
405 | |||
406 | u8 rv740_get_mclk_frequency_ratio(u32 memory_clock) |
||
407 | { |
||
408 | u8 mc_para_index; |
||
409 | |||
410 | if ((memory_clock < 10000) || (memory_clock > 47500)) |
||
411 | mc_para_index = 0x00; |
||
412 | else |
||
413 | mc_para_index = (u8)((memory_clock - 10000) / 2500); |
||
414 | |||
415 | return mc_para_index; |
||
416 | }>=>>> |