blob: 0a92706eac191597839972389248788ebebadb54 [file] [log] [blame]
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001/*
2 * Copyright 2007-8 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors: Dave Airlie
24 * Alex Deucher
25 */
26#include "drmP.h"
27#include "drm_crtc_helper.h"
28#include "radeon_drm.h"
29#include "radeon.h"
30#include "atom.h"
31
32extern int atom_debug;
33
34uint32_t
35radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac)
36{
37 struct radeon_device *rdev = dev->dev_private;
38 uint32_t ret = 0;
39
40 switch (supported_device) {
41 case ATOM_DEVICE_CRT1_SUPPORT:
42 case ATOM_DEVICE_TV1_SUPPORT:
43 case ATOM_DEVICE_TV2_SUPPORT:
44 case ATOM_DEVICE_CRT2_SUPPORT:
45 case ATOM_DEVICE_CV_SUPPORT:
46 switch (dac) {
47 case 1: /* dac a */
48 if ((rdev->family == CHIP_RS300) ||
49 (rdev->family == CHIP_RS400) ||
50 (rdev->family == CHIP_RS480))
51 ret = ENCODER_OBJECT_ID_INTERNAL_DAC2;
52 else if (ASIC_IS_AVIVO(rdev))
53 ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1;
54 else
55 ret = ENCODER_OBJECT_ID_INTERNAL_DAC1;
56 break;
57 case 2: /* dac b */
58 if (ASIC_IS_AVIVO(rdev))
59 ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
60 else {
61 /*if (rdev->family == CHIP_R200)
62 ret = ENCODER_OBJECT_ID_INTERNAL_DVO1;
63 else*/
64 ret = ENCODER_OBJECT_ID_INTERNAL_DAC2;
65 }
66 break;
67 case 3: /* external dac */
68 if (ASIC_IS_AVIVO(rdev))
69 ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1;
70 else
71 ret = ENCODER_OBJECT_ID_INTERNAL_DVO1;
72 break;
73 }
74 break;
75 case ATOM_DEVICE_LCD1_SUPPORT:
76 if (ASIC_IS_AVIVO(rdev))
77 ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1;
78 else
79 ret = ENCODER_OBJECT_ID_INTERNAL_LVDS;
80 break;
81 case ATOM_DEVICE_DFP1_SUPPORT:
82 if ((rdev->family == CHIP_RS300) ||
83 (rdev->family == CHIP_RS400) ||
84 (rdev->family == CHIP_RS480))
85 ret = ENCODER_OBJECT_ID_INTERNAL_DVO1;
86 else if (ASIC_IS_AVIVO(rdev))
87 ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1;
88 else
89 ret = ENCODER_OBJECT_ID_INTERNAL_TMDS1;
90 break;
91 case ATOM_DEVICE_LCD2_SUPPORT:
92 case ATOM_DEVICE_DFP2_SUPPORT:
93 if ((rdev->family == CHIP_RS600) ||
94 (rdev->family == CHIP_RS690) ||
95 (rdev->family == CHIP_RS740))
96 ret = ENCODER_OBJECT_ID_INTERNAL_DDI;
97 else if (ASIC_IS_AVIVO(rdev))
98 ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1;
99 else
100 ret = ENCODER_OBJECT_ID_INTERNAL_DVO1;
101 break;
102 case ATOM_DEVICE_DFP3_SUPPORT:
103 ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1;
104 break;
105 }
106
107 return ret;
108}
109
110void
111radeon_link_encoder_connector(struct drm_device *dev)
112{
113 struct drm_connector *connector;
114 struct radeon_connector *radeon_connector;
115 struct drm_encoder *encoder;
116 struct radeon_encoder *radeon_encoder;
117
118 /* walk the list and link encoders to connectors */
119 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
120 radeon_connector = to_radeon_connector(connector);
121 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
122 radeon_encoder = to_radeon_encoder(encoder);
123 if (radeon_encoder->devices & radeon_connector->devices)
124 drm_mode_connector_attach_encoder(connector, encoder);
125 }
126 }
127}
128
129static struct drm_connector *
130radeon_get_connector_for_encoder(struct drm_encoder *encoder)
131{
132 struct drm_device *dev = encoder->dev;
133 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
134 struct drm_connector *connector;
135 struct radeon_connector *radeon_connector;
136
137 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
138 radeon_connector = to_radeon_connector(connector);
139 if (radeon_encoder->devices & radeon_connector->devices)
140 return connector;
141 }
142 return NULL;
143}
144
145/* used for both atom and legacy */
146void radeon_rmx_mode_fixup(struct drm_encoder *encoder,
147 struct drm_display_mode *mode,
148 struct drm_display_mode *adjusted_mode)
149{
150 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
151 struct drm_device *dev = encoder->dev;
152 struct radeon_device *rdev = dev->dev_private;
153 struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;
154
155 if (mode->hdisplay < native_mode->panel_xres ||
156 mode->vdisplay < native_mode->panel_yres) {
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200157 if (ASIC_IS_AVIVO(rdev)) {
158 adjusted_mode->hdisplay = native_mode->panel_xres;
159 adjusted_mode->vdisplay = native_mode->panel_yres;
160 adjusted_mode->htotal = native_mode->panel_xres + native_mode->hblank;
161 adjusted_mode->hsync_start = native_mode->panel_xres + native_mode->hoverplus;
162 adjusted_mode->hsync_end = adjusted_mode->hsync_start + native_mode->hsync_width;
163 adjusted_mode->vtotal = native_mode->panel_yres + native_mode->vblank;
164 adjusted_mode->vsync_start = native_mode->panel_yres + native_mode->voverplus;
165 adjusted_mode->vsync_end = adjusted_mode->vsync_start + native_mode->vsync_width;
166 /* update crtc values */
167 drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
168 /* adjust crtc values */
169 adjusted_mode->crtc_hdisplay = native_mode->panel_xres;
170 adjusted_mode->crtc_vdisplay = native_mode->panel_yres;
171 adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + native_mode->hblank;
172 adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + native_mode->hoverplus;
173 adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + native_mode->hsync_width;
174 adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + native_mode->vblank;
175 adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + native_mode->voverplus;
176 adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + native_mode->vsync_width;
177 } else {
178 adjusted_mode->htotal = native_mode->panel_xres + native_mode->hblank;
179 adjusted_mode->hsync_start = native_mode->panel_xres + native_mode->hoverplus;
180 adjusted_mode->hsync_end = adjusted_mode->hsync_start + native_mode->hsync_width;
181 adjusted_mode->vtotal = native_mode->panel_yres + native_mode->vblank;
182 adjusted_mode->vsync_start = native_mode->panel_yres + native_mode->voverplus;
183 adjusted_mode->vsync_end = adjusted_mode->vsync_start + native_mode->vsync_width;
184 /* update crtc values */
185 drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
186 /* adjust crtc values */
187 adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + native_mode->hblank;
188 adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + native_mode->hoverplus;
189 adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + native_mode->hsync_width;
190 adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + native_mode->vblank;
191 adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + native_mode->voverplus;
192 adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + native_mode->vsync_width;
193 }
194 adjusted_mode->flags = native_mode->flags;
195 adjusted_mode->clock = native_mode->dotclock;
196 }
197}
198
Jerome Glissec93bb852009-07-13 21:04:08 +0200199
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200200static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
201 struct drm_display_mode *mode,
202 struct drm_display_mode *adjusted_mode)
203{
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200204 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
205
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200206 drm_mode_set_crtcinfo(adjusted_mode, 0);
207
208 if (radeon_encoder->rmx_type != RMX_OFF)
209 radeon_rmx_mode_fixup(encoder, mode, adjusted_mode);
210
211 /* hw bug */
212 if ((mode->flags & DRM_MODE_FLAG_INTERLACE)
213 && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))
214 adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
215
216 return true;
217}
218
219static void
220atombios_dac_setup(struct drm_encoder *encoder, int action)
221{
222 struct drm_device *dev = encoder->dev;
223 struct radeon_device *rdev = dev->dev_private;
224 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
225 DAC_ENCODER_CONTROL_PS_ALLOCATION args;
226 int index = 0, num = 0;
227 /* fixme - fill in enc_priv for atom dac */
228 enum radeon_tv_std tv_std = TV_STD_NTSC;
229
230 memset(&args, 0, sizeof(args));
231
232 switch (radeon_encoder->encoder_id) {
233 case ENCODER_OBJECT_ID_INTERNAL_DAC1:
234 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
235 index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);
236 num = 1;
237 break;
238 case ENCODER_OBJECT_ID_INTERNAL_DAC2:
239 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
240 index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);
241 num = 2;
242 break;
243 }
244
245 args.ucAction = action;
246
247 if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT))
248 args.ucDacStandard = ATOM_DAC1_PS2;
249 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
250 args.ucDacStandard = ATOM_DAC1_CV;
251 else {
252 switch (tv_std) {
253 case TV_STD_PAL:
254 case TV_STD_PAL_M:
255 case TV_STD_SCART_PAL:
256 case TV_STD_SECAM:
257 case TV_STD_PAL_CN:
258 args.ucDacStandard = ATOM_DAC1_PAL;
259 break;
260 case TV_STD_NTSC:
261 case TV_STD_NTSC_J:
262 case TV_STD_PAL_60:
263 default:
264 args.ucDacStandard = ATOM_DAC1_NTSC;
265 break;
266 }
267 }
268 args.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
269
270 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
271
272}
273
274static void
275atombios_tv_setup(struct drm_encoder *encoder, int action)
276{
277 struct drm_device *dev = encoder->dev;
278 struct radeon_device *rdev = dev->dev_private;
279 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
280 TV_ENCODER_CONTROL_PS_ALLOCATION args;
281 int index = 0;
282 /* fixme - fill in enc_priv for atom dac */
283 enum radeon_tv_std tv_std = TV_STD_NTSC;
284
285 memset(&args, 0, sizeof(args));
286
287 index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl);
288
289 args.sTVEncoder.ucAction = action;
290
291 if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
292 args.sTVEncoder.ucTvStandard = ATOM_TV_CV;
293 else {
294 switch (tv_std) {
295 case TV_STD_NTSC:
296 args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;
297 break;
298 case TV_STD_PAL:
299 args.sTVEncoder.ucTvStandard = ATOM_TV_PAL;
300 break;
301 case TV_STD_PAL_M:
302 args.sTVEncoder.ucTvStandard = ATOM_TV_PALM;
303 break;
304 case TV_STD_PAL_60:
305 args.sTVEncoder.ucTvStandard = ATOM_TV_PAL60;
306 break;
307 case TV_STD_NTSC_J:
308 args.sTVEncoder.ucTvStandard = ATOM_TV_NTSCJ;
309 break;
310 case TV_STD_SCART_PAL:
311 args.sTVEncoder.ucTvStandard = ATOM_TV_PAL; /* ??? */
312 break;
313 case TV_STD_SECAM:
314 args.sTVEncoder.ucTvStandard = ATOM_TV_SECAM;
315 break;
316 case TV_STD_PAL_CN:
317 args.sTVEncoder.ucTvStandard = ATOM_TV_PALCN;
318 break;
319 default:
320 args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;
321 break;
322 }
323 }
324
325 args.sTVEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
326
327 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
328
329}
330
331void
332atombios_external_tmds_setup(struct drm_encoder *encoder, int action)
333{
334 struct drm_device *dev = encoder->dev;
335 struct radeon_device *rdev = dev->dev_private;
336 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
337 ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION args;
338 int index = 0;
339
340 memset(&args, 0, sizeof(args));
341
342 index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
343
344 args.sXTmdsEncoder.ucEnable = action;
345
346 if (radeon_encoder->pixel_clock > 165000)
347 args.sXTmdsEncoder.ucMisc = PANEL_ENCODER_MISC_DUAL;
348
349 /*if (pScrn->rgbBits == 8)*/
350 args.sXTmdsEncoder.ucMisc |= (1 << 1);
351
352 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
353
354}
355
356static void
357atombios_ddia_setup(struct drm_encoder *encoder, int action)
358{
359 struct drm_device *dev = encoder->dev;
360 struct radeon_device *rdev = dev->dev_private;
361 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
362 DVO_ENCODER_CONTROL_PS_ALLOCATION args;
363 int index = 0;
364
365 memset(&args, 0, sizeof(args));
366
367 index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
368
369 args.sDVOEncoder.ucAction = action;
370 args.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
371
372 if (radeon_encoder->pixel_clock > 165000)
373 args.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = PANEL_ENCODER_MISC_DUAL;
374
375 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
376
377}
378
379union lvds_encoder_control {
380 LVDS_ENCODER_CONTROL_PS_ALLOCATION v1;
381 LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2;
382};
383
384static void
385atombios_digital_setup(struct drm_encoder *encoder, int action)
386{
387 struct drm_device *dev = encoder->dev;
388 struct radeon_device *rdev = dev->dev_private;
389 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
390 union lvds_encoder_control args;
391 int index = 0;
392 uint8_t frev, crev;
393 struct radeon_encoder_atom_dig *dig;
394 struct drm_connector *connector;
395 struct radeon_connector *radeon_connector;
396 struct radeon_connector_atom_dig *dig_connector;
397
398 connector = radeon_get_connector_for_encoder(encoder);
399 if (!connector)
400 return;
401
402 radeon_connector = to_radeon_connector(connector);
403
404 if (!radeon_encoder->enc_priv)
405 return;
406
407 dig = radeon_encoder->enc_priv;
408
409 if (!radeon_connector->con_priv)
410 return;
411
412 dig_connector = radeon_connector->con_priv;
413
414 memset(&args, 0, sizeof(args));
415
416 switch (radeon_encoder->encoder_id) {
417 case ENCODER_OBJECT_ID_INTERNAL_LVDS:
418 index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
419 break;
420 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
421 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
422 index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl);
423 break;
424 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
425 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
426 index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
427 else
428 index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl);
429 break;
430 }
431
432 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
433
434 switch (frev) {
435 case 1:
436 case 2:
437 switch (crev) {
438 case 1:
439 args.v1.ucMisc = 0;
440 args.v1.ucAction = action;
441 if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
442 args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
443 args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
444 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
445 if (dig->lvds_misc & (1 << 0))
446 args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
447 if (dig->lvds_misc & (1 << 1))
448 args.v1.ucMisc |= (1 << 1);
449 } else {
450 if (dig_connector->linkb)
451 args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
452 if (radeon_encoder->pixel_clock > 165000)
453 args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
454 /*if (pScrn->rgbBits == 8) */
455 args.v1.ucMisc |= (1 << 1);
456 }
457 break;
458 case 2:
459 case 3:
460 args.v2.ucMisc = 0;
461 args.v2.ucAction = action;
462 if (crev == 3) {
463 if (dig->coherent_mode)
464 args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT;
465 }
466 if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
467 args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
468 args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
469 args.v2.ucTruncate = 0;
470 args.v2.ucSpatial = 0;
471 args.v2.ucTemporal = 0;
472 args.v2.ucFRC = 0;
473 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
474 if (dig->lvds_misc & (1 << 0))
475 args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
476 if (dig->lvds_misc & (1 << 5)) {
477 args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN;
478 if (dig->lvds_misc & (1 << 1))
479 args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH;
480 }
481 if (dig->lvds_misc & (1 << 6)) {
482 args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN;
483 if (dig->lvds_misc & (1 << 1))
484 args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH;
485 if (((dig->lvds_misc >> 2) & 0x3) == 2)
486 args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4;
487 }
488 } else {
489 if (dig_connector->linkb)
490 args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
491 if (radeon_encoder->pixel_clock > 165000)
492 args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
493 }
494 break;
495 default:
496 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
497 break;
498 }
499 break;
500 default:
501 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
502 break;
503 }
504
505 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
506
507}
508
509int
510atombios_get_encoder_mode(struct drm_encoder *encoder)
511{
512 struct drm_connector *connector;
513 struct radeon_connector *radeon_connector;
514
515 connector = radeon_get_connector_for_encoder(encoder);
516 if (!connector)
517 return 0;
518
519 radeon_connector = to_radeon_connector(connector);
520
521 switch (connector->connector_type) {
522 case DRM_MODE_CONNECTOR_DVII:
523 if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
524 return ATOM_ENCODER_MODE_HDMI;
525 else if (radeon_connector->use_digital)
526 return ATOM_ENCODER_MODE_DVI;
527 else
528 return ATOM_ENCODER_MODE_CRT;
529 break;
530 case DRM_MODE_CONNECTOR_DVID:
531 case DRM_MODE_CONNECTOR_HDMIA:
532 case DRM_MODE_CONNECTOR_HDMIB:
533 default:
534 if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
535 return ATOM_ENCODER_MODE_HDMI;
536 else
537 return ATOM_ENCODER_MODE_DVI;
538 break;
539 case DRM_MODE_CONNECTOR_LVDS:
540 return ATOM_ENCODER_MODE_LVDS;
541 break;
542 case DRM_MODE_CONNECTOR_DisplayPort:
543 /*if (radeon_output->MonType == MT_DP)
544 return ATOM_ENCODER_MODE_DP;
545 else*/
546 if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
547 return ATOM_ENCODER_MODE_HDMI;
548 else
549 return ATOM_ENCODER_MODE_DVI;
550 break;
551 case CONNECTOR_DVI_A:
552 case CONNECTOR_VGA:
553 return ATOM_ENCODER_MODE_CRT;
554 break;
555 case CONNECTOR_STV:
556 case CONNECTOR_CTV:
557 case CONNECTOR_DIN:
558 /* fix me */
559 return ATOM_ENCODER_MODE_TV;
560 /*return ATOM_ENCODER_MODE_CV;*/
561 break;
562 }
563}
564
565static void
566atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
567{
568 struct drm_device *dev = encoder->dev;
569 struct radeon_device *rdev = dev->dev_private;
570 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
571 DIG_ENCODER_CONTROL_PS_ALLOCATION args;
572 int index = 0, num = 0;
573 uint8_t frev, crev;
574 struct radeon_encoder_atom_dig *dig;
575 struct drm_connector *connector;
576 struct radeon_connector *radeon_connector;
577 struct radeon_connector_atom_dig *dig_connector;
578
579 connector = radeon_get_connector_for_encoder(encoder);
580 if (!connector)
581 return;
582
583 radeon_connector = to_radeon_connector(connector);
584
585 if (!radeon_connector->con_priv)
586 return;
587
588 dig_connector = radeon_connector->con_priv;
589
590 if (!radeon_encoder->enc_priv)
591 return;
592
593 dig = radeon_encoder->enc_priv;
594
595 memset(&args, 0, sizeof(args));
596
597 if (ASIC_IS_DCE32(rdev)) {
598 if (dig->dig_block)
599 index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
600 else
601 index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
602 num = dig->dig_block + 1;
603 } else {
604 switch (radeon_encoder->encoder_id) {
605 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
606 index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
607 num = 1;
608 break;
609 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
610 index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
611 num = 2;
612 break;
613 }
614 }
615
616 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
617
618 args.ucAction = action;
619 args.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
620
621 if (ASIC_IS_DCE32(rdev)) {
622 switch (radeon_encoder->encoder_id) {
623 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
624 args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
625 break;
626 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
627 args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;
628 break;
629 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
630 args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
631 break;
632 }
633 } else {
634 switch (radeon_encoder->encoder_id) {
635 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
636 args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER1;
637 break;
638 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
639 args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER2;
640 break;
641 }
642 }
643
644 if (radeon_encoder->pixel_clock > 165000) {
645 args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B;
646 args.ucLaneNum = 8;
647 } else {
648 if (dig_connector->linkb)
649 args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
650 else
651 args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
652 args.ucLaneNum = 4;
653 }
654
655 args.ucEncoderMode = atombios_get_encoder_mode(encoder);
656
657 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
658
659}
660
661union dig_transmitter_control {
662 DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1;
663 DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2;
664};
665
666static void
667atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action)
668{
669 struct drm_device *dev = encoder->dev;
670 struct radeon_device *rdev = dev->dev_private;
671 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
672 union dig_transmitter_control args;
673 int index = 0, num = 0;
674 uint8_t frev, crev;
675 struct radeon_encoder_atom_dig *dig;
676 struct drm_connector *connector;
677 struct radeon_connector *radeon_connector;
678 struct radeon_connector_atom_dig *dig_connector;
679
680 connector = radeon_get_connector_for_encoder(encoder);
681 if (!connector)
682 return;
683
684 radeon_connector = to_radeon_connector(connector);
685
686 if (!radeon_encoder->enc_priv)
687 return;
688
689 dig = radeon_encoder->enc_priv;
690
691 if (!radeon_connector->con_priv)
692 return;
693
694 dig_connector = radeon_connector->con_priv;
695
696 memset(&args, 0, sizeof(args));
697
698 if (ASIC_IS_DCE32(rdev))
699 index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
700 else {
701 switch (radeon_encoder->encoder_id) {
702 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
703 index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl);
704 break;
705 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
706 index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl);
707 break;
708 }
709 }
710
711 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
712
713 args.v1.ucAction = action;
714
715 if (ASIC_IS_DCE32(rdev)) {
716 if (radeon_encoder->pixel_clock > 165000) {
717 args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock * 10 * 2) / 100);
718 args.v2.acConfig.fDualLinkConnector = 1;
719 } else {
720 args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock * 10 * 4) / 100);
721 }
722 if (dig->dig_block)
723 args.v2.acConfig.ucEncoderSel = 1;
724
725 switch (radeon_encoder->encoder_id) {
726 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
727 args.v2.acConfig.ucTransmitterSel = 0;
728 num = 0;
729 break;
730 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
731 args.v2.acConfig.ucTransmitterSel = 1;
732 num = 1;
733 break;
734 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
735 args.v2.acConfig.ucTransmitterSel = 2;
736 num = 2;
737 break;
738 }
739
740 if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
741 if (dig->coherent_mode)
742 args.v2.acConfig.fCoherentMode = 1;
743 }
744 } else {
745 args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
746 args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock) / 10);
747
748 switch (radeon_encoder->encoder_id) {
749 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
750 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
751 if (rdev->flags & RADEON_IS_IGP) {
752 if (radeon_encoder->pixel_clock > 165000) {
753 args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
754 ATOM_TRANSMITTER_CONFIG_LINKA_B);
755 if (dig_connector->igp_lane_info & 0x3)
756 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
757 else if (dig_connector->igp_lane_info & 0xc)
758 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
759 } else {
760 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
761 if (dig_connector->igp_lane_info & 0x1)
762 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
763 else if (dig_connector->igp_lane_info & 0x2)
764 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7;
765 else if (dig_connector->igp_lane_info & 0x4)
766 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11;
767 else if (dig_connector->igp_lane_info & 0x8)
768 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
769 }
770 } else {
771 if (radeon_encoder->pixel_clock > 165000)
772 args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
773 ATOM_TRANSMITTER_CONFIG_LINKA_B |
774 ATOM_TRANSMITTER_CONFIG_LANE_0_7);
775 else {
776 if (dig_connector->linkb)
777 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
778 else
779 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
780 }
781 }
782 break;
783 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
784 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
785 if (radeon_encoder->pixel_clock > 165000)
786 args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
787 ATOM_TRANSMITTER_CONFIG_LINKA_B |
788 ATOM_TRANSMITTER_CONFIG_LANE_0_7);
789 else {
790 if (dig_connector->linkb)
791 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
792 else
793 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
794 }
795 break;
796 }
797
798 if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
799 if (dig->coherent_mode)
800 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
801 }
802 }
803
804 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
805
806}
807
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200808static void
809atombios_yuv_setup(struct drm_encoder *encoder, bool enable)
810{
811 struct drm_device *dev = encoder->dev;
812 struct radeon_device *rdev = dev->dev_private;
813 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
814 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
815 ENABLE_YUV_PS_ALLOCATION args;
816 int index = GetIndexIntoMasterTable(COMMAND, EnableYUV);
817 uint32_t temp, reg;
818
819 memset(&args, 0, sizeof(args));
820
821 if (rdev->family >= CHIP_R600)
822 reg = R600_BIOS_3_SCRATCH;
823 else
824 reg = RADEON_BIOS_3_SCRATCH;
825
826 /* XXX: fix up scratch reg handling */
827 temp = RREG32(reg);
828 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
829 WREG32(reg, (ATOM_S3_TV1_ACTIVE |
830 (radeon_crtc->crtc_id << 18)));
831 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
832 WREG32(reg, (ATOM_S3_CV_ACTIVE | (radeon_crtc->crtc_id << 24)));
833 else
834 WREG32(reg, 0);
835
836 if (enable)
837 args.ucEnable = ATOM_ENABLE;
838 args.ucCRTC = radeon_crtc->crtc_id;
839
840 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
841
842 WREG32(reg, temp);
843}
844
845static void
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200846radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
847{
848 struct drm_device *dev = encoder->dev;
849 struct radeon_device *rdev = dev->dev_private;
850 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
851 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;
852 int index = 0;
853 bool is_dig = false;
854
855 memset(&args, 0, sizeof(args));
856
857 switch (radeon_encoder->encoder_id) {
858 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
859 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
860 index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl);
861 break;
862 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
863 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
864 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
865 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
866 is_dig = true;
867 break;
868 case ENCODER_OBJECT_ID_INTERNAL_DVO1:
869 case ENCODER_OBJECT_ID_INTERNAL_DDI:
870 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
871 index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
872 break;
873 case ENCODER_OBJECT_ID_INTERNAL_LVDS:
874 index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
875 break;
876 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
877 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
878 index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
879 else
880 index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl);
881 break;
882 case ENCODER_OBJECT_ID_INTERNAL_DAC1:
883 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
884 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
885 index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
886 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
887 index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
888 else
889 index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
890 break;
891 case ENCODER_OBJECT_ID_INTERNAL_DAC2:
892 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
893 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
894 index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
895 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
896 index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
897 else
898 index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
899 break;
900 }
901
902 if (is_dig) {
903 switch (mode) {
904 case DRM_MODE_DPMS_ON:
905 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE);
906 break;
907 case DRM_MODE_DPMS_STANDBY:
908 case DRM_MODE_DPMS_SUSPEND:
909 case DRM_MODE_DPMS_OFF:
910 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE);
911 break;
912 }
913 } else {
914 switch (mode) {
915 case DRM_MODE_DPMS_ON:
916 args.ucAction = ATOM_ENABLE;
917 break;
918 case DRM_MODE_DPMS_STANDBY:
919 case DRM_MODE_DPMS_SUSPEND:
920 case DRM_MODE_DPMS_OFF:
921 args.ucAction = ATOM_DISABLE;
922 break;
923 }
924 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
925 }
926 radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
927}
928
929union crtc_sourc_param {
930 SELECT_CRTC_SOURCE_PS_ALLOCATION v1;
931 SELECT_CRTC_SOURCE_PARAMETERS_V2 v2;
932};
933
934static void
935atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
936{
937 struct drm_device *dev = encoder->dev;
938 struct radeon_device *rdev = dev->dev_private;
939 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
940 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
941 union crtc_sourc_param args;
942 int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
943 uint8_t frev, crev;
944
945 memset(&args, 0, sizeof(args));
946
947 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
948
949 switch (frev) {
950 case 1:
951 switch (crev) {
952 case 1:
953 default:
954 if (ASIC_IS_AVIVO(rdev))
955 args.v1.ucCRTC = radeon_crtc->crtc_id;
956 else {
957 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) {
958 args.v1.ucCRTC = radeon_crtc->crtc_id;
959 } else {
960 args.v1.ucCRTC = radeon_crtc->crtc_id << 2;
961 }
962 }
963 switch (radeon_encoder->encoder_id) {
964 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
965 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
966 args.v1.ucDevice = ATOM_DEVICE_DFP1_INDEX;
967 break;
968 case ENCODER_OBJECT_ID_INTERNAL_LVDS:
969 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
970 if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT)
971 args.v1.ucDevice = ATOM_DEVICE_LCD1_INDEX;
972 else
973 args.v1.ucDevice = ATOM_DEVICE_DFP3_INDEX;
974 break;
975 case ENCODER_OBJECT_ID_INTERNAL_DVO1:
976 case ENCODER_OBJECT_ID_INTERNAL_DDI:
977 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
978 args.v1.ucDevice = ATOM_DEVICE_DFP2_INDEX;
979 break;
980 case ENCODER_OBJECT_ID_INTERNAL_DAC1:
981 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
982 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
983 args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;
984 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
985 args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;
986 else
987 args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX;
988 break;
989 case ENCODER_OBJECT_ID_INTERNAL_DAC2:
990 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
991 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
992 args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;
993 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
994 args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;
995 else
996 args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX;
997 break;
998 }
999 break;
1000 case 2:
1001 args.v2.ucCRTC = radeon_crtc->crtc_id;
1002 args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder);
1003 switch (radeon_encoder->encoder_id) {
1004 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
1005 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
1006 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
1007 if (ASIC_IS_DCE32(rdev)) {
1008 if (radeon_crtc->crtc_id)
1009 args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
1010 else
1011 args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
1012 } else
1013 args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
1014 break;
1015 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
1016 args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;
1017 break;
1018 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
1019 args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
1020 break;
1021 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
1022 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
1023 args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
1024 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
1025 args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
1026 else
1027 args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID;
1028 break;
1029 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
1030 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
1031 args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
1032 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
1033 args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
1034 else
1035 args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID;
1036 break;
1037 }
1038 break;
1039 }
1040 break;
1041 default:
1042 DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
1043 break;
1044 }
1045
1046 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
1047
1048}
1049
1050static void
1051atombios_apply_encoder_quirks(struct drm_encoder *encoder,
1052 struct drm_display_mode *mode)
1053{
1054 struct drm_device *dev = encoder->dev;
1055 struct radeon_device *rdev = dev->dev_private;
1056 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1057 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
1058
1059 /* Funky macbooks */
1060 if ((dev->pdev->device == 0x71C5) &&
1061 (dev->pdev->subsystem_vendor == 0x106b) &&
1062 (dev->pdev->subsystem_device == 0x0080)) {
1063 if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) {
1064 uint32_t lvtma_bit_depth_control = RREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL);
1065
1066 lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_TRUNCATE_EN;
1067 lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN;
1068
1069 WREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL, lvtma_bit_depth_control);
1070 }
1071 }
1072
1073 /* set scaler clears this on some chips */
1074 if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE))
1075 WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, AVIVO_D1MODE_INTERLEAVE_EN);
1076}
1077
1078static void
1079radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
1080 struct drm_display_mode *mode,
1081 struct drm_display_mode *adjusted_mode)
1082{
1083 struct drm_device *dev = encoder->dev;
1084 struct radeon_device *rdev = dev->dev_private;
1085 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1086 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
1087
1088 if (radeon_encoder->enc_priv) {
1089 struct radeon_encoder_atom_dig *dig;
1090
1091 dig = radeon_encoder->enc_priv;
1092 dig->dig_block = radeon_crtc->crtc_id;
1093 }
1094 radeon_encoder->pixel_clock = adjusted_mode->clock;
1095
1096 radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001097 atombios_set_encoder_crtc_source(encoder);
1098
1099 if (ASIC_IS_AVIVO(rdev)) {
1100 if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))
1101 atombios_yuv_setup(encoder, true);
1102 else
1103 atombios_yuv_setup(encoder, false);
1104 }
1105
1106 switch (radeon_encoder->encoder_id) {
1107 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
1108 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
1109 case ENCODER_OBJECT_ID_INTERNAL_LVDS:
1110 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
1111 atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_ENABLE);
1112 break;
1113 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
1114 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
1115 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
1116 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
1117 /* disable the encoder and transmitter */
1118 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE);
1119 atombios_dig_encoder_setup(encoder, ATOM_DISABLE);
1120
1121 /* setup and enable the encoder and transmitter */
1122 atombios_dig_encoder_setup(encoder, ATOM_ENABLE);
1123 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP);
1124 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE);
1125 break;
1126 case ENCODER_OBJECT_ID_INTERNAL_DDI:
1127 atombios_ddia_setup(encoder, ATOM_ENABLE);
1128 break;
1129 case ENCODER_OBJECT_ID_INTERNAL_DVO1:
1130 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
1131 atombios_external_tmds_setup(encoder, ATOM_ENABLE);
1132 break;
1133 case ENCODER_OBJECT_ID_INTERNAL_DAC1:
1134 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
1135 case ENCODER_OBJECT_ID_INTERNAL_DAC2:
1136 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
1137 atombios_dac_setup(encoder, ATOM_ENABLE);
1138 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
1139 atombios_tv_setup(encoder, ATOM_ENABLE);
1140 break;
1141 }
1142 atombios_apply_encoder_quirks(encoder, adjusted_mode);
1143}
1144
1145static bool
1146atombios_dac_load_detect(struct drm_encoder *encoder)
1147{
1148 struct drm_device *dev = encoder->dev;
1149 struct radeon_device *rdev = dev->dev_private;
1150 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1151
1152 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT |
1153 ATOM_DEVICE_CV_SUPPORT |
1154 ATOM_DEVICE_CRT_SUPPORT)) {
1155 DAC_LOAD_DETECTION_PS_ALLOCATION args;
1156 int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection);
1157 uint8_t frev, crev;
1158
1159 memset(&args, 0, sizeof(args));
1160
1161 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
1162
1163 args.sDacload.ucMisc = 0;
1164
1165 if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) ||
1166 (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1))
1167 args.sDacload.ucDacType = ATOM_DAC_A;
1168 else
1169 args.sDacload.ucDacType = ATOM_DAC_B;
1170
1171 if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT)
1172 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT);
1173 else if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT)
1174 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT);
1175 else if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) {
1176 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT);
1177 if (crev >= 3)
1178 args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
1179 } else if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) {
1180 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT);
1181 if (crev >= 3)
1182 args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
1183 }
1184
1185 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
1186
1187 return true;
1188 } else
1189 return false;
1190}
1191
1192static enum drm_connector_status
1193radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
1194{
1195 struct drm_device *dev = encoder->dev;
1196 struct radeon_device *rdev = dev->dev_private;
1197 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1198 uint32_t bios_0_scratch;
1199
1200 if (!atombios_dac_load_detect(encoder)) {
1201 DRM_DEBUG("detect returned false \n");
1202 return connector_status_unknown;
1203 }
1204
1205 if (rdev->family >= CHIP_R600)
1206 bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH);
1207 else
1208 bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH);
1209
1210 DRM_DEBUG("Bios 0 scratch %x\n", bios_0_scratch);
1211 if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) {
1212 if (bios_0_scratch & ATOM_S0_CRT1_MASK)
1213 return connector_status_connected;
1214 } else if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) {
1215 if (bios_0_scratch & ATOM_S0_CRT2_MASK)
1216 return connector_status_connected;
1217 } else if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) {
1218 if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A))
1219 return connector_status_connected;
1220 } else if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) {
1221 if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A))
1222 return connector_status_connected; /* CTV */
1223 else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A))
1224 return connector_status_connected; /* STV */
1225 }
1226 return connector_status_disconnected;
1227}
1228
1229static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
1230{
1231 radeon_atom_output_lock(encoder, true);
1232 radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
1233}
1234
1235static void radeon_atom_encoder_commit(struct drm_encoder *encoder)
1236{
1237 radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
1238 radeon_atom_output_lock(encoder, false);
1239}
1240
1241static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = {
1242 .dpms = radeon_atom_encoder_dpms,
1243 .mode_fixup = radeon_atom_mode_fixup,
1244 .prepare = radeon_atom_encoder_prepare,
1245 .mode_set = radeon_atom_encoder_mode_set,
1246 .commit = radeon_atom_encoder_commit,
1247 /* no detect for TMDS/LVDS yet */
1248};
1249
1250static const struct drm_encoder_helper_funcs radeon_atom_dac_helper_funcs = {
1251 .dpms = radeon_atom_encoder_dpms,
1252 .mode_fixup = radeon_atom_mode_fixup,
1253 .prepare = radeon_atom_encoder_prepare,
1254 .mode_set = radeon_atom_encoder_mode_set,
1255 .commit = radeon_atom_encoder_commit,
1256 .detect = radeon_atom_dac_detect,
1257};
1258
1259void radeon_enc_destroy(struct drm_encoder *encoder)
1260{
1261 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1262 kfree(radeon_encoder->enc_priv);
1263 drm_encoder_cleanup(encoder);
1264 kfree(radeon_encoder);
1265}
1266
1267static const struct drm_encoder_funcs radeon_atom_enc_funcs = {
1268 .destroy = radeon_enc_destroy,
1269};
1270
1271struct radeon_encoder_atom_dig *
1272radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder)
1273{
1274 struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL);
1275
1276 if (!dig)
1277 return NULL;
1278
1279 /* coherent mode by default */
1280 dig->coherent_mode = true;
1281
1282 return dig;
1283}
1284
1285void
1286radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device)
1287{
1288 struct drm_encoder *encoder;
1289 struct radeon_encoder *radeon_encoder;
1290
1291 /* see if we already added it */
1292 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
1293 radeon_encoder = to_radeon_encoder(encoder);
1294 if (radeon_encoder->encoder_id == encoder_id) {
1295 radeon_encoder->devices |= supported_device;
1296 return;
1297 }
1298
1299 }
1300
1301 /* add a new one */
1302 radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL);
1303 if (!radeon_encoder)
1304 return;
1305
1306 encoder = &radeon_encoder->base;
1307 encoder->possible_crtcs = 0x3;
1308 encoder->possible_clones = 0;
1309
1310 radeon_encoder->enc_priv = NULL;
1311
1312 radeon_encoder->encoder_id = encoder_id;
1313 radeon_encoder->devices = supported_device;
Jerome Glissec93bb852009-07-13 21:04:08 +02001314 radeon_encoder->rmx_type = RMX_OFF;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001315
1316 switch (radeon_encoder->encoder_id) {
1317 case ENCODER_OBJECT_ID_INTERNAL_LVDS:
1318 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
1319 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
1320 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
1321 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
1322 radeon_encoder->rmx_type = RMX_FULL;
1323 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
1324 radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder);
1325 } else {
1326 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
1327 radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
1328 }
1329 drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
1330 break;
1331 case ENCODER_OBJECT_ID_INTERNAL_DAC1:
1332 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
1333 drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);
1334 break;
1335 case ENCODER_OBJECT_ID_INTERNAL_DAC2:
1336 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
1337 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
1338 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TVDAC);
1339 drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);
1340 break;
1341 case ENCODER_OBJECT_ID_INTERNAL_DVO1:
1342 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
1343 case ENCODER_OBJECT_ID_INTERNAL_DDI:
1344 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
1345 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
1346 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
1347 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
Jerome Glissec93bb852009-07-13 21:04:08 +02001348 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
1349 radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001350 drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
1351 break;
1352 }
1353}