Mercurial > mplayer.hg
annotate drivers/mga_vid.c @ 4218:3931c41f740a
Added new syncengine thanks to a new previously undocumented feature of the em8300, this might fix playback on both slow and fast machines (more testing needed). This also requires users to get the em8300 driver from cvs until the next version is released (will probably happen this weekend)
Added lots of comments, should be pretty easy to understand most of the internals now
Added lots of brackets to if's for's while's etc, this is not a cosmetical thing but rather due to the fact I got some very odd bugs with else's since I didn't properly use brackets (and it's the K&R standard to have brackets everywhere)
Fixed some bugs that would occur when disabling libmp1e
Switched to default to the new naming scheme of device nodes, the driver will slowly switch over to this state, if it can't find devices under the new name it will try the old naming scheme
I stopped opening devices in non-blocking mode, it would break the new syncengine which tries to burst data to the device (alot of times meaning it will fill the fifo pretty fast which would previously result in jerkyness on fast machines)
The device now sets the initial state of the pts and speed (probably not needed, but assumption is the mother of all fuckups =)
Keep the control interface open during the entire duration of the libvo device, we might need this to flush video buffers on seeking (currently not implemented, therefore seeking is broken)
This is beta stuff to the driver, I will get some users to test it for me and do my best to fix seeking as soon as possible...
author | mswitch |
---|---|
date | Thu, 17 Jan 2002 10:33:47 +0000 |
parents | 72d8a4d0de18 |
children | fb4b914eab8a |
rev | line source |
---|---|
2345 | 1 //#define CRTC2 |
2 | |
1 | 3 // YUY2 support (see config.format) added by A'rpi/ESP-team |
57 | 4 // double buffering added by A'rpi/ESP-team |
5 | |
6 // Set this value, if autodetection fails! (video ram size in megabytes) | |
91 | 7 // #define MGA_MEMORY_SIZE 16 |
1 | 8 |
68 | 9 //#define MGA_ALLOW_IRQ |
10 | |
11 #define MGA_VSYNC_POS 2 | |
12 | |
1 | 13 /* |
14 * | |
15 * mga_vid.c | |
16 * | |
17 * Copyright (C) 1999 Aaron Holtzman | |
18 * | |
19 * Module skeleton based on gutted agpgart module by Jeff Hartmann | |
20 * <slicer@ionet.net> | |
21 * | |
22 * Matrox MGA G200/G400 YUV Video Interface module Version 0.1.0 | |
23 * | |
24 * BES == Back End Scaler | |
25 * | |
26 * This software has been released under the terms of the GNU Public | |
27 * license. See http://www.gnu.org/copyleft/gpl.html for details. | |
28 */ | |
29 | |
30 //It's entirely possible this major conflicts with something else | |
31 /* mknod /dev/mga_vid c 178 0 */ | |
32 | |
33 #include <linux/config.h> | |
34 #include <linux/version.h> | |
35 #include <linux/module.h> | |
36 #include <linux/types.h> | |
37 #include <linux/kernel.h> | |
38 #include <linux/sched.h> | |
39 #include <linux/mm.h> | |
40 #include <linux/string.h> | |
41 #include <linux/errno.h> | |
3125
d62aa0b7fd68
use <linux/slab.h> instead of <linux/malloc.h> for kernels 2.4.9+
szabi
parents:
2345
diff
changeset
|
42 |
d62aa0b7fd68
use <linux/slab.h> instead of <linux/malloc.h> for kernels 2.4.9+
szabi
parents:
2345
diff
changeset
|
43 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) |
1 | 44 #include <linux/malloc.h> |
3125
d62aa0b7fd68
use <linux/slab.h> instead of <linux/malloc.h> for kernels 2.4.9+
szabi
parents:
2345
diff
changeset
|
45 #else |
d62aa0b7fd68
use <linux/slab.h> instead of <linux/malloc.h> for kernels 2.4.9+
szabi
parents:
2345
diff
changeset
|
46 #include <linux/slab.h> |
d62aa0b7fd68
use <linux/slab.h> instead of <linux/malloc.h> for kernels 2.4.9+
szabi
parents:
2345
diff
changeset
|
47 #endif |
d62aa0b7fd68
use <linux/slab.h> instead of <linux/malloc.h> for kernels 2.4.9+
szabi
parents:
2345
diff
changeset
|
48 |
1 | 49 #include <linux/pci.h> |
63 | 50 #include <linux/ioport.h> |
1 | 51 #include <linux/init.h> |
52 | |
53 #include "mga_vid.h" | |
54 | |
55 #ifdef CONFIG_MTRR | |
56 #include <asm/mtrr.h> | |
57 #endif | |
58 | |
59 #include <asm/uaccess.h> | |
60 #include <asm/system.h> | |
61 #include <asm/io.h> | |
62 | |
63 #define TRUE 1 | |
64 #define FALSE 0 | |
65 | |
66 #define MGA_VID_MAJOR 178 | |
67 | |
57 | 68 //#define MGA_VIDMEM_SIZE mga_ram_size |
1 | 69 |
70 #ifndef PCI_DEVICE_ID_MATROX_G200_PCI | |
71 #define PCI_DEVICE_ID_MATROX_G200_PCI 0x0520 | |
72 #endif | |
73 | |
74 #ifndef PCI_DEVICE_ID_MATROX_G200_AGP | |
75 #define PCI_DEVICE_ID_MATROX_G200_AGP 0x0521 | |
76 #endif | |
77 | |
78 #ifndef PCI_DEVICE_ID_MATROX_G400 | |
79 #define PCI_DEVICE_ID_MATROX_G400 0x0525 | |
80 #endif | |
81 | |
1989 | 82 #ifndef PCI_DEVICE_ID_MATROX_G550 |
83 #define PCI_DEVICE_ID_MATROX_G550 0x2527 | |
84 #endif | |
85 | |
1 | 86 MODULE_AUTHOR("Aaron Holtzman <aholtzma@engr.uvic.ca>"); |
2262 | 87 #ifdef MODULE_LICENSE |
88 MODULE_LICENSE("GPL"); | |
89 #endif | |
1 | 90 |
91 typedef struct bes_registers_s | |
92 { | |
93 //BES Control | |
94 uint32_t besctl; | |
95 //BES Global control | |
96 uint32_t besglobctl; | |
97 //Luma control (brightness and contrast) | |
98 uint32_t beslumactl; | |
99 //Line pitch | |
100 uint32_t bespitch; | |
101 | |
102 //Buffer A-1 Chroma 3 plane org | |
103 uint32_t besa1c3org; | |
104 //Buffer A-1 Chroma org | |
105 uint32_t besa1corg; | |
106 //Buffer A-1 Luma org | |
107 uint32_t besa1org; | |
108 | |
109 //Buffer A-2 Chroma 3 plane org | |
110 uint32_t besa2c3org; | |
111 //Buffer A-2 Chroma org | |
112 uint32_t besa2corg; | |
113 //Buffer A-2 Luma org | |
114 uint32_t besa2org; | |
115 | |
116 //Buffer B-1 Chroma 3 plane org | |
117 uint32_t besb1c3org; | |
118 //Buffer B-1 Chroma org | |
119 uint32_t besb1corg; | |
120 //Buffer B-1 Luma org | |
121 uint32_t besb1org; | |
122 | |
123 //Buffer B-2 Chroma 3 plane org | |
124 uint32_t besb2c3org; | |
125 //Buffer B-2 Chroma org | |
126 uint32_t besb2corg; | |
127 //Buffer B-2 Luma org | |
128 uint32_t besb2org; | |
129 | |
130 //BES Horizontal coord | |
131 uint32_t beshcoord; | |
132 //BES Horizontal inverse scaling [5.14] | |
133 uint32_t beshiscal; | |
134 //BES Horizontal source start [10.14] (for scaling) | |
135 uint32_t beshsrcst; | |
136 //BES Horizontal source ending [10.14] (for scaling) | |
137 uint32_t beshsrcend; | |
138 //BES Horizontal source last | |
139 uint32_t beshsrclst; | |
140 | |
141 | |
142 //BES Vertical coord | |
143 uint32_t besvcoord; | |
144 //BES Vertical inverse scaling [5.14] | |
145 uint32_t besviscal; | |
146 //BES Field 1 vertical source last position | |
147 uint32_t besv1srclst; | |
148 //BES Field 1 weight start | |
149 uint32_t besv1wght; | |
150 //BES Field 2 vertical source last position | |
151 uint32_t besv2srclst; | |
152 //BES Field 2 weight start | |
153 uint32_t besv2wght; | |
154 | |
155 } bes_registers_t; | |
156 | |
157 static bes_registers_t regs; | |
2344 | 158 #ifdef CRTC2 |
159 typedef struct crtc2_registers_s | |
160 { | |
161 uint32_t c2ctl; | |
162 uint32_t c2datactl; | |
163 uint32_t c2misc; | |
164 uint32_t c2hparam; | |
165 uint32_t c2hsync; | |
166 uint32_t c2offset; | |
167 uint32_t c2pl2startadd0; | |
168 uint32_t c2pl2startadd1; | |
169 uint32_t c2pl3startadd0; | |
170 uint32_t c2pl3startadd1; | |
171 uint32_t c2preload; | |
172 uint32_t c2spicstartadd0; | |
173 uint32_t c2spicstartadd1; | |
174 uint32_t c2startadd0; | |
175 uint32_t c2startadd1; | |
176 uint32_t c2subpiclut; | |
177 uint32_t c2vcount; | |
178 uint32_t c2vparam; | |
179 uint32_t c2vsync; | |
180 } crtc2_registers_t; | |
181 static crtc2_registers_t cregs; | |
182 #endif | |
1 | 183 static uint32_t mga_vid_in_use = 0; |
184 static uint32_t is_g400 = 0; | |
185 static uint32_t vid_src_ready = 0; | |
186 static uint32_t vid_overlay_on = 0; | |
187 | |
188 static uint8_t *mga_mmio_base = 0; | |
189 static uint32_t mga_mem_base = 0; | |
190 | |
57 | 191 static int mga_src_base = 0; // YUV buffer position in video memory |
192 | |
193 static uint32_t mga_ram_size = 0; // how much megabytes videoram we have | |
1 | 194 |
95 | 195 //static int mga_force_memsize = 0; |
90 | 196 |
95 | 197 MODULE_PARM(mga_ram_size, "i"); |
90 | 198 |
1 | 199 static struct pci_dev *pci_dev; |
200 | |
201 static mga_vid_config_t mga_config; | |
202 | |
2086 | 203 static int colkey_saved=0; |
204 static int colkey_on=0; | |
205 static unsigned char colkey_color[4]; | |
206 static unsigned char colkey_mask[4]; | |
207 | |
48 | 208 static int mga_irq = -1; |
1 | 209 |
210 //All register offsets are converted to word aligned offsets (32 bit) | |
211 //because we want all our register accesses to be 32 bits | |
212 #define VCOUNT 0x1e20 | |
213 | |
214 #define PALWTADD 0x3c00 // Index register for X_DATAREG port | |
215 #define X_DATAREG 0x3c0a | |
216 | |
217 #define XMULCTRL 0x19 | |
218 #define BPP_8 0x00 | |
219 #define BPP_15 0x01 | |
220 #define BPP_16 0x02 | |
221 #define BPP_24 0x03 | |
222 #define BPP_32_DIR 0x04 | |
223 #define BPP_32_PAL 0x07 | |
224 | |
225 #define XCOLMSK 0x40 | |
226 #define X_COLKEY 0x42 | |
227 #define XKEYOPMODE 0x51 | |
228 #define XCOLMSK0RED 0x52 | |
229 #define XCOLMSK0GREEN 0x53 | |
230 #define XCOLMSK0BLUE 0x54 | |
231 #define XCOLKEY0RED 0x55 | |
232 #define XCOLKEY0GREEN 0x56 | |
233 #define XCOLKEY0BLUE 0x57 | |
234 | |
2344 | 235 #ifdef CRTC2 |
236 | |
237 /*CRTC2 registers*/ | |
238 #define XMISCCTRL 0x1e | |
239 #define C2CTL 0x3c10 | |
240 #define C2DATACTL 0x3c4c | |
241 #define C2MISC 0x3c44 | |
242 #define C2HPARAM 0x3c14 | |
243 #define C2HSYNC 0x3c18 | |
244 #define C2OFFSET 0x3c40 | |
245 #define C2PL2STARTADD0 0x3c30 // like BESA1CORG | |
246 #define C2PL2STARTADD1 0x3c34 // like BESA2CORG | |
247 #define C2PL3STARTADD0 0x3c38 // like BESA1C3ORG | |
248 #define C2PL3STARTADD1 0x3c3c // like BESA2C3ORG | |
249 #define C2PRELOAD 0x3c24 | |
250 #define C2SPICSTARTADD0 0x3c54 | |
251 #define C2SPICSTARTADD1 0x3c58 | |
252 #define C2STARTADD0 0x3c28 // like BESA1ORG | |
253 #define C2STARTADD1 0x3c2c // like BESA2ORG | |
254 #define C2SUBPICLUT 0x3c50 | |
255 #define C2VCOUNT 0x3c48 | |
256 #define C2VPARAM 0x3c1c | |
257 #define C2VSYNC 0x3c20 | |
258 | |
259 #endif | |
260 | |
1 | 261 // Backend Scaler registers |
262 #define BESCTL 0x3d20 | |
263 #define BESGLOBCTL 0x3dc0 | |
264 #define BESLUMACTL 0x3d40 | |
265 #define BESPITCH 0x3d24 | |
48 | 266 |
1 | 267 #define BESA1C3ORG 0x3d60 |
268 #define BESA1CORG 0x3d10 | |
269 #define BESA1ORG 0x3d00 | |
48 | 270 |
1 | 271 #define BESA2C3ORG 0x3d64 |
272 #define BESA2CORG 0x3d14 | |
273 #define BESA2ORG 0x3d04 | |
48 | 274 |
1 | 275 #define BESB1C3ORG 0x3d68 |
276 #define BESB1CORG 0x3d18 | |
277 #define BESB1ORG 0x3d08 | |
48 | 278 |
1 | 279 #define BESB2C3ORG 0x3d6C |
280 #define BESB2CORG 0x3d1C | |
281 #define BESB2ORG 0x3d0C | |
48 | 282 |
1 | 283 #define BESHCOORD 0x3d28 |
284 #define BESHISCAL 0x3d30 | |
285 #define BESHSRCEND 0x3d3C | |
286 #define BESHSRCLST 0x3d50 | |
287 #define BESHSRCST 0x3d38 | |
288 #define BESV1WGHT 0x3d48 | |
289 #define BESV2WGHT 0x3d4c | |
290 #define BESV1SRCLST 0x3d54 | |
291 #define BESV2SRCLST 0x3d58 | |
292 #define BESVISCAL 0x3d34 | |
293 #define BESVCOORD 0x3d2c | |
294 #define BESSTATUS 0x3dc4 | |
295 | |
48 | 296 #define CRTCX 0x1fd4 |
297 #define CRTCD 0x1fd5 | |
298 #define IEN 0x1e1c | |
299 #define ICLEAR 0x1e18 | |
300 #define STATUS 0x1e14 | |
301 | |
302 static int mga_next_frame=0; | |
1 | 303 |
2344 | 304 #ifdef CRTC2 |
305 static void crtc2_frame_sel(int frame) | |
306 { | |
307 switch(frame) { | |
308 case 0: | |
309 cregs.c2pl2startadd0=regs.besa1corg; | |
310 cregs.c2pl3startadd0=regs.besa1c3org; | |
311 cregs.c2startadd0=regs.besa1org; | |
312 break; | |
313 case 1: | |
314 cregs.c2pl2startadd0=regs.besa2corg; | |
315 cregs.c2pl3startadd0=regs.besa2c3org; | |
316 cregs.c2startadd0=regs.besa2org; | |
317 break; | |
318 case 2: | |
319 cregs.c2pl2startadd0=regs.besb1corg; | |
320 cregs.c2pl3startadd0=regs.besb1c3org; | |
321 cregs.c2startadd0=regs.besb1org; | |
322 break; | |
323 case 3: | |
324 cregs.c2pl2startadd0=regs.besb2corg; | |
325 cregs.c2pl3startadd0=regs.besb2c3org; | |
326 cregs.c2startadd0=regs.besb2org; | |
327 break; | |
328 } | |
329 writel(cregs.c2startadd0, mga_mmio_base + C2STARTADD0); | |
330 writel(cregs.c2pl2startadd0, mga_mmio_base + C2PL2STARTADD0); | |
331 writel(cregs.c2pl3startadd0, mga_mmio_base + C2PL3STARTADD0); | |
332 } | |
333 #endif | |
334 | |
1 | 335 static void mga_vid_frame_sel(int frame) |
336 { | |
48 | 337 if ( mga_irq != -1 ) { |
338 mga_next_frame=frame; | |
339 } else { | |
340 | |
1 | 341 //we don't need the vcount protection as we're only hitting |
342 //one register (and it doesn't seem to be double buffered) | |
343 regs.besctl = (regs.besctl & ~0x07000000) + (frame << 25); | |
344 writel( regs.besctl, mga_mmio_base + BESCTL ); | |
68 | 345 |
346 // writel( regs.besglobctl + ((readl(mga_mmio_base + VCOUNT)+2)<<16), | |
347 writel( regs.besglobctl + (MGA_VSYNC_POS<<16), | |
348 mga_mmio_base + BESGLOBCTL); | |
2344 | 349 #ifdef CRTC2 |
350 crtc2_frame_sel(frame); | |
351 #endif | |
68 | 352 |
48 | 353 } |
1 | 354 } |
355 | |
356 | |
2086 | 357 static void mga_vid_write_regs(int restore) |
1 | 358 { |
359 //Make sure internal registers don't get updated until we're done | |
360 writel( (readl(mga_mmio_base + VCOUNT)-1)<<16, | |
361 mga_mmio_base + BESGLOBCTL); | |
362 | |
363 // color or coordinate keying | |
2086 | 364 |
365 if(restore && colkey_saved){ | |
366 // restore it | |
367 colkey_saved=0; | |
368 | |
369 printk("mga_vid: Restoring colorkey (ON: %d %02X:%02X:%02X)\n", | |
370 colkey_on,colkey_color[0],colkey_color[1],colkey_color[2]); | |
371 | |
372 // Set color key registers: | |
373 writeb( XKEYOPMODE, mga_mmio_base + PALWTADD); | |
374 writeb( colkey_on, mga_mmio_base + X_DATAREG); | |
375 | |
376 writeb( XCOLKEY0RED, mga_mmio_base + PALWTADD); | |
377 writeb( colkey_color[0], mga_mmio_base + X_DATAREG); | |
378 writeb( XCOLKEY0GREEN, mga_mmio_base + PALWTADD); | |
379 writeb( colkey_color[1], mga_mmio_base + X_DATAREG); | |
380 writeb( XCOLKEY0BLUE, mga_mmio_base + PALWTADD); | |
381 writeb( colkey_color[2], mga_mmio_base + X_DATAREG); | |
382 writeb( X_COLKEY, mga_mmio_base + PALWTADD); | |
383 writeb( colkey_color[3], mga_mmio_base + X_DATAREG); | |
384 | |
385 writeb( XCOLMSK0RED, mga_mmio_base + PALWTADD); | |
386 writeb( colkey_mask[0], mga_mmio_base + X_DATAREG); | |
387 writeb( XCOLMSK0GREEN, mga_mmio_base + PALWTADD); | |
388 writeb( colkey_mask[1], mga_mmio_base + X_DATAREG); | |
389 writeb( XCOLMSK0BLUE, mga_mmio_base + PALWTADD); | |
390 writeb( colkey_mask[2], mga_mmio_base + X_DATAREG); | |
391 writeb( XCOLMSK, mga_mmio_base + PALWTADD); | |
392 writeb( colkey_mask[3], mga_mmio_base + X_DATAREG); | |
393 | |
394 } else if(!colkey_saved){ | |
395 // save it | |
396 colkey_saved=1; | |
397 // Get color key registers: | |
398 writeb( XKEYOPMODE, mga_mmio_base + PALWTADD); | |
399 colkey_on=(unsigned char)readb(mga_mmio_base + X_DATAREG) & 1; | |
400 | |
401 writeb( XCOLKEY0RED, mga_mmio_base + PALWTADD); | |
402 colkey_color[0]=(unsigned char)readb(mga_mmio_base + X_DATAREG); | |
403 writeb( XCOLKEY0GREEN, mga_mmio_base + PALWTADD); | |
404 colkey_color[1]=(unsigned char)readb(mga_mmio_base + X_DATAREG); | |
405 writeb( XCOLKEY0BLUE, mga_mmio_base + PALWTADD); | |
406 colkey_color[2]=(unsigned char)readb(mga_mmio_base + X_DATAREG); | |
407 writeb( X_COLKEY, mga_mmio_base + PALWTADD); | |
408 colkey_color[3]=(unsigned char)readb(mga_mmio_base + X_DATAREG); | |
409 | |
410 writeb( XCOLMSK0RED, mga_mmio_base + PALWTADD); | |
411 colkey_mask[0]=(unsigned char)readb(mga_mmio_base + X_DATAREG); | |
412 writeb( XCOLMSK0GREEN, mga_mmio_base + PALWTADD); | |
413 colkey_mask[1]=(unsigned char)readb(mga_mmio_base + X_DATAREG); | |
414 writeb( XCOLMSK0BLUE, mga_mmio_base + PALWTADD); | |
415 colkey_mask[2]=(unsigned char)readb(mga_mmio_base + X_DATAREG); | |
416 writeb( XCOLMSK, mga_mmio_base + PALWTADD); | |
417 colkey_mask[3]=(unsigned char)readb(mga_mmio_base + X_DATAREG); | |
418 | |
419 printk("mga_vid: Saved colorkey (ON: %d %02X:%02X:%02X)\n", | |
420 colkey_on,colkey_color[0],colkey_color[1],colkey_color[2]); | |
421 | |
422 } | |
423 | |
424 if(!restore){ | |
1 | 425 writeb( XKEYOPMODE, mga_mmio_base + PALWTADD); |
426 writeb( mga_config.colkey_on, mga_mmio_base + X_DATAREG); | |
427 if ( mga_config.colkey_on ) | |
428 { | |
429 uint32_t r=0, g=0, b=0; | |
430 | |
431 writeb( XMULCTRL, mga_mmio_base + PALWTADD); | |
432 switch (readb (mga_mmio_base + X_DATAREG)) | |
433 { | |
434 case BPP_8: | |
435 /* Need to look up the color index, just using | |
436 color 0 for now. */ | |
437 break; | |
438 | |
439 case BPP_15: | |
440 r = mga_config.colkey_red >> 3; | |
441 g = mga_config.colkey_green >> 3; | |
442 b = mga_config.colkey_blue >> 3; | |
443 break; | |
444 | |
445 case BPP_16: | |
446 r = mga_config.colkey_red >> 3; | |
447 g = mga_config.colkey_green >> 2; | |
448 b = mga_config.colkey_blue >> 3; | |
449 break; | |
450 | |
451 case BPP_24: | |
452 case BPP_32_DIR: | |
453 case BPP_32_PAL: | |
454 r = mga_config.colkey_red; | |
455 g = mga_config.colkey_green; | |
456 b = mga_config.colkey_blue; | |
457 break; | |
458 } | |
459 | |
460 // Disable color keying on alpha channel | |
461 writeb( XCOLMSK, mga_mmio_base + PALWTADD); | |
462 writeb( 0x00, mga_mmio_base + X_DATAREG); | |
463 writeb( X_COLKEY, mga_mmio_base + PALWTADD); | |
464 writeb( 0x00, mga_mmio_base + X_DATAREG); | |
465 | |
2086 | 466 |
1 | 467 // Set up color key registers |
468 writeb( XCOLKEY0RED, mga_mmio_base + PALWTADD); | |
469 writeb( r, mga_mmio_base + X_DATAREG); | |
470 writeb( XCOLKEY0GREEN, mga_mmio_base + PALWTADD); | |
471 writeb( g, mga_mmio_base + X_DATAREG); | |
472 writeb( XCOLKEY0BLUE, mga_mmio_base + PALWTADD); | |
473 writeb( b, mga_mmio_base + X_DATAREG); | |
474 | |
475 // Set up color key mask registers | |
476 writeb( XCOLMSK0RED, mga_mmio_base + PALWTADD); | |
477 writeb( 0xff, mga_mmio_base + X_DATAREG); | |
478 writeb( XCOLMSK0GREEN, mga_mmio_base + PALWTADD); | |
479 writeb( 0xff, mga_mmio_base + X_DATAREG); | |
480 writeb( XCOLMSK0BLUE, mga_mmio_base + PALWTADD); | |
481 writeb( 0xff, mga_mmio_base + X_DATAREG); | |
482 } | |
483 | |
2086 | 484 } |
485 | |
1 | 486 // Backend Scaler |
487 writel( regs.besctl, mga_mmio_base + BESCTL); | |
488 if(is_g400) | |
489 writel( regs.beslumactl, mga_mmio_base + BESLUMACTL); | |
490 writel( regs.bespitch, mga_mmio_base + BESPITCH); | |
491 | |
492 writel( regs.besa1org, mga_mmio_base + BESA1ORG); | |
493 writel( regs.besa1corg, mga_mmio_base + BESA1CORG); | |
48 | 494 writel( regs.besa2org, mga_mmio_base + BESA2ORG); |
495 writel( regs.besa2corg, mga_mmio_base + BESA2CORG); | |
1 | 496 writel( regs.besb1org, mga_mmio_base + BESB1ORG); |
497 writel( regs.besb1corg, mga_mmio_base + BESB1CORG); | |
48 | 498 writel( regs.besb2org, mga_mmio_base + BESB2ORG); |
499 writel( regs.besb2corg, mga_mmio_base + BESB2CORG); | |
1 | 500 if(is_g400) |
501 { | |
502 writel( regs.besa1c3org, mga_mmio_base + BESA1C3ORG); | |
48 | 503 writel( regs.besa2c3org, mga_mmio_base + BESA2C3ORG); |
1 | 504 writel( regs.besb1c3org, mga_mmio_base + BESB1C3ORG); |
48 | 505 writel( regs.besb2c3org, mga_mmio_base + BESB2C3ORG); |
1 | 506 } |
507 | |
508 writel( regs.beshcoord, mga_mmio_base + BESHCOORD); | |
509 writel( regs.beshiscal, mga_mmio_base + BESHISCAL); | |
510 writel( regs.beshsrcst, mga_mmio_base + BESHSRCST); | |
511 writel( regs.beshsrcend, mga_mmio_base + BESHSRCEND); | |
512 writel( regs.beshsrclst, mga_mmio_base + BESHSRCLST); | |
513 | |
514 writel( regs.besvcoord, mga_mmio_base + BESVCOORD); | |
515 writel( regs.besviscal, mga_mmio_base + BESVISCAL); | |
48 | 516 |
1 | 517 writel( regs.besv1srclst, mga_mmio_base + BESV1SRCLST); |
518 writel( regs.besv1wght, mga_mmio_base + BESV1WGHT); | |
48 | 519 writel( regs.besv2srclst, mga_mmio_base + BESV2SRCLST); |
520 writel( regs.besv2wght, mga_mmio_base + BESV2WGHT); | |
1 | 521 |
522 //update the registers somewhere between 1 and 2 frames from now. | |
523 writel( regs.besglobctl + ((readl(mga_mmio_base + VCOUNT)+2)<<16), | |
524 mga_mmio_base + BESGLOBCTL); | |
525 | |
77 | 526 #if 0 |
61 | 527 printk(KERN_DEBUG "mga_vid: wrote BES registers\n"); |
528 printk(KERN_DEBUG "mga_vid: BESCTL = 0x%08x\n", | |
1 | 529 readl(mga_mmio_base + BESCTL)); |
61 | 530 printk(KERN_DEBUG "mga_vid: BESGLOBCTL = 0x%08x\n", |
1 | 531 readl(mga_mmio_base + BESGLOBCTL)); |
61 | 532 printk(KERN_DEBUG "mga_vid: BESSTATUS= 0x%08x\n", |
1 | 533 readl(mga_mmio_base + BESSTATUS)); |
77 | 534 #endif |
2344 | 535 #ifdef CRTC2 |
536 // printk("c2ctl:0x%08x c2datactl:0x%08x\n",readl(mga_mmio_base + C2CTL),readl(mga_mmio_base + C2DATACTL)); | |
537 // printk("c2misc:0x%08x\n",readl(mga_mmio_base + C2MISC)); | |
538 // printk("c2ctl:0x%08x c2datactl:0x%08x\n",cregs.c2ctl,cregs.c2datactl); | |
539 | |
540 // writel(cregs.c2ctl, mga_mmio_base + C2CTL); | |
541 | |
542 writel(((readl(mga_mmio_base + C2CTL) & ~0x03e00000) + (cregs.c2ctl & 0x03e00000)), mga_mmio_base + C2CTL); | |
543 writel(((readl(mga_mmio_base + C2DATACTL) & ~0x000000ff) + (cregs.c2datactl & 0x000000ff)), mga_mmio_base + C2DATACTL); | |
544 // ctrc2 | |
545 // disable CRTC2 acording to specs | |
546 // writel(cregs.c2ctl & 0xfffffff0, mga_mmio_base + C2CTL); | |
547 // je to treba ??? | |
548 // writeb((readb(mga_mmio_base + XMISCCTRL) & 0x19) | 0xa2, mga_mmio_base + XMISCCTRL); // MAFC - mfcsel & vdoutsel | |
549 // writeb((readb(mga_mmio_base + XMISCCTRL) & 0x19) | 0x92, mga_mmio_base + XMISCCTRL); | |
550 // writeb((readb(mga_mmio_base + XMISCCTRL) & ~0xe9) + 0xa2, mga_mmio_base + XMISCCTRL); | |
551 // writel(cregs.c2datactl, mga_mmio_base + C2DATACTL); | |
552 // writel(cregs.c2hparam, mga_mmio_base + C2HPARAM); | |
553 // writel(cregs.c2hsync, mga_mmio_base + C2HSYNC); | |
554 // writel(cregs.c2vparam, mga_mmio_base + C2VPARAM); | |
555 // writel(cregs.c2vsync, mga_mmio_base + C2VSYNC); | |
556 writel(cregs.c2misc, mga_mmio_base + C2MISC); | |
557 | |
558 printk("c2offset = %d\n",cregs.c2offset); | |
559 | |
560 writel(cregs.c2offset, mga_mmio_base + C2OFFSET); | |
561 writel(cregs.c2startadd0, mga_mmio_base + C2STARTADD0); | |
562 // writel(cregs.c2startadd1, mga_mmio_base + C2STARTADD1); | |
563 writel(cregs.c2pl2startadd0, mga_mmio_base + C2PL2STARTADD0); | |
564 // writel(cregs.c2pl2startadd1, mga_mmio_base + C2PL2STARTADD1); | |
565 writel(cregs.c2pl3startadd0, mga_mmio_base + C2PL3STARTADD0); | |
566 // writel(cregs.c2pl3startadd1, mga_mmio_base + C2PL3STARTADD1); | |
567 writel(cregs.c2spicstartadd0, mga_mmio_base + C2SPICSTARTADD0); | |
568 // writel(cregs.c2spicstartadd1, mga_mmio_base + C2SPICSTARTADD1); | |
569 // writel(cregs.c2subpiclut, mga_mmio_base + C2SUBPICLUT); | |
570 // writel(cregs.c2preload, mga_mmio_base + C2PRELOAD); | |
571 // finaly enable everything | |
572 // writel(cregs.c2ctl, mga_mmio_base + C2CTL); | |
573 // printk("c2ctl:0x%08x c2datactl:0x%08x\n",readl(mga_mmio_base + C2CTL),readl(mga_mmio_base + C2DATACTL)); | |
574 // printk("c2misc:0x%08x\n", readl(mga_mmio_base + C2MISC)); | |
575 #endif | |
1 | 576 } |
577 | |
578 static int mga_vid_set_config(mga_vid_config_t *config) | |
579 { | |
580 int x, y, sw, sh, dw, dh; | |
581 int besleft, bestop, ifactor, ofsleft, ofstop, baseadrofs, weight, weights; | |
57 | 582 int frame_size=config->frame_size; |
2344 | 583 #ifdef CRTC2 |
584 #define right_margin 0 | |
585 #define left_margin 18 | |
586 #define hsync_len 46 | |
587 #define lower_margin 10 | |
588 #define vsync_len 4 | |
589 #define upper_margin 39 | |
590 | |
591 unsigned int hdispend = (config->src_width + 31) & ~31; | |
592 unsigned int hsyncstart = hdispend + (right_margin & ~7); | |
593 unsigned int hsyncend = hsyncstart + (hsync_len & ~7); | |
594 unsigned int htotal = hsyncend + (left_margin & ~7); | |
595 unsigned int vdispend = config->src_height; | |
596 unsigned int vsyncstart = vdispend + lower_margin; | |
597 unsigned int vsyncend = vsyncstart + vsync_len; | |
598 unsigned int vtotal = vsyncend + upper_margin; | |
599 #endif | |
1 | 600 x = config->x_org; |
601 y = config->y_org; | |
602 sw = config->src_width; | |
603 sh = config->src_height; | |
604 dw = config->dest_width; | |
605 dh = config->dest_height; | |
606 | |
61 | 607 printk(KERN_DEBUG "mga_vid: Setting up a %dx%d+%d+%d video window (src %dx%d) format %X\n", |
1 | 608 dw, dh, x, y, sw, sh, config->format); |
609 | |
3959 | 610 if(sw<4 || sh<4 || dw<4 || dh<4){ |
611 printk(KERN_ERR "mga_vid: Invalid src/dest dimenstions\n"); | |
612 return -1; | |
613 } | |
614 | |
1 | 615 //FIXME check that window is valid and inside desktop |
616 | |
617 //FIXME figure out a better way to allocate memory on card | |
618 //allocate 2 megs | |
619 //mga_src_base = mga_mem_base + (MGA_VIDMEM_SIZE-2) * 0x100000; | |
57 | 620 //mga_src_base = (MGA_VIDMEM_SIZE-3) * 0x100000; |
1 | 621 |
622 | |
623 //Setup the BES registers for a three plane 4:2:0 video source | |
624 | |
466 | 625 regs.besglobctl = 0; |
626 | |
1 | 627 switch(config->format){ |
628 case MGA_VID_FORMAT_YV12: | |
470 | 629 case MGA_VID_FORMAT_I420: |
630 case MGA_VID_FORMAT_IYUV: | |
1 | 631 regs.besctl = 1 // BES enabled |
632 + (0<<6) // even start polarity | |
633 + (1<<10) // x filtering enabled | |
634 + (1<<11) // y filtering enabled | |
635 + (1<<16) // chroma upsampling | |
636 + (1<<17) // 4:2:0 mode | |
637 + (1<<18); // dither enabled | |
466 | 638 #if 0 |
1 | 639 if(is_g400) |
640 { | |
641 //zoom disabled, zoom filter disabled, 420 3 plane format, proc amp | |
642 //disabled, rgb mode disabled | |
643 regs.besglobctl = (1<<5); | |
644 } | |
645 else | |
646 { | |
647 //zoom disabled, zoom filter disabled, Cb samples in 0246, Cr | |
648 //in 1357, BES register update on besvcnt | |
466 | 649 regs.besglobctl = 0; |
1 | 650 } |
466 | 651 #endif |
1 | 652 break; |
653 | |
654 case MGA_VID_FORMAT_YUY2: | |
655 regs.besctl = 1 // BES enabled | |
656 + (0<<6) // even start polarity | |
657 + (1<<10) // x filtering enabled | |
658 + (1<<11) // y filtering enabled | |
659 + (1<<16) // chroma upsampling | |
660 + (0<<17) // 4:2:2 mode | |
661 + (1<<18); // dither enabled | |
662 | |
663 regs.besglobctl = 0; // YUY2 format selected | |
664 break; | |
466 | 665 |
666 case MGA_VID_FORMAT_UYVY: | |
667 regs.besctl = 1 // BES enabled | |
668 + (0<<6) // even start polarity | |
669 + (1<<10) // x filtering enabled | |
670 + (1<<11) // y filtering enabled | |
671 + (1<<16) // chroma upsampling | |
672 + (0<<17) // 4:2:2 mode | |
673 + (1<<18); // dither enabled | |
674 | |
675 regs.besglobctl = 1<<6; // UYVY format selected | |
676 break; | |
677 | |
1 | 678 default: |
61 | 679 printk(KERN_ERR "mga_vid: Unsupported pixel format: 0x%X\n",config->format); |
1 | 680 return -1; |
681 } | |
682 | |
683 | |
684 //Disable contrast and brightness control | |
466 | 685 regs.besglobctl |= (1<<5) + (1<<7); |
1 | 686 regs.beslumactl = (0x7f << 16) + (0x80<<0); |
687 regs.beslumactl = 0x80<<0; | |
688 | |
689 //Setup destination window boundaries | |
690 besleft = x > 0 ? x : 0; | |
691 bestop = y > 0 ? y : 0; | |
692 regs.beshcoord = (besleft<<16) + (x + dw-1); | |
693 regs.besvcoord = (bestop<<16) + (y + dh-1); | |
694 | |
695 //Setup source dimensions | |
696 regs.beshsrclst = (sw - 1) << 16; | |
697 regs.bespitch = (sw + 31) & ~31 ; | |
698 | |
699 //Setup horizontal scaling | |
700 ifactor = ((sw-1)<<14)/(dw-1); | |
701 ofsleft = besleft - x; | |
702 | |
703 regs.beshiscal = ifactor<<2; | |
704 regs.beshsrcst = (ofsleft*ifactor)<<2; | |
705 regs.beshsrcend = regs.beshsrcst + (((dw - ofsleft - 1) * ifactor) << 2); | |
706 | |
707 //Setup vertical scaling | |
708 ifactor = ((sh-1)<<14)/(dh-1); | |
709 ofstop = bestop - y; | |
710 | |
711 regs.besviscal = ifactor<<2; | |
712 | |
713 baseadrofs = ((ofstop*regs.besviscal)>>16)*regs.bespitch; | |
57 | 714 //frame_size = ((sw + 31) & ~31) * sh + (((sw + 31) & ~31) * sh) / 2; |
1 | 715 regs.besa1org = (uint32_t) mga_src_base + baseadrofs; |
48 | 716 regs.besa2org = (uint32_t) mga_src_base + baseadrofs + 1*frame_size; |
717 regs.besb1org = (uint32_t) mga_src_base + baseadrofs + 2*frame_size; | |
718 regs.besb2org = (uint32_t) mga_src_base + baseadrofs + 3*frame_size; | |
1 | 719 |
470 | 720 if(config->format==MGA_VID_FORMAT_YV12 |
721 ||config->format==MGA_VID_FORMAT_IYUV | |
722 ||config->format==MGA_VID_FORMAT_I420 | |
723 ){ | |
57 | 724 // planar YUV frames: |
1 | 725 if (is_g400) |
726 baseadrofs = (((ofstop*regs.besviscal)/4)>>16)*regs.bespitch; | |
727 else | |
728 baseadrofs = (((ofstop*regs.besviscal)/2)>>16)*regs.bespitch; | |
729 | |
470 | 730 if(config->format==MGA_VID_FORMAT_YV12){ |
1 | 731 regs.besa1corg = (uint32_t) mga_src_base + baseadrofs + regs.bespitch * sh ; |
48 | 732 regs.besa2corg = (uint32_t) mga_src_base + baseadrofs + 1*frame_size + regs.bespitch * sh; |
733 regs.besb1corg = (uint32_t) mga_src_base + baseadrofs + 2*frame_size + regs.bespitch * sh; | |
734 regs.besb2corg = (uint32_t) mga_src_base + baseadrofs + 3*frame_size + regs.bespitch * sh; | |
1 | 735 regs.besa1c3org = regs.besa1corg + ((regs.bespitch * sh) / 4); |
48 | 736 regs.besa2c3org = regs.besa2corg + ((regs.bespitch * sh) / 4); |
1 | 737 regs.besb1c3org = regs.besb1corg + ((regs.bespitch * sh) / 4); |
48 | 738 regs.besb2c3org = regs.besb2corg + ((regs.bespitch * sh) / 4); |
470 | 739 } else { |
740 regs.besa1c3org = (uint32_t) mga_src_base + baseadrofs + regs.bespitch * sh ; | |
741 regs.besa2c3org = (uint32_t) mga_src_base + baseadrofs + 1*frame_size + regs.bespitch * sh; | |
742 regs.besb1c3org = (uint32_t) mga_src_base + baseadrofs + 2*frame_size + regs.bespitch * sh; | |
743 regs.besb2c3org = (uint32_t) mga_src_base + baseadrofs + 3*frame_size + regs.bespitch * sh; | |
744 regs.besa1corg = regs.besa1c3org + ((regs.bespitch * sh) / 4); | |
745 regs.besa2corg = regs.besa2c3org + ((regs.bespitch * sh) / 4); | |
746 regs.besb1corg = regs.besb1c3org + ((regs.bespitch * sh) / 4); | |
747 regs.besb2corg = regs.besb2c3org + ((regs.bespitch * sh) / 4); | |
748 } | |
749 | |
57 | 750 } |
1 | 751 |
752 weight = ofstop * (regs.besviscal >> 2); | |
753 weights = weight < 0 ? 1 : 0; | |
48 | 754 regs.besv2wght = regs.besv1wght = (weights << 16) + ((weight & 0x3FFF) << 2); |
755 regs.besv2srclst = regs.besv1srclst = sh - 1 - (((ofstop * regs.besviscal) >> 16) & 0x03FF); | |
1 | 756 |
2344 | 757 #ifdef CRTC2 |
758 // pridat hlavni registry - tj. casovani ... | |
759 | |
760 | |
761 switch(config->format){ | |
762 case MGA_VID_FORMAT_YV12: | |
763 case MGA_VID_FORMAT_I420: | |
764 case MGA_VID_FORMAT_IYUV: | |
765 cregs.c2ctl = 1 // CRTC2 enabled | |
766 + (1<<1) // external clock | |
767 + (0<<2) // external clock | |
768 + (1<<3) // pixel clock enable - not needed ??? | |
769 + (0<<4) // high prioryty req | |
770 + (1<<5) // high prioryty req | |
771 + (0<<6) // high prioryty req | |
772 + (1<<8) // high prioryty req max | |
773 + (0<<9) // high prioryty req max | |
774 + (0<<10) // high prioryty req max | |
775 + (0<<20) // CRTC1 to DAC | |
776 + (1<<21) // 420 mode | |
777 + (1<<22) // 420 mode | |
778 + (1<<23) // 420 mode | |
779 + (0<<24) // single chroma line for 420 mode - need to be corrected | |
780 + (0<<25) /*/ interlace mode - need to be corrected*/ | |
781 + (0<<26) // field legth polariry | |
782 + (0<<27) // field identification polariry | |
783 + (1<<28) // VIDRST detection mode | |
784 + (0<<29) // VIDRST detection mode | |
785 + (1<<30) // Horizontal counter preload | |
786 + (1<<31) // Vertical counter preload | |
787 ; | |
788 cregs.c2datactl = 1 // disable dither - propably not needed, we are already in YUV mode | |
789 + (1<<1) // Y filter enable | |
790 + (1<<2) // CbCr filter enable | |
791 + (0<<3) // subpicture enable (disabled) | |
792 + (0<<4) // NTSC enable (disabled - PAL) | |
793 + (0<<5) // C2 static subpicture enable (disabled) | |
794 + (0<<6) // C2 subpicture offset division (disabled) | |
795 + (0<<7) // 422 subformat selection ! | |
796 /* + (0<<8) // 15 bpp high alpha | |
797 + (0<<9) // 15 bpp high alpha | |
798 + (0<<10) // 15 bpp high alpha | |
799 + (0<<11) // 15 bpp high alpha | |
800 + (0<<12) // 15 bpp high alpha | |
801 + (0<<13) // 15 bpp high alpha | |
802 + (0<<14) // 15 bpp high alpha | |
803 + (0<<15) // 15 bpp high alpha | |
804 + (0<<16) // 15 bpp low alpha | |
805 + (0<<17) // 15 bpp low alpha | |
806 + (0<<18) // 15 bpp low alpha | |
807 + (0<<19) // 15 bpp low alpha | |
808 + (0<<20) // 15 bpp low alpha | |
809 + (0<<21) // 15 bpp low alpha | |
810 + (0<<22) // 15 bpp low alpha | |
811 + (0<<23) // 15 bpp low alpha | |
812 + (0<<24) // static subpicture key | |
813 + (0<<25) // static subpicture key | |
814 + (0<<26) // static subpicture key | |
815 + (0<<27) // static subpicture key | |
816 + (0<<28) // static subpicture key | |
817 */ ; | |
818 break; | |
819 | |
820 case MGA_VID_FORMAT_YUY2: | |
821 cregs.c2ctl = 1 // CRTC2 enabled | |
822 + (1<<1) // external clock | |
823 + (0<<2) // external clock | |
824 + (1<<3) // pixel clock enable - not needed ??? | |
825 + (0<<4) // high prioryty req - acc to spec | |
826 + (1<<5) // high prioryty req | |
827 + (0<<6) // high prioryty req | |
828 // 7 reserved | |
829 + (1<<8) // high prioryty req max | |
830 + (0<<9) // high prioryty req max | |
831 + (0<<10) // high prioryty req max | |
832 // 11-19 reserved | |
833 + (0<<20) // CRTC1 to DAC | |
834 + (1<<21) // 422 mode | |
835 + (0<<22) // 422 mode | |
836 + (1<<23) // 422 mode | |
837 + (0<<24) // single chroma line for 420 mode - need to be corrected | |
838 + (0<<25) /*/ interlace mode - need to be corrected*/ | |
839 + (0<<26) // field legth polariry | |
840 + (0<<27) // field identification polariry | |
841 + (1<<28) // VIDRST detection mode | |
842 + (0<<29) // VIDRST detection mode | |
843 + (1<<30) // Horizontal counter preload | |
844 + (1<<31) // Vertical counter preload | |
845 ; | |
846 cregs.c2datactl = 1 // disable dither - propably not needed, we are already in YUV mode | |
847 + (1<<1) // Y filter enable | |
848 + (1<<2) // CbCr filter enable | |
849 + (0<<3) // subpicture enable (disabled) | |
850 + (0<<4) // NTSC enable (disabled - PAL) | |
851 + (0<<5) // C2 static subpicture enable (disabled) | |
852 + (0<<6) // C2 subpicture offset division (disabled) | |
853 + (0<<7) // 422 subformat selection ! | |
854 /* + (0<<8) // 15 bpp high alpha | |
855 + (0<<9) // 15 bpp high alpha | |
856 + (0<<10) // 15 bpp high alpha | |
857 + (0<<11) // 15 bpp high alpha | |
858 + (0<<12) // 15 bpp high alpha | |
859 + (0<<13) // 15 bpp high alpha | |
860 + (0<<14) // 15 bpp high alpha | |
861 + (0<<15) // 15 bpp high alpha | |
862 + (0<<16) // 15 bpp low alpha | |
863 + (0<<17) // 15 bpp low alpha | |
864 + (0<<18) // 15 bpp low alpha | |
865 + (0<<19) // 15 bpp low alpha | |
866 + (0<<20) // 15 bpp low alpha | |
867 + (0<<21) // 15 bpp low alpha | |
868 + (0<<22) // 15 bpp low alpha | |
869 + (0<<23) // 15 bpp low alpha | |
870 + (0<<24) // static subpicture key | |
871 + (0<<25) // static subpicture key | |
872 + (0<<26) // static subpicture key | |
873 + (0<<27) // static subpicture key | |
874 + (0<<28) // static subpicture key | |
875 */ ; | |
876 break; | |
877 | |
878 case MGA_VID_FORMAT_UYVY: | |
879 cregs.c2ctl = 1 // CRTC2 enabled | |
880 + (1<<1) // external clock | |
881 + (0<<2) // external clock | |
882 + (1<<3) // pixel clock enable - not needed ??? | |
883 + (0<<4) // high prioryty req | |
884 + (1<<5) // high prioryty req | |
885 + (0<<6) // high prioryty req | |
886 + (1<<8) // high prioryty req max | |
887 + (0<<9) // high prioryty req max | |
888 + (0<<10) // high prioryty req max | |
889 + (0<<20) // CRTC1 to DAC | |
890 + (1<<21) // 422 mode | |
891 + (0<<22) // 422 mode | |
892 + (1<<23) // 422 mode | |
893 + (1<<24) // single chroma line for 420 mode - need to be corrected | |
894 + (1<<25) /*/ interlace mode - need to be corrected*/ | |
895 + (0<<26) // field legth polariry | |
896 + (0<<27) // field identification polariry | |
897 + (1<<28) // VIDRST detection mode | |
898 + (0<<29) // VIDRST detection mode | |
899 + (1<<30) // Horizontal counter preload | |
900 + (1<<31) // Vertical counter preload | |
901 ; | |
902 cregs.c2datactl = 0 // enable dither - propably not needed, we are already in YUV mode | |
903 + (1<<1) // Y filter enable | |
904 + (1<<2) // CbCr filter enable | |
905 + (0<<3) // subpicture enable (disabled) | |
906 + (0<<4) // NTSC enable (disabled - PAL) | |
907 + (0<<5) // C2 static subpicture enable (disabled) | |
908 + (0<<6) // C2 subpicture offset division (disabled) | |
909 + (1<<7) // 422 subformat selection ! | |
910 /* + (0<<8) // 15 bpp high alpha | |
911 + (0<<9) // 15 bpp high alpha | |
912 + (0<<10) // 15 bpp high alpha | |
913 + (0<<11) // 15 bpp high alpha | |
914 + (0<<12) // 15 bpp high alpha | |
915 + (0<<13) // 15 bpp high alpha | |
916 + (0<<14) // 15 bpp high alpha | |
917 + (0<<15) // 15 bpp high alpha | |
918 + (0<<16) // 15 bpp low alpha | |
919 + (0<<17) // 15 bpp low alpha | |
920 + (0<<18) // 15 bpp low alpha | |
921 + (0<<19) // 15 bpp low alpha | |
922 + (0<<20) // 15 bpp low alpha | |
923 + (0<<21) // 15 bpp low alpha | |
924 + (0<<22) // 15 bpp low alpha | |
925 + (0<<23) // 15 bpp low alpha | |
926 + (0<<24) // static subpicture key | |
927 + (0<<25) // static subpicture key | |
928 + (0<<26) // static subpicture key | |
929 + (0<<27) // static subpicture key | |
930 + (0<<28) // static subpicture key | |
931 */ ; | |
932 break; | |
933 | |
934 default: | |
935 printk(KERN_ERR "mga_vid: Unsupported pixel format: 0x%X\n",config->format); | |
936 return -1; | |
937 } | |
938 | |
939 cregs.c2hparam=((hdispend - 8) << 16) | (htotal - 8); | |
940 cregs.c2hsync=((hsyncend - 8) << 16) | (hsyncstart - 8); | |
941 | |
942 cregs.c2misc=0 // CRTCV2 656 togg f0 | |
943 +(0<<1) // CRTCV2 656 togg f0 | |
944 +(0<<2) // CRTCV2 656 togg f0 | |
945 +(0<<4) // CRTCV2 656 togg f1 | |
946 +(0<<5) // CRTCV2 656 togg f1 | |
947 +(0<<6) // CRTCV2 656 togg f1 | |
948 +(0<<8) // Hsync active high | |
949 +(0<<9) // Vsync active high | |
950 // 16-27 c2vlinecomp - nevim co tam dat | |
951 ; | |
952 cregs.c2offset=(regs.bespitch << 1); | |
953 | |
954 cregs.c2pl2startadd0=regs.besa1corg; | |
955 // cregs.c2pl2startadd1=regs.besa2corg; | |
956 cregs.c2pl3startadd0=regs.besa1c3org; | |
957 // cregs.c2pl3startadd1=regs.besa2c3org; | |
958 | |
959 cregs.c2preload=(vsyncstart << 16) | (hsyncstart); // from | |
960 | |
961 cregs.c2spicstartadd0=0; // not used | |
962 // cregs.c2spicstartadd1=0; // not used | |
963 | |
964 cregs.c2startadd0=regs.besa1org; | |
965 // cregs.c2startadd1=regs.besa2org; | |
966 | |
967 cregs.c2subpiclut=0; //not used | |
968 | |
969 cregs.c2vparam=((vdispend - 1) << 16) | (vtotal - 1); | |
970 cregs.c2vsync=((vsyncend - 1) << 16) | (vsyncstart - 1); | |
971 | |
972 | |
973 #endif | |
974 | |
2086 | 975 mga_vid_write_regs(0); |
1 | 976 return 0; |
977 } | |
978 | |
68 | 979 #ifdef MGA_ALLOW_IRQ |
980 | |
48 | 981 static void enable_irq(){ |
982 long int cc; | |
983 | |
984 cc = readl(mga_mmio_base + IEN); | |
63 | 985 // printk(KERN_ALERT "*** !!! IRQREG = %d\n", (int)(cc&0xff)); |
48 | 986 |
987 writeb( 0x11, mga_mmio_base + CRTCX); | |
988 | |
989 writeb(0x20, mga_mmio_base + CRTCD ); /* clear 0, enable off */ | |
990 writeb(0x00, mga_mmio_base + CRTCD ); /* enable on */ | |
991 writeb(0x10, mga_mmio_base + CRTCD ); /* clear = 1 */ | |
992 | |
993 writel( regs.besglobctl , mga_mmio_base + BESGLOBCTL); | |
994 | |
995 } | |
996 | |
997 static void disable_irq(){ | |
998 | |
999 writeb( 0x11, mga_mmio_base + CRTCX); | |
1000 writeb(0x20, mga_mmio_base + CRTCD ); /* clear 0, enable off */ | |
1001 | |
1002 } | |
1003 | |
1004 void mga_handle_irq(int irq, void *dev_id, struct pt_regs *pregs) { | |
1005 // static int frame=0; | |
854
76ca00724e12
gcc warnings fixed - patch by Aelius aelius@wish.net
arpi_esp
parents:
662
diff
changeset
|
1006 // static int counter=0; |
48 | 1007 long int cc; |
1008 // if ( ! mga_enabled_flag ) return; | |
1009 | |
68 | 1010 // printk(KERN_DEBUG "vcount = %d\n",readl(mga_mmio_base + VCOUNT)); |
1011 | |
48 | 1012 //printk("mga_interrupt #%d\n", irq); |
1013 | |
1014 if ( irq != -1 ) { | |
1015 | |
1016 cc = readl(mga_mmio_base + STATUS); | |
1017 if ( ! (cc & 0x10) ) return; /* vsyncpen */ | |
1018 // debug_irqcnt++; | |
1019 } | |
1020 | |
1021 // if ( debug_irqignore ) { | |
1022 // debug_irqignore = 0; | |
1023 | |
1024 | |
1025 /* | |
1026 if ( mga_conf_deinterlace ) { | |
1027 if ( mga_first_field ) { | |
1028 // printk("mga_interrupt first field\n"); | |
1029 if ( syncfb_interrupt() ) | |
1030 mga_first_field = 0; | |
1031 } else { | |
1032 // printk("mga_interrupt second field\n"); | |
1033 mga_select_buffer( mga_current_field | 2 ); | |
1034 mga_first_field = 1; | |
1035 } | |
1036 } else { | |
1037 syncfb_interrupt(); | |
1038 } | |
1039 */ | |
1040 | |
1041 // frame=(frame+1)&1; | |
1042 regs.besctl = (regs.besctl & ~0x07000000) + (mga_next_frame << 25); | |
1043 writel( regs.besctl, mga_mmio_base + BESCTL ); | |
2344 | 1044 |
1045 #ifdef CRTC2 | |
1046 // sem pridat vyber obrazku !!!! | |
1047 crtc2_frame_sel(mga_next_frame); | |
1048 #endif | |
48 | 1049 |
1050 #if 0 | |
1051 ++counter; | |
1052 if(!(counter&63)){ | |
1053 printk("mga irq counter = %d\n",counter); | |
1054 } | |
1055 #endif | |
1056 | |
1057 // } else { | |
1058 // debug_irqignore = 1; | |
1059 // } | |
1060 | |
1061 if ( irq != -1 ) { | |
1062 writeb( 0x11, mga_mmio_base + CRTCX); | |
1063 writeb( 0, mga_mmio_base + CRTCD ); | |
1064 writeb( 0x10, mga_mmio_base + CRTCD ); | |
1065 } | |
1066 | |
1067 // writel( regs.besglobctl, mga_mmio_base + BESGLOBCTL); | |
1068 | |
1069 | |
1070 return; | |
1071 | |
1072 } | |
1073 | |
68 | 1074 #endif |
1 | 1075 |
1076 static int mga_vid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | |
1077 { | |
1078 int frame; | |
1079 | |
1080 switch(cmd) | |
1081 { | |
1082 case MGA_VID_CONFIG: | |
1083 //FIXME remove | |
68 | 1084 // printk(KERN_DEBUG "vcount = %d\n",readl(mga_mmio_base + VCOUNT)); |
61 | 1085 printk(KERN_DEBUG "mga_mmio_base = %p\n",mga_mmio_base); |
854
76ca00724e12
gcc warnings fixed - patch by Aelius aelius@wish.net
arpi_esp
parents:
662
diff
changeset
|
1086 printk(KERN_DEBUG "mga_mem_base = %08x\n",mga_mem_base); |
1 | 1087 //FIXME remove |
1088 | |
61 | 1089 printk(KERN_DEBUG "mga_vid: Received configuration\n"); |
1 | 1090 |
1091 if(copy_from_user(&mga_config,(mga_vid_config_t*) arg,sizeof(mga_vid_config_t))) | |
1092 { | |
61 | 1093 printk(KERN_ERR "mga_vid: failed copy from userspace\n"); |
1 | 1094 return(-EFAULT); |
1095 } | |
57 | 1096 if(mga_config.version != MGA_VID_VERSION){ |
61 | 1097 printk(KERN_ERR "mga_vid: incompatible version! driver: %X requested: %X\n",MGA_VID_VERSION,mga_config.version); |
57 | 1098 return(-EFAULT); |
1099 } | |
1100 | |
1101 if(mga_config.frame_size==0 || mga_config.frame_size>1024*768*2){ | |
61 | 1102 printk(KERN_ERR "mga_vid: illegal frame_size: %d\n",mga_config.frame_size); |
57 | 1103 return(-EFAULT); |
1104 } | |
1105 | |
1106 if(mga_config.num_frames<1 || mga_config.num_frames>4){ | |
61 | 1107 printk(KERN_ERR "mga_vid: illegal num_frames: %d\n",mga_config.num_frames); |
57 | 1108 return(-EFAULT); |
1109 } | |
1110 | |
1111 mga_src_base = (mga_ram_size*0x100000-mga_config.num_frames*mga_config.frame_size); | |
1112 if(mga_src_base<0){ | |
61 | 1113 printk(KERN_ERR "mga_vid: not enough memory for frames!\n"); |
57 | 1114 return(-EFAULT); |
1115 } | |
1116 mga_src_base &= (~0xFFFF); // 64k boundary | |
61 | 1117 printk(KERN_DEBUG "mga YUV buffer base: 0x%X\n", mga_src_base); |
57 | 1118 |
1 | 1119 if (is_g400) |
1120 mga_config.card_type = MGA_G400; | |
1121 else | |
1122 mga_config.card_type = MGA_G200; | |
1123 | |
1124 mga_config.ram_size = mga_ram_size; | |
1125 | |
1126 if (copy_to_user((mga_vid_config_t *) arg, &mga_config, sizeof(mga_vid_config_t))) | |
1127 { | |
61 | 1128 printk(KERN_ERR "mga_vid: failed copy to userspace\n"); |
1 | 1129 return(-EFAULT); |
1130 } | |
1131 return mga_vid_set_config(&mga_config); | |
1132 break; | |
1133 | |
1134 case MGA_VID_ON: | |
61 | 1135 printk(KERN_DEBUG "mga_vid: Video ON\n"); |
1 | 1136 vid_src_ready = 1; |
1137 if(vid_overlay_on) | |
1138 { | |
1139 regs.besctl |= 1; | |
2086 | 1140 mga_vid_write_regs(0); |
1 | 1141 } |
68 | 1142 #ifdef MGA_ALLOW_IRQ |
48 | 1143 if ( mga_irq != -1 ) enable_irq(); |
68 | 1144 #endif |
48 | 1145 mga_next_frame=0; |
1 | 1146 break; |
1147 | |
1148 case MGA_VID_OFF: | |
94
fbd99740af99
printk() message for video off when releasing mga without ioctl()
lgb
parents:
93
diff
changeset
|
1149 printk(KERN_DEBUG "mga_vid: Video OFF (ioctl)\n"); |
1 | 1150 vid_src_ready = 0; |
68 | 1151 #ifdef MGA_ALLOW_IRQ |
48 | 1152 if ( mga_irq != -1 ) disable_irq(); |
68 | 1153 #endif |
1 | 1154 regs.besctl &= ~1; |
466 | 1155 regs.besglobctl &= ~(1<<6); // UYVY format selected |
2086 | 1156 mga_vid_write_regs(0); |
1 | 1157 break; |
1158 | |
1159 case MGA_VID_FSEL: | |
1160 if(copy_from_user(&frame,(int *) arg,sizeof(int))) | |
1161 { | |
61 | 1162 printk(KERN_ERR "mga_vid: FSEL failed copy from userspace\n"); |
1 | 1163 return(-EFAULT); |
1164 } | |
1165 | |
1166 mga_vid_frame_sel(frame); | |
1167 break; | |
1168 | |
1169 default: | |
61 | 1170 printk(KERN_ERR "mga_vid: Invalid ioctl\n"); |
1 | 1171 return (-EINVAL); |
1172 } | |
1173 | |
1174 return 0; | |
1175 } | |
1176 | |
1177 | |
1178 static int mga_vid_find_card(void) | |
1179 { | |
1180 struct pci_dev *dev = NULL; | |
854
76ca00724e12
gcc warnings fixed - patch by Aelius aelius@wish.net
arpi_esp
parents:
662
diff
changeset
|
1181 unsigned int card_option; |
1 | 1182 |
1989 | 1183 if((dev = pci_find_device(PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G550, NULL))) |
1184 { | |
1185 is_g400 = 1; | |
1186 printk(KERN_INFO "mga_vid: Found MGA G550\n"); | |
1187 } | |
1188 else if((dev = pci_find_device(PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400, NULL))) | |
1 | 1189 { |
1190 is_g400 = 1; | |
77 | 1191 printk(KERN_INFO "mga_vid: Found MGA G400/G450\n"); |
1 | 1192 } |
1193 else if((dev = pci_find_device(PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, NULL))) | |
1194 { | |
1195 is_g400 = 0; | |
63 | 1196 printk(KERN_INFO "mga_vid: Found MGA G200 AGP\n"); |
1 | 1197 } |
1198 else if((dev = pci_find_device(PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, NULL))) | |
1199 { | |
1200 is_g400 = 0; | |
63 | 1201 printk(KERN_INFO "mga_vid: Found MGA G200 PCI\n"); |
1 | 1202 } |
1203 else | |
1204 { | |
61 | 1205 printk(KERN_ERR "mga_vid: No supported cards found\n"); |
1 | 1206 return FALSE; |
1207 } | |
1208 | |
1209 pci_dev = dev; | |
48 | 1210 |
1211 mga_irq = pci_dev->irq; | |
1 | 1212 |
1213 #if LINUX_VERSION_CODE >= 0x020300 | |
1214 mga_mmio_base = ioremap_nocache(dev->resource[1].start,0x4000); | |
1215 mga_mem_base = dev->resource[0].start; | |
1216 #else | |
1217 mga_mmio_base = ioremap_nocache(dev->base_address[1] & PCI_BASE_ADDRESS_MEM_MASK,0x4000); | |
1218 mga_mem_base = dev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK; | |
1219 #endif | |
854
76ca00724e12
gcc warnings fixed - patch by Aelius aelius@wish.net
arpi_esp
parents:
662
diff
changeset
|
1220 printk(KERN_INFO "mga_vid: MMIO at 0x%p IRQ: %d framebuffer: 0x%08X\n", mga_mmio_base, mga_irq, mga_mem_base); |
1 | 1221 |
1222 pci_read_config_dword(dev, 0x40, &card_option); | |
77 | 1223 printk(KERN_INFO "mga_vid: OPTION word: 0x%08X mem: 0x%02X %s\n", card_option, |
1224 (card_option>>10)&0x17, ((card_option>>14)&1)?"SGRAM":"SDRAM"); | |
1 | 1225 |
57 | 1226 // temp = (card_option >> 10) & 0x17; |
1227 | |
95 | 1228 if (mga_ram_size) { |
1229 printk(KERN_INFO "mga_vid: RAMSIZE forced to %d MB\n", mga_ram_size); | |
91 | 1230 } else { |
90 | 1231 |
101
7fe6855f19cd
mga_ram_size=x works with hard-coded ramsize too (szabi)
arpi_esp
parents:
95
diff
changeset
|
1232 #ifdef MGA_MEMORY_SIZE |
7fe6855f19cd
mga_ram_size=x works with hard-coded ramsize too (szabi)
arpi_esp
parents:
95
diff
changeset
|
1233 mga_ram_size = MGA_MEMORY_SIZE; |
7fe6855f19cd
mga_ram_size=x works with hard-coded ramsize too (szabi)
arpi_esp
parents:
95
diff
changeset
|
1234 printk(KERN_INFO "mga_vid: hard-coded RAMSIZE is %d MB\n", (unsigned int) mga_ram_size); |
7fe6855f19cd
mga_ram_size=x works with hard-coded ramsize too (szabi)
arpi_esp
parents:
95
diff
changeset
|
1235 |
7fe6855f19cd
mga_ram_size=x works with hard-coded ramsize too (szabi)
arpi_esp
parents:
95
diff
changeset
|
1236 #else |
7fe6855f19cd
mga_ram_size=x works with hard-coded ramsize too (szabi)
arpi_esp
parents:
95
diff
changeset
|
1237 |
95 | 1238 if (is_g400){ |
75 | 1239 switch((card_option>>10)&0x17){ |
1240 // SDRAM: | |
1241 case 0x00: | |
1242 case 0x04: mga_ram_size = 16; break; | |
105 | 1243 case 0x03: mga_ram_size = 32; break; |
75 | 1244 // SGRAM: |
1245 case 0x10: | |
1246 case 0x14: mga_ram_size = 32; break; | |
1247 case 0x11: | |
1248 case 0x12: mga_ram_size = 16; break; | |
1249 default: | |
1250 mga_ram_size = 16; | |
1251 printk(KERN_INFO "mga_vid: Couldn't detect RAMSIZE, assuming 16MB!"); | |
1252 } | |
95 | 1253 }else{ |
662
4a959b73d51e
G200 ramsize detection disabled, using 8M by default
arpi_esp
parents:
470
diff
changeset
|
1254 switch((card_option>>10)&0x17){ |
4a959b73d51e
G200 ramsize detection disabled, using 8M by default
arpi_esp
parents:
470
diff
changeset
|
1255 // case 0x10: |
4a959b73d51e
G200 ramsize detection disabled, using 8M by default
arpi_esp
parents:
470
diff
changeset
|
1256 // case 0x13: mga_ram_size = 8; break; |
4a959b73d51e
G200 ramsize detection disabled, using 8M by default
arpi_esp
parents:
470
diff
changeset
|
1257 default: mga_ram_size = 8; |
64 | 1258 } |
95 | 1259 } |
64 | 1260 #if 0 |
95 | 1261 // printk("List resources -----------\n"); |
1262 for(temp=0;temp<DEVICE_COUNT_RESOURCE;temp++){ | |
1263 struct resource *res=&pci_dev->resource[temp]; | |
1264 if(res->flags){ | |
1265 int size=(1+res->end-res->start)>>20; | |
1266 printk(KERN_DEBUG "res %d: start: 0x%X end: 0x%X (%d MB) flags=0x%X\n",temp,res->start,res->end,size,res->flags); | |
1267 if(res->flags&(IORESOURCE_MEM|IORESOURCE_PREFETCH)){ | |
1268 if(size>mga_ram_size && size<=64) mga_ram_size=size; | |
1269 } | |
1270 } | |
57 | 1271 } |
64 | 1272 #endif |
95 | 1273 printk(KERN_INFO "mga_vid: detected RAMSIZE is %d MB\n", (unsigned int) mga_ram_size); |
101
7fe6855f19cd
mga_ram_size=x works with hard-coded ramsize too (szabi)
arpi_esp
parents:
95
diff
changeset
|
1274 #endif |
95 | 1275 } |
57 | 1276 |
48 | 1277 |
68 | 1278 #ifdef MGA_ALLOW_IRQ |
48 | 1279 if ( mga_irq != -1 ) { |
1280 int tmp = request_irq(mga_irq, mga_handle_irq, SA_INTERRUPT | SA_SHIRQ, "Syncfb Time Base", &mga_irq); | |
1281 if ( tmp ) { | |
61 | 1282 printk(KERN_INFO "syncfb (mga): cannot register irq %d (Err: %d)\n", mga_irq, tmp); |
48 | 1283 mga_irq=-1; |
1284 } else { | |
61 | 1285 printk(KERN_DEBUG "syncfb (mga): registered irq %d\n", mga_irq); |
48 | 1286 } |
1287 } else { | |
61 | 1288 printk(KERN_INFO "syncfb (mga): No valid irq was found\n"); |
48 | 1289 mga_irq=-1; |
1290 } | |
68 | 1291 #else |
1292 printk(KERN_INFO "syncfb (mga): IRQ disabled in mga_vid.c\n"); | |
1293 mga_irq=-1; | |
1294 #endif | |
48 | 1295 |
1 | 1296 return TRUE; |
1297 } | |
1298 | |
1299 | |
1300 static ssize_t mga_vid_read(struct file *file, char *buf, size_t count, loff_t *ppos) | |
1301 { | |
1302 return -EINVAL; | |
1303 } | |
1304 | |
1305 static ssize_t mga_vid_write(struct file *file, const char *buf, size_t count, loff_t *ppos) | |
1306 { | |
1307 return -EINVAL; | |
1308 } | |
1309 | |
1310 static int mga_vid_mmap(struct file *file, struct vm_area_struct *vma) | |
1311 { | |
1312 | |
61 | 1313 printk(KERN_DEBUG "mga_vid: mapping video memory into userspace\n"); |
57 | 1314 if(remap_page_range(vma->vm_start, mga_mem_base + mga_src_base, |
1 | 1315 vma->vm_end - vma->vm_start, vma->vm_page_prot)) |
1316 { | |
63 | 1317 printk(KERN_ERR "mga_vid: error mapping video memory\n"); |
1 | 1318 return(-EAGAIN); |
1319 } | |
1320 | |
1321 return(0); | |
1322 } | |
1323 | |
1324 static int mga_vid_release(struct inode *inode, struct file *file) | |
1325 { | |
1326 //Close the window just in case | |
94
fbd99740af99
printk() message for video off when releasing mga without ioctl()
lgb
parents:
93
diff
changeset
|
1327 printk(KERN_DEBUG "mga_vid: Video OFF (release)\n"); |
fbd99740af99
printk() message for video off when releasing mga without ioctl()
lgb
parents:
93
diff
changeset
|
1328 |
1 | 1329 vid_src_ready = 0; |
1330 regs.besctl &= ~1; | |
466 | 1331 regs.besglobctl &= ~(1<<6); // UYVY format selected |
2086 | 1332 // mga_config.colkey_on=0; //!!! |
1333 mga_vid_write_regs(1); | |
1 | 1334 mga_vid_in_use = 0; |
1335 | |
93 | 1336 MOD_DEC_USE_COUNT; |
1 | 1337 return 0; |
1338 } | |
1339 | |
1340 static long long mga_vid_lseek(struct file *file, long long offset, int origin) | |
1341 { | |
1342 return -ESPIPE; | |
1343 } | |
1344 | |
1345 static int mga_vid_open(struct inode *inode, struct file *file) | |
1346 { | |
1347 int minor = MINOR(inode->i_rdev); | |
1348 | |
1349 if(minor != 0) | |
1350 return(-ENXIO); | |
1351 | |
1352 if(mga_vid_in_use == 1) | |
1353 return(-EBUSY); | |
1354 | |
1355 mga_vid_in_use = 1; | |
93 | 1356 MOD_INC_USE_COUNT; |
1 | 1357 return(0); |
1358 } | |
1359 | |
1360 #if LINUX_VERSION_CODE >= 0x020400 | |
1361 static struct file_operations mga_vid_fops = | |
1362 { | |
1363 llseek: mga_vid_lseek, | |
1364 read: mga_vid_read, | |
1365 write: mga_vid_write, | |
1366 ioctl: mga_vid_ioctl, | |
1367 mmap: mga_vid_mmap, | |
1368 open: mga_vid_open, | |
1369 release: mga_vid_release | |
1370 }; | |
1371 #else | |
1372 static struct file_operations mga_vid_fops = | |
1373 { | |
1374 mga_vid_lseek, | |
1375 mga_vid_read, | |
1376 mga_vid_write, | |
1377 NULL, | |
1378 NULL, | |
1379 mga_vid_ioctl, | |
1380 mga_vid_mmap, | |
1381 mga_vid_open, | |
1382 NULL, | |
1383 mga_vid_release | |
1384 }; | |
1385 #endif | |
1386 | |
1387 | |
1388 /* | |
1389 * Main Initialization Function | |
1390 */ | |
1391 | |
1392 static int mga_vid_initialize(void) | |
1393 { | |
1394 mga_vid_in_use = 0; | |
1395 | |
77 | 1396 // printk(KERN_INFO "Matrox MGA G200/G400 YUV Video interface v0.01 (c) Aaron Holtzman \n"); |
1397 printk(KERN_INFO "Matrox MGA G200/G400/G450 YUV Video interface v2.01 (c) Aaron Holtzman & A'rpi\n"); | |
90 | 1398 |
95 | 1399 if (mga_ram_size) { |
1400 if (mga_ram_size<4 || mga_ram_size>64) { | |
1401 printk(KERN_ERR "mga_vid: invalid RAMSIZE: %d MB\n", mga_ram_size); | |
90 | 1402 return -EINVAL; |
1403 } | |
1404 } | |
1405 | |
1 | 1406 if(register_chrdev(MGA_VID_MAJOR, "mga_vid", &mga_vid_fops)) |
1407 { | |
61 | 1408 printk(KERN_ERR "mga_vid: unable to get major: %d\n", MGA_VID_MAJOR); |
1 | 1409 return -EIO; |
1410 } | |
1411 | |
1412 if (!mga_vid_find_card()) | |
1413 { | |
61 | 1414 printk(KERN_ERR "mga_vid: no supported devices found\n"); |
1 | 1415 unregister_chrdev(MGA_VID_MAJOR, "mga_vid"); |
1416 return -EINVAL; | |
1417 } | |
1418 | |
1419 return(0); | |
1420 } | |
1421 | |
1422 int init_module(void) | |
1423 { | |
1424 return mga_vid_initialize(); | |
1425 } | |
1426 | |
1427 void cleanup_module(void) | |
1428 { | |
48 | 1429 |
68 | 1430 #ifdef MGA_ALLOW_IRQ |
48 | 1431 if ( mga_irq != -1) |
1432 free_irq(mga_irq, &mga_irq); | |
68 | 1433 #endif |
48 | 1434 |
1 | 1435 if(mga_mmio_base) |
1436 iounmap(mga_mmio_base); | |
1437 | |
1438 //FIXME turn off BES | |
63 | 1439 printk(KERN_INFO "mga_vid: Cleaning up module\n"); |
1 | 1440 unregister_chrdev(MGA_VID_MAJOR, "mga_vid"); |
1441 } | |
1442 |