OSDN Git Service

Brute force port of legacy crtc/encoder code
[android-x86/external-libdrm.git] / linux-core / radeon_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 extern int atom_debug;
32
33 void radeon_rmx_mode_fixup(struct drm_encoder *encoder,
34                            struct drm_display_mode *mode,
35                            struct drm_display_mode *adjusted_mode)
36 {
37         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
38         if (mode->hdisplay < radeon_encoder->panel_xres ||
39             mode->vdisplay < radeon_encoder->panel_yres) {
40                 radeon_encoder->flags |= RADEON_USE_RMX;
41                 adjusted_mode->hdisplay = radeon_encoder->panel_xres;
42                 adjusted_mode->vdisplay = radeon_encoder->panel_yres;
43                 adjusted_mode->htotal = radeon_encoder->panel_xres + radeon_encoder->hblank;
44                 adjusted_mode->hsync_start = radeon_encoder->panel_xres + radeon_encoder->hoverplus;
45                 adjusted_mode->hsync_end = adjusted_mode->hsync_start + radeon_encoder->hsync_width;
46                 adjusted_mode->vtotal = radeon_encoder->panel_yres + radeon_encoder->vblank;
47                 adjusted_mode->vsync_start = radeon_encoder->panel_yres + radeon_encoder->voverplus;
48                 adjusted_mode->vsync_end = adjusted_mode->vsync_start + radeon_encoder->vsync_width;
49                 /* update crtc values */
50                 drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
51                 /* adjust crtc values */
52                 adjusted_mode->crtc_hdisplay = radeon_encoder->panel_xres;
53                 adjusted_mode->crtc_vdisplay = radeon_encoder->panel_yres;
54                 adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + radeon_encoder->hblank;
55                 adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + radeon_encoder->hoverplus;
56                 adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + radeon_encoder->hsync_width;
57                 adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + radeon_encoder->vblank;
58                 adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + radeon_encoder->voverplus;
59                 adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + radeon_encoder->vsync_width;
60         } else {
61                 adjusted_mode->htotal = radeon_encoder->panel_xres + radeon_encoder->hblank;
62                 adjusted_mode->hsync_start = radeon_encoder->panel_xres + radeon_encoder->hoverplus;
63                 adjusted_mode->hsync_end = adjusted_mode->hsync_start + radeon_encoder->hsync_width;
64                 adjusted_mode->vtotal = radeon_encoder->panel_yres + radeon_encoder->vblank;
65                 adjusted_mode->vsync_start = radeon_encoder->panel_yres + radeon_encoder->voverplus;
66                 adjusted_mode->vsync_end = adjusted_mode->vsync_start + radeon_encoder->vsync_width;
67                 /* update crtc values */
68                 drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
69                 /* adjust crtc values */
70                 adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + radeon_encoder->hblank;
71                 adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + radeon_encoder->hoverplus;
72                 adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + radeon_encoder->hsync_width;
73                 adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + radeon_encoder->vblank;
74                 adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + radeon_encoder->voverplus;
75                 adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + radeon_encoder->vsync_width;
76         }
77         adjusted_mode->clock = radeon_encoder->dotclock;
78         adjusted_mode->flags = radeon_encoder->flags;
79 }
80
81
82 static int atom_dac_find_atom_type(struct radeon_encoder *radeon_encoder, struct drm_connector *connector)
83 {
84         struct drm_device *dev = radeon_encoder->base.dev;
85         struct drm_connector *connector_find;
86         int atom_type = -1;
87
88         if (!connector) {
89                 list_for_each_entry(connector_find, &dev->mode_config.connector_list, head) {
90                         if (connector_find->encoder == &radeon_encoder->base)
91                                 connector = connector_find;
92                 }
93         }
94         if (connector) {
95                 /* look for the encoder in the connector list -
96                    check if we the DAC is enabled on a VGA or STV/CTV or CV connector */
97                 /* work out the ATOM_DEVICE bits */
98                 switch (connector->connector_type) {
99                 case CONNECTOR_VGA:
100                 case CONNECTOR_DVI_I:
101                 case CONNECTOR_DVI_A:
102                         if (radeon_encoder->atom_device & ATOM_DEVICE_CRT1_SUPPORT)
103                                 atom_type = ATOM_DEVICE_CRT1_INDEX;
104                         else if (radeon_encoder->atom_device & ATOM_DEVICE_CRT2_SUPPORT)
105                                 atom_type = ATOM_DEVICE_CRT2_INDEX;
106                         break;
107                 case CONNECTOR_STV:
108                 case CONNECTOR_CTV:
109                         if (radeon_encoder->atom_device & ATOM_DEVICE_TV1_SUPPORT)
110                                 atom_type = ATOM_DEVICE_TV1_INDEX;
111                         break;
112                 case CONNECTOR_DIN:
113                         if (radeon_encoder->atom_device & ATOM_DEVICE_TV1_SUPPORT)
114                                 atom_type = ATOM_DEVICE_TV1_INDEX;
115                         if (radeon_encoder->atom_device & ATOM_DEVICE_CV_SUPPORT)
116                                 atom_type = ATOM_DEVICE_CV_INDEX;
117                         break;
118                 }
119         }
120
121         return atom_type;
122 }
123
124 /* LVTMA encoder for LVDS usage */
125 static void atombios_display_device_control(struct drm_encoder *encoder, int index, uint8_t state)
126 {
127         struct drm_device *dev = encoder->dev;
128         struct drm_radeon_private *dev_priv = dev->dev_private;
129         DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;
130
131         memset(&args, 0, sizeof(args));
132         args.ucAction = state;
133
134         atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
135 }
136
137
138 static void atombios_scaler_setup(struct drm_encoder *encoder, struct drm_display_mode *mode)
139 {
140         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
141         struct drm_device *dev = encoder->dev;
142         struct drm_radeon_private *dev_priv = dev->dev_private;
143         struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
144         ENABLE_SCALER_PS_ALLOCATION args;
145         int index = GetIndexIntoMasterTable(COMMAND, EnableScaler);
146
147         memset(&args, 0, sizeof(args));
148         args.ucScaler = radeon_crtc->crtc_id;
149
150         if (radeon_encoder->flags & RADEON_USE_RMX) {
151                 if (radeon_encoder->rmx_type == RMX_FULL)
152                         args.ucEnable = ATOM_SCALER_EXPANSION;
153                 else if (radeon_encoder->rmx_type == RMX_CENTER)
154                         args.ucEnable = ATOM_SCALER_CENTER;
155         } else
156                 args.ucEnable = ATOM_SCALER_DISABLE;
157
158         atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
159 }
160
161 void atombios_set_crtc_source(struct drm_encoder *encoder, int source)
162 {
163         int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
164         struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
165         struct drm_radeon_private *dev_priv = encoder->dev->dev_private;
166         uint8_t frev, crev;
167         SELECT_CRTC_SOURCE_PS_ALLOCATION crtc_src_param;
168         SELECT_CRTC_SOURCE_PARAMETERS_V2 crtc_src_param2;
169         uint32_t *param = NULL;
170
171         atom_parse_cmd_header(dev_priv->mode_info.atom_context, index, &frev, &crev);
172         switch (frev) {
173         case 1: {
174                 switch (crev) {
175                 case 0:
176                 case 1:
177                 default:
178                         memset(&crtc_src_param, 0, sizeof(crtc_src_param));
179                         crtc_src_param.ucCRTC = radeon_crtc->crtc_id;
180                         crtc_src_param.ucDevice = source;
181                         param = (uint32_t *)&crtc_src_param;
182                         break;
183                 case 2:
184                         memset(&crtc_src_param2, 0, sizeof(crtc_src_param2));
185                         crtc_src_param2.ucCRTC = radeon_crtc->crtc_id;
186                         crtc_src_param2.ucEncoderID = source;
187                         switch (source) {
188                         case ATOM_DEVICE_CRT1_INDEX:
189                         case ATOM_DEVICE_CRT2_INDEX:
190                                 crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CRT;
191                                 break;
192                         case ATOM_DEVICE_DFP1_INDEX:
193                         case ATOM_DEVICE_DFP2_INDEX:
194                         case ATOM_DEVICE_DFP3_INDEX:
195                                 crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_DVI;
196                                 // TODO ENCODER MODE
197                                 break;
198                         case ATOM_DEVICE_LCD1_INDEX:
199                                 crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;
200                                 break;
201                         case ATOM_DEVICE_TV1_INDEX:
202                                 crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_TV;
203                                 break;
204                         case ATOM_DEVICE_CV_INDEX:
205                                 crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CV;
206                                 break;
207                         }
208                         param = (uint32_t *)&crtc_src_param2;
209                         break;
210                 }
211         }
212                 break;
213         default:
214                 return;
215         }
216         
217         atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)param);
218
219 }
220
221 static void radeon_dfp_disable_dither(struct drm_encoder *encoder, int device)
222 {
223         struct drm_device *dev = encoder->dev;
224         struct drm_radeon_private *dev_priv = dev->dev_private;
225
226         switch (device) {
227         case ATOM_DEVICE_DFP1_INDEX:
228                 RADEON_WRITE(AVIVO_TMDSA_BIT_DEPTH_CONTROL, 0); /* TMDSA */
229                 break;
230         case ATOM_DEVICE_DFP2_INDEX:
231                 if ((dev_priv->chip_family == CHIP_RS600) ||
232                     (dev_priv->chip_family == CHIP_RS690) ||
233                     (dev_priv->chip_family == CHIP_RS740))
234                         RADEON_WRITE(AVIVO_DDIA_BIT_DEPTH_CONTROL, 0); /* DDIA */
235                 else
236                         RADEON_WRITE(AVIVO_DVOA_BIT_DEPTH_CONTROL, 0); /* DVO */
237                 break;
238                 /*case ATOM_DEVICE_LCD1_INDEX:*/ /* LVDS panels need dither enabled */
239         case ATOM_DEVICE_DFP3_INDEX:
240                 RADEON_WRITE(AVIVO_LVTMA_BIT_DEPTH_CONTROL, 0); /* LVTMA */
241                 break;
242         default:
243                 break;
244         }
245 }
246
247
248 static void radeon_lvtma_mode_set(struct drm_encoder *encoder,
249                                   struct drm_display_mode *mode,
250                                   struct drm_display_mode *adjusted_mode)
251 {
252         struct drm_device *dev = encoder->dev;
253         struct drm_radeon_private *dev_priv = dev->dev_private;
254         LVDS_ENCODER_CONTROL_PS_ALLOCATION args;
255         int index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
256
257         memset(&args, 0, sizeof(args));
258         atombios_scaler_setup(encoder, mode);
259         atombios_set_crtc_source(encoder, ATOM_DEVICE_LCD1_INDEX);
260
261         args.ucAction = 1;
262         if (adjusted_mode->clock > 165000)
263                 args.ucMisc = 1;
264         else
265                 args.ucMisc = 0;
266         args.usPixelClock = cpu_to_le16(adjusted_mode->clock / 10);
267         
268         printk("executing set LVDS encoder\n");
269         atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
270 }
271
272
273 static void radeon_lvtma_dpms(struct drm_encoder *encoder, int mode)
274 {
275         struct drm_device *dev = encoder->dev;
276         int index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
277
278         switch(mode) {
279         case DRM_MODE_DPMS_ON:
280                 atombios_display_device_control(encoder, index, ATOM_ENABLE);
281                 break;
282         case DRM_MODE_DPMS_STANDBY:
283         case DRM_MODE_DPMS_SUSPEND:
284         case DRM_MODE_DPMS_OFF:
285                 atombios_display_device_control(encoder, index, ATOM_DISABLE);
286                 break;
287         }
288 }
289
290 static bool radeon_lvtma_mode_fixup(struct drm_encoder *encoder,
291                                     struct drm_display_mode *mode,
292                                     struct drm_display_mode *adjusted_mode)
293 {
294         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
295
296         radeon_encoder->flags &= ~RADEON_USE_RMX;
297
298         if (radeon_encoder->rmx_type != RMX_OFF)
299                 radeon_rmx_mode_fixup(encoder, mode, adjusted_mode);
300         
301         return true;
302 }
303
304 static void radeon_lvtma_prepare(struct drm_encoder *encoder)
305 {
306         radeon_lvtma_dpms(encoder, DRM_MODE_DPMS_OFF);
307 }
308
309 static void radeon_lvtma_commit(struct drm_encoder *encoder)
310 {
311         radeon_lvtma_dpms(encoder, DRM_MODE_DPMS_ON);
312 }
313
314 static const struct drm_encoder_helper_funcs radeon_atom_lvtma_helper_funcs = {
315         .dpms = radeon_lvtma_dpms,
316         .mode_fixup = radeon_lvtma_mode_fixup,
317         .prepare = radeon_lvtma_prepare,
318         .mode_set = radeon_lvtma_mode_set,
319         .commit = radeon_lvtma_commit,
320 };
321
322 void radeon_enc_destroy(struct drm_encoder *encoder)
323 {
324         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
325         drm_encoder_cleanup(encoder);
326         kfree(radeon_encoder);
327 }
328
329 static const struct drm_encoder_funcs radeon_atom_lvtma_enc_funcs = {
330         .destroy = radeon_enc_destroy,
331 };
332
333 struct drm_encoder *radeon_encoder_lvtma_add(struct drm_device *dev, int bios_index)
334 {
335         struct drm_radeon_private *dev_priv = dev->dev_private;
336         struct radeon_mode_info *mode_info = &dev_priv->mode_info;
337         struct radeon_encoder *radeon_encoder;
338         struct drm_encoder *encoder;
339         radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL);
340         if (!radeon_encoder) {
341                 return NULL;
342         }
343
344         encoder = &radeon_encoder->base;
345
346         encoder->possible_crtcs = 0x3;
347         encoder->possible_clones = 0;
348         drm_encoder_init(dev, encoder, &radeon_atom_lvtma_enc_funcs,
349                          DRM_MODE_ENCODER_LVDS);
350
351         drm_encoder_helper_add(encoder, &radeon_atom_lvtma_helper_funcs);
352         radeon_encoder->atom_device = mode_info->bios_connector[bios_index].devices;
353
354         /* TODO get the LVDS info from the BIOS for panel size etc. */
355         /* get the lvds info from the bios */
356         radeon_get_lvds_info(radeon_encoder);
357
358         /* LVDS gets default RMX full scaling */
359         radeon_encoder->rmx_type = RMX_FULL;
360
361         return encoder;
362 }
363
364 static void radeon_atom_dac_dpms(struct drm_encoder *encoder, int mode)
365 {
366         struct drm_device *dev = encoder->dev;
367         struct drm_radeon_private *dev_priv = dev->dev_private;
368         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
369         int atom_type = -1;
370         int index;
371
372         atom_type = atom_dac_find_atom_type(radeon_encoder, NULL);
373         if (atom_type == -1)
374                 return;
375         
376         switch(atom_type) {
377         case ATOM_DEVICE_CRT1_INDEX:
378                 index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
379                 break;
380         case ATOM_DEVICE_CRT2_INDEX:
381                 index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
382                 break;
383         case ATOM_DEVICE_TV1_INDEX:
384                 index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
385                 break;
386         case ATOM_DEVICE_CV_INDEX:
387                 index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
388                 break;
389         default:
390                 return;
391         }
392
393         switch(mode) {
394         case DRM_MODE_DPMS_ON:
395                 atombios_display_device_control(encoder, index, ATOM_ENABLE);
396                 break;
397         case DRM_MODE_DPMS_STANDBY:     
398         case DRM_MODE_DPMS_SUSPEND:
399         case DRM_MODE_DPMS_OFF:
400                 atombios_display_device_control(encoder, index, ATOM_DISABLE);
401                 break;
402         }
403 }
404
405 static bool radeon_atom_dac_mode_fixup(struct drm_encoder *encoder,
406                                   struct drm_display_mode *mode,
407                                   struct drm_display_mode *adjusted_mode)
408 {
409         return true;
410 }
411
412 static void radeon_atom_dac_prepare(struct drm_encoder *encoder)
413 {
414         radeon_atom_dac_dpms(encoder, DRM_MODE_DPMS_OFF);
415 }
416
417 static void radeon_atom_dac_commit(struct drm_encoder *encoder)
418 {
419         radeon_atom_dac_dpms(encoder, DRM_MODE_DPMS_ON);
420 }
421
422 static int atombios_dac_setup(struct drm_encoder *encoder,
423                               struct drm_display_mode *mode,
424                               int atom_type)
425 {
426         struct drm_device *dev = encoder->dev;
427         struct drm_radeon_private *dev_priv = dev->dev_private;
428         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
429         DAC_ENCODER_CONTROL_PS_ALLOCATION args;
430         int id = (radeon_encoder->type.dac == DAC_TVDAC);
431         int index;
432
433         memset(&args, 0, sizeof(args));
434         if (id == 0)
435                 index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);
436         else
437                 index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);
438
439         args.ucAction = 1;
440         args.usPixelClock = cpu_to_le16(mode->clock / 10);
441         if ((atom_type == ATOM_DEVICE_CRT1_INDEX) ||
442             (atom_type == ATOM_DEVICE_CRT2_INDEX))
443                 args.ucDacStandard = id ? ATOM_DAC2_PS2 : ATOM_DAC1_PS2;
444         else if (atom_type == ATOM_DEVICE_CV_INDEX)
445                 args.ucDacStandard = id ? ATOM_DAC2_CV : ATOM_DAC1_CV;
446         else if (atom_type == ATOM_DEVICE_TV1_INDEX)
447                 args.ucDacStandard = id ? ATOM_DAC2_NTSC : ATOM_DAC1_NTSC;
448         /* TODO PAL */
449         atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
450         
451         return 0;
452 }
453
454 static int atombios_tv1_setup(struct drm_encoder *encoder,
455                               struct drm_display_mode *mode,
456                               int atom_type)
457 {
458         struct drm_device *dev = encoder->dev;
459         struct drm_radeon_private *dev_priv = dev->dev_private;
460         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
461         TV_ENCODER_CONTROL_PS_ALLOCATION args;
462         int index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl);
463
464         memset(&args, 0, sizeof(args));
465         args.sTVEncoder.ucAction = 1;
466         if (atom_type == ATOM_DEVICE_CV_INDEX)
467                 args.sTVEncoder.ucTvStandard = ATOM_TV_CV;
468         else {
469                 // TODO PAL
470                 args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;
471         }
472
473         args.sTVEncoder.usPixelClock = cpu_to_le16(mode->clock / 10);
474         
475         atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
476         return 0;
477 }
478
479 static void radeon_atom_dac_mode_set(struct drm_encoder *encoder,
480                                      struct drm_display_mode *mode,
481                                      struct drm_display_mode *adjusted_mode)
482 {
483         struct drm_device *dev = encoder->dev;
484         struct drm_radeon_private *dev_priv = dev->dev_private;
485         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
486         int atom_type = -1;
487
488         atom_type = atom_dac_find_atom_type(radeon_encoder, NULL);
489         if (atom_type == -1)
490                 return;
491
492         atombios_scaler_setup(encoder, mode);
493         atombios_set_crtc_source(encoder, atom_type);
494
495         atombios_dac_setup(encoder, adjusted_mode, atom_type);
496         if ((atom_type == ATOM_DEVICE_TV1_INDEX) ||
497             (atom_type == ATOM_DEVICE_CV_INDEX))
498                 atombios_tv1_setup(encoder, adjusted_mode, atom_type);
499         
500 }
501
502 static bool atom_dac_load_detect(struct drm_encoder *encoder, int atom_devices)
503 {
504         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
505         struct drm_device *dev = encoder->dev;
506         struct drm_radeon_private *dev_priv = dev->dev_private;
507         DAC_LOAD_DETECTION_PS_ALLOCATION args;
508         int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection);
509
510         memset(&args, 0, sizeof(args));
511         args.sDacload.ucMisc = 0;
512         args.sDacload.ucDacType = (radeon_encoder->type.dac == DAC_PRIMARY) ? ATOM_DAC_A : ATOM_DAC_B;
513
514         if (atom_devices & ATOM_DEVICE_CRT1_SUPPORT)
515                 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT);
516         else if (atom_devices & ATOM_DEVICE_CRT2_SUPPORT)
517                 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT);
518         else if (atom_devices & ATOM_DEVICE_CV_SUPPORT) {
519                 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT);
520                 if (radeon_is_dce3(dev_priv))
521                         args.sDacload.ucMisc = 1;
522         } else if (atom_devices & ATOM_DEVICE_TV1_SUPPORT) {
523                 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT);
524                 if (radeon_is_dce3(dev_priv))
525                         args.sDacload.ucMisc = 1;
526         } else
527                 return false;
528         
529         DRM_DEBUG("writing %x %x\n", args.sDacload.usDeviceID, args.sDacload.ucDacType);
530         atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
531         return true;
532 }       
533
534 static enum drm_connector_status radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
535 {
536         struct drm_device *dev = encoder->dev;
537         struct drm_radeon_private *dev_priv = dev->dev_private;
538         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
539         int atom_type = -1;
540         uint32_t bios_0_scratch;
541
542         atom_type = atom_dac_find_atom_type(radeon_encoder, connector);
543         if (atom_type == -1) {
544                 DRM_DEBUG("exit after find \n");
545                 return connector_status_unknown;
546         }
547
548         if(!atom_dac_load_detect(encoder, (1 << atom_type))) {
549                 DRM_DEBUG("detect returned false \n");
550                 return connector_status_unknown;
551         }
552
553
554         if (dev_priv->chip_family >= CHIP_R600) 
555                 bios_0_scratch = RADEON_READ(R600_BIOS_0_SCRATCH);
556         else
557                 bios_0_scratch = RADEON_READ(RADEON_BIOS_0_SCRATCH);
558
559         DRM_DEBUG("Bios 0 scratch %x\n", bios_0_scratch);
560         if (radeon_encoder->atom_device & ATOM_DEVICE_CRT1_SUPPORT) {
561                 if (bios_0_scratch & ATOM_S0_CRT1_MASK)
562                         return connector_status_connected;
563         } else if (radeon_encoder->atom_device & ATOM_DEVICE_CRT2_SUPPORT) {
564                 if (bios_0_scratch & ATOM_S0_CRT2_MASK)
565                         return connector_status_connected;
566         } else if (radeon_encoder->atom_device & ATOM_DEVICE_CV_SUPPORT) {
567                 if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A))
568                         return connector_status_connected;
569         } else if (radeon_encoder->atom_device & ATOM_DEVICE_TV1_SUPPORT) {
570                 if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A))
571                         return connector_status_connected; // CTV
572                 else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A))
573                         return connector_status_connected; // STV
574         }
575         return connector_status_disconnected;
576 }
577
578 static const struct drm_encoder_helper_funcs radeon_atom_dac_helper_funcs = {
579         .dpms = radeon_atom_dac_dpms,
580         .mode_fixup = radeon_atom_dac_mode_fixup,
581         .prepare = radeon_atom_dac_prepare,
582         .mode_set = radeon_atom_dac_mode_set,
583         .commit = radeon_atom_dac_commit,
584         .detect = radeon_atom_dac_detect,
585 };
586
587 static const struct drm_encoder_funcs radeon_atom_dac_enc_funcs = {
588         . destroy = radeon_enc_destroy,
589 };
590
591
592 static void atombios_tmds1_setup(struct drm_encoder *encoder,
593                                  struct drm_display_mode *mode)
594 {
595         struct drm_device *dev = encoder->dev;
596         struct drm_radeon_private *dev_priv = dev->dev_private;
597         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
598         TMDS1_ENCODER_CONTROL_PS_ALLOCATION args;
599         int index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl);
600
601         memset(&args, 0, sizeof(args));
602         args.ucAction = 1;
603         if (mode->clock > 165000)
604                 args.ucMisc = 1;
605         else
606                 args.ucMisc = 0;
607
608         args.usPixelClock = cpu_to_le16(mode->clock / 10);
609
610         atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); 
611 }
612
613 static void atombios_tmds2_setup(struct drm_encoder *encoder,
614                                  struct drm_display_mode *mode)
615 {
616         struct drm_device *dev = encoder->dev;
617         struct drm_radeon_private *dev_priv = dev->dev_private;
618         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
619         TMDS2_ENCODER_CONTROL_PS_ALLOCATION args;
620         int index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl);
621
622         memset(&args, 0, sizeof(args));
623         args.ucAction = 1;
624         if (mode->clock > 165000)
625                 args.ucMisc = 1;
626         else
627                 args.ucMisc = 0;
628
629         args.usPixelClock = cpu_to_le16(mode->clock / 10);
630
631         atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); 
632 }
633
634
635 static void atombios_ext_tmds_setup(struct drm_encoder *encoder,
636                                     struct drm_display_mode *mode)
637 {
638         struct drm_device *dev = encoder->dev;
639         struct drm_radeon_private *dev_priv = dev->dev_private;
640         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
641         ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION args;
642         int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
643
644         memset(&args, 0, sizeof(args));
645         args.sXTmdsEncoder.ucEnable = 1;
646
647         if (mode->clock > 165000)
648                 args.sXTmdsEncoder.ucMisc = 1;
649         else
650                 args.sXTmdsEncoder.ucMisc = 0;
651
652         // TODO 6-bit DAC
653 //      args.usPixelClock = cpu_to_le16(mode->clock / 10);
654
655         atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); 
656 }
657
658 static void atombios_dig1_setup(struct drm_encoder *encoder,
659                                 struct drm_display_mode *mode)
660 {
661         struct drm_device *dev = encoder->dev;
662         struct drm_radeon_private *dev_priv = dev->dev_private;
663         DIG_ENCODER_CONTROL_PS_ALLOCATION args;
664         int index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
665
666         args.ucAction = 1;
667         args.usPixelClock = mode->clock / 10;
668         args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER1;
669
670         // TODO coherent mode
671 //      if (encoder->coherent_mode)
672 //              args.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
673
674         if (mode->clock > 165000) {
675                 args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B;
676                 args.ucLaneNum = 8;
677         } else {
678                 args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
679                 args.ucLaneNum = 4;
680         }
681
682         // TODO Encoder MODE
683         atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); 
684 }
685
686 static void atombios_ddia_setup(struct drm_encoder *encoder,
687                                 struct drm_display_mode *mode)
688 {
689         struct drm_device *dev = encoder->dev;
690         struct drm_radeon_private *dev_priv = dev->dev_private;
691         DVO_ENCODER_CONTROL_PS_ALLOCATION args;
692         int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
693
694         args.sDVOEncoder.ucAction = ATOM_ENABLE;
695         args.sDVOEncoder.usPixelClock = mode->clock / 10;
696
697         if (mode->clock > 165000)
698                 args.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = PANEL_ENCODER_MISC_DUAL;
699         else
700                 args.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = 0;
701
702         atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); 
703 }
704
705 struct drm_encoder *radeon_encoder_atom_dac_add(struct drm_device *dev, int bios_index, int dac_type, int with_tv)
706 {
707         struct drm_radeon_private *dev_priv = dev->dev_private;
708         struct radeon_mode_info *mode_info = &dev_priv->mode_info;
709         struct radeon_encoder *radeon_encoder = NULL;
710         struct drm_encoder *encoder;
711         int type = with_tv ? DRM_MODE_ENCODER_TVDAC : DRM_MODE_ENCODER_DAC;
712         int found = 0;
713         int digital_enc_mask = ~(ATOM_DEVICE_DFP1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT | ATOM_DEVICE_DFP3_SUPPORT |
714                                 ATOM_DEVICE_LCD1_SUPPORT);
715         /* we may already have added this encoder */
716         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
717                 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC ||
718                     encoder->encoder_type != DRM_MODE_ENCODER_TVDAC)
719                         continue;
720
721                 radeon_encoder = to_radeon_encoder(encoder);
722                 if (radeon_encoder->type.dac == dac_type) {
723                         found = 1;
724                         break;
725                 }
726         }
727
728         if (found) {
729                 /* upgrade to a TV controlling DAC */
730                 if (type == DRM_MODE_ENCODER_TVDAC)
731                         encoder->encoder_type = type;
732                 radeon_encoder->atom_device |= mode_info->bios_connector[bios_index].devices;
733                 radeon_encoder->atom_device &= digital_enc_mask;
734                 return encoder;
735         }
736
737         radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL);
738         if (!radeon_encoder) {
739                 return NULL;
740         }
741
742         encoder = &radeon_encoder->base;
743
744         encoder->possible_crtcs = 0x3;
745         encoder->possible_clones = 0;
746         drm_encoder_init(dev, encoder, &radeon_atom_dac_enc_funcs,
747                          type);
748
749         drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);
750         radeon_encoder->type.dac = dac_type;
751         radeon_encoder->atom_device = mode_info->bios_connector[bios_index].devices;
752
753         /* mask off any digital encoders */
754         radeon_encoder->atom_device &= digital_enc_mask;
755         return encoder;
756 }
757
758 static void radeon_atom_tmds_dpms(struct drm_encoder *encoder, int mode)
759 {
760         struct drm_device *dev = encoder->dev;
761         struct drm_radeon_private *dev_priv = dev->dev_private;
762         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
763         int atom_type = -1;
764         int index = -1;
765
766         if (radeon_encoder->atom_device & ATOM_DEVICE_DFP1_SUPPORT)
767                 atom_type = ATOM_DEVICE_DFP1_INDEX;
768         if (radeon_encoder->atom_device & ATOM_DEVICE_DFP2_SUPPORT)
769                 atom_type = ATOM_DEVICE_DFP2_INDEX;
770         if (radeon_encoder->atom_device & ATOM_DEVICE_DFP3_SUPPORT)
771                 atom_type = ATOM_DEVICE_DFP3_INDEX;
772
773         if (atom_type == -1)
774                 return;
775
776         switch(atom_type) {
777         case ATOM_DEVICE_DFP1_INDEX:
778                 index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl);
779                 break;
780         case ATOM_DEVICE_DFP2_INDEX:
781                 index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
782                 break;
783         case ATOM_DEVICE_DFP3_INDEX:
784                 index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl);
785                 break;
786         }
787
788         if (index == -1)
789                 return;
790
791         switch(mode) {
792         case DRM_MODE_DPMS_ON:
793                 atombios_display_device_control(encoder, index, ATOM_ENABLE);
794                 break;
795         case DRM_MODE_DPMS_STANDBY:
796         case DRM_MODE_DPMS_SUSPEND:
797         case DRM_MODE_DPMS_OFF:
798                 atombios_display_device_control(encoder, index, ATOM_DISABLE);
799                 break;
800         }
801 }
802
803 static bool radeon_atom_tmds_mode_fixup(struct drm_encoder *encoder,
804                                   struct drm_display_mode *mode,
805                                   struct drm_display_mode *adjusted_mode)
806 {
807         return true;
808 }
809
810 static void radeon_atom_tmds_mode_set(struct drm_encoder *encoder,
811                                       struct drm_display_mode *mode,
812                                       struct drm_display_mode *adjusted_mode)
813 {
814         struct drm_device *dev = encoder->dev;
815         struct drm_radeon_private *dev_priv = dev->dev_private;
816         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
817         int atom_type;
818
819         if (radeon_encoder->atom_device & ATOM_DEVICE_DFP1_SUPPORT)
820                 atom_type = ATOM_DEVICE_DFP1_INDEX;
821         if (radeon_encoder->atom_device & ATOM_DEVICE_DFP2_SUPPORT)
822                 atom_type = ATOM_DEVICE_DFP2_INDEX;
823         if (radeon_encoder->atom_device & ATOM_DEVICE_DFP3_SUPPORT)
824                 atom_type = ATOM_DEVICE_DFP3_INDEX;
825
826         atombios_scaler_setup(encoder, mode);
827         atombios_set_crtc_source(encoder, atom_type);
828
829         if (atom_type == ATOM_DEVICE_DFP1_INDEX)
830                 atombios_tmds1_setup(encoder, adjusted_mode);
831         if (atom_type == ATOM_DEVICE_DFP2_INDEX) {
832                 if ((dev_priv->chip_family == CHIP_RS600) ||
833                     (dev_priv->chip_family == CHIP_RS690) ||
834                     (dev_priv->chip_family == CHIP_RS740))
835                         atombios_ddia_setup(encoder, adjusted_mode);
836                 else
837                         atombios_ext_tmds_setup(encoder, adjusted_mode);
838         }
839         if (atom_type == ATOM_DEVICE_DFP3_INDEX)
840                 atombios_tmds2_setup(encoder, adjusted_mode);
841         radeon_dfp_disable_dither(encoder, atom_type);
842
843
844 }
845
846 static void radeon_atom_tmds_prepare(struct drm_encoder *encoder)
847 {
848         radeon_atom_tmds_dpms(encoder, DRM_MODE_DPMS_OFF);
849 }
850
851 static void radeon_atom_tmds_commit(struct drm_encoder *encoder)
852 {
853         radeon_atom_tmds_dpms(encoder, DRM_MODE_DPMS_ON);
854 }
855
856 static const struct drm_encoder_helper_funcs radeon_atom_tmds_helper_funcs = {
857         .dpms = radeon_atom_tmds_dpms,
858         .mode_fixup = radeon_atom_tmds_mode_fixup,
859         .prepare = radeon_atom_tmds_prepare,
860         .mode_set = radeon_atom_tmds_mode_set,
861         .commit = radeon_atom_tmds_commit,
862         /* no detect for TMDS */
863 };
864
865 static const struct drm_encoder_funcs radeon_atom_tmds_enc_funcs = {
866         . destroy = radeon_enc_destroy,
867 };
868
869 struct drm_encoder *radeon_encoder_atom_tmds_add(struct drm_device *dev, int bios_index, int tmds_type)
870 {
871         struct drm_radeon_private *dev_priv = dev->dev_private;
872         struct radeon_mode_info *mode_info = &dev_priv->mode_info;
873         struct radeon_encoder *radeon_encoder = NULL;
874         struct drm_encoder *encoder;
875         int analog_enc_mask = ~(ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_CRT2_SUPPORT);
876
877                 radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL);
878         if (!radeon_encoder) {
879                 return NULL;
880         }
881
882         encoder = &radeon_encoder->base;
883
884         encoder->possible_crtcs = 0x3;
885         encoder->possible_clones = 0;
886         drm_encoder_init(dev, encoder, &radeon_atom_tmds_enc_funcs,
887                          DRM_MODE_ENCODER_TMDS);
888
889         drm_encoder_helper_add(encoder, &radeon_atom_tmds_helper_funcs);
890
891         radeon_encoder->atom_device = mode_info->bios_connector[bios_index].devices;
892
893         /* mask off any analog encoders */
894         radeon_encoder->atom_device &= analog_enc_mask;
895         return encoder;
896 }
897