Brute force port of legacy crtc/encoder code
[platform/upstream/libdrm.git] / linux-core / radeon_legacy_encoders.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 "drmP.h"
27 #include "drm_crtc_helper.h"
28 #include "radeon_drm.h"
29 #include "radeon_drv.h"
30
31
32 static void radeon_legacy_rmx_mode_set(struct drm_encoder *encoder,
33                                        struct drm_display_mode *mode,
34                                        struct drm_display_mode *adjusted_mode)
35 {
36         struct drm_device *dev = encoder->dev;
37         struct drm_radeon_private *dev_priv = dev->dev_private;
38         struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
39         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
40         int    xres = mode->hdisplay;
41         int    yres = mode->vdisplay;
42         bool   hscale = true, vscale = true;
43         int    hsync_wid;
44         int    vsync_wid;
45         int    hsync_start;
46         uint32_t scale, inc;
47         uint32_t fp_horz_stretch, fp_vert_stretch, crtc_more_cntl, fp_horz_vert_active;
48         uint32_t fp_h_sync_strt_wid, fp_v_sync_strt_wid, fp_crtc_h_total_disp, fp_crtc_v_total_disp;
49
50
51         fp_vert_stretch = RADEON_READ(RADEON_FP_VERT_STRETCH) &
52                 (RADEON_VERT_STRETCH_RESERVED |
53                  RADEON_VERT_AUTO_RATIO_INC);
54         fp_horz_stretch = RADEON_READ(RADEON_FP_HORZ_STRETCH) &
55                 (RADEON_HORZ_FP_LOOP_STRETCH |
56                  RADEON_HORZ_AUTO_RATIO_INC);
57
58         crtc_more_cntl = 0;
59         if ((dev_priv->chip_family == CHIP_RS100) ||
60             (dev_priv->chip_family == CHIP_RS200)) {
61                 /* This is to workaround the asic bug for RMX, some versions
62                    of BIOS dosen't have this register initialized correctly. */
63                 crtc_more_cntl |= RADEON_CRTC_H_CUTOFF_ACTIVE_EN;
64         }
65
66
67         fp_crtc_h_total_disp = ((((mode->crtc_htotal / 8) - 1) & 0x3ff)
68                                 | ((((mode->crtc_hdisplay / 8) - 1) & 0x1ff) << 16));
69
70         hsync_wid = (mode->crtc_hsync_end - mode->crtc_hsync_start) / 8;
71         if (!hsync_wid)
72                 hsync_wid = 1;
73         hsync_start = mode->crtc_hsync_start - 8;
74
75         fp_h_sync_strt_wid = ((hsync_start & 0x1fff)
76                               | ((hsync_wid & 0x3f) << 16)
77                               | ((mode->flags & DRM_MODE_FLAG_NHSYNC)
78                                  ? RADEON_CRTC_H_SYNC_POL
79                                  : 0));
80
81         fp_crtc_v_total_disp = (((mode->crtc_vtotal - 1) & 0xffff)
82                                 | ((mode->crtc_vdisplay - 1) << 16));
83
84         vsync_wid = mode->crtc_vsync_end - mode->crtc_vsync_start;
85         if (!vsync_wid)
86                 vsync_wid = 1;
87
88         fp_v_sync_strt_wid = (((mode->crtc_vsync_start - 1) & 0xfff)
89                               | ((vsync_wid & 0x1f) << 16)
90                               | ((mode->flags & DRM_MODE_FLAG_NVSYNC)
91                                  ? RADEON_CRTC_V_SYNC_POL
92                                  : 0));
93
94         fp_horz_vert_active = 0;
95
96         if (radeon_encoder->panel_xres == 0 ||
97             radeon_encoder->panel_yres == 0) {
98                 hscale = false;
99                 vscale = false;
100         } else {
101                 if (xres > radeon_encoder->panel_xres)
102                         xres = radeon_encoder->panel_xres;
103                 if (yres > radeon_encoder->panel_yres)
104                         yres = radeon_encoder->panel_yres;
105
106                 if (xres == radeon_encoder->panel_xres)
107                         hscale = false;
108                 if (yres == radeon_encoder->panel_yres)
109                         vscale = false;
110         }
111
112         if (radeon_encoder->flags & RADEON_USE_RMX) {
113                 if (radeon_encoder->rmx_type != RMX_CENTER) {
114                         if (!hscale)
115                                 fp_horz_stretch |= ((xres/8-1) << 16);
116                         else {
117                                 inc = (fp_horz_stretch & RADEON_HORZ_AUTO_RATIO_INC) ? 1 : 0;
118                                 scale = ((xres + inc) * RADEON_HORZ_STRETCH_RATIO_MAX)
119                                         / radeon_encoder->panel_xres + 1;
120                                 fp_horz_stretch |= (((scale) & RADEON_HORZ_STRETCH_RATIO_MASK) |
121                                                     RADEON_HORZ_STRETCH_BLEND |
122                                                     RADEON_HORZ_STRETCH_ENABLE |
123                                                     ((radeon_encoder->panel_xres/8-1) << 16));
124                         }
125
126                         if (!vscale)
127                                 fp_vert_stretch |= ((yres-1) << 12);
128                         else {
129                                 inc = (fp_vert_stretch & RADEON_VERT_AUTO_RATIO_INC) ? 1 : 0;
130                                 scale = ((yres + inc) * RADEON_VERT_STRETCH_RATIO_MAX)
131                                         / radeon_encoder->panel_yres + 1;
132                                 fp_vert_stretch |= (((scale) & RADEON_VERT_STRETCH_RATIO_MASK) |
133                                                     RADEON_VERT_STRETCH_ENABLE |
134                                                     RADEON_VERT_STRETCH_BLEND |
135                                                     ((radeon_encoder->panel_yres-1) << 12));
136                         }
137                 } else if (radeon_encoder->rmx_type == RMX_CENTER) {
138                         int    blank_width;
139
140                         fp_horz_stretch |= ((xres/8-1) << 16);
141                         fp_vert_stretch |= ((yres-1) << 12);
142
143                         crtc_more_cntl |= (RADEON_CRTC_AUTO_HORZ_CENTER_EN |
144                                            RADEON_CRTC_AUTO_VERT_CENTER_EN);
145
146                         blank_width = (mode->crtc_hblank_end - mode->crtc_hblank_start) / 8;
147                         if (blank_width > 110)
148                                 blank_width = 110;
149
150                         fp_crtc_h_total_disp = (((blank_width) & 0x3ff)
151                                                 | ((((mode->crtc_hdisplay / 8) - 1) & 0x1ff) << 16));
152
153                         hsync_wid = (mode->crtc_hsync_end - mode->crtc_hsync_start) / 8;
154                         if (!hsync_wid)
155                                 hsync_wid = 1;
156
157                         fp_h_sync_strt_wid = ((((mode->crtc_hsync_start - mode->crtc_hblank_start) / 8) & 0x1fff)
158                                               | ((hsync_wid & 0x3f) << 16)
159                                               | ((mode->flags & DRM_MODE_FLAG_NHSYNC)
160                                                  ? RADEON_CRTC_H_SYNC_POL
161                                                  : 0));
162
163                         fp_crtc_v_total_disp = (((mode->crtc_vblank_end - mode->crtc_vblank_start) & 0xffff)
164                                                 | ((mode->crtc_vdisplay - 1) << 16));
165
166                         vsync_wid = mode->crtc_vsync_end - mode->crtc_vsync_start;
167                         if (!vsync_wid)
168                                 vsync_wid = 1;
169
170                         fp_v_sync_strt_wid = ((((mode->crtc_vsync_start - mode->crtc_vblank_start) & 0xfff)
171                                                | ((vsync_wid & 0x1f) << 16)
172                                                | ((mode->flags & DRM_MODE_FLAG_NVSYNC)
173                                                   ? RADEON_CRTC_V_SYNC_POL
174                                                   : 0)));
175
176                         fp_horz_vert_active = (((radeon_encoder->panel_yres) & 0xfff) |
177                                                (((radeon_encoder->panel_xres / 8) & 0x1ff) << 16));
178                 }
179         } else {
180                 fp_horz_stretch |= ((xres/8-1) << 16);
181                 fp_vert_stretch |= ((yres-1) << 12);
182         }
183
184         RADEON_WRITE(RADEON_FP_HORZ_STRETCH,      fp_horz_stretch);
185         RADEON_WRITE(RADEON_FP_VERT_STRETCH,      fp_vert_stretch);
186         RADEON_WRITE(RADEON_CRTC_MORE_CNTL,       crtc_more_cntl);
187         RADEON_WRITE(RADEON_FP_HORZ_VERT_ACTIVE,  fp_horz_vert_active);
188         RADEON_WRITE(RADEON_FP_H_SYNC_STRT_WID,   fp_h_sync_strt_wid);
189         RADEON_WRITE(RADEON_FP_V_SYNC_STRT_WID,   fp_v_sync_strt_wid);
190         RADEON_WRITE(RADEON_FP_CRTC_H_TOTAL_DISP, fp_crtc_h_total_disp);
191         RADEON_WRITE(RADEON_FP_CRTC_V_TOTAL_DISP, fp_crtc_v_total_disp);
192
193 }
194
195 static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode)
196 {
197         struct drm_device *dev = encoder->dev;
198         struct drm_radeon_private *dev_priv = dev->dev_private;
199         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
200         uint32_t lvds_gen_cntl, lvds_pll_cntl, pixclks_cntl, disp_pwr_man;
201
202         switch(mode) {
203         case DRM_MODE_DPMS_ON:
204                 disp_pwr_man = RADEON_READ(RADEON_DISP_PWR_MAN);
205                 disp_pwr_man |= RADEON_AUTO_PWRUP_EN;
206                 RADEON_WRITE(RADEON_DISP_PWR_MAN, disp_pwr_man);
207                 lvds_pll_cntl |= RADEON_LVDS_PLL_EN;
208                 RADEON_WRITE(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl);
209                 udelay(1000);
210                 lvds_pll_cntl = RADEON_READ(RADEON_LVDS_PLL_CNTL);
211                 lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET;
212                 RADEON_WRITE(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl);
213                 lvds_gen_cntl = RADEON_READ(RADEON_LVDS_GEN_CNTL);
214                 lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
215                 lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
216                 udelay(radeon_encoder->panel_pwr_delay * 1000);
217                 RADEON_WRITE(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
218                 break;
219         case DRM_MODE_DPMS_STANDBY:
220         case DRM_MODE_DPMS_SUSPEND:
221         case DRM_MODE_DPMS_OFF:
222                 pixclks_cntl = RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL);
223                 RADEON_WRITE_PLL_P(dev_priv, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
224                 lvds_gen_cntl = RADEON_READ(RADEON_LVDS_GEN_CNTL);
225                 lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
226                 lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
227                 RADEON_WRITE(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
228                 RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, pixclks_cntl);
229                 break;
230         }
231 }
232
233 static void radeon_legacy_lvds_prepare(struct drm_encoder *encoder)
234 {
235         radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF);
236 }
237
238 static void radeon_legacy_lvds_commit(struct drm_encoder *encoder)
239 {
240         radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_ON);
241 }
242
243 static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder,
244                                         struct drm_display_mode *mode,
245                                         struct drm_display_mode *adjusted_mode)
246 {
247         struct drm_device *dev = encoder->dev;
248         struct drm_radeon_private *dev_priv = dev->dev_private;
249         struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
250         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
251         uint32_t lvds_pll_cntl, lvds_gen_cntl;
252
253         if (radeon_crtc->crtc_id == 0)
254                 radeon_legacy_rmx_mode_set(encoder, mode, adjusted_mode);
255
256         lvds_pll_cntl = RADEON_READ(RADEON_LVDS_PLL_CNTL);
257         lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN;
258         lvds_gen_cntl = RADEON_READ(RADEON_LVDS_GEN_CNTL);
259         lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
260         lvds_gen_cntl &= ~(RADEON_LVDS_ON |
261                            RADEON_LVDS_BLON |
262                            RADEON_LVDS_EN |
263                            RADEON_LVDS_RST_FM);
264
265         if (radeon_is_r300(dev_priv))
266                 lvds_pll_cntl &= ~(R300_LVDS_SRC_SEL_MASK);
267
268         if (radeon_crtc->crtc_id == 0) {
269                 if (radeon_is_r300(dev_priv)) {
270                         if (radeon_encoder->flags & RADEON_USE_RMX)
271                                 lvds_pll_cntl |= R300_LVDS_SRC_SEL_RMX;
272                 } else
273                         lvds_gen_cntl &= ~RADEON_LVDS_SEL_CRTC2;
274         } else {
275                 if (radeon_is_r300(dev_priv)) {
276                         lvds_pll_cntl |= R300_LVDS_SRC_SEL_CRTC2;
277                 } else
278                         lvds_gen_cntl |= RADEON_LVDS_SEL_CRTC2;
279         }
280
281         RADEON_WRITE(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
282         RADEON_WRITE(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl);
283
284         if (dev_priv->chip_family == CHIP_RV410)
285                 RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, 0);
286 }
287
288 static bool radeon_legacy_lvds_mode_fixup(struct drm_encoder *encoder,
289                                           struct drm_display_mode *mode,
290                                           struct drm_display_mode *adjusted_mode)
291 {
292         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
293
294         radeon_encoder->flags &= ~RADEON_USE_RMX;
295
296         if (radeon_encoder->rmx_type != RMX_OFF)
297                 radeon_rmx_mode_fixup(encoder, mode, adjusted_mode);
298
299         return true;
300 }
301
302 static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = {
303         .dpms = radeon_legacy_lvds_dpms,
304         .mode_fixup = radeon_legacy_lvds_mode_fixup,
305         .prepare = radeon_legacy_lvds_prepare,
306         .mode_set = radeon_legacy_lvds_mode_set,
307         .commit = radeon_legacy_lvds_commit,
308 };
309
310
311 static const struct drm_encoder_funcs radeon_legacy_lvds_enc_funcs = {
312         .destroy = radeon_enc_destroy,
313 };
314
315
316 struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index)
317 {
318         struct drm_radeon_private *dev_priv = dev->dev_private;
319         struct radeon_mode_info *mode_info = &dev_priv->mode_info;
320         struct radeon_encoder *radeon_encoder;
321         struct drm_encoder *encoder;
322         radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL);
323         if (!radeon_encoder) {
324                 return NULL;
325         }
326
327         encoder = &radeon_encoder->base;
328
329         encoder->possible_crtcs = 0x3;
330         encoder->possible_clones = 0;
331         drm_encoder_init(dev, encoder, &radeon_legacy_lvds_enc_funcs,
332                          DRM_MODE_ENCODER_LVDS);
333
334         drm_encoder_helper_add(encoder, &radeon_legacy_lvds_helper_funcs);
335
336         /* TODO get the LVDS info from the BIOS for panel size etc. */
337         /* get the lvds info from the bios */
338         radeon_combios_get_lvds_info(radeon_encoder);
339
340         /* LVDS gets default RMX full scaling */
341         radeon_encoder->rmx_type = RMX_FULL;
342
343         return encoder;
344 }
345
346 static bool radeon_legacy_primary_dac_mode_fixup(struct drm_encoder *encoder,
347                                                  struct drm_display_mode *mode,
348                                                  struct drm_display_mode *adjusted_mode)
349 {
350         return true;
351 }
352
353 static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode)
354 {
355         struct drm_device *dev = encoder->dev;
356         struct drm_radeon_private *dev_priv = dev->dev_private;
357         uint32_t crtc_ext_cntl = RADEON_READ(RADEON_CRTC_EXT_CNTL);
358         uint32_t dac_cntl = RADEON_READ(RADEON_DAC_CNTL);
359         uint32_t dac_macro_cntl = RADEON_READ(RADEON_DAC_MACRO_CNTL);
360
361         switch(mode) {
362         case DRM_MODE_DPMS_ON:
363                 crtc_ext_cntl |= RADEON_CRTC_CRT_ON;
364                 dac_cntl &= ~RADEON_DAC_PDWN;
365                 dac_macro_cntl &= ~(RADEON_DAC_PDWN_R |
366                                     RADEON_DAC_PDWN_G |
367                                     RADEON_DAC_PDWN_B);
368                 break;
369         case DRM_MODE_DPMS_STANDBY:
370         case DRM_MODE_DPMS_SUSPEND:
371         case DRM_MODE_DPMS_OFF:
372                 crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON;
373                 dac_cntl |= RADEON_DAC_PDWN;
374                 dac_macro_cntl |= (RADEON_DAC_PDWN_R |
375                                    RADEON_DAC_PDWN_G |
376                                    RADEON_DAC_PDWN_B);
377                 break;
378         }
379
380         RADEON_WRITE(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
381         RADEON_WRITE(RADEON_DAC_CNTL, dac_cntl);
382         RADEON_WRITE(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
383
384 }
385
386 static void radeon_legacy_primary_dac_prepare(struct drm_encoder *encoder)
387 {
388         radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF);
389 }
390
391 static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder)
392 {
393         radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_ON);
394 }
395
396 static void radeon_legacy_primary_dac_mode_set(struct drm_encoder *encoder,
397                                                struct drm_display_mode *mode,
398                                                struct drm_display_mode *adjusted_mode)
399 {
400         struct drm_device *dev = encoder->dev;
401         struct drm_radeon_private *dev_priv = dev->dev_private;
402         struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
403         uint32_t disp_output_cntl, dac_cntl, dac2_cntl, dac_macro_cntl;
404
405         if (radeon_crtc->crtc_id == 0)
406                 radeon_legacy_rmx_mode_set(encoder, mode, adjusted_mode);
407
408         if (radeon_crtc->crtc_id == 0) {
409                 if (dev_priv->chip_family == CHIP_R200 || radeon_is_r300(dev_priv)) {
410                         disp_output_cntl = RADEON_READ(RADEON_DISP_OUTPUT_CNTL) &
411                                 ~(RADEON_DISP_DAC_SOURCE_MASK);
412                         RADEON_WRITE(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
413                 } else {
414                         dac2_cntl = RADEON_READ(RADEON_DAC_CNTL2)  & ~(RADEON_DAC2_DAC_CLK_SEL);
415                         RADEON_WRITE(RADEON_DAC_CNTL2, dac2_cntl);
416                 }
417         } else {
418                 if (dev_priv->chip_family == CHIP_R200 || radeon_is_r300(dev_priv)) {
419                         disp_output_cntl = RADEON_READ(RADEON_DISP_OUTPUT_CNTL) &
420                                 ~(RADEON_DISP_DAC_SOURCE_MASK);
421                         disp_output_cntl |= RADEON_DISP_DAC_SOURCE_CRTC2;
422                         RADEON_WRITE(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
423                 } else {
424                         dac2_cntl = RADEON_READ(RADEON_DAC_CNTL2) | RADEON_DAC2_DAC_CLK_SEL;
425                         RADEON_WRITE(RADEON_DAC_CNTL2, dac2_cntl);
426                 }
427         }
428
429         dac_cntl = (RADEON_DAC_MASK_ALL |
430                     RADEON_DAC_VGA_ADR_EN |
431                     /* TODO 6-bits */
432                     RADEON_DAC_8BIT_EN);
433
434         RADEON_WRITE_P(RADEON_DAC_CNTL,
435                        dac_cntl,
436                        RADEON_DAC_RANGE_CNTL |
437                        RADEON_DAC_BLANKING);
438
439         dac_macro_cntl = RADEON_READ(RADEON_DAC_MACRO_CNTL);
440         RADEON_WRITE(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
441 }
442
443 static const struct drm_encoder_helper_funcs radeon_legacy_primary_dac_helper_funcs = {
444         .dpms = radeon_legacy_primary_dac_dpms,
445         .mode_fixup = radeon_legacy_primary_dac_mode_fixup,
446         .prepare = radeon_legacy_primary_dac_prepare,
447         .mode_set = radeon_legacy_primary_dac_mode_set,
448         .commit = radeon_legacy_primary_dac_commit,
449 };
450
451
452 static const struct drm_encoder_funcs radeon_legacy_primary_dac_enc_funcs = {
453         .destroy = radeon_enc_destroy,
454 };
455
456 struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev, int bios_index, int has_tv)
457 {
458         struct drm_radeon_private *dev_priv = dev->dev_private;
459         struct radeon_mode_info *mode_info = &dev_priv->mode_info;
460         struct radeon_encoder *radeon_encoder;
461         struct drm_encoder *encoder;
462         radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL);
463         if (!radeon_encoder) {
464                 return NULL;
465         }
466
467         encoder = &radeon_encoder->base;
468
469         encoder->possible_crtcs = 0x3;
470         encoder->possible_clones = 0;
471         drm_encoder_init(dev, encoder, &radeon_legacy_primary_dac_enc_funcs,
472                          DRM_MODE_ENCODER_DAC);
473
474         drm_encoder_helper_add(encoder, &radeon_legacy_primary_dac_helper_funcs);
475
476         /* TODO get the primary dac vals from bios tables */
477         //radeon_combios_get_lvds_info(radeon_encoder);
478
479         return encoder;
480 }
481
482
483 static bool radeon_legacy_tmds_int_mode_fixup(struct drm_encoder *encoder,
484                                                  struct drm_display_mode *mode,
485                                                  struct drm_display_mode *adjusted_mode)
486 {
487         return true;
488 }
489
490 static void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode)
491 {
492         struct drm_device *dev = encoder->dev;
493         struct drm_radeon_private *dev_priv = dev->dev_private;
494         uint32_t fp_gen_cntl = RADEON_READ(RADEON_FP_GEN_CNTL);
495
496         switch(mode) {
497         case DRM_MODE_DPMS_ON:
498                 fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
499                 break;
500         case DRM_MODE_DPMS_STANDBY:
501         case DRM_MODE_DPMS_SUSPEND:
502         case DRM_MODE_DPMS_OFF:
503                 fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
504                 break;
505         }
506
507         RADEON_WRITE(RADEON_FP_GEN_CNTL, fp_gen_cntl);
508 }
509
510 static void radeon_legacy_tmds_int_prepare(struct drm_encoder *encoder)
511 {
512         radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF);
513 }
514
515 static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder)
516 {
517         radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_ON);
518 }
519
520 static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder,
521                                             struct drm_display_mode *mode,
522                                             struct drm_display_mode *adjusted_mode)
523 {
524         struct drm_device *dev = encoder->dev;
525         struct drm_radeon_private *dev_priv = dev->dev_private;
526         struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
527         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
528         uint32_t tmp, tmds_pll_cntl, tmds_transmitter_cntl, fp_gen_cntl;
529         int i;
530
531         if (radeon_crtc->crtc_id == 0)
532                 radeon_legacy_rmx_mode_set(encoder, mode, adjusted_mode);
533
534         tmp = tmds_pll_cntl = RADEON_READ(RADEON_TMDS_PLL_CNTL);
535         tmp &= 0xfffff;
536         if (dev_priv->chip_family == CHIP_RV280) {
537                 /* bit 22 of TMDS_PLL_CNTL is read-back inverted */
538                 tmp ^= (1 << 22);
539                 tmds_pll_cntl ^= (1 << 22);
540         }
541
542         for (i = 0; i < 4; i++) {
543                 if (radeon_encoder->tmds_pll[i].freq == 0)
544                         break;
545                 if ((uint32_t)(mode->clock / 10) < radeon_encoder->tmds_pll[i].freq) {
546                         tmp = radeon_encoder->tmds_pll[i].value ;
547                         break;
548                 }
549         }
550
551         if (radeon_is_r300(dev_priv) || (dev_priv->chip_family == CHIP_RV280)) {
552                 if (tmp & 0xfff00000)
553                         tmds_pll_cntl = tmp;
554                 else {
555                         tmds_pll_cntl &= 0xfff00000;
556                         tmds_pll_cntl |= tmp;
557                 }
558         } else
559                 tmds_pll_cntl = tmp;
560
561         tmds_transmitter_cntl = RADEON_READ(RADEON_TMDS_TRANSMITTER_CNTL) &
562                 ~(RADEON_TMDS_TRANSMITTER_PLLRST);
563
564     if (dev_priv->chip_family == CHIP_R200 ||
565         dev_priv->chip_family == CHIP_R100 ||
566         radeon_is_r300(dev_priv))
567             tmds_transmitter_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLEN);
568     else /* RV chips got this bit reversed */
569             tmds_transmitter_cntl |= RADEON_TMDS_TRANSMITTER_PLLEN;
570
571     fp_gen_cntl = (RADEON_READ(RADEON_FP_GEN_CNTL) |
572                    (RADEON_FP_CRTC_DONT_SHADOW_VPAR |
573                     RADEON_FP_CRTC_DONT_SHADOW_HEND));
574
575     fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
576
577     if (1) // FIXME rgbBits == 8
578             fp_gen_cntl |= RADEON_FP_PANEL_FORMAT;  /* 24 bit format */
579     else
580             fp_gen_cntl &= ~RADEON_FP_PANEL_FORMAT;/* 18 bit format */
581
582     if (radeon_crtc->crtc_id == 0) {
583             if (radeon_is_r300(dev_priv) || dev_priv->chip_family == CHIP_R200) {
584                     fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
585                     if (radeon_encoder->flags & RADEON_USE_RMX)
586                             fp_gen_cntl |= R200_FP_SOURCE_SEL_RMX;
587                     else
588                             fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1;
589             } else
590                     fp_gen_cntl |= RADEON_FP_SEL_CRTC1;
591     } else {
592             if (radeon_is_r300(dev_priv) || dev_priv->chip_family == CHIP_R200) {
593                     fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
594                     fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC2;
595             } else
596                     fp_gen_cntl |= RADEON_FP_SEL_CRTC2;
597     }
598
599     RADEON_WRITE(RADEON_TMDS_PLL_CNTL, tmds_pll_cntl);
600     RADEON_WRITE(RADEON_TMDS_TRANSMITTER_CNTL, tmds_transmitter_cntl);
601     RADEON_WRITE(RADEON_FP_GEN_CNTL, fp_gen_cntl);
602 }
603
604 static const struct drm_encoder_helper_funcs radeon_legacy_tmds_int_helper_funcs = {
605         .dpms = radeon_legacy_tmds_int_dpms,
606         .mode_fixup = radeon_legacy_tmds_int_mode_fixup,
607         .prepare = radeon_legacy_tmds_int_prepare,
608         .mode_set = radeon_legacy_tmds_int_mode_set,
609         .commit = radeon_legacy_tmds_int_commit,
610 };
611
612
613 static const struct drm_encoder_funcs radeon_legacy_tmds_int_enc_funcs = {
614         .destroy = radeon_enc_destroy,
615 };
616
617 struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, int bios_index)
618 {
619         struct drm_radeon_private *dev_priv = dev->dev_private;
620         struct radeon_mode_info *mode_info = &dev_priv->mode_info;
621         struct radeon_encoder *radeon_encoder;
622         struct drm_encoder *encoder;
623         radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL);
624         if (!radeon_encoder) {
625                 return NULL;
626         }
627
628         encoder = &radeon_encoder->base;
629
630         encoder->possible_crtcs = 0x3;
631         encoder->possible_clones = 0;
632         drm_encoder_init(dev, encoder, &radeon_legacy_tmds_int_enc_funcs,
633                          DRM_MODE_ENCODER_TMDS);
634
635         drm_encoder_helper_add(encoder, &radeon_legacy_tmds_int_helper_funcs);
636
637         radeon_combios_get_tmds_info(radeon_encoder);
638         return encoder;
639 }
640
641 static bool radeon_legacy_tmds_ext_mode_fixup(struct drm_encoder *encoder,
642                                               struct drm_display_mode *mode,
643                                               struct drm_display_mode *adjusted_mode)
644 {
645         return true;
646 }
647
648 static void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode)
649 {
650         struct drm_device *dev = encoder->dev;
651         struct drm_radeon_private *dev_priv = dev->dev_private;
652         uint32_t fp2_gen_cntl = RADEON_READ(RADEON_FP2_GEN_CNTL);
653
654         switch(mode) {
655         case DRM_MODE_DPMS_ON:
656                 fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN;
657                 fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
658                 break;
659         case DRM_MODE_DPMS_STANDBY:
660         case DRM_MODE_DPMS_SUSPEND:
661         case DRM_MODE_DPMS_OFF:
662                 fp2_gen_cntl |= RADEON_FP2_BLANK_EN;
663                 fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
664                 break;
665         }
666
667         RADEON_WRITE(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
668 }
669
670 static void radeon_legacy_tmds_ext_prepare(struct drm_encoder *encoder)
671 {
672         radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF);
673 }
674
675 static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder)
676 {
677         radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_ON);
678 }
679
680 static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder,
681                                             struct drm_display_mode *mode,
682                                             struct drm_display_mode *adjusted_mode)
683 {
684         struct drm_device *dev = encoder->dev;
685         struct drm_radeon_private *dev_priv = dev->dev_private;
686         struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
687         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
688         uint32_t fp2_gen_cntl = RADEON_READ(RADEON_FP2_GEN_CNTL);
689
690         if (radeon_crtc->crtc_id == 0)
691                 radeon_legacy_rmx_mode_set(encoder, mode, adjusted_mode);
692
693         if (1) // FIXME rgbBits == 8
694                 fp2_gen_cntl |= RADEON_FP2_PANEL_FORMAT; /* 24 bit format, */
695         else
696                 fp2_gen_cntl &= ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format, */
697
698         fp2_gen_cntl &= ~(RADEON_FP2_ON |
699                           RADEON_FP2_DVO_EN |
700                           RADEON_FP2_DVO_RATE_SEL_SDR);
701
702         /* XXX: these are oem specific */
703         if (radeon_is_r300(dev_priv)) {
704                 if ((dev->pdev->device == 0x4850) &&
705                     (dev->pdev->subsystem_vendor == 0x1028) &&
706                     (dev->pdev->subsystem_device == 0x2001)) /* Dell Inspiron 8600 */
707                         fp2_gen_cntl |= R300_FP2_DVO_CLOCK_MODE_SINGLE;
708                 else
709                         fp2_gen_cntl |= RADEON_FP2_PAD_FLOP_EN | R300_FP2_DVO_CLOCK_MODE_SINGLE;
710
711                 /*if (mode->clock > 165000)
712                         fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;*/
713         }
714
715         if (radeon_crtc->crtc_id == 0) {
716                 if ((dev_priv->chip_family == CHIP_R200) || radeon_is_r300(dev_priv)) {
717                         fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK;
718                         if (radeon_encoder->flags & RADEON_USE_RMX)
719                                 fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX;
720                         else
721                                 fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC1;
722                 } else
723                         fp2_gen_cntl &= ~RADEON_FP2_SRC_SEL_CRTC2;
724         } else {
725                 if ((dev_priv->chip_family == CHIP_R200) || radeon_is_r300(dev_priv)) {
726                         fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK;
727                         fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
728                 } else
729                         fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2;
730         }
731
732         RADEON_WRITE(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
733 }
734
735 static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs = {
736         .dpms = radeon_legacy_tmds_ext_dpms,
737         .mode_fixup = radeon_legacy_tmds_ext_mode_fixup,
738         .prepare = radeon_legacy_tmds_ext_prepare,
739         .mode_set = radeon_legacy_tmds_ext_mode_set,
740         .commit = radeon_legacy_tmds_ext_commit,
741 };
742
743
744 static const struct drm_encoder_funcs radeon_legacy_tmds_ext_enc_funcs = {
745         .destroy = radeon_enc_destroy,
746 };
747
748 struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index)
749 {
750         struct drm_radeon_private *dev_priv = dev->dev_private;
751         struct radeon_mode_info *mode_info = &dev_priv->mode_info;
752         struct radeon_encoder *radeon_encoder;
753         struct drm_encoder *encoder;
754         radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL);
755         if (!radeon_encoder) {
756                 return NULL;
757         }
758
759         encoder = &radeon_encoder->base;
760
761         encoder->possible_crtcs = 0x3;
762         encoder->possible_clones = 0;
763         drm_encoder_init(dev, encoder, &radeon_legacy_tmds_ext_enc_funcs,
764                          DRM_MODE_ENCODER_TMDS);
765
766         drm_encoder_helper_add(encoder, &radeon_legacy_tmds_ext_helper_funcs);
767
768         //radeon_combios_get_tmds_info(radeon_encoder);
769         return encoder;
770 }
771
772 static bool radeon_legacy_tv_dac_mode_fixup(struct drm_encoder *encoder,
773                                             struct drm_display_mode *mode,
774                                             struct drm_display_mode *adjusted_mode)
775 {
776         return true;
777 }
778
779 static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
780 {
781         struct drm_device *dev = encoder->dev;
782         struct drm_radeon_private *dev_priv = dev->dev_private;
783         uint32_t fp2_gen_cntl, crtc2_gen_cntl, tv_master_cntl, tv_dac_cntl;
784
785         if (dev_priv->chip_family == CHIP_R200)
786                 fp2_gen_cntl = RADEON_READ(RADEON_FP2_GEN_CNTL);
787         else {
788                 crtc2_gen_cntl = RADEON_READ(RADEON_CRTC2_GEN_CNTL);
789                 // FIXME TV
790                 //tv_master_cntl = RADEON_READ(RADEON_TV_MASTER_CNTL);
791                 tv_dac_cntl = RADEON_READ(RADEON_TV_DAC_CNTL);
792         }
793
794         switch(mode) {
795         case DRM_MODE_DPMS_ON:
796                 if (dev_priv->chip_family == CHIP_R200)
797                         fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
798                 else {
799                         crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON;
800                         //tv_master_cntl |= RADEON_TV_ON;
801                         if (dev_priv->chip_family == CHIP_R420 ||
802                             dev_priv->chip_family == CHIP_RV410)
803                                 tv_dac_cntl &= ~(R420_TV_DAC_RDACPD |
804                                                  R420_TV_DAC_GDACPD |
805                                                  R420_TV_DAC_BDACPD |
806                                                  RADEON_TV_DAC_BGSLEEP);
807                         else
808                                 tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD |
809                                                  RADEON_TV_DAC_GDACPD |
810                                                  RADEON_TV_DAC_BDACPD |
811                                                  RADEON_TV_DAC_BGSLEEP);
812                 }
813                 break;
814         case DRM_MODE_DPMS_STANDBY:
815         case DRM_MODE_DPMS_SUSPEND:
816         case DRM_MODE_DPMS_OFF:
817                 if (dev_priv->chip_family == CHIP_R200)
818                         fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
819                 else {
820                         crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;
821                         //tv_master_cntl &= ~RADEON_TV_ON;
822                         if (dev_priv->chip_family == CHIP_R420 ||
823                             dev_priv->chip_family == CHIP_RV410)
824                                 tv_dac_cntl |= (R420_TV_DAC_RDACPD |
825                                                 R420_TV_DAC_GDACPD |
826                                                 R420_TV_DAC_BDACPD |
827                                                 RADEON_TV_DAC_BGSLEEP);
828                         else
829                                 tv_dac_cntl |= (RADEON_TV_DAC_RDACPD |
830                                                 RADEON_TV_DAC_GDACPD |
831                                                 RADEON_TV_DAC_BDACPD |
832                                                 RADEON_TV_DAC_BGSLEEP);
833                 }
834                 break;
835         }
836
837         if (dev_priv->chip_family == CHIP_R200)
838                 RADEON_WRITE(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
839         else {
840                 RADEON_WRITE(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
841                 //RADEON_WRITE(RADEON_TV_MASTER_CNTL, tv_master_cntl);
842                 RADEON_WRITE(RADEON_TV_DAC_CNTL, tv_dac_cntl);
843         }
844
845 }
846
847 static void radeon_legacy_tv_dac_prepare(struct drm_encoder *encoder)
848 {
849         radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF);
850 }
851
852 static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder)
853 {
854         radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_ON);
855 }
856
857 static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
858                                           struct drm_display_mode *mode,
859                                           struct drm_display_mode *adjusted_mode)
860 {
861         struct drm_device *dev = encoder->dev;
862         struct drm_radeon_private *dev_priv = dev->dev_private;
863         struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
864         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
865         uint32_t tv_dac_cntl, gpiopad_a, dac2_cntl, disp_output_cntl, fp2_gen_cntl;
866         uint32_t disp_hw_debug;
867
868         if (radeon_crtc->crtc_id == 0)
869                 radeon_legacy_rmx_mode_set(encoder, mode, adjusted_mode);
870
871         if (dev_priv->chip_family != CHIP_R200) {
872                 tv_dac_cntl = RADEON_READ(RADEON_TV_DAC_CNTL);
873                 if (dev_priv->chip_family == CHIP_R420 ||
874                     dev_priv->chip_family == CHIP_RV410) {
875                         tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK |
876                                          RADEON_TV_DAC_BGADJ_MASK |
877                                          R420_TV_DAC_DACADJ_MASK |
878                                          R420_TV_DAC_RDACPD |
879                                          R420_TV_DAC_GDACPD |
880                                          R420_TV_DAC_GDACPD |
881                                          R420_TV_DAC_TVENABLE);
882                 } else {
883                         tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK |
884                                          RADEON_TV_DAC_BGADJ_MASK |
885                                          RADEON_TV_DAC_DACADJ_MASK |
886                                          RADEON_TV_DAC_RDACPD |
887                                          RADEON_TV_DAC_GDACPD |
888                                          RADEON_TV_DAC_GDACPD);
889                 }
890
891                 // FIXME TV
892                 tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
893                                 RADEON_TV_DAC_NHOLD |
894                                 RADEON_TV_DAC_STD_PS2 /*|
895                                 radeon_encoder->ps2_tvdac_adj*/); // fixme, get from bios
896
897                 RADEON_WRITE(RADEON_TV_DAC_CNTL, tv_dac_cntl);
898         }
899
900         if (radeon_is_r300(dev_priv)) {
901                 gpiopad_a = RADEON_READ(RADEON_GPIOPAD_A) | 1;
902                 disp_output_cntl = RADEON_READ(RADEON_DISP_OUTPUT_CNTL);
903         } else if (dev_priv->chip_family == CHIP_R200)
904                 fp2_gen_cntl = RADEON_READ(RADEON_FP2_GEN_CNTL);
905         else
906                 disp_hw_debug = RADEON_READ(RADEON_DISP_HW_DEBUG);
907
908         dac2_cntl = RADEON_READ(RADEON_DAC_CNTL2) | RADEON_DAC2_DAC2_CLK_SEL;
909
910         if (radeon_crtc->crtc_id == 0) {
911                 if (radeon_is_r300(dev_priv)) {
912                         disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
913                         disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC;
914                 } else if (dev_priv->chip_family == CHIP_R200) {
915                         fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK |
916                                           RADEON_FP2_DVO_RATE_SEL_SDR);
917                 } else
918                         disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
919         } else {
920                 if (radeon_is_r300(dev_priv)) {
921                         disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
922                         disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
923                 } else if (dev_priv->chip_family == CHIP_R200) {
924                         fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK |
925                                           RADEON_FP2_DVO_RATE_SEL_SDR);
926                         fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
927                 } else
928                         disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL;
929         }
930
931         RADEON_WRITE(RADEON_DAC_CNTL2, dac2_cntl);
932
933         if (radeon_is_r300(dev_priv)) {
934                 RADEON_WRITE_P(RADEON_GPIOPAD_A, gpiopad_a, ~1);
935                 RADEON_WRITE(RADEON_DISP_TV_OUT_CNTL, disp_output_cntl);
936         } else if (dev_priv->chip_family == CHIP_R200)
937                 RADEON_WRITE(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
938         else
939                 RADEON_WRITE(RADEON_DISP_HW_DEBUG, disp_hw_debug);
940
941 }
942
943 static const struct drm_encoder_helper_funcs radeon_legacy_tv_dac_helper_funcs = {
944         .dpms = radeon_legacy_tv_dac_dpms,
945         .mode_fixup = radeon_legacy_tv_dac_mode_fixup,
946         .prepare = radeon_legacy_tv_dac_prepare,
947         .mode_set = radeon_legacy_tv_dac_mode_set,
948         .commit = radeon_legacy_tv_dac_commit,
949 };
950
951
952 static const struct drm_encoder_funcs radeon_legacy_tv_dac_enc_funcs = {
953         .destroy = radeon_enc_destroy,
954 };
955
956 struct drm_encoder *radeon_encoder_legacy_tv_dac_add(struct drm_device *dev, int bios_index, int has_tv)
957 {
958         struct drm_radeon_private *dev_priv = dev->dev_private;
959         struct radeon_mode_info *mode_info = &dev_priv->mode_info;
960         struct radeon_encoder *radeon_encoder;
961         struct drm_encoder *encoder;
962         radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL);
963         if (!radeon_encoder) {
964                 return NULL;
965         }
966
967         encoder = &radeon_encoder->base;
968
969         encoder->possible_crtcs = 0x3;
970         encoder->possible_clones = 0;
971         drm_encoder_init(dev, encoder, &radeon_legacy_tv_dac_enc_funcs,
972                          DRM_MODE_ENCODER_DAC);
973
974         drm_encoder_helper_add(encoder, &radeon_legacy_tv_dac_helper_funcs);
975
976         /* TODO get the tv dac vals from bios tables */
977         //radeon_combios_get_lvds_info(radeon_encoder);
978
979         return encoder;
980 }