2 * VIDIX driver for S3 chipsets.
4 * Copyright (C) 2004 Reza Jelveh
5 * Thanks to Alex Deucher for Support
6 * Trio/Virge support by Michael Kostylev
8 * This file is part of MPlayer.
10 * MPlayer is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * MPlayer is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
38 #include "pci_names.h"
42 static void S3SetColorKeyOld (void);
43 static void S3SetColorKeyNew (void);
44 static void S3SetColorKey2000 (void);
45 static void (*S3SetColorKey
) (void) = NULL
;
47 static void S3SetColorOld (void);
48 static void S3SetColorNew (void);
49 static void S3SetColor2000 (void);
50 static void (*S3SetColor
) (void) = NULL
;
52 static void S3DisplayVideoOld (void);
53 static void S3DisplayVideoNew (void);
54 static void S3DisplayVideo2000 (void);
55 static void (*S3DisplayVideo
) (void) = NULL
;
57 static void S3InitStreamsOld (void);
58 static void S3InitStreamsNew (void);
59 static void S3InitStreams2000 (void);
60 static void (*S3InitStreams
) (void) = NULL
;
68 void (*lock
) (struct s3_chip
*, int);
70 typedef struct s3_chip s3_chip
;
75 unsigned int use_colorkey
;
76 unsigned int colorkey
;
77 unsigned int vidixcolorkey
;
82 unsigned int blendBase
;
83 unsigned int displayWidth
, displayHeight
;
84 unsigned int src_w
, src_h
;
85 unsigned int drw_w
, drw_h
;
87 unsigned int screen_x
;
88 unsigned int screen_y
;
89 unsigned long frame_size
;
93 unsigned long picture_base
;
94 unsigned long picture_offset
;
95 unsigned int num_frames
;
98 typedef struct s3_info s3_info
;
100 static s3_info
*info
;
102 static vidix_capability_t s3_cap
= {
104 "Reza Jelveh, Michael Kostylev",
112 FLAG_UPSCALER
| FLAG_DOWNSCALER
,
120 unsigned short chip_id
;
124 static struct s3_cards s3_card_ids
[] = {
126 {DEVICE_S3_INC_86C764_765_TRIO32_64_64V
, S3_TRIO64V
},
127 {DEVICE_S3_INC_86C767_TRIO_64UV
, S3_TRIO64V
},
128 {DEVICE_S3_INC_86C755_TRIO_64V2_DX
, S3_TRIO64V
},
129 {DEVICE_S3_INC_86C775_86C785_TRIO_64V2_DX
, S3_TRIO64V
},
130 {DEVICE_S3_INC_TRIO_64V_FAMILY
, S3_TRIO64V
},
131 {DEVICE_S3_INC_TRIO_64V_FAMILY2
, S3_TRIO64V
},
132 {DEVICE_S3_INC_TRIO_64V_FAMILY3
, S3_TRIO64V
},
133 {DEVICE_S3_INC_TRIO_64V_FAMILY4
, S3_TRIO64V
},
134 {DEVICE_S3_INC_TRIO_64V_FAMILY5
, S3_TRIO64V
},
135 {DEVICE_S3_INC_TRIO_64V_FAMILY6
, S3_TRIO64V
},
136 {DEVICE_S3_INC_TRIO_64V_FAMILY7
, S3_TRIO64V
},
137 {DEVICE_S3_INC_TRIO_64V_FAMILY8
, S3_TRIO64V
},
138 {DEVICE_S3_INC_TRIO_64V_FAMILY9
, S3_TRIO64V
},
139 {DEVICE_S3_INC_TRIO_64V_FAMILY10
, S3_TRIO64V
},
140 {DEVICE_S3_INC_TRIO_64V_FAMILY11
, S3_TRIO64V
},
142 {DEVICE_S3_INC_86C325_VIRGE
, S3_VIRGE
},
143 {DEVICE_S3_INC_86C988_VIRGE_VX
, S3_VIRGE
},
144 {DEVICE_S3_INC_VIRGE_DX_OR_GX
, S3_VIRGE
},
145 {DEVICE_S3_INC_VIRGE_GX2
, S3_VIRGE
},
146 {DEVICE_S3_INC_VIRGE_M3
, S3_VIRGE
},
147 {DEVICE_S3_INC_VIRGE_MX
, S3_VIRGE
},
148 {DEVICE_S3_INC_VIRGE_MX2
, S3_VIRGE
},
149 {DEVICE_S3_INC_VIRGE_MX_MV
, S3_VIRGE
},
151 {DEVICE_S3_INC_86C794_SAVAGE_3D
, S3_SAVAGE3D
},
152 {DEVICE_S3_INC_86C390_SAVAGE_3D_MV
, S3_SAVAGE3D
},
154 {DEVICE_S3_INC_SAVAGE_4
, S3_SAVAGE4
},
155 {DEVICE_S3_INC_SAVAGE_42
, S3_SAVAGE4
},
157 {DEVICE_S3_INC_86C270_294_SAVAGE_MX_MV
, S3_SAVAGE_MX
},
158 {DEVICE_S3_INC_82C270_294_SAVAGE_MX
, S3_SAVAGE_MX
},
159 {DEVICE_S3_INC_86C270_294_SAVAGE_IX_MV
, S3_SAVAGE_MX
},
161 {DEVICE_S3_INC_SUPERSAVAGE_MX_128
, S3_SUPERSAVAGE
},
162 {DEVICE_S3_INC_SUPERSAVAGE_MX_64
, S3_SUPERSAVAGE
},
163 {DEVICE_S3_INC_SUPERSAVAGE_MX_64C
, S3_SUPERSAVAGE
},
164 {DEVICE_S3_INC_SUPERSAVAGE_IX_128_SDR
, S3_SUPERSAVAGE
},
165 {DEVICE_S3_INC_SUPERSAVAGE_IX_128_DDR
, S3_SUPERSAVAGE
},
166 {DEVICE_S3_INC_SUPERSAVAGE_IX_64_SDR
, S3_SUPERSAVAGE
},
167 {DEVICE_S3_INC_SUPERSAVAGE_IX_64_DDR
, S3_SUPERSAVAGE
},
168 {DEVICE_S3_INC_SUPERSAVAGE_IX_C_SDR
, S3_SUPERSAVAGE
},
169 {DEVICE_S3_INC_SUPERSAVAGE_IX_C_DDR
, S3_SUPERSAVAGE
},
171 {DEVICE_S3_INC_PROSAVAGE_PM133
, S3_PROSAVAGE
},
172 {DEVICE_S3_INC_PROSAVAGE_KM133
, S3_PROSAVAGE
},
173 {DEVICE_S3_INC_86C380_PROSAVAGEDDR_K4M266
, S3_PROSAVAGE
},
174 {DEVICE_S3_INC_VT8636A_PROSAVAGE_KN133
, S3_PROSAVAGE
},
175 {DEVICE_S3_INC_VT8751_PROSAVAGEDDR_P4M266
, S3_PROSAVAGE
},
176 {DEVICE_S3_INC_VT8375_PROSAVAGE8_KM266_KL266
, S3_PROSAVAGE
},
178 {DEVICE_S3_INC_86C410_SAVAGE_2000
, S3_SAVAGE2000
}
181 static unsigned int GetBlendForFourCC (int id
)
204 static void S3SetColorOld (void)
206 char sat
= (info
->eq
.saturation
+ 1000) * 15 / 2000;
207 double hue
= info
->eq
.hue
* 3.1415926 / 1000.0;
208 char hsx
= ((char) (sat
* cos (hue
))) & 0x1f;
209 char hsy
= ((char) (sat
* sin (hue
))) & 0x1f;
211 OUTREG (COLOR_ADJUSTMENT_REG
, 0x80008000 | hsy
<< 24 | hsx
<< 16 |
212 ((info
->eq
.contrast
+ 1000) * 31 / 2000) << 8 |
213 (info
->eq
.brightness
+ 1000) * 255 / 2000);
216 static void S3SetColorNew (void)
221 static void S3SetColor2000 (void)
226 static void S3SetColorKeyOld (void)
228 int red
, green
, blue
;
230 /* Here, we reset the colorkey and all the controls */
232 red
= (info
->vidixcolorkey
& 0x00FF0000) >> 16;
233 green
= (info
->vidixcolorkey
& 0x0000FF00) >> 8;
234 blue
= info
->vidixcolorkey
& 0x000000FF;
236 if (!info
->vidixcolorkey
)
238 OUTREG (COL_CHROMA_KEY_CONTROL_REG
, 0);
239 OUTREG (CHROMA_KEY_UPPER_BOUND_REG
, 0);
240 OUTREG (BLEND_CONTROL_REG
, 0);
246 // FIXME: isnt fixed yet
248 OUTREG (COL_CHROMA_KEY_CONTROL_REG
, 0x37000000 | (info
->vidixcolorkey
& 0xFF));
249 OUTREG (CHROMA_KEY_UPPER_BOUND_REG
, 0x00000000 | (info
->vidixcolorkey
& 0xFF));
256 OUTREG (COL_CHROMA_KEY_CONTROL_REG
, 0x05000000 | (red
<< 19) | (green
<< 11) | (blue
<< 3));
257 OUTREG (CHROMA_KEY_UPPER_BOUND_REG
, 0x00000000 | (red
<< 19) | (green
<< 11) | (blue
<< 3));
264 OUTREG (COL_CHROMA_KEY_CONTROL_REG
, 0x16000000 | (red
<< 19) | (green
<< 10) | (blue
<< 3));
265 OUTREG (CHROMA_KEY_UPPER_BOUND_REG
, 0x00020002 | (red
<< 19) | (green
<< 10) | (blue
<< 3));
269 OUTREG (COL_CHROMA_KEY_CONTROL_REG
, 0x17000000 | (red
<< 16) | (green
<< 8) | (blue
));
270 OUTREG (CHROMA_KEY_UPPER_BOUND_REG
, 0x00000000 | (red
<< 16) | (green
<< 8) | (blue
));
274 /* We use destination colorkey */
275 OUTREG (BLEND_CONTROL_REG
, 0x05000000);
279 static void S3SetColorKeyNew (void)
284 static void S3SetColorKey2000 (void)
289 static void S3DisplayVideoOld (void)
291 unsigned int ssControl
;
294 /* Set surface location and stride */
295 OUTREG (SSTREAM_FBADDR0_REG
, info
->picture_offset
);
296 OUTREG (SSTREAM_FBADDR1_REG
, 0);
297 OUTREG (SSTREAM_STRIDE_REG
, info
->pitch
);
298 /* Set window parameters */
299 OUTREG (SSTREAM_WINDOW_START_REG
, OS_XY (info
->wx
, info
->wy
));
300 OUTREG (SSTREAM_WINDOW_SIZE_REG
, OS_WH (info
->drw_w
, info
->drw_h
));
302 /* Set surface format and adjust scaling */
303 if (info
->chip
.arch
<= S3_VIRGE
)
305 ssControl
= ((info
->src_w
- 1) << 1) - ((info
->drw_w
- 1) & 0xffff);
306 ssControl
|= GetBlendForFourCC (info
->format
) << 24;
307 if (info
->src_w
!= info
->drw_w
)
308 ssControl
|= 2 << 28;
310 OUTREG (SSTREAM_CONTROL_REG
, ssControl
);
311 OUTREG (SSTREAM_STRETCH_REG
, (((info
->src_w
- info
->drw_w
) & 0x7ff) << 16) | (info
->src_w
- 1));
312 /* Calculate vertical scale factor */
313 OUTREG (K1_VSCALE_REG
, info
->src_h
- 1);
314 OUTREG (K2_VSCALE_REG
, (info
->src_h
- info
->drw_h
) & 0x7ff);
315 OUTREG (DDA_VERT_REG
, (1 - info
->drw_h
) & 0xfff);
319 ssControl
= GetBlendForFourCC (info
->format
) << 24 | info
->src_w
;
320 if (info
->src_w
> (info
->drw_w
<< 1))
322 /* BUGBUG shouldn't this be >=? */
323 if (info
->src_w
<= (info
->drw_w
<< 2))
324 ssControl
|= HDSCALE_4
;
325 else if (info
->src_w
> (info
->drw_w
<< 3))
326 ssControl
|= HDSCALE_8
;
327 else if (info
->src_w
> (info
->drw_w
<< 4))
328 ssControl
|= HDSCALE_16
;
329 else if (info
->src_w
> (info
->drw_w
<< 5))
330 ssControl
|= HDSCALE_32
;
331 else if (info
->src_w
> (info
->drw_w
<< 6))
332 ssControl
|= HDSCALE_64
;
335 OUTREG (SSTREAM_CONTROL_REG
, ssControl
);
336 OUTREG (SSTREAM_STRETCH_REG
, (info
->src_w
<< 15) / info
->drw_w
);
337 OUTREG (SSTREAM_LINES_REG
, info
->src_h
);
338 /* Calculate vertical scale factor. */
339 OUTREG (SSTREAM_VSCALE_REG
, VSCALING (info
->src_h
, info
->drw_h
));
342 if (info
->chip
.arch
== S3_TRIO64V
)
343 OUTREG (STREAMS_FIFO_REG
, (6 << 10) | (14 << 5) | 16);
346 // FIXME: this should actually be enabled
347 info
->pitch
= (info
->pitch
+ 7) / 8;
348 VGAOUT8 (vgaCRIndex
, 0x92);
349 cr92
= VGAIN8 (vgaCRReg
);
350 VGAOUT8 (vgaCRReg
, (cr92
& 0x40) | (info
->pitch
>> 8) | 0x80);
351 VGAOUT8 (vgaCRIndex
, 0x93);
352 VGAOUT8 (vgaCRReg
, info
->pitch
);
353 OUTREG (STREAMS_FIFO_REG
, 2 | 25 << 5 | 32 << 11);
357 static void S3DisplayVideoNew (void)
362 static void S3DisplayVideo2000 (void)
367 static void S3InitStreamsOld (void)
369 /*unsigned long jDelta; */
370 unsigned long format
= 0;
372 /*jDelta = pScrn->displayWidth * (pScrn->bitsPerPixel + 7) / 8; */
388 OUTREG (PSTREAM_FBSIZE_REG
, info
->screen_y
* info
->screen_x
* (info
->bpp
>> 3));
389 OUTREG (PSTREAM_WINDOW_START_REG
, OS_XY (0, 0));
390 OUTREG (PSTREAM_WINDOW_SIZE_REG
, OS_WH (info
->screen_x
, info
->screen_y
));
391 OUTREG (PSTREAM_FBADDR1_REG
, 0);
392 /*OUTREG( PSTREAM_STRIDE_REG, jDelta ); */
393 OUTREG (PSTREAM_CONTROL_REG
, format
);
394 OUTREG (PSTREAM_FBADDR0_REG
, 0);
396 OUTREG (COL_CHROMA_KEY_CONTROL_REG
, 0);
397 OUTREG (SSTREAM_CONTROL_REG
, 0);
398 OUTREG (CHROMA_KEY_UPPER_BOUND_REG
, 0);
399 OUTREG (SSTREAM_STRETCH_REG
, 0);
400 OUTREG (COLOR_ADJUSTMENT_REG
, 0);
401 OUTREG (BLEND_CONTROL_REG
, 1 << 24);
402 OUTREG (DOUBLE_BUFFER_REG
, 0);
403 OUTREG (SSTREAM_FBADDR0_REG
, 0);
404 OUTREG (SSTREAM_FBADDR1_REG
, 0);
405 OUTREG (SSTREAM_FBADDR2_REG
, 0);
406 OUTREG (SSTREAM_FBSIZE_REG
, 0);
407 OUTREG (SSTREAM_STRIDE_REG
, 0);
408 OUTREG (SSTREAM_VSCALE_REG
, 0);
409 OUTREG (SSTREAM_LINES_REG
, 0);
410 OUTREG (SSTREAM_VINITIAL_REG
, 0);
413 static void S3InitStreamsNew (void)
418 static void S3InitStreams2000 (void)
423 static void S3StreamsOn (void)
425 unsigned char jStreamsControl
;
427 VGAOUT8 (vgaCRIndex
, EXT_MISC_CTRL2
);
429 if (S3_SAVAGE_MOBILE_SERIES (info
->chip
.arch
))
431 jStreamsControl
= VGAIN8 (vgaCRReg
) | ENABLE_STREAM1
;
432 VerticalRetraceWait ();
433 VGAOUT16 (vgaCRIndex
, (jStreamsControl
<< 8) | EXT_MISC_CTRL2
);
435 S3InitStreams
= S3InitStreamsNew
;
436 S3SetColor
= S3SetColorNew
;
437 S3SetColorKey
= S3SetColorKeyNew
;
438 S3DisplayVideo
= S3DisplayVideoNew
;
440 else if (info
->chip
.arch
== S3_SAVAGE2000
)
442 jStreamsControl
= VGAIN8 (vgaCRReg
) | ENABLE_STREAM1
;
443 VerticalRetraceWait ();
444 VGAOUT16 (vgaCRIndex
, (jStreamsControl
<< 8) | EXT_MISC_CTRL2
);
446 S3InitStreams
= S3InitStreams2000
;
447 S3SetColor
= S3SetColor2000
;
448 S3SetColorKey
= S3SetColorKey2000
;
449 S3DisplayVideo
= S3DisplayVideo2000
;
453 jStreamsControl
= VGAIN8 (vgaCRReg
) | ENABLE_STREAMS_OLD
;
454 VerticalRetraceWait ();
455 VGAOUT16 (vgaCRIndex
, (jStreamsControl
<< 8) | EXT_MISC_CTRL2
);
457 S3InitStreams
= S3InitStreamsOld
;
458 S3SetColor
= S3SetColorOld
;
459 S3SetColorKey
= S3SetColorKeyOld
;
460 S3DisplayVideo
= S3DisplayVideoOld
;
465 VerticalRetraceWait ();
466 /* Turn on secondary stream TV flicker filter, once we support TV. */
470 static void S3GetScrProp (struct s3_info
*info
)
472 unsigned char bpp
= 0;
474 VGAOUT8 (vgaCRIndex
, EXT_MISC_CTRL2
);
475 bpp
= VGAIN8 (vgaCRReg
);
501 VGAOUT8 (vgaCRIndex
, 0x1);
502 info
->screen_x
= (1 + VGAIN8 (vgaCRReg
)) << 3;
503 VGAOUT8 (vgaCRIndex
, 0x12);
504 info
->screen_y
= VGAIN8 (vgaCRReg
);
505 VGAOUT8 (vgaCRIndex
, 0x07);
506 info
->screen_y
|= (VGAIN8 (vgaCRReg
) & 0x02) << 7;
507 info
->screen_y
|= (VGAIN8 (vgaCRReg
) & 0x40) << 3;
510 printf ("[s3_vid] x = %d, y = %d, bpp = %d\n", info
->screen_x
, info
->screen_y
, info
->bpp
);
513 static void S3StreamsOff (void)
515 unsigned char jStreamsControl
;
517 if (info
->chip
.arch
== S3_TRIO64V
)
518 OUTREG (STREAMS_FIFO_REG
, (20 << 10));
520 VGAOUT8 (vgaCRIndex
, EXT_MISC_CTRL2
);
521 if (S3_SAVAGE_MOBILE_SERIES (info
->chip
.arch
) ||
522 (info
->chip
.arch
== S3_SUPERSAVAGE
) || (info
->chip
.arch
== S3_SAVAGE2000
))
523 jStreamsControl
= VGAIN8 (vgaCRReg
) & NO_STREAMS
;
525 jStreamsControl
= VGAIN8 (vgaCRReg
) & NO_STREAMS_OLD
;
527 VerticalRetraceWait ();
528 VGAOUT16 (vgaCRIndex
, (jStreamsControl
<< 8) | EXT_MISC_CTRL2
);
530 if (S3_SAVAGE_SERIES (info
->chip
.arch
))
532 VGAOUT16 (vgaCRIndex
, 0x0093);
533 VGAOUT8 (vgaCRIndex
, 0x92);
534 VGAOUT8 (vgaCRReg
, VGAIN8 (vgaCRReg
) & 0x40);
538 static int find_chip (unsigned chip_id
)
542 for (i
= 0; i
< sizeof (s3_card_ids
) / sizeof (struct s3_cards
); i
++)
543 if (chip_id
== s3_card_ids
[i
].chip_id
)
548 static int s3_probe (int verbose
, int force
)
550 pciinfo_t lst
[MAX_PCI_DEVICES
];
555 printf ("[s3_vid] Warning: forcing not supported yet!\n");
556 err
= pci_scan (lst
, &num_pci
);
559 printf ("[s3_vid] Error occurred during pci scan: %s\n", strerror (err
));
565 for (i
= 0; i
< num_pci
; i
++)
567 if (lst
[i
].vendor
== VENDOR_S3_INC
)
571 idx
= find_chip (lst
[i
].device
);
574 dname
= pci_device_name (lst
[i
].vendor
, lst
[i
].device
);
575 dname
= dname
? dname
: "Unknown chip";
576 printf ("[s3_vid] Found chip: %s\n", dname
);
577 // FIXME: whats wrong here?
578 if ((lst
[i
].command
& PCI_COMMAND_IO
) == 0)
580 printf ("[s3_vid] Device is disabled, ignoring\n");
583 s3_cap
.device_id
= lst
[i
].device
;
585 memcpy (&pci_info
, &lst
[i
], sizeof (pciinfo_t
));
591 printf ("[s3_vid] Can't find chip\n");
595 static int s3_init (void)
599 static unsigned char RamTrioVirge
[] = { 4, 0, 3, 8, 2, 6, 1, 0 };
600 static unsigned char RamSavage3D
[] = { 8, 4, 4, 2 };
601 static unsigned char RamSavage4
[] = { 2, 4, 8, 12, 16, 32, 64, 32 };
602 static unsigned char RamSavageMX
[] = { 2, 8, 4, 16, 8, 16, 4, 16 };
603 static unsigned char RamSavageNB
[] = { 0, 2, 4, 8, 16, 32, 16, 2 };
607 info
= calloc (1, sizeof (s3_info
));
609 info
->chip
.arch
= s3_card_ids
[find_chip (pci_info
.device
)].arch
;
611 /* Switch to vga registers */
612 OUTPORT8 (0x3c3, INPORT8 (0x3c3) | 0x01);
613 OUTPORT8 (0x3c2, INPORT8 (0x3cc) | 0x01);
614 /* Unlock extended registers */
615 OUTPORT8 (vgaCRIndex
, 0x38);
616 OUTPORT8 (vgaCRReg
, 0x48);
617 OUTPORT8 (vgaCRIndex
, 0x39);
618 OUTPORT8 (vgaCRReg
, 0xa0);
620 if (info
->chip
.arch
<= S3_VIRGE
)
622 /* TODO: Improve detecting code */
625 OUTPORT8 (vgaCRIndex
, LIN_ADDR_CTRL
);
626 OUTPORT8 (vgaCRReg
, INPORT8 (vgaCRReg
) | ENABLE_LFB
);
628 OUTPORT8 (vgaCRIndex
, EXT_MEM_CTRL1
);
629 OUTPORT8 (vgaCRReg
, INPORT8 (vgaCRReg
) | ENABLE_NEWMMIO
);
632 if (info
->chip
.arch
< S3_SAVAGE3D
)
633 info
->control_base
= map_phys_mem (pci_info
.base0
+ S3_NEWMMIO_REGBASE
, S3_NEWMMIO_REGSIZE
);
634 else if (info
->chip
.arch
== S3_SAVAGE3D
)
635 info
->control_base
= map_phys_mem (pci_info
.base0
+ S3_NEWMMIO_REGBASE
, S3_NEWMMIO_REGSIZE_SAVAGE
);
637 info
->control_base
= map_phys_mem (pci_info
.base0
, S3_NEWMMIO_REGSIZE_SAVAGE
);
639 /* Unlock CRTC[0-7] */
640 VGAOUT8 (vgaCRIndex
, 0x11);
641 VGAOUT8 (vgaCRReg
, VGAIN8 (vgaCRReg
) & 0x7f);
642 /* Unlock sequencer */
643 VGAOUT16 (0x3c4, 0x0608);
644 /* Detect amount of installed ram */
645 VGAOUT8 (vgaCRIndex
, 0x36);
646 cr36
= VGAIN8 (vgaCRReg
);
648 switch (info
->chip
.arch
)
652 videoRam
= RamTrioVirge
[(cr36
& 0xE0) >> 5] * 1024;
656 videoRam
= RamSavage3D
[(cr36
& 0xC0) >> 6] * 1024;
661 * The Savage4 has one ugly special case to consider. On
662 * systems with 4 banks of 2Mx32 SDRAM, the BIOS says 4MB
663 * when it really means 8MB. Why do it the same when you
664 * can do it different...
666 VGAOUT8 (vgaCRIndex
, 0x68);
667 if ((VGAIN8 (vgaCRReg
) & 0xC0) == (0x01 << 6))
671 videoRam
= RamSavage4
[(cr36
& 0xE0) >> 5] * 1024;
675 videoRam
= RamSavageMX
[(cr36
& 0x0E) >> 1] * 1024;
679 videoRam
= RamSavageNB
[(cr36
& 0xE0) >> 5] * 1024;
683 /* How did we get here? */
688 printf ("[s3_vid] VideoRam = %d\n", videoRam
);
689 info
->chip
.fbsize
= videoRam
* 1024;
691 if (info
->chip
.arch
<= S3_SAVAGE3D
)
692 mtrr
= mtrr_set_type (pci_info
.base0
, info
->chip
.fbsize
, MTRR_TYPE_WRCOMB
);
694 mtrr
= mtrr_set_type (pci_info
.base1
, info
->chip
.fbsize
, MTRR_TYPE_WRCOMB
);
697 printf ("[s3_vid] Unable to setup MTRR: %s\n", strerror (mtrr
));
699 printf ("[s3_vid] MTRR set up\n");
707 static void s3_destroy (void)
709 unmap_phys_mem (info
->video_base
, info
->chip
.fbsize
);
710 if (S3_SAVAGE_SERIES (info
->chip
.arch
))
711 unmap_phys_mem (info
->control_base
, S3_NEWMMIO_REGSIZE_SAVAGE
);
713 unmap_phys_mem (info
->control_base
, S3_NEWMMIO_REGSIZE
);
718 static int s3_get_caps (vidix_capability_t
* to
)
720 memcpy (to
, &s3_cap
, sizeof (vidix_capability_t
));
724 static int is_supported_fourcc (uint32_t fourcc
)
728 //FIXME: Burst Command Interface should be used
729 // for planar to packed conversion
745 static int s3_query_fourcc (vidix_fourcc_t
* to
)
747 if (is_supported_fourcc (to
->fourcc
))
749 to
->depth
= VID_DEPTH_ALL
;
750 to
->flags
= VID_CAP_EXPAND
| VID_CAP_SHRINK
| VID_CAP_COLORKEY
;
754 to
->depth
= to
->flags
= 0;
760 static int s3_get_gkeys (vidix_grkey_t
* grkey
)
766 static int s3_set_gkeys (const vidix_grkey_t
* grkey
)
768 if (grkey
->ckey
.op
== CKEY_FALSE
)
770 info
->use_colorkey
= 0;
771 info
->vidixcolorkey
= 0;
772 printf ("[s3_vid] Colorkeying disabled\n");
776 info
->use_colorkey
= 1;
777 info
->vidixcolorkey
= ((grkey
->ckey
.red
<< 16) | (grkey
->ckey
.green
<< 8) | grkey
->ckey
.blue
);
778 printf ("[s3_vid] Set colorkey 0x%x\n", info
->vidixcolorkey
);
785 static int s3_get_eq (vidix_video_eq_t
* eq
)
787 memcpy (eq
, &(info
->eq
), sizeof (vidix_video_eq_t
));
791 static int s3_set_eq (const vidix_video_eq_t
* eq
)
793 if (eq
->cap
& VEQ_CAP_BRIGHTNESS
)
794 info
->eq
.brightness
= eq
->brightness
;
795 if (eq
->cap
& VEQ_CAP_CONTRAST
)
796 info
->eq
.contrast
= eq
->contrast
;
797 if (eq
->cap
& VEQ_CAP_SATURATION
)
798 info
->eq
.saturation
= eq
->saturation
;
799 if (eq
->cap
& VEQ_CAP_HUE
)
800 info
->eq
.hue
= eq
->hue
;
806 static int s3_config_playback (vidix_playback_t
* vinfo
)
810 if (!is_supported_fourcc (vinfo
->fourcc
))
813 info
->src_w
= vinfo
->src
.w
;
814 info
->src_h
= vinfo
->src
.h
;
816 info
->drw_w
= vinfo
->dest
.w
;
817 info
->drw_h
= vinfo
->dest
.h
;
819 info
->wx
= vinfo
->dest
.x
;
820 info
->wy
= vinfo
->dest
.y
;
821 info
->format
= vinfo
->fourcc
;
823 info
->eq
.cap
= VEQ_CAP_BRIGHTNESS
| VEQ_CAP_CONTRAST
|
824 VEQ_CAP_SATURATION
| VEQ_CAP_HUE
;
825 info
->eq
.brightness
= 0;
826 info
->eq
.contrast
= 0;
827 info
->eq
.saturation
= 0;
834 vinfo
->dest
.pitch
.y
= 32;
835 vinfo
->dest
.pitch
.u
= 32;
836 vinfo
->dest
.pitch
.v
= 32;
838 switch (vinfo
->fourcc
)
854 info
->pitch
= ((info
->src_w
* bpp
) + 15) & ~15;
855 info
->pitch
|= ((info
->pitch
/ bpp
) << 16);
857 vinfo
->frame_size
= (info
->pitch
& 0xffff) * info
->src_h
;
858 info
->frame_size
= vinfo
->frame_size
;
860 info
->picture_offset
= info
->screen_x
* info
->screen_y
* (info
->bpp
>> 3);
861 if (info
->picture_offset
> (info
->chip
.fbsize
- vinfo
->frame_size
))
863 printf ("[s3_vid] Not enough memory for overlay\n");
867 if (info
->chip
.arch
<= S3_SAVAGE3D
)
868 info
->video_base
= map_phys_mem (pci_info
.base0
, info
->chip
.fbsize
);
870 info
->video_base
= map_phys_mem (pci_info
.base1
, info
->chip
.fbsize
);
872 if (info
->video_base
== NULL
)
874 printf ("[s3_vid] errno = %s\n", strerror (errno
));
878 info
->picture_base
= (uint32_t) info
->video_base
+ info
->picture_offset
;
880 vinfo
->dga_addr
= (void *) (info
->picture_base
);
882 vinfo
->num_frames
= (info
->chip
.fbsize
- info
->picture_offset
) / vinfo
->frame_size
;
883 if (vinfo
->num_frames
> VID_PLAY_MAXFRAMES
)
884 vinfo
->num_frames
= VID_PLAY_MAXFRAMES
;
886 for (i
= 0; i
< vinfo
->num_frames
; i
++)
887 vinfo
->offsets
[i
] = vinfo
->frame_size
* i
;
892 static int s3_playback_on (void)
898 static int s3_playback_off (void)
904 static int s3_frame_sel (unsigned int frame
)
906 OUTREG (SSTREAM_FBADDR0_REG
, info
->picture_offset
+ (info
->frame_size
* frame
));
914 .get_caps
= s3_get_caps
,
915 .query_fourcc
= s3_query_fourcc
,
917 .destroy
= s3_destroy
,
918 .config_playback
= s3_config_playback
,
919 .playback_on
= s3_playback_on
,
920 .playback_off
= s3_playback_off
,
921 .frame_sel
= s3_frame_sel
,
924 .set_gkey
= s3_set_gkeys
,