blob: 9322675ef6d0158806ae7a4123ed927a3c2402da [file] [log] [blame]
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001/*
2 * Copyright 2007-8 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors: Dave Airlie
24 * Alex Deucher
25 */
26#include "drmP.h"
27#include "drm_crtc_helper.h"
28#include "radeon_drm.h"
29#include "radeon.h"
30#include "atom.h"
31
32
Jerome Glisse771fe6b2009-06-05 14:42:42 +020033static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode)
34{
35 struct drm_device *dev = encoder->dev;
36 struct radeon_device *rdev = dev->dev_private;
37 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
38 uint32_t lvds_gen_cntl, lvds_pll_cntl, pixclks_cntl, disp_pwr_man;
39 int panel_pwr_delay = 2000;
40 DRM_DEBUG("\n");
41
42 if (radeon_encoder->enc_priv) {
43 if (rdev->is_atom_bios) {
44 struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv;
45 panel_pwr_delay = lvds->panel_pwr_delay;
46 } else {
47 struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv;
48 panel_pwr_delay = lvds->panel_pwr_delay;
49 }
50 }
51
52 switch (mode) {
53 case DRM_MODE_DPMS_ON:
54 disp_pwr_man = RREG32(RADEON_DISP_PWR_MAN);
55 disp_pwr_man |= RADEON_AUTO_PWRUP_EN;
56 WREG32(RADEON_DISP_PWR_MAN, disp_pwr_man);
57 lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL);
58 lvds_pll_cntl |= RADEON_LVDS_PLL_EN;
59 WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl);
60 udelay(1000);
61
62 lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL);
63 lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET;
64 WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl);
65
66 lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
67 lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_EN | RADEON_LVDS_DIGON | RADEON_LVDS_BLON);
68 lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
69 udelay(panel_pwr_delay * 1000);
70 WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
71 break;
72 case DRM_MODE_DPMS_STANDBY:
73 case DRM_MODE_DPMS_SUSPEND:
74 case DRM_MODE_DPMS_OFF:
75 pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL);
76 WREG32_PLL_P(RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
77 lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
78 lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
79 lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON);
80 udelay(panel_pwr_delay * 1000);
81 WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
82 WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
83 break;
84 }
85
86 if (rdev->is_atom_bios)
87 radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
88 else
89 radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
90}
91
92static void radeon_legacy_lvds_prepare(struct drm_encoder *encoder)
93{
94 struct radeon_device *rdev = encoder->dev->dev_private;
95
96 if (rdev->is_atom_bios)
97 radeon_atom_output_lock(encoder, true);
98 else
99 radeon_combios_output_lock(encoder, true);
100 radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF);
101}
102
103static void radeon_legacy_lvds_commit(struct drm_encoder *encoder)
104{
105 struct radeon_device *rdev = encoder->dev->dev_private;
106
107 radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_ON);
108 if (rdev->is_atom_bios)
109 radeon_atom_output_lock(encoder, false);
110 else
111 radeon_combios_output_lock(encoder, false);
112}
113
114static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder,
115 struct drm_display_mode *mode,
116 struct drm_display_mode *adjusted_mode)
117{
118 struct drm_device *dev = encoder->dev;
119 struct radeon_device *rdev = dev->dev_private;
120 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
121 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
122 uint32_t lvds_pll_cntl, lvds_gen_cntl, lvds_ss_gen_cntl;
123
124 DRM_DEBUG("\n");
125
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200126 lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL);
127 lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN;
128
129 lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL);
130 if ((!rdev->is_atom_bios)) {
131 struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv;
132 if (lvds) {
133 DRM_DEBUG("bios LVDS_GEN_CNTL: 0x%x\n", lvds->lvds_gen_cntl);
134 lvds_gen_cntl = lvds->lvds_gen_cntl;
135 lvds_ss_gen_cntl &= ~((0xf << RADEON_LVDS_PWRSEQ_DELAY1_SHIFT) |
136 (0xf << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT));
137 lvds_ss_gen_cntl |= ((lvds->panel_digon_delay << RADEON_LVDS_PWRSEQ_DELAY1_SHIFT) |
138 (lvds->panel_blon_delay << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT));
139 } else
140 lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
141 } else
142 lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
143 lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
144 lvds_gen_cntl &= ~(RADEON_LVDS_ON |
145 RADEON_LVDS_BLON |
146 RADEON_LVDS_EN |
147 RADEON_LVDS_RST_FM);
148
149 if (ASIC_IS_R300(rdev))
150 lvds_pll_cntl &= ~(R300_LVDS_SRC_SEL_MASK);
151
152 if (radeon_crtc->crtc_id == 0) {
153 if (ASIC_IS_R300(rdev)) {
Jerome Glissec93bb852009-07-13 21:04:08 +0200154 if (radeon_encoder->rmx_type != RMX_OFF)
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200155 lvds_pll_cntl |= R300_LVDS_SRC_SEL_RMX;
156 } else
157 lvds_gen_cntl &= ~RADEON_LVDS_SEL_CRTC2;
158 } else {
159 if (ASIC_IS_R300(rdev))
160 lvds_pll_cntl |= R300_LVDS_SRC_SEL_CRTC2;
161 else
162 lvds_gen_cntl |= RADEON_LVDS_SEL_CRTC2;
163 }
164
165 WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
166 WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl);
167 WREG32(RADEON_LVDS_SS_GEN_CNTL, lvds_ss_gen_cntl);
168
169 if (rdev->family == CHIP_RV410)
170 WREG32(RADEON_CLOCK_CNTL_INDEX, 0);
171
172 if (rdev->is_atom_bios)
173 radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
174 else
175 radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
176}
177
178static bool radeon_legacy_lvds_mode_fixup(struct drm_encoder *encoder,
179 struct drm_display_mode *mode,
180 struct drm_display_mode *adjusted_mode)
181{
182 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
183
184 drm_mode_set_crtcinfo(adjusted_mode, 0);
185
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200186 if (radeon_encoder->rmx_type != RMX_OFF)
187 radeon_rmx_mode_fixup(encoder, mode, adjusted_mode);
188
189 return true;
190}
191
192static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = {
193 .dpms = radeon_legacy_lvds_dpms,
194 .mode_fixup = radeon_legacy_lvds_mode_fixup,
195 .prepare = radeon_legacy_lvds_prepare,
196 .mode_set = radeon_legacy_lvds_mode_set,
197 .commit = radeon_legacy_lvds_commit,
198};
199
200
201static const struct drm_encoder_funcs radeon_legacy_lvds_enc_funcs = {
202 .destroy = radeon_enc_destroy,
203};
204
205static bool radeon_legacy_primary_dac_mode_fixup(struct drm_encoder *encoder,
206 struct drm_display_mode *mode,
207 struct drm_display_mode *adjusted_mode)
208{
209
210 drm_mode_set_crtcinfo(adjusted_mode, 0);
211
212 return true;
213}
214
215static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode)
216{
217 struct drm_device *dev = encoder->dev;
218 struct radeon_device *rdev = dev->dev_private;
219 uint32_t crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL);
220 uint32_t dac_cntl = RREG32(RADEON_DAC_CNTL);
221 uint32_t dac_macro_cntl = RREG32(RADEON_DAC_MACRO_CNTL);
222
223 DRM_DEBUG("\n");
224
225 switch (mode) {
226 case DRM_MODE_DPMS_ON:
227 crtc_ext_cntl |= RADEON_CRTC_CRT_ON;
228 dac_cntl &= ~RADEON_DAC_PDWN;
229 dac_macro_cntl &= ~(RADEON_DAC_PDWN_R |
230 RADEON_DAC_PDWN_G |
231 RADEON_DAC_PDWN_B);
232 break;
233 case DRM_MODE_DPMS_STANDBY:
234 case DRM_MODE_DPMS_SUSPEND:
235 case DRM_MODE_DPMS_OFF:
236 crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON;
237 dac_cntl |= RADEON_DAC_PDWN;
238 dac_macro_cntl |= (RADEON_DAC_PDWN_R |
239 RADEON_DAC_PDWN_G |
240 RADEON_DAC_PDWN_B);
241 break;
242 }
243
244 WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
245 WREG32(RADEON_DAC_CNTL, dac_cntl);
246 WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
247
248 if (rdev->is_atom_bios)
249 radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
250 else
251 radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
252}
253
254static void radeon_legacy_primary_dac_prepare(struct drm_encoder *encoder)
255{
256 struct radeon_device *rdev = encoder->dev->dev_private;
257
258 if (rdev->is_atom_bios)
259 radeon_atom_output_lock(encoder, true);
260 else
261 radeon_combios_output_lock(encoder, true);
262 radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF);
263}
264
265static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder)
266{
267 struct radeon_device *rdev = encoder->dev->dev_private;
268
269 radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_ON);
270
271 if (rdev->is_atom_bios)
272 radeon_atom_output_lock(encoder, false);
273 else
274 radeon_combios_output_lock(encoder, false);
275}
276
277static void radeon_legacy_primary_dac_mode_set(struct drm_encoder *encoder,
278 struct drm_display_mode *mode,
279 struct drm_display_mode *adjusted_mode)
280{
281 struct drm_device *dev = encoder->dev;
282 struct radeon_device *rdev = dev->dev_private;
283 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
284 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
285 uint32_t disp_output_cntl, dac_cntl, dac2_cntl, dac_macro_cntl;
286
287 DRM_DEBUG("\n");
288
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200289 if (radeon_crtc->crtc_id == 0) {
290 if (rdev->family == CHIP_R200 || ASIC_IS_R300(rdev)) {
291 disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL) &
292 ~(RADEON_DISP_DAC_SOURCE_MASK);
293 WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
294 } else {
295 dac2_cntl = RREG32(RADEON_DAC_CNTL2) & ~(RADEON_DAC2_DAC_CLK_SEL);
296 WREG32(RADEON_DAC_CNTL2, dac2_cntl);
297 }
298 } else {
299 if (rdev->family == CHIP_R200 || ASIC_IS_R300(rdev)) {
300 disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL) &
301 ~(RADEON_DISP_DAC_SOURCE_MASK);
302 disp_output_cntl |= RADEON_DISP_DAC_SOURCE_CRTC2;
303 WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
304 } else {
305 dac2_cntl = RREG32(RADEON_DAC_CNTL2) | RADEON_DAC2_DAC_CLK_SEL;
306 WREG32(RADEON_DAC_CNTL2, dac2_cntl);
307 }
308 }
309
310 dac_cntl = (RADEON_DAC_MASK_ALL |
311 RADEON_DAC_VGA_ADR_EN |
312 /* TODO 6-bits */
313 RADEON_DAC_8BIT_EN);
314
315 WREG32_P(RADEON_DAC_CNTL,
316 dac_cntl,
317 RADEON_DAC_RANGE_CNTL |
318 RADEON_DAC_BLANKING);
319
320 if (radeon_encoder->enc_priv) {
321 struct radeon_encoder_primary_dac *p_dac = (struct radeon_encoder_primary_dac *)radeon_encoder->enc_priv;
322 dac_macro_cntl = p_dac->ps2_pdac_adj;
323 } else
324 dac_macro_cntl = RREG32(RADEON_DAC_MACRO_CNTL);
325 dac_macro_cntl |= RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G | RADEON_DAC_PDWN_B;
326 WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
327
328 if (rdev->is_atom_bios)
329 radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
330 else
331 radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
332}
333
334static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_encoder *encoder,
335 struct drm_connector *connector)
336{
337 struct drm_device *dev = encoder->dev;
338 struct radeon_device *rdev = dev->dev_private;
339 uint32_t vclk_ecp_cntl, crtc_ext_cntl;
340 uint32_t dac_ext_cntl, dac_cntl, dac_macro_cntl, tmp;
341 enum drm_connector_status found = connector_status_disconnected;
342 bool color = true;
343
344 /* save the regs we need */
345 vclk_ecp_cntl = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
346 crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL);
347 dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL);
348 dac_cntl = RREG32(RADEON_DAC_CNTL);
349 dac_macro_cntl = RREG32(RADEON_DAC_MACRO_CNTL);
350
351 tmp = vclk_ecp_cntl &
352 ~(RADEON_PIXCLK_ALWAYS_ONb | RADEON_PIXCLK_DAC_ALWAYS_ONb);
353 WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
354
355 tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON;
356 WREG32(RADEON_CRTC_EXT_CNTL, tmp);
357
358 tmp = RADEON_DAC_FORCE_BLANK_OFF_EN |
359 RADEON_DAC_FORCE_DATA_EN;
360
361 if (color)
362 tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB;
363 else
364 tmp |= RADEON_DAC_FORCE_DATA_SEL_G;
365
366 if (ASIC_IS_R300(rdev))
367 tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
368 else
369 tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
370
371 WREG32(RADEON_DAC_EXT_CNTL, tmp);
372
373 tmp = dac_cntl & ~(RADEON_DAC_RANGE_CNTL_MASK | RADEON_DAC_PDWN);
374 tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN;
375 WREG32(RADEON_DAC_CNTL, tmp);
376
377 tmp &= ~(RADEON_DAC_PDWN_R |
378 RADEON_DAC_PDWN_G |
379 RADEON_DAC_PDWN_B);
380
381 WREG32(RADEON_DAC_MACRO_CNTL, tmp);
382
383 udelay(2000);
384
385 if (RREG32(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT)
386 found = connector_status_connected;
387
388 /* restore the regs we used */
389 WREG32(RADEON_DAC_CNTL, dac_cntl);
390 WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
391 WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
392 WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
393 WREG32_PLL(RADEON_VCLK_ECP_CNTL, vclk_ecp_cntl);
394
395 return found;
396}
397
398static const struct drm_encoder_helper_funcs radeon_legacy_primary_dac_helper_funcs = {
399 .dpms = radeon_legacy_primary_dac_dpms,
400 .mode_fixup = radeon_legacy_primary_dac_mode_fixup,
401 .prepare = radeon_legacy_primary_dac_prepare,
402 .mode_set = radeon_legacy_primary_dac_mode_set,
403 .commit = radeon_legacy_primary_dac_commit,
404 .detect = radeon_legacy_primary_dac_detect,
405};
406
407
408static const struct drm_encoder_funcs radeon_legacy_primary_dac_enc_funcs = {
409 .destroy = radeon_enc_destroy,
410};
411
412static bool radeon_legacy_tmds_int_mode_fixup(struct drm_encoder *encoder,
413 struct drm_display_mode *mode,
414 struct drm_display_mode *adjusted_mode)
415{
416
417 drm_mode_set_crtcinfo(adjusted_mode, 0);
418
419 return true;
420}
421
422static void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode)
423{
424 struct drm_device *dev = encoder->dev;
425 struct radeon_device *rdev = dev->dev_private;
426 uint32_t fp_gen_cntl = RREG32(RADEON_FP_GEN_CNTL);
427 DRM_DEBUG("\n");
428
429 switch (mode) {
430 case DRM_MODE_DPMS_ON:
431 fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
432 break;
433 case DRM_MODE_DPMS_STANDBY:
434 case DRM_MODE_DPMS_SUSPEND:
435 case DRM_MODE_DPMS_OFF:
436 fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
437 break;
438 }
439
440 WREG32(RADEON_FP_GEN_CNTL, fp_gen_cntl);
441
442 if (rdev->is_atom_bios)
443 radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
444 else
445 radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
446}
447
448static void radeon_legacy_tmds_int_prepare(struct drm_encoder *encoder)
449{
450 struct radeon_device *rdev = encoder->dev->dev_private;
451
452 if (rdev->is_atom_bios)
453 radeon_atom_output_lock(encoder, true);
454 else
455 radeon_combios_output_lock(encoder, true);
456 radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF);
457}
458
459static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder)
460{
461 struct radeon_device *rdev = encoder->dev->dev_private;
462
463 radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_ON);
464
465 if (rdev->is_atom_bios)
466 radeon_atom_output_lock(encoder, true);
467 else
468 radeon_combios_output_lock(encoder, true);
469}
470
471static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder,
472 struct drm_display_mode *mode,
473 struct drm_display_mode *adjusted_mode)
474{
475 struct drm_device *dev = encoder->dev;
476 struct radeon_device *rdev = dev->dev_private;
477 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
478 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
479 uint32_t tmp, tmds_pll_cntl, tmds_transmitter_cntl, fp_gen_cntl;
480 int i;
481
482 DRM_DEBUG("\n");
483
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200484 tmp = tmds_pll_cntl = RREG32(RADEON_TMDS_PLL_CNTL);
485 tmp &= 0xfffff;
486 if (rdev->family == CHIP_RV280) {
487 /* bit 22 of TMDS_PLL_CNTL is read-back inverted */
488 tmp ^= (1 << 22);
489 tmds_pll_cntl ^= (1 << 22);
490 }
491
492 if (radeon_encoder->enc_priv) {
493 struct radeon_encoder_int_tmds *tmds = (struct radeon_encoder_int_tmds *)radeon_encoder->enc_priv;
494
495 for (i = 0; i < 4; i++) {
496 if (tmds->tmds_pll[i].freq == 0)
497 break;
498 if ((uint32_t)(mode->clock / 10) < tmds->tmds_pll[i].freq) {
499 tmp = tmds->tmds_pll[i].value ;
500 break;
501 }
502 }
503 }
504
505 if (ASIC_IS_R300(rdev) || (rdev->family == CHIP_RV280)) {
506 if (tmp & 0xfff00000)
507 tmds_pll_cntl = tmp;
508 else {
509 tmds_pll_cntl &= 0xfff00000;
510 tmds_pll_cntl |= tmp;
511 }
512 } else
513 tmds_pll_cntl = tmp;
514
515 tmds_transmitter_cntl = RREG32(RADEON_TMDS_TRANSMITTER_CNTL) &
516 ~(RADEON_TMDS_TRANSMITTER_PLLRST);
517
518 if (rdev->family == CHIP_R200 ||
519 rdev->family == CHIP_R100 ||
520 ASIC_IS_R300(rdev))
521 tmds_transmitter_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLEN);
522 else /* RV chips got this bit reversed */
523 tmds_transmitter_cntl |= RADEON_TMDS_TRANSMITTER_PLLEN;
524
525 fp_gen_cntl = (RREG32(RADEON_FP_GEN_CNTL) |
526 (RADEON_FP_CRTC_DONT_SHADOW_VPAR |
527 RADEON_FP_CRTC_DONT_SHADOW_HEND));
528
529 fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
530
531 if (1) /* FIXME rgbBits == 8 */
532 fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; /* 24 bit format */
533 else
534 fp_gen_cntl &= ~RADEON_FP_PANEL_FORMAT;/* 18 bit format */
535
536 if (radeon_crtc->crtc_id == 0) {
537 if (ASIC_IS_R300(rdev) || rdev->family == CHIP_R200) {
538 fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
Jerome Glissec93bb852009-07-13 21:04:08 +0200539 if (radeon_encoder->rmx_type != RMX_OFF)
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200540 fp_gen_cntl |= R200_FP_SOURCE_SEL_RMX;
541 else
542 fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1;
543 } else
544 fp_gen_cntl |= RADEON_FP_SEL_CRTC1;
545 } else {
546 if (ASIC_IS_R300(rdev) || rdev->family == CHIP_R200) {
547 fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
548 fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC2;
549 } else
550 fp_gen_cntl |= RADEON_FP_SEL_CRTC2;
551 }
552
553 WREG32(RADEON_TMDS_PLL_CNTL, tmds_pll_cntl);
554 WREG32(RADEON_TMDS_TRANSMITTER_CNTL, tmds_transmitter_cntl);
555 WREG32(RADEON_FP_GEN_CNTL, fp_gen_cntl);
556
557 if (rdev->is_atom_bios)
558 radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
559 else
560 radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
561}
562
563static const struct drm_encoder_helper_funcs radeon_legacy_tmds_int_helper_funcs = {
564 .dpms = radeon_legacy_tmds_int_dpms,
565 .mode_fixup = radeon_legacy_tmds_int_mode_fixup,
566 .prepare = radeon_legacy_tmds_int_prepare,
567 .mode_set = radeon_legacy_tmds_int_mode_set,
568 .commit = radeon_legacy_tmds_int_commit,
569};
570
571
572static const struct drm_encoder_funcs radeon_legacy_tmds_int_enc_funcs = {
573 .destroy = radeon_enc_destroy,
574};
575
576static bool radeon_legacy_tmds_ext_mode_fixup(struct drm_encoder *encoder,
577 struct drm_display_mode *mode,
578 struct drm_display_mode *adjusted_mode)
579{
580
581 drm_mode_set_crtcinfo(adjusted_mode, 0);
582
583 return true;
584}
585
586static void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode)
587{
588 struct drm_device *dev = encoder->dev;
589 struct radeon_device *rdev = dev->dev_private;
590 uint32_t fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
591 DRM_DEBUG("\n");
592
593 switch (mode) {
594 case DRM_MODE_DPMS_ON:
595 fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN;
596 fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
597 break;
598 case DRM_MODE_DPMS_STANDBY:
599 case DRM_MODE_DPMS_SUSPEND:
600 case DRM_MODE_DPMS_OFF:
601 fp2_gen_cntl |= RADEON_FP2_BLANK_EN;
602 fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
603 break;
604 }
605
606 WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
607
608 if (rdev->is_atom_bios)
609 radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
610 else
611 radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
612}
613
614static void radeon_legacy_tmds_ext_prepare(struct drm_encoder *encoder)
615{
616 struct radeon_device *rdev = encoder->dev->dev_private;
617
618 if (rdev->is_atom_bios)
619 radeon_atom_output_lock(encoder, true);
620 else
621 radeon_combios_output_lock(encoder, true);
622 radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF);
623}
624
625static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder)
626{
627 struct radeon_device *rdev = encoder->dev->dev_private;
628 radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_ON);
629
630 if (rdev->is_atom_bios)
631 radeon_atom_output_lock(encoder, false);
632 else
633 radeon_combios_output_lock(encoder, false);
634}
635
636static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder,
637 struct drm_display_mode *mode,
638 struct drm_display_mode *adjusted_mode)
639{
640 struct drm_device *dev = encoder->dev;
641 struct radeon_device *rdev = dev->dev_private;
642 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
643 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
644 uint32_t fp2_gen_cntl;
645
646 DRM_DEBUG("\n");
647
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200648 if (rdev->is_atom_bios) {
649 radeon_encoder->pixel_clock = adjusted_mode->clock;
650 atombios_external_tmds_setup(encoder, ATOM_ENABLE);
651 fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
652 } else {
653 fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
654
655 if (1) /* FIXME rgbBits == 8 */
656 fp2_gen_cntl |= RADEON_FP2_PANEL_FORMAT; /* 24 bit format, */
657 else
658 fp2_gen_cntl &= ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format, */
659
660 fp2_gen_cntl &= ~(RADEON_FP2_ON |
661 RADEON_FP2_DVO_EN |
662 RADEON_FP2_DVO_RATE_SEL_SDR);
663
664 /* XXX: these are oem specific */
665 if (ASIC_IS_R300(rdev)) {
666 if ((dev->pdev->device == 0x4850) &&
667 (dev->pdev->subsystem_vendor == 0x1028) &&
668 (dev->pdev->subsystem_device == 0x2001)) /* Dell Inspiron 8600 */
669 fp2_gen_cntl |= R300_FP2_DVO_CLOCK_MODE_SINGLE;
670 else
671 fp2_gen_cntl |= RADEON_FP2_PAD_FLOP_EN | R300_FP2_DVO_CLOCK_MODE_SINGLE;
672
673 /*if (mode->clock > 165000)
674 fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;*/
675 }
676 }
677
678 if (radeon_crtc->crtc_id == 0) {
679 if ((rdev->family == CHIP_R200) || ASIC_IS_R300(rdev)) {
680 fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK;
Jerome Glissec93bb852009-07-13 21:04:08 +0200681 if (radeon_encoder->rmx_type != RMX_OFF)
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200682 fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX;
683 else
684 fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC1;
685 } else
686 fp2_gen_cntl &= ~RADEON_FP2_SRC_SEL_CRTC2;
687 } else {
688 if ((rdev->family == CHIP_R200) || ASIC_IS_R300(rdev)) {
689 fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK;
690 fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
691 } else
692 fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2;
693 }
694
695 WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
696
697 if (rdev->is_atom_bios)
698 radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
699 else
700 radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
701}
702
703static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs = {
704 .dpms = radeon_legacy_tmds_ext_dpms,
705 .mode_fixup = radeon_legacy_tmds_ext_mode_fixup,
706 .prepare = radeon_legacy_tmds_ext_prepare,
707 .mode_set = radeon_legacy_tmds_ext_mode_set,
708 .commit = radeon_legacy_tmds_ext_commit,
709};
710
711
712static const struct drm_encoder_funcs radeon_legacy_tmds_ext_enc_funcs = {
713 .destroy = radeon_enc_destroy,
714};
715
716static bool radeon_legacy_tv_dac_mode_fixup(struct drm_encoder *encoder,
717 struct drm_display_mode *mode,
718 struct drm_display_mode *adjusted_mode)
719{
720
721 drm_mode_set_crtcinfo(adjusted_mode, 0);
722
723 return true;
724}
725
726static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
727{
728 struct drm_device *dev = encoder->dev;
729 struct radeon_device *rdev = dev->dev_private;
730 uint32_t fp2_gen_cntl = 0, crtc2_gen_cntl = 0, tv_dac_cntl = 0;
731 /* uint32_t tv_master_cntl = 0; */
732
733 DRM_DEBUG("\n");
734
735 if (rdev->family == CHIP_R200)
736 fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
737 else {
738 crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
739 /* FIXME TV */
740 /* tv_master_cntl = RREG32(RADEON_TV_MASTER_CNTL); */
741 tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
742 }
743
744 switch (mode) {
745 case DRM_MODE_DPMS_ON:
746 if (rdev->family == CHIP_R200) {
747 fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
748 } else {
749 crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON;
750 /* tv_master_cntl |= RADEON_TV_ON; */
751 if (rdev->family == CHIP_R420 ||
752 rdev->family == CHIP_R423 ||
753 rdev->family == CHIP_RV410)
754 tv_dac_cntl &= ~(R420_TV_DAC_RDACPD |
755 R420_TV_DAC_GDACPD |
756 R420_TV_DAC_BDACPD |
757 RADEON_TV_DAC_BGSLEEP);
758 else
759 tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD |
760 RADEON_TV_DAC_GDACPD |
761 RADEON_TV_DAC_BDACPD |
762 RADEON_TV_DAC_BGSLEEP);
763 }
764 break;
765 case DRM_MODE_DPMS_STANDBY:
766 case DRM_MODE_DPMS_SUSPEND:
767 case DRM_MODE_DPMS_OFF:
768 if (rdev->family == CHIP_R200)
769 fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
770 else {
771 crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;
772 /* tv_master_cntl &= ~RADEON_TV_ON; */
773 if (rdev->family == CHIP_R420 ||
774 rdev->family == CHIP_R423 ||
775 rdev->family == CHIP_RV410)
776 tv_dac_cntl |= (R420_TV_DAC_RDACPD |
777 R420_TV_DAC_GDACPD |
778 R420_TV_DAC_BDACPD |
779 RADEON_TV_DAC_BGSLEEP);
780 else
781 tv_dac_cntl |= (RADEON_TV_DAC_RDACPD |
782 RADEON_TV_DAC_GDACPD |
783 RADEON_TV_DAC_BDACPD |
784 RADEON_TV_DAC_BGSLEEP);
785 }
786 break;
787 }
788
789 if (rdev->family == CHIP_R200) {
790 WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
791 } else {
792 WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
793 /* WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); */
794 WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
795 }
796
797 if (rdev->is_atom_bios)
798 radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
799 else
800 radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
801}
802
803static void radeon_legacy_tv_dac_prepare(struct drm_encoder *encoder)
804{
805 struct radeon_device *rdev = encoder->dev->dev_private;
806
807 if (rdev->is_atom_bios)
808 radeon_atom_output_lock(encoder, true);
809 else
810 radeon_combios_output_lock(encoder, true);
811 radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF);
812}
813
814static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder)
815{
816 struct radeon_device *rdev = encoder->dev->dev_private;
817
818 radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_ON);
819
820 if (rdev->is_atom_bios)
821 radeon_atom_output_lock(encoder, true);
822 else
823 radeon_combios_output_lock(encoder, true);
824}
825
826static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
827 struct drm_display_mode *mode,
828 struct drm_display_mode *adjusted_mode)
829{
830 struct drm_device *dev = encoder->dev;
831 struct radeon_device *rdev = dev->dev_private;
832 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
833 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
834 uint32_t tv_dac_cntl, gpiopad_a = 0, dac2_cntl, disp_output_cntl = 0;
835 uint32_t disp_hw_debug = 0, fp2_gen_cntl = 0;
836
837 DRM_DEBUG("\n");
838
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200839 if (rdev->family != CHIP_R200) {
840 tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
841 if (rdev->family == CHIP_R420 ||
842 rdev->family == CHIP_R423 ||
843 rdev->family == CHIP_RV410) {
844 tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK |
845 RADEON_TV_DAC_BGADJ_MASK |
846 R420_TV_DAC_DACADJ_MASK |
847 R420_TV_DAC_RDACPD |
848 R420_TV_DAC_GDACPD |
849 R420_TV_DAC_GDACPD |
850 R420_TV_DAC_TVENABLE);
851 } else {
852 tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK |
853 RADEON_TV_DAC_BGADJ_MASK |
854 RADEON_TV_DAC_DACADJ_MASK |
855 RADEON_TV_DAC_RDACPD |
856 RADEON_TV_DAC_GDACPD |
857 RADEON_TV_DAC_GDACPD);
858 }
859
860 /* FIXME TV */
861 if (radeon_encoder->enc_priv) {
862 struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
863 tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
864 RADEON_TV_DAC_NHOLD |
865 RADEON_TV_DAC_STD_PS2 |
866 tv_dac->ps2_tvdac_adj);
867 } else
868 tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
869 RADEON_TV_DAC_NHOLD |
870 RADEON_TV_DAC_STD_PS2);
871
872 WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
873 }
874
875 if (ASIC_IS_R300(rdev)) {
876 gpiopad_a = RREG32(RADEON_GPIOPAD_A) | 1;
877 disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL);
878 } else if (rdev->family == CHIP_R200)
879 fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
880 else
881 disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG);
882
883 dac2_cntl = RREG32(RADEON_DAC_CNTL2) | RADEON_DAC2_DAC2_CLK_SEL;
884
885 if (radeon_crtc->crtc_id == 0) {
886 if (ASIC_IS_R300(rdev)) {
887 disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
888 disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC;
889 } else if (rdev->family == CHIP_R200) {
890 fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK |
891 RADEON_FP2_DVO_RATE_SEL_SDR);
892 } else
893 disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
894 } else {
895 if (ASIC_IS_R300(rdev)) {
896 disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
897 disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
898 } else if (rdev->family == CHIP_R200) {
899 fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK |
900 RADEON_FP2_DVO_RATE_SEL_SDR);
901 fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
902 } else
903 disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL;
904 }
905
906 WREG32(RADEON_DAC_CNTL2, dac2_cntl);
907
908 if (ASIC_IS_R300(rdev)) {
909 WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1);
910 WREG32(RADEON_DISP_TV_OUT_CNTL, disp_output_cntl);
911 } else if (rdev->family == CHIP_R200)
912 WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
913 else
914 WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);
915
916 if (rdev->is_atom_bios)
917 radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
918 else
919 radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
920
921}
922
923static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder,
924 struct drm_connector *connector)
925{
926 struct drm_device *dev = encoder->dev;
927 struct radeon_device *rdev = dev->dev_private;
928 uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
929 uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp;
930 enum drm_connector_status found = connector_status_disconnected;
931 bool color = true;
932
933 /* FIXME tv */
934
935 /* save the regs we need */
936 pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL);
937 gpiopad_a = ASIC_IS_R300(rdev) ? RREG32(RADEON_GPIOPAD_A) : 0;
938 disp_output_cntl = ASIC_IS_R300(rdev) ? RREG32(RADEON_DISP_OUTPUT_CNTL) : 0;
939 disp_hw_debug = ASIC_IS_R300(rdev) ? 0 : RREG32(RADEON_DISP_HW_DEBUG);
940 crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
941 tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
942 dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL);
943 dac_cntl2 = RREG32(RADEON_DAC_CNTL2);
944
945 tmp = pixclks_cntl & ~(RADEON_PIX2CLK_ALWAYS_ONb
946 | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
947 WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
948
949 if (ASIC_IS_R300(rdev))
950 WREG32_P(RADEON_GPIOPAD_A, 1, ~1);
951
952 tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK;
953 tmp |= RADEON_CRTC2_CRT2_ON |
954 (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT);
955
956 WREG32(RADEON_CRTC2_GEN_CNTL, tmp);
957
958 if (ASIC_IS_R300(rdev)) {
959 tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
960 tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
961 WREG32(RADEON_DISP_OUTPUT_CNTL, tmp);
962 } else {
963 tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL;
964 WREG32(RADEON_DISP_HW_DEBUG, tmp);
965 }
966
967 tmp = RADEON_TV_DAC_NBLANK |
968 RADEON_TV_DAC_NHOLD |
969 RADEON_TV_MONITOR_DETECT_EN |
970 RADEON_TV_DAC_STD_PS2;
971
972 WREG32(RADEON_TV_DAC_CNTL, tmp);
973
974 tmp = RADEON_DAC2_FORCE_BLANK_OFF_EN |
975 RADEON_DAC2_FORCE_DATA_EN;
976
977 if (color)
978 tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB;
979 else
980 tmp |= RADEON_DAC_FORCE_DATA_SEL_G;
981
982 if (ASIC_IS_R300(rdev))
983 tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
984 else
985 tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
986
987 WREG32(RADEON_DAC_EXT_CNTL, tmp);
988
989 tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN;
990 WREG32(RADEON_DAC_CNTL2, tmp);
991
992 udelay(10000);
993
994 if (ASIC_IS_R300(rdev)) {
995 if (RREG32(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B)
996 found = connector_status_connected;
997 } else {
998 if (RREG32(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUTPUT)
999 found = connector_status_connected;
1000 }
1001
1002 /* restore regs we used */
1003 WREG32(RADEON_DAC_CNTL2, dac_cntl2);
1004 WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
1005 WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
1006 WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
1007
1008 if (ASIC_IS_R300(rdev)) {
1009 WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
1010 WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1);
1011 } else {
1012 WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);
1013 }
1014 WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
1015
1016 /* return found; */
1017 return connector_status_disconnected;
1018
1019}
1020
1021static const struct drm_encoder_helper_funcs radeon_legacy_tv_dac_helper_funcs = {
1022 .dpms = radeon_legacy_tv_dac_dpms,
1023 .mode_fixup = radeon_legacy_tv_dac_mode_fixup,
1024 .prepare = radeon_legacy_tv_dac_prepare,
1025 .mode_set = radeon_legacy_tv_dac_mode_set,
1026 .commit = radeon_legacy_tv_dac_commit,
1027 .detect = radeon_legacy_tv_dac_detect,
1028};
1029
1030
1031static const struct drm_encoder_funcs radeon_legacy_tv_dac_enc_funcs = {
1032 .destroy = radeon_enc_destroy,
1033};
1034
1035void
1036radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device)
1037{
1038 struct radeon_device *rdev = dev->dev_private;
1039 struct drm_encoder *encoder;
1040 struct radeon_encoder *radeon_encoder;
1041
1042 /* see if we already added it */
1043 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
1044 radeon_encoder = to_radeon_encoder(encoder);
1045 if (radeon_encoder->encoder_id == encoder_id) {
1046 radeon_encoder->devices |= supported_device;
1047 return;
1048 }
1049
1050 }
1051
1052 /* add a new one */
1053 radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL);
1054 if (!radeon_encoder)
1055 return;
1056
1057 encoder = &radeon_encoder->base;
1058 encoder->possible_crtcs = 0x3;
1059 encoder->possible_clones = 0;
1060
1061 radeon_encoder->enc_priv = NULL;
1062
1063 radeon_encoder->encoder_id = encoder_id;
1064 radeon_encoder->devices = supported_device;
Jerome Glissec93bb852009-07-13 21:04:08 +02001065 radeon_encoder->rmx_type = RMX_OFF;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001066
1067 switch (radeon_encoder->encoder_id) {
1068 case ENCODER_OBJECT_ID_INTERNAL_LVDS:
Dave Airlie80e69142009-08-17 10:22:37 +10001069 encoder->possible_crtcs = 0x1;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001070 drm_encoder_init(dev, encoder, &radeon_legacy_lvds_enc_funcs, DRM_MODE_ENCODER_LVDS);
1071 drm_encoder_helper_add(encoder, &radeon_legacy_lvds_helper_funcs);
1072 if (rdev->is_atom_bios)
1073 radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder);
1074 else
1075 radeon_encoder->enc_priv = radeon_combios_get_lvds_info(radeon_encoder);
1076 radeon_encoder->rmx_type = RMX_FULL;
1077 break;
1078 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
1079 drm_encoder_init(dev, encoder, &radeon_legacy_tmds_int_enc_funcs, DRM_MODE_ENCODER_TMDS);
1080 drm_encoder_helper_add(encoder, &radeon_legacy_tmds_int_helper_funcs);
1081 if (rdev->is_atom_bios)
1082 radeon_encoder->enc_priv = radeon_atombios_get_tmds_info(radeon_encoder);
1083 else
1084 radeon_encoder->enc_priv = radeon_combios_get_tmds_info(radeon_encoder);
1085 break;
1086 case ENCODER_OBJECT_ID_INTERNAL_DAC1:
1087 drm_encoder_init(dev, encoder, &radeon_legacy_primary_dac_enc_funcs, DRM_MODE_ENCODER_DAC);
1088 drm_encoder_helper_add(encoder, &radeon_legacy_primary_dac_helper_funcs);
Alex Deucher6fe7ac32009-06-12 17:26:08 +00001089 if (rdev->is_atom_bios)
1090 radeon_encoder->enc_priv = radeon_atombios_get_primary_dac_info(radeon_encoder);
1091 else
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001092 radeon_encoder->enc_priv = radeon_combios_get_primary_dac_info(radeon_encoder);
1093 break;
1094 case ENCODER_OBJECT_ID_INTERNAL_DAC2:
1095 drm_encoder_init(dev, encoder, &radeon_legacy_tv_dac_enc_funcs, DRM_MODE_ENCODER_TVDAC);
1096 drm_encoder_helper_add(encoder, &radeon_legacy_tv_dac_helper_funcs);
Alex Deucher6fe7ac32009-06-12 17:26:08 +00001097 if (rdev->is_atom_bios)
1098 radeon_encoder->enc_priv = radeon_atombios_get_tv_dac_info(radeon_encoder);
1099 else
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001100 radeon_encoder->enc_priv = radeon_combios_get_tv_dac_info(radeon_encoder);
1101 break;
1102 case ENCODER_OBJECT_ID_INTERNAL_DVO1:
1103 drm_encoder_init(dev, encoder, &radeon_legacy_tmds_ext_enc_funcs, DRM_MODE_ENCODER_TMDS);
1104 drm_encoder_helper_add(encoder, &radeon_legacy_tmds_ext_helper_funcs);
1105 if (!rdev->is_atom_bios)
1106 radeon_combios_get_ext_tmds_info(radeon_encoder);
1107 break;
1108 }
1109}