aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-07-08 20:37:42 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-07-12 20:13:54 -0400
commit271f29e7b55278bc2e4bab53448eef9b35778664 (patch)
treec3780fb30c8a40ad97664e642ebe0ed4e9f7b1ca
parentbaf8035edb5d8285cbf0bf2d1895b0a787501f8f (diff)
drm/nv50: move dp_set_tmds() function to happen in the last display irq
It seems on some chipsets that doing this from the 0x20 handler causes the display engine to not ever signal the final 0x40 stage. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c65
1 files changed, 33 insertions, 32 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index ec1ccf680ddf..c19ed8c8e3b5 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -788,37 +788,6 @@ nv50_display_unk20_dp_hack(struct drm_device *dev, struct dcb_entry *dcb)
788 } 788 }
789} 789}
790 790
791/* If programming a TMDS output on a SOR that can also be configured for
792 * DisplayPort, make sure NV50_SOR_DP_CTRL_ENABLE is forced off.
793 *
794 * It looks like the VBIOS TMDS scripts make an attempt at this, however,
795 * the VBIOS scripts on at least one board I have only switch it off on
796 * link 0, causing a blank display if the output has previously been
797 * programmed for DisplayPort.
798 */
799static void
800nv50_display_unk20_dp_set_tmds(struct drm_device *dev, struct dcb_entry *dcb)
801{
802 int or = ffs(dcb->or) - 1, link = !(dcb->dpconf.sor.link & 1);
803 struct drm_encoder *encoder;
804 u32 tmp;
805
806 if (dcb->type != OUTPUT_TMDS)
807 return;
808
809 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
810 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
811
812 if (nv_encoder->dcb->type == OUTPUT_DP &&
813 nv_encoder->dcb->or & (1 << or)) {
814 tmp = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link));
815 tmp &= ~NV50_SOR_DP_CTRL_ENABLED;
816 nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), tmp);
817 break;
818 }
819 }
820}
821
822static void 791static void
823nv50_display_unk20_handler(struct drm_device *dev) 792nv50_display_unk20_handler(struct drm_device *dev)
824{ 793{
@@ -917,7 +886,6 @@ nv50_display_unk20_handler(struct drm_device *dev)
917 nouveau_bios_run_display_table(dev, dcb, script, pclk); 886 nouveau_bios_run_display_table(dev, dcb, script, pclk);
918 887
919 nv50_display_unk20_dp_hack(dev, dcb); 888 nv50_display_unk20_dp_hack(dev, dcb);
920 nv50_display_unk20_dp_set_tmds(dev, dcb);
921 889
922 if (dcb->type != OUTPUT_ANALOG) { 890 if (dcb->type != OUTPUT_ANALOG) {
923 tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or)); 891 tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or));
@@ -938,6 +906,37 @@ ack:
938 nv_wr32(dev, 0x610030, 0x80000000); 906 nv_wr32(dev, 0x610030, 0x80000000);
939} 907}
940 908
909/* If programming a TMDS output on a SOR that can also be configured for
910 * DisplayPort, make sure NV50_SOR_DP_CTRL_ENABLE is forced off.
911 *
912 * It looks like the VBIOS TMDS scripts make an attempt at this, however,
913 * the VBIOS scripts on at least one board I have only switch it off on
914 * link 0, causing a blank display if the output has previously been
915 * programmed for DisplayPort.
916 */
917static void
918nv50_display_unk40_dp_set_tmds(struct drm_device *dev, struct dcb_entry *dcb)
919{
920 int or = ffs(dcb->or) - 1, link = !(dcb->dpconf.sor.link & 1);
921 struct drm_encoder *encoder;
922 u32 tmp;
923
924 if (dcb->type != OUTPUT_TMDS)
925 return;
926
927 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
928 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
929
930 if (nv_encoder->dcb->type == OUTPUT_DP &&
931 nv_encoder->dcb->or & (1 << or)) {
932 tmp = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link));
933 tmp &= ~NV50_SOR_DP_CTRL_ENABLED;
934 nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), tmp);
935 break;
936 }
937 }
938}
939
941static void 940static void
942nv50_display_unk40_handler(struct drm_device *dev) 941nv50_display_unk40_handler(struct drm_device *dev)
943{ 942{
@@ -952,6 +951,8 @@ nv50_display_unk40_handler(struct drm_device *dev)
952 goto ack; 951 goto ack;
953 952
954 nouveau_bios_run_display_table(dev, dcb, script, -pclk); 953 nouveau_bios_run_display_table(dev, dcb, script, -pclk);
954 nv50_display_unk40_dp_set_tmds(dev, dcb);
955
955ack: 956ack:
956 nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK40); 957 nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK40);
957 nv_wr32(dev, 0x610030, 0x80000000); 958 nv_wr32(dev, 0x610030, 0x80000000);