diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2007-10-16 04:28:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 12:43:15 -0400 |
commit | 254c94710754127631a4e05d3131cef38c9996c7 (patch) | |
tree | b2c95c9ef50bf39b92fdb7b02652c17cec254982 /drivers/video/tdfxfb.c | |
parent | 92744dd517258181af0637105eed5f72d95e05e7 (diff) |
tdfxfb: palette fixes
This patch fixes:
- palette setting in 8-bit mode (aka 'funky penguin')
- grayscale handling
- adds proper barriers in xxx_inb/outb functions
Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: Antonino Daplas <adaplas@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/tdfxfb.c')
-rw-r--r-- | drivers/video/tdfxfb.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c index 2566683cbfef..c032f6feb13e 100644 --- a/drivers/video/tdfxfb.c +++ b/drivers/video/tdfxfb.c | |||
@@ -35,7 +35,6 @@ | |||
35 | * driver by Ilario Nardinocchi, which in turn is based on skeletonfb. | 35 | * driver by Ilario Nardinocchi, which in turn is based on skeletonfb. |
36 | * | 36 | * |
37 | * TODO: | 37 | * TODO: |
38 | * - support for 16/32 bpp needs fixing (funky bootup penguin) | ||
39 | * - multihead support (basically need to support an array of fb_infos) | 38 | * - multihead support (basically need to support an array of fb_infos) |
40 | * - support other architectures (PPC, Alpha); does the fact that the VGA | 39 | * - support other architectures (PPC, Alpha); does the fact that the VGA |
41 | * core can be accessed only thru I/O (not memory mapped) complicate | 40 | * core can be accessed only thru I/O (not memory mapped) complicate |
@@ -184,30 +183,38 @@ static inline void vga_outb(struct tdfx_par *par, u32 reg, u8 val) | |||
184 | static inline void gra_outb(struct tdfx_par *par, u32 idx, u8 val) | 183 | static inline void gra_outb(struct tdfx_par *par, u32 idx, u8 val) |
185 | { | 184 | { |
186 | vga_outb(par, GRA_I, idx); | 185 | vga_outb(par, GRA_I, idx); |
186 | wmb(); | ||
187 | vga_outb(par, GRA_D, val); | 187 | vga_outb(par, GRA_D, val); |
188 | wmb(); | ||
188 | } | 189 | } |
189 | 190 | ||
190 | static inline void seq_outb(struct tdfx_par *par, u32 idx, u8 val) | 191 | static inline void seq_outb(struct tdfx_par *par, u32 idx, u8 val) |
191 | { | 192 | { |
192 | vga_outb(par, SEQ_I, idx); | 193 | vga_outb(par, SEQ_I, idx); |
194 | wmb(); | ||
193 | vga_outb(par, SEQ_D, val); | 195 | vga_outb(par, SEQ_D, val); |
196 | wmb(); | ||
194 | } | 197 | } |
195 | 198 | ||
196 | static inline u8 seq_inb(struct tdfx_par *par, u32 idx) | 199 | static inline u8 seq_inb(struct tdfx_par *par, u32 idx) |
197 | { | 200 | { |
198 | vga_outb(par, SEQ_I, idx); | 201 | vga_outb(par, SEQ_I, idx); |
202 | mb(); | ||
199 | return vga_inb(par, SEQ_D); | 203 | return vga_inb(par, SEQ_D); |
200 | } | 204 | } |
201 | 205 | ||
202 | static inline void crt_outb(struct tdfx_par *par, u32 idx, u8 val) | 206 | static inline void crt_outb(struct tdfx_par *par, u32 idx, u8 val) |
203 | { | 207 | { |
204 | vga_outb(par, CRT_I, idx); | 208 | vga_outb(par, CRT_I, idx); |
209 | wmb(); | ||
205 | vga_outb(par, CRT_D, val); | 210 | vga_outb(par, CRT_D, val); |
211 | wmb(); | ||
206 | } | 212 | } |
207 | 213 | ||
208 | static inline u8 crt_inb(struct tdfx_par *par, u32 idx) | 214 | static inline u8 crt_inb(struct tdfx_par *par, u32 idx) |
209 | { | 215 | { |
210 | vga_outb(par, CRT_I, idx); | 216 | vga_outb(par, CRT_I, idx); |
217 | mb(); | ||
211 | return vga_inb(par, CRT_D); | 218 | return vga_inb(par, CRT_D); |
212 | } | 219 | } |
213 | 220 | ||
@@ -243,6 +250,7 @@ static inline void vga_enable_video(struct tdfx_par *par) | |||
243 | static inline void vga_enable_palette(struct tdfx_par *par) | 250 | static inline void vga_enable_palette(struct tdfx_par *par) |
244 | { | 251 | { |
245 | vga_inb(par, IS1_R); | 252 | vga_inb(par, IS1_R); |
253 | mb(); | ||
246 | vga_outb(par, ATT_IW, 0x20); | 254 | vga_outb(par, ATT_IW, 0x20); |
247 | } | 255 | } |
248 | 256 | ||
@@ -286,6 +294,8 @@ static inline void do_setpalentry(struct tdfx_par *par, unsigned regno, u32 c) | |||
286 | { | 294 | { |
287 | banshee_make_room(par, 2); | 295 | banshee_make_room(par, 2); |
288 | tdfx_outl(par, DACADDR, regno); | 296 | tdfx_outl(par, DACADDR, regno); |
297 | /* read after write makes it working */ | ||
298 | tdfx_inl(par, DACADDR); | ||
289 | tdfx_outl(par, DACDATA, c); | 299 | tdfx_outl(par, DACDATA, c); |
290 | } | 300 | } |
291 | 301 | ||
@@ -771,6 +781,12 @@ static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
771 | if (regno >= info->cmap.len || regno > 255) | 781 | if (regno >= info->cmap.len || regno > 255) |
772 | return 1; | 782 | return 1; |
773 | 783 | ||
784 | /* grayscale works only partially under directcolor */ | ||
785 | if (info->var.grayscale) { | ||
786 | /* grayscale = 0.30*R + 0.59*G + 0.11*B */ | ||
787 | red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; | ||
788 | } | ||
789 | |||
774 | switch (info->fix.visual) { | 790 | switch (info->fix.visual) { |
775 | case FB_VISUAL_PSEUDOCOLOR: | 791 | case FB_VISUAL_PSEUDOCOLOR: |
776 | rgbcol =(((u32)red & 0xff00) << 8) | | 792 | rgbcol =(((u32)red & 0xff00) << 8) | |