diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2008-07-24 00:30:55 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-24 13:47:35 -0400 |
commit | 7f762d23e607af786bba8ff4a18059f43950c0e8 (patch) | |
tree | 6990e342c1b977821c0eec7bd79abc735f6c6ff2 /drivers/video/tridentfb.c | |
parent | 10172ed6dc4d40ff42bf5ce2dd2f65f401a93696 (diff) |
tridentfb: fix timing calculations
Fix broken timings calculations. This patch helps with following
problems:
- no left part of screen visible (up to half of the screen)
- monitor's frequencies are not the ones intended for selected modes
- if mode with resoultion y > 1024 is selected at least once then
all modes with y < 1024 are "out of sync" (no display)
Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/tridentfb.c')
-rw-r--r-- | drivers/video/tridentfb.c | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c index 381e5853df6f..af02af11353c 100644 --- a/drivers/video/tridentfb.c +++ b/drivers/video/tridentfb.c | |||
@@ -886,20 +886,19 @@ static int tridentfb_set_par(struct fb_info *info) | |||
886 | 886 | ||
887 | debug("enter\n"); | 887 | debug("enter\n"); |
888 | hdispend = var->xres / 8 - 1; | 888 | hdispend = var->xres / 8 - 1; |
889 | hsyncstart = (var->xres + var->right_margin) / 8; | 889 | hsyncstart = (var->xres + var->right_margin) / 8 - 1; |
890 | hsyncend = var->hsync_len / 8; | 890 | hsyncend = (var->xres + var->right_margin + var->hsync_len) / 8 - 1; |
891 | htotal = | 891 | htotal = (var->xres + var->left_margin + var->right_margin + |
892 | (var->xres + var->left_margin + var->right_margin + | 892 | var->hsync_len) / 8 - 5; |
893 | var->hsync_len) / 8 - 10; | 893 | hblankstart = hdispend + 2; |
894 | hblankstart = hdispend + 1; | 894 | hblankend = htotal + 3; |
895 | hblankend = htotal + 5; | ||
896 | 895 | ||
897 | vdispend = var->yres - 1; | 896 | vdispend = var->yres - 1; |
898 | vsyncstart = var->yres + var->lower_margin; | 897 | vsyncstart = var->yres + var->lower_margin; |
899 | vsyncend = var->vsync_len; | 898 | vsyncend = vsyncstart + var->vsync_len; |
900 | vtotal = var->upper_margin + vsyncstart + vsyncend - 2; | 899 | vtotal = var->upper_margin + vsyncend - 2; |
901 | vblankstart = var->yres; | 900 | vblankstart = vdispend + 2; |
902 | vblankend = vtotal + 2; | 901 | vblankend = vtotal; |
903 | 902 | ||
904 | crtc_unlock(par); | 903 | crtc_unlock(par); |
905 | write3CE(par, CyberControl, 8); | 904 | write3CE(par, CyberControl, 8); |
@@ -930,7 +929,7 @@ static int tridentfb_set_par(struct fb_info *info) | |||
930 | write3X4(par, VGA_CRTC_V_SYNC_START, vsyncstart & 0xFF); | 929 | write3X4(par, VGA_CRTC_V_SYNC_START, vsyncstart & 0xFF); |
931 | write3X4(par, VGA_CRTC_V_SYNC_END, (vsyncend & 0x0F)); | 930 | write3X4(par, VGA_CRTC_V_SYNC_END, (vsyncend & 0x0F)); |
932 | write3X4(par, VGA_CRTC_V_BLANK_START, vblankstart & 0xFF); | 931 | write3X4(par, VGA_CRTC_V_BLANK_START, vblankstart & 0xFF); |
933 | write3X4(par, VGA_CRTC_V_BLANK_END, 0 /* p->vblankend & 0xFF */); | 932 | write3X4(par, VGA_CRTC_V_BLANK_END, vblankend & 0xFF); |
934 | 933 | ||
935 | /* horizontal timing values */ | 934 | /* horizontal timing values */ |
936 | write3X4(par, VGA_CRTC_H_TOTAL, htotal & 0xFF); | 935 | write3X4(par, VGA_CRTC_H_TOTAL, htotal & 0xFF); |
@@ -939,7 +938,7 @@ static int tridentfb_set_par(struct fb_info *info) | |||
939 | write3X4(par, VGA_CRTC_H_SYNC_END, | 938 | write3X4(par, VGA_CRTC_H_SYNC_END, |
940 | (hsyncend & 0x1F) | ((hblankend & 0x20) << 2)); | 939 | (hsyncend & 0x1F) | ((hblankend & 0x20) << 2)); |
941 | write3X4(par, VGA_CRTC_H_BLANK_START, hblankstart & 0xFF); | 940 | write3X4(par, VGA_CRTC_H_BLANK_START, hblankstart & 0xFF); |
942 | write3X4(par, VGA_CRTC_H_BLANK_END, 0 /* (p->hblankend & 0x1F) */); | 941 | write3X4(par, VGA_CRTC_H_BLANK_END, hblankend & 0x1F); |
943 | 942 | ||
944 | /* higher bits of vertical timing values */ | 943 | /* higher bits of vertical timing values */ |
945 | tmp = 0x10; | 944 | tmp = 0x10; |
@@ -953,16 +952,18 @@ static int tridentfb_set_par(struct fb_info *info) | |||
953 | if (vsyncstart & 0x200) tmp |= 0x80; | 952 | if (vsyncstart & 0x200) tmp |= 0x80; |
954 | write3X4(par, VGA_CRTC_OVERFLOW, tmp); | 953 | write3X4(par, VGA_CRTC_OVERFLOW, tmp); |
955 | 954 | ||
956 | tmp = read3X4(par, CRTHiOrd) | 0x08; /* line compare bit 10 */ | 955 | tmp = read3X4(par, CRTHiOrd) & 0x07; |
956 | tmp |= 0x08; /* line compare bit 10 */ | ||
957 | if (vtotal & 0x400) tmp |= 0x80; | 957 | if (vtotal & 0x400) tmp |= 0x80; |
958 | if (vblankstart & 0x400) tmp |= 0x40; | 958 | if (vblankstart & 0x400) tmp |= 0x40; |
959 | if (vsyncstart & 0x400) tmp |= 0x20; | 959 | if (vsyncstart & 0x400) tmp |= 0x20; |
960 | if (vdispend & 0x400) tmp |= 0x10; | 960 | if (vdispend & 0x400) tmp |= 0x10; |
961 | write3X4(par, CRTHiOrd, tmp); | 961 | write3X4(par, CRTHiOrd, tmp); |
962 | 962 | ||
963 | tmp = 0; | 963 | tmp = (htotal >> 8) & 0x01; |
964 | if (htotal & 0x800) tmp |= 0x800 >> 11; | 964 | tmp |= (hdispend >> 7) & 0x02; |
965 | if (hblankstart & 0x800) tmp |= 0x800 >> 7; | 965 | tmp |= (hsyncstart >> 5) & 0x08; |
966 | tmp |= (hblankstart >> 4) & 0x10; | ||
966 | write3X4(par, HorizOverflow, tmp); | 967 | write3X4(par, HorizOverflow, tmp); |
967 | 968 | ||
968 | tmp = 0x40; | 969 | tmp = 0x40; |