Mercurial > mplayer.hg
annotate vidix/mach64_vid.c @ 33259:04dc3e55cd90
Increase the maximum value of the DVB timeout to 240 seconds.
Some devices may need more time for the initial tune (e.g. firmware loading).
Let the user specify higher timeout value if there is need to.
The default remains 30 seconds.
author | iive |
---|---|
date | Sun, 01 May 2011 18:07:59 +0000 |
parents | 0f1b5b68af32 |
children | d4af28753ec8 |
rev | line source |
---|---|
22850 | 1 /* |
23046
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
2 * VIDIX driver for ATI Mach64 and 3DRage chipsets. |
26718
051b2632f121
consistency cosmetics: Move some parts of file headers around; typo fixes.
diego
parents:
25859
diff
changeset
|
3 * |
23046
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
4 * Copyright (C) 2002 Nick Kurshev |
26718
051b2632f121
consistency cosmetics: Move some parts of file headers around; typo fixes.
diego
parents:
25859
diff
changeset
|
5 * This file is based on sources from |
051b2632f121
consistency cosmetics: Move some parts of file headers around; typo fixes.
diego
parents:
25859
diff
changeset
|
6 * GATOS (gatos.sf.net) and X11 (www.xfree86.org) |
23046
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
7 * |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
8 * This file is part of MPlayer. |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
9 * |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
10 * MPlayer is free software; you can redistribute it and/or modify |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
11 * it under the terms of the GNU General Public License as published by |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
12 * the Free Software Foundation; either version 2 of the License, or |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
13 * (at your option) any later version. |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
14 * |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
15 * MPlayer is distributed in the hope that it will be useful, |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
18 * GNU General Public License for more details. |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
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. | |
23046
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
23 */ |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
24 |
22850 | 25 #include <errno.h> |
26 #include <stdio.h> | |
27 #include <stdlib.h> | |
28 #include <string.h> | |
29 #include <math.h> | |
30 #include <inttypes.h> | |
31 #include <fcntl.h> | |
32 | |
22905 | 33 #include "config.h" |
34 #include "libavutil/common.h" | |
35 #include "mpbswap.h" | |
22850 | 36 #include "vidix.h" |
37 #include "fourcc.h" | |
22901 | 38 #include "dha.h" |
22900
a9e111b88c4a
merged libdha and libvidix, moved all files from libdha to vidix directory
ben
parents:
22858
diff
changeset
|
39 #include "pci_ids.h" |
a9e111b88c4a
merged libdha and libvidix, moved all files from libdha to vidix directory
ben
parents:
22858
diff
changeset
|
40 #include "pci_names.h" |
22850 | 41 |
42 #include "mach64.h" | |
43 | |
44 #define UNUSED(x) ((void)(x)) /**< Removes warning about unused arguments */ | |
45 | |
46 static void *mach64_mmio_base = 0; | |
47 static void *mach64_mem_base = 0; | |
48 static int32_t mach64_overlay_offset = 0; | |
49 static uint32_t mach64_ram_size = 0; | |
50 static uint32_t mach64_buffer_base[10][3]; | |
51 static int num_mach64_buffers=-1; | |
52 static int supports_planar=0; | |
53 static int supports_lcd_v_stretch=0; | |
54 | |
23053 | 55 static pciinfo_t pci_info; |
22850 | 56 static int probed = 0; |
25859
e8af7338a462
Fix illegal identifiers, names starting with __ are reserved for the system.
diego
parents:
24126
diff
changeset
|
57 static int verbosity = 0; |
22850 | 58 |
59 #define VERBOSE_LEVEL 1 | |
60 | |
61 typedef struct bes_registers_s | |
62 { | |
63 /* base address of yuv framebuffer */ | |
64 uint32_t yuv_base; | |
65 uint32_t fourcc; | |
66 /* YUV BES registers */ | |
67 uint32_t reg_load_cntl; | |
68 uint32_t scale_inc; | |
69 uint32_t y_x_start; | |
70 uint32_t y_x_end; | |
71 uint32_t vid_buf_pitch; | |
72 uint32_t height_width; | |
73 | |
74 uint32_t scale_cntl; | |
75 uint32_t exclusive_horz; | |
76 uint32_t auto_flip_cntl; | |
77 uint32_t filter_cntl; | |
78 uint32_t key_cntl; | |
79 uint32_t test; | |
80 /* Configurable stuff */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
81 |
22850 | 82 int brightness; |
83 int saturation; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
84 |
22850 | 85 int ckey_on; |
86 uint32_t graphics_key_clr; | |
87 uint32_t graphics_key_msk; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
88 |
22850 | 89 int deinterlace_on; |
90 uint32_t deinterlace_pattern; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
91 |
22850 | 92 } bes_registers_t; |
93 | |
94 static bes_registers_t besr; | |
95 | |
96 typedef struct video_registers_s | |
97 { | |
98 const char * sname; | |
99 uint32_t name; | |
100 uint32_t value; | |
101 }video_registers_t; | |
102 | |
103 /* Graphic keys */ | |
104 static vidix_grkey_t mach64_grkey; | |
105 | |
106 #define DECLARE_VREG(name) { #name, name, 0 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
107 static video_registers_t vregs[] = |
22850 | 108 { |
109 DECLARE_VREG(OVERLAY_SCALE_INC), | |
110 DECLARE_VREG(OVERLAY_Y_X_START), | |
111 DECLARE_VREG(OVERLAY_Y_X_END), | |
112 DECLARE_VREG(OVERLAY_SCALE_CNTL), | |
113 DECLARE_VREG(OVERLAY_EXCLUSIVE_HORZ), | |
114 DECLARE_VREG(OVERLAY_EXCLUSIVE_VERT), | |
115 DECLARE_VREG(OVERLAY_TEST), | |
116 DECLARE_VREG(SCALER_BUF_PITCH), | |
117 DECLARE_VREG(SCALER_HEIGHT_WIDTH), | |
118 DECLARE_VREG(SCALER_BUF0_OFFSET), | |
119 DECLARE_VREG(SCALER_BUF0_OFFSET_U), | |
120 DECLARE_VREG(SCALER_BUF0_OFFSET_V), | |
121 DECLARE_VREG(SCALER_BUF1_OFFSET), | |
122 DECLARE_VREG(SCALER_BUF1_OFFSET_U), | |
123 DECLARE_VREG(SCALER_BUF1_OFFSET_V), | |
124 DECLARE_VREG(SCALER_H_COEFF0), | |
125 DECLARE_VREG(SCALER_H_COEFF1), | |
126 DECLARE_VREG(SCALER_H_COEFF2), | |
127 DECLARE_VREG(SCALER_H_COEFF3), | |
128 DECLARE_VREG(SCALER_H_COEFF4), | |
129 DECLARE_VREG(SCALER_COLOUR_CNTL), | |
130 DECLARE_VREG(SCALER_THRESHOLD), | |
131 DECLARE_VREG(VIDEO_FORMAT), | |
132 DECLARE_VREG(VIDEO_CONFIG), | |
133 DECLARE_VREG(VIDEO_SYNC_TEST), | |
134 DECLARE_VREG(VIDEO_SYNC_TEST_B) | |
135 }; | |
136 | |
137 /* have to restore it on exit */ | |
138 static uint32_t SAVED_OVERLAY_GRAPHICS_KEY_CLR; | |
139 | |
140 /* VIDIX exports */ | |
141 | |
142 /* MMIO space*/ | |
143 #define GETREG(TYPE,PTR,OFFZ) (*((volatile TYPE*)((PTR)+(OFFZ)))) | |
144 #define SETREG(TYPE,PTR,OFFZ,VAL) (*((volatile TYPE*)((PTR)+(OFFZ))))=VAL | |
145 | |
146 #define INREG8(addr) GETREG(uint8_t,(uint8_t *)mach64_mmio_base,((addr)^0x100)<<2) | |
147 #define OUTREG8(addr,val) SETREG(uint8_t,(uint8_t *)mach64_mmio_base,((addr)^0x100)<<2,val) | |
148 | |
149 static inline uint32_t INREG (uint32_t addr) { | |
150 uint32_t tmp = GETREG(uint32_t,(uint8_t *)mach64_mmio_base,((addr)^0x100)<<2); | |
151 return le2me_32(tmp); | |
152 } | |
153 #define OUTREG(addr,val) SETREG(uint32_t,(uint8_t *)mach64_mmio_base,((addr)^0x100)<<2,le2me_32(val)) | |
154 | |
155 #define OUTREGP(addr,val,mask) \ | |
156 do { \ | |
157 unsigned int _tmp = INREG(addr); \ | |
158 _tmp &= (mask); \ | |
159 _tmp |= (val); \ | |
160 OUTREG(addr, _tmp); \ | |
161 } while (0) | |
162 | |
163 static __inline__ int ATIGetMach64LCDReg(int _Index) | |
164 { | |
165 OUTREG8(LCD_INDEX, _Index); | |
166 return INREG(LCD_DATA); | |
167 } | |
168 | |
169 static __inline__ uint32_t INPLL(uint32_t addr) | |
170 { | |
171 uint32_t res; | |
172 uint32_t in; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
173 |
22850 | 174 in= INREG(CLOCK_CNTL); |
175 in &= ~((PLL_WR_EN | PLL_ADDR)); //clean some stuff | |
176 OUTREG(CLOCK_CNTL, in | (addr<<10)); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
177 |
22850 | 178 /* read the register value */ |
179 res = (INREG(CLOCK_CNTL)>>16)&0xFF; | |
180 return res; | |
181 } | |
182 | |
183 static __inline__ void OUTPLL(uint32_t addr,uint32_t val) | |
184 { | |
185 //FIXME buggy but its not used | |
186 /* write addr byte */ | |
187 OUTREG8(CLOCK_CNTL + 1, (addr << 2) | PLL_WR_EN); | |
188 /* write the register value */ | |
189 OUTREG(CLOCK_CNTL + 2, val); | |
190 OUTREG8(CLOCK_CNTL + 1, (addr << 2) & ~PLL_WR_EN); | |
191 } | |
192 | |
193 #define OUTPLLP(addr,val,mask) \ | |
194 do { \ | |
195 unsigned int _tmp = INPLL(addr); \ | |
196 _tmp &= (mask); \ | |
197 _tmp |= (val); \ | |
198 OUTPLL(addr, _tmp); \ | |
199 } while (0) | |
200 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
201 static void mach64_fifo_wait(unsigned n) |
22850 | 202 { |
203 while ((INREG(FIFO_STAT) & 0xffff) > ((uint32_t)(0x8000 >> n))); | |
204 } | |
205 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
206 static void mach64_wait_for_idle( void ) |
22850 | 207 { |
208 mach64_fifo_wait(16); | |
209 while ((INREG(GUI_STAT) & 1)!= 0); | |
210 } | |
211 | |
212 static void mach64_wait_vsync( void ) | |
213 { | |
214 int i; | |
215 | |
216 for(i=0; i<2000000; i++) | |
217 if( (INREG(CRTC_INT_CNTL)&CRTC_VBLANK)==0 ) break; | |
218 for(i=0; i<2000000; i++) | |
219 if( (INREG(CRTC_INT_CNTL)&CRTC_VBLANK) ) break; | |
220 | |
221 } | |
222 | |
223 static vidix_capability_t mach64_cap = | |
224 { | |
225 "BES driver for Mach64/3DRage cards", | |
226 "Nick Kurshev and Michael Niedermayer", | |
227 TYPE_OUTPUT, | |
228 { 0, 0, 0, 0 }, | |
229 2048, | |
230 2048, | |
231 4, | |
232 4, | |
233 -1, | |
234 FLAG_UPSCALER|FLAG_DOWNSCALER, | |
235 VENDOR_ATI, | |
236 -1, | |
237 { 0, 0, 0, 0 } | |
238 }; | |
239 | |
240 static uint32_t mach64_vid_get_dbpp( void ) | |
241 { | |
242 uint32_t dbpp,retval; | |
243 dbpp = (INREG(CRTC_GEN_CNTL)>>8)& 0x7; | |
244 switch(dbpp) | |
245 { | |
246 case 1: retval = 4; break; | |
247 case 2: retval = 8; break; | |
248 case 3: retval = 15; break; | |
249 case 4: retval = 16; break; | |
250 case 5: retval = 24; break; | |
251 default: retval=32; break; | |
252 } | |
253 return retval; | |
254 } | |
255 | |
256 static int mach64_is_dbl_scan( void ) | |
257 { | |
258 return INREG(CRTC_GEN_CNTL) & CRTC_DBL_SCAN_EN; | |
259 } | |
260 | |
261 static int mach64_is_interlace( void ) | |
262 { | |
263 return INREG(CRTC_GEN_CNTL) & CRTC_INTERLACE_EN; | |
264 } | |
265 | |
266 static uint32_t mach64_get_xres( void ) | |
267 { | |
268 /* FIXME: currently we extract that from CRTC!!!*/ | |
269 uint32_t xres,h_total; | |
270 h_total = INREG(CRTC_H_TOTAL_DISP); | |
271 xres = (h_total >> 16) & 0xffff; | |
272 return (xres + 1)*8; | |
273 } | |
274 | |
275 static uint32_t mach64_get_yres( void ) | |
276 { | |
277 /* FIXME: currently we extract that from CRTC!!!*/ | |
278 uint32_t yres,v_total; | |
279 v_total = INREG(CRTC_V_TOTAL_DISP); | |
280 yres = (v_total >> 16) & 0xffff; | |
281 return yres + 1; | |
282 } | |
283 | |
284 // returns the verical stretch factor in 16.16 | |
285 static int mach64_get_vert_stretch(void) | |
286 { | |
287 int lcd_index; | |
288 int vert_stretching; | |
289 int ext_vert_stretch; | |
290 int ret; | |
291 int yres= mach64_get_yres(); | |
292 | |
293 if(!supports_lcd_v_stretch){ | |
25859
e8af7338a462
Fix illegal identifiers, names starting with __ are reserved for the system.
diego
parents:
24126
diff
changeset
|
294 if(verbosity > 0) printf("[mach64] vertical stretching not supported\n"); |
22850 | 295 return 1<<16; |
296 } | |
297 | |
298 lcd_index= INREG(LCD_INDEX); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
299 |
22850 | 300 vert_stretching= ATIGetMach64LCDReg(LCD_VERT_STRETCHING); |
301 if(!(vert_stretching&VERT_STRETCH_EN)) ret= 1<<16; | |
302 else | |
303 { | |
304 int panel_size; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
305 |
22850 | 306 ext_vert_stretch= ATIGetMach64LCDReg(LCD_EXT_VERT_STRETCH); |
307 panel_size= (ext_vert_stretch&VERT_PANEL_SIZE)>>11; | |
308 panel_size++; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
309 |
22850 | 310 ret= ((yres<<16) + (panel_size>>1))/panel_size; |
311 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
312 |
22850 | 313 // lcd_gen_ctrl = ATIGetMach64LCDReg(LCD_GEN_CNTL); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
314 |
22850 | 315 OUTREG(LCD_INDEX, lcd_index); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
316 |
25859
e8af7338a462
Fix illegal identifiers, names starting with __ are reserved for the system.
diego
parents:
24126
diff
changeset
|
317 if(verbosity > 0) printf("[mach64] vertical stretching factor= %d\n", ret); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
318 |
22850 | 319 return ret; |
320 } | |
321 | |
322 static void mach64_vid_make_default(void) | |
323 { | |
324 mach64_fifo_wait(5); | |
325 OUTREG(SCALER_COLOUR_CNTL,0x00101000); | |
326 | |
327 besr.ckey_on=0; | |
328 besr.graphics_key_msk=0; | |
329 besr.graphics_key_clr=0; | |
330 | |
331 OUTREG(OVERLAY_GRAPHICS_KEY_MSK, besr.graphics_key_msk); | |
332 OUTREG(OVERLAY_GRAPHICS_KEY_CLR, besr.graphics_key_clr); | |
333 OUTREG(OVERLAY_KEY_CNTL,VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_EQ|CMP_MIX_AND); | |
334 | |
335 } | |
336 | |
337 static void mach64_vid_dump_regs( void ) | |
338 { | |
339 size_t i; | |
340 printf("[mach64] *** Begin of DRIVER variables dump ***\n"); | |
341 printf("[mach64] mach64_mmio_base=%p\n",mach64_mmio_base); | |
342 printf("[mach64] mach64_mem_base=%p\n",mach64_mem_base); | |
343 printf("[mach64] mach64_overlay_off=%08X\n",mach64_overlay_offset); | |
344 printf("[mach64] mach64_ram_size=%08X\n",mach64_ram_size); | |
345 printf("[mach64] video mode: %ux%u@%u\n",mach64_get_xres(),mach64_get_yres(),mach64_vid_get_dbpp()); | |
346 printf("[mach64] *** Begin of OV0 registers dump ***\n"); | |
347 for(i=0;i<sizeof(vregs)/sizeof(video_registers_t);i++) | |
348 { | |
349 mach64_wait_for_idle(); | |
350 printf("[mach64] %s = %08X\n",vregs[i].sname,INREG(vregs[i].name)); | |
351 } | |
352 printf("[mach64] *** End of OV0 registers dump ***\n"); | |
353 } | |
354 | |
355 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
356 static unsigned short ati_card_ids[] = |
22850 | 357 { |
358 DEVICE_ATI_215CT_MACH64_CT, | |
359 DEVICE_ATI_210888CX_MACH64_CX, | |
360 DEVICE_ATI_210888ET_MACH64_ET, | |
361 DEVICE_ATI_MACH64_VT, | |
362 DEVICE_ATI_210888GX_MACH64_GX, | |
363 DEVICE_ATI_264LT_MACH64_LT, | |
364 DEVICE_ATI_264VT_MACH64_VT, | |
365 DEVICE_ATI_264VT3_MACH64_VT3, | |
366 DEVICE_ATI_264VT4_MACH64_VT4, | |
367 /**/ | |
368 DEVICE_ATI_3D_RAGE_PRO, | |
369 DEVICE_ATI_3D_RAGE_PRO2, | |
370 DEVICE_ATI_3D_RAGE_PRO3, | |
371 DEVICE_ATI_3D_RAGE_PRO4, | |
372 DEVICE_ATI_RAGE_XC, | |
373 DEVICE_ATI_RAGE_XL_AGP, | |
374 DEVICE_ATI_RAGE_XC_AGP, | |
375 DEVICE_ATI_RAGE_XL, | |
376 DEVICE_ATI_3D_RAGE_PRO5, | |
377 DEVICE_ATI_3D_RAGE_PRO6, | |
378 DEVICE_ATI_RAGE_XL2, | |
379 DEVICE_ATI_RAGE_XC2, | |
380 DEVICE_ATI_3D_RAGE_I_II, | |
381 DEVICE_ATI_3D_RAGE_II, | |
382 DEVICE_ATI_3D_RAGE_IIC, | |
383 DEVICE_ATI_3D_RAGE_IIC2, | |
384 DEVICE_ATI_3D_RAGE_IIC3, | |
385 DEVICE_ATI_3D_RAGE_IIC4, | |
386 DEVICE_ATI_3D_RAGE_LT, | |
387 DEVICE_ATI_3D_RAGE_LT2, | |
388 DEVICE_ATI_3D_RAGE_LT_G, | |
389 DEVICE_ATI_3D_RAGE_LT3, | |
390 DEVICE_ATI_RAGE_MOBILITY_P_M, | |
391 DEVICE_ATI_RAGE_MOBILITY_L, | |
392 DEVICE_ATI_3D_RAGE_LT4, | |
393 DEVICE_ATI_3D_RAGE_LT5, | |
394 DEVICE_ATI_RAGE_MOBILITY_P_M2, | |
395 DEVICE_ATI_RAGE_MOBILITY_L2 | |
396 }; | |
397 | |
398 static int find_chip(unsigned chip_id) | |
399 { | |
400 unsigned i; | |
401 for(i = 0;i < sizeof(ati_card_ids)/sizeof(unsigned short);i++) | |
402 { | |
403 if(chip_id == ati_card_ids[i]) return i; | |
404 } | |
405 return -1; | |
406 } | |
407 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
408 static int mach64_probe(int verbose,int force) |
22850 | 409 { |
410 pciinfo_t lst[MAX_PCI_DEVICES]; | |
411 unsigned i,num_pci; | |
412 int err; | |
25859
e8af7338a462
Fix illegal identifiers, names starting with __ are reserved for the system.
diego
parents:
24126
diff
changeset
|
413 verbosity = verbose; |
22850 | 414 err = pci_scan(lst,&num_pci); |
415 if(err) | |
416 { | |
417 printf("[mach64] Error occurred during pci scan: %s\n",strerror(err)); | |
418 return err; | |
419 } | |
420 else | |
421 { | |
422 err = ENXIO; | |
423 for(i=0;i<num_pci;i++) | |
424 { | |
425 if(lst[i].vendor == VENDOR_ATI) | |
426 { | |
427 int idx; | |
428 const char *dname; | |
429 idx = find_chip(lst[i].device); | |
430 if(idx == -1 && force == PROBE_NORMAL) continue; | |
431 dname = pci_device_name(VENDOR_ATI,lst[i].device); | |
432 dname = dname ? dname : "Unknown chip"; | |
433 printf("[mach64] Found chip: %s\n",dname); | |
23167
2ab3eac7f6da
synced with upstream vidix, prevented some drivers to work on some configs/archs
ben
parents:
23060
diff
changeset
|
434 #if 0 |
22850 | 435 if ((lst[i].command & PCI_COMMAND_IO) == 0) |
436 { | |
437 printf("[mach64] Device is disabled, ignoring\n"); | |
438 continue; | |
439 } | |
23167
2ab3eac7f6da
synced with upstream vidix, prevented some drivers to work on some configs/archs
ben
parents:
23060
diff
changeset
|
440 #endif |
22850 | 441 if(force > PROBE_NORMAL) |
442 { | |
443 printf("[mach64] Driver was forced. Was found %sknown chip\n",idx == -1 ? "un" : ""); | |
444 if(idx == -1) | |
445 printf("[mach64] Assuming it as Mach64\n"); | |
446 } | |
447 mach64_cap.device_id = lst[i].device; | |
448 err = 0; | |
449 memcpy(&pci_info,&lst[i],sizeof(pciinfo_t)); | |
450 probed=1; | |
451 break; | |
452 } | |
453 } | |
454 } | |
455 if(err && verbose) printf("[mach64] Can't find chip\n"); | |
456 return err; | |
457 } | |
458 | |
459 static void reset_regs( void ) | |
460 { | |
461 size_t i; | |
462 for(i=0;i<sizeof(vregs)/sizeof(video_registers_t);i++) | |
463 { | |
464 mach64_fifo_wait(2); | |
465 OUTREG(vregs[i].name,0); | |
466 } | |
467 } | |
468 | |
469 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
470 static int mach64_init(void) |
22850 | 471 { |
472 int err; | |
473 if(!probed) | |
474 { | |
475 printf("[mach64] Driver was not probed but is being initializing\n"); | |
476 return EINTR; | |
477 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
478 |
22850 | 479 if((mach64_mmio_base = map_phys_mem(pci_info.base2,0x1000))==(void *)-1) return ENOMEM; |
480 mach64_wait_for_idle(); | |
481 mach64_ram_size = INREG(MEM_CNTL) & CTL_MEM_SIZEB; | |
482 if (mach64_ram_size < 8) mach64_ram_size = (mach64_ram_size + 1) * 512; | |
483 else if (mach64_ram_size < 12) mach64_ram_size = (mach64_ram_size - 3) * 1024; | |
484 else mach64_ram_size = (mach64_ram_size - 7) * 2048; | |
485 mach64_ram_size *= 0x400; /* KB -> bytes */ | |
486 if((mach64_mem_base = map_phys_mem(pci_info.base0,mach64_ram_size))==(void *)-1) return ENOMEM; | |
487 memset(&besr,0,sizeof(bes_registers_t)); | |
488 printf("[mach64] Video memory = %uMb\n",mach64_ram_size/0x100000); | |
489 err = mtrr_set_type(pci_info.base0,mach64_ram_size,MTRR_TYPE_WRCOMB); | |
490 if(!err) printf("[mach64] Set write-combining type of video memory\n"); | |
491 | |
492 /* save this */ | |
493 mach64_wait_for_idle(); | |
494 SAVED_OVERLAY_GRAPHICS_KEY_CLR = INREG(OVERLAY_GRAPHICS_KEY_CLR); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
495 |
22850 | 496 /* check if planar formats are supported */ |
497 supports_planar=0; | |
498 mach64_wait_for_idle(); | |
499 mach64_fifo_wait(2); | |
500 if(INREG(SCALER_BUF0_OFFSET_U)) supports_planar=1; | |
501 else | |
502 { | |
503 OUTREG(SCALER_BUF0_OFFSET_U, -1); | |
504 | |
505 mach64_wait_vsync(); | |
506 mach64_wait_for_idle(); | |
507 mach64_fifo_wait(2); | |
508 | |
509 if(INREG(SCALER_BUF0_OFFSET_U)) supports_planar=1; | |
510 } | |
511 if(supports_planar) printf("[mach64] Planar YUV formats are supported :)\n"); | |
512 else printf("[mach64] Planar YUV formats are not supported :(\n"); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
513 |
22850 | 514 if( mach64_cap.device_id==DEVICE_ATI_RAGE_MOBILITY_P_M |
515 || mach64_cap.device_id==DEVICE_ATI_RAGE_MOBILITY_P_M2 | |
516 || mach64_cap.device_id==DEVICE_ATI_RAGE_MOBILITY_L | |
517 || mach64_cap.device_id==DEVICE_ATI_RAGE_MOBILITY_L2) | |
518 supports_lcd_v_stretch=1; | |
519 else | |
520 supports_lcd_v_stretch=0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
521 |
22850 | 522 reset_regs(); |
523 mach64_vid_make_default(); | |
524 | |
25859
e8af7338a462
Fix illegal identifiers, names starting with __ are reserved for the system.
diego
parents:
24126
diff
changeset
|
525 if(verbosity > VERBOSE_LEVEL) mach64_vid_dump_regs(); |
22850 | 526 return 0; |
527 } | |
528 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
529 static void mach64_destroy(void) |
22850 | 530 { |
531 /*restore this*/ | |
532 mach64_wait_for_idle(); | |
533 OUTREG(OVERLAY_GRAPHICS_KEY_CLR,SAVED_OVERLAY_GRAPHICS_KEY_CLR); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
534 |
22850 | 535 unmap_phys_mem(mach64_mem_base,mach64_ram_size); |
536 unmap_phys_mem(mach64_mmio_base,0x1000); | |
537 } | |
538 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
539 static int mach64_get_caps(vidix_capability_t *to) |
22850 | 540 { |
541 memcpy(to, &mach64_cap, sizeof(vidix_capability_t)); | |
542 return 0; | |
543 } | |
544 | |
545 static unsigned mach64_query_pitch(unsigned fourcc,const vidix_yuv_t *spitch) | |
546 { | |
547 unsigned pitch,spy,spv,spu; | |
548 spy = spv = spu = 0; | |
549 switch(spitch->y) | |
550 { | |
551 case 16: | |
552 case 32: | |
553 case 64: | |
554 case 128: | |
555 case 256: spy = spitch->y; break; | |
556 default: break; | |
557 } | |
558 switch(spitch->u) | |
559 { | |
560 case 16: | |
561 case 32: | |
562 case 64: | |
563 case 128: | |
564 case 256: spu = spitch->u; break; | |
565 default: break; | |
566 } | |
567 switch(spitch->v) | |
568 { | |
569 case 16: | |
570 case 32: | |
571 case 64: | |
572 case 128: | |
573 case 256: spv = spitch->v; break; | |
574 default: break; | |
575 } | |
576 switch(fourcc) | |
577 { | |
578 /* 4:2:0 */ | |
579 case IMGFMT_IYUV: | |
580 case IMGFMT_YV12: | |
581 case IMGFMT_I420: | |
582 if(spy > 16 && spu == spy/2 && spv == spy/2) pitch = spy; | |
583 else pitch = 32; | |
584 break; | |
585 case IMGFMT_YVU9: | |
586 if(spy > 32 && spu == spy/4 && spv == spy/4) pitch = spy; | |
587 else pitch = 64; | |
588 break; | |
589 default: | |
590 if(spy >= 16) pitch = spy; | |
591 else pitch = 16; | |
592 break; | |
593 } | |
594 return pitch; | |
595 } | |
596 | |
597 static void mach64_compute_framesize(vidix_playback_t *info) | |
598 { | |
599 unsigned pitch,awidth; | |
600 pitch = mach64_query_pitch(info->fourcc,&info->src.pitch); | |
601 switch(info->fourcc) | |
602 { | |
603 case IMGFMT_I420: | |
604 case IMGFMT_YV12: | |
605 case IMGFMT_IYUV: | |
606 awidth = (info->src.w + (pitch-1)) & ~(pitch-1); | |
607 info->frame_size = awidth*(info->src.h+info->src.h/2); | |
608 break; | |
609 case IMGFMT_YVU9: | |
610 awidth = (info->src.w + (pitch-1)) & ~(pitch-1); | |
611 info->frame_size = awidth*(info->src.h+info->src.h/8); | |
612 break; | |
613 // case IMGFMT_RGB32: | |
614 case IMGFMT_BGR32: | |
615 awidth = (info->src.w*4 + (pitch-1)) & ~(pitch-1); | |
616 info->frame_size = (awidth*info->src.h); | |
617 break; | |
618 /* YUY2 YVYU, RGB15, RGB16 */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
619 default: |
22850 | 620 awidth = (info->src.w*2 + (pitch-1)) & ~(pitch-1); |
621 info->frame_size = (awidth*info->src.h); | |
622 break; | |
623 } | |
624 info->frame_size+=256; // so we have some space for alignment & such | |
625 info->frame_size&=~16; | |
626 } | |
627 | |
628 static void mach64_vid_stop_video( void ) | |
629 { | |
630 mach64_fifo_wait(14); | |
631 OUTREG(OVERLAY_SCALE_CNTL, 0x80000000); | |
632 OUTREG(OVERLAY_EXCLUSIVE_HORZ, 0); | |
633 OUTREG(OVERLAY_EXCLUSIVE_VERT, 0); | |
634 OUTREG(SCALER_H_COEFF0, 0x00002000); | |
635 OUTREG(SCALER_H_COEFF1, 0x0D06200D); | |
636 OUTREG(SCALER_H_COEFF2, 0x0D0A1C0D); | |
637 OUTREG(SCALER_H_COEFF3, 0x0C0E1A0C); | |
638 OUTREG(SCALER_H_COEFF4, 0x0C14140C); | |
639 OUTREG(VIDEO_FORMAT, 0xB000B); | |
640 OUTREG(OVERLAY_TEST, 0x0); | |
641 } | |
642 | |
643 static void mach64_vid_display_video( void ) | |
644 { | |
645 uint32_t vf; | |
646 mach64_fifo_wait(14); | |
647 | |
648 OUTREG(OVERLAY_Y_X_START, besr.y_x_start); | |
649 OUTREG(OVERLAY_Y_X_END, besr.y_x_end); | |
650 OUTREG(OVERLAY_SCALE_INC, besr.scale_inc); | |
651 OUTREG(SCALER_BUF_PITCH, besr.vid_buf_pitch); | |
652 OUTREG(SCALER_HEIGHT_WIDTH, besr.height_width); | |
653 OUTREG(SCALER_BUF0_OFFSET, mach64_buffer_base[0][0]); | |
654 OUTREG(SCALER_BUF0_OFFSET_U, mach64_buffer_base[0][1]); | |
655 OUTREG(SCALER_BUF0_OFFSET_V, mach64_buffer_base[0][2]); | |
656 OUTREG(SCALER_BUF1_OFFSET, mach64_buffer_base[0][0]); | |
657 OUTREG(SCALER_BUF1_OFFSET_U, mach64_buffer_base[0][1]); | |
658 OUTREG(SCALER_BUF1_OFFSET_V, mach64_buffer_base[0][2]); | |
659 mach64_wait_vsync(); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
660 |
22850 | 661 mach64_fifo_wait(4); |
662 OUTREG(OVERLAY_SCALE_CNTL, 0xC4000003); | |
663 // OVERLAY_SCALE_CNTL bits & what they seem to affect | |
664 // bit 0 no effect | |
665 // bit 1 yuv2rgb coeff related | |
666 // bit 2 horizontal interpolation if 0 | |
667 // bit 3 vertical interpolation if 0 | |
668 // bit 4 chroma encoding (0-> 128=neutral / 1-> 0->neutral) | |
669 // bit 5-6 gamma correction | |
670 // bit 7 nothing visible if set | |
671 // bit 8-27 no effect | |
672 // bit 28-31 nothing interresting just crashed my system when i played with them :( | |
673 | |
674 mach64_wait_for_idle(); | |
675 vf = INREG(VIDEO_FORMAT); | |
676 | |
677 // Bits 16-19 seem to select the format | |
678 // 0x0 dunno behaves strange | |
679 // 0x1 dunno behaves strange | |
680 // 0x2 dunno behaves strange | |
681 // 0x3 BGR15 | |
682 // 0x4 BGR16 | |
683 // 0x5 BGR16 (hmm, that need investigation, 2 BGR16 formats, i guess 1 will have only 5bits for green) | |
684 // 0x6 BGR32 | |
685 // 0x7 BGR32 with somehow mixed even / odd pixels ? | |
686 // 0x8 YYYYUVUV | |
687 // 0x9 YVU9 | |
688 // 0xA YV12 | |
689 // 0xB YUY2 | |
690 // 0xC UYVY | |
691 // 0xD UYVY (no difference is visible if i switch between C/D for every even/odd frame) | |
692 // 0xE dunno behaves strange | |
693 // 0xF dunno behaves strange | |
694 // Bit 28 all values are assumed to be 7 bit with chroma=64 for black (tested with YV12 & YUY2) | |
695 // the remaining bits seem to have no effect | |
696 | |
697 | |
698 switch(besr.fourcc) | |
699 { | |
700 /* BGR formats */ | |
701 case IMGFMT_BGR15: OUTREG(VIDEO_FORMAT, 0x00030000); break; | |
702 case IMGFMT_BGR16: OUTREG(VIDEO_FORMAT, 0x00040000); break; | |
703 case IMGFMT_BGR32: OUTREG(VIDEO_FORMAT, 0x00060000); break; | |
704 /* 4:2:0 */ | |
705 case IMGFMT_IYUV: | |
706 case IMGFMT_I420: | |
707 case IMGFMT_YV12: OUTREG(VIDEO_FORMAT, 0x000A0000); break; | |
708 | |
709 case IMGFMT_YVU9: OUTREG(VIDEO_FORMAT, 0x00090000); break; | |
710 /* 4:2:2 */ | |
711 case IMGFMT_YVYU: | |
712 case IMGFMT_UYVY: OUTREG(VIDEO_FORMAT, 0x000C0000); break; | |
713 case IMGFMT_YUY2: | |
714 default: OUTREG(VIDEO_FORMAT, 0x000B0000); break; | |
715 } | |
25859
e8af7338a462
Fix illegal identifiers, names starting with __ are reserved for the system.
diego
parents:
24126
diff
changeset
|
716 if(verbosity > VERBOSE_LEVEL) mach64_vid_dump_regs(); |
22850 | 717 } |
718 | |
719 static int mach64_vid_init_video( vidix_playback_t *config ) | |
720 { | |
721 uint32_t src_w,src_h,dest_w,dest_h,pitch,h_inc,v_inc,left,leftUV,top,ecp,y_pos; | |
722 int is_420,best_pitch,mpitch; | |
723 int src_offset_y, src_offset_u, src_offset_v; | |
724 unsigned int i; | |
725 | |
726 mach64_vid_stop_video(); | |
727 /* warning, if left or top are != 0 this will fail, as the framesize is too small then */ | |
728 left = config->src.x; | |
729 top = config->src.y; | |
730 src_h = config->src.h; | |
731 src_w = config->src.w; | |
732 is_420 = 0; | |
733 if(config->fourcc == IMGFMT_YV12 || | |
734 config->fourcc == IMGFMT_I420 || | |
735 config->fourcc == IMGFMT_IYUV) is_420 = 1; | |
736 best_pitch = mach64_query_pitch(config->fourcc,&config->src.pitch); | |
737 mpitch = best_pitch-1; | |
738 switch(config->fourcc) | |
739 { | |
740 case IMGFMT_YVU9: | |
741 /* 4:2:0 */ | |
742 case IMGFMT_IYUV: | |
743 case IMGFMT_YV12: | |
744 case IMGFMT_I420: pitch = (src_w + mpitch) & ~mpitch; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
745 config->dest.pitch.y = |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
746 config->dest.pitch.u = |
22850 | 747 config->dest.pitch.v = best_pitch; |
748 besr.vid_buf_pitch= pitch; | |
749 break; | |
750 /* RGB 4:4:4:4 */ | |
751 case IMGFMT_RGB32: | |
752 case IMGFMT_BGR32: pitch = (src_w*4 + mpitch) & ~mpitch; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
753 config->dest.pitch.y = |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
754 config->dest.pitch.u = |
22850 | 755 config->dest.pitch.v = best_pitch; |
756 besr.vid_buf_pitch= pitch>>2; | |
757 break; | |
758 /* 4:2:2 */ | |
759 default: /* RGB15, RGB16, YVYU, UYVY, YUY2 */ | |
760 pitch = ((src_w*2) + mpitch) & ~mpitch; | |
761 config->dest.pitch.y = | |
762 config->dest.pitch.u = | |
763 config->dest.pitch.v = best_pitch; | |
764 besr.vid_buf_pitch= pitch>>1; | |
765 break; | |
766 } | |
767 dest_w = config->dest.w; | |
768 dest_h = config->dest.h; | |
769 besr.fourcc = config->fourcc; | |
770 ecp = (INPLL(PLL_VCLK_CNTL) & PLL_ECP_DIV) >> 4; | |
23048 | 771 |
25859
e8af7338a462
Fix illegal identifiers, names starting with __ are reserved for the system.
diego
parents:
24126
diff
changeset
|
772 if(verbosity > 0) printf("[mach64] ecp: %d\n", ecp); |
22850 | 773 v_inc = src_h * mach64_get_vert_stretch(); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
774 |
22850 | 775 if(mach64_is_interlace()) v_inc<<=1; |
776 if(mach64_is_dbl_scan() ) v_inc>>=1; | |
777 v_inc>>=4; // convert 16.16 -> 20.12 | |
778 v_inc/= dest_h; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
779 |
22850 | 780 h_inc = (src_w << (12+ecp)) / dest_w; |
781 /* keep everything in 16.16 */ | |
782 config->offsets[0] = 0; | |
783 for(i=1; i<config->num_frames; i++) | |
784 config->offsets[i] = config->offsets[i-1] + config->frame_size; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
785 |
22850 | 786 /*FIXME the left / top stuff is broken (= zoom a src rectangle from a larger one) |
787 1. the framesize isn't known as the outer src rectangle dimensions aren't known | |
788 2. the mach64 needs aligned addresses so it can't work anyway | |
789 -> so we could shift the outer buffer to compensate that but that would mean | |
790 alignment problems for the code which writes into it | |
791 */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
792 |
22850 | 793 if(is_420) |
794 { | |
795 config->offset.y= 0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
796 config->offset.u= (pitch*src_h + 15)&~15; |
22850 | 797 config->offset.v= (config->offset.u + (pitch*src_h>>2) + 15)&~15; |
798 | |
799 if(besr.fourcc == IMGFMT_I420 || besr.fourcc == IMGFMT_IYUV) | |
800 { | |
801 uint32_t tmp; | |
802 tmp = config->offset.u; | |
803 config->offset.u = config->offset.v; | |
804 config->offset.v = tmp; | |
805 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
806 |
22850 | 807 src_offset_y= config->offset.y + top*pitch + left; |
808 src_offset_u= config->offset.u + (top*pitch>>2) + (left>>1); | |
809 src_offset_v= config->offset.v + (top*pitch>>2) + (left>>1); | |
810 } | |
811 else if(besr.fourcc == IMGFMT_YVU9) | |
812 { | |
813 config->offset.y= 0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
814 config->offset.u= (pitch*src_h + 15)&~15; |
22850 | 815 config->offset.v= (config->offset.u + (pitch*src_h>>4) + 15)&~15; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
816 |
22850 | 817 src_offset_y= config->offset.y + top*pitch + left; |
818 src_offset_u= config->offset.u + (top*pitch>>4) + (left>>1); | |
819 src_offset_v= config->offset.v + (top*pitch>>4) + (left>>1); | |
820 } | |
821 else if(besr.fourcc == IMGFMT_BGR32) | |
822 { | |
823 config->offset.y = config->offset.u = config->offset.v = 0; | |
824 src_offset_y= src_offset_u= src_offset_v= top*pitch + (left << 2); | |
825 } | |
826 else | |
827 { | |
828 config->offset.y = config->offset.u = config->offset.v = 0; | |
829 src_offset_y= src_offset_u= src_offset_v= top*pitch + (left << 1); | |
830 } | |
831 | |
832 num_mach64_buffers= config->num_frames; | |
833 for(i=0; i<config->num_frames; i++) | |
834 { | |
835 mach64_buffer_base[i][0]= (mach64_overlay_offset + config->offsets[i] + src_offset_y)&~15; | |
836 mach64_buffer_base[i][1]= (mach64_overlay_offset + config->offsets[i] + src_offset_u)&~15; | |
837 mach64_buffer_base[i][2]= (mach64_overlay_offset + config->offsets[i] + src_offset_v)&~15; | |
838 } | |
839 | |
840 leftUV = (left >> 17) & 15; | |
841 left = (left >> 16) & 15; | |
842 besr.scale_inc = ( h_inc << 16 ) | v_inc; | |
843 y_pos = config->dest.y; | |
844 if(mach64_is_dbl_scan()) y_pos*=2; | |
845 else | |
846 if(mach64_is_interlace()) y_pos/=2; | |
847 besr.y_x_start = y_pos | (config->dest.x << 16); | |
848 y_pos =config->dest.y + dest_h; | |
849 if(mach64_is_dbl_scan()) y_pos*=2; | |
850 else | |
851 if(mach64_is_interlace()) y_pos/=2; | |
852 besr.y_x_end = y_pos | ((config->dest.x + dest_w) << 16); | |
853 besr.height_width = ((src_w - left)<<16) | (src_h - top); | |
854 | |
855 return 0; | |
856 } | |
857 | |
858 static int is_supported_fourcc(uint32_t fourcc) | |
859 { | |
860 switch(fourcc) | |
861 { | |
862 case IMGFMT_YV12: | |
863 case IMGFMT_I420: | |
864 case IMGFMT_YVU9: | |
865 case IMGFMT_IYUV: | |
866 return supports_planar; | |
867 case IMGFMT_YUY2: | |
868 case IMGFMT_UYVY: | |
869 case IMGFMT_BGR15: | |
870 case IMGFMT_BGR16: | |
871 case IMGFMT_BGR32: | |
872 return 1; | |
873 default: | |
874 return 0; | |
875 } | |
876 } | |
877 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
878 static int mach64_query_fourcc(vidix_fourcc_t *to) |
22850 | 879 { |
880 if(is_supported_fourcc(to->fourcc)) | |
881 { | |
23060 | 882 to->depth = VID_DEPTH_ALL; |
22850 | 883 to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY; |
884 return 0; | |
885 } | |
886 else to->depth = to->flags = 0; | |
887 return ENOSYS; | |
888 } | |
889 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
890 static int mach64_config_playback(vidix_playback_t *info) |
22850 | 891 { |
892 if(!is_supported_fourcc(info->fourcc)) return ENOSYS; | |
893 | |
894 mach64_compute_framesize(info); | |
895 | |
896 if(info->num_frames>4) info->num_frames=4; | |
897 for(;info->num_frames>0; info->num_frames--) | |
898 { | |
899 mach64_overlay_offset = mach64_ram_size - info->frame_size*info->num_frames; | |
900 mach64_overlay_offset &= 0xffff0000; | |
901 if(mach64_overlay_offset>0) break; | |
902 } | |
903 if(info->num_frames <= 0) return EINVAL; | |
904 | |
905 info->dga_addr = (char *)mach64_mem_base + mach64_overlay_offset; | |
906 mach64_vid_init_video(info); | |
907 return 0; | |
908 } | |
909 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
910 static int mach64_playback_on(void) |
22850 | 911 { |
912 mach64_vid_display_video(); | |
913 return 0; | |
914 } | |
915 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
916 static int mach64_playback_off(void) |
22850 | 917 { |
918 mach64_vid_stop_video(); | |
919 return 0; | |
920 } | |
921 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
922 static int mach64_frame_sel(unsigned int frame) |
22850 | 923 { |
924 uint32_t off[6]; | |
925 int i; | |
926 int last_frame= (frame-1+num_mach64_buffers) % num_mach64_buffers; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
927 //printf("Selecting frame %d\n", frame); |
22850 | 928 /* |
929 buf3-5 always should point onto second buffer for better | |
930 deinterlacing and TV-in | |
931 */ | |
932 if(num_mach64_buffers==1) return 0; | |
933 | |
934 for(i=0; i<3; i++) | |
935 { | |
936 off[i] = mach64_buffer_base[frame][i]; | |
937 off[i+3]= mach64_buffer_base[last_frame][i]; | |
938 } | |
939 | |
940 mach64_wait_for_idle(); | |
941 mach64_fifo_wait(7); | |
942 | |
943 OUTREG(SCALER_BUF0_OFFSET, off[0]); | |
944 OUTREG(SCALER_BUF0_OFFSET_U, off[1]); | |
945 OUTREG(SCALER_BUF0_OFFSET_V, off[2]); | |
946 OUTREG(SCALER_BUF1_OFFSET, off[3]); | |
947 OUTREG(SCALER_BUF1_OFFSET_U, off[4]); | |
948 OUTREG(SCALER_BUF1_OFFSET_V, off[5]); | |
949 if(num_mach64_buffers==2) mach64_wait_vsync(); //only wait for vsync if we do double buffering | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27079
diff
changeset
|
950 |
25859
e8af7338a462
Fix illegal identifiers, names starting with __ are reserved for the system.
diego
parents:
24126
diff
changeset
|
951 if(verbosity > VERBOSE_LEVEL) mach64_vid_dump_regs(); |
22850 | 952 return 0; |
953 } | |
954 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
955 static vidix_video_eq_t equal = |
22850 | 956 { |
957 VEQ_CAP_BRIGHTNESS | VEQ_CAP_SATURATION | |
958 , | |
959 0, 0, 0, 0, 0, 0, 0, 0 }; | |
960 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
961 static int mach64_get_eq( vidix_video_eq_t * eq) |
22850 | 962 { |
963 memcpy(eq,&equal,sizeof(vidix_video_eq_t)); | |
964 return 0; | |
965 } | |
966 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
967 static int mach64_set_eq( const vidix_video_eq_t * eq) |
22850 | 968 { |
969 int br,sat; | |
970 if(eq->cap & VEQ_CAP_BRIGHTNESS) equal.brightness = eq->brightness; | |
971 if(eq->cap & VEQ_CAP_CONTRAST) equal.contrast = eq->contrast; | |
972 if(eq->cap & VEQ_CAP_SATURATION) equal.saturation = eq->saturation; | |
973 if(eq->cap & VEQ_CAP_HUE) equal.hue = eq->hue; | |
974 if(eq->cap & VEQ_CAP_RGB_INTENSITY) | |
975 { | |
976 equal.red_intensity = eq->red_intensity; | |
977 equal.green_intensity = eq->green_intensity; | |
978 equal.blue_intensity = eq->blue_intensity; | |
979 } | |
980 equal.flags = eq->flags; | |
981 br = equal.brightness * 64 / 1000; | |
982 if(br < -64) br = -64; if(br > 63) br = 63; | |
983 sat = (equal.saturation + 1000) * 16 / 1000; | |
984 if(sat < 0) sat = 0; if(sat > 31) sat = 31; | |
985 OUTREG(SCALER_COLOUR_CNTL, (br & 0x7f) | (sat << 8) | (sat << 16)); | |
986 return 0; | |
987 } | |
988 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
989 static int mach64_get_gkeys(vidix_grkey_t *grkey) |
22850 | 990 { |
991 memcpy(grkey, &mach64_grkey, sizeof(vidix_grkey_t)); | |
26753
502f04b67653
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26719
diff
changeset
|
992 return 0; |
22850 | 993 } |
994 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
995 static int mach64_set_gkeys(const vidix_grkey_t *grkey) |
22850 | 996 { |
997 memcpy(&mach64_grkey, grkey, sizeof(vidix_grkey_t)); | |
998 | |
999 if(mach64_grkey.ckey.op == CKEY_TRUE) | |
1000 { | |
1001 besr.ckey_on=1; | |
1002 | |
1003 switch(mach64_vid_get_dbpp()) | |
1004 { | |
1005 case 15: | |
1006 besr.graphics_key_msk=0x7FFF; | |
1007 besr.graphics_key_clr= | |
1008 ((mach64_grkey.ckey.blue &0xF8)>>3) | |
1009 | ((mach64_grkey.ckey.green&0xF8)<<2) | |
1010 | ((mach64_grkey.ckey.red &0xF8)<<7); | |
1011 break; | |
1012 case 16: | |
1013 besr.graphics_key_msk=0xFFFF; | |
1014 besr.graphics_key_clr= | |
1015 ((mach64_grkey.ckey.blue &0xF8)>>3) | |
1016 | ((mach64_grkey.ckey.green&0xFC)<<3) | |
1017 | ((mach64_grkey.ckey.red &0xF8)<<8); | |
1018 //besr.graphics_key_clr=le2me_32(besr.graphics_key_clr); | |
1019 break; | |
1020 case 24: | |
1021 besr.graphics_key_msk=0xFFFFFF; | |
1022 besr.graphics_key_clr= | |
1023 ((mach64_grkey.ckey.blue &0xFF)) | |
1024 | ((mach64_grkey.ckey.green&0xFF)<<8) | |
1025 | ((mach64_grkey.ckey.red &0xFF)<<16); | |
1026 break; | |
1027 case 32: | |
1028 besr.graphics_key_msk=0xFFFFFF; | |
1029 besr.graphics_key_clr= | |
1030 ((mach64_grkey.ckey.blue &0xFF)) | |
1031 | ((mach64_grkey.ckey.green&0xFF)<<8) | |
1032 | ((mach64_grkey.ckey.red &0xFF)<<16); | |
1033 break; | |
1034 default: | |
1035 besr.ckey_on=0; | |
1036 besr.graphics_key_msk=0; | |
1037 besr.graphics_key_clr=0; | |
1038 } | |
1039 } | |
1040 else | |
1041 { | |
1042 besr.ckey_on=0; | |
1043 besr.graphics_key_msk=0; | |
1044 besr.graphics_key_clr=0; | |
1045 } | |
1046 | |
1047 mach64_fifo_wait(4); | |
1048 OUTREG(OVERLAY_GRAPHICS_KEY_MSK, besr.graphics_key_msk); | |
1049 OUTREG(OVERLAY_GRAPHICS_KEY_CLR, besr.graphics_key_clr); | |
1050 // OUTREG(OVERLAY_VIDEO_KEY_MSK, 0); | |
1051 // OUTREG(OVERLAY_VIDEO_KEY_CLR, 0); | |
1052 if(besr.ckey_on) | |
1053 OUTREG(OVERLAY_KEY_CNTL,VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_EQ|CMP_MIX_AND); | |
1054 else | |
1055 OUTREG(OVERLAY_KEY_CNTL,VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_TRUE|CMP_MIX_AND); | |
1056 | |
26753
502f04b67653
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26719
diff
changeset
|
1057 return 0; |
22850 | 1058 } |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1059 |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1060 VDXDriver mach64_drv = { |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1061 "mach64", |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1062 NULL, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1063 .probe = mach64_probe, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1064 .get_caps = mach64_get_caps, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1065 .query_fourcc = mach64_query_fourcc, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1066 .init = mach64_init, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1067 .destroy = mach64_destroy, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1068 .config_playback = mach64_config_playback, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1069 .playback_on = mach64_playback_on, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1070 .playback_off = mach64_playback_off, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1071 .frame_sel = mach64_frame_sel, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1072 .get_eq = mach64_get_eq, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1073 .set_eq = mach64_set_eq, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1074 .get_gkey = mach64_get_gkeys, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1075 .set_gkey = mach64_set_gkeys, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1076 }; |