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)&REG_LD_CTL_LOCK_READBACK)); 473 while(!(INREG(OV0_REG_LOAD_CNTL)&REG_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 }