aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_clocks.c
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2009-06-05 08:42:42 -0400
committerDave Airlie <airlied@redhat.com>2009-06-14 22:01:53 -0400
commit771fe6b912fca54f03e8a72eb63058b582775362 (patch)
tree58aa5469ba8058c2b564d50807395ad6cd7bd7e4 /drivers/gpu/drm/radeon/radeon_clocks.c
parentba4e7d973dd09b66912ac4c0856add8b0703a997 (diff)
drm/radeon: introduce kernel modesetting for radeon hardware
Add kernel modesetting support to radeon driver, use the ttm memory manager to manage memory and DRM/GEM to provide userspace API. In order to avoid backward compatibility issue and to allow clean design and code the radeon kernel modesetting use different code path than old radeon/drm driver. When kernel modesetting is enabled the IOCTL of radeon/drm driver are considered as invalid and an error message is printed in the log and they return failure. KMS enabled userspace will use new API to talk with the radeon/drm driver. The new API provide functions to create/destroy/share/mmap buffer object which are then managed by the kernel memory manager (here TTM). In order to submit command to the GPU the userspace provide a buffer holding the command stream, along this buffer userspace have to provide a list of buffer object used by the command stream. The kernel radeon driver will then place buffer in GPU accessible memory and will update command stream to reflect the position of the different buffers. The kernel will also perform security check on command stream provided by the user, we want to catch and forbid any illegal use of the GPU such as DMA into random system memory or into memory not owned by the process supplying the command stream. This part of the code is still incomplete and this why we propose that patch as a staging driver addition, future security might forbid current experimental userspace to run. This code support the following hardware : R1XX,R2XX,R3XX,R4XX,R5XX (radeon up to X1950). Works is underway to provide support for R6XX, R7XX and newer hardware (radeon from HD2XXX to HD4XXX). Authors: Jerome Glisse <jglisse@redhat.com> Dave Airlie <airlied@redhat.com> Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com> Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_clocks.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_clocks.c833
1 files changed, 833 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c
new file mode 100644
index 000000000000..a37cbce53181
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_clocks.c
@@ -0,0 +1,833 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#include "drmP.h"
29#include "radeon_drm.h"
30#include "radeon_reg.h"
31#include "radeon.h"
32#include "atom.h"
33
34/* 10 khz */
35static uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev)
36{
37 struct radeon_pll *spll = &rdev->clock.spll;
38 uint32_t fb_div, ref_div, post_div, sclk;
39
40 fb_div = RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV);
41 fb_div = (fb_div >> RADEON_SPLL_FB_DIV_SHIFT) & RADEON_SPLL_FB_DIV_MASK;
42 fb_div <<= 1;
43 fb_div *= spll->reference_freq;
44
45 ref_div =
46 RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK;
47 sclk = fb_div / ref_div;
48
49 post_div = RREG32_PLL(RADEON_SCLK_CNTL) & RADEON_SCLK_SRC_SEL_MASK;
50 if (post_div == 2)
51 sclk >>= 1;
52 else if (post_div == 3)
53 sclk >>= 2;
54 else if (post_div == 4)
55 sclk >>= 4;
56
57 return sclk;
58}
59
60/* 10 khz */
61static uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev)
62{
63 struct radeon_pll *mpll = &rdev->clock.mpll;
64 uint32_t fb_div, ref_div, post_div, mclk;
65
66 fb_div = RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV);
67 fb_div = (fb_div >> RADEON_MPLL_FB_DIV_SHIFT) & RADEON_MPLL_FB_DIV_MASK;
68 fb_div <<= 1;
69 fb_div *= mpll->reference_freq;
70
71 ref_div =
72 RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK;
73 mclk = fb_div / ref_div;
74
75 post_div = RREG32_PLL(RADEON_MCLK_CNTL) & 0x7;
76 if (post_div == 2)
77 mclk >>= 1;
78 else if (post_div == 3)
79 mclk >>= 2;
80 else if (post_div == 4)
81 mclk >>= 4;
82
83 return mclk;
84}
85
86void radeon_get_clock_info(struct drm_device *dev)
87{
88 struct radeon_device *rdev = dev->dev_private;
89 struct radeon_pll *p1pll = &rdev->clock.p1pll;
90 struct radeon_pll *p2pll = &rdev->clock.p2pll;
91 struct radeon_pll *spll = &rdev->clock.spll;
92 struct radeon_pll *mpll = &rdev->clock.mpll;
93 int ret;
94
95 if (rdev->is_atom_bios)
96 ret = radeon_atom_get_clock_info(dev);
97 else
98 ret = radeon_combios_get_clock_info(dev);
99
100 if (ret) {
101 if (p1pll->reference_div < 2)
102 p1pll->reference_div = 12;
103 if (p2pll->reference_div < 2)
104 p2pll->reference_div = 12;
105 if (spll->reference_div < 2)
106 spll->reference_div =
107 RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) &
108 RADEON_M_SPLL_REF_DIV_MASK;
109 if (mpll->reference_div < 2)
110 mpll->reference_div = spll->reference_div;
111 } else {
112 if (ASIC_IS_AVIVO(rdev)) {
113 /* TODO FALLBACK */
114 } else {
115 DRM_INFO("Using generic clock info\n");
116
117 if (rdev->flags & RADEON_IS_IGP) {
118 p1pll->reference_freq = 1432;
119 p2pll->reference_freq = 1432;
120 spll->reference_freq = 1432;
121 mpll->reference_freq = 1432;
122 } else {
123 p1pll->reference_freq = 2700;
124 p2pll->reference_freq = 2700;
125 spll->reference_freq = 2700;
126 mpll->reference_freq = 2700;
127 }
128 p1pll->reference_div =
129 RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff;
130 if (p1pll->reference_div < 2)
131 p1pll->reference_div = 12;
132 p2pll->reference_div = p1pll->reference_div;
133
134 if (rdev->family >= CHIP_R420) {
135 p1pll->pll_in_min = 100;
136 p1pll->pll_in_max = 1350;
137 p1pll->pll_out_min = 20000;
138 p1pll->pll_out_max = 50000;
139 p2pll->pll_in_min = 100;
140 p2pll->pll_in_max = 1350;
141 p2pll->pll_out_min = 20000;
142 p2pll->pll_out_max = 50000;
143 } else {
144 p1pll->pll_in_min = 40;
145 p1pll->pll_in_max = 500;
146 p1pll->pll_out_min = 12500;
147 p1pll->pll_out_max = 35000;
148 p2pll->pll_in_min = 40;
149 p2pll->pll_in_max = 500;
150 p2pll->pll_out_min = 12500;
151 p2pll->pll_out_max = 35000;
152 }
153
154 spll->reference_div =
155 RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) &
156 RADEON_M_SPLL_REF_DIV_MASK;
157 mpll->reference_div = spll->reference_div;
158 rdev->clock.default_sclk =
159 radeon_legacy_get_engine_clock(rdev);
160 rdev->clock.default_mclk =
161 radeon_legacy_get_memory_clock(rdev);
162 }
163 }
164
165 /* pixel clocks */
166 if (ASIC_IS_AVIVO(rdev)) {
167 p1pll->min_post_div = 2;
168 p1pll->max_post_div = 0x7f;
169 p1pll->min_frac_feedback_div = 0;
170 p1pll->max_frac_feedback_div = 9;
171 p2pll->min_post_div = 2;
172 p2pll->max_post_div = 0x7f;
173 p2pll->min_frac_feedback_div = 0;
174 p2pll->max_frac_feedback_div = 9;
175 } else {
176 p1pll->min_post_div = 1;
177 p1pll->max_post_div = 16;
178 p1pll->min_frac_feedback_div = 0;
179 p1pll->max_frac_feedback_div = 0;
180 p2pll->min_post_div = 1;
181 p2pll->max_post_div = 12;
182 p2pll->min_frac_feedback_div = 0;
183 p2pll->max_frac_feedback_div = 0;
184 }
185
186 p1pll->min_ref_div = 2;
187 p1pll->max_ref_div = 0x3ff;
188 p1pll->min_feedback_div = 4;
189 p1pll->max_feedback_div = 0x7ff;
190 p1pll->best_vco = 0;
191
192 p2pll->min_ref_div = 2;
193 p2pll->max_ref_div = 0x3ff;
194 p2pll->min_feedback_div = 4;
195 p2pll->max_feedback_div = 0x7ff;
196 p2pll->best_vco = 0;
197
198 /* system clock */
199 spll->min_post_div = 1;
200 spll->max_post_div = 1;
201 spll->min_ref_div = 2;
202 spll->max_ref_div = 0xff;
203 spll->min_feedback_div = 4;
204 spll->max_feedback_div = 0xff;
205 spll->best_vco = 0;
206
207 /* memory clock */
208 mpll->min_post_div = 1;
209 mpll->max_post_div = 1;
210 mpll->min_ref_div = 2;
211 mpll->max_ref_div = 0xff;
212 mpll->min_feedback_div = 4;
213 mpll->max_feedback_div = 0xff;
214 mpll->best_vco = 0;
215
216}
217
218/* 10 khz */
219static uint32_t calc_eng_mem_clock(struct radeon_device *rdev,
220 uint32_t req_clock,
221 int *fb_div, int *post_div)
222{
223 struct radeon_pll *spll = &rdev->clock.spll;
224 int ref_div = spll->reference_div;
225
226 if (!ref_div)
227 ref_div =
228 RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) &
229 RADEON_M_SPLL_REF_DIV_MASK;
230
231 if (req_clock < 15000) {
232 *post_div = 8;
233 req_clock *= 8;
234 } else if (req_clock < 30000) {
235 *post_div = 4;
236 req_clock *= 4;
237 } else if (req_clock < 60000) {
238 *post_div = 2;
239 req_clock *= 2;
240 } else
241 *post_div = 1;
242
243 req_clock *= ref_div;
244 req_clock += spll->reference_freq;
245 req_clock /= (2 * spll->reference_freq);
246
247 *fb_div = req_clock & 0xff;
248
249 req_clock = (req_clock & 0xffff) << 1;
250 req_clock *= spll->reference_freq;
251 req_clock /= ref_div;
252 req_clock /= *post_div;
253
254 return req_clock;
255}
256
257/* 10 khz */
258void radeon_legacy_set_engine_clock(struct radeon_device *rdev,
259 uint32_t eng_clock)
260{
261 uint32_t tmp;
262 int fb_div, post_div;
263
264 /* XXX: wait for idle */
265
266 eng_clock = calc_eng_mem_clock(rdev, eng_clock, &fb_div, &post_div);
267
268 tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL);
269 tmp &= ~RADEON_DONT_USE_XTALIN;
270 WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp);
271
272 tmp = RREG32_PLL(RADEON_SCLK_CNTL);
273 tmp &= ~RADEON_SCLK_SRC_SEL_MASK;
274 WREG32_PLL(RADEON_SCLK_CNTL, tmp);
275
276 udelay(10);
277
278 tmp = RREG32_PLL(RADEON_SPLL_CNTL);
279 tmp |= RADEON_SPLL_SLEEP;
280 WREG32_PLL(RADEON_SPLL_CNTL, tmp);
281
282 udelay(2);
283
284 tmp = RREG32_PLL(RADEON_SPLL_CNTL);
285 tmp |= RADEON_SPLL_RESET;
286 WREG32_PLL(RADEON_SPLL_CNTL, tmp);
287
288 udelay(200);
289
290 tmp = RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV);
291 tmp &= ~(RADEON_SPLL_FB_DIV_MASK << RADEON_SPLL_FB_DIV_SHIFT);
292 tmp |= (fb_div & RADEON_SPLL_FB_DIV_MASK) << RADEON_SPLL_FB_DIV_SHIFT;
293 WREG32_PLL(RADEON_M_SPLL_REF_FB_DIV, tmp);
294
295 /* XXX: verify on different asics */
296 tmp = RREG32_PLL(RADEON_SPLL_CNTL);
297 tmp &= ~RADEON_SPLL_PVG_MASK;
298 if ((eng_clock * post_div) >= 90000)
299 tmp |= (0x7 << RADEON_SPLL_PVG_SHIFT);
300 else
301 tmp |= (0x4 << RADEON_SPLL_PVG_SHIFT);
302 WREG32_PLL(RADEON_SPLL_CNTL, tmp);
303
304 tmp = RREG32_PLL(RADEON_SPLL_CNTL);
305 tmp &= ~RADEON_SPLL_SLEEP;
306 WREG32_PLL(RADEON_SPLL_CNTL, tmp);
307
308 udelay(2);
309
310 tmp = RREG32_PLL(RADEON_SPLL_CNTL);
311 tmp &= ~RADEON_SPLL_RESET;
312 WREG32_PLL(RADEON_SPLL_CNTL, tmp);
313
314 udelay(200);
315
316 tmp = RREG32_PLL(RADEON_SCLK_CNTL);
317 tmp &= ~RADEON_SCLK_SRC_SEL_MASK;
318 switch (post_div) {
319 case 1:
320 default:
321 tmp |= 1;
322 break;
323 case 2:
324 tmp |= 2;
325 break;
326 case 4:
327 tmp |= 3;
328 break;
329 case 8:
330 tmp |= 4;
331 break;
332 }
333 WREG32_PLL(RADEON_SCLK_CNTL, tmp);
334
335 udelay(20);
336
337 tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL);
338 tmp |= RADEON_DONT_USE_XTALIN;
339 WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp);
340
341 udelay(10);
342}
343
344void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
345{
346 uint32_t tmp;
347
348 if (enable) {
349 if (rdev->flags & RADEON_SINGLE_CRTC) {
350 tmp = RREG32_PLL(RADEON_SCLK_CNTL);
351 if ((RREG32(RADEON_CONFIG_CNTL) &
352 RADEON_CFG_ATI_REV_ID_MASK) >
353 RADEON_CFG_ATI_REV_A13) {
354 tmp &=
355 ~(RADEON_SCLK_FORCE_CP |
356 RADEON_SCLK_FORCE_RB);
357 }
358 tmp &=
359 ~(RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 |
360 RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_SE |
361 RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_RE |
362 RADEON_SCLK_FORCE_PB | RADEON_SCLK_FORCE_TAM |
363 RADEON_SCLK_FORCE_TDM);
364 WREG32_PLL(RADEON_SCLK_CNTL, tmp);
365 } else if (ASIC_IS_R300(rdev)) {
366 if ((rdev->family == CHIP_RS400) ||
367 (rdev->family == CHIP_RS480)) {
368 tmp = RREG32_PLL(RADEON_SCLK_CNTL);
369 tmp &=
370 ~(RADEON_SCLK_FORCE_DISP2 |
371 RADEON_SCLK_FORCE_CP |
372 RADEON_SCLK_FORCE_HDP |
373 RADEON_SCLK_FORCE_DISP1 |
374 RADEON_SCLK_FORCE_TOP |
375 RADEON_SCLK_FORCE_E2 | R300_SCLK_FORCE_VAP
376 | RADEON_SCLK_FORCE_IDCT |
377 RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR
378 | R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX
379 | R300_SCLK_FORCE_US |
380 RADEON_SCLK_FORCE_TV_SCLK |
381 R300_SCLK_FORCE_SU |
382 RADEON_SCLK_FORCE_OV0);
383 tmp |= RADEON_DYN_STOP_LAT_MASK;
384 tmp |=
385 RADEON_SCLK_FORCE_TOP |
386 RADEON_SCLK_FORCE_VIP;
387 WREG32_PLL(RADEON_SCLK_CNTL, tmp);
388
389 tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
390 tmp &= ~RADEON_SCLK_MORE_FORCEON;
391 tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT;
392 WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
393
394 tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
395 tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
396 RADEON_PIXCLK_DAC_ALWAYS_ONb);
397 WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
398
399 tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
400 tmp |= (RADEON_PIX2CLK_ALWAYS_ONb |
401 RADEON_PIX2CLK_DAC_ALWAYS_ONb |
402 RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
403 R300_DVOCLK_ALWAYS_ONb |
404 RADEON_PIXCLK_BLEND_ALWAYS_ONb |
405 RADEON_PIXCLK_GV_ALWAYS_ONb |
406 R300_PIXCLK_DVO_ALWAYS_ONb |
407 RADEON_PIXCLK_LVDS_ALWAYS_ONb |
408 RADEON_PIXCLK_TMDS_ALWAYS_ONb |
409 R300_PIXCLK_TRANS_ALWAYS_ONb |
410 R300_PIXCLK_TVO_ALWAYS_ONb |
411 R300_P2G2CLK_ALWAYS_ONb |
412 R300_P2G2CLK_ALWAYS_ONb);
413 WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
414 } else if (rdev->family >= CHIP_RV350) {
415 tmp = RREG32_PLL(R300_SCLK_CNTL2);
416 tmp &= ~(R300_SCLK_FORCE_TCL |
417 R300_SCLK_FORCE_GA |
418 R300_SCLK_FORCE_CBA);
419 tmp |= (R300_SCLK_TCL_MAX_DYN_STOP_LAT |
420 R300_SCLK_GA_MAX_DYN_STOP_LAT |
421 R300_SCLK_CBA_MAX_DYN_STOP_LAT);
422 WREG32_PLL(R300_SCLK_CNTL2, tmp);
423
424 tmp = RREG32_PLL(RADEON_SCLK_CNTL);
425 tmp &=
426 ~(RADEON_SCLK_FORCE_DISP2 |
427 RADEON_SCLK_FORCE_CP |
428 RADEON_SCLK_FORCE_HDP |
429 RADEON_SCLK_FORCE_DISP1 |
430 RADEON_SCLK_FORCE_TOP |
431 RADEON_SCLK_FORCE_E2 | R300_SCLK_FORCE_VAP
432 | RADEON_SCLK_FORCE_IDCT |
433 RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR
434 | R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX
435 | R300_SCLK_FORCE_US |
436 RADEON_SCLK_FORCE_TV_SCLK |
437 R300_SCLK_FORCE_SU |
438 RADEON_SCLK_FORCE_OV0);
439 tmp |= RADEON_DYN_STOP_LAT_MASK;
440 WREG32_PLL(RADEON_SCLK_CNTL, tmp);
441
442 tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
443 tmp &= ~RADEON_SCLK_MORE_FORCEON;
444 tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT;
445 WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
446
447 tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
448 tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
449 RADEON_PIXCLK_DAC_ALWAYS_ONb);
450 WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
451
452 tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
453 tmp |= (RADEON_PIX2CLK_ALWAYS_ONb |
454 RADEON_PIX2CLK_DAC_ALWAYS_ONb |
455 RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
456 R300_DVOCLK_ALWAYS_ONb |
457 RADEON_PIXCLK_BLEND_ALWAYS_ONb |
458 RADEON_PIXCLK_GV_ALWAYS_ONb |
459 R300_PIXCLK_DVO_ALWAYS_ONb |
460 RADEON_PIXCLK_LVDS_ALWAYS_ONb |
461 RADEON_PIXCLK_TMDS_ALWAYS_ONb |
462 R300_PIXCLK_TRANS_ALWAYS_ONb |
463 R300_PIXCLK_TVO_ALWAYS_ONb |
464 R300_P2G2CLK_ALWAYS_ONb |
465 R300_P2G2CLK_ALWAYS_ONb);
466 WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
467
468 tmp = RREG32_PLL(RADEON_MCLK_MISC);
469 tmp |= (RADEON_MC_MCLK_DYN_ENABLE |
470 RADEON_IO_MCLK_DYN_ENABLE);
471 WREG32_PLL(RADEON_MCLK_MISC, tmp);
472
473 tmp = RREG32_PLL(RADEON_MCLK_CNTL);
474 tmp |= (RADEON_FORCEON_MCLKA |
475 RADEON_FORCEON_MCLKB);
476
477 tmp &= ~(RADEON_FORCEON_YCLKA |
478 RADEON_FORCEON_YCLKB |
479 RADEON_FORCEON_MC);
480
481 /* Some releases of vbios have set DISABLE_MC_MCLKA
482 and DISABLE_MC_MCLKB bits in the vbios table. Setting these
483 bits will cause H/W hang when reading video memory with dynamic clocking
484 enabled. */
485 if ((tmp & R300_DISABLE_MC_MCLKA) &&
486 (tmp & R300_DISABLE_MC_MCLKB)) {
487 /* If both bits are set, then check the active channels */
488 tmp = RREG32_PLL(RADEON_MCLK_CNTL);
489 if (rdev->mc.vram_width == 64) {
490 if (RREG32(RADEON_MEM_CNTL) &
491 R300_MEM_USE_CD_CH_ONLY)
492 tmp &=
493 ~R300_DISABLE_MC_MCLKB;
494 else
495 tmp &=
496 ~R300_DISABLE_MC_MCLKA;
497 } else {
498 tmp &= ~(R300_DISABLE_MC_MCLKA |
499 R300_DISABLE_MC_MCLKB);
500 }
501 }
502
503 WREG32_PLL(RADEON_MCLK_CNTL, tmp);
504 } else {
505 tmp = RREG32_PLL(RADEON_SCLK_CNTL);
506 tmp &= ~(R300_SCLK_FORCE_VAP);
507 tmp |= RADEON_SCLK_FORCE_CP;
508 WREG32_PLL(RADEON_SCLK_CNTL, tmp);
509 udelay(15000);
510
511 tmp = RREG32_PLL(R300_SCLK_CNTL2);
512 tmp &= ~(R300_SCLK_FORCE_TCL |
513 R300_SCLK_FORCE_GA |
514 R300_SCLK_FORCE_CBA);
515 WREG32_PLL(R300_SCLK_CNTL2, tmp);
516 }
517 } else {
518 tmp = RREG32_PLL(RADEON_CLK_PWRMGT_CNTL);
519
520 tmp &= ~(RADEON_ACTIVE_HILO_LAT_MASK |
521 RADEON_DISP_DYN_STOP_LAT_MASK |
522 RADEON_DYN_STOP_MODE_MASK);
523
524 tmp |= (RADEON_ENGIN_DYNCLK_MODE |
525 (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT));
526 WREG32_PLL(RADEON_CLK_PWRMGT_CNTL, tmp);
527 udelay(15000);
528
529 tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL);
530 tmp |= RADEON_SCLK_DYN_START_CNTL;
531 WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp);
532 udelay(15000);
533
534 /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200
535 to lockup randomly, leave them as set by BIOS.
536 */
537 tmp = RREG32_PLL(RADEON_SCLK_CNTL);
538 /*tmp &= RADEON_SCLK_SRC_SEL_MASK; */
539 tmp &= ~RADEON_SCLK_FORCEON_MASK;
540
541 /*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300 */
542 if (((rdev->family == CHIP_RV250) &&
543 ((RREG32(RADEON_CONFIG_CNTL) &
544 RADEON_CFG_ATI_REV_ID_MASK) <
545 RADEON_CFG_ATI_REV_A13))
546 || ((rdev->family == CHIP_RV100)
547 &&
548 ((RREG32(RADEON_CONFIG_CNTL) &
549 RADEON_CFG_ATI_REV_ID_MASK) <=
550 RADEON_CFG_ATI_REV_A13))) {
551 tmp |= RADEON_SCLK_FORCE_CP;
552 tmp |= RADEON_SCLK_FORCE_VIP;
553 }
554
555 WREG32_PLL(RADEON_SCLK_CNTL, tmp);
556
557 if ((rdev->family == CHIP_RV200) ||
558 (rdev->family == CHIP_RV250) ||
559 (rdev->family == CHIP_RV280)) {
560 tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
561 tmp &= ~RADEON_SCLK_MORE_FORCEON;
562
563 /* RV200::A11 A12 RV250::A11 A12 */
564 if (((rdev->family == CHIP_RV200) ||
565 (rdev->family == CHIP_RV250)) &&
566 ((RREG32(RADEON_CONFIG_CNTL) &
567 RADEON_CFG_ATI_REV_ID_MASK) <
568 RADEON_CFG_ATI_REV_A13)) {
569 tmp |= RADEON_SCLK_MORE_FORCEON;
570 }
571 WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
572 udelay(15000);
573 }
574
575 /* RV200::A11 A12, RV250::A11 A12 */
576 if (((rdev->family == CHIP_RV200) ||
577 (rdev->family == CHIP_RV250)) &&
578 ((RREG32(RADEON_CONFIG_CNTL) &
579 RADEON_CFG_ATI_REV_ID_MASK) <
580 RADEON_CFG_ATI_REV_A13)) {
581 tmp = RREG32_PLL(RADEON_PLL_PWRMGT_CNTL);
582 tmp |= RADEON_TCL_BYPASS_DISABLE;
583 WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp);
584 }
585 udelay(15000);
586
587 /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK) */
588 tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
589 tmp |= (RADEON_PIX2CLK_ALWAYS_ONb |
590 RADEON_PIX2CLK_DAC_ALWAYS_ONb |
591 RADEON_PIXCLK_BLEND_ALWAYS_ONb |
592 RADEON_PIXCLK_GV_ALWAYS_ONb |
593 RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb |
594 RADEON_PIXCLK_LVDS_ALWAYS_ONb |
595 RADEON_PIXCLK_TMDS_ALWAYS_ONb);
596
597 WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
598 udelay(15000);
599
600 tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
601 tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
602 RADEON_PIXCLK_DAC_ALWAYS_ONb);
603
604 WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
605 udelay(15000);
606 }
607 } else {
608 /* Turn everything OFF (ForceON to everything) */
609 if (rdev->flags & RADEON_SINGLE_CRTC) {
610 tmp = RREG32_PLL(RADEON_SCLK_CNTL);
611 tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_HDP |
612 RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_TOP
613 | RADEON_SCLK_FORCE_E2 | RADEON_SCLK_FORCE_SE |
614 RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_VIP |
615 RADEON_SCLK_FORCE_RE | RADEON_SCLK_FORCE_PB |
616 RADEON_SCLK_FORCE_TAM | RADEON_SCLK_FORCE_TDM |
617 RADEON_SCLK_FORCE_RB);
618 WREG32_PLL(RADEON_SCLK_CNTL, tmp);
619 } else if ((rdev->family == CHIP_RS400) ||
620 (rdev->family == CHIP_RS480)) {
621 tmp = RREG32_PLL(RADEON_SCLK_CNTL);
622 tmp |= (RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP |
623 RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1
624 | RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 |
625 R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT |
626 RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR |
627 R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX |
628 R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK |
629 R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0);
630 WREG32_PLL(RADEON_SCLK_CNTL, tmp);
631
632 tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
633 tmp |= RADEON_SCLK_MORE_FORCEON;
634 WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
635
636 tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
637 tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
638 RADEON_PIXCLK_DAC_ALWAYS_ONb |
639 R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF);
640 WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
641
642 tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
643 tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb |
644 RADEON_PIX2CLK_DAC_ALWAYS_ONb |
645 RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
646 R300_DVOCLK_ALWAYS_ONb |
647 RADEON_PIXCLK_BLEND_ALWAYS_ONb |
648 RADEON_PIXCLK_GV_ALWAYS_ONb |
649 R300_PIXCLK_DVO_ALWAYS_ONb |
650 RADEON_PIXCLK_LVDS_ALWAYS_ONb |
651 RADEON_PIXCLK_TMDS_ALWAYS_ONb |
652 R300_PIXCLK_TRANS_ALWAYS_ONb |
653 R300_PIXCLK_TVO_ALWAYS_ONb |
654 R300_P2G2CLK_ALWAYS_ONb |
655 R300_P2G2CLK_ALWAYS_ONb |
656 R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF);
657 WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
658 } else if (rdev->family >= CHIP_RV350) {
659 /* for RV350/M10, no delays are required. */
660 tmp = RREG32_PLL(R300_SCLK_CNTL2);
661 tmp |= (R300_SCLK_FORCE_TCL |
662 R300_SCLK_FORCE_GA | R300_SCLK_FORCE_CBA);
663 WREG32_PLL(R300_SCLK_CNTL2, tmp);
664
665 tmp = RREG32_PLL(RADEON_SCLK_CNTL);
666 tmp |= (RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP |
667 RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1
668 | RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 |
669 R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT |
670 RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR |
671 R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX |
672 R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK |
673 R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0);
674 WREG32_PLL(RADEON_SCLK_CNTL, tmp);
675
676 tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
677 tmp |= RADEON_SCLK_MORE_FORCEON;
678 WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
679
680 tmp = RREG32_PLL(RADEON_MCLK_CNTL);
681 tmp |= (RADEON_FORCEON_MCLKA |
682 RADEON_FORCEON_MCLKB |
683 RADEON_FORCEON_YCLKA |
684 RADEON_FORCEON_YCLKB | RADEON_FORCEON_MC);
685 WREG32_PLL(RADEON_MCLK_CNTL, tmp);
686
687 tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
688 tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
689 RADEON_PIXCLK_DAC_ALWAYS_ONb |
690 R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF);
691 WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
692
693 tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
694 tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb |
695 RADEON_PIX2CLK_DAC_ALWAYS_ONb |
696 RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
697 R300_DVOCLK_ALWAYS_ONb |
698 RADEON_PIXCLK_BLEND_ALWAYS_ONb |
699 RADEON_PIXCLK_GV_ALWAYS_ONb |
700 R300_PIXCLK_DVO_ALWAYS_ONb |
701 RADEON_PIXCLK_LVDS_ALWAYS_ONb |
702 RADEON_PIXCLK_TMDS_ALWAYS_ONb |
703 R300_PIXCLK_TRANS_ALWAYS_ONb |
704 R300_PIXCLK_TVO_ALWAYS_ONb |
705 R300_P2G2CLK_ALWAYS_ONb |
706 R300_P2G2CLK_ALWAYS_ONb |
707 R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF);
708 WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
709 } else {
710 tmp = RREG32_PLL(RADEON_SCLK_CNTL);
711 tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_E2);
712 tmp |= RADEON_SCLK_FORCE_SE;
713
714 if (rdev->flags & RADEON_SINGLE_CRTC) {
715 tmp |= (RADEON_SCLK_FORCE_RB |
716 RADEON_SCLK_FORCE_TDM |
717 RADEON_SCLK_FORCE_TAM |
718 RADEON_SCLK_FORCE_PB |
719 RADEON_SCLK_FORCE_RE |
720 RADEON_SCLK_FORCE_VIP |
721 RADEON_SCLK_FORCE_IDCT |
722 RADEON_SCLK_FORCE_TOP |
723 RADEON_SCLK_FORCE_DISP1 |
724 RADEON_SCLK_FORCE_DISP2 |
725 RADEON_SCLK_FORCE_HDP);
726 } else if ((rdev->family == CHIP_R300) ||
727 (rdev->family == CHIP_R350)) {
728 tmp |= (RADEON_SCLK_FORCE_HDP |
729 RADEON_SCLK_FORCE_DISP1 |
730 RADEON_SCLK_FORCE_DISP2 |
731 RADEON_SCLK_FORCE_TOP |
732 RADEON_SCLK_FORCE_IDCT |
733 RADEON_SCLK_FORCE_VIP);
734 }
735 WREG32_PLL(RADEON_SCLK_CNTL, tmp);
736
737 udelay(16000);
738
739 if ((rdev->family == CHIP_R300) ||
740 (rdev->family == CHIP_R350)) {
741 tmp = RREG32_PLL(R300_SCLK_CNTL2);
742 tmp |= (R300_SCLK_FORCE_TCL |
743 R300_SCLK_FORCE_GA |
744 R300_SCLK_FORCE_CBA);
745 WREG32_PLL(R300_SCLK_CNTL2, tmp);
746 udelay(16000);
747 }
748
749 if (rdev->flags & RADEON_IS_IGP) {
750 tmp = RREG32_PLL(RADEON_MCLK_CNTL);
751 tmp &= ~(RADEON_FORCEON_MCLKA |
752 RADEON_FORCEON_YCLKA);
753 WREG32_PLL(RADEON_MCLK_CNTL, tmp);
754 udelay(16000);
755 }
756
757 if ((rdev->family == CHIP_RV200) ||
758 (rdev->family == CHIP_RV250) ||
759 (rdev->family == CHIP_RV280)) {
760 tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
761 tmp |= RADEON_SCLK_MORE_FORCEON;
762 WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
763 udelay(16000);
764 }
765
766 tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
767 tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb |
768 RADEON_PIX2CLK_DAC_ALWAYS_ONb |
769 RADEON_PIXCLK_BLEND_ALWAYS_ONb |
770 RADEON_PIXCLK_GV_ALWAYS_ONb |
771 RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb |
772 RADEON_PIXCLK_LVDS_ALWAYS_ONb |
773 RADEON_PIXCLK_TMDS_ALWAYS_ONb);
774
775 WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
776 udelay(16000);
777
778 tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
779 tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
780 RADEON_PIXCLK_DAC_ALWAYS_ONb);
781 WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
782 }
783 }
784}
785
786static void radeon_apply_clock_quirks(struct radeon_device *rdev)
787{
788 uint32_t tmp;
789
790 /* XXX make sure engine is idle */
791
792 if (rdev->family < CHIP_RS600) {
793 tmp = RREG32_PLL(RADEON_SCLK_CNTL);
794 if (ASIC_IS_R300(rdev) || ASIC_IS_RV100(rdev))
795 tmp |= RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_VIP;
796 if ((rdev->family == CHIP_RV250)
797 || (rdev->family == CHIP_RV280))
798 tmp |=
799 RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_DISP2;
800 if ((rdev->family == CHIP_RV350)
801 || (rdev->family == CHIP_RV380))
802 tmp |= R300_SCLK_FORCE_VAP;
803 if (rdev->family == CHIP_R420)
804 tmp |= R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX;
805 WREG32_PLL(RADEON_SCLK_CNTL, tmp);
806 } else if (rdev->family < CHIP_R600) {
807 tmp = RREG32_PLL(AVIVO_CP_DYN_CNTL);
808 tmp |= AVIVO_CP_FORCEON;
809 WREG32_PLL(AVIVO_CP_DYN_CNTL, tmp);
810
811 tmp = RREG32_PLL(AVIVO_E2_DYN_CNTL);
812 tmp |= AVIVO_E2_FORCEON;
813 WREG32_PLL(AVIVO_E2_DYN_CNTL, tmp);
814
815 tmp = RREG32_PLL(AVIVO_IDCT_DYN_CNTL);
816 tmp |= AVIVO_IDCT_FORCEON;
817 WREG32_PLL(AVIVO_IDCT_DYN_CNTL, tmp);
818 }
819}
820
821int radeon_static_clocks_init(struct drm_device *dev)
822{
823 struct radeon_device *rdev = dev->dev_private;
824
825 /* XXX make sure engine is idle */
826
827 if (radeon_dynclks != -1) {
828 if (radeon_dynclks)
829 radeon_set_clock_gating(rdev, 1);
830 }
831 radeon_apply_clock_quirks(rdev);
832 return 0;
833}