Mercurial > mplayer.hg
comparison drivers/radeon/radeon_vid.c @ 3019:64ce4a515a78
Bad attempt of YV12 direct support
author | nick |
---|---|
date | Tue, 20 Nov 2001 10:00:58 +0000 |
parents | eb5e41e06ccc |
children | e5ebde3ebdd6 |
comparison
equal
deleted
inserted
replaced
3018:9eb1cae56cae | 3019:64ce4a515a78 |
---|---|
82 uint32_t step_by; | 82 uint32_t step_by; |
83 uint32_t y_x_start; | 83 uint32_t y_x_start; |
84 uint32_t y_x_end; | 84 uint32_t y_x_end; |
85 uint32_t v_inc; | 85 uint32_t v_inc; |
86 uint32_t p1_blank_lines_at_top; | 86 uint32_t p1_blank_lines_at_top; |
87 uint32_t p23_blank_lines_at_top; | |
87 uint32_t vid_buf_pitch0_value; | 88 uint32_t vid_buf_pitch0_value; |
88 uint32_t vid_buf_pitch1_value; | 89 uint32_t vid_buf_pitch1_value; |
89 uint32_t p1_x_start_end; | 90 uint32_t p1_x_start_end; |
90 uint32_t p2_x_start_end; | 91 uint32_t p2_x_start_end; |
91 uint32_t p3_x_start_end; | 92 uint32_t p3_x_start_end; |
97 uint32_t vid_buf4_base_adrs; | 98 uint32_t vid_buf4_base_adrs; |
98 uint32_t vid_buf5_base_adrs; | 99 uint32_t vid_buf5_base_adrs; |
99 | 100 |
100 uint32_t p1_v_accum_init; | 101 uint32_t p1_v_accum_init; |
101 uint32_t p1_h_accum_init; | 102 uint32_t p1_h_accum_init; |
103 uint32_t p23_v_accum_init; | |
102 uint32_t p23_h_accum_init; | 104 uint32_t p23_h_accum_init; |
103 uint32_t scale_cntl; | 105 uint32_t scale_cntl; |
104 uint32_t exclusive_horz; | 106 uint32_t exclusive_horz; |
105 uint32_t auto_flip_cntl; | 107 uint32_t auto_flip_cntl; |
106 uint32_t filter_cntl; | 108 uint32_t filter_cntl; |
125 { OV0_STEP_BY, 0 }, | 127 { OV0_STEP_BY, 0 }, |
126 { OV0_Y_X_START, 0 }, | 128 { OV0_Y_X_START, 0 }, |
127 { OV0_Y_X_END, 0 }, | 129 { OV0_Y_X_END, 0 }, |
128 { OV0_V_INC, 0 }, | 130 { OV0_V_INC, 0 }, |
129 { OV0_P1_BLANK_LINES_AT_TOP, 0 }, | 131 { OV0_P1_BLANK_LINES_AT_TOP, 0 }, |
132 { OV0_P23_BLANK_LINES_AT_TOP, 0 }, | |
130 { OV0_VID_BUF_PITCH0_VALUE, 0 }, | 133 { OV0_VID_BUF_PITCH0_VALUE, 0 }, |
131 { OV0_VID_BUF_PITCH1_VALUE, 0 }, | 134 { OV0_VID_BUF_PITCH1_VALUE, 0 }, |
132 { OV0_P1_X_START_END, 0 }, | 135 { OV0_P1_X_START_END, 0 }, |
133 { OV0_P2_X_START_END, 0 }, | 136 { OV0_P2_X_START_END, 0 }, |
134 { OV0_P3_X_START_END, 0 }, | 137 { OV0_P3_X_START_END, 0 }, |
138 { OV0_VID_BUF3_BASE_ADRS, 0 }, | 141 { OV0_VID_BUF3_BASE_ADRS, 0 }, |
139 { OV0_VID_BUF4_BASE_ADRS, 0 }, | 142 { OV0_VID_BUF4_BASE_ADRS, 0 }, |
140 { OV0_VID_BUF5_BASE_ADRS, 0 }, | 143 { OV0_VID_BUF5_BASE_ADRS, 0 }, |
141 { OV0_P1_V_ACCUM_INIT, 0 }, | 144 { OV0_P1_V_ACCUM_INIT, 0 }, |
142 { OV0_P1_H_ACCUM_INIT, 0 }, | 145 { OV0_P1_H_ACCUM_INIT, 0 }, |
146 { OV0_P23_V_ACCUM_INIT, 0 }, | |
143 { OV0_P23_H_ACCUM_INIT, 0 }, | 147 { OV0_P23_H_ACCUM_INIT, 0 }, |
144 { OV0_SCALE_CNTL, 0 }, | 148 { OV0_SCALE_CNTL, 0 }, |
145 { OV0_EXCLUSIVE_HORZ, 0 }, | 149 { OV0_EXCLUSIVE_HORZ, 0 }, |
146 { OV0_AUTO_FLIP_CNTL, 0 }, | 150 { OV0_AUTO_FLIP_CNTL, 0 }, |
147 { OV0_FILTER_CNTL, 0 }, | 151 { OV0_FILTER_CNTL, 0 }, |
154 | 158 |
155 static uint32_t radeon_vid_in_use = 0; | 159 static uint32_t radeon_vid_in_use = 0; |
156 | 160 |
157 static uint8_t *radeon_mmio_base = 0; | 161 static uint8_t *radeon_mmio_base = 0; |
158 static uint32_t radeon_mem_base = 0; | 162 static uint32_t radeon_mem_base = 0; |
159 #define RADEON_SRC_BASE 0x1000000ULL /* this driver uses all video memory */ | 163 static int32_t radeon_overlay_off = 0; |
160 | 164 |
161 static uint32_t radeon_ram_size = 0; | 165 static uint32_t radeon_ram_size = 0; |
162 | 166 |
163 //static struct video_window radeon_win; | 167 //static struct video_window radeon_win; |
164 static mga_vid_config_t radeon_config; | 168 static mga_vid_config_t radeon_config; |
271 | 275 |
272 case IMGFMT_UYVY: bes_flags |= SCALER_SOURCE_YVYU422; break; | 276 case IMGFMT_UYVY: bes_flags |= SCALER_SOURCE_YVYU422; break; |
273 case IMGFMT_YVU9: bes_flags |= SCALER_SOURCE_YUV9; break; | 277 case IMGFMT_YVU9: bes_flags |= SCALER_SOURCE_YUV9; break; |
274 case IMGFMT_IYUV: bes_flags |= SCALER_SOURCE_YUV12; break; | 278 case IMGFMT_IYUV: bes_flags |= SCALER_SOURCE_YUV12; break; |
275 | 279 |
276 case IMGFMT_YV12: | |
277 case IMGFMT_I420: | 280 case IMGFMT_I420: |
281 case IMGFMT_YV12: bes_flags |= SCALER_SOURCE_YUV12 | | |
282 SCALER_PIX_EXPAND | | |
283 SCALER_Y2R_TEMP; | |
284 break; | |
278 case IMGFMT_YUY2: | 285 case IMGFMT_YUY2: |
279 default: bes_flags |= SCALER_SOURCE_VYUY422; break; | 286 default: bes_flags |= SCALER_SOURCE_VYUY422; break; |
280 } | 287 } |
281 RTRACE("radeon_vid: OV0: SCALER=%x\n",bes_flags); | 288 RTRACE("radeon_vid: OV0: SCALER=%x\n",bes_flags); |
282 OUTREG(OV0_SCALE_CNTL, bes_flags); | 289 OUTREG(OV0_SCALE_CNTL, bes_flags); |
307 #define XXX_DRW_W config->dest_width | 314 #define XXX_DRW_W config->dest_width |
308 #define XXX_DRW_H config->dest_height | 315 #define XXX_DRW_H config->dest_height |
309 | 316 |
310 static int radeon_vid_init_video( mga_vid_config_t *config ) | 317 static int radeon_vid_init_video( mga_vid_config_t *config ) |
311 { | 318 { |
312 uint32_t tmp,src_w,pitch,h_inc,step_by,left,top; | 319 uint32_t tmp,src_w,pitch,h_inc,step_by,left,leftUV,top; |
313 | 320 int is_420; |
314 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" | 321 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" |
315 ,(uint32_t)config->version | 322 ,(uint32_t)config->version |
316 ,(uint32_t)config->format | 323 ,(uint32_t)config->format |
317 ,(uint32_t)config->card_type | 324 ,(uint32_t)config->card_type |
318 ,(uint32_t)config->ram_size | 325 ,(uint32_t)config->ram_size |
346 break; | 353 break; |
347 default: | 354 default: |
348 printk( "radeon_vid: Unsupported pixel format: 0x%X\n",config->format); | 355 printk( "radeon_vid: Unsupported pixel format: 0x%X\n",config->format); |
349 return -1; | 356 return -1; |
350 } | 357 } |
358 is_420 = 0; | |
359 if(config->format == IMGFMT_YV12 || config->format == IMGFMT_I420) is_420 = 1; | |
351 switch(config->format) | 360 switch(config->format) |
352 { | 361 { |
353 default: | 362 default: |
354 case IMGFMT_YVU9: | 363 case IMGFMT_YVU9: |
355 case IMGFMT_IYUV: | 364 case IMGFMT_IYUV: |
364 case IMGFMT_RGB24: | 373 case IMGFMT_RGB24: |
365 case IMGFMT_BGR24: pitch = ((XXX_WIDTH*3) + 15) & ~15; break; | 374 case IMGFMT_BGR24: pitch = ((XXX_WIDTH*3) + 15) & ~15; break; |
366 case IMGFMT_RGB32: | 375 case IMGFMT_RGB32: |
367 case IMGFMT_BGR32: pitch = ((XXX_WIDTH*4) + 15) & ~15; break; | 376 case IMGFMT_BGR32: pitch = ((XXX_WIDTH*4) + 15) & ~15; break; |
368 } | 377 } |
369 /*pitch 9c0 ->4e0 */ | |
370 | 378 |
371 left = XXX_SRC_X << 16; | 379 left = XXX_SRC_X << 16; |
372 top = XXX_SRC_Y << 16; | 380 top = XXX_SRC_Y << 16; |
373 | 381 |
374 besr.fourcc = config->format; | 382 besr.fourcc = config->format; |
382 h_inc >>= 1; | 390 h_inc >>= 1; |
383 } | 391 } |
384 | 392 |
385 /* keep everything in 16.16 */ | 393 /* keep everything in 16.16 */ |
386 | 394 |
387 besr.vid_buf0_base_adrs = RADEON_SRC_BASE; /* I guess that offset 0 is o'k */ | 395 if(is_420) |
388 besr.vid_buf0_base_adrs += ((left & ~7) << 1)&0xfffffff0; | 396 { |
389 besr.vid_buf1_base_adrs = besr.vid_buf0_base_adrs + config->frame_size; | 397 uint32_t dstPitch,d1line,d2line,d3line; |
390 besr.vid_buf2_base_adrs = besr.vid_buf0_base_adrs; | 398 dstPitch = (XXX_WIDTH + 31) & ~31; /* of luma */ |
391 besr.vid_buf3_base_adrs = besr.vid_buf0_base_adrs + config->frame_size; | 399 d1line = top * dstPitch; |
392 besr.vid_buf4_base_adrs = besr.vid_buf0_base_adrs; | 400 d2line = (XXX_HEIGHT * dstPitch) + ((top >> 1) * (dstPitch >> 1)); |
393 besr.vid_buf5_base_adrs = besr.vid_buf0_base_adrs + config->frame_size; | 401 d3line = d2line + ((XXX_HEIGHT >> 1) * (dstPitch >> 1)); |
402 d1line += (left >> 16) & ~15; | |
403 d2line += (left >> 17) & ~15; | |
404 d3line += (left >> 17) & ~15; | |
405 besr.vid_buf0_base_adrs = (radeon_overlay_off + d1line) & 0xfffffff0; | |
406 besr.vid_buf1_base_adrs = ((radeon_overlay_off + d2line) & 0xfffffff0) | 0x00000001; | |
407 besr.vid_buf2_base_adrs = ((radeon_overlay_off + d3line) & 0xfffffff0) | 0x00000001; | |
408 besr.vid_buf3_base_adrs = besr.vid_buf0_base_adrs; | |
409 besr.vid_buf4_base_adrs = besr.vid_buf1_base_adrs; | |
410 besr.vid_buf5_base_adrs = besr.vid_buf2_base_adrs; | |
411 } | |
412 else | |
413 { | |
414 besr.vid_buf0_base_adrs = radeon_overlay_off; | |
415 besr.vid_buf0_base_adrs += ((left & ~7) << 1)&0xfffffff0; | |
416 besr.vid_buf1_base_adrs = besr.vid_buf0_base_adrs + config->frame_size; | |
417 besr.vid_buf2_base_adrs = besr.vid_buf0_base_adrs; | |
418 besr.vid_buf3_base_adrs = besr.vid_buf0_base_adrs + config->frame_size; | |
419 besr.vid_buf4_base_adrs = besr.vid_buf0_base_adrs; | |
420 besr.vid_buf5_base_adrs = besr.vid_buf0_base_adrs + config->frame_size; | |
421 } | |
394 | 422 |
395 tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3); | 423 tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3); |
396 besr.p1_h_accum_init = ((tmp << 4) & 0x000f8000) | | 424 besr.p1_h_accum_init = ((tmp << 4) & 0x000f8000) | |
397 ((tmp << 12) & 0xf0000000); | 425 ((tmp << 12) & 0xf0000000); |
398 | 426 |
401 ((tmp << 12) & 0x70000000); | 429 ((tmp << 12) & 0x70000000); |
402 | 430 |
403 tmp = (top & 0x0000ffff) + 0x00018000; | 431 tmp = (top & 0x0000ffff) + 0x00018000; |
404 besr.p1_v_accum_init = ((tmp << 4) & 0x03ff8000) | 0x00000001; | 432 besr.p1_v_accum_init = ((tmp << 4) & 0x03ff8000) | 0x00000001; |
405 | 433 |
434 | |
435 tmp = ((top >> 1) & 0x0000ffff) + 0x00018000; | |
436 besr.p23_v_accum_init = is_420 ? ((tmp << 4) & 0x01ff8000) | 0x00000001 : 0; | |
437 | |
438 leftUV = (left >> 17) & 7; | |
406 left = (left >> 16) & 7; | 439 left = (left >> 16) & 7; |
407 besr.h_inc = h_inc | ((h_inc >> 1) << 16); | 440 besr.h_inc = h_inc | ((h_inc >> 1) << 16); |
408 besr.step_by = step_by | (step_by << 8); | 441 besr.step_by = step_by | (step_by << 8); |
409 besr.y_x_start = (config->x_org+8) | (config->y_org << 16); /*5c008->5d009*/ | 442 besr.y_x_start = (config->x_org+8) | (config->y_org << 16); /*5c008->5d009*/ |
410 besr.y_x_end = (config->x_org + config->dest_width+8) | ((config->y_org + config->dest_height) << 16); | 443 besr.y_x_end = (config->x_org + config->dest_width+8) | ((config->y_org + config->dest_height) << 16); |
411 besr.p1_blank_lines_at_top = 0x00000fff | ((config->src_height - 1) << 16); | 444 besr.p1_blank_lines_at_top = 0x00000fff | ((config->src_height - 1) << 16); |
445 besr.p23_blank_lines_at_top = is_420 ? 0x000007ff | ((((config->src_height+1)>>1) - 1) << 16) : 0; | |
412 besr.vid_buf_pitch0_value = pitch; | 446 besr.vid_buf_pitch0_value = pitch; |
413 besr.vid_buf_pitch1_value = pitch; | 447 besr.vid_buf_pitch1_value = is_420 ? pitch/2 : pitch; |
414 RTRACE("radeon_vid: BES: v_inc=%x h_inc=%x step_by=%x\n",besr.v_inc,besr.h_inc,besr.step_by); | 448 RTRACE("radeon_vid: BES: v_inc=%x h_inc=%x step_by=%x\n",besr.v_inc,besr.h_inc,besr.step_by); |
415 RTRACE("radeon_vid: BES: vid_buf0_basey=%x\n",besr.vid_buf0_base_adrs); | 449 RTRACE("radeon_vid: BES: vid_buf0_basey=%x\n",besr.vid_buf0_base_adrs); |
416 RTRACE("radeon_vid: BES: y_x_start=%x y_x_end=%x blank_at_top=%x pitch0_value=%x\n" | 450 RTRACE("radeon_vid: BES: y_x_start=%x y_x_end=%x blank_at_top=%x pitch0_value=%x\n" |
417 ,besr.y_x_start,besr.y_x_end,besr.p1_blank_lines_at_top,besr.vid_buf_pitch0_value); | 451 ,besr.y_x_start,besr.y_x_end,besr.p1_blank_lines_at_top,besr.vid_buf_pitch0_value); |
418 besr.p1_x_start_end = (config->src_width + left - 1) | (left << 16); | 452 besr.p1_x_start_end = (config->src_width + left - 1) | (left << 16); |
419 left >>= 1; src_w=config->src_width >> 1; | 453 src_w=config->src_width >> 1; |
420 besr.p2_x_start_end = (src_w + left - 1) | (left << 16); | 454 besr.p2_x_start_end = (src_w + left - 1) | (leftUV << 16); |
421 besr.p3_x_start_end = besr.p2_x_start_end; | 455 besr.p3_x_start_end = besr.p2_x_start_end; |
422 return 0; | 456 return 0; |
423 } | 457 } |
424 | 458 |
425 static void radeon_vid_frame_sel(int frame) | 459 static void radeon_vid_frame_sel(int frame) |
427 uint32_t off; | 461 uint32_t off; |
428 switch(frame) | 462 switch(frame) |
429 { | 463 { |
430 default: | 464 default: |
431 case 0: off = besr.vid_buf0_base_adrs; break; | 465 case 0: off = besr.vid_buf0_base_adrs; break; |
432 case 1: off = besr.vid_buf1_base_adrs; break; | 466 case 1: off = besr.vid_buf3_base_adrs; break; |
433 case 2: off = besr.vid_buf2_base_adrs; break; | 467 case 2: off = besr.vid_buf0_base_adrs; break; |
434 case 3: off = besr.vid_buf3_base_adrs; break; | 468 case 3: off = besr.vid_buf3_base_adrs; break; |
435 case 4: off = besr.vid_buf4_base_adrs; break; | 469 case 4: off = besr.vid_buf0_base_adrs; break; |
436 case 5: off = besr.vid_buf5_base_adrs; break; | 470 case 5: off = besr.vid_buf3_base_adrs; break; |
437 } | 471 } |
438 OUTREG(OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK); | 472 OUTREG(OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK); |
439 while(!(INREG(OV0_REG_LOAD_CNTL)®_LD_CTL_LOCK_READBACK)); | 473 while(!(INREG(OV0_REG_LOAD_CNTL)®_LD_CTL_LOCK_READBACK)); |
440 OUTREG(OV0_VID_BUF0_BASE_ADRS, off); | 474 OUTREG(OV0_VID_BUF0_BASE_ADRS, off); |
441 OUTREG(OV0_REG_LOAD_CNTL, 0); | 475 OUTREG(OV0_REG_LOAD_CNTL, 0); |
442 | |
443 } | 476 } |
444 | 477 |
445 static int video_on = 0; | 478 static int video_on = 0; |
446 | 479 |
447 static int radeon_vid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 480 static int radeon_vid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) |
456 RTRACE( "radeon_vid: Received configuration\n"); | 489 RTRACE( "radeon_vid: Received configuration\n"); |
457 | 490 |
458 if(copy_from_user(&radeon_config,(mga_vid_config_t*) arg,sizeof(mga_vid_config_t))) | 491 if(copy_from_user(&radeon_config,(mga_vid_config_t*) arg,sizeof(mga_vid_config_t))) |
459 { | 492 { |
460 printk( "radeon_vid: failed copy from userspace\n"); | 493 printk( "radeon_vid: failed copy from userspace\n"); |
461 return(-EFAULT); | 494 return -EFAULT; |
462 } | 495 } |
463 if(radeon_config.version != MGA_VID_VERSION){ | 496 if(radeon_config.version != MGA_VID_VERSION){ |
464 printk( "radeon_vid: incompatible version! driver: %X requested: %X\n",MGA_VID_VERSION,radeon_config.version); | 497 printk( "radeon_vid: incompatible version! driver: %X requested: %X\n",MGA_VID_VERSION,radeon_config.version); |
465 return(-EFAULT); | 498 return -EFAULT; |
466 } | 499 } |
467 | 500 |
468 if(radeon_config.frame_size==0 || radeon_config.frame_size>1024*768*2){ | 501 if(radeon_config.frame_size==0 || radeon_config.frame_size>1024*768*2){ |
469 printk( "radeon_vid: illegal frame_size: %d\n",radeon_config.frame_size); | 502 printk( "radeon_vid: illegal frame_size: %d\n",radeon_config.frame_size); |
470 return(-EFAULT); | 503 return -EFAULT; |
471 } | 504 } |
472 | 505 |
473 if(radeon_config.num_frames<1 || radeon_config.num_frames>4){ | 506 if(radeon_config.num_frames<1 || radeon_config.num_frames>4){ |
474 printk( "radeon_vid: illegal num_frames: %d\n",radeon_config.num_frames); | 507 printk( "radeon_vid: illegal num_frames: %d\n",radeon_config.num_frames); |
475 return(-EFAULT); | 508 return -EFAULT; |
476 } | 509 } |
477 | 510 |
478 /* FIXME: Fake of G400 ;) or would be better G200 ??? */ | 511 /* FIXME: Fake of G400 ;) or would be better G200 ??? */ |
479 radeon_config.card_type = 0; | 512 radeon_config.card_type = 0; |
480 radeon_config.ram_size = radeon_ram_size; | 513 radeon_config.ram_size = radeon_ram_size; |
481 | 514 radeon_overlay_off = radeon_ram_size*0x100000 - radeon_config.frame_size*radeon_config.num_frames; |
515 radeon_overlay_off &= 0xffff0000; | |
516 if(radeon_overlay_off < 0){ | |
517 printk("radeon_vid: not enough video memory. Need: %u has: %u\n",radeon_config.frame_size*radeon_config.num_frames,radeon_ram_size*0x100000); | |
518 return -EFAULT; | |
519 } | |
520 RTRACE("radeon_vid: using video overlay at offset %p\n",radeon_overlay_off); | |
482 if (copy_to_user((mga_vid_config_t *) arg, &radeon_config, sizeof(mga_vid_config_t))) | 521 if (copy_to_user((mga_vid_config_t *) arg, &radeon_config, sizeof(mga_vid_config_t))) |
483 { | 522 { |
484 printk( "radeon_vid: failed copy to userspace\n"); | 523 printk( "radeon_vid: failed copy to userspace\n"); |
485 return(-EFAULT); | 524 return -EFAULT; |
486 } | 525 } |
487 return radeon_vid_init_video(&radeon_config); | 526 return radeon_vid_init_video(&radeon_config); |
488 break; | 527 break; |
489 | 528 |
490 case MGA_VID_ON: | 529 case MGA_VID_ON: |
575 | 614 |
576 static int radeon_vid_mmap(struct file *file, struct vm_area_struct *vma) | 615 static int radeon_vid_mmap(struct file *file, struct vm_area_struct *vma) |
577 { | 616 { |
578 | 617 |
579 RTRACE( "radeon_vid: mapping video memory into userspace\n"); | 618 RTRACE( "radeon_vid: mapping video memory into userspace\n"); |
580 if(remap_page_range(vma->vm_start, radeon_mem_base + RADEON_SRC_BASE, | 619 if(remap_page_range(vma->vm_start, radeon_mem_base + radeon_overlay_off, |
581 vma->vm_end - vma->vm_start, vma->vm_page_prot)) | 620 vma->vm_end - vma->vm_start, vma->vm_page_prot)) |
582 { | 621 { |
583 printk( "radeon_vid: error mapping video memory\n"); | 622 printk( "radeon_vid: error mapping video memory\n"); |
584 return(-EAGAIN); | 623 return(-EAGAIN); |
585 } | 624 } |