blob: 7d06dc98a42a5d678bf5adc33ef0b686c629488c [file] [log] [blame]
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001/*
2 * Copyright 2007-8 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors: Dave Airlie
24 * Alex Deucher
25 */
26#include <drm/drmP.h>
27#include <drm/drm_crtc_helper.h>
28#include <drm/radeon_drm.h>
29#include "radeon_fixed.h"
30#include "radeon.h"
31
Jerome Glissec93bb852009-07-13 21:04:08 +020032static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc,
33 struct drm_display_mode *mode,
34 struct drm_display_mode *adjusted_mode)
35{
36 struct drm_device *dev = crtc->dev;
37 struct radeon_device *rdev = dev->dev_private;
38 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
39 int xres = mode->hdisplay;
40 int yres = mode->vdisplay;
41 bool hscale = true, vscale = true;
42 int hsync_wid;
43 int vsync_wid;
44 int hsync_start;
45 int blank_width;
46 u32 scale, inc, crtc_more_cntl;
47 u32 fp_horz_stretch, fp_vert_stretch, fp_horz_vert_active;
48 u32 fp_h_sync_strt_wid, fp_crtc_h_total_disp;
49 u32 fp_v_sync_strt_wid, fp_crtc_v_total_disp;
50 struct radeon_native_mode *native_mode = &radeon_crtc->native_mode;
51
52 fp_vert_stretch = RREG32(RADEON_FP_VERT_STRETCH) &
53 (RADEON_VERT_STRETCH_RESERVED |
54 RADEON_VERT_AUTO_RATIO_INC);
55 fp_horz_stretch = RREG32(RADEON_FP_HORZ_STRETCH) &
56 (RADEON_HORZ_FP_LOOP_STRETCH |
57 RADEON_HORZ_AUTO_RATIO_INC);
58
59 crtc_more_cntl = 0;
60 if ((rdev->family == CHIP_RS100) ||
61 (rdev->family == CHIP_RS200)) {
62 /* This is to workaround the asic bug for RMX, some versions
63 of BIOS dosen't have this register initialized correctly. */
64 crtc_more_cntl |= RADEON_CRTC_H_CUTOFF_ACTIVE_EN;
65 }
66
67
68 fp_crtc_h_total_disp = ((((mode->crtc_htotal / 8) - 1) & 0x3ff)
69 | ((((mode->crtc_hdisplay / 8) - 1) & 0x1ff) << 16));
70
71 hsync_wid = (mode->crtc_hsync_end - mode->crtc_hsync_start) / 8;
72 if (!hsync_wid)
73 hsync_wid = 1;
74 hsync_start = mode->crtc_hsync_start - 8;
75
76 fp_h_sync_strt_wid = ((hsync_start & 0x1fff)
77 | ((hsync_wid & 0x3f) << 16)
78 | ((mode->flags & DRM_MODE_FLAG_NHSYNC)
79 ? RADEON_CRTC_H_SYNC_POL
80 : 0));
81
82 fp_crtc_v_total_disp = (((mode->crtc_vtotal - 1) & 0xffff)
83 | ((mode->crtc_vdisplay - 1) << 16));
84
85 vsync_wid = mode->crtc_vsync_end - mode->crtc_vsync_start;
86 if (!vsync_wid)
87 vsync_wid = 1;
88
89 fp_v_sync_strt_wid = (((mode->crtc_vsync_start - 1) & 0xfff)
90 | ((vsync_wid & 0x1f) << 16)
91 | ((mode->flags & DRM_MODE_FLAG_NVSYNC)
92 ? RADEON_CRTC_V_SYNC_POL
93 : 0));
94
95 fp_horz_vert_active = 0;
96
97 if (native_mode->panel_xres == 0 ||
98 native_mode->panel_yres == 0) {
99 hscale = false;
100 vscale = false;
101 } else {
102 if (xres > native_mode->panel_xres)
103 xres = native_mode->panel_xres;
104 if (yres > native_mode->panel_yres)
105 yres = native_mode->panel_yres;
106
107 if (xres == native_mode->panel_xres)
108 hscale = false;
109 if (yres == native_mode->panel_yres)
110 vscale = false;
111 }
112
113 switch (radeon_crtc->rmx_type) {
114 case RMX_FULL:
115 case RMX_ASPECT:
116 if (!hscale)
117 fp_horz_stretch |= ((xres/8-1) << 16);
118 else {
119 inc = (fp_horz_stretch & RADEON_HORZ_AUTO_RATIO_INC) ? 1 : 0;
120 scale = ((xres + inc) * RADEON_HORZ_STRETCH_RATIO_MAX)
121 / native_mode->panel_xres + 1;
122 fp_horz_stretch |= (((scale) & RADEON_HORZ_STRETCH_RATIO_MASK) |
123 RADEON_HORZ_STRETCH_BLEND |
124 RADEON_HORZ_STRETCH_ENABLE |
125 ((native_mode->panel_xres/8-1) << 16));
126 }
127
128 if (!vscale)
129 fp_vert_stretch |= ((yres-1) << 12);
130 else {
131 inc = (fp_vert_stretch & RADEON_VERT_AUTO_RATIO_INC) ? 1 : 0;
132 scale = ((yres + inc) * RADEON_VERT_STRETCH_RATIO_MAX)
133 / native_mode->panel_yres + 1;
134 fp_vert_stretch |= (((scale) & RADEON_VERT_STRETCH_RATIO_MASK) |
135 RADEON_VERT_STRETCH_ENABLE |
136 RADEON_VERT_STRETCH_BLEND |
137 ((native_mode->panel_yres-1) << 12));
138 }
139 break;
140 case RMX_CENTER:
141 fp_horz_stretch |= ((xres/8-1) << 16);
142 fp_vert_stretch |= ((yres-1) << 12);
143
144 crtc_more_cntl |= (RADEON_CRTC_AUTO_HORZ_CENTER_EN |
145 RADEON_CRTC_AUTO_VERT_CENTER_EN);
146
147 blank_width = (mode->crtc_hblank_end - mode->crtc_hblank_start) / 8;
148 if (blank_width > 110)
149 blank_width = 110;
150
151 fp_crtc_h_total_disp = (((blank_width) & 0x3ff)
152 | ((((mode->crtc_hdisplay / 8) - 1) & 0x1ff) << 16));
153
154 hsync_wid = (mode->crtc_hsync_end - mode->crtc_hsync_start) / 8;
155 if (!hsync_wid)
156 hsync_wid = 1;
157
158 fp_h_sync_strt_wid = ((((mode->crtc_hsync_start - mode->crtc_hblank_start) / 8) & 0x1fff)
159 | ((hsync_wid & 0x3f) << 16)
160 | ((mode->flags & DRM_MODE_FLAG_NHSYNC)
161 ? RADEON_CRTC_H_SYNC_POL
162 : 0));
163
164 fp_crtc_v_total_disp = (((mode->crtc_vblank_end - mode->crtc_vblank_start) & 0xffff)
165 | ((mode->crtc_vdisplay - 1) << 16));
166
167 vsync_wid = mode->crtc_vsync_end - mode->crtc_vsync_start;
168 if (!vsync_wid)
169 vsync_wid = 1;
170
171 fp_v_sync_strt_wid = ((((mode->crtc_vsync_start - mode->crtc_vblank_start) & 0xfff)
172 | ((vsync_wid & 0x1f) << 16)
173 | ((mode->flags & DRM_MODE_FLAG_NVSYNC)
174 ? RADEON_CRTC_V_SYNC_POL
175 : 0)));
176
177 fp_horz_vert_active = (((native_mode->panel_yres) & 0xfff) |
178 (((native_mode->panel_xres / 8) & 0x1ff) << 16));
179 break;
180 case RMX_OFF:
181 default:
182 fp_horz_stretch |= ((xres/8-1) << 16);
183 fp_vert_stretch |= ((yres-1) << 12);
184 break;
185 }
186
187 WREG32(RADEON_FP_HORZ_STRETCH, fp_horz_stretch);
188 WREG32(RADEON_FP_VERT_STRETCH, fp_vert_stretch);
189 WREG32(RADEON_CRTC_MORE_CNTL, crtc_more_cntl);
190 WREG32(RADEON_FP_HORZ_VERT_ACTIVE, fp_horz_vert_active);
191 WREG32(RADEON_FP_H_SYNC_STRT_WID, fp_h_sync_strt_wid);
192 WREG32(RADEON_FP_V_SYNC_STRT_WID, fp_v_sync_strt_wid);
193 WREG32(RADEON_FP_CRTC_H_TOTAL_DISP, fp_crtc_h_total_disp);
194 WREG32(RADEON_FP_CRTC_V_TOTAL_DISP, fp_crtc_v_total_disp);
195}
196
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200197void radeon_restore_common_regs(struct drm_device *dev)
198{
199 /* don't need this yet */
200}
201
202static void radeon_pll_wait_for_read_update_complete(struct drm_device *dev)
203{
204 struct radeon_device *rdev = dev->dev_private;
205 int i = 0;
206
207 /* FIXME: Certain revisions of R300 can't recover here. Not sure of
208 the cause yet, but this workaround will mask the problem for now.
209 Other chips usually will pass at the very first test, so the
210 workaround shouldn't have any effect on them. */
211 for (i = 0;
212 (i < 10000 &&
213 RREG32_PLL(RADEON_PPLL_REF_DIV) & RADEON_PPLL_ATOMIC_UPDATE_R);
214 i++);
215}
216
217static void radeon_pll_write_update(struct drm_device *dev)
218{
219 struct radeon_device *rdev = dev->dev_private;
220
221 while (RREG32_PLL(RADEON_PPLL_REF_DIV) & RADEON_PPLL_ATOMIC_UPDATE_R);
222
223 WREG32_PLL_P(RADEON_PPLL_REF_DIV,
224 RADEON_PPLL_ATOMIC_UPDATE_W,
225 ~(RADEON_PPLL_ATOMIC_UPDATE_W));
226}
227
228static void radeon_pll2_wait_for_read_update_complete(struct drm_device *dev)
229{
230 struct radeon_device *rdev = dev->dev_private;
231 int i = 0;
232
233
234 /* FIXME: Certain revisions of R300 can't recover here. Not sure of
235 the cause yet, but this workaround will mask the problem for now.
236 Other chips usually will pass at the very first test, so the
237 workaround shouldn't have any effect on them. */
238 for (i = 0;
239 (i < 10000 &&
240 RREG32_PLL(RADEON_P2PLL_REF_DIV) & RADEON_P2PLL_ATOMIC_UPDATE_R);
241 i++);
242}
243
244static void radeon_pll2_write_update(struct drm_device *dev)
245{
246 struct radeon_device *rdev = dev->dev_private;
247
248 while (RREG32_PLL(RADEON_P2PLL_REF_DIV) & RADEON_P2PLL_ATOMIC_UPDATE_R);
249
250 WREG32_PLL_P(RADEON_P2PLL_REF_DIV,
251 RADEON_P2PLL_ATOMIC_UPDATE_W,
252 ~(RADEON_P2PLL_ATOMIC_UPDATE_W));
253}
254
255static uint8_t radeon_compute_pll_gain(uint16_t ref_freq, uint16_t ref_div,
256 uint16_t fb_div)
257{
258 unsigned int vcoFreq;
259
260 if (!ref_div)
261 return 1;
262
263 vcoFreq = ((unsigned)ref_freq & fb_div) / ref_div;
264
265 /*
266 * This is horribly crude: the VCO frequency range is divided into
267 * 3 parts, each part having a fixed PLL gain value.
268 */
269 if (vcoFreq >= 30000)
270 /*
271 * [300..max] MHz : 7
272 */
273 return 7;
274 else if (vcoFreq >= 18000)
275 /*
276 * [180..300) MHz : 4
277 */
278 return 4;
279 else
280 /*
281 * [0..180) MHz : 1
282 */
283 return 1;
284}
285
286void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
287{
288 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
289 struct drm_device *dev = crtc->dev;
290 struct radeon_device *rdev = dev->dev_private;
291 uint32_t mask;
292
293 if (radeon_crtc->crtc_id)
294 mask = (RADEON_CRTC2_EN |
295 RADEON_CRTC2_DISP_DIS |
296 RADEON_CRTC2_VSYNC_DIS |
297 RADEON_CRTC2_HSYNC_DIS |
298 RADEON_CRTC2_DISP_REQ_EN_B);
299 else
300 mask = (RADEON_CRTC_DISPLAY_DIS |
301 RADEON_CRTC_VSYNC_DIS |
302 RADEON_CRTC_HSYNC_DIS);
303
304 switch (mode) {
305 case DRM_MODE_DPMS_ON:
306 if (radeon_crtc->crtc_id)
307 WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~mask);
308 else {
309 WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN |
310 RADEON_CRTC_DISP_REQ_EN_B));
311 WREG32_P(RADEON_CRTC_EXT_CNTL, 0, ~mask);
312 }
313 break;
314 case DRM_MODE_DPMS_STANDBY:
315 case DRM_MODE_DPMS_SUSPEND:
316 case DRM_MODE_DPMS_OFF:
317 if (radeon_crtc->crtc_id)
318 WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~mask);
319 else {
320 WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN |
321 RADEON_CRTC_DISP_REQ_EN_B));
322 WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~mask);
323 }
324 break;
325 }
326
327 if (mode != DRM_MODE_DPMS_OFF) {
328 radeon_crtc_load_lut(crtc);
329 }
330}
331
332/* properly set crtc bpp when using atombios */
333void radeon_legacy_atom_set_surface(struct drm_crtc *crtc)
334{
335 struct drm_device *dev = crtc->dev;
336 struct radeon_device *rdev = dev->dev_private;
337 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
338 int format;
339 uint32_t crtc_gen_cntl;
340 uint32_t disp_merge_cntl;
341 uint32_t crtc_pitch;
342
343 switch (crtc->fb->bits_per_pixel) {
344 case 15: /* 555 */
345 format = 3;
346 break;
347 case 16: /* 565 */
348 format = 4;
349 break;
350 case 24: /* RGB */
351 format = 5;
352 break;
353 case 32: /* xRGB */
354 format = 6;
355 break;
356 default:
357 return;
358 }
359
360 crtc_pitch = ((((crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8)) * crtc->fb->bits_per_pixel) +
361 ((crtc->fb->bits_per_pixel * 8) - 1)) /
362 (crtc->fb->bits_per_pixel * 8));
363 crtc_pitch |= crtc_pitch << 16;
364
365 WREG32(RADEON_CRTC_PITCH + radeon_crtc->crtc_offset, crtc_pitch);
366
367 switch (radeon_crtc->crtc_id) {
368 case 0:
369 disp_merge_cntl = RREG32(RADEON_DISP_MERGE_CNTL);
370 disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
371 WREG32(RADEON_DISP_MERGE_CNTL, disp_merge_cntl);
372
373 crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL) & 0xfffff0ff;
374 crtc_gen_cntl |= (format << 8);
375 crtc_gen_cntl |= RADEON_CRTC_EXT_DISP_EN;
376 WREG32(RADEON_CRTC_GEN_CNTL, crtc_gen_cntl);
377 break;
378 case 1:
379 disp_merge_cntl = RREG32(RADEON_DISP2_MERGE_CNTL);
380 disp_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN;
381 WREG32(RADEON_DISP2_MERGE_CNTL, disp_merge_cntl);
382
383 crtc_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL) & 0xfffff0ff;
384 crtc_gen_cntl |= (format << 8);
385 WREG32(RADEON_CRTC2_GEN_CNTL, crtc_gen_cntl);
386 WREG32(RADEON_FP_H2_SYNC_STRT_WID, RREG32(RADEON_CRTC2_H_SYNC_STRT_WID));
387 WREG32(RADEON_FP_V2_SYNC_STRT_WID, RREG32(RADEON_CRTC2_V_SYNC_STRT_WID));
388 break;
389 }
390}
391
392int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
393 struct drm_framebuffer *old_fb)
394{
395 struct drm_device *dev = crtc->dev;
396 struct radeon_device *rdev = dev->dev_private;
397 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
398 struct radeon_framebuffer *radeon_fb;
399 struct drm_gem_object *obj;
400 uint64_t base;
401 uint32_t crtc_offset, crtc_offset_cntl, crtc_tile_x0_y0 = 0;
402 uint32_t crtc_pitch, pitch_pixels;
Dave Airliee024e112009-06-24 09:48:08 +1000403 uint32_t tiling_flags;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200404
405 DRM_DEBUG("\n");
406
407 radeon_fb = to_radeon_framebuffer(crtc->fb);
408
409 obj = radeon_fb->obj;
410 if (radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &base)) {
411 return -EINVAL;
412 }
Dave Airlie41623382009-07-09 15:04:19 +1000413 /* if scanout was in GTT this really wouldn't work */
414 /* crtc offset is from display base addr not FB location */
415 radeon_crtc->legacy_display_base_addr = rdev->mc.vram_location;
416
417 base -= radeon_crtc->legacy_display_base_addr;
418
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200419 crtc_offset_cntl = 0;
420
421 pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8);
422 crtc_pitch = (((pitch_pixels * crtc->fb->bits_per_pixel) +
423 ((crtc->fb->bits_per_pixel * 8) - 1)) /
424 (crtc->fb->bits_per_pixel * 8));
425 crtc_pitch |= crtc_pitch << 16;
426
Dave Airliee024e112009-06-24 09:48:08 +1000427 radeon_object_get_tiling_flags(obj->driver_private,
428 &tiling_flags, NULL);
429 if (tiling_flags & RADEON_TILING_MICRO)
430 DRM_ERROR("trying to scanout microtiled buffer\n");
431
432 if (tiling_flags & RADEON_TILING_MACRO) {
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200433 if (ASIC_IS_R300(rdev))
434 crtc_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
435 R300_CRTC_MICRO_TILE_BUFFER_DIS |
436 R300_CRTC_MACRO_TILE_EN);
437 else
438 crtc_offset_cntl |= RADEON_CRTC_TILE_EN;
439 } else {
440 if (ASIC_IS_R300(rdev))
441 crtc_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN |
442 R300_CRTC_MICRO_TILE_BUFFER_DIS |
443 R300_CRTC_MACRO_TILE_EN);
444 else
445 crtc_offset_cntl &= ~RADEON_CRTC_TILE_EN;
446 }
447
Dave Airliee024e112009-06-24 09:48:08 +1000448 if (tiling_flags & RADEON_TILING_MACRO) {
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200449 if (ASIC_IS_R300(rdev)) {
450 crtc_tile_x0_y0 = x | (y << 16);
451 base &= ~0x7ff;
452 } else {
453 int byteshift = crtc->fb->bits_per_pixel >> 4;
Dave Airliee024e112009-06-24 09:48:08 +1000454 int tile_addr = (((y >> 3) * pitch_pixels + x) >> (8 - byteshift)) << 11;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200455 base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8);
456 crtc_offset_cntl |= (y % 16);
457 }
458 } else {
459 int offset = y * pitch_pixels + x;
460 switch (crtc->fb->bits_per_pixel) {
461 case 15:
462 case 16:
463 offset *= 2;
464 break;
465 case 24:
466 offset *= 3;
467 break;
468 case 32:
469 offset *= 4;
470 break;
471 default:
472 return false;
473 }
474 base += offset;
475 }
476
477 base &= ~7;
478
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200479 crtc_offset = (u32)base;
480
Dave Airlie41623382009-07-09 15:04:19 +1000481 WREG32(RADEON_DISPLAY_BASE_ADDR + radeon_crtc->crtc_offset, radeon_crtc->legacy_display_base_addr);
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200482
483 if (ASIC_IS_R300(rdev)) {
484 if (radeon_crtc->crtc_id)
485 WREG32(R300_CRTC2_TILE_X0_Y0, crtc_tile_x0_y0);
486 else
487 WREG32(R300_CRTC_TILE_X0_Y0, crtc_tile_x0_y0);
488 }
489 WREG32(RADEON_CRTC_OFFSET_CNTL + radeon_crtc->crtc_offset, crtc_offset_cntl);
490 WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, crtc_offset);
491 WREG32(RADEON_CRTC_PITCH + radeon_crtc->crtc_offset, crtc_pitch);
492
493 if (old_fb && old_fb != crtc->fb) {
494 radeon_fb = to_radeon_framebuffer(old_fb);
495 radeon_gem_object_unpin(radeon_fb->obj);
496 }
497 return 0;
498}
499
500static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mode *mode)
501{
502 struct drm_device *dev = crtc->dev;
503 struct radeon_device *rdev = dev->dev_private;
504 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
505 int format;
506 int hsync_start;
507 int hsync_wid;
508 int vsync_wid;
509 uint32_t crtc_h_total_disp;
510 uint32_t crtc_h_sync_strt_wid;
511 uint32_t crtc_v_total_disp;
512 uint32_t crtc_v_sync_strt_wid;
513
514 DRM_DEBUG("\n");
515
516 switch (crtc->fb->bits_per_pixel) {
517 case 15: /* 555 */
518 format = 3;
519 break;
520 case 16: /* 565 */
521 format = 4;
522 break;
523 case 24: /* RGB */
524 format = 5;
525 break;
526 case 32: /* xRGB */
527 format = 6;
528 break;
529 default:
530 return false;
531 }
532
533 crtc_h_total_disp = ((((mode->crtc_htotal / 8) - 1) & 0x3ff)
534 | ((((mode->crtc_hdisplay / 8) - 1) & 0x1ff) << 16));
535
536 hsync_wid = (mode->crtc_hsync_end - mode->crtc_hsync_start) / 8;
537 if (!hsync_wid)
538 hsync_wid = 1;
539 hsync_start = mode->crtc_hsync_start - 8;
540
541 crtc_h_sync_strt_wid = ((hsync_start & 0x1fff)
542 | ((hsync_wid & 0x3f) << 16)
543 | ((mode->flags & DRM_MODE_FLAG_NHSYNC)
544 ? RADEON_CRTC_H_SYNC_POL
545 : 0));
546
547 /* This works for double scan mode. */
548 crtc_v_total_disp = (((mode->crtc_vtotal - 1) & 0xffff)
549 | ((mode->crtc_vdisplay - 1) << 16));
550
551 vsync_wid = mode->crtc_vsync_end - mode->crtc_vsync_start;
552 if (!vsync_wid)
553 vsync_wid = 1;
554
555 crtc_v_sync_strt_wid = (((mode->crtc_vsync_start - 1) & 0xfff)
556 | ((vsync_wid & 0x1f) << 16)
557 | ((mode->flags & DRM_MODE_FLAG_NVSYNC)
558 ? RADEON_CRTC_V_SYNC_POL
559 : 0));
560
561 /* TODO -> Dell Server */
562 if (0) {
563 uint32_t disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG);
564 uint32_t tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
565 uint32_t dac2_cntl = RREG32(RADEON_DAC_CNTL2);
566 uint32_t crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
567
568 dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL;
569 dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL;
570
571 /* For CRT on DAC2, don't turn it on if BIOS didn't
572 enable it, even it's detected.
573 */
574 disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
575 tv_dac_cntl &= ~((1<<2) | (3<<8) | (7<<24) | (0xff<<16));
576 tv_dac_cntl |= (0x03 | (2<<8) | (0x58<<16));
577
578 WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
579 WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);
580 WREG32(RADEON_DAC_CNTL2, dac2_cntl);
581 WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
582 }
583
584 if (radeon_crtc->crtc_id) {
585 uint32_t crtc2_gen_cntl;
586 uint32_t disp2_merge_cntl;
587
588 /* check to see if TV DAC is enabled for another crtc and keep it enabled */
589 if (RREG32(RADEON_CRTC2_GEN_CNTL) & RADEON_CRTC2_CRT2_ON)
590 crtc2_gen_cntl = RADEON_CRTC2_CRT2_ON;
591 else
592 crtc2_gen_cntl = 0;
593
594 crtc2_gen_cntl |= ((format << 8)
595 | RADEON_CRTC2_VSYNC_DIS
596 | RADEON_CRTC2_HSYNC_DIS
597 | RADEON_CRTC2_DISP_DIS
598 | RADEON_CRTC2_DISP_REQ_EN_B
599 | ((mode->flags & DRM_MODE_FLAG_DBLSCAN)
600 ? RADEON_CRTC2_DBL_SCAN_EN
601 : 0)
602 | ((mode->flags & DRM_MODE_FLAG_CSYNC)
603 ? RADEON_CRTC2_CSYNC_EN
604 : 0)
605 | ((mode->flags & DRM_MODE_FLAG_INTERLACE)
606 ? RADEON_CRTC2_INTERLACE_EN
607 : 0));
608
609 disp2_merge_cntl = RREG32(RADEON_DISP2_MERGE_CNTL);
610 disp2_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN;
611
612 WREG32(RADEON_DISP2_MERGE_CNTL, disp2_merge_cntl);
613 WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
614 } else {
615 uint32_t crtc_gen_cntl;
616 uint32_t crtc_ext_cntl;
617 uint32_t disp_merge_cntl;
618
619 crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN
620 | (format << 8)
621 | RADEON_CRTC_DISP_REQ_EN_B
622 | ((mode->flags & DRM_MODE_FLAG_DBLSCAN)
623 ? RADEON_CRTC_DBL_SCAN_EN
624 : 0)
625 | ((mode->flags & DRM_MODE_FLAG_CSYNC)
626 ? RADEON_CRTC_CSYNC_EN
627 : 0)
628 | ((mode->flags & DRM_MODE_FLAG_INTERLACE)
629 ? RADEON_CRTC_INTERLACE_EN
630 : 0));
631
632 crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL);
633 crtc_ext_cntl |= (RADEON_XCRT_CNT_EN |
634 RADEON_CRTC_VSYNC_DIS |
635 RADEON_CRTC_HSYNC_DIS |
636 RADEON_CRTC_DISPLAY_DIS);
637
638 disp_merge_cntl = RREG32(RADEON_DISP_MERGE_CNTL);
639 disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
640
641 WREG32(RADEON_DISP_MERGE_CNTL, disp_merge_cntl);
642 WREG32(RADEON_CRTC_GEN_CNTL, crtc_gen_cntl);
643 WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
644 }
645
646 WREG32(RADEON_CRTC_H_TOTAL_DISP + radeon_crtc->crtc_offset, crtc_h_total_disp);
647 WREG32(RADEON_CRTC_H_SYNC_STRT_WID + radeon_crtc->crtc_offset, crtc_h_sync_strt_wid);
648 WREG32(RADEON_CRTC_V_TOTAL_DISP + radeon_crtc->crtc_offset, crtc_v_total_disp);
649 WREG32(RADEON_CRTC_V_SYNC_STRT_WID + radeon_crtc->crtc_offset, crtc_v_sync_strt_wid);
650
651 return true;
652}
653
654static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
655{
656 struct drm_device *dev = crtc->dev;
657 struct radeon_device *rdev = dev->dev_private;
658 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
659 struct drm_encoder *encoder;
660 uint32_t feedback_div = 0;
661 uint32_t frac_fb_div = 0;
662 uint32_t reference_div = 0;
663 uint32_t post_divider = 0;
664 uint32_t freq = 0;
665 uint8_t pll_gain;
666 int pll_flags = RADEON_PLL_LEGACY;
667 bool use_bios_divs = false;
668 /* PLL registers */
669 uint32_t pll_ref_div = 0;
670 uint32_t pll_fb_post_div = 0;
671 uint32_t htotal_cntl = 0;
672
673 struct radeon_pll *pll;
674
675 struct {
676 int divider;
677 int bitvalue;
678 } *post_div, post_divs[] = {
679 /* From RAGE 128 VR/RAGE 128 GL Register
680 * Reference Manual (Technical Reference
681 * Manual P/N RRG-G04100-C Rev. 0.04), page
682 * 3-17 (PLL_DIV_[3:0]).
683 */
684 { 1, 0 }, /* VCLK_SRC */
685 { 2, 1 }, /* VCLK_SRC/2 */
686 { 4, 2 }, /* VCLK_SRC/4 */
687 { 8, 3 }, /* VCLK_SRC/8 */
688 { 3, 4 }, /* VCLK_SRC/3 */
689 { 16, 5 }, /* VCLK_SRC/16 */
690 { 6, 6 }, /* VCLK_SRC/6 */
691 { 12, 7 }, /* VCLK_SRC/12 */
692 { 0, 0 }
693 };
694
695 if (radeon_crtc->crtc_id)
696 pll = &rdev->clock.p2pll;
697 else
698 pll = &rdev->clock.p1pll;
699
700 if (mode->clock > 200000) /* range limits??? */
701 pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
702 else
703 pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
704
705 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
706 if (encoder->crtc == crtc) {
707 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
708 pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
709 if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
710 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
711 struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv;
712 if (lvds) {
713 if (lvds->use_bios_dividers) {
714 pll_ref_div = lvds->panel_ref_divider;
715 pll_fb_post_div = (lvds->panel_fb_divider |
716 (lvds->panel_post_divider << 16));
717 htotal_cntl = 0;
718 use_bios_divs = true;
719 }
720 }
721 pll_flags |= RADEON_PLL_USE_REF_DIV;
722 }
723 }
724 }
725
726 DRM_DEBUG("\n");
727
728 if (!use_bios_divs) {
729 radeon_compute_pll(pll, mode->clock,
730 &freq, &feedback_div, &frac_fb_div,
731 &reference_div, &post_divider,
732 pll_flags);
733
734 for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
735 if (post_div->divider == post_divider)
736 break;
737 }
738
739 if (!post_div->divider)
740 post_div = &post_divs[0];
741
742 DRM_DEBUG("dc=%u, fd=%d, rd=%d, pd=%d\n",
743 (unsigned)freq,
744 feedback_div,
745 reference_div,
746 post_divider);
747
748 pll_ref_div = reference_div;
749#if defined(__powerpc__) && (0) /* TODO */
750 /* apparently programming this otherwise causes a hang??? */
751 if (info->MacModel == RADEON_MAC_IBOOK)
752 pll_fb_post_div = 0x000600ad;
753 else
754#endif
755 pll_fb_post_div = (feedback_div | (post_div->bitvalue << 16));
756
757 htotal_cntl = mode->htotal & 0x7;
758
759 }
760
761 pll_gain = radeon_compute_pll_gain(pll->reference_freq,
762 pll_ref_div & 0x3ff,
763 pll_fb_post_div & 0x7ff);
764
765 if (radeon_crtc->crtc_id) {
766 uint32_t pixclks_cntl = ((RREG32_PLL(RADEON_PIXCLKS_CNTL) &
767 ~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
768 RADEON_PIX2CLK_SRC_SEL_P2PLLCLK);
769
770 WREG32_PLL_P(RADEON_PIXCLKS_CNTL,
771 RADEON_PIX2CLK_SRC_SEL_CPUCLK,
772 ~(RADEON_PIX2CLK_SRC_SEL_MASK));
773
774 WREG32_PLL_P(RADEON_P2PLL_CNTL,
775 RADEON_P2PLL_RESET
776 | RADEON_P2PLL_ATOMIC_UPDATE_EN
777 | ((uint32_t)pll_gain << RADEON_P2PLL_PVG_SHIFT),
778 ~(RADEON_P2PLL_RESET
779 | RADEON_P2PLL_ATOMIC_UPDATE_EN
780 | RADEON_P2PLL_PVG_MASK));
781
782 WREG32_PLL_P(RADEON_P2PLL_REF_DIV,
783 pll_ref_div,
784 ~RADEON_P2PLL_REF_DIV_MASK);
785
786 WREG32_PLL_P(RADEON_P2PLL_DIV_0,
787 pll_fb_post_div,
788 ~RADEON_P2PLL_FB0_DIV_MASK);
789
790 WREG32_PLL_P(RADEON_P2PLL_DIV_0,
791 pll_fb_post_div,
792 ~RADEON_P2PLL_POST0_DIV_MASK);
793
794 radeon_pll2_write_update(dev);
795 radeon_pll2_wait_for_read_update_complete(dev);
796
797 WREG32_PLL(RADEON_HTOTAL2_CNTL, htotal_cntl);
798
799 WREG32_PLL_P(RADEON_P2PLL_CNTL,
800 0,
801 ~(RADEON_P2PLL_RESET
802 | RADEON_P2PLL_SLEEP
803 | RADEON_P2PLL_ATOMIC_UPDATE_EN));
804
805 DRM_DEBUG("Wrote2: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
806 (unsigned)pll_ref_div,
807 (unsigned)pll_fb_post_div,
808 (unsigned)htotal_cntl,
809 RREG32_PLL(RADEON_P2PLL_CNTL));
810 DRM_DEBUG("Wrote2: rd=%u, fd=%u, pd=%u\n",
811 (unsigned)pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
812 (unsigned)pll_fb_post_div & RADEON_P2PLL_FB0_DIV_MASK,
813 (unsigned)((pll_fb_post_div &
814 RADEON_P2PLL_POST0_DIV_MASK) >> 16));
815
816 mdelay(50); /* Let the clock to lock */
817
818 WREG32_PLL_P(RADEON_PIXCLKS_CNTL,
819 RADEON_PIX2CLK_SRC_SEL_P2PLLCLK,
820 ~(RADEON_PIX2CLK_SRC_SEL_MASK));
821
822 WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
823 } else {
824 if (rdev->flags & RADEON_IS_MOBILITY) {
825 /* A temporal workaround for the occational blanking on certain laptop panels.
826 This appears to related to the PLL divider registers (fail to lock?).
827 It occurs even when all dividers are the same with their old settings.
828 In this case we really don't need to fiddle with PLL registers.
829 By doing this we can avoid the blanking problem with some panels.
830 */
831 if ((pll_ref_div == (RREG32_PLL(RADEON_PPLL_REF_DIV) & RADEON_PPLL_REF_DIV_MASK)) &&
832 (pll_fb_post_div == (RREG32_PLL(RADEON_PPLL_DIV_3) &
833 (RADEON_PPLL_POST3_DIV_MASK | RADEON_PPLL_FB3_DIV_MASK)))) {
834 WREG32_P(RADEON_CLOCK_CNTL_INDEX,
835 RADEON_PLL_DIV_SEL,
836 ~(RADEON_PLL_DIV_SEL));
837 r100_pll_errata_after_index(rdev);
838 return;
839 }
840 }
841
842 WREG32_PLL_P(RADEON_VCLK_ECP_CNTL,
843 RADEON_VCLK_SRC_SEL_CPUCLK,
844 ~(RADEON_VCLK_SRC_SEL_MASK));
845 WREG32_PLL_P(RADEON_PPLL_CNTL,
846 RADEON_PPLL_RESET
847 | RADEON_PPLL_ATOMIC_UPDATE_EN
848 | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
849 | ((uint32_t)pll_gain << RADEON_PPLL_PVG_SHIFT),
850 ~(RADEON_PPLL_RESET
851 | RADEON_PPLL_ATOMIC_UPDATE_EN
852 | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
853 | RADEON_PPLL_PVG_MASK));
854
855 WREG32_P(RADEON_CLOCK_CNTL_INDEX,
856 RADEON_PLL_DIV_SEL,
857 ~(RADEON_PLL_DIV_SEL));
858 r100_pll_errata_after_index(rdev);
859
860 if (ASIC_IS_R300(rdev) ||
861 (rdev->family == CHIP_RS300) ||
862 (rdev->family == CHIP_RS400) ||
863 (rdev->family == CHIP_RS480)) {
864 if (pll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
865 /* When restoring console mode, use saved PPLL_REF_DIV
866 * setting.
867 */
868 WREG32_PLL_P(RADEON_PPLL_REF_DIV,
869 pll_ref_div,
870 0);
871 } else {
872 /* R300 uses ref_div_acc field as real ref divider */
873 WREG32_PLL_P(RADEON_PPLL_REF_DIV,
874 (pll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT),
875 ~R300_PPLL_REF_DIV_ACC_MASK);
876 }
877 } else
878 WREG32_PLL_P(RADEON_PPLL_REF_DIV,
879 pll_ref_div,
880 ~RADEON_PPLL_REF_DIV_MASK);
881
882 WREG32_PLL_P(RADEON_PPLL_DIV_3,
883 pll_fb_post_div,
884 ~RADEON_PPLL_FB3_DIV_MASK);
885
886 WREG32_PLL_P(RADEON_PPLL_DIV_3,
887 pll_fb_post_div,
888 ~RADEON_PPLL_POST3_DIV_MASK);
889
890 radeon_pll_write_update(dev);
891 radeon_pll_wait_for_read_update_complete(dev);
892
893 WREG32_PLL(RADEON_HTOTAL_CNTL, htotal_cntl);
894
895 WREG32_PLL_P(RADEON_PPLL_CNTL,
896 0,
897 ~(RADEON_PPLL_RESET
898 | RADEON_PPLL_SLEEP
899 | RADEON_PPLL_ATOMIC_UPDATE_EN
900 | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN));
901
902 DRM_DEBUG("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
903 pll_ref_div,
904 pll_fb_post_div,
905 (unsigned)htotal_cntl,
906 RREG32_PLL(RADEON_PPLL_CNTL));
907 DRM_DEBUG("Wrote: rd=%d, fd=%d, pd=%d\n",
908 pll_ref_div & RADEON_PPLL_REF_DIV_MASK,
909 pll_fb_post_div & RADEON_PPLL_FB3_DIV_MASK,
910 (pll_fb_post_div & RADEON_PPLL_POST3_DIV_MASK) >> 16);
911
912 mdelay(50); /* Let the clock to lock */
913
914 WREG32_PLL_P(RADEON_VCLK_ECP_CNTL,
915 RADEON_VCLK_SRC_SEL_PPLLCLK,
916 ~(RADEON_VCLK_SRC_SEL_MASK));
917
918 }
919}
920
921static bool radeon_crtc_mode_fixup(struct drm_crtc *crtc,
922 struct drm_display_mode *mode,
923 struct drm_display_mode *adjusted_mode)
924{
Jerome Glissec93bb852009-07-13 21:04:08 +0200925 if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))
926 return false;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200927 return true;
928}
929
930static int radeon_crtc_mode_set(struct drm_crtc *crtc,
931 struct drm_display_mode *mode,
932 struct drm_display_mode *adjusted_mode,
933 int x, int y, struct drm_framebuffer *old_fb)
934{
Jerome Glissec93bb852009-07-13 21:04:08 +0200935 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
936 struct drm_device *dev = crtc->dev;
937 struct radeon_device *rdev = dev->dev_private;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200938
939 /* TODO TV */
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200940 radeon_crtc_set_base(crtc, x, y, old_fb);
941 radeon_set_crtc_timing(crtc, adjusted_mode);
942 radeon_set_pll(crtc, adjusted_mode);
Jerome Glissec93bb852009-07-13 21:04:08 +0200943 radeon_bandwidth_update(rdev);
944 if (radeon_crtc->crtc_id == 0) {
945 radeon_legacy_rmx_mode_set(crtc, mode, adjusted_mode);
946 } else {
947 if (radeon_crtc->rmx_type != RMX_OFF) {
948 /* FIXME: only first crtc has rmx what should we
949 * do ?
950 */
951 DRM_ERROR("Mode need scaling but only first crtc can do that.\n");
952 }
953 }
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200954 return 0;
955}
956
957static void radeon_crtc_prepare(struct drm_crtc *crtc)
958{
959 radeon_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
960}
961
962static void radeon_crtc_commit(struct drm_crtc *crtc)
963{
964 radeon_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
965}
966
967static const struct drm_crtc_helper_funcs legacy_helper_funcs = {
968 .dpms = radeon_crtc_dpms,
969 .mode_fixup = radeon_crtc_mode_fixup,
970 .mode_set = radeon_crtc_mode_set,
971 .mode_set_base = radeon_crtc_set_base,
972 .prepare = radeon_crtc_prepare,
973 .commit = radeon_crtc_commit,
974};
975
976
977void radeon_legacy_init_crtc(struct drm_device *dev,
978 struct radeon_crtc *radeon_crtc)
979{
980 if (radeon_crtc->crtc_id == 1)
981 radeon_crtc->crtc_offset = RADEON_CRTC2_H_TOTAL_DISP - RADEON_CRTC_H_TOTAL_DISP;
982 drm_crtc_helper_add(&radeon_crtc->base, &legacy_helper_funcs);
983}