Mercurial > mplayer.hg
annotate vidix/s3_vid.c @ 29288:4a1c217a844b
In all demux_info_add calls change "name" to "title".
Currently "name" and "title" are both used at random, this makes it consistent.
"title" was chosen because it is less ambiguous and also the get_meta_title
slave mode command uses that (there is no get_meta_name command).
author | reimar |
---|---|
date | Sat, 30 May 2009 13:18:57 +0000 |
parents | 0f1b5b68af32 |
children | 914208d188b9 |
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 //#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); | |
396 | |
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); | |
412 } | |
413 | |
414 static void S3InitStreamsNew (void) | |
415 { | |
416 /* not yet */ | |
417 } | |
418 | |
419 static void S3InitStreams2000 (void) | |
420 { | |
421 /* not yet */ | |
422 } | |
423 | |
424 static void S3StreamsOn (void) | |
425 { | |
426 unsigned char jStreamsControl; | |
427 | |
428 VGAOUT8 (vgaCRIndex, EXT_MISC_CTRL2); | |
429 | |
430 if (S3_SAVAGE_MOBILE_SERIES (info->chip.arch)) | |
431 { | |
432 jStreamsControl = VGAIN8 (vgaCRReg) | ENABLE_STREAM1; | |
433 VerticalRetraceWait (); | |
434 VGAOUT16 (vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2); | |
435 | |
436 S3InitStreams = S3InitStreamsNew; | |
437 S3SetColor = S3SetColorNew; | |
438 S3SetColorKey = S3SetColorKeyNew; | |
439 S3DisplayVideo = S3DisplayVideoNew; | |
440 } | |
441 else if (info->chip.arch == S3_SAVAGE2000) | |
442 { | |
443 jStreamsControl = VGAIN8 (vgaCRReg) | ENABLE_STREAM1; | |
444 VerticalRetraceWait (); | |
445 VGAOUT16 (vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2); | |
446 | |
447 S3InitStreams = S3InitStreams2000; | |
448 S3SetColor = S3SetColor2000; | |
449 S3SetColorKey = S3SetColorKey2000; | |
450 S3DisplayVideo = S3DisplayVideo2000; | |
451 } | |
452 else | |
453 { | |
454 jStreamsControl = VGAIN8 (vgaCRReg) | ENABLE_STREAMS_OLD; | |
455 VerticalRetraceWait (); | |
456 VGAOUT16 (vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2); | |
457 | |
458 S3InitStreams = S3InitStreamsOld; | |
459 S3SetColor = S3SetColorOld; | |
460 S3SetColorKey = S3SetColorKeyOld; | |
461 S3DisplayVideo = S3DisplayVideoOld; | |
462 } | |
463 | |
464 S3InitStreams (); | |
465 | |
466 VerticalRetraceWait (); | |
467 /* Turn on secondary stream TV flicker filter, once we support TV. */ | |
468 /* SR70 |= 0x10 */ | |
469 } | |
470 | |
471 static void S3GetScrProp (struct s3_info *info) | |
472 { | |
473 unsigned char bpp = 0; | |
474 | |
475 VGAOUT8 (vgaCRIndex, EXT_MISC_CTRL2); | |
476 bpp = VGAIN8 (vgaCRReg); | |
477 | |
478 switch (bpp & 0xf0) | |
479 { | |
480 case 0x00: | |
481 case 0x10: | |
482 info->depth = 8; | |
483 info->bpp = 8; | |
484 break; | |
485 case 0x20: | |
486 case 0x30: | |
487 info->depth = 15; | |
488 info->bpp = 16; | |
489 break; | |
490 case 0x40: | |
491 case 0x50: | |
492 info->depth = 16; | |
493 info->bpp = 16; | |
494 break; | |
495 case 0x70: | |
496 case 0xd0: | |
497 info->depth = 24; | |
498 info->bpp = 32; | |
499 break; | |
500 } | |
501 | |
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; | |
509 ++info->screen_y; | |
510 | |
511 printf ("[s3_vid] x = %d, y = %d, bpp = %d\n", info->screen_x, info->screen_y, info->bpp); | |
512 } | |
513 | |
514 static void S3StreamsOff (void) | |
515 { | |
516 unsigned char jStreamsControl; | |
517 | |
518 if (info->chip.arch == S3_TRIO64V) | |
519 OUTREG (STREAMS_FIFO_REG, (20 << 10)); | |
520 | |
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; | |
525 else | |
526 jStreamsControl = VGAIN8 (vgaCRReg) & NO_STREAMS_OLD; | |
527 | |
528 VerticalRetraceWait (); | |
529 VGAOUT16 (vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2); | |
530 | |
531 if (S3_SAVAGE_SERIES (info->chip.arch)) | |
532 { | |
533 VGAOUT16 (vgaCRIndex, 0x0093); | |
534 VGAOUT8 (vgaCRIndex, 0x92); | |
535 VGAOUT8 (vgaCRReg, VGAIN8 (vgaCRReg) & 0x40); | |
536 } | |
537 } | |
538 | |
539 static int find_chip (unsigned chip_id) | |
540 { | |
541 unsigned i; | |
542 | |
543 for (i = 0; i < sizeof (s3_card_ids) / sizeof (struct s3_cards); i++) | |
544 if (chip_id == s3_card_ids[i].chip_id) | |
545 return i; | |
546 return -1; | |
547 } | |
548 | |
549 static int s3_probe (int verbose, int force) | |
550 { | |
551 pciinfo_t lst[MAX_PCI_DEVICES]; | |
552 unsigned i, num_pci; | |
553 int err; | |
554 | |
555 if (force) | |
556 printf ("[s3_vid] Warning: forcing not supported yet!\n"); | |
557 err = pci_scan (lst, &num_pci); | |
558 if (err) | |
559 { | |
560 printf ("[s3_vid] Error occurred during pci scan: %s\n", strerror (err)); | |
561 return err; | |
562 } | |
563 else | |
564 { | |
565 err = ENXIO; | |
566 for (i = 0; i < num_pci; i++) | |
567 { | |
568 if (lst[i].vendor == VENDOR_S3_INC) | |
569 { | |
570 int idx; | |
571 const char *dname; | |
572 idx = find_chip (lst[i].device); | |
573 if (idx == -1) | |
574 continue; | |
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) | |
580 { | |
581 printf ("[s3_vid] Device is disabled, ignoring\n"); | |
582 continue; | |
583 } | |
584 s3_cap.device_id = lst[i].device; | |
585 err = 0; | |
586 memcpy (&pci_info, &lst[i], sizeof (pciinfo_t)); | |
587 break; | |
588 } | |
589 } | |
590 } | |
591 if (err && verbose) | |
592 printf ("[s3_vid] Can't find chip\n"); | |
593 return err; | |
594 } | |
595 | |
26099 | 596 static int s3_init (void) |
26096 | 597 { |
598 unsigned char cr36; | |
599 int mtrr, videoRam; | |
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 }; | |
605 | |
606 enable_app_io (); | |
607 | |
608 info = calloc (1, sizeof (s3_info)); | |
609 | |
610 info->chip.arch = s3_card_ids[find_chip (pci_info.device)].arch; | |
611 | |
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); | |
620 | |
621 if (info->chip.arch <= S3_VIRGE) | |
622 { | |
623 /* TODO: Improve detecting code */ | |
624 | |
625 /* Enable LFB */ | |
626 OUTPORT8 (vgaCRIndex, LIN_ADDR_CTRL); | |
627 OUTPORT8 (vgaCRReg, INPORT8 (vgaCRReg) | ENABLE_LFB); | |
628 /* Enable NewMMIO */ | |
629 OUTPORT8 (vgaCRIndex, EXT_MEM_CTRL1); | |
630 OUTPORT8 (vgaCRReg, INPORT8 (vgaCRReg) | ENABLE_NEWMMIO); | |
631 } | |
632 | |
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); | |
637 else | |
638 info->control_base = map_phys_mem (pci_info.base0, S3_NEWMMIO_REGSIZE_SAVAGE); | |
639 | |
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); | |
648 | |
649 switch (info->chip.arch) | |
650 { | |
651 case S3_TRIO64V: | |
652 case S3_VIRGE: | |
653 videoRam = RamTrioVirge[(cr36 & 0xE0) >> 5] * 1024; | |
654 break; | |
655 | |
656 case S3_SAVAGE3D: | |
657 videoRam = RamSavage3D[(cr36 & 0xC0) >> 6] * 1024; | |
658 break; | |
659 | |
660 case S3_SAVAGE4: | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
661 /* |
26096 | 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... | |
666 */ | |
667 VGAOUT8 (vgaCRIndex, 0x68); | |
668 if ((VGAIN8 (vgaCRReg) & 0xC0) == (0x01 << 6)) | |
669 RamSavage4[1] = 8; | |
670 | |
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 else | |
755 to->depth = to->flags = 0; | |
756 | |
757 return ENOSYS; | |
758 } | |
759 | |
760 #if 0 | |
761 static int s3_get_gkeys (vidix_grkey_t * grkey) | |
762 { | |
763 return 0; | |
764 } | |
765 #endif | |
766 | |
767 static int s3_set_gkeys (const vidix_grkey_t * grkey) | |
768 { | |
769 if (grkey->ckey.op == CKEY_FALSE) | |
770 { | |
771 info->use_colorkey = 0; | |
772 info->vidixcolorkey = 0; | |
773 printf ("[s3_vid] Colorkeying disabled\n"); | |
774 } | |
775 else | |
776 { | |
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); | |
780 } | |
781 if (S3SetColorKey) | |
782 S3SetColorKey (); | |
783 return 0; | |
784 } | |
785 | |
786 static int s3_get_eq (vidix_video_eq_t * eq) | |
787 { | |
788 memcpy (eq, &(info->eq), sizeof (vidix_video_eq_t)); | |
789 return 0; | |
790 } | |
791 | |
792 static int s3_set_eq (const vidix_video_eq_t * eq) | |
793 { | |
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; | |
802 if (S3SetColor) | |
803 S3SetColor (); | |
804 return 0; | |
805 } | |
806 | |
807 static int s3_config_playback (vidix_playback_t * vinfo) | |
808 { | |
809 unsigned int i, bpp; | |
810 | |
811 if (!is_supported_fourcc (vinfo->fourcc)) | |
812 return -1; | |
813 | |
814 info->src_w = vinfo->src.w; | |
815 info->src_h = vinfo->src.h; | |
816 | |
817 info->drw_w = vinfo->dest.w; | |
818 info->drw_h = vinfo->dest.h; | |
819 | |
820 info->wx = vinfo->dest.x; | |
821 info->wy = vinfo->dest.y; | |
822 info->format = vinfo->fourcc; | |
823 | |
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; | |
829 info->eq.hue = 0; | |
830 | |
831 vinfo->offset.y = 0; | |
832 vinfo->offset.v = 0; | |
833 vinfo->offset.u = 0; | |
834 | |
835 vinfo->dest.pitch.y = 32; | |
836 vinfo->dest.pitch.u = 32; | |
837 vinfo->dest.pitch.v = 32; | |
838 | |
839 switch (vinfo->fourcc) | |
840 { | |
841 case IMGFMT_Y211: | |
842 bpp = 1; | |
843 break; | |
844 case IMGFMT_BGR24: | |
845 bpp = 3; | |
846 break; | |
847 case IMGFMT_BGR32: | |
848 bpp = 4; | |
849 break; | |
850 default: | |
851 bpp = 2; | |
852 break; | |
853 } | |
854 | |
855 info->pitch = ((info->src_w * bpp) + 15) & ~15; | |
856 info->pitch |= ((info->pitch / bpp) << 16); | |
857 | |
858 vinfo->frame_size = (info->pitch & 0xffff) * info->src_h; | |
859 info->frame_size = vinfo->frame_size; | |
860 | |
861 info->picture_offset = info->screen_x * info->screen_y * (info->bpp >> 3); | |
862 if (info->picture_offset > (info->chip.fbsize - vinfo->frame_size)) | |
863 { | |
864 printf ("[s3_vid] Not enough memory for overlay\n"); | |
865 return -1; | |
866 } | |
867 | |
868 if (info->chip.arch <= S3_SAVAGE3D) | |
869 info->video_base = map_phys_mem (pci_info.base0, info->chip.fbsize); | |
870 else | |
871 info->video_base = map_phys_mem (pci_info.base1, info->chip.fbsize); | |
872 | |
873 if (info->video_base == NULL) | |
874 { | |
875 printf ("[s3_vid] errno = %s\n", strerror (errno)); | |
876 return -1; | |
877 } | |
878 | |
879 info->picture_base = (uint32_t) info->video_base + info->picture_offset; | |
880 | |
881 vinfo->dga_addr = (void *) (info->picture_base); | |
882 | |
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; | |
886 | |
887 for (i = 0; i < vinfo->num_frames; i++) | |
888 vinfo->offsets[i] = vinfo->frame_size * i; | |
889 | |
890 return 0; | |
891 } | |
892 | |
893 static int s3_playback_on (void) | |
894 { | |
895 S3DisplayVideo (); | |
896 return 0; | |
897 } | |
898 | |
899 static int s3_playback_off (void) | |
900 { | |
901 S3StreamsOff (); | |
902 return 0; | |
903 } | |
904 | |
905 static int s3_frame_sel (unsigned int frame) | |
906 { | |
907 OUTREG (SSTREAM_FBADDR0_REG, info->picture_offset + (info->frame_size * frame)); | |
908 return 0; | |
909 } | |
910 | |
911 VDXDriver s3_drv = { | |
912 "s3", | |
913 NULL, | |
914 .probe = s3_probe, | |
915 .get_caps = s3_get_caps, | |
916 .query_fourcc = s3_query_fourcc, | |
917 .init = s3_init, | |
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, | |
923 .get_eq = s3_get_eq, | |
924 .set_eq = s3_set_eq, | |
925 .set_gkey = s3_set_gkeys, | |
926 }; |