2 * Copyright (C) 2009 Francisco Jerez.
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 #include "drm_crtc_helper.h"
29 #include "nouveau_drv.h"
30 #include "nouveau_encoder.h"
31 #include "nouveau_connector.h"
32 #include "nouveau_crtc.h"
33 #include "nouveau_hw.h"
36 static uint32_t nv42_tv_sample_load(struct drm_encoder
*encoder
)
38 struct drm_device
*dev
= encoder
->dev
;
39 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
40 struct nouveau_gpio_engine
*gpio
= &dev_priv
->engine
.gpio
;
41 uint32_t testval
, regoffset
= nv04_dac_output_offset(encoder
);
42 uint32_t gpio0
, gpio1
, fp_htotal
, fp_hsync_start
, fp_hsync_end
,
43 fp_control
, test_ctrl
, dacclk
, ctv_14
, ctv_1c
, ctv_6c
;
47 #define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20)
48 testval
= RGB_TEST_DATA(0x82, 0xeb, 0x82);
49 if (dev_priv
->vbios
.tvdactestval
)
50 testval
= dev_priv
->vbios
.tvdactestval
;
52 dacclk
= NVReadRAMDAC(dev
, 0, NV_PRAMDAC_DACCLK
+ regoffset
);
53 head
= (dacclk
& 0x100) >> 8;
55 /* Save the previous state. */
56 gpio1
= gpio
->get(dev
, DCB_GPIO_TVDAC1
);
57 gpio0
= gpio
->get(dev
, DCB_GPIO_TVDAC0
);
58 fp_htotal
= NVReadRAMDAC(dev
, head
, NV_PRAMDAC_FP_HTOTAL
);
59 fp_hsync_start
= NVReadRAMDAC(dev
, head
, NV_PRAMDAC_FP_HSYNC_START
);
60 fp_hsync_end
= NVReadRAMDAC(dev
, head
, NV_PRAMDAC_FP_HSYNC_END
);
61 fp_control
= NVReadRAMDAC(dev
, head
, NV_PRAMDAC_FP_TG_CONTROL
);
62 test_ctrl
= NVReadRAMDAC(dev
, 0, NV_PRAMDAC_TEST_CONTROL
+ regoffset
);
63 ctv_1c
= NVReadRAMDAC(dev
, head
, 0x680c1c);
64 ctv_14
= NVReadRAMDAC(dev
, head
, 0x680c14);
65 ctv_6c
= NVReadRAMDAC(dev
, head
, 0x680c6c);
67 /* Prepare the DAC for load detection. */
68 gpio
->set(dev
, DCB_GPIO_TVDAC1
, true);
69 gpio
->set(dev
, DCB_GPIO_TVDAC0
, true);
71 NVWriteRAMDAC(dev
, head
, NV_PRAMDAC_FP_HTOTAL
, 1343);
72 NVWriteRAMDAC(dev
, head
, NV_PRAMDAC_FP_HSYNC_START
, 1047);
73 NVWriteRAMDAC(dev
, head
, NV_PRAMDAC_FP_HSYNC_END
, 1183);
74 NVWriteRAMDAC(dev
, head
, NV_PRAMDAC_FP_TG_CONTROL
,
75 NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS
|
76 NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12
|
77 NV_PRAMDAC_FP_TG_CONTROL_READ_PROG
|
78 NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS
|
79 NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS
);
81 NVWriteRAMDAC(dev
, 0, NV_PRAMDAC_TEST_CONTROL
+ regoffset
, 0);
83 NVWriteRAMDAC(dev
, 0, NV_PRAMDAC_DACCLK
+ regoffset
,
84 (dacclk
& ~0xff) | 0x22);
86 NVWriteRAMDAC(dev
, 0, NV_PRAMDAC_DACCLK
+ regoffset
,
87 (dacclk
& ~0xff) | 0x21);
89 NVWriteRAMDAC(dev
, head
, 0x680c1c, 1 << 20);
90 NVWriteRAMDAC(dev
, head
, 0x680c14, 4 << 16);
92 /* Sample pin 0x4 (usually S-video luma). */
93 NVWriteRAMDAC(dev
, head
, 0x680c6c, testval
>> 10 & 0x3ff);
95 sample
|= NVReadRAMDAC(dev
, 0, NV_PRAMDAC_TEST_CONTROL
+ regoffset
)
98 /* Sample the remaining pins. */
99 NVWriteRAMDAC(dev
, head
, 0x680c6c, testval
& 0x3ff);
101 sample
|= NVReadRAMDAC(dev
, 0, NV_PRAMDAC_TEST_CONTROL
+ regoffset
)
104 /* Restore the previous state. */
105 NVWriteRAMDAC(dev
, head
, 0x680c1c, ctv_1c
);
106 NVWriteRAMDAC(dev
, head
, 0x680c14, ctv_14
);
107 NVWriteRAMDAC(dev
, head
, 0x680c6c, ctv_6c
);
108 NVWriteRAMDAC(dev
, 0, NV_PRAMDAC_DACCLK
+ regoffset
, dacclk
);
109 NVWriteRAMDAC(dev
, 0, NV_PRAMDAC_TEST_CONTROL
+ regoffset
, test_ctrl
);
110 NVWriteRAMDAC(dev
, head
, NV_PRAMDAC_FP_TG_CONTROL
, fp_control
);
111 NVWriteRAMDAC(dev
, head
, NV_PRAMDAC_FP_HSYNC_END
, fp_hsync_end
);
112 NVWriteRAMDAC(dev
, head
, NV_PRAMDAC_FP_HSYNC_START
, fp_hsync_start
);
113 NVWriteRAMDAC(dev
, head
, NV_PRAMDAC_FP_HTOTAL
, fp_htotal
);
114 gpio
->set(dev
, DCB_GPIO_TVDAC1
, gpio1
);
115 gpio
->set(dev
, DCB_GPIO_TVDAC0
, gpio0
);
121 get_tv_detect_quirks(struct drm_device
*dev
, uint32_t *pin_mask
)
124 if (dev
->pdev
->device
== 0x0322 &&
125 dev
->pdev
->subsystem_vendor
== 0x19da &&
126 (dev
->pdev
->subsystem_device
== 0x1035 ||
127 dev
->pdev
->subsystem_device
== 0x2035)) {
135 static enum drm_connector_status
136 nv17_tv_detect(struct drm_encoder
*encoder
, struct drm_connector
*connector
)
138 struct drm_device
*dev
= encoder
->dev
;
139 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
140 struct drm_mode_config
*conf
= &dev
->mode_config
;
141 struct nv17_tv_encoder
*tv_enc
= to_tv_enc(encoder
);
142 struct dcb_entry
*dcb
= tv_enc
->base
.dcb
;
143 bool reliable
= get_tv_detect_quirks(dev
, &tv_enc
->pin_mask
);
145 if (nv04_dac_in_use(encoder
))
146 return connector_status_disconnected
;
149 if (dev_priv
->chipset
== 0x42 ||
150 dev_priv
->chipset
== 0x43)
152 nv42_tv_sample_load(encoder
) >> 28 & 0xe;
155 nv17_dac_sample_load(encoder
) >> 28 & 0xe;
158 switch (tv_enc
->pin_mask
) {
161 tv_enc
->subconnector
= DRM_MODE_SUBCONNECTOR_Composite
;
164 tv_enc
->subconnector
= DRM_MODE_SUBCONNECTOR_SVIDEO
;
167 if (dcb
->tvconf
.has_component_output
)
168 tv_enc
->subconnector
= DRM_MODE_SUBCONNECTOR_Component
;
170 tv_enc
->subconnector
= DRM_MODE_SUBCONNECTOR_SCART
;
173 tv_enc
->subconnector
= DRM_MODE_SUBCONNECTOR_Unknown
;
177 drm_connector_property_set_value(connector
,
178 conf
->tv_subconnector_property
,
179 tv_enc
->subconnector
);
182 return connector_status_unknown
;
183 } else if (tv_enc
->subconnector
) {
184 NV_INFO(dev
, "Load detected on output %c\n",
186 return connector_status_connected
;
188 return connector_status_disconnected
;
192 static const struct {
207 static int nv17_tv_get_modes(struct drm_encoder
*encoder
,
208 struct drm_connector
*connector
)
210 struct nv17_tv_norm_params
*tv_norm
= get_tv_norm(encoder
);
211 struct drm_display_mode
*mode
;
212 struct drm_display_mode
*output_mode
;
216 if (tv_norm
->kind
!= CTV_ENC_MODE
) {
217 struct drm_display_mode
*tv_mode
;
219 for (tv_mode
= nv17_tv_modes
; tv_mode
->hdisplay
; tv_mode
++) {
220 mode
= drm_mode_duplicate(encoder
->dev
, tv_mode
);
222 mode
->clock
= tv_norm
->tv_enc_mode
.vrefresh
*
223 mode
->htotal
/ 1000 *
226 if (mode
->flags
& DRM_MODE_FLAG_DBLSCAN
)
229 if (mode
->hdisplay
== tv_norm
->tv_enc_mode
.hdisplay
&&
230 mode
->vdisplay
== tv_norm
->tv_enc_mode
.vdisplay
)
231 mode
->type
|= DRM_MODE_TYPE_PREFERRED
;
233 drm_mode_probed_add(connector
, mode
);
239 /* tv_norm->kind == CTV_ENC_MODE */
240 output_mode
= &tv_norm
->ctv_enc_mode
.mode
;
241 for (i
= 0; i
< ARRAY_SIZE(modes
); i
++) {
242 if (modes
[i
].hdisplay
> output_mode
->hdisplay
||
243 modes
[i
].vdisplay
> output_mode
->vdisplay
)
246 if (modes
[i
].hdisplay
== output_mode
->hdisplay
&&
247 modes
[i
].vdisplay
== output_mode
->vdisplay
) {
248 mode
= drm_mode_duplicate(encoder
->dev
, output_mode
);
249 mode
->type
|= DRM_MODE_TYPE_PREFERRED
;
251 mode
= drm_cvt_mode(encoder
->dev
, modes
[i
].hdisplay
,
252 modes
[i
].vdisplay
, 60, false,
253 output_mode
->flags
& DRM_MODE_FLAG_INTERLACE
,
257 /* CVT modes are sometimes unsuitable... */
258 if (output_mode
->hdisplay
<= 720
259 || output_mode
->hdisplay
>= 1920) {
260 mode
->htotal
= output_mode
->htotal
;
261 mode
->hsync_start
= (mode
->hdisplay
+ (mode
->htotal
262 - mode
->hdisplay
) * 9 / 10) & ~7;
263 mode
->hsync_end
= mode
->hsync_start
+ 8;
265 if (output_mode
->vdisplay
>= 1024) {
266 mode
->vtotal
= output_mode
->vtotal
;
267 mode
->vsync_start
= output_mode
->vsync_start
;
268 mode
->vsync_end
= output_mode
->vsync_end
;
271 mode
->type
|= DRM_MODE_TYPE_DRIVER
;
272 drm_mode_probed_add(connector
, mode
);
278 static int nv17_tv_mode_valid(struct drm_encoder
*encoder
,
279 struct drm_display_mode
*mode
)
281 struct nv17_tv_norm_params
*tv_norm
= get_tv_norm(encoder
);
283 if (tv_norm
->kind
== CTV_ENC_MODE
) {
284 struct drm_display_mode
*output_mode
=
285 &tv_norm
->ctv_enc_mode
.mode
;
287 if (mode
->clock
> 400000)
288 return MODE_CLOCK_HIGH
;
290 if (mode
->hdisplay
> output_mode
->hdisplay
||
291 mode
->vdisplay
> output_mode
->vdisplay
)
294 if ((mode
->flags
& DRM_MODE_FLAG_INTERLACE
) !=
295 (output_mode
->flags
& DRM_MODE_FLAG_INTERLACE
))
296 return MODE_NO_INTERLACE
;
298 if (mode
->flags
& DRM_MODE_FLAG_DBLSCAN
)
299 return MODE_NO_DBLESCAN
;
302 const int vsync_tolerance
= 600;
304 if (mode
->clock
> 70000)
305 return MODE_CLOCK_HIGH
;
307 if (abs(drm_mode_vrefresh(mode
) * 1000 -
308 tv_norm
->tv_enc_mode
.vrefresh
) > vsync_tolerance
)
311 /* The encoder takes care of the actual interlacing */
312 if (mode
->flags
& DRM_MODE_FLAG_INTERLACE
)
313 return MODE_NO_INTERLACE
;
319 static bool nv17_tv_mode_fixup(struct drm_encoder
*encoder
,
320 struct drm_display_mode
*mode
,
321 struct drm_display_mode
*adjusted_mode
)
323 struct nv17_tv_norm_params
*tv_norm
= get_tv_norm(encoder
);
325 if (nv04_dac_in_use(encoder
))
328 if (tv_norm
->kind
== CTV_ENC_MODE
)
329 adjusted_mode
->clock
= tv_norm
->ctv_enc_mode
.mode
.clock
;
331 adjusted_mode
->clock
= 90000;
336 static void nv17_tv_dpms(struct drm_encoder
*encoder
, int mode
)
338 struct drm_device
*dev
= encoder
->dev
;
339 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
340 struct nouveau_gpio_engine
*gpio
= &dev_priv
->engine
.gpio
;
341 struct nv17_tv_state
*regs
= &to_tv_enc(encoder
)->state
;
342 struct nv17_tv_norm_params
*tv_norm
= get_tv_norm(encoder
);
344 if (nouveau_encoder(encoder
)->last_dpms
== mode
)
346 nouveau_encoder(encoder
)->last_dpms
= mode
;
348 NV_INFO(dev
, "Setting dpms mode %d on TV encoder (output %d)\n",
349 mode
, nouveau_encoder(encoder
)->dcb
->index
);
353 if (tv_norm
->kind
== CTV_ENC_MODE
) {
354 nv04_dfp_update_fp_control(encoder
, mode
);
357 nv04_dfp_update_fp_control(encoder
, DRM_MODE_DPMS_OFF
);
359 if (mode
== DRM_MODE_DPMS_ON
)
363 nv_load_ptv(dev
, regs
, 200);
365 gpio
->set(dev
, DCB_GPIO_TVDAC1
, mode
== DRM_MODE_DPMS_ON
);
366 gpio
->set(dev
, DCB_GPIO_TVDAC0
, mode
== DRM_MODE_DPMS_ON
);
368 nv04_dac_update_dacclk(encoder
, mode
== DRM_MODE_DPMS_ON
);
371 static void nv17_tv_prepare(struct drm_encoder
*encoder
)
373 struct drm_device
*dev
= encoder
->dev
;
374 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
375 struct drm_encoder_helper_funcs
*helper
= encoder
->helper_private
;
376 struct nv17_tv_norm_params
*tv_norm
= get_tv_norm(encoder
);
377 int head
= nouveau_crtc(encoder
->crtc
)->index
;
378 uint8_t *cr_lcd
= &dev_priv
->mode_reg
.crtc_reg
[head
].CRTC
[
379 NV_CIO_CRE_LCD__INDEX
];
380 uint32_t dacclk_off
= NV_PRAMDAC_DACCLK
+
381 nv04_dac_output_offset(encoder
);
384 helper
->dpms(encoder
, DRM_MODE_DPMS_OFF
);
386 nv04_dfp_disable(dev
, head
);
388 /* Unbind any FP encoders from this head if we need the FP
390 if (tv_norm
->kind
== CTV_ENC_MODE
) {
391 struct drm_encoder
*enc
;
393 list_for_each_entry(enc
, &dev
->mode_config
.encoder_list
, head
) {
394 struct dcb_entry
*dcb
= nouveau_encoder(enc
)->dcb
;
396 if ((dcb
->type
== OUTPUT_TMDS
||
397 dcb
->type
== OUTPUT_LVDS
) &&
399 nv04_dfp_get_bound_head(dev
, dcb
) == head
) {
400 nv04_dfp_bind_head(dev
, dcb
, head
^ 1,
401 dev_priv
->vbios
.fp
.dual_link
);
407 /* Some NV4x have unknown values (0x3f, 0x50, 0x54, 0x6b, 0x79, 0x7f)
408 * at LCD__INDEX which we don't alter
410 if (!(*cr_lcd
& 0x44)) {
411 if (tv_norm
->kind
== CTV_ENC_MODE
)
412 *cr_lcd
= 0x1 | (head
? 0x0 : 0x8);
417 /* Set the DACCLK register */
418 dacclk
= (NVReadRAMDAC(dev
, 0, dacclk_off
) & ~0x30) | 0x1;
420 if (dev_priv
->card_type
== NV_40
)
421 dacclk
|= 0x1a << 16;
423 if (tv_norm
->kind
== CTV_ENC_MODE
) {
436 NVWriteRAMDAC(dev
, 0, dacclk_off
, dacclk
);
439 static void nv17_tv_mode_set(struct drm_encoder
*encoder
,
440 struct drm_display_mode
*drm_mode
,
441 struct drm_display_mode
*adjusted_mode
)
443 struct drm_device
*dev
= encoder
->dev
;
444 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
445 int head
= nouveau_crtc(encoder
->crtc
)->index
;
446 struct nv04_crtc_reg
*regs
= &dev_priv
->mode_reg
.crtc_reg
[head
];
447 struct nv17_tv_state
*tv_regs
= &to_tv_enc(encoder
)->state
;
448 struct nv17_tv_norm_params
*tv_norm
= get_tv_norm(encoder
);
451 regs
->CRTC
[NV_CIO_CRE_53
] = 0x40; /* FP_HTIMING */
452 regs
->CRTC
[NV_CIO_CRE_54
] = 0; /* FP_VTIMING */
453 regs
->ramdac_630
= 0x2; /* turn off green mode (tv test pattern?) */
455 regs
->ramdac_8c0
= 0x0;
457 if (tv_norm
->kind
== TV_ENC_MODE
) {
458 tv_regs
->ptv_200
= 0x13111100;
460 tv_regs
->ptv_200
|= 0x10;
462 tv_regs
->ptv_20c
= 0x808010;
463 tv_regs
->ptv_304
= 0x2d00000;
464 tv_regs
->ptv_600
= 0x0;
465 tv_regs
->ptv_60c
= 0x0;
466 tv_regs
->ptv_610
= 0x1e00000;
468 if (tv_norm
->tv_enc_mode
.vdisplay
== 576) {
469 tv_regs
->ptv_508
= 0x1200000;
470 tv_regs
->ptv_614
= 0x33;
472 } else if (tv_norm
->tv_enc_mode
.vdisplay
== 480) {
473 tv_regs
->ptv_508
= 0xf00000;
474 tv_regs
->ptv_614
= 0x13;
477 if (dev_priv
->card_type
>= NV_30
) {
478 tv_regs
->ptv_500
= 0xe8e0;
479 tv_regs
->ptv_504
= 0x1710;
480 tv_regs
->ptv_604
= 0x0;
481 tv_regs
->ptv_608
= 0x0;
483 if (tv_norm
->tv_enc_mode
.vdisplay
== 576) {
484 tv_regs
->ptv_604
= 0x20;
485 tv_regs
->ptv_608
= 0x10;
486 tv_regs
->ptv_500
= 0x19710;
487 tv_regs
->ptv_504
= 0x68f0;
489 } else if (tv_norm
->tv_enc_mode
.vdisplay
== 480) {
490 tv_regs
->ptv_604
= 0x10;
491 tv_regs
->ptv_608
= 0x20;
492 tv_regs
->ptv_500
= 0x4b90;
493 tv_regs
->ptv_504
= 0x1b480;
497 for (i
= 0; i
< 0x40; i
++)
498 tv_regs
->tv_enc
[i
] = tv_norm
->tv_enc_mode
.tv_enc
[i
];
501 struct drm_display_mode
*output_mode
=
502 &tv_norm
->ctv_enc_mode
.mode
;
504 /* The registers in PRAMDAC+0xc00 control some timings and CSC
505 * parameters for the CTV encoder (It's only used for "HD" TV
506 * modes, I don't think I have enough working to guess what
507 * they exactly mean...), it's probably connected at the
508 * output of the FP encoder, but it also needs the analog
509 * encoder in its OR enabled and routed to the head it's
510 * using. It's enabled with the DACCLK register, bits [5:4].
512 for (i
= 0; i
< 38; i
++)
513 regs
->ctv_regs
[i
] = tv_norm
->ctv_enc_mode
.ctv_regs
[i
];
515 regs
->fp_horiz_regs
[FP_DISPLAY_END
] = output_mode
->hdisplay
- 1;
516 regs
->fp_horiz_regs
[FP_TOTAL
] = output_mode
->htotal
- 1;
517 regs
->fp_horiz_regs
[FP_SYNC_START
] =
518 output_mode
->hsync_start
- 1;
519 regs
->fp_horiz_regs
[FP_SYNC_END
] = output_mode
->hsync_end
- 1;
520 regs
->fp_horiz_regs
[FP_CRTC
] = output_mode
->hdisplay
+
521 max((output_mode
->hdisplay
-600)/40 - 1, 1);
523 regs
->fp_vert_regs
[FP_DISPLAY_END
] = output_mode
->vdisplay
- 1;
524 regs
->fp_vert_regs
[FP_TOTAL
] = output_mode
->vtotal
- 1;
525 regs
->fp_vert_regs
[FP_SYNC_START
] =
526 output_mode
->vsync_start
- 1;
527 regs
->fp_vert_regs
[FP_SYNC_END
] = output_mode
->vsync_end
- 1;
528 regs
->fp_vert_regs
[FP_CRTC
] = output_mode
->vdisplay
- 1;
530 regs
->fp_control
= NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS
|
531 NV_PRAMDAC_FP_TG_CONTROL_READ_PROG
|
532 NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12
;
534 if (output_mode
->flags
& DRM_MODE_FLAG_PVSYNC
)
535 regs
->fp_control
|= NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS
;
536 if (output_mode
->flags
& DRM_MODE_FLAG_PHSYNC
)
537 regs
->fp_control
|= NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS
;
539 regs
->fp_debug_0
= NV_PRAMDAC_FP_DEBUG_0_YWEIGHT_ROUND
|
540 NV_PRAMDAC_FP_DEBUG_0_XWEIGHT_ROUND
|
541 NV_PRAMDAC_FP_DEBUG_0_YINTERP_BILINEAR
|
542 NV_PRAMDAC_FP_DEBUG_0_XINTERP_BILINEAR
|
543 NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED
|
544 NV_PRAMDAC_FP_DEBUG_0_YSCALE_ENABLE
|
545 NV_PRAMDAC_FP_DEBUG_0_XSCALE_ENABLE
;
547 regs
->fp_debug_2
= 0;
549 regs
->fp_margin_color
= 0x801080;
554 static void nv17_tv_commit(struct drm_encoder
*encoder
)
556 struct drm_device
*dev
= encoder
->dev
;
557 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
558 struct nouveau_crtc
*nv_crtc
= nouveau_crtc(encoder
->crtc
);
559 struct nouveau_encoder
*nv_encoder
= nouveau_encoder(encoder
);
560 struct drm_encoder_helper_funcs
*helper
= encoder
->helper_private
;
562 if (get_tv_norm(encoder
)->kind
== TV_ENC_MODE
) {
563 nv17_tv_update_rescaler(encoder
);
564 nv17_tv_update_properties(encoder
);
566 nv17_ctv_update_rescaler(encoder
);
569 nv17_tv_state_load(dev
, &to_tv_enc(encoder
)->state
);
571 /* This could use refinement for flatpanels, but it should work */
572 if (dev_priv
->chipset
< 0x44)
573 NVWriteRAMDAC(dev
, 0, NV_PRAMDAC_TEST_CONTROL
+
574 nv04_dac_output_offset(encoder
),
577 NVWriteRAMDAC(dev
, 0, NV_PRAMDAC_TEST_CONTROL
+
578 nv04_dac_output_offset(encoder
),
581 helper
->dpms(encoder
, DRM_MODE_DPMS_ON
);
583 NV_INFO(dev
, "Output %s is running on CRTC %d using output %c\n",
584 drm_get_connector_name(
585 &nouveau_encoder_connector_get(nv_encoder
)->base
),
586 nv_crtc
->index
, '@' + ffs(nv_encoder
->dcb
->or));
589 static void nv17_tv_save(struct drm_encoder
*encoder
)
591 struct drm_device
*dev
= encoder
->dev
;
592 struct nv17_tv_encoder
*tv_enc
= to_tv_enc(encoder
);
594 nouveau_encoder(encoder
)->restore
.output
=
597 nv04_dac_output_offset(encoder
));
599 nv17_tv_state_save(dev
, &tv_enc
->saved_state
);
601 tv_enc
->state
.ptv_200
= tv_enc
->saved_state
.ptv_200
;
604 static void nv17_tv_restore(struct drm_encoder
*encoder
)
606 struct drm_device
*dev
= encoder
->dev
;
608 NVWriteRAMDAC(dev
, 0, NV_PRAMDAC_DACCLK
+
609 nv04_dac_output_offset(encoder
),
610 nouveau_encoder(encoder
)->restore
.output
);
612 nv17_tv_state_load(dev
, &to_tv_enc(encoder
)->saved_state
);
614 nouveau_encoder(encoder
)->last_dpms
= NV_DPMS_CLEARED
;
617 static int nv17_tv_create_resources(struct drm_encoder
*encoder
,
618 struct drm_connector
*connector
)
620 struct drm_device
*dev
= encoder
->dev
;
621 struct drm_mode_config
*conf
= &dev
->mode_config
;
622 struct nv17_tv_encoder
*tv_enc
= to_tv_enc(encoder
);
623 struct dcb_entry
*dcb
= nouveau_encoder(encoder
)->dcb
;
624 int num_tv_norms
= dcb
->tvconf
.has_component_output
? NUM_TV_NORMS
:
628 if (nouveau_tv_norm
) {
629 for (i
= 0; i
< num_tv_norms
; i
++) {
630 if (!strcmp(nv17_tv_norm_names
[i
], nouveau_tv_norm
)) {
636 if (i
== num_tv_norms
)
637 NV_WARN(dev
, "Invalid TV norm setting \"%s\"\n",
641 drm_mode_create_tv_properties(dev
, num_tv_norms
, nv17_tv_norm_names
);
643 drm_connector_attach_property(connector
,
644 conf
->tv_select_subconnector_property
,
645 tv_enc
->select_subconnector
);
646 drm_connector_attach_property(connector
,
647 conf
->tv_subconnector_property
,
648 tv_enc
->subconnector
);
649 drm_connector_attach_property(connector
,
650 conf
->tv_mode_property
,
652 drm_connector_attach_property(connector
,
653 conf
->tv_flicker_reduction_property
,
655 drm_connector_attach_property(connector
,
656 conf
->tv_saturation_property
,
658 drm_connector_attach_property(connector
,
659 conf
->tv_hue_property
,
661 drm_connector_attach_property(connector
,
662 conf
->tv_overscan_property
,
668 static int nv17_tv_set_property(struct drm_encoder
*encoder
,
669 struct drm_connector
*connector
,
670 struct drm_property
*property
,
673 struct drm_mode_config
*conf
= &encoder
->dev
->mode_config
;
674 struct drm_crtc
*crtc
= encoder
->crtc
;
675 struct nv17_tv_encoder
*tv_enc
= to_tv_enc(encoder
);
676 struct nv17_tv_norm_params
*tv_norm
= get_tv_norm(encoder
);
677 bool modes_changed
= false;
679 if (property
== conf
->tv_overscan_property
) {
680 tv_enc
->overscan
= val
;
682 if (tv_norm
->kind
== CTV_ENC_MODE
)
683 nv17_ctv_update_rescaler(encoder
);
685 nv17_tv_update_rescaler(encoder
);
688 } else if (property
== conf
->tv_saturation_property
) {
689 if (tv_norm
->kind
!= TV_ENC_MODE
)
692 tv_enc
->saturation
= val
;
693 nv17_tv_update_properties(encoder
);
695 } else if (property
== conf
->tv_hue_property
) {
696 if (tv_norm
->kind
!= TV_ENC_MODE
)
700 nv17_tv_update_properties(encoder
);
702 } else if (property
== conf
->tv_flicker_reduction_property
) {
703 if (tv_norm
->kind
!= TV_ENC_MODE
)
706 tv_enc
->flicker
= val
;
708 nv17_tv_update_rescaler(encoder
);
710 } else if (property
== conf
->tv_mode_property
) {
711 if (connector
->dpms
!= DRM_MODE_DPMS_OFF
)
714 tv_enc
->tv_norm
= val
;
716 modes_changed
= true;
718 } else if (property
== conf
->tv_select_subconnector_property
) {
719 if (tv_norm
->kind
!= TV_ENC_MODE
)
722 tv_enc
->select_subconnector
= val
;
723 nv17_tv_update_properties(encoder
);
730 drm_helper_probe_single_connector_modes(connector
, 0, 0);
732 /* Disable the crtc to ensure a full modeset is
733 * performed whenever it's turned on again. */
735 struct drm_mode_set modeset
= {
739 crtc
->funcs
->set_config(&modeset
);
746 static void nv17_tv_destroy(struct drm_encoder
*encoder
)
748 struct nv17_tv_encoder
*tv_enc
= to_tv_enc(encoder
);
750 NV_DEBUG_KMS(encoder
->dev
, "\n");
752 drm_encoder_cleanup(encoder
);
756 static struct drm_encoder_helper_funcs nv17_tv_helper_funcs
= {
757 .dpms
= nv17_tv_dpms
,
758 .save
= nv17_tv_save
,
759 .restore
= nv17_tv_restore
,
760 .mode_fixup
= nv17_tv_mode_fixup
,
761 .prepare
= nv17_tv_prepare
,
762 .commit
= nv17_tv_commit
,
763 .mode_set
= nv17_tv_mode_set
,
764 .detect
= nv17_tv_detect
,
767 static struct drm_encoder_slave_funcs nv17_tv_slave_funcs
= {
768 .get_modes
= nv17_tv_get_modes
,
769 .mode_valid
= nv17_tv_mode_valid
,
770 .create_resources
= nv17_tv_create_resources
,
771 .set_property
= nv17_tv_set_property
,
774 static struct drm_encoder_funcs nv17_tv_funcs
= {
775 .destroy
= nv17_tv_destroy
,
779 nv17_tv_create(struct drm_connector
*connector
, struct dcb_entry
*entry
)
781 struct drm_device
*dev
= connector
->dev
;
782 struct drm_encoder
*encoder
;
783 struct nv17_tv_encoder
*tv_enc
= NULL
;
785 tv_enc
= kzalloc(sizeof(*tv_enc
), GFP_KERNEL
);
789 tv_enc
->overscan
= 50;
790 tv_enc
->flicker
= 50;
791 tv_enc
->saturation
= 50;
793 tv_enc
->tv_norm
= TV_NORM_PAL
;
794 tv_enc
->subconnector
= DRM_MODE_SUBCONNECTOR_Unknown
;
795 tv_enc
->select_subconnector
= DRM_MODE_SUBCONNECTOR_Automatic
;
796 tv_enc
->pin_mask
= 0;
798 encoder
= to_drm_encoder(&tv_enc
->base
);
800 tv_enc
->base
.dcb
= entry
;
801 tv_enc
->base
.or = ffs(entry
->or) - 1;
803 drm_encoder_init(dev
, encoder
, &nv17_tv_funcs
, DRM_MODE_ENCODER_TVDAC
);
804 drm_encoder_helper_add(encoder
, &nv17_tv_helper_funcs
);
805 to_encoder_slave(encoder
)->slave_funcs
= &nv17_tv_slave_funcs
;
807 encoder
->possible_crtcs
= entry
->heads
;
808 encoder
->possible_clones
= 0;
810 nv17_tv_create_resources(encoder
, connector
);
811 drm_mode_connector_attach_encoder(connector
, encoder
);