Mercurial > mplayer.hg
annotate vidix/s3_vid.c @ 36659:f41b65ac7e81
configure: disable internal libmpeg2 by default.
While the last tests showed that it can be slightly
faster in some cases, the difference should not be
relevant to the majority of users.
In addition, the code is of not particularly high
quality, so I consider it better/safer to have it
disabled by default.
Removing the code after the next release is a possible
future action.
author | reimar |
---|---|
date | Sun, 26 Jan 2014 18:19:31 +0000 |
parents | 598ef7d90b78 |
children | 3c5c93a30fb7 |
rev | line source |
---|---|
26096 | 1 /* |
2 * VIDIX driver for S3 chipsets. | |
26718
051b2632f121
consistency cosmetics: Move some parts of file headers around; typo fixes.
diego
parents:
26203
diff
changeset
|
3 * |
26096 | 4 * Copyright (C) 2004 Reza Jelveh |
26718
051b2632f121
consistency cosmetics: Move some parts of file headers around; typo fixes.
diego
parents:
26203
diff
changeset
|
5 * Thanks to Alex Deucher for Support |
051b2632f121
consistency cosmetics: Move some parts of file headers around; typo fixes.
diego
parents:
26203
diff
changeset
|
6 * Trio/Virge support by Michael Kostylev |
26096 | 7 * |
8 * This file is part of MPlayer. | |
9 * | |
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. | |
14 * | |
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. | |
19 * | |
26719 | 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. | |
26096 | 23 */ |
24 | |
25 #include <errno.h> | |
26 #include <stdio.h> | |
27 #include <stdlib.h> | |
28 #include <string.h> | |
29 #include <inttypes.h> | |
30 #include <unistd.h> | |
31 #include <math.h> | |
32 | |
26203 | 33 #include "config.h" |
26096 | 34 #include "vidix.h" |
35 #include "fourcc.h" | |
36 #include "dha.h" | |
37 #include "pci_ids.h" | |
38 #include "pci_names.h" | |
39 | |
40 #include "s3_regs.h" | |
41 | |
42 static void S3SetColorKeyOld (void); | |
43 static void S3SetColorKeyNew (void); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
44 static void S3SetColorKey2000 (void); |
26096 | 45 static void (*S3SetColorKey) (void) = NULL; |
46 | |
47 static void S3SetColorOld (void); | |
48 static void S3SetColorNew (void); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
49 static void S3SetColor2000 (void); |
26096 | 50 static void (*S3SetColor) (void) = NULL; |
51 | |
52 static void S3DisplayVideoOld (void); | |
53 static void S3DisplayVideoNew (void); | |
54 static void S3DisplayVideo2000 (void); | |
55 static void (*S3DisplayVideo) (void) = NULL; | |
56 | |
57 static void S3InitStreamsOld (void); | |
58 static void S3InitStreamsNew (void); | |
59 static void S3InitStreams2000 (void); | |
60 static void (*S3InitStreams) (void) = NULL; | |
61 | |
62 pciinfo_t pci_info; | |
63 | |
64 struct s3_chip | |
65 { | |
66 int arch; | |
67 unsigned long fbsize; | |
68 void (*lock) (struct s3_chip *, int); | |
69 }; | |
70 typedef struct s3_chip s3_chip; | |
71 | |
72 struct s3_info | |
73 { | |
74 vidix_video_eq_t eq; | |
75 unsigned int use_colorkey; | |
76 unsigned int colorkey; | |
77 unsigned int vidixcolorkey; | |
78 unsigned int depth; | |
79 unsigned int bpp; | |
80 unsigned int format; | |
81 unsigned int pitch; | |
82 unsigned int blendBase; | |
83 unsigned int displayWidth, displayHeight; | |
84 unsigned int src_w, src_h; | |
85 unsigned int drw_w, drw_h; | |
86 unsigned int wx, wy; | |
87 unsigned int screen_x; | |
88 unsigned int screen_y; | |
89 unsigned long frame_size; | |
90 struct s3_chip chip; | |
91 void *video_base; | |
92 void *control_base; | |
93 unsigned long picture_base; | |
94 unsigned long picture_offset; | |
95 unsigned int num_frames; | |
96 int bps; | |
97 }; | |
98 typedef struct s3_info s3_info; | |
99 | |
100 static s3_info *info; | |
101 | |
102 static vidix_capability_t s3_cap = { | |
103 "S3 BES", | |
104 "Reza Jelveh, Michael Kostylev", | |
105 TYPE_OUTPUT, | |
106 {0, 0, 0, 0}, | |
107 4096, | |
108 4096, | |
109 4, | |
110 4, | |
111 -1, | |
112 FLAG_UPSCALER | FLAG_DOWNSCALER, | |
113 VENDOR_S3_INC, | |
114 -1, | |
115 {0, 0, 0, 0} | |
116 }; | |
117 | |
118 struct s3_cards | |
119 { | |
120 unsigned short chip_id; | |
121 unsigned short arch; | |
122 }; | |
123 | |
124 static struct s3_cards s3_card_ids[] = { | |
125 /* Trio64V */ | |
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}, | |
141 /* Virge */ | |
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}, | |
150 /* Savage3D */ | |
151 {DEVICE_S3_INC_86C794_SAVAGE_3D, S3_SAVAGE3D}, | |
152 {DEVICE_S3_INC_86C390_SAVAGE_3D_MV, S3_SAVAGE3D}, | |
153 /* Savage4 */ | |
154 {DEVICE_S3_INC_SAVAGE_4, S3_SAVAGE4}, | |
155 {DEVICE_S3_INC_SAVAGE_42, S3_SAVAGE4}, | |
156 /* SavageMX */ | |
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}, | |
160 /* SuperSavage */ | |
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}, | |
170 /* ProSavage */ | |
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}, | |
177 /* Savage2000 */ | |
178 {DEVICE_S3_INC_86C410_SAVAGE_2000, S3_SAVAGE2000} | |
179 }; | |
180 | |
181 static unsigned int GetBlendForFourCC (int id) | |
182 { | |
183 switch (id) | |
184 { | |
185 case IMGFMT_UYVY: | |
186 return 0; | |
187 case IMGFMT_YUY2: | |
188 return 1; | |
189 case IMGFMT_Y211: | |
190 return 4; | |
191 case IMGFMT_BGR15: | |
192 return 3; | |
193 case IMGFMT_BGR16: | |
194 return 5; | |
195 case IMGFMT_BGR24: | |
196 return 6; | |
197 case IMGFMT_BGR32: | |
198 return 7; | |
199 default: | |
200 return 1; | |
201 } | |
202 } | |
203 | |
204 static void S3SetColorOld (void) | |
205 { | |
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; | |
210 | |
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); | |
214 } | |
215 | |
216 static void S3SetColorNew (void) | |
217 { | |
218 /* not yet */ | |
219 } | |
220 | |
221 static void S3SetColor2000 (void) | |
222 { | |
223 /* not yet */ | |
224 } | |
225 | |
226 static void S3SetColorKeyOld (void) | |
227 { | |
228 int red, green, blue; | |
229 | |
230 /* Here, we reset the colorkey and all the controls */ | |
231 | |
232 red = (info->vidixcolorkey & 0x00FF0000) >> 16; | |
233 green = (info->vidixcolorkey & 0x0000FF00) >> 8; | |
234 blue = info->vidixcolorkey & 0x000000FF; | |
235 | |
236 if (!info->vidixcolorkey) | |
237 { | |
238 OUTREG (COL_CHROMA_KEY_CONTROL_REG, 0); | |
239 OUTREG (CHROMA_KEY_UPPER_BOUND_REG, 0); | |
240 OUTREG (BLEND_CONTROL_REG, 0); | |
241 } | |
242 else | |
243 { | |
244 switch (info->depth) | |
245 { | |
246 // FIXME: isnt fixed yet | |
247 case 8: | |
248 OUTREG (COL_CHROMA_KEY_CONTROL_REG, 0x37000000 | (info->vidixcolorkey & 0xFF)); | |
249 OUTREG (CHROMA_KEY_UPPER_BOUND_REG, 0x00000000 | (info->vidixcolorkey & 0xFF)); | |
250 break; | |
251 case 15: | |
252 /* 15 bpp 555 */ | |
253 red &= 0x1f; | |
254 green &= 0x1f; | |
255 blue &= 0x1f; | |
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)); | |
258 break; | |
259 case 16: | |
260 /* 16 bpp 565 */ | |
261 red &= 0x1f; | |
262 green &= 0x3f; | |
263 blue &= 0x1f; | |
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)); | |
266 break; | |
267 case 24: | |
268 /* 24 bpp 888 */ | |
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)); | |
271 break; | |
272 } | |
273 | |
274 /* We use destination colorkey */ | |
275 OUTREG (BLEND_CONTROL_REG, 0x05000000); | |
276 } | |
277 } | |
278 | |
279 static void S3SetColorKeyNew (void) | |
280 { | |
281 /* not yet */ | |
282 } | |
283 | |
284 static void S3SetColorKey2000 (void) | |
285 { | |
286 /* not yet */ | |
287 } | |
288 | |
289 static void S3DisplayVideoOld (void) | |
290 { | |
291 unsigned int ssControl; | |
292 int cr92; | |
293 | |
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)); | |
301 | |
302 /* Set surface format and adjust scaling */ | |
303 if (info->chip.arch <= S3_VIRGE) | |
304 { | |
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) | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
308 ssControl |= 2 << 28; |
26096 | 309 |
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); | |
316 } | |
317 else | |
318 { | |
319 ssControl = GetBlendForFourCC (info->format) << 24 | info->src_w; | |
320 if (info->src_w > (info->drw_w << 1)) | |
321 { | |
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; | |
333 } | |
334 | |
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)); | |
340 } | |
341 | |
342 if (info->chip.arch == S3_TRIO64V) | |
343 OUTREG (STREAMS_FIFO_REG, (6 << 10) | (14 << 5) | 16); | |
344 else | |
345 { | |
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); | |
354 } | |
355 } | |
356 | |
357 static void S3DisplayVideoNew (void) | |
358 { | |
359 /* not yet */ | |
360 } | |
361 | |
362 static void S3DisplayVideo2000 (void) | |
363 { | |
364 /* not yet */ | |
365 } | |
366 | |
367 static void S3InitStreamsOld (void) | |
368 { | |
369 /*unsigned long jDelta; */ | |
370 unsigned long format = 0; | |
371 | |
372 /*jDelta = pScrn->displayWidth * (pScrn->bitsPerPixel + 7) / 8; */ | |
373 switch (info->depth) | |
374 { | |
375 case 8: | |
376 format = 0 << 24; | |
377 break; | |
378 case 15: | |
379 format = 3 << 24; | |
380 break; | |
381 case 16: | |
382 format = 5 << 24; | |
383 break; | |
384 case 24: | |
385 format = 7 << 24; | |
386 break; | |
387 } | |
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); | |
395 | |
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); | |
411 } | |
412 | |
413 static void S3InitStreamsNew (void) | |
414 { | |
415 /* not yet */ | |
416 } | |
417 | |
418 static void S3InitStreams2000 (void) | |
419 { | |
420 /* not yet */ | |
421 } | |
422 | |
423 static void S3StreamsOn (void) | |
424 { | |
425 unsigned char jStreamsControl; | |
426 | |
427 VGAOUT8 (vgaCRIndex, EXT_MISC_CTRL2); | |
428 | |
429 if (S3_SAVAGE_MOBILE_SERIES (info->chip.arch)) | |
430 { | |
431 jStreamsControl = VGAIN8 (vgaCRReg) | ENABLE_STREAM1; | |
432 VerticalRetraceWait (); | |
433 VGAOUT16 (vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2); | |
434 | |
435 S3InitStreams = S3InitStreamsNew; | |
436 S3SetColor = S3SetColorNew; | |
437 S3SetColorKey = S3SetColorKeyNew; | |
438 S3DisplayVideo = S3DisplayVideoNew; | |
439 } | |
440 else if (info->chip.arch == S3_SAVAGE2000) | |
441 { | |
442 jStreamsControl = VGAIN8 (vgaCRReg) | ENABLE_STREAM1; | |
443 VerticalRetraceWait (); | |
444 VGAOUT16 (vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2); | |
445 | |
446 S3InitStreams = S3InitStreams2000; | |
447 S3SetColor = S3SetColor2000; | |
448 S3SetColorKey = S3SetColorKey2000; | |
449 S3DisplayVideo = S3DisplayVideo2000; | |
450 } | |
451 else | |
452 { | |
453 jStreamsControl = VGAIN8 (vgaCRReg) | ENABLE_STREAMS_OLD; | |
454 VerticalRetraceWait (); | |
455 VGAOUT16 (vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2); | |
456 | |
457 S3InitStreams = S3InitStreamsOld; | |
458 S3SetColor = S3SetColorOld; | |
459 S3SetColorKey = S3SetColorKeyOld; | |
460 S3DisplayVideo = S3DisplayVideoOld; | |
461 } | |
462 | |
463 S3InitStreams (); | |
464 | |
465 VerticalRetraceWait (); | |
466 /* Turn on secondary stream TV flicker filter, once we support TV. */ | |
467 /* SR70 |= 0x10 */ | |
468 } | |
469 | |
470 static void S3GetScrProp (struct s3_info *info) | |
471 { | |
472 unsigned char bpp = 0; | |
473 | |
474 VGAOUT8 (vgaCRIndex, EXT_MISC_CTRL2); | |
475 bpp = VGAIN8 (vgaCRReg); | |
476 | |
477 switch (bpp & 0xf0) | |
478 { | |
479 case 0x00: | |
480 case 0x10: | |
481 info->depth = 8; | |
482 info->bpp = 8; | |
483 break; | |
484 case 0x20: | |
485 case 0x30: | |
486 info->depth = 15; | |
487 info->bpp = 16; | |
488 break; | |
489 case 0x40: | |
490 case 0x50: | |
491 info->depth = 16; | |
492 info->bpp = 16; | |
493 break; | |
494 case 0x70: | |
495 case 0xd0: | |
496 info->depth = 24; | |
497 info->bpp = 32; | |
498 break; | |
499 } | |
500 | |
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; | |
508 ++info->screen_y; | |
509 | |
510 printf ("[s3_vid] x = %d, y = %d, bpp = %d\n", info->screen_x, info->screen_y, info->bpp); | |
511 } | |
512 | |
513 static void S3StreamsOff (void) | |
514 { | |
515 unsigned char jStreamsControl; | |
516 | |
517 if (info->chip.arch == S3_TRIO64V) | |
518 OUTREG (STREAMS_FIFO_REG, (20 << 10)); | |
519 | |
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; | |
524 else | |
525 jStreamsControl = VGAIN8 (vgaCRReg) & NO_STREAMS_OLD; | |
526 | |
527 VerticalRetraceWait (); | |
528 VGAOUT16 (vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2); | |
529 | |
530 if (S3_SAVAGE_SERIES (info->chip.arch)) | |
531 { | |
532 VGAOUT16 (vgaCRIndex, 0x0093); | |
533 VGAOUT8 (vgaCRIndex, 0x92); | |
534 VGAOUT8 (vgaCRReg, VGAIN8 (vgaCRReg) & 0x40); | |
535 } | |
536 } | |
537 | |
538 static int find_chip (unsigned chip_id) | |
539 { | |
540 unsigned i; | |
541 | |
542 for (i = 0; i < sizeof (s3_card_ids) / sizeof (struct s3_cards); i++) | |
543 if (chip_id == s3_card_ids[i].chip_id) | |
544 return i; | |
545 return -1; | |
546 } | |
547 | |
548 static int s3_probe (int verbose, int force) | |
549 { | |
550 pciinfo_t lst[MAX_PCI_DEVICES]; | |
551 unsigned i, num_pci; | |
552 int err; | |
553 | |
554 if (force) | |
555 printf ("[s3_vid] Warning: forcing not supported yet!\n"); | |
556 err = pci_scan (lst, &num_pci); | |
557 if (err) | |
558 { | |
559 printf ("[s3_vid] Error occurred during pci scan: %s\n", strerror (err)); | |
560 return err; | |
561 } | |
562 else | |
563 { | |
564 err = ENXIO; | |
565 for (i = 0; i < num_pci; i++) | |
566 { | |
567 if (lst[i].vendor == VENDOR_S3_INC) | |
568 { | |
569 int idx; | |
570 const char *dname; | |
571 idx = find_chip (lst[i].device); | |
572 if (idx == -1) | |
573 continue; | |
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) | |
579 { | |
580 printf ("[s3_vid] Device is disabled, ignoring\n"); | |
581 continue; | |
582 } | |
583 s3_cap.device_id = lst[i].device; | |
584 err = 0; | |
585 memcpy (&pci_info, &lst[i], sizeof (pciinfo_t)); | |
586 break; | |
587 } | |
588 } | |
589 } | |
590 if (err && verbose) | |
591 printf ("[s3_vid] Can't find chip\n"); | |
592 return err; | |
593 } | |
594 | |
26099 | 595 static int s3_init (void) |
26096 | 596 { |
597 unsigned char cr36; | |
598 int mtrr, videoRam; | |
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 }; | |
604 | |
605 enable_app_io (); | |
606 | |
607 info = calloc (1, sizeof (s3_info)); | |
608 | |
609 info->chip.arch = s3_card_ids[find_chip (pci_info.device)].arch; | |
610 | |
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); | |
619 | |
620 if (info->chip.arch <= S3_VIRGE) | |
621 { | |
622 /* TODO: Improve detecting code */ | |
623 | |
624 /* Enable LFB */ | |
625 OUTPORT8 (vgaCRIndex, LIN_ADDR_CTRL); | |
626 OUTPORT8 (vgaCRReg, INPORT8 (vgaCRReg) | ENABLE_LFB); | |
627 /* Enable NewMMIO */ | |
628 OUTPORT8 (vgaCRIndex, EXT_MEM_CTRL1); | |
629 OUTPORT8 (vgaCRReg, INPORT8 (vgaCRReg) | ENABLE_NEWMMIO); | |
630 } | |
631 | |
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); | |
636 else | |
637 info->control_base = map_phys_mem (pci_info.base0, S3_NEWMMIO_REGSIZE_SAVAGE); | |
638 | |
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); | |
647 | |
648 switch (info->chip.arch) | |
649 { | |
650 case S3_TRIO64V: | |
651 case S3_VIRGE: | |
652 videoRam = RamTrioVirge[(cr36 & 0xE0) >> 5] * 1024; | |
653 break; | |
654 | |
655 case S3_SAVAGE3D: | |
656 videoRam = RamSavage3D[(cr36 & 0xC0) >> 6] * 1024; | |
657 break; | |
658 | |
659 case S3_SAVAGE4: | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
660 /* |
26096 | 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... | |
665 */ | |
666 VGAOUT8 (vgaCRIndex, 0x68); | |
667 if ((VGAIN8 (vgaCRReg) & 0xC0) == (0x01 << 6)) | |
668 RamSavage4[1] = 8; | |
669 | |
36641 | 670 /* Otherwise the same, so fallthrough */ |
26096 | 671 case S3_SAVAGE2000: |
672 videoRam = RamSavage4[(cr36 & 0xE0) >> 5] * 1024; | |
673 break; | |
674 | |
675 case S3_SAVAGE_MX: | |
676 videoRam = RamSavageMX[(cr36 & 0x0E) >> 1] * 1024; | |
677 break; | |
678 | |
679 case S3_PROSAVAGE: | |
680 videoRam = RamSavageNB[(cr36 & 0xE0) >> 5] * 1024; | |
681 break; | |
682 | |
683 default: | |
684 /* How did we get here? */ | |
685 videoRam = 0; | |
686 break; | |
687 } | |
688 | |
689 printf ("[s3_vid] VideoRam = %d\n", videoRam); | |
690 info->chip.fbsize = videoRam * 1024; | |
691 | |
692 if (info->chip.arch <= S3_SAVAGE3D) | |
693 mtrr = mtrr_set_type (pci_info.base0, info->chip.fbsize, MTRR_TYPE_WRCOMB); | |
694 else | |
695 mtrr = mtrr_set_type (pci_info.base1, info->chip.fbsize, MTRR_TYPE_WRCOMB); | |
696 | |
697 if (mtrr != 0) | |
698 printf ("[s3_vid] Unable to setup MTRR: %s\n", strerror (mtrr)); | |
699 else | |
700 printf ("[s3_vid] MTRR set up\n"); | |
701 | |
702 S3GetScrProp (info); | |
703 S3StreamsOn (); | |
704 | |
705 return 0; | |
706 } | |
707 | |
708 static void s3_destroy (void) | |
709 { | |
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); | |
713 else | |
714 unmap_phys_mem (info->control_base, S3_NEWMMIO_REGSIZE); | |
715 | |
716 free (info); | |
717 } | |
718 | |
719 static int s3_get_caps (vidix_capability_t * to) | |
720 { | |
721 memcpy (to, &s3_cap, sizeof (vidix_capability_t)); | |
722 return 0; | |
723 } | |
724 | |
725 static int is_supported_fourcc (uint32_t fourcc) | |
726 { | |
727 switch (fourcc) | |
728 { | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
729 //FIXME: Burst Command Interface should be used |
26096 | 730 // for planar to packed conversion |
731 // case IMGFMT_YV12: | |
732 // case IMGFMT_I420: | |
733 case IMGFMT_UYVY: | |
734 case IMGFMT_YUY2: | |
735 case IMGFMT_Y211: | |
736 case IMGFMT_BGR15: | |
737 case IMGFMT_BGR16: | |
738 case IMGFMT_BGR24: | |
739 case IMGFMT_BGR32: | |
740 return 1; | |
741 default: | |
742 return 0; | |
743 } | |
744 } | |
745 | |
746 static int s3_query_fourcc (vidix_fourcc_t * to) | |
747 { | |
748 if (is_supported_fourcc (to->fourcc)) | |
749 { | |
750 to->depth = VID_DEPTH_ALL; | |
751 to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY; | |
752 return 0; | |
753 } | |
754 return ENOSYS; | |
755 } | |
756 | |
757 #if 0 | |
758 static int s3_get_gkeys (vidix_grkey_t * grkey) | |
759 { | |
760 return 0; | |
761 } | |
762 #endif | |
763 | |
764 static int s3_set_gkeys (const vidix_grkey_t * grkey) | |
765 { | |
766 if (grkey->ckey.op == CKEY_FALSE) | |
767 { | |
768 info->use_colorkey = 0; | |
769 info->vidixcolorkey = 0; | |
770 printf ("[s3_vid] Colorkeying disabled\n"); | |
771 } | |
772 else | |
773 { | |
774 info->use_colorkey = 1; | |
775 info->vidixcolorkey = ((grkey->ckey.red << 16) | (grkey->ckey.green << 8) | grkey->ckey.blue); | |
776 printf ("[s3_vid] Set colorkey 0x%x\n", info->vidixcolorkey); | |
777 } | |
778 if (S3SetColorKey) | |
779 S3SetColorKey (); | |
780 return 0; | |
781 } | |
782 | |
783 static int s3_get_eq (vidix_video_eq_t * eq) | |
784 { | |
785 memcpy (eq, &(info->eq), sizeof (vidix_video_eq_t)); | |
786 return 0; | |
787 } | |
788 | |
789 static int s3_set_eq (const vidix_video_eq_t * eq) | |
790 { | |
791 if (eq->cap & VEQ_CAP_BRIGHTNESS) | |
792 info->eq.brightness = eq->brightness; | |
793 if (eq->cap & VEQ_CAP_CONTRAST) | |
794 info->eq.contrast = eq->contrast; | |
795 if (eq->cap & VEQ_CAP_SATURATION) | |
796 info->eq.saturation = eq->saturation; | |
797 if (eq->cap & VEQ_CAP_HUE) | |
798 info->eq.hue = eq->hue; | |
799 if (S3SetColor) | |
800 S3SetColor (); | |
801 return 0; | |
802 } | |
803 | |
804 static int s3_config_playback (vidix_playback_t * vinfo) | |
805 { | |
806 unsigned int i, bpp; | |
807 | |
808 if (!is_supported_fourcc (vinfo->fourcc)) | |
809 return -1; | |
810 | |
811 info->src_w = vinfo->src.w; | |
812 info->src_h = vinfo->src.h; | |
813 | |
814 info->drw_w = vinfo->dest.w; | |
815 info->drw_h = vinfo->dest.h; | |
816 | |
817 info->wx = vinfo->dest.x; | |
818 info->wy = vinfo->dest.y; | |
819 info->format = vinfo->fourcc; | |
820 | |
821 info->eq.cap = VEQ_CAP_BRIGHTNESS | VEQ_CAP_CONTRAST | | |
822 VEQ_CAP_SATURATION | VEQ_CAP_HUE; | |
823 info->eq.brightness = 0; | |
824 info->eq.contrast = 0; | |
825 info->eq.saturation = 0; | |
826 info->eq.hue = 0; | |
827 | |
828 vinfo->offset.y = 0; | |
829 vinfo->offset.v = 0; | |
830 vinfo->offset.u = 0; | |
831 | |
832 vinfo->dest.pitch.y = 32; | |
833 vinfo->dest.pitch.u = 32; | |
834 vinfo->dest.pitch.v = 32; | |
835 | |
836 switch (vinfo->fourcc) | |
837 { | |
838 case IMGFMT_Y211: | |
839 bpp = 1; | |
840 break; | |
841 case IMGFMT_BGR24: | |
842 bpp = 3; | |
843 break; | |
844 case IMGFMT_BGR32: | |
845 bpp = 4; | |
846 break; | |
847 default: | |
848 bpp = 2; | |
849 break; | |
850 } | |
851 | |
852 info->pitch = ((info->src_w * bpp) + 15) & ~15; | |
853 info->pitch |= ((info->pitch / bpp) << 16); | |
854 | |
855 vinfo->frame_size = (info->pitch & 0xffff) * info->src_h; | |
856 info->frame_size = vinfo->frame_size; | |
857 | |
858 info->picture_offset = info->screen_x * info->screen_y * (info->bpp >> 3); | |
859 if (info->picture_offset > (info->chip.fbsize - vinfo->frame_size)) | |
860 { | |
861 printf ("[s3_vid] Not enough memory for overlay\n"); | |
862 return -1; | |
863 } | |
864 | |
865 if (info->chip.arch <= S3_SAVAGE3D) | |
866 info->video_base = map_phys_mem (pci_info.base0, info->chip.fbsize); | |
867 else | |
868 info->video_base = map_phys_mem (pci_info.base1, info->chip.fbsize); | |
869 | |
870 if (info->video_base == NULL) | |
871 { | |
872 printf ("[s3_vid] errno = %s\n", strerror (errno)); | |
873 return -1; | |
874 } | |
875 | |
876 info->picture_base = (uint32_t) info->video_base + info->picture_offset; | |
877 | |
878 vinfo->dga_addr = (void *) (info->picture_base); | |
879 | |
880 vinfo->num_frames = (info->chip.fbsize - info->picture_offset) / vinfo->frame_size; | |
881 if (vinfo->num_frames > VID_PLAY_MAXFRAMES) | |
882 vinfo->num_frames = VID_PLAY_MAXFRAMES; | |
883 | |
884 for (i = 0; i < vinfo->num_frames; i++) | |
885 vinfo->offsets[i] = vinfo->frame_size * i; | |
886 | |
887 return 0; | |
888 } | |
889 | |
890 static int s3_playback_on (void) | |
891 { | |
892 S3DisplayVideo (); | |
893 return 0; | |
894 } | |
895 | |
896 static int s3_playback_off (void) | |
897 { | |
898 S3StreamsOff (); | |
899 return 0; | |
900 } | |
901 | |
902 static int s3_frame_sel (unsigned int frame) | |
903 { | |
904 OUTREG (SSTREAM_FBADDR0_REG, info->picture_offset + (info->frame_size * frame)); | |
905 return 0; | |
906 } | |
907 | |
908 VDXDriver s3_drv = { | |
909 "s3", | |
910 NULL, | |
911 .probe = s3_probe, | |
912 .get_caps = s3_get_caps, | |
913 .query_fourcc = s3_query_fourcc, | |
914 .init = s3_init, | |
915 .destroy = s3_destroy, | |
916 .config_playback = s3_config_playback, | |
917 .playback_on = s3_playback_on, | |
918 .playback_off = s3_playback_off, | |
919 .frame_sel = s3_frame_sel, | |
920 .get_eq = s3_get_eq, | |
921 .set_eq = s3_set_eq, | |
922 .set_gkey = s3_set_gkeys, | |
923 }; |