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 //#warning enable this again
389 OUTREG (PSTREAM_FBSIZE_REG
, info
->screen_y
* info
->screen_x
* (info
->bpp
>> 3));
390 OUTREG (PSTREAM_WINDOW_START_REG
, OS_XY (0, 0));
391 OUTREG (PSTREAM_WINDOW_SIZE_REG
, OS_WH (info
->screen_x
, info
->screen_y
));
392 OUTREG (PSTREAM_FBADDR1_REG
, 0);
393 /*OUTREG( PSTREAM_STRIDE_REG, jDelta ); */
394 OUTREG (PSTREAM_CONTROL_REG
, format
);
395 OUTREG (PSTREAM_FBADDR0_REG
, 0);
397 OUTREG (COL_CHROMA_KEY_CONTROL_REG
, 0);
398 OUTREG (SSTREAM_CONTROL_REG
, 0);
399 OUTREG (CHROMA_KEY_UPPER_BOUND_REG
, 0);
400 OUTREG (SSTREAM_STRETCH_REG
, 0);
401 OUTREG (COLOR_ADJUSTMENT_REG
, 0);
402 OUTREG (BLEND_CONTROL_REG
, 1 << 24);
403 OUTREG (DOUBLE_BUFFER_REG
, 0);
404 OUTREG (SSTREAM_FBADDR0_REG
, 0);
405 OUTREG (SSTREAM_FBADDR1_REG
, 0);
406 OUTREG (SSTREAM_FBADDR2_REG
, 0);
407 OUTREG (SSTREAM_FBSIZE_REG
, 0);
408 OUTREG (SSTREAM_STRIDE_REG
, 0);
409 OUTREG (SSTREAM_VSCALE_REG
, 0);
410 OUTREG (SSTREAM_LINES_REG
, 0);
411 OUTREG (SSTREAM_VINITIAL_REG
, 0);
414 static void S3InitStreamsNew (void)
419 static void S3InitStreams2000 (void)
424 static void S3StreamsOn (void)
426 unsigned char jStreamsControl
;
428 VGAOUT8 (vgaCRIndex
, EXT_MISC_CTRL2
);
430 if (S3_SAVAGE_MOBILE_SERIES (info
->chip
.arch
))
432 jStreamsControl
= VGAIN8 (vgaCRReg
) | ENABLE_STREAM1
;
433 VerticalRetraceWait ();
434 VGAOUT16 (vgaCRIndex
, (jStreamsControl
<< 8) | EXT_MISC_CTRL2
);
436 S3InitStreams
= S3InitStreamsNew
;
437 S3SetColor
= S3SetColorNew
;
438 S3SetColorKey
= S3SetColorKeyNew
;
439 S3DisplayVideo
= S3DisplayVideoNew
;
441 else if (info
->chip
.arch
== S3_SAVAGE2000
)
443 jStreamsControl
= VGAIN8 (vgaCRReg
) | ENABLE_STREAM1
;
444 VerticalRetraceWait ();
445 VGAOUT16 (vgaCRIndex
, (jStreamsControl
<< 8) | EXT_MISC_CTRL2
);
447 S3InitStreams
= S3InitStreams2000
;
448 S3SetColor
= S3SetColor2000
;
449 S3SetColorKey
= S3SetColorKey2000
;
450 S3DisplayVideo
= S3DisplayVideo2000
;
454 jStreamsControl
= VGAIN8 (vgaCRReg
) | ENABLE_STREAMS_OLD
;
455 VerticalRetraceWait ();
456 VGAOUT16 (vgaCRIndex
, (jStreamsControl
<< 8) | EXT_MISC_CTRL2
);
458 S3InitStreams
= S3InitStreamsOld
;
459 S3SetColor
= S3SetColorOld
;
460 S3SetColorKey
= S3SetColorKeyOld
;
461 S3DisplayVideo
= S3DisplayVideoOld
;
466 VerticalRetraceWait ();
467 /* Turn on secondary stream TV flicker filter, once we support TV. */
471 static void S3GetScrProp (struct s3_info
*info
)
473 unsigned char bpp
= 0;
475 VGAOUT8 (vgaCRIndex
, EXT_MISC_CTRL2
);
476 bpp
= VGAIN8 (vgaCRReg
);
502 VGAOUT8 (vgaCRIndex
, 0x1);
503 info
->screen_x
= (1 + VGAIN8 (vgaCRReg
)) << 3;
504 VGAOUT8 (vgaCRIndex
, 0x12);
505 info
->screen_y
= VGAIN8 (vgaCRReg
);
506 VGAOUT8 (vgaCRIndex
, 0x07);
507 info
->screen_y
|= (VGAIN8 (vgaCRReg
) & 0x02) << 7;
508 info
->screen_y
|= (VGAIN8 (vgaCRReg
) & 0x40) << 3;
511 printf ("[s3_vid] x = %d, y = %d, bpp = %d\n", info
->screen_x
, info
->screen_y
, info
->bpp
);
514 static void S3StreamsOff (void)
516 unsigned char jStreamsControl
;
518 if (info
->chip
.arch
== S3_TRIO64V
)
519 OUTREG (STREAMS_FIFO_REG
, (20 << 10));
521 VGAOUT8 (vgaCRIndex
, EXT_MISC_CTRL2
);
522 if (S3_SAVAGE_MOBILE_SERIES (info
->chip
.arch
) ||
523 (info
->chip
.arch
== S3_SUPERSAVAGE
) || (info
->chip
.arch
== S3_SAVAGE2000
))
524 jStreamsControl
= VGAIN8 (vgaCRReg
) & NO_STREAMS
;
526 jStreamsControl
= VGAIN8 (vgaCRReg
) & NO_STREAMS_OLD
;
528 VerticalRetraceWait ();
529 VGAOUT16 (vgaCRIndex
, (jStreamsControl
<< 8) | EXT_MISC_CTRL2
);
531 if (S3_SAVAGE_SERIES (info
->chip
.arch
))
533 VGAOUT16 (vgaCRIndex
, 0x0093);
534 VGAOUT8 (vgaCRIndex
, 0x92);
535 VGAOUT8 (vgaCRReg
, VGAIN8 (vgaCRReg
) & 0x40);
539 static int find_chip (unsigned chip_id
)
543 for (i
= 0; i
< sizeof (s3_card_ids
) / sizeof (struct s3_cards
); i
++)
544 if (chip_id
== s3_card_ids
[i
].chip_id
)
549 static int s3_probe (int verbose
, int force
)
551 pciinfo_t lst
[MAX_PCI_DEVICES
];
556 printf ("[s3_vid] Warning: forcing not supported yet!\n");
557 err
= pci_scan (lst
, &num_pci
);
560 printf ("[s3_vid] Error occurred during pci scan: %s\n", strerror (err
));
566 for (i
= 0; i
< num_pci
; i
++)
568 if (lst
[i
].vendor
== VENDOR_S3_INC
)
572 idx
= find_chip (lst
[i
].device
);
575 dname
= pci_device_name (lst
[i
].vendor
, lst
[i
].device
);
576 dname
= dname
? dname
: "Unknown chip";
577 printf ("[s3_vid] Found chip: %s\n", dname
);
578 // FIXME: whats wrong here?
579 if ((lst
[i
].command
& PCI_COMMAND_IO
) == 0)
581 printf ("[s3_vid] Device is disabled, ignoring\n");
584 s3_cap
.device_id
= lst
[i
].device
;
586 memcpy (&pci_info
, &lst
[i
], sizeof (pciinfo_t
));
592 printf ("[s3_vid] Can't find chip\n");
596 static int s3_init (void)
600 static unsigned char RamTrioVirge
[] = { 4, 0, 3, 8, 2, 6, 1, 0 };
601 static unsigned char RamSavage3D
[] = { 8, 4, 4, 2 };
602 static unsigned char RamSavage4
[] = { 2, 4, 8, 12, 16, 32, 64, 32 };
603 static unsigned char RamSavageMX
[] = { 2, 8, 4, 16, 8, 16, 4, 16 };
604 static unsigned char RamSavageNB
[] = { 0, 2, 4, 8, 16, 32, 16, 2 };
608 info
= calloc (1, sizeof (s3_info
));
610 info
->chip
.arch
= s3_card_ids
[find_chip (pci_info
.device
)].arch
;
612 /* Switch to vga registers */
613 OUTPORT8 (0x3c3, INPORT8 (0x3c3) | 0x01);
614 OUTPORT8 (0x3c2, INPORT8 (0x3cc) | 0x01);
615 /* Unlock extended registers */
616 OUTPORT8 (vgaCRIndex
, 0x38);
617 OUTPORT8 (vgaCRReg
, 0x48);
618 OUTPORT8 (vgaCRIndex
, 0x39);
619 OUTPORT8 (vgaCRReg
, 0xa0);
621 if (info
->chip
.arch
<= S3_VIRGE
)
623 /* TODO: Improve detecting code */
626 OUTPORT8 (vgaCRIndex
, LIN_ADDR_CTRL
);
627 OUTPORT8 (vgaCRReg
, INPORT8 (vgaCRReg
) | ENABLE_LFB
);
629 OUTPORT8 (vgaCRIndex
, EXT_MEM_CTRL1
);
630 OUTPORT8 (vgaCRReg
, INPORT8 (vgaCRReg
) | ENABLE_NEWMMIO
);
633 if (info
->chip
.arch
< S3_SAVAGE3D
)
634 info
->control_base
= map_phys_mem (pci_info
.base0
+ S3_NEWMMIO_REGBASE
, S3_NEWMMIO_REGSIZE
);
635 else if (info
->chip
.arch
== S3_SAVAGE3D
)
636 info
->control_base
= map_phys_mem (pci_info
.base0
+ S3_NEWMMIO_REGBASE
, S3_NEWMMIO_REGSIZE_SAVAGE
);
638 info
->control_base
= map_phys_mem (pci_info
.base0
, S3_NEWMMIO_REGSIZE_SAVAGE
);
640 /* Unlock CRTC[0-7] */
641 VGAOUT8 (vgaCRIndex
, 0x11);
642 VGAOUT8 (vgaCRReg
, VGAIN8 (vgaCRReg
) & 0x7f);
643 /* Unlock sequencer */
644 VGAOUT16 (0x3c4, 0x0608);
645 /* Detect amount of installed ram */
646 VGAOUT8 (vgaCRIndex
, 0x36);
647 cr36
= VGAIN8 (vgaCRReg
);
649 switch (info
->chip
.arch
)
653 videoRam
= RamTrioVirge
[(cr36
& 0xE0) >> 5] * 1024;
657 videoRam
= RamSavage3D
[(cr36
& 0xC0) >> 6] * 1024;
662 * The Savage4 has one ugly special case to consider. On
663 * systems with 4 banks of 2Mx32 SDRAM, the BIOS says 4MB
664 * when it really means 8MB. Why do it the same when you
665 * can do it different...
667 VGAOUT8 (vgaCRIndex
, 0x68);
668 if ((VGAIN8 (vgaCRReg
) & 0xC0) == (0x01 << 6))
672 videoRam
= RamSavage4
[(cr36
& 0xE0) >> 5] * 1024;
676 videoRam
= RamSavageMX
[(cr36
& 0x0E) >> 1] * 1024;
680 videoRam
= RamSavageNB
[(cr36
& 0xE0) >> 5] * 1024;
684 /* How did we get here? */
689 printf ("[s3_vid] VideoRam = %d\n", videoRam
);
690 info
->chip
.fbsize
= videoRam
* 1024;
692 if (info
->chip
.arch
<= S3_SAVAGE3D
)
693 mtrr
= mtrr_set_type (pci_info
.base0
, info
->chip
.fbsize
, MTRR_TYPE_WRCOMB
);
695 mtrr
= mtrr_set_type (pci_info
.base1
, info
->chip
.fbsize
, MTRR_TYPE_WRCOMB
);
698 printf ("[s3_vid] Unable to setup MTRR: %s\n", strerror (mtrr
));
700 printf ("[s3_vid] MTRR set up\n");
708 static void s3_destroy (void)
710 unmap_phys_mem (info
->video_base
, info
->chip
.fbsize
);
711 if (S3_SAVAGE_SERIES (info
->chip
.arch
))
712 unmap_phys_mem (info
->control_base
, S3_NEWMMIO_REGSIZE_SAVAGE
);
714 unmap_phys_mem (info
->control_base
, S3_NEWMMIO_REGSIZE
);
719 static int s3_get_caps (vidix_capability_t
* to
)
721 memcpy (to
, &s3_cap
, sizeof (vidix_capability_t
));
725 static int is_supported_fourcc (uint32_t fourcc
)
729 //FIXME: Burst Command Interface should be used
730 // for planar to packed conversion
746 static int s3_query_fourcc (vidix_fourcc_t
* to
)
748 if (is_supported_fourcc (to
->fourcc
))
750 to
->depth
= VID_DEPTH_ALL
;
751 to
->flags
= VID_CAP_EXPAND
| VID_CAP_SHRINK
| VID_CAP_COLORKEY
;
755 to
->depth
= to
->flags
= 0;
761 static int s3_get_gkeys (vidix_grkey_t
* grkey
)
767 static int s3_set_gkeys (const vidix_grkey_t
* grkey
)
769 if (grkey
->ckey
.op
== CKEY_FALSE
)
771 info
->use_colorkey
= 0;
772 info
->vidixcolorkey
= 0;
773 printf ("[s3_vid] Colorkeying disabled\n");
777 info
->use_colorkey
= 1;
778 info
->vidixcolorkey
= ((grkey
->ckey
.red
<< 16) | (grkey
->ckey
.green
<< 8) | grkey
->ckey
.blue
);
779 printf ("[s3_vid] Set colorkey 0x%x\n", info
->vidixcolorkey
);
786 static int s3_get_eq (vidix_video_eq_t
* eq
)
788 memcpy (eq
, &(info
->eq
), sizeof (vidix_video_eq_t
));
792 static int s3_set_eq (const vidix_video_eq_t
* eq
)
794 if (eq
->cap
& VEQ_CAP_BRIGHTNESS
)
795 info
->eq
.brightness
= eq
->brightness
;
796 if (eq
->cap
& VEQ_CAP_CONTRAST
)
797 info
->eq
.contrast
= eq
->contrast
;
798 if (eq
->cap
& VEQ_CAP_SATURATION
)
799 info
->eq
.saturation
= eq
->saturation
;
800 if (eq
->cap
& VEQ_CAP_HUE
)
801 info
->eq
.hue
= eq
->hue
;
807 static int s3_config_playback (vidix_playback_t
* vinfo
)
811 if (!is_supported_fourcc (vinfo
->fourcc
))
814 info
->src_w
= vinfo
->src
.w
;
815 info
->src_h
= vinfo
->src
.h
;
817 info
->drw_w
= vinfo
->dest
.w
;
818 info
->drw_h
= vinfo
->dest
.h
;
820 info
->wx
= vinfo
->dest
.x
;
821 info
->wy
= vinfo
->dest
.y
;
822 info
->format
= vinfo
->fourcc
;
824 info
->eq
.cap
= VEQ_CAP_BRIGHTNESS
| VEQ_CAP_CONTRAST
|
825 VEQ_CAP_SATURATION
| VEQ_CAP_HUE
;
826 info
->eq
.brightness
= 0;
827 info
->eq
.contrast
= 0;
828 info
->eq
.saturation
= 0;
835 vinfo
->dest
.pitch
.y
= 32;
836 vinfo
->dest
.pitch
.u
= 32;
837 vinfo
->dest
.pitch
.v
= 32;
839 switch (vinfo
->fourcc
)
855 info
->pitch
= ((info
->src_w
* bpp
) + 15) & ~15;
856 info
->pitch
|= ((info
->pitch
/ bpp
) << 16);
858 vinfo
->frame_size
= (info
->pitch
& 0xffff) * info
->src_h
;
859 info
->frame_size
= vinfo
->frame_size
;
861 info
->picture_offset
= info
->screen_x
* info
->screen_y
* (info
->bpp
>> 3);
862 if (info
->picture_offset
> (info
->chip
.fbsize
- vinfo
->frame_size
))
864 printf ("[s3_vid] Not enough memory for overlay\n");
868 if (info
->chip
.arch
<= S3_SAVAGE3D
)
869 info
->video_base
= map_phys_mem (pci_info
.base0
, info
->chip
.fbsize
);
871 info
->video_base
= map_phys_mem (pci_info
.base1
, info
->chip
.fbsize
);
873 if (info
->video_base
== NULL
)
875 printf ("[s3_vid] errno = %s\n", strerror (errno
));
879 info
->picture_base
= (uint32_t) info
->video_base
+ info
->picture_offset
;
881 vinfo
->dga_addr
= (void *) (info
->picture_base
);
883 vinfo
->num_frames
= (info
->chip
.fbsize
- info
->picture_offset
) / vinfo
->frame_size
;
884 if (vinfo
->num_frames
> VID_PLAY_MAXFRAMES
)
885 vinfo
->num_frames
= VID_PLAY_MAXFRAMES
;
887 for (i
= 0; i
< vinfo
->num_frames
; i
++)
888 vinfo
->offsets
[i
] = vinfo
->frame_size
* i
;
893 static int s3_playback_on (void)
899 static int s3_playback_off (void)
905 static int s3_frame_sel (unsigned int frame
)
907 OUTREG (SSTREAM_FBADDR0_REG
, info
->picture_offset
+ (info
->frame_size
* frame
));
915 .get_caps
= s3_get_caps
,
916 .query_fourcc
= s3_query_fourcc
,
918 .destroy
= s3_destroy
,
919 .config_playback
= s3_config_playback
,
920 .playback_on
= s3_playback_on
,
921 .playback_off
= s3_playback_off
,
922 .frame_sel
= s3_frame_sel
,
925 .set_gkey
= s3_set_gkeys
,