]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/gpu/drm/radeon/radeon_encoders.c
drm/radeon: introduce kernel modesetting for radeon hardware
[net-next-2.6.git] / drivers / gpu / drm / radeon / radeon_encoders.c
CommitLineData
771fe6b9
JG
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.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) {
157 radeon_encoder->flags |= RADEON_USE_RMX;
158 if (ASIC_IS_AVIVO(rdev)) {
159 adjusted_mode->hdisplay = native_mode->panel_xres;
160 adjusted_mode->vdisplay = native_mode->panel_yres;
161 adjusted_mode->htotal = native_mode->panel_xres + native_mode->hblank;
162 adjusted_mode->hsync_start = native_mode->panel_xres + native_mode->hoverplus;
163 adjusted_mode->hsync_end = adjusted_mode->hsync_start + native_mode->hsync_width;
164 adjusted_mode->vtotal = native_mode->panel_yres + native_mode->vblank;
165 adjusted_mode->vsync_start = native_mode->panel_yres + native_mode->voverplus;
166 adjusted_mode->vsync_end = adjusted_mode->vsync_start + native_mode->vsync_width;
167 /* update crtc values */
168 drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
169 /* adjust crtc values */
170 adjusted_mode->crtc_hdisplay = native_mode->panel_xres;
171 adjusted_mode->crtc_vdisplay = native_mode->panel_yres;
172 adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + native_mode->hblank;
173 adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + native_mode->hoverplus;
174 adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + native_mode->hsync_width;
175 adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + native_mode->vblank;
176 adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + native_mode->voverplus;
177 adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + native_mode->vsync_width;
178 } else {
179 adjusted_mode->htotal = native_mode->panel_xres + native_mode->hblank;
180 adjusted_mode->hsync_start = native_mode->panel_xres + native_mode->hoverplus;
181 adjusted_mode->hsync_end = adjusted_mode->hsync_start + native_mode->hsync_width;
182 adjusted_mode->vtotal = native_mode->panel_yres + native_mode->vblank;
183 adjusted_mode->vsync_start = native_mode->panel_yres + native_mode->voverplus;
184 adjusted_mode->vsync_end = adjusted_mode->vsync_start + native_mode->vsync_width;
185 /* update crtc values */
186 drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
187 /* adjust crtc values */
188 adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + native_mode->hblank;
189 adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + native_mode->hoverplus;
190 adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + native_mode->hsync_width;
191 adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + native_mode->vblank;
192 adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + native_mode->voverplus;
193 adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + native_mode->vsync_width;
194 }
195 adjusted_mode->flags = native_mode->flags;
196 adjusted_mode->clock = native_mode->dotclock;
197 }
198}
199
200static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
201 struct drm_display_mode *mode,
202 struct drm_display_mode *adjusted_mode)
203{
204
205 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
206
207 radeon_encoder->flags &= ~RADEON_USE_RMX;
208
209 drm_mode_set_crtcinfo(adjusted_mode, 0);
210
211 if (radeon_encoder->rmx_type != RMX_OFF)
212 radeon_rmx_mode_fixup(encoder, mode, adjusted_mode);
213
214 /* hw bug */
215 if ((mode->flags & DRM_MODE_FLAG_INTERLACE)
216 && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))
217 adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
218
219 return true;
220}
221
222static void
223atombios_dac_setup(struct drm_encoder *encoder, int action)
224{
225 struct drm_device *dev = encoder->dev;
226 struct radeon_device *rdev = dev->dev_private;
227 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
228 DAC_ENCODER_CONTROL_PS_ALLOCATION args;
229 int index = 0, num = 0;
230 /* fixme - fill in enc_priv for atom dac */
231 enum radeon_tv_std tv_std = TV_STD_NTSC;
232
233 memset(&args, 0, sizeof(args));
234
235 switch (radeon_encoder->encoder_id) {
236 case ENCODER_OBJECT_ID_INTERNAL_DAC1:
237 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
238 index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);
239 num = 1;
240 break;
241 case ENCODER_OBJECT_ID_INTERNAL_DAC2:
242 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
243 index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);
244 num = 2;
245 break;
246 }
247
248 args.ucAction = action;
249
250 if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT))
251 args.ucDacStandard = ATOM_DAC1_PS2;
252 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
253 args.ucDacStandard = ATOM_DAC1_CV;
254 else {
255 switch (tv_std) {
256 case TV_STD_PAL:
257 case TV_STD_PAL_M:
258 case TV_STD_SCART_PAL:
259 case TV_STD_SECAM:
260 case TV_STD_PAL_CN:
261 args.ucDacStandard = ATOM_DAC1_PAL;
262 break;
263 case TV_STD_NTSC:
264 case TV_STD_NTSC_J:
265 case TV_STD_PAL_60:
266 default:
267 args.ucDacStandard = ATOM_DAC1_NTSC;
268 break;
269 }
270 }
271 args.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
272
273 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
274
275}
276
277static void
278atombios_tv_setup(struct drm_encoder *encoder, int action)
279{
280 struct drm_device *dev = encoder->dev;
281 struct radeon_device *rdev = dev->dev_private;
282 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
283 TV_ENCODER_CONTROL_PS_ALLOCATION args;
284 int index = 0;
285 /* fixme - fill in enc_priv for atom dac */
286 enum radeon_tv_std tv_std = TV_STD_NTSC;
287
288 memset(&args, 0, sizeof(args));
289
290 index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl);
291
292 args.sTVEncoder.ucAction = action;
293
294 if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
295 args.sTVEncoder.ucTvStandard = ATOM_TV_CV;
296 else {
297 switch (tv_std) {
298 case TV_STD_NTSC:
299 args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;
300 break;
301 case TV_STD_PAL:
302 args.sTVEncoder.ucTvStandard = ATOM_TV_PAL;
303 break;
304 case TV_STD_PAL_M:
305 args.sTVEncoder.ucTvStandard = ATOM_TV_PALM;
306 break;
307 case TV_STD_PAL_60:
308 args.sTVEncoder.ucTvStandard = ATOM_TV_PAL60;
309 break;
310 case TV_STD_NTSC_J:
311 args.sTVEncoder.ucTvStandard = ATOM_TV_NTSCJ;
312 break;
313 case TV_STD_SCART_PAL:
314 args.sTVEncoder.ucTvStandard = ATOM_TV_PAL; /* ??? */
315 break;
316 case TV_STD_SECAM:
317 args.sTVEncoder.ucTvStandard = ATOM_TV_SECAM;
318 break;
319 case TV_STD_PAL_CN:
320 args.sTVEncoder.ucTvStandard = ATOM_TV_PALCN;
321 break;
322 default:
323 args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;
324 break;
325 }
326 }
327
328 args.sTVEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
329
330 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
331
332}
333
334void
335atombios_external_tmds_setup(struct drm_encoder *encoder, int action)
336{
337 struct drm_device *dev = encoder->dev;
338 struct radeon_device *rdev = dev->dev_private;
339 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
340 ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION args;
341 int index = 0;
342
343 memset(&args, 0, sizeof(args));
344
345 index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
346
347 args.sXTmdsEncoder.ucEnable = action;
348
349 if (radeon_encoder->pixel_clock > 165000)
350 args.sXTmdsEncoder.ucMisc = PANEL_ENCODER_MISC_DUAL;
351
352 /*if (pScrn->rgbBits == 8)*/
353 args.sXTmdsEncoder.ucMisc |= (1 << 1);
354
355 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
356
357}
358
359static void
360atombios_ddia_setup(struct drm_encoder *encoder, int action)
361{
362 struct drm_device *dev = encoder->dev;
363 struct radeon_device *rdev = dev->dev_private;
364 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
365 DVO_ENCODER_CONTROL_PS_ALLOCATION args;
366 int index = 0;
367
368 memset(&args, 0, sizeof(args));
369
370 index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
371
372 args.sDVOEncoder.ucAction = action;
373 args.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
374
375 if (radeon_encoder->pixel_clock > 165000)
376 args.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = PANEL_ENCODER_MISC_DUAL;
377
378 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
379
380}
381
382union lvds_encoder_control {
383 LVDS_ENCODER_CONTROL_PS_ALLOCATION v1;
384 LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2;
385};
386
387static void
388atombios_digital_setup(struct drm_encoder *encoder, int action)
389{
390 struct drm_device *dev = encoder->dev;
391 struct radeon_device *rdev = dev->dev_private;
392 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
393 union lvds_encoder_control args;
394 int index = 0;
395 uint8_t frev, crev;
396 struct radeon_encoder_atom_dig *dig;
397 struct drm_connector *connector;
398 struct radeon_connector *radeon_connector;
399 struct radeon_connector_atom_dig *dig_connector;
400
401 connector = radeon_get_connector_for_encoder(encoder);
402 if (!connector)
403 return;
404
405 radeon_connector = to_radeon_connector(connector);
406
407 if (!radeon_encoder->enc_priv)
408 return;
409
410 dig = radeon_encoder->enc_priv;
411
412 if (!radeon_connector->con_priv)
413 return;
414
415 dig_connector = radeon_connector->con_priv;
416
417 memset(&args, 0, sizeof(args));
418
419 switch (radeon_encoder->encoder_id) {
420 case ENCODER_OBJECT_ID_INTERNAL_LVDS:
421 index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
422 break;
423 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
424 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
425 index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl);
426 break;
427 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
428 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
429 index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
430 else
431 index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl);
432 break;
433 }
434
435 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
436
437 switch (frev) {
438 case 1:
439 case 2:
440 switch (crev) {
441 case 1:
442 args.v1.ucMisc = 0;
443 args.v1.ucAction = action;
444 if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
445 args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
446 args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
447 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
448 if (dig->lvds_misc & (1 << 0))
449 args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
450 if (dig->lvds_misc & (1 << 1))
451 args.v1.ucMisc |= (1 << 1);
452 } else {
453 if (dig_connector->linkb)
454 args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
455 if (radeon_encoder->pixel_clock > 165000)
456 args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
457 /*if (pScrn->rgbBits == 8) */
458 args.v1.ucMisc |= (1 << 1);
459 }
460 break;
461 case 2:
462 case 3:
463 args.v2.ucMisc = 0;
464 args.v2.ucAction = action;
465 if (crev == 3) {
466 if (dig->coherent_mode)
467 args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT;
468 }
469 if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
470 args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
471 args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
472 args.v2.ucTruncate = 0;
473 args.v2.ucSpatial = 0;
474 args.v2.ucTemporal = 0;
475 args.v2.ucFRC = 0;
476 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
477 if (dig->lvds_misc & (1 << 0))
478 args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
479 if (dig->lvds_misc & (1 << 5)) {
480 args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN;
481 if (dig->lvds_misc & (1 << 1))
482 args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH;
483 }
484 if (dig->lvds_misc & (1 << 6)) {
485 args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN;
486 if (dig->lvds_misc & (1 << 1))
487 args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH;
488 if (((dig->lvds_misc >> 2) & 0x3) == 2)
489 args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4;
490 }
491 } else {
492 if (dig_connector->linkb)
493 args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
494 if (radeon_encoder->pixel_clock > 165000)
495 args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
496 }
497 break;
498 default:
499 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
500 break;
501 }
502 break;
503 default:
504 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
505 break;
506 }
507
508 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
509
510}
511
512int
513atombios_get_encoder_mode(struct drm_encoder *encoder)
514{
515 struct drm_connector *connector;
516 struct radeon_connector *radeon_connector;
517
518 connector = radeon_get_connector_for_encoder(encoder);
519 if (!connector)
520 return 0;
521
522 radeon_connector = to_radeon_connector(connector);
523
524 switch (connector->connector_type) {
525 case DRM_MODE_CONNECTOR_DVII:
526 if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
527 return ATOM_ENCODER_MODE_HDMI;
528 else if (radeon_connector->use_digital)
529 return ATOM_ENCODER_MODE_DVI;
530 else
531 return ATOM_ENCODER_MODE_CRT;
532 break;
533 case DRM_MODE_CONNECTOR_DVID:
534 case DRM_MODE_CONNECTOR_HDMIA:
535 case DRM_MODE_CONNECTOR_HDMIB:
536 default:
537 if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
538 return ATOM_ENCODER_MODE_HDMI;
539 else
540 return ATOM_ENCODER_MODE_DVI;
541 break;
542 case DRM_MODE_CONNECTOR_LVDS:
543 return ATOM_ENCODER_MODE_LVDS;
544 break;
545 case DRM_MODE_CONNECTOR_DisplayPort:
546 /*if (radeon_output->MonType == MT_DP)
547 return ATOM_ENCODER_MODE_DP;
548 else*/
549 if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
550 return ATOM_ENCODER_MODE_HDMI;
551 else
552 return ATOM_ENCODER_MODE_DVI;
553 break;
554 case CONNECTOR_DVI_A:
555 case CONNECTOR_VGA:
556 return ATOM_ENCODER_MODE_CRT;
557 break;
558 case CONNECTOR_STV:
559 case CONNECTOR_CTV:
560 case CONNECTOR_DIN:
561 /* fix me */
562 return ATOM_ENCODER_MODE_TV;
563 /*return ATOM_ENCODER_MODE_CV;*/
564 break;
565 }
566}
567
568static void
569atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
570{
571 struct drm_device *dev = encoder->dev;
572 struct radeon_device *rdev = dev->dev_private;
573 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
574 DIG_ENCODER_CONTROL_PS_ALLOCATION args;
575 int index = 0, num = 0;
576 uint8_t frev, crev;
577 struct radeon_encoder_atom_dig *dig;
578 struct drm_connector *connector;
579 struct radeon_connector *radeon_connector;
580 struct radeon_connector_atom_dig *dig_connector;
581
582 connector = radeon_get_connector_for_encoder(encoder);
583 if (!connector)
584 return;
585
586 radeon_connector = to_radeon_connector(connector);
587
588 if (!radeon_connector->con_priv)
589 return;
590
591 dig_connector = radeon_connector->con_priv;
592
593 if (!radeon_encoder->enc_priv)
594 return;
595
596 dig = radeon_encoder->enc_priv;
597
598 memset(&args, 0, sizeof(args));
599
600 if (ASIC_IS_DCE32(rdev)) {
601 if (dig->dig_block)
602 index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
603 else
604 index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
605 num = dig->dig_block + 1;
606 } else {
607 switch (radeon_encoder->encoder_id) {
608 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
609 index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
610 num = 1;
611 break;
612 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
613 index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
614 num = 2;
615 break;
616 }
617 }
618
619 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
620
621 args.ucAction = action;
622 args.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
623
624 if (ASIC_IS_DCE32(rdev)) {
625 switch (radeon_encoder->encoder_id) {
626 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
627 args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
628 break;
629 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
630 args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;
631 break;
632 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
633 args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
634 break;
635 }
636 } else {
637 switch (radeon_encoder->encoder_id) {
638 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
639 args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER1;
640 break;
641 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
642 args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER2;
643 break;
644 }
645 }
646
647 if (radeon_encoder->pixel_clock > 165000) {
648 args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B;
649 args.ucLaneNum = 8;
650 } else {
651 if (dig_connector->linkb)
652 args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
653 else
654 args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
655 args.ucLaneNum = 4;
656 }
657
658 args.ucEncoderMode = atombios_get_encoder_mode(encoder);
659
660 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
661
662}
663
664union dig_transmitter_control {
665 DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1;
666 DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2;
667};
668
669static void
670atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action)
671{
672 struct drm_device *dev = encoder->dev;
673 struct radeon_device *rdev = dev->dev_private;
674 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
675 union dig_transmitter_control args;
676 int index = 0, num = 0;
677 uint8_t frev, crev;
678 struct radeon_encoder_atom_dig *dig;
679 struct drm_connector *connector;
680 struct radeon_connector *radeon_connector;
681 struct radeon_connector_atom_dig *dig_connector;
682
683 connector = radeon_get_connector_for_encoder(encoder);
684 if (!connector)
685 return;
686
687 radeon_connector = to_radeon_connector(connector);
688
689 if (!radeon_encoder->enc_priv)
690 return;
691
692 dig = radeon_encoder->enc_priv;
693
694 if (!radeon_connector->con_priv)
695 return;
696
697 dig_connector = radeon_connector->con_priv;
698
699 memset(&args, 0, sizeof(args));
700
701 if (ASIC_IS_DCE32(rdev))
702 index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
703 else {
704 switch (radeon_encoder->encoder_id) {
705 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
706 index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl);
707 break;
708 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
709 index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl);
710 break;
711 }
712 }
713
714 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
715
716 args.v1.ucAction = action;
717
718 if (ASIC_IS_DCE32(rdev)) {
719 if (radeon_encoder->pixel_clock > 165000) {
720 args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock * 10 * 2) / 100);
721 args.v2.acConfig.fDualLinkConnector = 1;
722 } else {
723 args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock * 10 * 4) / 100);
724 }
725 if (dig->dig_block)
726 args.v2.acConfig.ucEncoderSel = 1;
727
728 switch (radeon_encoder->encoder_id) {
729 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
730 args.v2.acConfig.ucTransmitterSel = 0;
731 num = 0;
732 break;
733 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
734 args.v2.acConfig.ucTransmitterSel = 1;
735 num = 1;
736 break;
737 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
738 args.v2.acConfig.ucTransmitterSel = 2;
739 num = 2;
740 break;
741 }
742
743 if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
744 if (dig->coherent_mode)
745 args.v2.acConfig.fCoherentMode = 1;
746 }
747 } else {
748 args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
749 args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock) / 10);
750
751 switch (radeon_encoder->encoder_id) {
752 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
753 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
754 if (rdev->flags & RADEON_IS_IGP) {
755 if (radeon_encoder->pixel_clock > 165000) {
756 args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
757 ATOM_TRANSMITTER_CONFIG_LINKA_B);
758 if (dig_connector->igp_lane_info & 0x3)
759 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
760 else if (dig_connector->igp_lane_info & 0xc)
761 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
762 } else {
763 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
764 if (dig_connector->igp_lane_info & 0x1)
765 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
766 else if (dig_connector->igp_lane_info & 0x2)
767 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7;
768 else if (dig_connector->igp_lane_info & 0x4)
769 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11;
770 else if (dig_connector->igp_lane_info & 0x8)
771 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
772 }
773 } else {
774 if (radeon_encoder->pixel_clock > 165000)
775 args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
776 ATOM_TRANSMITTER_CONFIG_LINKA_B |
777 ATOM_TRANSMITTER_CONFIG_LANE_0_7);
778 else {
779 if (dig_connector->linkb)
780 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
781 else
782 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
783 }
784 }
785 break;
786 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
787 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
788 if (radeon_encoder->pixel_clock > 165000)
789 args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
790 ATOM_TRANSMITTER_CONFIG_LINKA_B |
791 ATOM_TRANSMITTER_CONFIG_LANE_0_7);
792 else {
793 if (dig_connector->linkb)
794 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
795 else
796 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
797 }
798 break;
799 }
800
801 if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
802 if (dig->coherent_mode)
803 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
804 }
805 }
806
807 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
808
809}
810
811static void atom_rv515_force_tv_scaler(struct radeon_device *rdev)
812{
813
814 WREG32(0x659C, 0x0);
815 WREG32(0x6594, 0x705);
816 WREG32(0x65A4, 0x10001);
817 WREG32(0x65D8, 0x0);
818 WREG32(0x65B0, 0x0);
819 WREG32(0x65C0, 0x0);
820 WREG32(0x65D4, 0x0);
821 WREG32(0x6578, 0x0);
822 WREG32(0x657C, 0x841880A8);
823 WREG32(0x6578, 0x1);
824 WREG32(0x657C, 0x84208680);
825 WREG32(0x6578, 0x2);
826 WREG32(0x657C, 0xBFF880B0);
827 WREG32(0x6578, 0x100);
828 WREG32(0x657C, 0x83D88088);
829 WREG32(0x6578, 0x101);
830 WREG32(0x657C, 0x84608680);
831 WREG32(0x6578, 0x102);
832 WREG32(0x657C, 0xBFF080D0);
833 WREG32(0x6578, 0x200);
834 WREG32(0x657C, 0x83988068);
835 WREG32(0x6578, 0x201);
836 WREG32(0x657C, 0x84A08680);
837 WREG32(0x6578, 0x202);
838 WREG32(0x657C, 0xBFF080F8);
839 WREG32(0x6578, 0x300);
840 WREG32(0x657C, 0x83588058);
841 WREG32(0x6578, 0x301);
842 WREG32(0x657C, 0x84E08660);
843 WREG32(0x6578, 0x302);
844 WREG32(0x657C, 0xBFF88120);
845 WREG32(0x6578, 0x400);
846 WREG32(0x657C, 0x83188040);
847 WREG32(0x6578, 0x401);
848 WREG32(0x657C, 0x85008660);
849 WREG32(0x6578, 0x402);
850 WREG32(0x657C, 0xBFF88150);
851 WREG32(0x6578, 0x500);
852 WREG32(0x657C, 0x82D88030);
853 WREG32(0x6578, 0x501);
854 WREG32(0x657C, 0x85408640);
855 WREG32(0x6578, 0x502);
856 WREG32(0x657C, 0xBFF88180);
857 WREG32(0x6578, 0x600);
858 WREG32(0x657C, 0x82A08018);
859 WREG32(0x6578, 0x601);
860 WREG32(0x657C, 0x85808620);
861 WREG32(0x6578, 0x602);
862 WREG32(0x657C, 0xBFF081B8);
863 WREG32(0x6578, 0x700);
864 WREG32(0x657C, 0x82608010);
865 WREG32(0x6578, 0x701);
866 WREG32(0x657C, 0x85A08600);
867 WREG32(0x6578, 0x702);
868 WREG32(0x657C, 0x800081F0);
869 WREG32(0x6578, 0x800);
870 WREG32(0x657C, 0x8228BFF8);
871 WREG32(0x6578, 0x801);
872 WREG32(0x657C, 0x85E085E0);
873 WREG32(0x6578, 0x802);
874 WREG32(0x657C, 0xBFF88228);
875 WREG32(0x6578, 0x10000);
876 WREG32(0x657C, 0x82A8BF00);
877 WREG32(0x6578, 0x10001);
878 WREG32(0x657C, 0x82A08CC0);
879 WREG32(0x6578, 0x10002);
880 WREG32(0x657C, 0x8008BEF8);
881 WREG32(0x6578, 0x10100);
882 WREG32(0x657C, 0x81F0BF28);
883 WREG32(0x6578, 0x10101);
884 WREG32(0x657C, 0x83608CA0);
885 WREG32(0x6578, 0x10102);
886 WREG32(0x657C, 0x8018BED0);
887 WREG32(0x6578, 0x10200);
888 WREG32(0x657C, 0x8148BF38);
889 WREG32(0x6578, 0x10201);
890 WREG32(0x657C, 0x84408C80);
891 WREG32(0x6578, 0x10202);
892 WREG32(0x657C, 0x8008BEB8);
893 WREG32(0x6578, 0x10300);
894 WREG32(0x657C, 0x80B0BF78);
895 WREG32(0x6578, 0x10301);
896 WREG32(0x657C, 0x85008C20);
897 WREG32(0x6578, 0x10302);
898 WREG32(0x657C, 0x8020BEA0);
899 WREG32(0x6578, 0x10400);
900 WREG32(0x657C, 0x8028BF90);
901 WREG32(0x6578, 0x10401);
902 WREG32(0x657C, 0x85E08BC0);
903 WREG32(0x6578, 0x10402);
904 WREG32(0x657C, 0x8018BE90);
905 WREG32(0x6578, 0x10500);
906 WREG32(0x657C, 0xBFB8BFB0);
907 WREG32(0x6578, 0x10501);
908 WREG32(0x657C, 0x86C08B40);
909 WREG32(0x6578, 0x10502);
910 WREG32(0x657C, 0x8010BE90);
911 WREG32(0x6578, 0x10600);
912 WREG32(0x657C, 0xBF58BFC8);
913 WREG32(0x6578, 0x10601);
914 WREG32(0x657C, 0x87A08AA0);
915 WREG32(0x6578, 0x10602);
916 WREG32(0x657C, 0x8010BE98);
917 WREG32(0x6578, 0x10700);
918 WREG32(0x657C, 0xBF10BFF0);
919 WREG32(0x6578, 0x10701);
920 WREG32(0x657C, 0x886089E0);
921 WREG32(0x6578, 0x10702);
922 WREG32(0x657C, 0x8018BEB0);
923 WREG32(0x6578, 0x10800);
924 WREG32(0x657C, 0xBED8BFE8);
925 WREG32(0x6578, 0x10801);
926 WREG32(0x657C, 0x89408940);
927 WREG32(0x6578, 0x10802);
928 WREG32(0x657C, 0xBFE8BED8);
929 WREG32(0x6578, 0x20000);
930 WREG32(0x657C, 0x80008000);
931 WREG32(0x6578, 0x20001);
932 WREG32(0x657C, 0x90008000);
933 WREG32(0x6578, 0x20002);
934 WREG32(0x657C, 0x80008000);
935 WREG32(0x6578, 0x20003);
936 WREG32(0x657C, 0x80008000);
937 WREG32(0x6578, 0x20100);
938 WREG32(0x657C, 0x80108000);
939 WREG32(0x6578, 0x20101);
940 WREG32(0x657C, 0x8FE0BF70);
941 WREG32(0x6578, 0x20102);
942 WREG32(0x657C, 0xBFE880C0);
943 WREG32(0x6578, 0x20103);
944 WREG32(0x657C, 0x80008000);
945 WREG32(0x6578, 0x20200);
946 WREG32(0x657C, 0x8018BFF8);
947 WREG32(0x6578, 0x20201);
948 WREG32(0x657C, 0x8F80BF08);
949 WREG32(0x6578, 0x20202);
950 WREG32(0x657C, 0xBFD081A0);
951 WREG32(0x6578, 0x20203);
952 WREG32(0x657C, 0xBFF88000);
953 WREG32(0x6578, 0x20300);
954 WREG32(0x657C, 0x80188000);
955 WREG32(0x6578, 0x20301);
956 WREG32(0x657C, 0x8EE0BEC0);
957 WREG32(0x6578, 0x20302);
958 WREG32(0x657C, 0xBFB082A0);
959 WREG32(0x6578, 0x20303);
960 WREG32(0x657C, 0x80008000);
961 WREG32(0x6578, 0x20400);
962 WREG32(0x657C, 0x80188000);
963 WREG32(0x6578, 0x20401);
964 WREG32(0x657C, 0x8E00BEA0);
965 WREG32(0x6578, 0x20402);
966 WREG32(0x657C, 0xBF8883C0);
967 WREG32(0x6578, 0x20403);
968 WREG32(0x657C, 0x80008000);
969 WREG32(0x6578, 0x20500);
970 WREG32(0x657C, 0x80188000);
971 WREG32(0x6578, 0x20501);
972 WREG32(0x657C, 0x8D00BE90);
973 WREG32(0x6578, 0x20502);
974 WREG32(0x657C, 0xBF588500);
975 WREG32(0x6578, 0x20503);
976 WREG32(0x657C, 0x80008008);
977 WREG32(0x6578, 0x20600);
978 WREG32(0x657C, 0x80188000);
979 WREG32(0x6578, 0x20601);
980 WREG32(0x657C, 0x8BC0BE98);
981 WREG32(0x6578, 0x20602);
982 WREG32(0x657C, 0xBF308660);
983 WREG32(0x6578, 0x20603);
984 WREG32(0x657C, 0x80008008);
985 WREG32(0x6578, 0x20700);
986 WREG32(0x657C, 0x80108000);
987 WREG32(0x6578, 0x20701);
988 WREG32(0x657C, 0x8A80BEB0);
989 WREG32(0x6578, 0x20702);
990 WREG32(0x657C, 0xBF0087C0);
991 WREG32(0x6578, 0x20703);
992 WREG32(0x657C, 0x80008008);
993 WREG32(0x6578, 0x20800);
994 WREG32(0x657C, 0x80108000);
995 WREG32(0x6578, 0x20801);
996 WREG32(0x657C, 0x8920BED0);
997 WREG32(0x6578, 0x20802);
998 WREG32(0x657C, 0xBED08920);
999 WREG32(0x6578, 0x20803);
1000 WREG32(0x657C, 0x80008010);
1001 WREG32(0x6578, 0x30000);
1002 WREG32(0x657C, 0x90008000);
1003 WREG32(0x6578, 0x30001);
1004 WREG32(0x657C, 0x80008000);
1005 WREG32(0x6578, 0x30100);
1006 WREG32(0x657C, 0x8FE0BF90);
1007 WREG32(0x6578, 0x30101);
1008 WREG32(0x657C, 0xBFF880A0);
1009 WREG32(0x6578, 0x30200);
1010 WREG32(0x657C, 0x8F60BF40);
1011 WREG32(0x6578, 0x30201);
1012 WREG32(0x657C, 0xBFE88180);
1013 WREG32(0x6578, 0x30300);
1014 WREG32(0x657C, 0x8EC0BF00);
1015 WREG32(0x6578, 0x30301);
1016 WREG32(0x657C, 0xBFC88280);
1017 WREG32(0x6578, 0x30400);
1018 WREG32(0x657C, 0x8DE0BEE0);
1019 WREG32(0x6578, 0x30401);
1020 WREG32(0x657C, 0xBFA083A0);
1021 WREG32(0x6578, 0x30500);
1022 WREG32(0x657C, 0x8CE0BED0);
1023 WREG32(0x6578, 0x30501);
1024 WREG32(0x657C, 0xBF7884E0);
1025 WREG32(0x6578, 0x30600);
1026 WREG32(0x657C, 0x8BA0BED8);
1027 WREG32(0x6578, 0x30601);
1028 WREG32(0x657C, 0xBF508640);
1029 WREG32(0x6578, 0x30700);
1030 WREG32(0x657C, 0x8A60BEE8);
1031 WREG32(0x6578, 0x30701);
1032 WREG32(0x657C, 0xBF2087A0);
1033 WREG32(0x6578, 0x30800);
1034 WREG32(0x657C, 0x8900BF00);
1035 WREG32(0x6578, 0x30801);
1036 WREG32(0x657C, 0xBF008900);
1037}
1038
1039static void
1040atombios_yuv_setup(struct drm_encoder *encoder, bool enable)
1041{
1042 struct drm_device *dev = encoder->dev;
1043 struct radeon_device *rdev = dev->dev_private;
1044 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1045 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
1046 ENABLE_YUV_PS_ALLOCATION args;
1047 int index = GetIndexIntoMasterTable(COMMAND, EnableYUV);
1048 uint32_t temp, reg;
1049
1050 memset(&args, 0, sizeof(args));
1051
1052 if (rdev->family >= CHIP_R600)
1053 reg = R600_BIOS_3_SCRATCH;
1054 else
1055 reg = RADEON_BIOS_3_SCRATCH;
1056
1057 /* XXX: fix up scratch reg handling */
1058 temp = RREG32(reg);
1059 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
1060 WREG32(reg, (ATOM_S3_TV1_ACTIVE |
1061 (radeon_crtc->crtc_id << 18)));
1062 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
1063 WREG32(reg, (ATOM_S3_CV_ACTIVE | (radeon_crtc->crtc_id << 24)));
1064 else
1065 WREG32(reg, 0);
1066
1067 if (enable)
1068 args.ucEnable = ATOM_ENABLE;
1069 args.ucCRTC = radeon_crtc->crtc_id;
1070
1071 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
1072
1073 WREG32(reg, temp);
1074}
1075
1076static void
1077atombios_overscan_setup(struct drm_encoder *encoder,
1078 struct drm_display_mode *mode,
1079 struct drm_display_mode *adjusted_mode)
1080{
1081 struct drm_device *dev = encoder->dev;
1082 struct radeon_device *rdev = dev->dev_private;
1083 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1084 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
1085 SET_CRTC_OVERSCAN_PS_ALLOCATION args;
1086 int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_OverScan);
1087
1088 memset(&args, 0, sizeof(args));
1089
1090 args.usOverscanRight = 0;
1091 args.usOverscanLeft = 0;
1092 args.usOverscanBottom = 0;
1093 args.usOverscanTop = 0;
1094 args.ucCRTC = radeon_crtc->crtc_id;
1095
1096 if (radeon_encoder->flags & RADEON_USE_RMX) {
1097 if (radeon_encoder->rmx_type == RMX_FULL) {
1098 args.usOverscanRight = 0;
1099 args.usOverscanLeft = 0;
1100 args.usOverscanBottom = 0;
1101 args.usOverscanTop = 0;
1102 } else if (radeon_encoder->rmx_type == RMX_CENTER) {
1103 args.usOverscanTop = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2;
1104 args.usOverscanBottom = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2;
1105 args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2;
1106 args.usOverscanRight = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2;
1107 } else if (radeon_encoder->rmx_type == RMX_ASPECT) {
1108 int a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay;
1109 int a2 = adjusted_mode->crtc_vdisplay * mode->crtc_hdisplay;
1110
1111 if (a1 > a2) {
1112 args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2;
1113 args.usOverscanRight = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2;
1114 } else if (a2 > a1) {
1115 args.usOverscanLeft = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2;
1116 args.usOverscanRight = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2;
1117 }
1118 }
1119 }
1120
1121 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
1122
1123}
1124
1125static void
1126atombios_scaler_setup(struct drm_encoder *encoder)
1127{
1128 struct drm_device *dev = encoder->dev;
1129 struct radeon_device *rdev = dev->dev_private;
1130 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1131 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
1132 ENABLE_SCALER_PS_ALLOCATION args;
1133 int index = GetIndexIntoMasterTable(COMMAND, EnableScaler);
1134 /* fixme - fill in enc_priv for atom dac */
1135 enum radeon_tv_std tv_std = TV_STD_NTSC;
1136
1137 if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id)
1138 return;
1139
1140 memset(&args, 0, sizeof(args));
1141
1142 args.ucScaler = radeon_crtc->crtc_id;
1143
1144 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) {
1145 switch (tv_std) {
1146 case TV_STD_NTSC:
1147 default:
1148 args.ucTVStandard = ATOM_TV_NTSC;
1149 break;
1150 case TV_STD_PAL:
1151 args.ucTVStandard = ATOM_TV_PAL;
1152 break;
1153 case TV_STD_PAL_M:
1154 args.ucTVStandard = ATOM_TV_PALM;
1155 break;
1156 case TV_STD_PAL_60:
1157 args.ucTVStandard = ATOM_TV_PAL60;
1158 break;
1159 case TV_STD_NTSC_J:
1160 args.ucTVStandard = ATOM_TV_NTSCJ;
1161 break;
1162 case TV_STD_SCART_PAL:
1163 args.ucTVStandard = ATOM_TV_PAL; /* ??? */
1164 break;
1165 case TV_STD_SECAM:
1166 args.ucTVStandard = ATOM_TV_SECAM;
1167 break;
1168 case TV_STD_PAL_CN:
1169 args.ucTVStandard = ATOM_TV_PALCN;
1170 break;
1171 }
1172 args.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
1173 } else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) {
1174 args.ucTVStandard = ATOM_TV_CV;
1175 args.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
1176 } else if (radeon_encoder->flags & RADEON_USE_RMX) {
1177 if (radeon_encoder->rmx_type == RMX_FULL)
1178 args.ucEnable = ATOM_SCALER_EXPANSION;
1179 else if (radeon_encoder->rmx_type == RMX_CENTER)
1180 args.ucEnable = ATOM_SCALER_CENTER;
1181 else if (radeon_encoder->rmx_type == RMX_ASPECT)
1182 args.ucEnable = ATOM_SCALER_EXPANSION;
1183 } else {
1184 if (ASIC_IS_AVIVO(rdev))
1185 args.ucEnable = ATOM_SCALER_DISABLE;
1186 else
1187 args.ucEnable = ATOM_SCALER_CENTER;
1188 }
1189
1190 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
1191
1192 if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)
1193 && rdev->family >= CHIP_RV515 && rdev->family <= CHIP_RV570) {
1194 atom_rv515_force_tv_scaler(rdev);
1195 }
1196
1197}
1198
1199static void
1200radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
1201{
1202 struct drm_device *dev = encoder->dev;
1203 struct radeon_device *rdev = dev->dev_private;
1204 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1205 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;
1206 int index = 0;
1207 bool is_dig = false;
1208
1209 memset(&args, 0, sizeof(args));
1210
1211 switch (radeon_encoder->encoder_id) {
1212 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
1213 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
1214 index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl);
1215 break;
1216 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
1217 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
1218 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
1219 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
1220 is_dig = true;
1221 break;
1222 case ENCODER_OBJECT_ID_INTERNAL_DVO1:
1223 case ENCODER_OBJECT_ID_INTERNAL_DDI:
1224 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
1225 index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
1226 break;
1227 case ENCODER_OBJECT_ID_INTERNAL_LVDS:
1228 index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
1229 break;
1230 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
1231 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
1232 index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
1233 else
1234 index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl);
1235 break;
1236 case ENCODER_OBJECT_ID_INTERNAL_DAC1:
1237 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
1238 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
1239 index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
1240 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
1241 index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
1242 else
1243 index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
1244 break;
1245 case ENCODER_OBJECT_ID_INTERNAL_DAC2:
1246 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
1247 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
1248 index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
1249 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
1250 index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
1251 else
1252 index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
1253 break;
1254 }
1255
1256 if (is_dig) {
1257 switch (mode) {
1258 case DRM_MODE_DPMS_ON:
1259 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE);
1260 break;
1261 case DRM_MODE_DPMS_STANDBY:
1262 case DRM_MODE_DPMS_SUSPEND:
1263 case DRM_MODE_DPMS_OFF:
1264 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE);
1265 break;
1266 }
1267 } else {
1268 switch (mode) {
1269 case DRM_MODE_DPMS_ON:
1270 args.ucAction = ATOM_ENABLE;
1271 break;
1272 case DRM_MODE_DPMS_STANDBY:
1273 case DRM_MODE_DPMS_SUSPEND:
1274 case DRM_MODE_DPMS_OFF:
1275 args.ucAction = ATOM_DISABLE;
1276 break;
1277 }
1278 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
1279 }
1280 radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
1281}
1282
1283union crtc_sourc_param {
1284 SELECT_CRTC_SOURCE_PS_ALLOCATION v1;
1285 SELECT_CRTC_SOURCE_PARAMETERS_V2 v2;
1286};
1287
1288static void
1289atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
1290{
1291 struct drm_device *dev = encoder->dev;
1292 struct radeon_device *rdev = dev->dev_private;
1293 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1294 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
1295 union crtc_sourc_param args;
1296 int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
1297 uint8_t frev, crev;
1298
1299 memset(&args, 0, sizeof(args));
1300
1301 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
1302
1303 switch (frev) {
1304 case 1:
1305 switch (crev) {
1306 case 1:
1307 default:
1308 if (ASIC_IS_AVIVO(rdev))
1309 args.v1.ucCRTC = radeon_crtc->crtc_id;
1310 else {
1311 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) {
1312 args.v1.ucCRTC = radeon_crtc->crtc_id;
1313 } else {
1314 args.v1.ucCRTC = radeon_crtc->crtc_id << 2;
1315 }
1316 }
1317 switch (radeon_encoder->encoder_id) {
1318 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
1319 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
1320 args.v1.ucDevice = ATOM_DEVICE_DFP1_INDEX;
1321 break;
1322 case ENCODER_OBJECT_ID_INTERNAL_LVDS:
1323 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
1324 if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT)
1325 args.v1.ucDevice = ATOM_DEVICE_LCD1_INDEX;
1326 else
1327 args.v1.ucDevice = ATOM_DEVICE_DFP3_INDEX;
1328 break;
1329 case ENCODER_OBJECT_ID_INTERNAL_DVO1:
1330 case ENCODER_OBJECT_ID_INTERNAL_DDI:
1331 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
1332 args.v1.ucDevice = ATOM_DEVICE_DFP2_INDEX;
1333 break;
1334 case ENCODER_OBJECT_ID_INTERNAL_DAC1:
1335 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
1336 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
1337 args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;
1338 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
1339 args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;
1340 else
1341 args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX;
1342 break;
1343 case ENCODER_OBJECT_ID_INTERNAL_DAC2:
1344 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
1345 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
1346 args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;
1347 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
1348 args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;
1349 else
1350 args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX;
1351 break;
1352 }
1353 break;
1354 case 2:
1355 args.v2.ucCRTC = radeon_crtc->crtc_id;
1356 args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder);
1357 switch (radeon_encoder->encoder_id) {
1358 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
1359 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
1360 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
1361 if (ASIC_IS_DCE32(rdev)) {
1362 if (radeon_crtc->crtc_id)
1363 args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
1364 else
1365 args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
1366 } else
1367 args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
1368 break;
1369 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
1370 args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;
1371 break;
1372 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
1373 args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
1374 break;
1375 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
1376 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
1377 args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
1378 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
1379 args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
1380 else
1381 args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID;
1382 break;
1383 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
1384 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
1385 args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
1386 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
1387 args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
1388 else
1389 args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID;
1390 break;
1391 }
1392 break;
1393 }
1394 break;
1395 default:
1396 DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
1397 break;
1398 }
1399
1400 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
1401
1402}
1403
1404static void
1405atombios_apply_encoder_quirks(struct drm_encoder *encoder,
1406 struct drm_display_mode *mode)
1407{
1408 struct drm_device *dev = encoder->dev;
1409 struct radeon_device *rdev = dev->dev_private;
1410 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1411 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
1412
1413 /* Funky macbooks */
1414 if ((dev->pdev->device == 0x71C5) &&
1415 (dev->pdev->subsystem_vendor == 0x106b) &&
1416 (dev->pdev->subsystem_device == 0x0080)) {
1417 if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) {
1418 uint32_t lvtma_bit_depth_control = RREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL);
1419
1420 lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_TRUNCATE_EN;
1421 lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN;
1422
1423 WREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL, lvtma_bit_depth_control);
1424 }
1425 }
1426
1427 /* set scaler clears this on some chips */
1428 if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE))
1429 WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, AVIVO_D1MODE_INTERLEAVE_EN);
1430}
1431
1432static void
1433radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
1434 struct drm_display_mode *mode,
1435 struct drm_display_mode *adjusted_mode)
1436{
1437 struct drm_device *dev = encoder->dev;
1438 struct radeon_device *rdev = dev->dev_private;
1439 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1440 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
1441
1442 if (radeon_encoder->enc_priv) {
1443 struct radeon_encoder_atom_dig *dig;
1444
1445 dig = radeon_encoder->enc_priv;
1446 dig->dig_block = radeon_crtc->crtc_id;
1447 }
1448 radeon_encoder->pixel_clock = adjusted_mode->clock;
1449
1450 radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
1451 atombios_overscan_setup(encoder, mode, adjusted_mode);
1452 atombios_scaler_setup(encoder);
1453 atombios_set_encoder_crtc_source(encoder);
1454
1455 if (ASIC_IS_AVIVO(rdev)) {
1456 if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))
1457 atombios_yuv_setup(encoder, true);
1458 else
1459 atombios_yuv_setup(encoder, false);
1460 }
1461
1462 switch (radeon_encoder->encoder_id) {
1463 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
1464 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
1465 case ENCODER_OBJECT_ID_INTERNAL_LVDS:
1466 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
1467 atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_ENABLE);
1468 break;
1469 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
1470 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
1471 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
1472 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
1473 /* disable the encoder and transmitter */
1474 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE);
1475 atombios_dig_encoder_setup(encoder, ATOM_DISABLE);
1476
1477 /* setup and enable the encoder and transmitter */
1478 atombios_dig_encoder_setup(encoder, ATOM_ENABLE);
1479 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP);
1480 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE);
1481 break;
1482 case ENCODER_OBJECT_ID_INTERNAL_DDI:
1483 atombios_ddia_setup(encoder, ATOM_ENABLE);
1484 break;
1485 case ENCODER_OBJECT_ID_INTERNAL_DVO1:
1486 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
1487 atombios_external_tmds_setup(encoder, ATOM_ENABLE);
1488 break;
1489 case ENCODER_OBJECT_ID_INTERNAL_DAC1:
1490 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
1491 case ENCODER_OBJECT_ID_INTERNAL_DAC2:
1492 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
1493 atombios_dac_setup(encoder, ATOM_ENABLE);
1494 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
1495 atombios_tv_setup(encoder, ATOM_ENABLE);
1496 break;
1497 }
1498 atombios_apply_encoder_quirks(encoder, adjusted_mode);
1499}
1500
1501static bool
1502atombios_dac_load_detect(struct drm_encoder *encoder)
1503{
1504 struct drm_device *dev = encoder->dev;
1505 struct radeon_device *rdev = dev->dev_private;
1506 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1507
1508 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT |
1509 ATOM_DEVICE_CV_SUPPORT |
1510 ATOM_DEVICE_CRT_SUPPORT)) {
1511 DAC_LOAD_DETECTION_PS_ALLOCATION args;
1512 int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection);
1513 uint8_t frev, crev;
1514
1515 memset(&args, 0, sizeof(args));
1516
1517 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
1518
1519 args.sDacload.ucMisc = 0;
1520
1521 if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) ||
1522 (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1))
1523 args.sDacload.ucDacType = ATOM_DAC_A;
1524 else
1525 args.sDacload.ucDacType = ATOM_DAC_B;
1526
1527 if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT)
1528 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT);
1529 else if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT)
1530 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT);
1531 else if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) {
1532 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT);
1533 if (crev >= 3)
1534 args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
1535 } else if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) {
1536 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT);
1537 if (crev >= 3)
1538 args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
1539 }
1540
1541 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
1542
1543 return true;
1544 } else
1545 return false;
1546}
1547
1548static enum drm_connector_status
1549radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
1550{
1551 struct drm_device *dev = encoder->dev;
1552 struct radeon_device *rdev = dev->dev_private;
1553 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1554 uint32_t bios_0_scratch;
1555
1556 if (!atombios_dac_load_detect(encoder)) {
1557 DRM_DEBUG("detect returned false \n");
1558 return connector_status_unknown;
1559 }
1560
1561 if (rdev->family >= CHIP_R600)
1562 bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH);
1563 else
1564 bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH);
1565
1566 DRM_DEBUG("Bios 0 scratch %x\n", bios_0_scratch);
1567 if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) {
1568 if (bios_0_scratch & ATOM_S0_CRT1_MASK)
1569 return connector_status_connected;
1570 } else if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) {
1571 if (bios_0_scratch & ATOM_S0_CRT2_MASK)
1572 return connector_status_connected;
1573 } else if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) {
1574 if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A))
1575 return connector_status_connected;
1576 } else if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) {
1577 if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A))
1578 return connector_status_connected; /* CTV */
1579 else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A))
1580 return connector_status_connected; /* STV */
1581 }
1582 return connector_status_disconnected;
1583}
1584
1585static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
1586{
1587 radeon_atom_output_lock(encoder, true);
1588 radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
1589}
1590
1591static void radeon_atom_encoder_commit(struct drm_encoder *encoder)
1592{
1593 radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
1594 radeon_atom_output_lock(encoder, false);
1595}
1596
1597static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = {
1598 .dpms = radeon_atom_encoder_dpms,
1599 .mode_fixup = radeon_atom_mode_fixup,
1600 .prepare = radeon_atom_encoder_prepare,
1601 .mode_set = radeon_atom_encoder_mode_set,
1602 .commit = radeon_atom_encoder_commit,
1603 /* no detect for TMDS/LVDS yet */
1604};
1605
1606static const struct drm_encoder_helper_funcs radeon_atom_dac_helper_funcs = {
1607 .dpms = radeon_atom_encoder_dpms,
1608 .mode_fixup = radeon_atom_mode_fixup,
1609 .prepare = radeon_atom_encoder_prepare,
1610 .mode_set = radeon_atom_encoder_mode_set,
1611 .commit = radeon_atom_encoder_commit,
1612 .detect = radeon_atom_dac_detect,
1613};
1614
1615void radeon_enc_destroy(struct drm_encoder *encoder)
1616{
1617 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1618 kfree(radeon_encoder->enc_priv);
1619 drm_encoder_cleanup(encoder);
1620 kfree(radeon_encoder);
1621}
1622
1623static const struct drm_encoder_funcs radeon_atom_enc_funcs = {
1624 .destroy = radeon_enc_destroy,
1625};
1626
1627struct radeon_encoder_atom_dig *
1628radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder)
1629{
1630 struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL);
1631
1632 if (!dig)
1633 return NULL;
1634
1635 /* coherent mode by default */
1636 dig->coherent_mode = true;
1637
1638 return dig;
1639}
1640
1641void
1642radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device)
1643{
1644 struct drm_encoder *encoder;
1645 struct radeon_encoder *radeon_encoder;
1646
1647 /* see if we already added it */
1648 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
1649 radeon_encoder = to_radeon_encoder(encoder);
1650 if (radeon_encoder->encoder_id == encoder_id) {
1651 radeon_encoder->devices |= supported_device;
1652 return;
1653 }
1654
1655 }
1656
1657 /* add a new one */
1658 radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL);
1659 if (!radeon_encoder)
1660 return;
1661
1662 encoder = &radeon_encoder->base;
1663 encoder->possible_crtcs = 0x3;
1664 encoder->possible_clones = 0;
1665
1666 radeon_encoder->enc_priv = NULL;
1667
1668 radeon_encoder->encoder_id = encoder_id;
1669 radeon_encoder->devices = supported_device;
1670
1671 switch (radeon_encoder->encoder_id) {
1672 case ENCODER_OBJECT_ID_INTERNAL_LVDS:
1673 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
1674 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
1675 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
1676 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
1677 radeon_encoder->rmx_type = RMX_FULL;
1678 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
1679 radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder);
1680 } else {
1681 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
1682 radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
1683 }
1684 drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
1685 break;
1686 case ENCODER_OBJECT_ID_INTERNAL_DAC1:
1687 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
1688 drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);
1689 break;
1690 case ENCODER_OBJECT_ID_INTERNAL_DAC2:
1691 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
1692 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
1693 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TVDAC);
1694 drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);
1695 break;
1696 case ENCODER_OBJECT_ID_INTERNAL_DVO1:
1697 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
1698 case ENCODER_OBJECT_ID_INTERNAL_DDI:
1699 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
1700 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
1701 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
1702 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
1703 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
1704 radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
1705 drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
1706 break;
1707 }
1708}