Mercurial > mplayer.hg
comparison drivers/radeon/radeon_vid.c @ 2951:31730e84515d
First public release
author | nick |
---|---|
date | Sat, 17 Nov 2001 16:10:12 +0000 |
parents | ff8389ac4eb7 |
children | eb5e41e06ccc |
comparison
equal
deleted
inserted
replaced
2950:20157c719b2c | 2951:31730e84515d |
---|---|
12 * This file is partly based on mga_vid and sis_vid stuff from | 12 * This file is partly based on mga_vid and sis_vid stuff from |
13 * mplayer's package. | 13 * mplayer's package. |
14 * Also here was used code from CVS of GATOS project and X11 trees. | 14 * Also here was used code from CVS of GATOS project and X11 trees. |
15 */ | 15 */ |
16 | 16 |
17 #define RADEON_VID_VERSION "0.9.9" | |
18 | |
17 /* | 19 /* |
18 It's entirely possible this major conflicts with something else | 20 It's entirely possible this major conflicts with something else |
19 mknod /dev/radeon_vid c 178 0 | 21 mknod /dev/radeon_vid c 178 0 |
20 */ | 22 */ |
21 | 23 |
62 | 64 |
63 #define RADEON_VID_MAJOR 178 | 65 #define RADEON_VID_MAJOR 178 |
64 | 66 |
65 | 67 |
66 MODULE_AUTHOR("Nick Kurshev <nickols_k@mail.ru>"); | 68 MODULE_AUTHOR("Nick Kurshev <nickols_k@mail.ru>"); |
67 MODULE_DESCRIPTION("Accelerated YUV BES driver for Radeons"); | 69 MODULE_DESCRIPTION("Accelerated YUV BES driver for Radeons. Version: "RADEON_VID_VERSION); |
68 MODULE_LICENSE("GPL"); | 70 MODULE_LICENSE("GPL"); |
69 | 71 |
70 | 72 |
71 typedef struct bes_registers_s | 73 typedef struct bes_registers_s |
72 { | 74 { |
151 | 153 |
152 static uint32_t radeon_vid_in_use = 0; | 154 static uint32_t radeon_vid_in_use = 0; |
153 | 155 |
154 static uint8_t *radeon_mmio_base = 0; | 156 static uint8_t *radeon_mmio_base = 0; |
155 static uint32_t radeon_mem_base = 0; | 157 static uint32_t radeon_mem_base = 0; |
156 #define RADEON_SRC_BASE 8000000ULL /* this driver uses all video memory */ | 158 #define RADEON_SRC_BASE 0x1000000ULL /* this driver uses all video memory */ |
157 | 159 |
158 static uint32_t radeon_ram_size = 0; | 160 static uint32_t radeon_ram_size = 0; |
159 | 161 |
160 //static struct video_window radeon_win; | 162 //static struct video_window radeon_win; |
161 static mga_vid_config_t radeon_config; | 163 static mga_vid_config_t radeon_config; |
162 | 164 |
163 #define DEBUG 1 | 165 #undef DEBUG |
164 #if DEBUG | 166 #if DEBUG |
165 #define RTRACE printk | 167 #define RTRACE printk |
166 #else | 168 #else |
167 #define RTRACE(...) ((void)0) | 169 #define RTRACE(...) ((void)0) |
168 #endif | 170 #endif |
210 | 212 |
211 static void radeon_vid_display_video( void ) | 213 static void radeon_vid_display_video( void ) |
212 { | 214 { |
213 int bes_flags; | 215 int bes_flags; |
214 RTRACE("radeon_vid: OV0: v_inc=%x h_inc=%x step_by=%x\n",besr.v_inc,besr.h_inc,besr.step_by); | 216 RTRACE("radeon_vid: OV0: v_inc=%x h_inc=%x step_by=%x\n",besr.v_inc,besr.h_inc,besr.step_by); |
215 RTRACE("radeon_vid: OV0: vid_buf0_basey=%x\n",besr.vid_buf0_base_adrs); | 217 RTRACE("radeon_vid: OV0: vid_buf0_base=%x\n",besr.vid_buf0_base_adrs); |
216 RTRACE("radeon_vid: OV0: y_x_start=%x y_x_end=%x blank_at_top=%x pitch0_value=%x\n" | 218 RTRACE("radeon_vid: OV0: y_x_start=%x y_x_end=%x blank_at_top=%x pitch0_value=%x\n" |
217 ,besr.y_x_start,besr.y_x_end,besr.p1_blank_lines_at_top,besr.vid_buf_pitch0_value); | 219 ,besr.y_x_start,besr.y_x_end,besr.p1_blank_lines_at_top,besr.vid_buf_pitch0_value); |
220 RTRACE("radeon_vid: OV0: p1_x_start_end=%x p2_x_start_end=%x p3_x_start-end=%x\n" | |
221 ,besr.p1_x_start_end,besr.p2_x_start_end,besr.p2_x_start_end); | |
222 RTRACE("radeon_vid: OV0: p1_v_accum_init=%x p1_h_accum_init=%x p23_h_accum_init=%x\n" | |
223 ,besr.p1_v_accum_init,besr.p1_h_accum_init,besr.p23_h_accum_init); | |
218 OUTREG(OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK); | 224 OUTREG(OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK); |
219 while(!(INREG(OV0_REG_LOAD_CNTL)®_LD_CTL_LOCK_READBACK)); | 225 while(!(INREG(OV0_REG_LOAD_CNTL)®_LD_CTL_LOCK_READBACK)); |
220 | 226 /* |
221 OUTREG(OV0_AUTO_FLIP_CNTL,OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD); | 227 OUTREG(OV0_AUTO_FLIP_CNTL,OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD); |
222 | 228 |
223 OUTREG(OV0_DEINTERLACE_PATTERN,0xAAAAAAAA); | 229 OUTREG(OV0_DEINTERLACE_PATTERN,0xAAAAAAAA); |
224 | 230 |
225 OUTREG(OV0_AUTO_FLIP_CNTL,(INREG(OV0_AUTO_FLIP_CNTL)^OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE)); | 231 OUTREG(OV0_AUTO_FLIP_CNTL,(INREG(OV0_AUTO_FLIP_CNTL)^OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE)); |
226 OUTREG(OV0_AUTO_FLIP_CNTL,(INREG(OV0_AUTO_FLIP_CNTL)^OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE)); | 232 OUTREG(OV0_AUTO_FLIP_CNTL,(INREG(OV0_AUTO_FLIP_CNTL)^OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE)); |
227 | 233 */ |
228 OUTREG(OV0_H_INC, besr.h_inc); | 234 OUTREG(OV0_H_INC, besr.h_inc); |
229 OUTREG(OV0_STEP_BY, besr.step_by); | 235 OUTREG(OV0_STEP_BY, besr.step_by); |
230 OUTREG(OV0_Y_X_START, besr.y_x_start); | 236 OUTREG(OV0_Y_X_START, besr.y_x_start); |
231 OUTREG(OV0_Y_X_END, besr.y_x_end); | 237 OUTREG(OV0_Y_X_END, besr.y_x_end); |
232 OUTREG(OV0_V_INC, besr.v_inc); | 238 OUTREG(OV0_V_INC, besr.v_inc); |
246 OUTREG(OV0_P1_H_ACCUM_INIT, besr.p1_h_accum_init); | 252 OUTREG(OV0_P1_H_ACCUM_INIT, besr.p1_h_accum_init); |
247 OUTREG(OV0_P23_H_ACCUM_INIT, besr.p23_h_accum_init); | 253 OUTREG(OV0_P23_H_ACCUM_INIT, besr.p23_h_accum_init); |
248 | 254 |
249 bes_flags = SCALER_ENABLE | | 255 bes_flags = SCALER_ENABLE | |
250 SCALER_DOUBLE_BUFFER | | 256 SCALER_DOUBLE_BUFFER | |
251 SCALER_ADAPTIVE_DEINT | | 257 // SCALER_ADAPTIVE_DEINT | |
252 SCALER_SMART_SWITCH | | 258 SCALER_SMART_SWITCH | |
253 SCALER_HORZ_PICK_NEAREST; | 259 SCALER_HORZ_PICK_NEAREST; |
254 switch(besr.fourcc) | 260 switch(besr.fourcc) |
255 { | 261 { |
256 case IMGFMT_RGB15: | 262 case IMGFMT_RGB15: |
269 case IMGFMT_YV12: | 275 case IMGFMT_YV12: |
270 case IMGFMT_I420: | 276 case IMGFMT_I420: |
271 case IMGFMT_YUY2: | 277 case IMGFMT_YUY2: |
272 default: bes_flags |= SCALER_SOURCE_VYUY422; break; | 278 default: bes_flags |= SCALER_SOURCE_VYUY422; break; |
273 } | 279 } |
280 RTRACE("radeon_vid: OV0: SCALER=%x\n",bes_flags); | |
274 OUTREG(OV0_SCALE_CNTL, bes_flags); | 281 OUTREG(OV0_SCALE_CNTL, bes_flags); |
275 /* | 282 /* |
276 TODO: | 283 TODO: |
277 brightness: -64 : +63 | 284 brightness: -64 : +63 |
278 saturation: 0 : 31 | 285 saturation: 0 : 31 |
288 static void radeon_vid_start_video( void ) | 295 static void radeon_vid_start_video( void ) |
289 { | 296 { |
290 radeon_vid_display_video(); | 297 radeon_vid_display_video(); |
291 } | 298 } |
292 | 299 |
293 #define XXX_SRC_X 0 | 300 #define XXX_SRC_X 0 |
294 #define XXX_SRC_Y 0 | 301 #define XXX_SRC_Y 0 |
295 | 302 |
296 #define XXX_WIDTH config->src_width | 303 #define XXX_WIDTH config->src_width |
297 #define XXX_HEIGHT config->src_height | 304 #define XXX_HEIGHT config->src_height |
298 | 305 |
299 #define XXX_DRW_W (config->dest_width) | 306 #define XXX_DRW_W config->dest_width |
300 #define XXX_DRW_H (config->dest_height) | 307 #define XXX_DRW_H config->dest_height |
301 | 308 |
302 static int radeon_vid_init_video( mga_vid_config_t *config ) | 309 static int radeon_vid_init_video( mga_vid_config_t *config ) |
303 { | 310 { |
304 uint32_t tmp,left,src_w,pitch,h_inc,step_by; | 311 uint32_t tmp,src_w,pitch,h_inc,step_by,left,top; |
305 | 312 |
306 RTRACE("radeon_vid: usr_config: version = %x card=%x ram=%x src(%xx%x) dest(%x:%xx%x:%x) frame_size=%x num_frames=%x\n" | 313 RTRACE("radeon_vid: 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" |
307 ,(uint32_t)config->version | 314 ,(uint32_t)config->version |
315 ,(uint32_t)config->format | |
308 ,(uint32_t)config->card_type | 316 ,(uint32_t)config->card_type |
309 ,(uint32_t)config->ram_size | 317 ,(uint32_t)config->ram_size |
310 ,(uint32_t)config->src_width | 318 ,(uint32_t)config->src_width |
311 ,(uint32_t)config->src_height | 319 ,(uint32_t)config->src_height |
312 ,(uint32_t)config->x_org | 320 ,(uint32_t)config->x_org |
337 break; | 345 break; |
338 default: | 346 default: |
339 printk( "radeon_vid: Unsupported pixel format: 0x%X\n",config->format); | 347 printk( "radeon_vid: Unsupported pixel format: 0x%X\n",config->format); |
340 return -1; | 348 return -1; |
341 } | 349 } |
342 | 350 switch(config->format) |
343 pitch = ((XXX_WIDTH << 1) + 15) & ~15; | 351 { |
352 default: | |
353 case IMGFMT_YVU9: | |
354 case IMGFMT_IYUV: | |
355 case IMGFMT_UYVY: | |
356 case IMGFMT_YV12: | |
357 case IMGFMT_I420: | |
358 case IMGFMT_YUY2: | |
359 case IMGFMT_RGB15: | |
360 case IMGFMT_BGR15: | |
361 case IMGFMT_RGB16: | |
362 case IMGFMT_BGR16: pitch = ((XXX_WIDTH*2) + 15) & ~15; break; | |
363 case IMGFMT_RGB24: | |
364 case IMGFMT_BGR24: pitch = ((XXX_WIDTH*3) + 15) & ~15; break; | |
365 case IMGFMT_RGB32: | |
366 case IMGFMT_BGR32: pitch = ((XXX_WIDTH*4) + 15) & ~15; break; | |
367 } | |
368 /*pitch 9c0 ->4e0 */ | |
369 | |
370 left = XXX_SRC_X << 16; | |
371 top = XXX_SRC_Y << 16; | |
372 | |
344 besr.fourcc = config->format; | 373 besr.fourcc = config->format; |
345 | 374 |
346 besr.v_inc = (config->src_height << 20) / XXX_DRW_H; | 375 besr.v_inc = (config->src_height << 20) / XXX_DRW_H; /*9c0e0 -> 9c528*/ |
347 h_inc = (config->src_width << 12) / XXX_DRW_W; | 376 h_inc = (config->src_width << 12) / XXX_DRW_W; |
348 step_by = 1; | 377 step_by = 1; |
349 | 378 |
350 while(h_inc >= (2 << 12)) { | 379 while(h_inc >= (2 << 12)) { |
351 step_by++; | 380 step_by++; |
353 } | 382 } |
354 | 383 |
355 /* keep everything in 16.16 */ | 384 /* keep everything in 16.16 */ |
356 | 385 |
357 besr.vid_buf0_base_adrs = RADEON_SRC_BASE; /* I guess that offset 0 is o'k */ | 386 besr.vid_buf0_base_adrs = RADEON_SRC_BASE; /* I guess that offset 0 is o'k */ |
358 besr.vid_buf0_base_adrs += (((XXX_SRC_X >> 16) & ~7) << 1)&0xfffffff0; | 387 besr.vid_buf0_base_adrs += ((left & ~7) << 1)&0xfffffff0; |
359 besr.vid_buf1_base_adrs = besr.vid_buf0_base_adrs + config->frame_size; | 388 besr.vid_buf1_base_adrs = besr.vid_buf0_base_adrs + config->frame_size; |
360 besr.vid_buf2_base_adrs = besr.vid_buf0_base_adrs; | 389 besr.vid_buf2_base_adrs = besr.vid_buf0_base_adrs; |
361 besr.vid_buf3_base_adrs = besr.vid_buf0_base_adrs + config->frame_size; | 390 besr.vid_buf3_base_adrs = besr.vid_buf0_base_adrs + config->frame_size; |
362 besr.vid_buf4_base_adrs = besr.vid_buf0_base_adrs; | 391 besr.vid_buf4_base_adrs = besr.vid_buf0_base_adrs; |
363 besr.vid_buf5_base_adrs = besr.vid_buf0_base_adrs + config->frame_size; | 392 besr.vid_buf5_base_adrs = besr.vid_buf0_base_adrs + config->frame_size; |
364 | 393 |
365 tmp = (XXX_SRC_X & 0x0003ffff) + 0x00028000 + (h_inc << 3); | 394 tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3); |
366 besr.p1_h_accum_init = ((tmp << 4) & 0x000f8000) | | 395 besr.p1_h_accum_init = ((tmp << 4) & 0x000f8000) | |
367 ((tmp << 12) & 0xf0000000); | 396 ((tmp << 12) & 0xf0000000); |
368 | 397 |
369 tmp = ((XXX_SRC_X >> 1) & 0x0001ffff) + 0x00028000 + (h_inc << 2); | 398 tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc << 2); |
370 besr.p23_h_accum_init = ((tmp << 4) & 0x000f8000) | | 399 besr.p23_h_accum_init = ((tmp << 4) & 0x000f8000) | |
371 ((tmp << 12) & 0x70000000); | 400 ((tmp << 12) & 0x70000000); |
372 | 401 |
373 tmp = (XXX_SRC_Y & 0x0000ffff) + 0x00018000; | 402 tmp = (top & 0x0000ffff) + 0x00018000; |
374 besr.p1_v_accum_init = ((tmp << 4) & 0x03ff8000) | 0x00000001; | 403 besr.p1_v_accum_init = ((tmp << 4) & 0x03ff8000) | 0x00000001; |
375 | 404 |
376 left = (XXX_SRC_X >> 16) & 7; | 405 left = (left >> 16) & 7; |
377 besr.h_inc = h_inc | ((h_inc >> 1) << 16); | 406 besr.h_inc = h_inc | ((h_inc >> 1) << 16); |
378 besr.step_by = step_by | (step_by << 8); | 407 besr.step_by = step_by | (step_by << 8); |
379 besr.y_x_start = (config->x_org) | (config->y_org << 16); | 408 besr.y_x_start = (config->x_org+8) | (config->y_org << 16); /*5c008->5d009*/ |
380 besr.y_x_end = (config->x_org + config->dest_width+8) | ((config->y_org + config->dest_height) << 16); | 409 besr.y_x_end = (config->x_org + config->dest_width+8) | ((config->y_org + config->dest_height) << 16); |
381 besr.p1_blank_lines_at_top = 0x00000fff | ((config->src_height - 1) << 16); | 410 besr.p1_blank_lines_at_top = 0x00000fff | ((config->src_height - 1) << 16); |
382 besr.vid_buf_pitch0_value = pitch; | 411 besr.vid_buf_pitch0_value = pitch; |
383 besr.vid_buf_pitch1_value = pitch; | 412 besr.vid_buf_pitch1_value = pitch; |
384 RTRACE("radeon_vid: BES: v_inc=%x h_inc=%x step_by=%x\n",besr.v_inc,besr.h_inc,besr.step_by); | 413 RTRACE("radeon_vid: BES: v_inc=%x h_inc=%x step_by=%x\n",besr.v_inc,besr.h_inc,besr.step_by); |
410 OUTREG(OV0_VID_BUF0_BASE_ADRS, off); | 439 OUTREG(OV0_VID_BUF0_BASE_ADRS, off); |
411 OUTREG(OV0_REG_LOAD_CNTL, 0); | 440 OUTREG(OV0_REG_LOAD_CNTL, 0); |
412 | 441 |
413 } | 442 } |
414 | 443 |
444 static int video_on = 0; | |
445 | |
415 static int radeon_vid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 446 static int radeon_vid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) |
416 { | 447 { |
417 int frame; | 448 int frame; |
418 | 449 |
419 switch(cmd) | 450 switch(cmd) |
456 break; | 487 break; |
457 | 488 |
458 case MGA_VID_ON: | 489 case MGA_VID_ON: |
459 RTRACE( "radeon_vid: Video ON (ioctl)\n"); | 490 RTRACE( "radeon_vid: Video ON (ioctl)\n"); |
460 radeon_vid_start_video(); | 491 radeon_vid_start_video(); |
492 video_on = 1; | |
461 break; | 493 break; |
462 | 494 |
463 case MGA_VID_OFF: | 495 case MGA_VID_OFF: |
464 RTRACE( "radeon_vid: Video OFF (ioctl)\n"); | 496 RTRACE( "radeon_vid: Video OFF (ioctl)\n"); |
465 radeon_vid_stop_video(); | 497 if(video_on) radeon_vid_stop_video(); |
498 video_on = 0; | |
466 break; | 499 break; |
467 | 500 |
468 case MGA_VID_FSEL: | 501 case MGA_VID_FSEL: |
469 if(copy_from_user(&frame,(int *) arg,sizeof(int))) | 502 if(copy_from_user(&frame,(int *) arg,sizeof(int))) |
470 { | 503 { |