diff options
author | Francisco Jerez <currojerez@riseup.net> | 2010-07-20 10:48:08 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-08-05 18:34:59 -0400 |
commit | 4a9f822fe1a6ca5de7d8cdd5efbead3b9ab4283b (patch) | |
tree | 201e0191a1414ff04fe867e2bc6b2dfae8809fe3 /drivers/gpu | |
parent | d2f4e89254b5816925a207a221e6b26100357eea (diff) |
drm/nv17-nv4x: Attempt to init some external TMDS transmitters.
sil164 and friends are the most common, usually they just need to be
poked once because a fixed configuration is enough for any modes and
clocks, so they worked without this patch if the BIOS had done a good
job on POST. Display couldn't survive a suspend/resume cycle though.
Unfortunately, BIOS scripts are useless here.
Signed-off-by: Francisco Jerez <currojerez@riseup.net>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_bios.c | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_bios.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_connector.c | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_encoder.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_hw.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv04_crtc.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv04_dfp.c | 42 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv04_tv.c | 9 |
9 files changed, 93 insertions, 21 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index c608b0b29a36..e86f46cf8837 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
@@ -5982,7 +5982,13 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, | |||
5982 | } | 5982 | } |
5983 | break; | 5983 | break; |
5984 | case OUTPUT_TMDS: | 5984 | case OUTPUT_TMDS: |
5985 | entry->tmdsconf.sor.link = (conf & 0x00000030) >> 4; | 5985 | if (dcb->version >= 0x22) |
5986 | entry->tmdsconf.slave_addr = (conf & 0x00000070) >> 4; | ||
5987 | else if (dcb->version >= 0x30) | ||
5988 | entry->tmdsconf.slave_addr = (conf & 0x00000700) >> 8; | ||
5989 | else if (dcb->version >= 0x40) | ||
5990 | entry->tmdsconf.sor.link = (conf & 0x00000030) >> 4; | ||
5991 | |||
5986 | break; | 5992 | break; |
5987 | case 0xe: | 5993 | case 0xe: |
5988 | /* weird g80 mobile type that "nv" treats as a terminator */ | 5994 | /* weird g80 mobile type that "nv" treats as a terminator */ |
@@ -6272,6 +6278,19 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) | |||
6272 | dcb->i2c_table = &bios->data[i2ctabptr]; | 6278 | dcb->i2c_table = &bios->data[i2ctabptr]; |
6273 | if (dcb->version >= 0x30) | 6279 | if (dcb->version >= 0x30) |
6274 | dcb->i2c_default_indices = dcb->i2c_table[4]; | 6280 | dcb->i2c_default_indices = dcb->i2c_table[4]; |
6281 | |||
6282 | /* | ||
6283 | * Parse the "management" I2C bus, used for hardware | ||
6284 | * monitoring and some external TMDS transmitters. | ||
6285 | */ | ||
6286 | if (dcb->version >= 0x22) { | ||
6287 | int idx = (dcb->version >= 0x40 ? | ||
6288 | dcb->i2c_default_indices & 0xf : | ||
6289 | 2); | ||
6290 | |||
6291 | read_dcb_i2c_entry(dev, dcb->version, dcb->i2c_table, | ||
6292 | idx, &dcb->i2c[idx]); | ||
6293 | } | ||
6275 | } | 6294 | } |
6276 | 6295 | ||
6277 | if (entries > DCB_MAX_NUM_ENTRIES) | 6296 | if (entries > DCB_MAX_NUM_ENTRIES) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index 024458a8d060..fd14dfd3d780 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h | |||
@@ -131,6 +131,7 @@ struct dcb_entry { | |||
131 | } dpconf; | 131 | } dpconf; |
132 | struct { | 132 | struct { |
133 | struct sor_conf sor; | 133 | struct sor_conf sor; |
134 | int slave_addr; | ||
134 | } tmdsconf; | 135 | } tmdsconf; |
135 | }; | 136 | }; |
136 | bool i2c_upper_default; | 137 | bool i2c_upper_default; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 734e92635e83..b1b22baf1428 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
@@ -37,12 +37,6 @@ | |||
37 | #include "nouveau_connector.h" | 37 | #include "nouveau_connector.h" |
38 | #include "nouveau_hw.h" | 38 | #include "nouveau_hw.h" |
39 | 39 | ||
40 | static inline struct drm_encoder_slave_funcs * | ||
41 | get_slave_funcs(struct nouveau_encoder *enc) | ||
42 | { | ||
43 | return to_encoder_slave(to_drm_encoder(enc))->slave_funcs; | ||
44 | } | ||
45 | |||
46 | static struct nouveau_encoder * | 40 | static struct nouveau_encoder * |
47 | find_encoder_by_type(struct drm_connector *connector, int type) | 41 | find_encoder_by_type(struct drm_connector *connector, int type) |
48 | { | 42 | { |
@@ -360,6 +354,7 @@ nouveau_connector_set_property(struct drm_connector *connector, | |||
360 | { | 354 | { |
361 | struct nouveau_connector *nv_connector = nouveau_connector(connector); | 355 | struct nouveau_connector *nv_connector = nouveau_connector(connector); |
362 | struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; | 356 | struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; |
357 | struct drm_encoder *encoder = to_drm_encoder(nv_encoder); | ||
363 | struct drm_device *dev = connector->dev; | 358 | struct drm_device *dev = connector->dev; |
364 | int ret; | 359 | int ret; |
365 | 360 | ||
@@ -432,8 +427,8 @@ nouveau_connector_set_property(struct drm_connector *connector, | |||
432 | } | 427 | } |
433 | 428 | ||
434 | if (nv_encoder && nv_encoder->dcb->type == OUTPUT_TV) | 429 | if (nv_encoder && nv_encoder->dcb->type == OUTPUT_TV) |
435 | return get_slave_funcs(nv_encoder)-> | 430 | return get_slave_funcs(encoder)->set_property( |
436 | set_property(to_drm_encoder(nv_encoder), connector, property, value); | 431 | encoder, connector, property, value); |
437 | 432 | ||
438 | return -EINVAL; | 433 | return -EINVAL; |
439 | } | 434 | } |
@@ -545,6 +540,7 @@ nouveau_connector_get_modes(struct drm_connector *connector) | |||
545 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 540 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
546 | struct nouveau_connector *nv_connector = nouveau_connector(connector); | 541 | struct nouveau_connector *nv_connector = nouveau_connector(connector); |
547 | struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; | 542 | struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; |
543 | struct drm_encoder *encoder = to_drm_encoder(nv_encoder); | ||
548 | int ret = 0; | 544 | int ret = 0; |
549 | 545 | ||
550 | /* destroy the native mode, the attached monitor could have changed. | 546 | /* destroy the native mode, the attached monitor could have changed. |
@@ -580,8 +576,7 @@ nouveau_connector_get_modes(struct drm_connector *connector) | |||
580 | } | 576 | } |
581 | 577 | ||
582 | if (nv_encoder->dcb->type == OUTPUT_TV) | 578 | if (nv_encoder->dcb->type == OUTPUT_TV) |
583 | ret = get_slave_funcs(nv_encoder)-> | 579 | ret = get_slave_funcs(encoder)->get_modes(encoder, connector); |
584 | get_modes(to_drm_encoder(nv_encoder), connector); | ||
585 | 580 | ||
586 | if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS || | 581 | if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS || |
587 | nv_connector->dcb->type == DCB_CONNECTOR_eDP) | 582 | nv_connector->dcb->type == DCB_CONNECTOR_eDP) |
@@ -597,6 +592,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector, | |||
597 | struct drm_nouveau_private *dev_priv = connector->dev->dev_private; | 592 | struct drm_nouveau_private *dev_priv = connector->dev->dev_private; |
598 | struct nouveau_connector *nv_connector = nouveau_connector(connector); | 593 | struct nouveau_connector *nv_connector = nouveau_connector(connector); |
599 | struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; | 594 | struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; |
595 | struct drm_encoder *encoder = to_drm_encoder(nv_encoder); | ||
600 | unsigned min_clock = 25000, max_clock = min_clock; | 596 | unsigned min_clock = 25000, max_clock = min_clock; |
601 | unsigned clock = mode->clock; | 597 | unsigned clock = mode->clock; |
602 | 598 | ||
@@ -623,8 +619,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector, | |||
623 | max_clock = 350000; | 619 | max_clock = 350000; |
624 | break; | 620 | break; |
625 | case OUTPUT_TV: | 621 | case OUTPUT_TV: |
626 | return get_slave_funcs(nv_encoder)-> | 622 | return get_slave_funcs(encoder)->mode_valid(encoder, mode); |
627 | mode_valid(to_drm_encoder(nv_encoder), mode); | ||
628 | case OUTPUT_DP: | 623 | case OUTPUT_DP: |
629 | if (nv_encoder->dp.link_bw == DP_LINK_BW_2_7) | 624 | if (nv_encoder->dp.link_bw == DP_LINK_BW_2_7) |
630 | max_clock = nv_encoder->dp.link_nr * 270000; | 625 | max_clock = nv_encoder->dp.link_nr * 270000; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index db10809e9131..9e17d88bc890 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -410,7 +410,7 @@ enum nv04_fp_display_regs { | |||
410 | 410 | ||
411 | struct nv04_crtc_reg { | 411 | struct nv04_crtc_reg { |
412 | unsigned char MiscOutReg; /* */ | 412 | unsigned char MiscOutReg; /* */ |
413 | uint8_t CRTC[0x9f]; | 413 | uint8_t CRTC[0xa0]; |
414 | uint8_t CR58[0x10]; | 414 | uint8_t CR58[0x10]; |
415 | uint8_t Sequencer[5]; | 415 | uint8_t Sequencer[5]; |
416 | uint8_t Graphics[9]; | 416 | uint8_t Graphics[9]; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h index a1a0d48ae70c..7c82d68bc155 100644 --- a/drivers/gpu/drm/nouveau/nouveau_encoder.h +++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h | |||
@@ -71,6 +71,12 @@ static inline struct drm_encoder *to_drm_encoder(struct nouveau_encoder *enc) | |||
71 | return &enc->base.base; | 71 | return &enc->base.base; |
72 | } | 72 | } |
73 | 73 | ||
74 | static inline struct drm_encoder_slave_funcs * | ||
75 | get_slave_funcs(struct drm_encoder *enc) | ||
76 | { | ||
77 | return to_encoder_slave(enc)->slave_funcs; | ||
78 | } | ||
79 | |||
74 | struct nouveau_connector * | 80 | struct nouveau_connector * |
75 | nouveau_encoder_connector_get(struct nouveau_encoder *encoder); | 81 | nouveau_encoder_connector_get(struct nouveau_encoder *encoder); |
76 | int nv50_sor_create(struct drm_connector *, struct dcb_entry *); | 82 | int nv50_sor_create(struct drm_connector *, struct dcb_entry *); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/nouveau_hw.c index 7855b35effc3..7b613682e400 100644 --- a/drivers/gpu/drm/nouveau/nouveau_hw.c +++ b/drivers/gpu/drm/nouveau/nouveau_hw.c | |||
@@ -865,8 +865,12 @@ nv_save_state_ext(struct drm_device *dev, int head, | |||
865 | rd_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX); | 865 | rd_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX); |
866 | rd_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX); | 866 | rd_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX); |
867 | rd_cio_state(dev, head, regp, NV_CIO_CRE_21); | 867 | rd_cio_state(dev, head, regp, NV_CIO_CRE_21); |
868 | if (dev_priv->card_type >= NV_30) | 868 | |
869 | if (dev_priv->card_type >= NV_30) { | ||
869 | rd_cio_state(dev, head, regp, NV_CIO_CRE_47); | 870 | rd_cio_state(dev, head, regp, NV_CIO_CRE_47); |
871 | rd_cio_state(dev, head, regp, 0x9f); | ||
872 | } | ||
873 | |||
870 | rd_cio_state(dev, head, regp, NV_CIO_CRE_49); | 874 | rd_cio_state(dev, head, regp, NV_CIO_CRE_49); |
871 | rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX); | 875 | rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX); |
872 | rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX); | 876 | rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX); |
@@ -971,8 +975,11 @@ nv_load_state_ext(struct drm_device *dev, int head, | |||
971 | wr_cio_state(dev, head, regp, NV_CIO_CRE_ENH_INDEX); | 975 | wr_cio_state(dev, head, regp, NV_CIO_CRE_ENH_INDEX); |
972 | wr_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX); | 976 | wr_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX); |
973 | wr_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX); | 977 | wr_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX); |
974 | if (dev_priv->card_type >= NV_30) | 978 | |
979 | if (dev_priv->card_type >= NV_30) { | ||
975 | wr_cio_state(dev, head, regp, NV_CIO_CRE_47); | 980 | wr_cio_state(dev, head, regp, NV_CIO_CRE_47); |
981 | wr_cio_state(dev, head, regp, 0x9f); | ||
982 | } | ||
976 | 983 | ||
977 | wr_cio_state(dev, head, regp, NV_CIO_CRE_49); | 984 | wr_cio_state(dev, head, regp, NV_CIO_CRE_49); |
978 | wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX); | 985 | wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX); |
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c index 1c20c08ce67c..08c7e073edce 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c | |||
@@ -542,6 +542,9 @@ nv_crtc_mode_set_regs(struct drm_crtc *crtc, struct drm_display_mode * mode) | |||
542 | * 1 << 30 on 0x60.830), for no apparent reason */ | 542 | * 1 << 30 on 0x60.830), for no apparent reason */ |
543 | regp->CRTC[NV_CIO_CRE_59] = off_chip_digital; | 543 | regp->CRTC[NV_CIO_CRE_59] = off_chip_digital; |
544 | 544 | ||
545 | if (dev_priv->card_type >= NV_30) | ||
546 | regp->CRTC[0x9f] = off_chip_digital ? 0x11 : 0x1; | ||
547 | |||
545 | regp->crtc_830 = mode->crtc_vdisplay - 3; | 548 | regp->crtc_830 = mode->crtc_vdisplay - 3; |
546 | regp->crtc_834 = mode->crtc_vdisplay - 1; | 549 | regp->crtc_834 = mode->crtc_vdisplay - 1; |
547 | 550 | ||
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index 3311f3a8c818..9871570d2ff4 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include "nouveau_hw.h" | 34 | #include "nouveau_hw.h" |
35 | #include "nvreg.h" | 35 | #include "nvreg.h" |
36 | 36 | ||
37 | #include "i2c/sil164.h" | ||
38 | |||
37 | #define FP_TG_CONTROL_ON (NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS | \ | 39 | #define FP_TG_CONTROL_ON (NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS | \ |
38 | NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS | \ | 40 | NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS | \ |
39 | NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS) | 41 | NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS) |
@@ -429,6 +431,11 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) | |||
429 | else | 431 | else |
430 | NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000); | 432 | NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000); |
431 | 433 | ||
434 | /* Init external transmitters */ | ||
435 | if (get_slave_funcs(encoder)) | ||
436 | get_slave_funcs(encoder)->mode_set(encoder, &nv_encoder->mode, | ||
437 | &nv_encoder->mode); | ||
438 | |||
432 | helper->dpms(encoder, DRM_MODE_DPMS_ON); | 439 | helper->dpms(encoder, DRM_MODE_DPMS_ON); |
433 | 440 | ||
434 | NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", | 441 | NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", |
@@ -550,10 +557,41 @@ static void nv04_dfp_destroy(struct drm_encoder *encoder) | |||
550 | 557 | ||
551 | NV_DEBUG_KMS(encoder->dev, "\n"); | 558 | NV_DEBUG_KMS(encoder->dev, "\n"); |
552 | 559 | ||
560 | if (get_slave_funcs(encoder)) | ||
561 | get_slave_funcs(encoder)->destroy(encoder); | ||
562 | |||
553 | drm_encoder_cleanup(encoder); | 563 | drm_encoder_cleanup(encoder); |
554 | kfree(nv_encoder); | 564 | kfree(nv_encoder); |
555 | } | 565 | } |
556 | 566 | ||
567 | static void nv04_tmds_slave_init(struct drm_encoder *encoder) | ||
568 | { | ||
569 | struct drm_device *dev = encoder->dev; | ||
570 | struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; | ||
571 | struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, 2); | ||
572 | struct i2c_board_info info[] = { | ||
573 | { | ||
574 | .type = "sil164", | ||
575 | .addr = (dcb->tmdsconf.slave_addr == 0x7 ? 0x3a : 0x38), | ||
576 | .platform_data = &(struct sil164_encoder_params) { | ||
577 | SIL164_INPUT_EDGE_RISING | ||
578 | } | ||
579 | }, | ||
580 | { } | ||
581 | }; | ||
582 | int type; | ||
583 | |||
584 | if (!nv_gf4_disp_arch(dev) || !i2c) | ||
585 | return; | ||
586 | |||
587 | type = nouveau_i2c_identify(dev, "TMDS transmitter", info, 2); | ||
588 | if (type < 0) | ||
589 | return; | ||
590 | |||
591 | drm_i2c_encoder_init(dev, to_encoder_slave(encoder), | ||
592 | &i2c->adapter, &info[type]); | ||
593 | } | ||
594 | |||
557 | static const struct drm_encoder_helper_funcs nv04_lvds_helper_funcs = { | 595 | static const struct drm_encoder_helper_funcs nv04_lvds_helper_funcs = { |
558 | .dpms = nv04_lvds_dpms, | 596 | .dpms = nv04_lvds_dpms, |
559 | .save = nv04_dfp_save, | 597 | .save = nv04_dfp_save, |
@@ -616,6 +654,10 @@ nv04_dfp_create(struct drm_connector *connector, struct dcb_entry *entry) | |||
616 | encoder->possible_crtcs = entry->heads; | 654 | encoder->possible_crtcs = entry->heads; |
617 | encoder->possible_clones = 0; | 655 | encoder->possible_clones = 0; |
618 | 656 | ||
657 | if (entry->type == OUTPUT_TMDS && | ||
658 | entry->location != DCB_LOC_ON_CHIP) | ||
659 | nv04_tmds_slave_init(encoder); | ||
660 | |||
619 | drm_mode_connector_attach_encoder(connector, encoder); | 661 | drm_mode_connector_attach_encoder(connector, encoder); |
620 | return 0; | 662 | return 0; |
621 | } | 663 | } |
diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c index 94e299cef0b2..4e73c4461a22 100644 --- a/drivers/gpu/drm/nouveau/nv04_tv.c +++ b/drivers/gpu/drm/nouveau/nv04_tv.c | |||
@@ -89,7 +89,7 @@ static void nv04_tv_dpms(struct drm_encoder *encoder, int mode) | |||
89 | 89 | ||
90 | NVWriteRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT, state->pllsel); | 90 | NVWriteRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT, state->pllsel); |
91 | 91 | ||
92 | to_encoder_slave(encoder)->slave_funcs->dpms(encoder, mode); | 92 | get_slave_funcs(encoder)->dpms(encoder, mode); |
93 | } | 93 | } |
94 | 94 | ||
95 | static void nv04_tv_bind(struct drm_device *dev, int head, bool bind) | 95 | static void nv04_tv_bind(struct drm_device *dev, int head, bool bind) |
@@ -152,7 +152,7 @@ static void nv04_tv_mode_set(struct drm_encoder *encoder, | |||
152 | regp->tv_vskew = 1; | 152 | regp->tv_vskew = 1; |
153 | regp->tv_vsync_delay = 1; | 153 | regp->tv_vsync_delay = 1; |
154 | 154 | ||
155 | to_encoder_slave(encoder)->slave_funcs->mode_set(encoder, mode, adjusted_mode); | 155 | get_slave_funcs(encoder)->mode_set(encoder, mode, adjusted_mode); |
156 | } | 156 | } |
157 | 157 | ||
158 | static void nv04_tv_commit(struct drm_encoder *encoder) | 158 | static void nv04_tv_commit(struct drm_encoder *encoder) |
@@ -171,8 +171,7 @@ static void nv04_tv_commit(struct drm_encoder *encoder) | |||
171 | 171 | ||
172 | static void nv04_tv_destroy(struct drm_encoder *encoder) | 172 | static void nv04_tv_destroy(struct drm_encoder *encoder) |
173 | { | 173 | { |
174 | to_encoder_slave(encoder)->slave_funcs->destroy(encoder); | 174 | get_slave_funcs(encoder)->destroy(encoder); |
175 | |||
176 | drm_encoder_cleanup(encoder); | 175 | drm_encoder_cleanup(encoder); |
177 | 176 | ||
178 | kfree(encoder->helper_private); | 177 | kfree(encoder->helper_private); |
@@ -229,7 +228,7 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry) | |||
229 | goto fail_cleanup; | 228 | goto fail_cleanup; |
230 | 229 | ||
231 | /* Fill the function pointers */ | 230 | /* Fill the function pointers */ |
232 | sfuncs = to_encoder_slave(encoder)->slave_funcs; | 231 | sfuncs = get_slave_funcs(encoder); |
233 | 232 | ||
234 | *hfuncs = (struct drm_encoder_helper_funcs) { | 233 | *hfuncs = (struct drm_encoder_helper_funcs) { |
235 | .dpms = nv04_tv_dpms, | 234 | .dpms = nv04_tv_dpms, |