Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6
[pandora-kernel.git] / drivers / gpu / drm / radeon / radeon_legacy_crtc.c
1 /*
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
32 static 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
197 void radeon_restore_common_regs(struct drm_device *dev)
198 {
199         /* don't need this yet */
200 }
201
202 static 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
217 static 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
228 static 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
244 static 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
255 static 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
286 void 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 */
333 void 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
392 int 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;
403         uint32_t tiling_flags;
404
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         }
413         /* 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
419         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
427         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) {
433                 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
448         if (tiling_flags & RADEON_TILING_MACRO) {
449                 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;
454                         int tile_addr = (((y >> 3) * pitch_pixels +  x) >> (8 - byteshift)) << 11;
455                         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
479         crtc_offset = (u32)base;
480
481         WREG32(RADEON_DISPLAY_BASE_ADDR + radeon_crtc->crtc_offset, radeon_crtc->legacy_display_base_addr);
482
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
500 static 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
654 static 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
921 static bool radeon_crtc_mode_fixup(struct drm_crtc *crtc,
922                                    struct drm_display_mode *mode,
923                                    struct drm_display_mode *adjusted_mode)
924 {
925         if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))
926                 return false;
927         return true;
928 }
929
930 static 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 {
935         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
936         struct drm_device *dev = crtc->dev;
937         struct radeon_device *rdev = dev->dev_private;
938
939         /* TODO TV */
940         radeon_crtc_set_base(crtc, x, y, old_fb);
941         radeon_set_crtc_timing(crtc, adjusted_mode);
942         radeon_set_pll(crtc, adjusted_mode);
943         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         }
954         return 0;
955 }
956
957 static void radeon_crtc_prepare(struct drm_crtc *crtc)
958 {
959         radeon_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
960 }
961
962 static void radeon_crtc_commit(struct drm_crtc *crtc)
963 {
964         radeon_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
965 }
966
967 static 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
977 void 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 }