Mercurial > mplayer.hg
annotate drivers/radeon_vid.c @ 30811:50e0f6942e43
Implement Win32 mutexes.
Implement Win32 mutexes; they used to just be mapped on top of events, which
is not the same thing at all.
The implementation is pretty much the obvious one, similar to the
current critical section implementation and the semaphore implementation;
a single lock count protected by a pthread mutex, and an event lockers can
sleep on to know when the mutex is available.
Also make CreateMutexA and ReleaseMutex available even if QuickTime codecs
support is not configured.
author | sesse |
---|---|
date | Sat, 06 Mar 2010 10:13:37 +0000 |
parents | 32725ca88fed |
children | 958431e2cde0 |
rev | line source |
---|---|
22691 | 1 /* |
26003
a506a6ab14e1
Add standard license header and make copyright notices consistent.
diego
parents:
25862
diff
changeset
|
2 * BES YUV video overlay driver for Radeon/Rage128Pro/Rage128 cards |
22691 | 3 * |
4 * Copyright (C) 2001 Nick Kurshev | |
5 * | |
26003
a506a6ab14e1
Add standard license header and make copyright notices consistent.
diego
parents:
25862
diff
changeset
|
6 * This file is partly based on mga_vid and sis_vid from MPlayer. |
a506a6ab14e1
Add standard license header and make copyright notices consistent.
diego
parents:
25862
diff
changeset
|
7 * Code from CVS of GATOS project and X11 trees was also used. |
22691 | 8 * |
9 * SPECIAL THANKS TO: Hans-Peter Raschke for active testing and hacking | |
10 * Rage128(pro) stuff of this driver. | |
26003
a506a6ab14e1
Add standard license header and make copyright notices consistent.
diego
parents:
25862
diff
changeset
|
11 * |
a506a6ab14e1
Add standard license header and make copyright notices consistent.
diego
parents:
25862
diff
changeset
|
12 * This file is part of MPlayer. |
a506a6ab14e1
Add standard license header and make copyright notices consistent.
diego
parents:
25862
diff
changeset
|
13 * |
a506a6ab14e1
Add standard license header and make copyright notices consistent.
diego
parents:
25862
diff
changeset
|
14 * MPlayer is free software; you can redistribute it and/or modify |
a506a6ab14e1
Add standard license header and make copyright notices consistent.
diego
parents:
25862
diff
changeset
|
15 * it under the terms of the GNU General Public License as published by |
a506a6ab14e1
Add standard license header and make copyright notices consistent.
diego
parents:
25862
diff
changeset
|
16 * the Free Software Foundation; either version 2 of the License, or |
a506a6ab14e1
Add standard license header and make copyright notices consistent.
diego
parents:
25862
diff
changeset
|
17 * (at your option) any later version. |
a506a6ab14e1
Add standard license header and make copyright notices consistent.
diego
parents:
25862
diff
changeset
|
18 * |
a506a6ab14e1
Add standard license header and make copyright notices consistent.
diego
parents:
25862
diff
changeset
|
19 * MPlayer is distributed in the hope that it will be useful, |
a506a6ab14e1
Add standard license header and make copyright notices consistent.
diego
parents:
25862
diff
changeset
|
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
a506a6ab14e1
Add standard license header and make copyright notices consistent.
diego
parents:
25862
diff
changeset
|
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
a506a6ab14e1
Add standard license header and make copyright notices consistent.
diego
parents:
25862
diff
changeset
|
22 * GNU General Public License for more details. |
a506a6ab14e1
Add standard license header and make copyright notices consistent.
diego
parents:
25862
diff
changeset
|
23 * |
a506a6ab14e1
Add standard license header and make copyright notices consistent.
diego
parents:
25862
diff
changeset
|
24 * You should have received a copy of the GNU General Public License along |
a506a6ab14e1
Add standard license header and make copyright notices consistent.
diego
parents:
25862
diff
changeset
|
25 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
a506a6ab14e1
Add standard license header and make copyright notices consistent.
diego
parents:
25862
diff
changeset
|
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
22691 | 27 */ |
28 | |
29 #define RADEON_VID_VERSION "1.2.1" | |
30 | |
31 /* | |
32 It's entirely possible this major conflicts with something else | |
33 mknod /dev/radeon_vid c 178 0 | |
34 or | |
35 mknod /dev/rage128_vid c 178 0 | |
36 for Rage128/Rage128Pro chips (although it doesn't matter) | |
37 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
38 TESTED and WORKING formats: YUY2, UYVY, IYUV, I420, YV12 | |
39 ----------------------------------------------------------- | |
40 TODO: | |
41 Highest priority: fbvid.h compatibility | |
42 High priority: Fixing BUGS | |
43 Middle priority: RGB/BGR 2-32, YVU9, IF09 support | |
44 Low priority: CLPL, IYU1, IYU2, UYNV, CYUV, YUNV, YVYU, Y41P, Y211, Y41T, | |
45 ^^^^ | |
46 Y42T, V422, V655, CLJR, YUVP, UYVP, Mpeg PES (mpeg-1,2) support | |
47 ........................................................... | |
48 BUGS and LACKS: | |
49 Color and video keys don't work | |
50 */ | |
51 | |
52 #include <linux/config.h> | |
53 #include <linux/version.h> | |
54 #include <linux/module.h> | |
55 #include <linux/types.h> | |
56 #include <linux/kernel.h> | |
57 #include <linux/sched.h> | |
58 #include <linux/mm.h> | |
59 #include <linux/string.h> | |
60 #include <linux/errno.h> | |
61 #include <linux/slab.h> | |
62 #include <linux/pci.h> | |
63 #include <linux/ioport.h> | |
64 #include <linux/init.h> | |
65 #include <linux/byteorder/swab.h> | |
66 | |
67 #include "radeon_vid.h" | |
68 #include "radeon.h" | |
69 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
70 #ifdef CONFIG_MTRR |
22691 | 71 #include <asm/mtrr.h> |
72 #endif | |
73 | |
74 #include <asm/uaccess.h> | |
75 #include <asm/system.h> | |
76 #include <asm/io.h> | |
77 | |
78 #define TRUE 1 | |
79 #define FALSE 0 | |
80 | |
81 #define RADEON_VID_MAJOR 178 | |
82 | |
83 | |
84 MODULE_AUTHOR("Nick Kurshev <nickols_k@mail.ru>"); | |
85 #ifdef RAGE128 | |
86 MODULE_DESCRIPTION("Accelerated YUV BES driver for Rage128. Version: "RADEON_VID_VERSION); | |
87 #else | |
88 MODULE_DESCRIPTION("Accelerated YUV BES driver for Radeons. Version: "RADEON_VID_VERSION); | |
89 #endif | |
90 #ifdef MODULE_LICENSE | |
91 MODULE_LICENSE("GPL"); | |
92 #endif | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
93 #ifdef CONFIG_MTRR |
22691 | 94 MODULE_PARM(mtrr, "i"); |
95 MODULE_PARM_DESC(mtrr, "Tune MTRR (touch=1(default))"); | |
96 static int mtrr __initdata = 1; | |
97 static struct { int vram; int vram_valid; } smtrr; | |
98 #endif | |
99 MODULE_PARM(swap_fourcc, "i"); | |
100 MODULE_PARM_DESC(swap_fourcc, "Swap fourcc (don't swap=0(default))"); | |
101 static int swap_fourcc __initdata = 0; | |
102 | |
103 #ifdef RAGE128 | |
104 #define RVID_MSG "rage128_vid: " | |
105 #define X_ADJUST 0 | |
106 #else | |
107 #define RVID_MSG "radeon_vid: " | |
108 #define X_ADJUST 8 | |
109 #ifndef RADEON | |
110 #define RADEON | |
111 #endif | |
112 #endif | |
113 | |
114 #undef DEBUG | |
115 #if DEBUG | |
116 #define RTRACE printk | |
117 #else | |
118 #define RTRACE(...) ((void)0) | |
119 #endif | |
120 | |
121 #ifndef min | |
122 #define min(a,b) (a < b ? a : b) | |
123 #endif | |
124 | |
125 #ifndef RAGE128 | |
126 #if defined(__i386__) | |
127 /* Ugly but only way */ | |
128 #undef AVOID_FPU | |
25862
4be9faee0360
Rename some identifiers to not use leading underscores.
diego
parents:
22691
diff
changeset
|
129 static inline double FastSin(double x) |
22691 | 130 { |
131 register double res; | |
27757
b5a46071062a
Replace all occurrences of '__volatile__' and '__volatile' by plain 'volatile'.
diego
parents:
27754
diff
changeset
|
132 __asm__ volatile("fsin":"=t"(res):"0"(x)); |
22691 | 133 return res; |
134 } | |
135 #undef sin | |
25862
4be9faee0360
Rename some identifiers to not use leading underscores.
diego
parents:
22691
diff
changeset
|
136 #define sin(x) FastSin(x) |
22691 | 137 |
25862
4be9faee0360
Rename some identifiers to not use leading underscores.
diego
parents:
22691
diff
changeset
|
138 static inline double FastCos(double x) |
22691 | 139 { |
140 register double res; | |
27757
b5a46071062a
Replace all occurrences of '__volatile__' and '__volatile' by plain 'volatile'.
diego
parents:
27754
diff
changeset
|
141 __asm__ volatile("fcos":"=t"(res):"0"(x)); |
22691 | 142 return res; |
143 } | |
144 #undef cos | |
25862
4be9faee0360
Rename some identifiers to not use leading underscores.
diego
parents:
22691
diff
changeset
|
145 #define cos(x) FastCos(x) |
22691 | 146 #else |
147 #include "generic_math.h" | |
148 #endif /*__386__*/ | |
149 #endif /*RAGE128*/ | |
150 | |
151 #if !defined( RAGE128 ) && !defined( AVOID_FPU ) | |
152 #define RADEON_FPU 1 | |
153 #endif | |
154 | |
155 typedef struct bes_registers_s | |
156 { | |
157 /* base address of yuv framebuffer */ | |
158 uint32_t yuv_base; | |
159 uint32_t fourcc; | |
160 uint32_t dest_bpp; | |
161 /* YUV BES registers */ | |
162 uint32_t reg_load_cntl; | |
163 uint32_t h_inc; | |
164 uint32_t step_by; | |
165 uint32_t y_x_start; | |
166 uint32_t y_x_end; | |
167 uint32_t v_inc; | |
168 uint32_t p1_blank_lines_at_top; | |
169 uint32_t p23_blank_lines_at_top; | |
170 uint32_t vid_buf_pitch0_value; | |
171 uint32_t vid_buf_pitch1_value; | |
172 uint32_t p1_x_start_end; | |
173 uint32_t p2_x_start_end; | |
174 uint32_t p3_x_start_end; | |
175 uint32_t base_addr; | |
176 uint32_t vid_buf0_base_adrs; | |
177 /* These ones are for auto flip: maybe in the future */ | |
178 uint32_t vid_buf1_base_adrs; | |
179 uint32_t vid_buf2_base_adrs; | |
180 uint32_t vid_buf3_base_adrs; | |
181 uint32_t vid_buf4_base_adrs; | |
182 uint32_t vid_buf5_base_adrs; | |
183 | |
184 uint32_t p1_v_accum_init; | |
185 uint32_t p1_h_accum_init; | |
186 uint32_t p23_v_accum_init; | |
187 uint32_t p23_h_accum_init; | |
188 uint32_t scale_cntl; | |
189 uint32_t exclusive_horz; | |
190 uint32_t auto_flip_cntl; | |
191 uint32_t filter_cntl; | |
192 uint32_t key_cntl; | |
193 uint32_t test; | |
194 /* Configurable stuff */ | |
195 int double_buff; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
196 |
22691 | 197 int brightness; |
198 int saturation; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
199 |
22691 | 200 int ckey_on; |
201 uint32_t graphics_key_clr; | |
202 uint32_t graphics_key_msk; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
203 |
22691 | 204 int deinterlace_on; |
205 uint32_t deinterlace_pattern; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
206 |
22691 | 207 } bes_registers_t; |
208 | |
209 typedef struct video_registers_s | |
210 { | |
211 #ifdef DEBUG | |
212 const char * sname; | |
213 #endif | |
214 uint32_t name; | |
215 uint32_t value; | |
216 }video_registers_t; | |
217 | |
218 static bes_registers_t besr; | |
219 #ifndef RAGE128 | |
220 static int IsR200=0; | |
221 #endif | |
222 #ifdef DEBUG | |
223 #define DECLARE_VREG(name) { #name, name, 0 } | |
224 #else | |
225 #define DECLARE_VREG(name) { name, 0 } | |
226 #endif | |
227 #ifdef DEBUG | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
228 static video_registers_t vregs[] = |
22691 | 229 { |
230 DECLARE_VREG(VIDEOMUX_CNTL), | |
231 DECLARE_VREG(VIPPAD_MASK), | |
232 DECLARE_VREG(VIPPAD1_A), | |
233 DECLARE_VREG(VIPPAD1_EN), | |
234 DECLARE_VREG(VIPPAD1_Y), | |
235 DECLARE_VREG(OV0_Y_X_START), | |
236 DECLARE_VREG(OV0_Y_X_END), | |
237 DECLARE_VREG(OV0_PIPELINE_CNTL), | |
238 DECLARE_VREG(OV0_EXCLUSIVE_HORZ), | |
239 DECLARE_VREG(OV0_EXCLUSIVE_VERT), | |
240 DECLARE_VREG(OV0_REG_LOAD_CNTL), | |
241 DECLARE_VREG(OV0_SCALE_CNTL), | |
242 DECLARE_VREG(OV0_V_INC), | |
243 DECLARE_VREG(OV0_P1_V_ACCUM_INIT), | |
244 DECLARE_VREG(OV0_P23_V_ACCUM_INIT), | |
245 DECLARE_VREG(OV0_P1_BLANK_LINES_AT_TOP), | |
246 DECLARE_VREG(OV0_P23_BLANK_LINES_AT_TOP), | |
247 #ifdef RADEON | |
248 DECLARE_VREG(OV0_BASE_ADDR), | |
249 #endif | |
250 DECLARE_VREG(OV0_VID_BUF0_BASE_ADRS), | |
251 DECLARE_VREG(OV0_VID_BUF1_BASE_ADRS), | |
252 DECLARE_VREG(OV0_VID_BUF2_BASE_ADRS), | |
253 DECLARE_VREG(OV0_VID_BUF3_BASE_ADRS), | |
254 DECLARE_VREG(OV0_VID_BUF4_BASE_ADRS), | |
255 DECLARE_VREG(OV0_VID_BUF5_BASE_ADRS), | |
256 DECLARE_VREG(OV0_VID_BUF_PITCH0_VALUE), | |
257 DECLARE_VREG(OV0_VID_BUF_PITCH1_VALUE), | |
258 DECLARE_VREG(OV0_AUTO_FLIP_CNTL), | |
259 DECLARE_VREG(OV0_DEINTERLACE_PATTERN), | |
260 DECLARE_VREG(OV0_SUBMIT_HISTORY), | |
261 DECLARE_VREG(OV0_H_INC), | |
262 DECLARE_VREG(OV0_STEP_BY), | |
263 DECLARE_VREG(OV0_P1_H_ACCUM_INIT), | |
264 DECLARE_VREG(OV0_P23_H_ACCUM_INIT), | |
265 DECLARE_VREG(OV0_P1_X_START_END), | |
266 DECLARE_VREG(OV0_P2_X_START_END), | |
267 DECLARE_VREG(OV0_P3_X_START_END), | |
268 DECLARE_VREG(OV0_FILTER_CNTL), | |
269 DECLARE_VREG(OV0_FOUR_TAP_COEF_0), | |
270 DECLARE_VREG(OV0_FOUR_TAP_COEF_1), | |
271 DECLARE_VREG(OV0_FOUR_TAP_COEF_2), | |
272 DECLARE_VREG(OV0_FOUR_TAP_COEF_3), | |
273 DECLARE_VREG(OV0_FOUR_TAP_COEF_4), | |
274 DECLARE_VREG(OV0_FLAG_CNTL), | |
275 #ifdef RAGE128 | |
276 DECLARE_VREG(OV0_COLOUR_CNTL), | |
277 #else | |
278 DECLARE_VREG(OV0_SLICE_CNTL), | |
279 #endif | |
280 DECLARE_VREG(OV0_VID_KEY_CLR), | |
281 DECLARE_VREG(OV0_VID_KEY_MSK), | |
282 DECLARE_VREG(OV0_GRAPHICS_KEY_CLR), | |
283 DECLARE_VREG(OV0_GRAPHICS_KEY_MSK), | |
284 DECLARE_VREG(OV0_KEY_CNTL), | |
285 DECLARE_VREG(OV0_TEST), | |
286 DECLARE_VREG(OV0_LIN_TRANS_A), | |
287 DECLARE_VREG(OV0_LIN_TRANS_B), | |
288 DECLARE_VREG(OV0_LIN_TRANS_C), | |
289 DECLARE_VREG(OV0_LIN_TRANS_D), | |
290 DECLARE_VREG(OV0_LIN_TRANS_E), | |
291 DECLARE_VREG(OV0_LIN_TRANS_F), | |
292 DECLARE_VREG(OV0_GAMMA_0_F), | |
293 DECLARE_VREG(OV0_GAMMA_10_1F), | |
294 DECLARE_VREG(OV0_GAMMA_20_3F), | |
295 DECLARE_VREG(OV0_GAMMA_40_7F), | |
296 DECLARE_VREG(OV0_GAMMA_380_3BF), | |
297 DECLARE_VREG(OV0_GAMMA_3C0_3FF), | |
298 DECLARE_VREG(SUBPIC_CNTL), | |
299 DECLARE_VREG(SUBPIC_DEFCOLCON), | |
300 DECLARE_VREG(SUBPIC_Y_X_START), | |
301 DECLARE_VREG(SUBPIC_Y_X_END), | |
302 DECLARE_VREG(SUBPIC_V_INC), | |
303 DECLARE_VREG(SUBPIC_H_INC), | |
304 DECLARE_VREG(SUBPIC_BUF0_OFFSET), | |
305 DECLARE_VREG(SUBPIC_BUF1_OFFSET), | |
306 DECLARE_VREG(SUBPIC_LC0_OFFSET), | |
307 DECLARE_VREG(SUBPIC_LC1_OFFSET), | |
308 DECLARE_VREG(SUBPIC_PITCH), | |
309 DECLARE_VREG(SUBPIC_BTN_HLI_COLCON), | |
310 DECLARE_VREG(SUBPIC_BTN_HLI_Y_X_START), | |
311 DECLARE_VREG(SUBPIC_BTN_HLI_Y_X_END), | |
312 DECLARE_VREG(SUBPIC_PALETTE_INDEX), | |
313 DECLARE_VREG(SUBPIC_PALETTE_DATA), | |
314 DECLARE_VREG(SUBPIC_H_ACCUM_INIT), | |
315 DECLARE_VREG(SUBPIC_V_ACCUM_INIT), | |
316 DECLARE_VREG(IDCT_RUNS), | |
317 DECLARE_VREG(IDCT_LEVELS), | |
318 DECLARE_VREG(IDCT_AUTH_CONTROL), | |
319 DECLARE_VREG(IDCT_AUTH), | |
320 DECLARE_VREG(IDCT_CONTROL) | |
321 }; | |
322 #endif | |
323 static uint32_t radeon_vid_in_use = 0; | |
324 | |
325 static uint8_t *radeon_mmio_base = 0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
326 static uint32_t radeon_mem_base = 0; |
22691 | 327 static int32_t radeon_overlay_off = 0; |
328 static uint32_t radeon_ram_size = 0; | |
329 #define PARAM_BUFF_SIZE 4096 | |
330 static uint8_t *radeon_param_buff = NULL; | |
331 static uint32_t radeon_param_buff_size=0; | |
332 static uint32_t radeon_param_buff_len=0; /* real length of buffer */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
333 static mga_vid_config_t radeon_config; |
22691 | 334 |
335 static char *fourcc_format_name(int format) | |
336 { | |
337 switch(format) | |
338 { | |
26759
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
339 case IMGFMT_RGB8: return "RGB 8-bit"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
340 case IMGFMT_RGB15: return "RGB 15-bit"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
341 case IMGFMT_RGB16: return "RGB 16-bit"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
342 case IMGFMT_RGB24: return "RGB 24-bit"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
343 case IMGFMT_RGB32: return "RGB 32-bit"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
344 case IMGFMT_BGR8: return "BGR 8-bit"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
345 case IMGFMT_BGR15: return "BGR 15-bit"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
346 case IMGFMT_BGR16: return "BGR 16-bit"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
347 case IMGFMT_BGR24: return "BGR 24-bit"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
348 case IMGFMT_BGR32: return "BGR 32-bit"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
349 case IMGFMT_YVU9: return "Planar YVU9"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
350 case IMGFMT_IF09: return "Planar IF09"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
351 case IMGFMT_YV12: return "Planar YV12"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
352 case IMGFMT_I420: return "Planar I420"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
353 case IMGFMT_IYUV: return "Planar IYUV"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
354 case IMGFMT_CLPL: return "Planar CLPL"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
355 case IMGFMT_Y800: return "Planar Y800"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
356 case IMGFMT_Y8: return "Planar Y8"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
357 case IMGFMT_IUYV: return "Packed IUYV"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
358 case IMGFMT_IY41: return "Packed IY41"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
359 case IMGFMT_IYU1: return "Packed IYU1"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
360 case IMGFMT_IYU2: return "Packed IYU2"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
361 case IMGFMT_UYNV: return "Packed UYNV"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
362 case IMGFMT_cyuv: return "Packed CYUV"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
363 case IMGFMT_Y422: return "Packed Y422"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
364 case IMGFMT_YUY2: return "Packed YUY2"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
365 case IMGFMT_YUNV: return "Packed YUNV"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
366 case IMGFMT_UYVY: return "Packed UYVY"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
367 // case IMGFMT_YVYU: return "Packed YVYU"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
368 case IMGFMT_Y41P: return "Packed Y41P"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
369 case IMGFMT_Y211: return "Packed Y211"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
370 case IMGFMT_Y41T: return "Packed Y41T"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
371 case IMGFMT_Y42T: return "Packed Y42T"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
372 case IMGFMT_V422: return "Packed V422"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
373 case IMGFMT_V655: return "Packed V655"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
374 case IMGFMT_CLJR: return "Packed CLJR"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
375 case IMGFMT_YUVP: return "Packed YUVP"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
376 case IMGFMT_UYVP: return "Packed UYVP"; |
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
377 case IMGFMT_MPEGPES: return "Mpeg PES"; |
22691 | 378 } |
26759
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
379 return "Unknown"; |
22691 | 380 } |
381 | |
382 | |
383 /* | |
384 * IO macros | |
385 */ | |
386 | |
387 #define INREG8(addr) readb((radeon_mmio_base)+addr) | |
388 #define OUTREG8(addr,val) writeb(val, (radeon_mmio_base)+addr) | |
389 #define INREG(addr) readl((radeon_mmio_base)+addr) | |
390 #define OUTREG(addr,val) writel(val, (radeon_mmio_base)+addr) | |
391 #define OUTREGP(addr,val,mask) \ | |
392 do { \ | |
25862
4be9faee0360
Rename some identifiers to not use leading underscores.
diego
parents:
22691
diff
changeset
|
393 unsigned int tmp = INREG(addr); \ |
4be9faee0360
Rename some identifiers to not use leading underscores.
diego
parents:
22691
diff
changeset
|
394 tmp &= (mask); \ |
4be9faee0360
Rename some identifiers to not use leading underscores.
diego
parents:
22691
diff
changeset
|
395 tmp |= (val); \ |
4be9faee0360
Rename some identifiers to not use leading underscores.
diego
parents:
22691
diff
changeset
|
396 OUTREG(addr, tmp); \ |
22691 | 397 } while (0) |
398 | |
399 static uint32_t radeon_vid_get_dbpp( void ) | |
400 { | |
401 uint32_t dbpp,retval; | |
402 dbpp = (INREG(CRTC_GEN_CNTL)>>8)& 0xF; | |
403 switch(dbpp) | |
404 { | |
405 case DST_8BPP: retval = 8; break; | |
406 case DST_15BPP: retval = 15; break; | |
407 case DST_16BPP: retval = 16; break; | |
408 case DST_24BPP: retval = 24; break; | |
409 default: retval=32; break; | |
410 } | |
411 return retval; | |
412 } | |
413 | |
414 static int radeon_is_dbl_scan( void ) | |
415 { | |
416 return (INREG(CRTC_GEN_CNTL))&CRTC_DBL_SCAN_EN; | |
417 } | |
418 | |
419 static int radeon_is_interlace( void ) | |
420 { | |
421 return (INREG(CRTC_GEN_CNTL))&CRTC_INTERLACE_EN; | |
422 } | |
423 | |
424 static __inline__ void radeon_engine_flush ( void ) | |
425 { | |
426 int i; | |
427 | |
428 /* initiate flush */ | |
429 OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL, | |
430 ~RB2D_DC_FLUSH_ALL); | |
431 | |
432 for (i=0; i < 2000000; i++) { | |
433 if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY)) | |
434 break; | |
435 } | |
436 } | |
437 | |
438 | |
25862
4be9faee0360
Rename some identifiers to not use leading underscores.
diego
parents:
22691
diff
changeset
|
439 static __inline__ void radeon_fifo_wait (int entries) |
22691 | 440 { |
441 int i; | |
442 | |
443 for (i=0; i<2000000; i++) | |
444 if ((INREG(RBBM_STATUS) & 0x7f) >= entries) | |
445 return; | |
446 } | |
447 | |
448 | |
25862
4be9faee0360
Rename some identifiers to not use leading underscores.
diego
parents:
22691
diff
changeset
|
449 static __inline__ void radeon_engine_idle ( void ) |
22691 | 450 { |
451 int i; | |
452 | |
453 /* ensure FIFO is empty before waiting for idle */ | |
25862
4be9faee0360
Rename some identifiers to not use leading underscores.
diego
parents:
22691
diff
changeset
|
454 radeon_fifo_wait (64); |
22691 | 455 |
456 for (i=0; i<2000000; i++) { | |
457 if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) { | |
458 radeon_engine_flush (); | |
459 return; | |
460 } | |
461 } | |
462 } | |
463 | |
464 #if 0 | |
465 static void __init radeon_vid_save_state( void ) | |
466 { | |
467 size_t i; | |
468 for(i=0;i<sizeof(vregs)/sizeof(video_registers_t);i++) | |
469 vregs[i].value = INREG(vregs[i].name); | |
470 } | |
471 | |
472 static void __exit radeon_vid_restore_state( void ) | |
473 { | |
474 size_t i; | |
475 radeon_fifo_wait(2); | |
476 OUTREG(OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK); | |
477 radeon_engine_idle(); | |
478 while(!(INREG(OV0_REG_LOAD_CNTL)®_LD_CTL_LOCK_READBACK)); | |
479 radeon_fifo_wait(15); | |
480 for(i=0;i<sizeof(vregs)/sizeof(video_registers_t);i++) | |
481 { | |
482 radeon_fifo_wait(1); | |
483 OUTREG(vregs[i].name,vregs[i].value); | |
484 } | |
485 OUTREG(OV0_REG_LOAD_CNTL, 0); | |
486 } | |
487 #endif | |
488 #ifdef DEBUG | |
489 static void radeon_vid_dump_regs( void ) | |
490 { | |
491 size_t i; | |
492 printk(RVID_MSG"*** Begin of OV0 registers dump ***\n"); | |
493 for(i=0;i<sizeof(vregs)/sizeof(video_registers_t);i++) | |
494 printk(RVID_MSG"%s = %08X\n",vregs[i].sname,INREG(vregs[i].name)); | |
495 printk(RVID_MSG"*** End of OV0 registers dump ***\n"); | |
496 } | |
497 #endif | |
498 | |
499 #ifdef RADEON_FPU | |
500 /* Reference color space transform data */ | |
501 typedef struct tagREF_TRANSFORM | |
502 { | |
503 float RefLuma; | |
504 float RefRCb; | |
505 float RefRCr; | |
506 float RefGCb; | |
507 float RefGCr; | |
508 float RefBCb; | |
509 float RefBCr; | |
510 } REF_TRANSFORM; | |
511 | |
512 /* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces */ | |
513 REF_TRANSFORM trans[2] = | |
514 { | |
515 {1.1678, 0.0, 1.6007, -0.3929, -0.8154, 2.0232, 0.0}, /* BT.601 */ | |
516 {1.1678, 0.0, 1.7980, -0.2139, -0.5345, 2.1186, 0.0} /* BT.709 */ | |
517 }; | |
518 /**************************************************************************** | |
519 * SetTransform * | |
520 * Function: Calculates and sets color space transform from supplied * | |
521 * reference transform, gamma, brightness, contrast, hue and * | |
522 * saturation. * | |
523 * Inputs: bright - brightness * | |
524 * cont - contrast * | |
525 * sat - saturation * | |
526 * hue - hue * | |
527 * ref - index to the table of refernce transforms * | |
528 * Outputs: NONE * | |
529 ****************************************************************************/ | |
530 | |
531 static void radeon_set_transform(float bright, float cont, float sat, | |
532 float hue, unsigned ref) | |
533 { | |
534 float OvHueSin, OvHueCos; | |
535 float CAdjLuma, CAdjOff; | |
536 float CAdjRCb, CAdjRCr; | |
537 float CAdjGCb, CAdjGCr; | |
538 float CAdjBCb, CAdjBCr; | |
539 float OvLuma, OvROff, OvGOff, OvBOff; | |
540 float OvRCb, OvRCr; | |
541 float OvGCb, OvGCr; | |
542 float OvBCb, OvBCr; | |
543 float Loff = 64.0; | |
544 float Coff = 512.0f; | |
545 | |
546 u32 dwOvLuma, dwOvROff, dwOvGOff, dwOvBOff; | |
547 u32 dwOvRCb, dwOvRCr; | |
548 u32 dwOvGCb, dwOvGCr; | |
549 u32 dwOvBCb, dwOvBCr; | |
550 | |
551 if (ref >= 2) return; | |
552 | |
553 OvHueSin = sin((double)hue); | |
554 OvHueCos = cos((double)hue); | |
555 | |
556 CAdjLuma = cont * trans[ref].RefLuma; | |
557 CAdjOff = cont * trans[ref].RefLuma * bright * 1023.0; | |
558 | |
559 CAdjRCb = sat * -OvHueSin * trans[ref].RefRCr; | |
560 CAdjRCr = sat * OvHueCos * trans[ref].RefRCr; | |
561 CAdjGCb = sat * (OvHueCos * trans[ref].RefGCb - OvHueSin * trans[ref].RefGCr); | |
562 CAdjGCr = sat * (OvHueSin * trans[ref].RefGCb + OvHueCos * trans[ref].RefGCr); | |
563 CAdjBCb = sat * OvHueCos * trans[ref].RefBCb; | |
564 CAdjBCr = sat * OvHueSin * trans[ref].RefBCb; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
565 |
22691 | 566 #if 0 /* default constants */ |
567 CAdjLuma = 1.16455078125; | |
568 | |
569 CAdjRCb = 0.0; | |
570 CAdjRCr = 1.59619140625; | |
571 CAdjGCb = -0.39111328125; | |
572 CAdjGCr = -0.8125; | |
573 CAdjBCb = 2.01708984375; | |
574 CAdjBCr = 0; | |
575 #endif | |
576 OvLuma = CAdjLuma; | |
577 OvRCb = CAdjRCb; | |
578 OvRCr = CAdjRCr; | |
579 OvGCb = CAdjGCb; | |
580 OvGCr = CAdjGCr; | |
581 OvBCb = CAdjBCb; | |
582 OvBCr = CAdjBCr; | |
583 OvROff = CAdjOff - | |
584 OvLuma * Loff - (OvRCb + OvRCr) * Coff; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
585 OvGOff = CAdjOff - |
22691 | 586 OvLuma * Loff - (OvGCb + OvGCr) * Coff; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
587 OvBOff = CAdjOff - |
22691 | 588 OvLuma * Loff - (OvBCb + OvBCr) * Coff; |
589 #if 0 /* default constants */ | |
590 OvROff = -888.5; | |
591 OvGOff = 545; | |
592 OvBOff = -1104; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
593 #endif |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
594 |
22691 | 595 dwOvROff = ((int)(OvROff * 2.0)) & 0x1fff; |
596 dwOvGOff = (int)(OvGOff * 2.0) & 0x1fff; | |
597 dwOvBOff = (int)(OvBOff * 2.0) & 0x1fff; | |
598 if(!IsR200) | |
599 { | |
600 dwOvLuma =(((int)(OvLuma * 2048.0))&0x7fff)<<17; | |
601 dwOvRCb = (((int)(OvRCb * 2048.0))&0x7fff)<<1; | |
602 dwOvRCr = (((int)(OvRCr * 2048.0))&0x7fff)<<17; | |
603 dwOvGCb = (((int)(OvGCb * 2048.0))&0x7fff)<<1; | |
604 dwOvGCr = (((int)(OvGCr * 2048.0))&0x7fff)<<17; | |
605 dwOvBCb = (((int)(OvBCb * 2048.0))&0x7fff)<<1; | |
606 dwOvBCr = (((int)(OvBCr * 2048.0))&0x7fff)<<17; | |
607 } | |
608 else | |
609 { | |
610 dwOvLuma = (((int)(OvLuma * 256.0))&0x7ff)<<20; | |
611 dwOvRCb = (((int)(OvRCb * 256.0))&0x7ff)<<4; | |
612 dwOvRCr = (((int)(OvRCr * 256.0))&0x7ff)<<20; | |
613 dwOvGCb = (((int)(OvGCb * 256.0))&0x7ff)<<4; | |
614 dwOvGCr = (((int)(OvGCr * 256.0))&0x7ff)<<20; | |
615 dwOvBCb = (((int)(OvBCb * 256.0))&0x7ff)<<4; | |
616 dwOvBCr = (((int)(OvBCr * 256.0))&0x7ff)<<20; | |
617 } | |
618 | |
619 OUTREG(OV0_LIN_TRANS_A, dwOvRCb | dwOvLuma); | |
620 OUTREG(OV0_LIN_TRANS_B, dwOvROff | dwOvRCr); | |
621 OUTREG(OV0_LIN_TRANS_C, dwOvGCb | dwOvLuma); | |
622 OUTREG(OV0_LIN_TRANS_D, dwOvGOff | dwOvGCr); | |
623 OUTREG(OV0_LIN_TRANS_E, dwOvBCb | dwOvLuma); | |
624 OUTREG(OV0_LIN_TRANS_F, dwOvBOff | dwOvBCr); | |
625 } | |
626 #endif | |
627 | |
628 #ifndef RAGE128 | |
629 /* Gamma curve definition */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
630 typedef struct |
22691 | 631 { |
632 unsigned int gammaReg; | |
633 unsigned int gammaSlope; | |
634 unsigned int gammaOffset; | |
635 }GAMMA_SETTINGS; | |
636 | |
637 /* Recommended gamma curve parameters */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
638 GAMMA_SETTINGS r200_def_gamma[18] = |
22691 | 639 { |
640 {OV0_GAMMA_0_F, 0x100, 0x0000}, | |
641 {OV0_GAMMA_10_1F, 0x100, 0x0020}, | |
642 {OV0_GAMMA_20_3F, 0x100, 0x0040}, | |
643 {OV0_GAMMA_40_7F, 0x100, 0x0080}, | |
644 {OV0_GAMMA_80_BF, 0x100, 0x0100}, | |
645 {OV0_GAMMA_C0_FF, 0x100, 0x0100}, | |
646 {OV0_GAMMA_100_13F, 0x100, 0x0200}, | |
647 {OV0_GAMMA_140_17F, 0x100, 0x0200}, | |
648 {OV0_GAMMA_180_1BF, 0x100, 0x0300}, | |
649 {OV0_GAMMA_1C0_1FF, 0x100, 0x0300}, | |
650 {OV0_GAMMA_200_23F, 0x100, 0x0400}, | |
651 {OV0_GAMMA_240_27F, 0x100, 0x0400}, | |
652 {OV0_GAMMA_280_2BF, 0x100, 0x0500}, | |
653 {OV0_GAMMA_2C0_2FF, 0x100, 0x0500}, | |
654 {OV0_GAMMA_300_33F, 0x100, 0x0600}, | |
655 {OV0_GAMMA_340_37F, 0x100, 0x0600}, | |
656 {OV0_GAMMA_380_3BF, 0x100, 0x0700}, | |
657 {OV0_GAMMA_3C0_3FF, 0x100, 0x0700} | |
658 }; | |
659 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
660 GAMMA_SETTINGS r100_def_gamma[6] = |
22691 | 661 { |
662 {OV0_GAMMA_0_F, 0x100, 0x0000}, | |
663 {OV0_GAMMA_10_1F, 0x100, 0x0020}, | |
664 {OV0_GAMMA_20_3F, 0x100, 0x0040}, | |
665 {OV0_GAMMA_40_7F, 0x100, 0x0080}, | |
666 {OV0_GAMMA_380_3BF, 0x100, 0x0100}, | |
667 {OV0_GAMMA_3C0_3FF, 0x100, 0x0100} | |
668 }; | |
669 | |
670 static void make_default_gamma_correction( void ) | |
671 { | |
672 size_t i; | |
673 if(!IsR200){ | |
674 OUTREG(OV0_LIN_TRANS_A, 0x12A00000); | |
675 OUTREG(OV0_LIN_TRANS_B, 0x199018FE); | |
676 OUTREG(OV0_LIN_TRANS_C, 0x12A0F9B0); | |
677 OUTREG(OV0_LIN_TRANS_D, 0xF2F0043B); | |
678 OUTREG(OV0_LIN_TRANS_E, 0x12A02050); | |
679 OUTREG(OV0_LIN_TRANS_F, 0x0000174E); | |
680 for(i=0; i<6; i++){ | |
681 OUTREG(r100_def_gamma[i].gammaReg, | |
682 (r100_def_gamma[i].gammaSlope<<16) | | |
683 r100_def_gamma[i].gammaOffset); | |
684 } | |
685 } | |
686 else{ | |
687 OUTREG(OV0_LIN_TRANS_A, 0x12a00000); | |
688 OUTREG(OV0_LIN_TRANS_B, 0x1990190e); | |
689 OUTREG(OV0_LIN_TRANS_C, 0x12a0f9c0); | |
690 OUTREG(OV0_LIN_TRANS_D, 0xf3000442); | |
691 OUTREG(OV0_LIN_TRANS_E, 0x12a02040); | |
692 OUTREG(OV0_LIN_TRANS_F, 0x175f); | |
693 | |
694 /* Default Gamma, | |
695 Of 18 segments for gamma cure, all segments in R200 are programmable, | |
696 while only lower 4 and upper 2 segments are programmable in Radeon*/ | |
697 for(i=0; i<18; i++){ | |
698 OUTREG(r200_def_gamma[i].gammaReg, | |
699 (r200_def_gamma[i].gammaSlope<<16) | | |
700 r200_def_gamma[i].gammaOffset); | |
701 } | |
702 } | |
703 } | |
704 #endif | |
705 | |
706 static void radeon_vid_stop_video( void ) | |
707 { | |
708 radeon_engine_idle(); | |
709 OUTREG(OV0_SCALE_CNTL, SCALER_SOFT_RESET); | |
710 OUTREG(OV0_EXCLUSIVE_HORZ, 0); | |
711 OUTREG(OV0_AUTO_FLIP_CNTL, 0); /* maybe */ | |
712 OUTREG(OV0_FILTER_CNTL, FILTER_HARDCODED_COEF); | |
713 OUTREG(OV0_KEY_CNTL, GRAPHIC_KEY_FN_NE); | |
714 OUTREG(OV0_TEST, 0); | |
715 } | |
716 | |
717 static void radeon_vid_display_video( void ) | |
718 { | |
719 int bes_flags; | |
720 radeon_fifo_wait(2); | |
721 OUTREG(OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK); | |
722 radeon_engine_idle(); | |
723 while(!(INREG(OV0_REG_LOAD_CNTL)®_LD_CTL_LOCK_READBACK)); | |
724 radeon_fifo_wait(15); | |
725 OUTREG(OV0_AUTO_FLIP_CNTL,OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD); | |
726 OUTREG(OV0_AUTO_FLIP_CNTL,(INREG(OV0_AUTO_FLIP_CNTL)^OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE)); | |
727 OUTREG(OV0_AUTO_FLIP_CNTL,(INREG(OV0_AUTO_FLIP_CNTL)^OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE)); | |
728 | |
729 OUTREG(OV0_DEINTERLACE_PATTERN,besr.deinterlace_pattern); | |
730 #ifdef RAGE128 | |
731 OUTREG(OV0_COLOUR_CNTL, (besr.brightness & 0x7f) | | |
732 (besr.saturation << 8) | | |
733 (besr.saturation << 16)); | |
734 #endif | |
735 radeon_fifo_wait(2); | |
736 if(besr.ckey_on) | |
737 { | |
738 OUTREG(OV0_GRAPHICS_KEY_MSK, besr.graphics_key_msk); | |
739 OUTREG(OV0_GRAPHICS_KEY_CLR, besr.graphics_key_clr); | |
740 OUTREG(OV0_KEY_CNTL,GRAPHIC_KEY_FN_EQ|VIDEO_KEY_FN_FALSE|CMP_MIX_OR); | |
741 } | |
742 else | |
743 { | |
744 OUTREG(OV0_GRAPHICS_KEY_MSK, 0ULL); | |
745 OUTREG(OV0_GRAPHICS_KEY_CLR, 0ULL); | |
746 OUTREG(OV0_KEY_CNTL,GRAPHIC_KEY_FN_NE); | |
747 } | |
748 | |
749 OUTREG(OV0_H_INC, besr.h_inc); | |
750 OUTREG(OV0_STEP_BY, besr.step_by); | |
751 OUTREG(OV0_Y_X_START, besr.y_x_start); | |
752 OUTREG(OV0_Y_X_END, besr.y_x_end); | |
753 OUTREG(OV0_V_INC, besr.v_inc); | |
754 OUTREG(OV0_P1_BLANK_LINES_AT_TOP, besr.p1_blank_lines_at_top); | |
755 OUTREG(OV0_P23_BLANK_LINES_AT_TOP, besr.p23_blank_lines_at_top); | |
756 OUTREG(OV0_VID_BUF_PITCH0_VALUE, besr.vid_buf_pitch0_value); | |
757 OUTREG(OV0_VID_BUF_PITCH1_VALUE, besr.vid_buf_pitch1_value); | |
758 OUTREG(OV0_P1_X_START_END, besr.p1_x_start_end); | |
759 OUTREG(OV0_P2_X_START_END, besr.p2_x_start_end); | |
760 OUTREG(OV0_P3_X_START_END, besr.p3_x_start_end); | |
761 #ifdef RADEON | |
762 OUTREG(OV0_BASE_ADDR, besr.base_addr); | |
763 #endif | |
764 OUTREG(OV0_VID_BUF0_BASE_ADRS, besr.vid_buf0_base_adrs); | |
765 OUTREG(OV0_VID_BUF1_BASE_ADRS, besr.vid_buf1_base_adrs); | |
766 OUTREG(OV0_VID_BUF2_BASE_ADRS, besr.vid_buf2_base_adrs); | |
767 radeon_fifo_wait(9); | |
768 OUTREG(OV0_VID_BUF3_BASE_ADRS, besr.vid_buf3_base_adrs); | |
769 OUTREG(OV0_VID_BUF4_BASE_ADRS, besr.vid_buf4_base_adrs); | |
770 OUTREG(OV0_VID_BUF5_BASE_ADRS, besr.vid_buf5_base_adrs); | |
771 OUTREG(OV0_P1_V_ACCUM_INIT, besr.p1_v_accum_init); | |
772 OUTREG(OV0_P1_H_ACCUM_INIT, besr.p1_h_accum_init); | |
773 OUTREG(OV0_P23_H_ACCUM_INIT, besr.p23_h_accum_init); | |
774 OUTREG(OV0_P23_V_ACCUM_INIT, besr.p23_v_accum_init); | |
775 | |
776 #ifdef RADEON | |
777 bes_flags = SCALER_ENABLE | | |
778 SCALER_SMART_SWITCH; | |
779 // SCALER_HORZ_PICK_NEAREST; | |
780 #else | |
781 bes_flags = SCALER_ENABLE | | |
782 SCALER_SMART_SWITCH | | |
783 SCALER_Y2R_TEMP | | |
784 SCALER_PIX_EXPAND; | |
785 #endif | |
786 if(besr.double_buff) bes_flags |= SCALER_DOUBLE_BUFFER; | |
787 if(besr.deinterlace_on) bes_flags |= SCALER_ADAPTIVE_DEINT; | |
788 #ifdef RAGE128 | |
789 bes_flags |= SCALER_BURST_PER_PLANE; | |
790 #endif | |
791 switch(besr.fourcc) | |
792 { | |
793 case IMGFMT_RGB15: | |
794 case IMGFMT_BGR15: bes_flags |= SCALER_SOURCE_15BPP; break; | |
795 case IMGFMT_RGB16: | |
796 case IMGFMT_BGR16: bes_flags |= SCALER_SOURCE_16BPP; break; | |
797 case IMGFMT_RGB24: | |
798 case IMGFMT_BGR24: bes_flags |= SCALER_SOURCE_24BPP; break; | |
799 case IMGFMT_RGB32: | |
800 case IMGFMT_BGR32: bes_flags |= SCALER_SOURCE_32BPP; break; | |
801 /* 4:1:0*/ | |
802 case IMGFMT_IF09: | |
803 case IMGFMT_YVU9: bes_flags |= SCALER_SOURCE_YUV9; break; | |
804 /* 4:2:0 */ | |
805 case IMGFMT_IYUV: | |
806 case IMGFMT_I420: | |
807 case IMGFMT_YV12: bes_flags |= SCALER_SOURCE_YUV12; | |
808 break; | |
809 /* 4:2:2 */ | |
810 case IMGFMT_UYVY: bes_flags |= SCALER_SOURCE_YVYU422; break; | |
811 case IMGFMT_YUY2: | |
812 default: bes_flags |= SCALER_SOURCE_VYUY422; break; | |
813 } | |
814 OUTREG(OV0_SCALE_CNTL, bes_flags); | |
815 OUTREG(OV0_REG_LOAD_CNTL, 0); | |
816 #ifdef DEBUG | |
817 radeon_vid_dump_regs(); | |
818 #endif | |
819 } | |
820 | |
821 void radeon_vid_set_color_key(int ckey_on, uint8_t R, uint8_t G, uint8_t B) | |
822 { | |
823 besr.ckey_on = ckey_on; | |
824 besr.graphics_key_msk=(1ULL<<radeon_vid_get_dbpp()) - 1; | |
825 besr.graphics_key_clr=(R<<16)|(G<<8)|(B)|(0x00 << 24); | |
826 } | |
827 | |
828 | |
829 #define XXX_SRC_X 0 | |
830 #define XXX_SRC_Y 0 | |
831 | |
832 static int radeon_vid_init_video( mga_vid_config_t *config ) | |
833 { | |
834 uint32_t tmp,src_w,src_h,pitch,h_inc,step_by,left,leftUV,top; | |
835 int is_420; | |
836 RTRACE(RVID_MSG"usr_config: version = %x format=%x card=%x ram=%u src(%ux%u) dest(%u:%ux%u:%u) frame_size=%u num_frames=%u\n" | |
837 ,(uint32_t)config->version | |
838 ,(uint32_t)config->format | |
839 ,(uint32_t)config->card_type | |
840 ,(uint32_t)config->ram_size | |
841 ,(uint32_t)config->src_width | |
842 ,(uint32_t)config->src_height | |
843 ,(uint32_t)config->x_org | |
844 ,(uint32_t)config->y_org | |
845 ,(uint32_t)config->dest_width | |
846 ,(uint32_t)config->dest_height | |
847 ,(uint32_t)config->frame_size | |
848 ,(uint32_t)config->num_frames); | |
849 radeon_vid_stop_video(); | |
850 left = XXX_SRC_X << 16; | |
851 top = XXX_SRC_Y << 16; | |
852 src_h = config->src_height; | |
853 src_w = config->src_width; | |
854 switch(config->format) | |
855 { | |
856 case IMGFMT_RGB15: | |
857 case IMGFMT_BGR15: | |
858 case IMGFMT_RGB16: | |
859 case IMGFMT_BGR16: | |
860 case IMGFMT_RGB24: | |
861 case IMGFMT_BGR24: | |
862 case IMGFMT_RGB32: | |
863 case IMGFMT_BGR32: | |
864 /* 4:1:0 */ | |
865 case IMGFMT_IF09: | |
866 case IMGFMT_YVU9: | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
867 /* 4:2:0 */ |
22691 | 868 case IMGFMT_IYUV: |
869 case IMGFMT_YV12: | |
870 case IMGFMT_I420: | |
871 /* 4:2:2 */ | |
872 case IMGFMT_UYVY: | |
873 case IMGFMT_YUY2: | |
874 break; | |
875 default: | |
876 printk(RVID_MSG"Unsupported pixel format: 0x%X\n",config->format); | |
877 return -1; | |
878 } | |
879 is_420 = 0; | |
880 if(config->format == IMGFMT_YV12 || | |
881 config->format == IMGFMT_I420 || | |
882 config->format == IMGFMT_IYUV) is_420 = 1; | |
883 switch(config->format) | |
884 { | |
885 /* 4:1:0 */ | |
886 case IMGFMT_YVU9: | |
887 case IMGFMT_IF09: | |
888 /* 4:2:0 */ | |
889 case IMGFMT_IYUV: | |
890 case IMGFMT_YV12: | |
891 case IMGFMT_I420: pitch = (src_w + 31) & ~31; break; | |
892 /* 4:2:2 */ | |
893 default: | |
894 case IMGFMT_UYVY: | |
895 case IMGFMT_YUY2: | |
896 case IMGFMT_RGB15: | |
897 case IMGFMT_BGR15: | |
898 case IMGFMT_RGB16: | |
899 case IMGFMT_BGR16: pitch = ((src_w*2) + 15) & ~15; break; | |
900 case IMGFMT_RGB24: | |
901 case IMGFMT_BGR24: pitch = ((src_w*3) + 15) & ~15; break; | |
902 case IMGFMT_RGB32: | |
903 case IMGFMT_BGR32: pitch = ((src_w*4) + 15) & ~15; break; | |
904 } | |
905 if(radeon_is_dbl_scan()) config->dest_height *= 2; | |
906 else | |
907 if(radeon_is_interlace()) config->dest_height /= 2; | |
908 besr.dest_bpp = radeon_vid_get_dbpp(); | |
909 besr.fourcc = config->format; | |
910 besr.v_inc = (src_h << 20) / config->dest_height; | |
911 h_inc = (src_w << 12) / config->dest_width; | |
912 step_by = 1; | |
913 | |
914 while(h_inc >= (2 << 12)) { | |
915 step_by++; | |
916 h_inc >>= 1; | |
917 } | |
918 | |
919 /* keep everything in 16.16 */ | |
920 besr.base_addr = radeon_mem_base; | |
921 if(is_420) | |
922 { | |
923 uint32_t d1line,d2line,d3line; | |
924 d1line = top*pitch; | |
925 d2line = src_h*pitch+(d1line>>1); | |
926 d3line = d2line+((src_h*pitch)>>2); | |
927 d1line += (left >> 16) & ~15; | |
928 d2line += (left >> 17) & ~15; | |
929 d3line += (left >> 17) & ~15; | |
930 besr.vid_buf0_base_adrs=((radeon_overlay_off+d1line)&VIF_BUF0_BASE_ADRS_MASK); | |
931 besr.vid_buf1_base_adrs=((radeon_overlay_off+d2line)&VIF_BUF1_BASE_ADRS_MASK)|VIF_BUF1_PITCH_SEL; | |
932 besr.vid_buf2_base_adrs=((radeon_overlay_off+d3line)&VIF_BUF2_BASE_ADRS_MASK)|VIF_BUF2_PITCH_SEL; | |
933 if(besr.fourcc == IMGFMT_I420 || besr.fourcc == IMGFMT_IYUV) | |
934 { | |
935 uint32_t tmp; | |
936 tmp = besr.vid_buf1_base_adrs; | |
937 besr.vid_buf1_base_adrs = besr.vid_buf2_base_adrs; | |
938 besr.vid_buf2_base_adrs = tmp; | |
939 } | |
940 } | |
941 else | |
942 { | |
943 besr.vid_buf0_base_adrs = radeon_overlay_off; | |
944 besr.vid_buf0_base_adrs += ((left & ~7) << 1)&VIF_BUF0_BASE_ADRS_MASK; | |
945 besr.vid_buf1_base_adrs = besr.vid_buf0_base_adrs; | |
946 besr.vid_buf2_base_adrs = besr.vid_buf0_base_adrs; | |
947 } | |
948 besr.vid_buf3_base_adrs = besr.vid_buf0_base_adrs+config->frame_size; | |
949 besr.vid_buf4_base_adrs = besr.vid_buf1_base_adrs+config->frame_size; | |
950 besr.vid_buf5_base_adrs = besr.vid_buf2_base_adrs+config->frame_size; | |
951 | |
952 tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3); | |
953 besr.p1_h_accum_init = ((tmp << 4) & 0x000f8000) | | |
954 ((tmp << 12) & 0xf0000000); | |
955 | |
956 tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc << 2); | |
957 besr.p23_h_accum_init = ((tmp << 4) & 0x000f8000) | | |
958 ((tmp << 12) & 0x70000000); | |
959 tmp = (top & 0x0000ffff) + 0x00018000; | |
960 besr.p1_v_accum_init = ((tmp << 4) & OV0_P1_V_ACCUM_INIT_MASK) | |
961 |(OV0_P1_MAX_LN_IN_PER_LN_OUT & 1); | |
962 | |
963 tmp = ((top >> 1) & 0x0000ffff) + 0x00018000; | |
964 besr.p23_v_accum_init = is_420 ? ((tmp << 4) & OV0_P23_V_ACCUM_INIT_MASK) | |
965 |(OV0_P23_MAX_LN_IN_PER_LN_OUT & 1) : 0; | |
966 | |
967 leftUV = (left >> 17) & 15; | |
968 left = (left >> 16) & 15; | |
969 besr.h_inc = h_inc | ((h_inc >> 1) << 16); | |
970 besr.step_by = step_by | (step_by << 8); | |
971 besr.y_x_start = (config->x_org+X_ADJUST) | (config->y_org << 16); | |
972 besr.y_x_end = (config->x_org + config->dest_width+X_ADJUST) | ((config->y_org + config->dest_height) << 16); | |
973 besr.p1_blank_lines_at_top = P1_BLNK_LN_AT_TOP_M1_MASK|((src_h-1)<<16); | |
974 if(is_420) | |
975 { | |
976 src_h = (src_h + 1) >> 1; | |
977 besr.p23_blank_lines_at_top = P23_BLNK_LN_AT_TOP_M1_MASK|((src_h-1)<<16); | |
978 } | |
979 else besr.p23_blank_lines_at_top = 0; | |
980 besr.vid_buf_pitch0_value = pitch; | |
981 besr.vid_buf_pitch1_value = is_420 ? pitch>>1 : pitch; | |
982 besr.p1_x_start_end = (src_w+left-1)|(left<<16); | |
983 src_w>>=1; | |
984 besr.p2_x_start_end = (src_w+left-1)|(leftUV<<16); | |
985 besr.p3_x_start_end = besr.p2_x_start_end; | |
986 return 0; | |
987 } | |
988 | |
989 static void radeon_vid_frame_sel(int frame) | |
990 { | |
991 uint32_t off0,off1,off2; | |
992 if(!besr.double_buff) return; | |
993 if(frame%2) | |
994 { | |
995 off0 = besr.vid_buf3_base_adrs; | |
996 off1 = besr.vid_buf4_base_adrs; | |
997 off2 = besr.vid_buf5_base_adrs; | |
998 } | |
999 else | |
1000 { | |
1001 off0 = besr.vid_buf0_base_adrs; | |
1002 off1 = besr.vid_buf1_base_adrs; | |
1003 off2 = besr.vid_buf2_base_adrs; | |
1004 } | |
1005 OUTREG(OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK); | |
1006 while(!(INREG(OV0_REG_LOAD_CNTL)®_LD_CTL_LOCK_READBACK)); | |
1007 OUTREG(OV0_VID_BUF0_BASE_ADRS, off0); | |
1008 OUTREG(OV0_VID_BUF1_BASE_ADRS, off1); | |
1009 OUTREG(OV0_VID_BUF2_BASE_ADRS, off2); | |
1010 OUTREG(OV0_REG_LOAD_CNTL, 0); | |
1011 } | |
1012 | |
1013 static void radeon_vid_make_default(void) | |
1014 { | |
1015 #ifdef RAGE128 | |
1016 OUTREG(OV0_COLOUR_CNTL,0x00101000UL); /* Default brihgtness and saturation for Rage128 */ | |
1017 #else | |
1018 make_default_gamma_correction(); | |
1019 #endif | |
1020 besr.deinterlace_pattern = 0x900AAAAA; | |
1021 OUTREG(OV0_DEINTERLACE_PATTERN,besr.deinterlace_pattern); | |
1022 besr.deinterlace_on=1; | |
1023 besr.double_buff=1; | |
1024 } | |
1025 | |
1026 | |
1027 static void radeon_vid_preset(void) | |
1028 { | |
1029 #ifdef RAGE128 | |
1030 unsigned tmp; | |
1031 tmp = INREG(OV0_COLOUR_CNTL); | |
1032 besr.saturation = (tmp>>8)&0x1f; | |
1033 besr.brightness = tmp & 0x7f; | |
1034 #endif | |
1035 besr.graphics_key_clr = INREG(OV0_GRAPHICS_KEY_CLR); | |
1036 besr.deinterlace_pattern = INREG(OV0_DEINTERLACE_PATTERN); | |
1037 } | |
1038 | |
1039 static int video_on = 0; | |
1040 | |
1041 static int radeon_vid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | |
1042 { | |
1043 int frame; | |
1044 | |
1045 switch(cmd) | |
1046 { | |
1047 case MGA_VID_CONFIG: | |
1048 RTRACE(RVID_MSG"radeon_mmio_base = %p\n",radeon_mmio_base); | |
1049 RTRACE(RVID_MSG"radeon_mem_base = %08x\n",radeon_mem_base); | |
1050 RTRACE(RVID_MSG"Received configuration\n"); | |
1051 | |
1052 if(copy_from_user(&radeon_config,(mga_vid_config_t*) arg,sizeof(mga_vid_config_t))) | |
1053 { | |
1054 printk(RVID_MSG"failed copy from userspace\n"); | |
1055 return -EFAULT; | |
1056 } | |
1057 if(radeon_config.version != MGA_VID_VERSION){ | |
1058 printk(RVID_MSG"incompatible version! driver: %X requested: %X\n",MGA_VID_VERSION,radeon_config.version); | |
1059 return -EFAULT; | |
1060 } | |
1061 | |
1062 if(radeon_config.frame_size==0 || radeon_config.frame_size>1024*768*2){ | |
1063 printk(RVID_MSG"illegal frame_size: %d\n",radeon_config.frame_size); | |
1064 return -EFAULT; | |
1065 } | |
1066 | |
1067 if(radeon_config.num_frames<1){ | |
1068 printk(RVID_MSG"illegal num_frames: %d\n",radeon_config.num_frames); | |
1069 return -EFAULT; | |
1070 } | |
1071 if(radeon_config.num_frames==1) besr.double_buff=0; | |
1072 if(!besr.double_buff) radeon_config.num_frames=1; | |
1073 else radeon_config.num_frames=2; | |
1074 radeon_config.card_type = 0; | |
1075 radeon_config.ram_size = radeon_ram_size; | |
1076 radeon_overlay_off = radeon_ram_size*0x100000 - radeon_config.frame_size*radeon_config.num_frames; | |
1077 radeon_overlay_off &= 0xffff0000; | |
1078 if(radeon_overlay_off < 0){ | |
1079 printk(RVID_MSG"not enough video memory. Need: %u has: %u\n",radeon_config.frame_size*radeon_config.num_frames,radeon_ram_size*0x100000); | |
1080 return -EFAULT; | |
1081 } | |
1082 RTRACE(RVID_MSG"using video overlay at offset %08X\n",radeon_overlay_off); | |
1083 if (copy_to_user((mga_vid_config_t *) arg, &radeon_config, sizeof(mga_vid_config_t))) | |
1084 { | |
1085 printk(RVID_MSG"failed copy to userspace\n"); | |
1086 return -EFAULT; | |
1087 } | |
1088 radeon_vid_set_color_key(radeon_config.colkey_on, | |
1089 radeon_config.colkey_red, | |
1090 radeon_config.colkey_green, | |
1091 radeon_config.colkey_blue); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
1092 if(swap_fourcc) radeon_config.format = swab32(radeon_config.format); |
22691 | 1093 printk(RVID_MSG"configuring for '%s' fourcc\n",fourcc_format_name(radeon_config.format)); |
1094 return radeon_vid_init_video(&radeon_config); | |
1095 break; | |
1096 | |
1097 case MGA_VID_ON: | |
1098 RTRACE(RVID_MSG"Video ON (ioctl)\n"); | |
1099 radeon_vid_display_video(); | |
1100 video_on = 1; | |
1101 break; | |
1102 | |
1103 case MGA_VID_OFF: | |
1104 RTRACE(RVID_MSG"Video OFF (ioctl)\n"); | |
1105 if(video_on) radeon_vid_stop_video(); | |
1106 video_on = 0; | |
1107 break; | |
1108 | |
1109 case MGA_VID_FSEL: | |
1110 if(copy_from_user(&frame,(int *) arg,sizeof(int))) | |
1111 { | |
1112 printk(RVID_MSG"FSEL failed copy from userspace\n"); | |
26759
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
1113 return -EFAULT; |
22691 | 1114 } |
1115 radeon_vid_frame_sel(frame); | |
1116 break; | |
1117 | |
1118 default: | |
1119 printk(RVID_MSG"Invalid ioctl\n"); | |
26759
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
1120 return -EINVAL; |
22691 | 1121 } |
1122 | |
1123 return 0; | |
1124 } | |
1125 | |
1126 struct ati_card_id_s | |
1127 { | |
1128 const int id; | |
1129 const char name[17]; | |
1130 }; | |
1131 | |
1132 const struct ati_card_id_s ati_card_ids[]= | |
1133 { | |
1134 #ifdef RAGE128 | |
1135 /* | |
1136 This driver should be compatible with Rage128 (pro) chips. | |
1137 (include adaptive deinterlacing!!!). | |
1138 Moreover: the same logic can be used with Mach64 chips. | |
1139 (I mean: mach64xx, 3d rage, 3d rage IIc, 3D rage pro, 3d rage mobility). | |
1140 but they are incompatible by i/o ports. So if enthusiasts will want | |
1141 then they can redefine OUTREG and INREG macros and redefine OV0_* | |
1142 constants. Also it seems that mach64 chips supports only: YUY2, YV12, UYVY | |
1143 fourccs (422 and 420 formats only). | |
1144 */ | |
1145 /* Rage128 Pro GL */ | |
1146 { PCI_DEVICE_ID_ATI_Rage128_PA, "R128Pro PA" }, | |
1147 { PCI_DEVICE_ID_ATI_Rage128_PB, "R128Pro PB" }, | |
1148 { PCI_DEVICE_ID_ATI_Rage128_PC, "R128Pro PC" }, | |
1149 { PCI_DEVICE_ID_ATI_Rage128_PD, "R128Pro PD" }, | |
1150 { PCI_DEVICE_ID_ATI_Rage128_PE, "R128Pro PE" }, | |
1151 { PCI_DEVICE_ID_ATI_RAGE128_PF, "R128Pro PF" }, | |
1152 /* Rage128 Pro VR */ | |
1153 { PCI_DEVICE_ID_ATI_RAGE128_PG, "R128Pro PG" }, | |
1154 { PCI_DEVICE_ID_ATI_RAGE128_PH, "R128Pro PH" }, | |
1155 { PCI_DEVICE_ID_ATI_RAGE128_PI, "R128Pro PI" }, | |
1156 { PCI_DEVICE_ID_ATI_RAGE128_PJ, "R128Pro PJ" }, | |
1157 { PCI_DEVICE_ID_ATI_RAGE128_PK, "R128Pro PK" }, | |
1158 { PCI_DEVICE_ID_ATI_RAGE128_PL, "R128Pro PL" }, | |
1159 { PCI_DEVICE_ID_ATI_RAGE128_PM, "R128Pro PM" }, | |
1160 { PCI_DEVICE_ID_ATI_RAGE128_PN, "R128Pro PN" }, | |
1161 { PCI_DEVICE_ID_ATI_RAGE128_PO, "R128Pro PO" }, | |
1162 { PCI_DEVICE_ID_ATI_RAGE128_PP, "R128Pro PP" }, | |
1163 { PCI_DEVICE_ID_ATI_RAGE128_PQ, "R128Pro PQ" }, | |
1164 { PCI_DEVICE_ID_ATI_RAGE128_PR, "R128Pro PR" }, | |
1165 { PCI_DEVICE_ID_ATI_RAGE128_TR, "R128Pro TR" }, | |
1166 { PCI_DEVICE_ID_ATI_RAGE128_PS, "R128Pro PS" }, | |
1167 { PCI_DEVICE_ID_ATI_RAGE128_PT, "R128Pro PT" }, | |
1168 { PCI_DEVICE_ID_ATI_RAGE128_PU, "R128Pro PU" }, | |
1169 { PCI_DEVICE_ID_ATI_RAGE128_PV, "R128Pro PV" }, | |
1170 { PCI_DEVICE_ID_ATI_RAGE128_PW, "R128Pro PW" }, | |
1171 { PCI_DEVICE_ID_ATI_RAGE128_PX, "R128Pro PX" }, | |
1172 /* Rage128 GL */ | |
1173 { PCI_DEVICE_ID_ATI_RAGE128_RE, "R128 RE" }, | |
1174 { PCI_DEVICE_ID_ATI_RAGE128_RF, "R128 RF" }, | |
1175 { PCI_DEVICE_ID_ATI_RAGE128_RG, "R128 RG" }, | |
1176 { PCI_DEVICE_ID_ATI_RAGE128_RH, "R128 RH" }, | |
1177 { PCI_DEVICE_ID_ATI_RAGE128_RI, "R128 RI" }, | |
1178 /* Rage128 VR */ | |
1179 { PCI_DEVICE_ID_ATI_RAGE128_RK, "R128 RK" }, | |
1180 { PCI_DEVICE_ID_ATI_RAGE128_RL, "R128 RL" }, | |
1181 { PCI_DEVICE_ID_ATI_RAGE128_RM, "R128 RM" }, | |
1182 { PCI_DEVICE_ID_ATI_RAGE128_RN, "R128 RN" }, | |
1183 { PCI_DEVICE_ID_ATI_RAGE128_RO, "R128 RO" }, | |
1184 /* Rage128 M3 */ | |
1185 { PCI_DEVICE_ID_ATI_RAGE128_LE, "R128 M3 LE" }, | |
1186 { PCI_DEVICE_ID_ATI_RAGE128_LF, "R128 M3 LF" }, | |
1187 /* Rage128 Pro Ultra */ | |
1188 { PCI_DEVICE_ID_ATI_RAGE128_U1, "R128Pro U1" }, | |
1189 { PCI_DEVICE_ID_ATI_RAGE128_U2, "R128Pro U2" }, | |
1190 { PCI_DEVICE_ID_ATI_RAGE128_U3, "R128Pro U3" } | |
1191 #else | |
1192 /* Radeons (indeed: Rage 256 Pro ;) */ | |
1193 { PCI_DEVICE_ID_RADEON_QD, "Radeon QD " }, | |
1194 { PCI_DEVICE_ID_RADEON_QE, "Radeon QE " }, | |
1195 { PCI_DEVICE_ID_RADEON_QF, "Radeon QF " }, | |
1196 { PCI_DEVICE_ID_RADEON_QG, "Radeon QG " }, | |
1197 { PCI_DEVICE_ID_RADEON_QY, "Radeon VE QY " }, | |
1198 { PCI_DEVICE_ID_RADEON_QZ, "Radeon VE QZ " }, | |
1199 { PCI_DEVICE_ID_RADEON_LY, "Radeon M6 LY " }, | |
1200 { PCI_DEVICE_ID_RADEON_LZ, "Radeon M6 LZ " }, | |
1201 { PCI_DEVICE_ID_RADEON_LW, "Radeon M7 LW " }, | |
1202 { PCI_DEVICE_ID_R200_QL, "Radeon2 8500 QL " }, | |
1203 { PCI_DEVICE_ID_R200_BB, "Radeon2 8500 AIW" }, | |
1204 { PCI_DEVICE_ID_RV200_QW, "Radeon2 7500 QW " } | |
1205 #endif | |
1206 }; | |
1207 | |
1208 static int detected_chip; | |
1209 | |
1210 static int __init radeon_vid_config_card(void) | |
1211 { | |
1212 struct pci_dev *dev = NULL; | |
1213 size_t i; | |
1214 | |
1215 for(i=0;i<sizeof(ati_card_ids)/sizeof(struct ati_card_id_s);i++) | |
1216 if((dev=pci_find_device(PCI_VENDOR_ID_ATI, ati_card_ids[i].id, NULL))) | |
1217 break; | |
1218 if(!dev) | |
1219 { | |
1220 printk(RVID_MSG"No supported cards found\n"); | |
1221 return FALSE; | |
1222 } | |
1223 | |
1224 radeon_mmio_base = ioremap_nocache(pci_resource_start (dev, 2),RADEON_REGSIZE); | |
1225 radeon_mem_base = dev->resource[0].start; | |
1226 | |
1227 RTRACE(RVID_MSG"MMIO at 0x%p\n", radeon_mmio_base); | |
1228 RTRACE(RVID_MSG"Frame Buffer at 0x%08x\n", radeon_mem_base); | |
1229 | |
1230 /* video memory size */ | |
1231 radeon_ram_size = INREG(CONFIG_MEMSIZE); | |
1232 | |
1233 /* mem size is bits [28:0], mask off the rest. Range: from 1Mb up to 512 Mb */ | |
1234 radeon_ram_size &= CONFIG_MEMSIZE_MASK; | |
1235 radeon_ram_size /= 0x100000; | |
1236 detected_chip = i; | |
1237 printk(RVID_MSG"Found %s (%uMb memory)\n",ati_card_ids[i].name,radeon_ram_size); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
1238 #ifndef RAGE128 |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
1239 if(ati_card_ids[i].id == PCI_DEVICE_ID_R200_QL || |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
1240 ati_card_ids[i].id == PCI_DEVICE_ID_R200_BB || |
22691 | 1241 ati_card_ids[i].id == PCI_DEVICE_ID_RV200_QW) IsR200 = 1; |
1242 #endif | |
1243 return TRUE; | |
1244 } | |
1245 | |
1246 #define PARAM_BRIGHTNESS "brightness=" | |
1247 #define PARAM_SATURATION "saturation=" | |
1248 #define PARAM_CONTRAST "contrast=" | |
1249 #define PARAM_HUE "hue=" | |
1250 #define PARAM_DOUBLE_BUFF "double_buff=" | |
1251 #define PARAM_DEINTERLACE "deinterlace=" | |
1252 #define PARAM_DEINTERLACE_PATTERN "deinterlace_pattern=" | |
1253 #ifdef RADEON_FPU | |
1254 static int ovBrightness=0, ovSaturation=0, ovContrast=0, ovHue=0, ov_trans_idx=0; | |
1255 #endif | |
1256 | |
1257 static void radeon_param_buff_fill( void ) | |
1258 { | |
1259 unsigned len,saturation; | |
1260 int8_t brightness; | |
1261 brightness = besr.brightness & 0x7f; | |
1262 /* FIXME: It's probably x86 specific convertion. But it doesn't matter | |
1263 for general logic - only for printing value */ | |
1264 if(brightness > 63) brightness = (((~besr.brightness) & 0x3f)+1) * (-1); | |
1265 saturation = besr.saturation; | |
1266 len = 0; | |
1267 len += sprintf(&radeon_param_buff[len],"Interface version: %04X\nDriver version: %s\n",MGA_VID_VERSION,RADEON_VID_VERSION); | |
1268 len += sprintf(&radeon_param_buff[len],"Chip: %s\n",ati_card_ids[detected_chip].name); | |
1269 len += sprintf(&radeon_param_buff[len],"Memory: %x:%x\n",radeon_mem_base,radeon_ram_size*0x100000); | |
1270 len += sprintf(&radeon_param_buff[len],"MMIO: %p\n",radeon_mmio_base); | |
1271 len += sprintf(&radeon_param_buff[len],"Overlay offset: %x\n",radeon_overlay_off); | |
1272 #ifdef CONFIG_MTRR | |
1273 len += sprintf(&radeon_param_buff[len],"Tune MTRR: %s\n",mtrr?"on":"off"); | |
1274 #endif | |
1275 if(besr.ckey_on) len += sprintf(&radeon_param_buff[len],"Last used color_key=%X (mask=%X)\n",besr.graphics_key_clr,besr.graphics_key_msk); | |
1276 len += sprintf(&radeon_param_buff[len],"Swapped fourcc: %s\n",swap_fourcc?"on":"off"); | |
1277 len += sprintf(&radeon_param_buff[len],"Last BPP: %u\n",besr.dest_bpp); | |
1278 len += sprintf(&radeon_param_buff[len],"Last fourcc: %s\n\n",fourcc_format_name(besr.fourcc)); | |
1279 len += sprintf(&radeon_param_buff[len],"Configurable stuff:\n"); | |
1280 len += sprintf(&radeon_param_buff[len],"~~~~~~~~~~~~~~~~~~~\n"); | |
1281 len += sprintf(&radeon_param_buff[len],PARAM_DOUBLE_BUFF"%s\n",besr.double_buff?"on":"off"); | |
1282 #ifdef RAGE128 | |
1283 len += sprintf(&radeon_param_buff[len],PARAM_BRIGHTNESS"%i\n",(int)brightness); | |
1284 len += sprintf(&radeon_param_buff[len],PARAM_SATURATION"%u\n",saturation); | |
1285 #else | |
1286 #ifdef RADEON_FPU | |
1287 len += sprintf(&radeon_param_buff[len],PARAM_BRIGHTNESS"%i\n",ovBrightness); | |
1288 len += sprintf(&radeon_param_buff[len],PARAM_SATURATION"%i\n",ovSaturation); | |
1289 len += sprintf(&radeon_param_buff[len],PARAM_CONTRAST"%i\n",ovContrast); | |
1290 len += sprintf(&radeon_param_buff[len],PARAM_HUE"%i\n",ovHue); | |
1291 #endif | |
1292 #endif | |
1293 len += sprintf(&radeon_param_buff[len],PARAM_DEINTERLACE"%s\n",besr.deinterlace_on?"on":"off"); | |
1294 len += sprintf(&radeon_param_buff[len],PARAM_DEINTERLACE_PATTERN"%X\n",besr.deinterlace_pattern); | |
1295 radeon_param_buff_len = len; | |
1296 } | |
1297 | |
1298 static ssize_t radeon_vid_read(struct file *file, char *buf, size_t count, loff_t *ppos) | |
1299 { | |
1300 uint32_t size; | |
1301 if(!radeon_param_buff) return -ESPIPE; | |
1302 if(!(*ppos)) radeon_param_buff_fill(); | |
1303 if(*ppos >= radeon_param_buff_len) return 0; | |
1304 size = min(count,radeon_param_buff_len-(uint32_t)(*ppos)); | |
1305 memcpy(buf,radeon_param_buff,size); | |
1306 *ppos += size; | |
1307 return size; | |
1308 } | |
1309 | |
1310 #define RTFSaturation(a) (1.0 + ((a)*1.0)/1000.0) | |
1311 #define RTFBrightness(a) (((a)*1.0)/2000.0) | |
1312 #define RTFContrast(a) (1.0 + ((a)*1.0)/1000.0) | |
1313 #define RTFHue(a) (((a)*3.1416)/1000.0) | |
1314 #define RadeonSetParm(a,b,c,d) if((b)>=(c)&&(b)<=(d)) { (a)=(b);\ | |
1315 radeon_set_transform(RTFBrightness(ovBrightness),RTFContrast(ovContrast)\ | |
1316 ,RTFSaturation(ovSaturation),RTFHue(ovHue),ov_trans_idx); } | |
1317 | |
1318 | |
1319 static ssize_t radeon_vid_write(struct file *file, const char *buf, size_t count, loff_t *ppos) | |
1320 { | |
1321 #ifdef RAGE128 | |
1322 if(memcmp(buf,PARAM_BRIGHTNESS,min(count,strlen(PARAM_BRIGHTNESS))) == 0) | |
1323 { | |
1324 long brightness; | |
1325 brightness=simple_strtol(&buf[strlen(PARAM_BRIGHTNESS)],NULL,10); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
1326 if(brightness >= -64 && brightness <= 63) |
22691 | 1327 { |
1328 besr.brightness = brightness; | |
1329 OUTREG(OV0_COLOUR_CNTL, (brightness & 0x7f) | | |
1330 (besr.saturation << 8) | | |
1331 (besr.saturation << 16)); | |
1332 } | |
1333 } | |
1334 else | |
1335 if(memcmp(buf,PARAM_SATURATION,min(count,strlen(PARAM_SATURATION))) == 0) | |
1336 { | |
1337 long saturation; | |
1338 saturation=simple_strtol(&buf[strlen(PARAM_SATURATION)],NULL,10); | |
1339 if(saturation >= 0 && saturation <= 31) | |
1340 OUTREG(OV0_COLOUR_CNTL, (besr.brightness & 0x7f) | | |
1341 (saturation << 8) | | |
1342 (saturation << 16)); | |
1343 } | |
1344 else | |
1345 #else | |
1346 #ifdef RADEON_FPU | |
1347 if(memcmp(buf,PARAM_BRIGHTNESS,min(count,strlen(PARAM_BRIGHTNESS))) == 0) | |
1348 { | |
1349 int tmp; | |
1350 tmp=simple_strtol(&buf[strlen(PARAM_BRIGHTNESS)],NULL,10); | |
1351 RadeonSetParm(ovBrightness,tmp,-1000,1000); | |
1352 } | |
1353 else | |
1354 if(memcmp(buf,PARAM_SATURATION,min(count,strlen(PARAM_SATURATION))) == 0) | |
1355 { | |
1356 int tmp; | |
1357 tmp=simple_strtol(&buf[strlen(PARAM_SATURATION)],NULL,10); | |
1358 RadeonSetParm(ovSaturation,tmp,-1000,1000); | |
1359 } | |
1360 else | |
1361 if(memcmp(buf,PARAM_CONTRAST,min(count,strlen(PARAM_CONTRAST))) == 0) | |
1362 { | |
1363 int tmp; | |
1364 tmp=simple_strtol(&buf[strlen(PARAM_CONTRAST)],NULL,10); | |
1365 RadeonSetParm(ovContrast,tmp,-1000,1000); | |
1366 } | |
1367 else | |
1368 if(memcmp(buf,PARAM_HUE,min(count,strlen(PARAM_HUE))) == 0) | |
1369 { | |
1370 int tmp; | |
1371 tmp=simple_strtol(&buf[strlen(PARAM_HUE)],NULL,10); | |
1372 RadeonSetParm(ovHue,tmp,-1000,1000); | |
1373 } | |
1374 else | |
1375 #endif | |
1376 #endif | |
1377 if(memcmp(buf,PARAM_DOUBLE_BUFF,min(count,strlen(PARAM_DOUBLE_BUFF))) == 0) | |
1378 { | |
1379 if(memcmp(&buf[strlen(PARAM_DOUBLE_BUFF)],"on",2) == 0) besr.double_buff = 1; | |
1380 else besr.double_buff = 0; | |
1381 } | |
1382 else | |
1383 if(memcmp(buf,PARAM_DEINTERLACE,min(count,strlen(PARAM_DEINTERLACE))) == 0) | |
1384 { | |
1385 if(memcmp(&buf[strlen(PARAM_DEINTERLACE)],"on",2) == 0) besr.deinterlace_on = 1; | |
1386 else besr.deinterlace_on = 0; | |
1387 } | |
1388 else | |
1389 if(memcmp(buf,PARAM_DEINTERLACE_PATTERN,min(count,strlen(PARAM_DEINTERLACE_PATTERN))) == 0) | |
1390 { | |
1391 long dpat; | |
1392 dpat=simple_strtol(&buf[strlen(PARAM_DEINTERLACE_PATTERN)],NULL,16); | |
1393 OUTREG(OV0_DEINTERLACE_PATTERN, dpat); | |
1394 } | |
1395 else count = -EIO; | |
1396 radeon_vid_preset(); | |
1397 return count; | |
1398 } | |
1399 | |
1400 static int radeon_vid_mmap(struct file *file, struct vm_area_struct *vma) | |
1401 { | |
1402 | |
1403 RTRACE(RVID_MSG"mapping video memory into userspace\n"); | |
1404 if(remap_page_range(vma->vm_start, radeon_mem_base + radeon_overlay_off, | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
1405 vma->vm_end - vma->vm_start, vma->vm_page_prot)) |
22691 | 1406 { |
1407 printk(RVID_MSG"error mapping video memory\n"); | |
26759
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
1408 return -EAGAIN; |
22691 | 1409 } |
1410 | |
26759
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
1411 return 0; |
22691 | 1412 } |
1413 | |
1414 static int radeon_vid_release(struct inode *inode, struct file *file) | |
1415 { | |
1416 radeon_vid_in_use = 0; | |
1417 radeon_vid_stop_video(); | |
1418 | |
1419 MOD_DEC_USE_COUNT; | |
1420 return 0; | |
1421 } | |
1422 | |
1423 static long long radeon_vid_lseek(struct file *file, long long offset, int origin) | |
1424 { | |
1425 return -ESPIPE; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
1426 } |
22691 | 1427 |
1428 static int radeon_vid_open(struct inode *inode, struct file *file) | |
1429 { | |
1430 int minor = MINOR(inode->i_rdev); | |
1431 | |
1432 if(minor != 0) | |
26759
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
1433 return -ENXIO; |
22691 | 1434 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
1435 if(radeon_vid_in_use == 1) |
26759
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
1436 return -EBUSY; |
22691 | 1437 |
1438 radeon_vid_in_use = 1; | |
1439 MOD_INC_USE_COUNT; | |
26759
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
1440 return 0; |
22691 | 1441 } |
1442 | |
1443 #if LINUX_VERSION_CODE >= 0x020400 | |
1444 static struct file_operations radeon_vid_fops = | |
1445 { | |
1446 llseek: radeon_vid_lseek, | |
1447 read: radeon_vid_read, | |
1448 write: radeon_vid_write, | |
1449 /* | |
1450 readdir: | |
1451 poll: | |
1452 */ | |
1453 ioctl: radeon_vid_ioctl, | |
1454 mmap: radeon_vid_mmap, | |
1455 open: radeon_vid_open, | |
1456 /* | |
1457 flush: | |
1458 */ | |
1459 release: radeon_vid_release | |
1460 /* | |
1461 fsync: | |
1462 fasync: | |
1463 lock: | |
1464 readv: | |
1465 writev: | |
1466 sendpage: | |
1467 get_unmapped_area: | |
1468 */ | |
1469 }; | |
1470 #else | |
1471 static struct file_operations radeon_vid_fops = | |
1472 { | |
1473 radeon_vid_lseek, | |
1474 radeon_vid_read, | |
1475 radeon_vid_write, | |
1476 NULL, | |
1477 NULL, | |
1478 radeon_vid_ioctl, | |
1479 radeon_vid_mmap, | |
1480 radeon_vid_open, | |
1481 NULL, | |
1482 radeon_vid_release | |
1483 }; | |
1484 #endif | |
1485 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
1486 /* |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
1487 * Main Initialization Function |
22691 | 1488 */ |
1489 | |
1490 static int __init radeon_vid_initialize(void) | |
1491 { | |
1492 radeon_vid_in_use = 0; | |
1493 #ifdef RAGE128 | |
1494 printk(RVID_MSG"Rage128/Rage128Pro video overlay driver v"RADEON_VID_VERSION" (C) Nick Kurshev\n"); | |
1495 #else | |
1496 printk(RVID_MSG"Radeon video overlay driver v"RADEON_VID_VERSION" (C) Nick Kurshev\n"); | |
1497 #endif | |
1498 if(register_chrdev(RADEON_VID_MAJOR, "radeon_vid", &radeon_vid_fops)) | |
1499 { | |
1500 printk(RVID_MSG"unable to get major: %d\n", RADEON_VID_MAJOR); | |
1501 return -EIO; | |
1502 } | |
1503 | |
1504 if (!radeon_vid_config_card()) | |
1505 { | |
1506 printk(RVID_MSG"can't configure this card\n"); | |
1507 unregister_chrdev(RADEON_VID_MAJOR, "radeon_vid"); | |
1508 return -EINVAL; | |
1509 } | |
1510 radeon_param_buff = kmalloc(PARAM_BUFF_SIZE,GFP_KERNEL); | |
1511 if(radeon_param_buff) radeon_param_buff_size = PARAM_BUFF_SIZE; | |
1512 #if 0 | |
1513 radeon_vid_save_state(); | |
1514 #endif | |
1515 radeon_vid_make_default(); | |
1516 radeon_vid_preset(); | |
1517 #ifdef CONFIG_MTRR | |
1518 if (mtrr) { | |
1519 smtrr.vram = mtrr_add(radeon_mem_base, | |
1520 radeon_ram_size*0x100000, MTRR_TYPE_WRCOMB, 1); | |
1521 smtrr.vram_valid = 1; | |
1522 /* let there be speed */ | |
1523 printk(RVID_MSG"MTRR set to ON\n"); | |
1524 } | |
1525 #endif /* CONFIG_MTRR */ | |
26759
8eff880f638c
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26003
diff
changeset
|
1526 return 0; |
22691 | 1527 } |
1528 | |
1529 int __init init_module(void) | |
1530 { | |
1531 return radeon_vid_initialize(); | |
1532 } | |
1533 | |
1534 void __exit cleanup_module(void) | |
1535 { | |
1536 #if 0 | |
1537 radeon_vid_restore_state(); | |
1538 #endif | |
1539 if(radeon_mmio_base) | |
1540 iounmap(radeon_mmio_base); | |
1541 kfree(radeon_param_buff); | |
1542 RTRACE(RVID_MSG"Cleaning up module\n"); | |
1543 unregister_chrdev(RADEON_VID_MAJOR, "radeon_vid"); | |
1544 #ifdef CONFIG_MTRR | |
1545 if (smtrr.vram_valid) | |
1546 mtrr_del(smtrr.vram, radeon_mem_base, | |
1547 radeon_ram_size*0x100000); | |
1548 #endif /* CONFIG_MTRR */ | |
1549 } |