aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_encoders.c
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2009-06-05 08:42:42 -0400
committerDave Airlie <airlied@redhat.com>2009-06-14 22:01:53 -0400
commit771fe6b912fca54f03e8a72eb63058b582775362 (patch)
tree58aa5469ba8058c2b564d50807395ad6cd7bd7e4 /drivers/gpu/drm/radeon/radeon_encoders.c
parentba4e7d973dd09b66912ac4c0856add8b0703a997 (diff)
drm/radeon: introduce kernel modesetting for radeon hardware
Add kernel modesetting support to radeon driver, use the ttm memory manager to manage memory and DRM/GEM to provide userspace API. In order to avoid backward compatibility issue and to allow clean design and code the radeon kernel modesetting use different code path than old radeon/drm driver. When kernel modesetting is enabled the IOCTL of radeon/drm driver are considered as invalid and an error message is printed in the log and they return failure. KMS enabled userspace will use new API to talk with the radeon/drm driver. The new API provide functions to create/destroy/share/mmap buffer object which are then managed by the kernel memory manager (here TTM). In order to submit command to the GPU the userspace provide a buffer holding the command stream, along this buffer userspace have to provide a list of buffer object used by the command stream. The kernel radeon driver will then place buffer in GPU accessible memory and will update command stream to reflect the position of the different buffers. The kernel will also perform security check on command stream provided by the user, we want to catch and forbid any illegal use of the GPU such as DMA into random system memory or into memory not owned by the process supplying the command stream. This part of the code is still incomplete and this why we propose that patch as a staging driver addition, future security might forbid current experimental userspace to run. This code support the following hardware : R1XX,R2XX,R3XX,R4XX,R5XX (radeon up to X1950). Works is underway to provide support for R6XX, R7XX and newer hardware (radeon from HD2XXX to HD4XXX). Authors: Jerome Glisse <jglisse@redhat.com> Dave Airlie <airlied@redhat.com> Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com> Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_encoders.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c1708
1 files changed, 1708 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
new file mode 100644
index 000000000000..c8ef0d14ffab
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -0,0 +1,1708 @@
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}