42 #define FP_TG_CONTROL_ON (NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS | \
43 NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS | \
44 NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS)
45 #define FP_TG_CONTROL_OFF (NV_PRAMDAC_FP_TG_CONTROL_DISPEN_DISABLE | \
46 NV_PRAMDAC_FP_TG_CONTROL_HSYNC_DISABLE | \
47 NV_PRAMDAC_FP_TG_CONTROL_VSYNC_DISABLE)
49 static inline bool is_fpc_off(
uint32_t fpc)
87 nv_write_tmds(dev, dcbent->
or, 0, 0x04, tmds04);
90 nv_write_tmds(dev, dcbent->
or, 1, 0x04, tmds04 ^ 0x08);
124 if (is_fpc_off(*fpc)) {
140 if (!is_fpc_off(*fpc) && !nv_crtc->
fp_users) {
145 NVWriteRAMDAC(dev, nv_crtc->
index,
182 static bool nv04_dfp_mode_fixup(
struct drm_encoder *encoder,
193 nv_encoder->
mode = *adjusted_mode;
203 static void nv04_dfp_prepare_sel_clk(
struct drm_device *dev,
240 state->
sel_clk |= (head ? 0x40 : 0x10) << shift;
244 static void nv04_dfp_prepare(
struct drm_encoder *encoder)
256 nv04_dfp_prepare_sel_clk(dev, nv_encoder, head);
260 if (nv_two_heads(dev)) {
262 *cr_lcd |= head ? 0x0 : 0x8;
264 *cr_lcd |= (nv_encoder->
dcb->or << 4) & 0x30;
267 if ((*cr_lcd & 0x30) == (*cr_lcd_oth & 0x30)) {
269 *cr_lcd_oth &= ~0x30;
270 NVWriteVgaCrtc(dev, head ^ 1,
279 static void nv04_dfp_mode_set(
struct drm_encoder *encoder,
301 if (!nv_gf4_disp_arch(dev) ||
303 drm->
vbios.digital_min_front_porch)
341 output_mode->
clock > 165000)
344 bool duallink =
false,
dummy;
345 if (nv_connector->
edid &&
347 duallink = (((
u8 *)nv_connector->
edid)[121] == 2);
356 if (output_mode->
clock > 165000)
378 mode_ratio != panel_ratio) {
380 bool divide_by_2 = nv_gf4_disp_arch(dev);
382 if (mode_ratio < panel_ratio) {
393 output_mode->
vdisplay * mode_ratio / (1 << 12);
398 if (mode_ratio > panel_ratio) {
409 (1 << 12) * output_mode->
hdisplay / mode_ratio;
419 if (nv_device(drm->
device)->chipset == 0x11)
430 if (nv_device(drm->
device)->chipset != 0x11) {
433 for (i = 0; i < 3; i++) {
444 static void nv04_dfp_commit(
struct drm_encoder *encoder)
466 if (nv_device(drm->
device)->chipset < 0x44)
472 slave_encoder = get_tmds_slave(encoder);
474 get_slave_funcs(slave_encoder)->mode_set(
475 slave_encoder, &nv_encoder->
mode, &nv_encoder->
mode);
479 NV_DEBUG(drm,
"Output %s is running on CRTC %d using output %c\n",
484 static void nv04_dfp_update_backlight(
struct drm_encoder *encoder,
int mode)
493 if (dev->pci_device == 0x0179 || dev->pci_device == 0x0189 ||
494 dev->pci_device == 0x0329) {
506 static inline bool is_powersaving_dpms(
int mode)
511 static void nv04_lvds_dpms(
struct drm_encoder *encoder,
int mode)
517 bool was_powersaving = is_powersaving_dpms(nv_encoder->
last_dpms);
523 NV_DEBUG(drm,
"Setting dpms mode %d on lvds encoder (output %d)\n",
524 mode, nv_encoder->
dcb->index);
526 if (was_powersaving && is_powersaving_dpms(mode))
529 if (nv_encoder->
dcb->lvdsconf.use_power_scripts) {
547 nv04_dfp_update_backlight(encoder, mode);
559 static void nv04_tmds_dpms(
struct drm_encoder *encoder,
int mode)
568 NV_DEBUG(drm,
"Setting dpms mode %d on tmds encoder (output %d)\n",
569 mode, nv_encoder->
dcb->index);
571 nv04_dfp_update_backlight(encoder, mode);
575 static void nv04_dfp_save(
struct drm_encoder *encoder)
580 if (nv_two_heads(dev))
585 static void nv04_dfp_restore(
struct drm_encoder *encoder)
589 int head = nv_encoder->
restore.head;
610 static void nv04_dfp_destroy(
struct drm_encoder *encoder)
614 if (get_slave_funcs(encoder))
615 get_slave_funcs(encoder)->destroy(encoder);
621 static void nv04_tmds_slave_init(
struct drm_encoder *encoder)
631 .addr = (dcb->
tmdsconf.slave_addr == 0x7 ? 0x3a : 0x38),
633 SIL164_INPUT_EDGE_RISING
640 if (!nv_gf4_disp_arch(dev) || !port ||
641 get_tmds_slave(encoder))
644 type = i2c->
identify(i2c, 2,
"TMDS transmitter", info,
NULL);
653 .dpms = nv04_lvds_dpms,
654 .save = nv04_dfp_save,
655 .restore = nv04_dfp_restore,
656 .mode_fixup = nv04_dfp_mode_fixup,
657 .prepare = nv04_dfp_prepare,
658 .commit = nv04_dfp_commit,
659 .mode_set = nv04_dfp_mode_set,
664 .dpms = nv04_tmds_dpms,
665 .save = nv04_dfp_save,
666 .restore = nv04_dfp_restore,
667 .mode_fixup = nv04_dfp_mode_fixup,
668 .prepare = nv04_dfp_prepare,
669 .commit = nv04_dfp_commit,
670 .mode_set = nv04_dfp_mode_set,
675 .destroy = nv04_dfp_destroy,
686 switch (entry->
type) {
689 helper = &nv04_tmds_helper_funcs;
693 helper = &nv04_lvds_helper_funcs;
699 nv_encoder = kzalloc(
sizeof(*nv_encoder),
GFP_KERNEL);
703 encoder = to_drm_encoder(nv_encoder);
706 nv_encoder->
or =
ffs(entry->
or) - 1;
709 drm_encoder_helper_add(encoder, helper);
716 nv04_tmds_slave_init(encoder);