diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-07-07 22:52:14 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-09-20 02:07:36 -0400 |
commit | 3b6d83d1b9f9be1c9778c2c6fa6761b440734fdd (patch) | |
tree | 1c32bae50b918f50e4268b1289d495e301b166dd /drivers/gpu/drm/nouveau/nvd0_display.c | |
parent | c6f2f71daed12f57d6f72769b49d29c7391f24ae (diff) |
drm/nvd0/disp: untested LVDS support
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvd0_display.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvd0_display.c | 82 |
1 files changed, 66 insertions, 16 deletions
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index 45f8a31e9ac3..1a561d308215 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c | |||
@@ -816,26 +816,66 @@ nvd0_sor_commit(struct drm_encoder *encoder) | |||
816 | } | 816 | } |
817 | 817 | ||
818 | static void | 818 | static void |
819 | nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | 819 | nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, |
820 | struct drm_display_mode *adjusted_mode) | 820 | struct drm_display_mode *mode) |
821 | { | 821 | { |
822 | struct drm_nouveau_private *dev_priv = encoder->dev->dev_private; | ||
822 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 823 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
823 | struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); | 824 | struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); |
825 | struct nouveau_connector *nv_connector; | ||
826 | struct nvbios *bios = &dev_priv->vbios; | ||
824 | u32 mode_ctrl = (1 << nv_crtc->index); | 827 | u32 mode_ctrl = (1 << nv_crtc->index); |
825 | u32 *push, or_config; | 828 | u32 *push, or_config; |
826 | 829 | ||
827 | if (nv_encoder->dcb->sorconf.link & 1) { | 830 | nv_connector = nouveau_encoder_connector_get(nv_encoder); |
828 | if (adjusted_mode->clock < 165000) | 831 | switch (nv_encoder->dcb->type) { |
829 | mode_ctrl |= 0x00000100; | 832 | case OUTPUT_TMDS: |
830 | else | 833 | if (nv_encoder->dcb->sorconf.link & 1) { |
831 | mode_ctrl |= 0x00000500; | 834 | if (mode->clock < 165000) |
832 | } else { | 835 | mode_ctrl |= 0x00000100; |
833 | mode_ctrl |= 0x00000200; | 836 | else |
834 | } | 837 | mode_ctrl |= 0x00000500; |
838 | } else { | ||
839 | mode_ctrl |= 0x00000200; | ||
840 | } | ||
841 | |||
842 | or_config = (mode_ctrl & 0x00000f00) >> 8; | ||
843 | if (mode->clock >= 165000) | ||
844 | or_config |= 0x0100; | ||
845 | break; | ||
846 | case OUTPUT_LVDS: | ||
847 | or_config = (mode_ctrl & 0x00000f00) >> 8; | ||
848 | if (bios->fp_no_ddc) { | ||
849 | if (bios->fp.dual_link) | ||
850 | or_config |= 0x0100; | ||
851 | if (bios->fp.if_is_24bit) | ||
852 | or_config |= 0x0200; | ||
853 | } else { | ||
854 | if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS_SPWG) { | ||
855 | if (((u8 *)nv_connector->edid)[121] == 2) | ||
856 | or_config |= 0x0100; | ||
857 | } else | ||
858 | if (mode->clock >= bios->fp.duallink_transition_clk) { | ||
859 | or_config |= 0x0100; | ||
860 | } | ||
835 | 861 | ||
836 | or_config = (mode_ctrl & 0x00000f00) >> 8; | 862 | if (or_config & 0x0100) { |
837 | if (adjusted_mode->clock >= 165000) | 863 | if (bios->fp.strapless_is_24bit & 2) |
838 | or_config |= 0x0100; | 864 | or_config |= 0x0200; |
865 | } else { | ||
866 | if (bios->fp.strapless_is_24bit & 1) | ||
867 | or_config |= 0x0200; | ||
868 | } | ||
869 | |||
870 | if (nv_connector->base.display_info.bpc == 8) | ||
871 | or_config |= 0x0200; | ||
872 | |||
873 | } | ||
874 | break; | ||
875 | default: | ||
876 | BUG_ON(1); | ||
877 | break; | ||
878 | } | ||
839 | 879 | ||
840 | nvd0_sor_dpms(encoder, DRM_MODE_DPMS_ON); | 880 | nvd0_sor_dpms(encoder, DRM_MODE_DPMS_ON); |
841 | 881 | ||
@@ -932,8 +972,16 @@ lookup_dcb(struct drm_device *dev, int id, u32 mc) | |||
932 | type = OUTPUT_ANALOG; | 972 | type = OUTPUT_ANALOG; |
933 | or = id; | 973 | or = id; |
934 | } else { | 974 | } else { |
935 | type = OUTPUT_TMDS; | 975 | switch (mc & 0x00000f00) { |
936 | or = id - 4; | 976 | case 0x00000000: type = OUTPUT_LVDS; break; |
977 | case 0x00000100: type = OUTPUT_TMDS; break; | ||
978 | case 0x00000200: type = OUTPUT_TMDS; break; | ||
979 | case 0x00000500: type = OUTPUT_TMDS; break; | ||
980 | default: | ||
981 | return NULL; | ||
982 | } | ||
983 | |||
984 | or = id - 4; | ||
937 | } | 985 | } |
938 | 986 | ||
939 | for (i = 0; i < dev_priv->vbios.dcb.entries; i++) { | 987 | for (i = 0; i < dev_priv->vbios.dcb.entries; i++) { |
@@ -1024,7 +1072,8 @@ nvd0_display_unk2_handler(struct drm_device *dev) | |||
1024 | nv_wr32(dev, 0x612280 + (or * 0x800), 0x00000000); | 1072 | nv_wr32(dev, 0x612280 + (or * 0x800), 0x00000000); |
1025 | break; | 1073 | break; |
1026 | case OUTPUT_TMDS: | 1074 | case OUTPUT_TMDS: |
1027 | if (disp->irq.pclk >= 165000) | 1075 | case OUTPUT_LVDS: |
1076 | if (disp->irq.cfg & 0x00000100) | ||
1028 | tmp = 0x00000101; | 1077 | tmp = 0x00000101; |
1029 | else | 1078 | else |
1030 | tmp = 0x00000000; | 1079 | tmp = 0x00000000; |
@@ -1298,6 +1347,7 @@ nvd0_display_create(struct drm_device *dev) | |||
1298 | 1347 | ||
1299 | switch (dcbe->type) { | 1348 | switch (dcbe->type) { |
1300 | case OUTPUT_TMDS: | 1349 | case OUTPUT_TMDS: |
1350 | case OUTPUT_LVDS: | ||
1301 | nvd0_sor_create(connector, dcbe); | 1351 | nvd0_sor_create(connector, dcbe); |
1302 | break; | 1352 | break; |
1303 | case OUTPUT_ANALOG: | 1353 | case OUTPUT_ANALOG: |