diff options
Diffstat (limited to 'src/video_out/vidix/drivers/radeon_vid.c')
-rw-r--r-- | src/video_out/vidix/drivers/radeon_vid.c | 469 |
1 files changed, 423 insertions, 46 deletions
diff --git a/src/video_out/vidix/drivers/radeon_vid.c b/src/video_out/vidix/drivers/radeon_vid.c index 1393a49e5..ed5a4ee41 100644 --- a/src/video_out/vidix/drivers/radeon_vid.c +++ b/src/video_out/vidix/drivers/radeon_vid.c @@ -11,6 +11,7 @@ #include <string.h> #include <math.h> #include <inttypes.h> +#include <sys/mman.h> #include "../../libdha/pci_ids.h" #include "../../libdha/pci_names.h" #include "../vidix.h" @@ -29,6 +30,25 @@ #endif #endif +//#undef RADEON_ENABLE_BM /* unfinished stuff. May corrupt your filesystem ever */ +#define RADEON_ENABLE_BM 1 + +#ifdef RADEON_ENABLE_BM +static void * radeon_dma_desc_base = 0; +static unsigned long bus_addr_dma_desc = 0; +static unsigned long *dma_phys_addrs = 0; +#pragma pack(1) +typedef struct +{ + uint32_t framebuf_offset; + uint32_t sys_addr; + uint32_t command; + uint32_t reserved; +} bm_list_descriptor; +#pragma pack() +#endif + +#define VERBOSE_LEVEL 0 static int __verbose = 0; typedef struct bes_registers_s @@ -187,7 +207,43 @@ static video_registers_t vregs[] = DECLARE_VREG(IDCT_LEVELS), DECLARE_VREG(IDCT_AUTH_CONTROL), DECLARE_VREG(IDCT_AUTH), - DECLARE_VREG(IDCT_CONTROL) + DECLARE_VREG(IDCT_CONTROL), +#ifdef RAGE128 + DECLARE_VREG(BM_FRAME_BUF_OFFSET), + DECLARE_VREG(BM_SYSTEM_MEM_ADDR), + DECLARE_VREG(BM_COMMAND), + DECLARE_VREG(BM_STATUS), + DECLARE_VREG(BM_QUEUE_STATUS), + DECLARE_VREG(BM_QUEUE_FREE_STATUS), + DECLARE_VREG(BM_CHUNK_0_VAL), + DECLARE_VREG(BM_CHUNK_1_VAL), + DECLARE_VREG(BM_VIP0_BUF), + DECLARE_VREG(BM_VIP0_ACTIVE), + DECLARE_VREG(BM_VIP1_BUF), + DECLARE_VREG(BM_VIP1_ACTIVE), + DECLARE_VREG(BM_VIP2_BUF), + DECLARE_VREG(BM_VIP2_ACTIVE), + DECLARE_VREG(BM_VIP3_BUF), + DECLARE_VREG(BM_VIP3_ACTIVE), + DECLARE_VREG(BM_VIDCAP_BUF0), + DECLARE_VREG(BM_VIDCAP_BUF1), + DECLARE_VREG(BM_VIDCAP_BUF2), + DECLARE_VREG(BM_VIDCAP_ACTIVE), + DECLARE_VREG(BM_GUI), + DECLARE_VREG(BM_ABORT) +#else + DECLARE_VREG(DMA_GUI_TABLE_ADDR), + DECLARE_VREG(DMA_GUI_SRC_ADDR), + DECLARE_VREG(DMA_GUI_DST_ADDR), + DECLARE_VREG(DMA_GUI_COMMAND), + DECLARE_VREG(DMA_GUI_STATUS), + DECLARE_VREG(DMA_GUI_ACT_DSCRPTR), + DECLARE_VREG(DMA_VID_SRC_ADDR), + DECLARE_VREG(DMA_VID_DST_ADDR), + DECLARE_VREG(DMA_VID_COMMAND), + DECLARE_VREG(DMA_VID_STATUS), + DECLARE_VREG(DMA_VID_ACT_DSCRPTR), +#endif }; static void * radeon_mmio_base = 0; @@ -906,6 +962,84 @@ int vixProbe( int verbose,int force ) return err; } +#ifndef RAGE128 +enum radeon_montype +{ + MT_NONE, + MT_CRT, /* CRT-(cathode ray tube) analog monitor. (15-pin VGA connector) */ + MT_LCD, /* Liquid Crystal Display */ + MT_DFP, /* DFP-digital flat panel monitor. (24-pin DVI-I connector) */ + MT_CTV, /* Composite TV out (not in VE) */ + MT_STV /* S-Video TV out (probably in VE only) */ +}; + +typedef struct radeon_info_s +{ + int hasCRTC2; + int crtDispType; + int dviDispType; +}rinfo_t; + +static rinfo_t rinfo; + +static char * GET_MON_NAME(int type) +{ + char *pret; + switch(type) + { + case MT_NONE: pret = "no"; break; + case MT_CRT: pret = "CRT"; break; + case MT_DFP: pret = "DFP"; break; + case MT_LCD: pret = "LCD"; break; + case MT_CTV: pret = "CTV"; break; + case MT_STV: pret = "STV"; break; + default: pret = "Unknown"; + } + return pret; +} + +static void radeon_get_moninfo (rinfo_t *rinfo) +{ + unsigned int tmp; + + tmp = INREG(RADEON_BIOS_4_SCRATCH); + + if (rinfo->hasCRTC2) { + /* primary DVI port */ + if (tmp & 0x08) + rinfo->dviDispType = MT_DFP; + else if (tmp & 0x4) + rinfo->dviDispType = MT_LCD; + else if (tmp & 0x200) + rinfo->dviDispType = MT_CRT; + else if (tmp & 0x10) + rinfo->dviDispType = MT_CTV; + else if (tmp & 0x20) + rinfo->dviDispType = MT_STV; + + /* secondary CRT port */ + if (tmp & 0x2) + rinfo->crtDispType = MT_CRT; + else if (tmp & 0x800) + rinfo->crtDispType = MT_DFP; + else if (tmp & 0x400) + rinfo->crtDispType = MT_LCD; + else if (tmp & 0x1000) + rinfo->crtDispType = MT_CTV; + else if (tmp & 0x2000) + rinfo->crtDispType = MT_STV; + } else { + rinfo->dviDispType = MT_NONE; + + tmp = INREG(FP_GEN_CNTL); + + if (tmp & FP_EN_TMDS) + rinfo->crtDispType = MT_DFP; + else + rinfo->crtDispType = MT_CRT; + } +} +#endif int vixInit( void ) { int err; @@ -924,6 +1058,43 @@ int vixInit( void ) printf(RADEON_MSG" Video memory = %uMb\n",radeon_ram_size/0x100000); err = mtrr_set_type(pci_info.base0,radeon_ram_size,MTRR_TYPE_WRCOMB); if(!err) printf(RADEON_MSG" Set write-combining type of video memory\n"); +#ifndef RAGE128 + { + memset(&rinfo,0,sizeof(rinfo_t)); + switch(def_cap.device_id) + { + case DEVICE_ATI_RADEON_VE_QY: + case DEVICE_ATI_RADEON_VE_QZ: + case DEVICE_ATI_RADEON_MOBILITY_M6: + case DEVICE_ATI_RADEON_MOBILITY_M62: + case DEVICE_ATI_RADEON_MOBILITY_M63: + case DEVICE_ATI_RADEON_QL: + case DEVICE_ATI_RADEON_8500_DV: + case DEVICE_ATI_RADEON_QW: + rinfo.hasCRTC2 = 1; + break; + default: break; + } + radeon_get_moninfo(&rinfo); + if(rinfo.hasCRTC2) { + printf(RADEON_MSG" DVI port has %s monitor connected\n",GET_MON_NAME(rinfo.dviDispType)); + printf(RADEON_MSG" CRT port has %s monitor connected\n",GET_MON_NAME(rinfo.crtDispType)); + } + else + printf(RADEON_MSG" CRT port has %s monitor connected\n",GET_MON_NAME(rinfo.crtDispType)); + } +#endif +#ifdef RADEON_ENABLE_BM + if(bm_open() == 0) + { + if((dma_phys_addrs = malloc(radeon_ram_size*sizeof(unsigned long)/4096)) != 0) + def_cap.flags |= FLAG_DMA | FLAG_EQ_DMA; + else + printf(RADEON_MSG" Can't allocate temopary buffer for DMA\n"); + } + else + if(__verbose) printf(RADEON_MSG" Can't initialize busmastering: %s\n",strerror(errno)); +#endif return 0; } @@ -931,6 +1102,7 @@ void vixDestroy( void ) { unmap_phys_mem(radeon_mem_base,radeon_ram_size); unmap_phys_mem(radeon_mmio_base,0xFFFF); + bm_close(); } int vixGetCapability(vidix_capability_t *to) @@ -939,8 +1111,14 @@ int vixGetCapability(vidix_capability_t *to) return 0; } +/* + Full list of fourcc which are supported by Win2K radeon driver: + YUY2, UYVY, DDES, OGLT, OGL2, OGLS, OGLB, OGNT, OGNZ, OGNS, + IF09, YVU9, IMC4, M2IA, IYUV, VBID, DXT1, DXT2, DXT3, DXT4, DXT5 +*/ uint32_t supported_fourcc[] = { + IMGFMT_Y800, IMGFMT_YVU9, IMGFMT_IF09, IMGFMT_YV12, IMGFMT_I420, IMGFMT_IYUV, IMGFMT_UYVY, IMGFMT_YUY2, IMGFMT_YVYU, IMGFMT_RGB15, IMGFMT_BGR15, @@ -1058,9 +1236,6 @@ static void radeon_vid_display_video( void ) bes_flags = SCALER_ENABLE | SCALER_SMART_SWITCH | -#ifdef RADEON - SCALER_HORZ_PICK_NEAREST | -#endif SCALER_Y2R_TEMP | SCALER_PIX_EXPAND; if(besr.double_buff) bes_flags |= SCALER_DOUBLE_BUFFER; @@ -1071,23 +1246,24 @@ static void radeon_vid_display_video( void ) switch(besr.fourcc) { case IMGFMT_RGB15: - case IMGFMT_BGR15: bes_flags |= SCALER_SOURCE_15BPP; break; + case IMGFMT_BGR15: bes_flags |= SCALER_SOURCE_15BPP | 0x10000000; break; case IMGFMT_RGB16: - case IMGFMT_BGR16: bes_flags |= SCALER_SOURCE_16BPP; break; + case IMGFMT_BGR16: bes_flags |= SCALER_SOURCE_16BPP | 0x10000000; break; /* case IMGFMT_RGB24: case IMGFMT_BGR24: bes_flags |= SCALER_SOURCE_24BPP; break; */ case IMGFMT_RGB32: - case IMGFMT_BGR32: bes_flags |= SCALER_SOURCE_32BPP; break; + case IMGFMT_BGR32: bes_flags |= SCALER_SOURCE_32BPP | 0x10000000; break; /* 4:1:0*/ case IMGFMT_IF09: case IMGFMT_YVU9: bes_flags |= SCALER_SOURCE_YUV9; break; + /* 4:0:0*/ + case IMGFMT_Y800: /* 4:2:0 */ case IMGFMT_IYUV: case IMGFMT_I420: - case IMGFMT_YV12: bes_flags |= SCALER_SOURCE_YUV12; - break; + case IMGFMT_YV12: bes_flags |= SCALER_SOURCE_YUV12; break; /* 4:2:2 */ case IMGFMT_YVYU: case IMGFMT_UYVY: bes_flags |= SCALER_SOURCE_YVYU422; break; @@ -1095,11 +1271,40 @@ static void radeon_vid_display_video( void ) default: bes_flags |= SCALER_SOURCE_VYUY422; break; } OUTREG(OV0_SCALE_CNTL, bes_flags); +#ifndef RAGE128 + if(rinfo.hasCRTC2 && + (rinfo.dviDispType == MT_CTV || rinfo.dviDispType == MT_STV)) + { + /* TODO: suppress scaler output to CRTC here and enable TVO only */ + } +#endif OUTREG(OV0_REG_LOAD_CNTL, 0); - if(__verbose > 1) printf(RADEON_MSG"we wanted: scaler=%08X\n",bes_flags); - if(__verbose > 1) radeon_vid_dump_regs(); + if(__verbose > VERBOSE_LEVEL) printf(RADEON_MSG"we wanted: scaler=%08X\n",bes_flags); + if(__verbose > VERBOSE_LEVEL) radeon_vid_dump_regs(); +} + +/* Goal of this function: hide RGB background and provide black screen around movie. + Useful in '-vo fbdev:vidix -fs -zoom' mode. + Reverse effect to colorkey */ +#ifdef RAGE128 +static void radeon_vid_exclusive( void ) +{ +/* this function works only with Rage128. + Radeon should has something the same */ + unsigned screenw,screenh; + screenw = radeon_get_xres(); + screenh = radeon_get_yres(); + radeon_fifo_wait(2); + OUTREG(OV0_EXCLUSIVE_VERT,(((screenh-1)<<16)&EXCL_VERT_END_MASK)); + OUTREG(OV0_EXCLUSIVE_HORZ,(((screenw/8+1)<<8)&EXCL_HORZ_END_MASK)|EXCL_HORZ_EXCLUSIVE_EN); } +static void radeon_vid_non_exclusive( void ) +{ + OUTREG(OV0_EXCLUSIVE_HORZ,0); +} +#endif + static unsigned radeon_query_pitch(unsigned fourcc,const vidix_yuv_t *spitch) { unsigned pitch,spy,spv,spu; @@ -1140,8 +1345,9 @@ static unsigned radeon_query_pitch(unsigned fourcc,const vidix_yuv_t *spitch) if(spy > 16 && spu == spy/2 && spv == spy/2) pitch = spy; else pitch = 32; break; + case IMGFMT_IF09: case IMGFMT_YVU9: - if(spy > 32 && spu == spy/4 && spv == spy/4) pitch = spy; + if(spy >= 64 && spu == spy/4 && spv == spy/4) pitch = spy; else pitch = 64; break; default: @@ -1155,16 +1361,19 @@ static unsigned radeon_query_pitch(unsigned fourcc,const vidix_yuv_t *spitch) static int radeon_vid_init_video( vidix_playback_t *config ) { uint32_t i,tmp,src_w,src_h,dest_w,dest_h,pitch,h_inc,step_by,left,leftUV,top; - int is_420,is_rgb32,is_rgb,best_pitch,mpitch; + int is_400,is_410,is_420,is_rgb32,is_rgb,best_pitch,mpitch; radeon_vid_stop_video(); left = config->src.x << 16; top = config->src.y << 16; src_h = config->src.h; src_w = config->src.w; - is_420 = is_rgb32 = is_rgb = 0; + is_400 = is_410 = is_420 = is_rgb32 = is_rgb = 0; if(config->fourcc == IMGFMT_YV12 || config->fourcc == IMGFMT_I420 || config->fourcc == IMGFMT_IYUV) is_420 = 1; + if(config->fourcc == IMGFMT_YVU9 || + config->fourcc == IMGFMT_IF09) is_410 = 1; + if(config->fourcc == IMGFMT_Y800) is_400 = 1; if(config->fourcc == IMGFMT_RGB32 || config->fourcc == IMGFMT_BGR32) is_rgb32 = 1; if(config->fourcc == IMGFMT_RGB32 || @@ -1179,7 +1388,11 @@ static int radeon_vid_init_video( vidix_playback_t *config ) mpitch = best_pitch-1; switch(config->fourcc) { + /* 4:0:0*/ + case IMGFMT_Y800: + /* 4:1:0*/ case IMGFMT_YVU9: + case IMGFMT_IF09: /* 4:2:0 */ case IMGFMT_IYUV: case IMGFMT_YV12: @@ -1222,27 +1435,73 @@ static int radeon_vid_init_video( vidix_playback_t *config ) config->offsets[0] = 0; for(i=1;i<besr.vid_nbufs;i++) config->offsets[i] = config->offsets[i-1]+config->frame_size; - if(is_420) + if(is_420 || is_410 || is_400) { uint32_t d1line,d2line,d3line; d1line = top*pitch; - d2line = src_h*pitch+(d1line>>2); - d3line = d2line+((src_h*pitch)>>2); + if(is_420) + { + d2line = src_h*pitch+(d1line>>2); + d3line = d2line+((src_h*pitch)>>2); + } + else + if(is_410) + { + d2line = src_h*pitch+(d1line>>4); + d3line = d2line+((src_h*pitch)>>4); + } + else + { + d2line = 0; + d3line = 0; + } d1line += (left >> 16) & ~15; - d2line += (left >> 17) & ~15; - d3line += (left >> 17) & ~15; + if(is_420) + { + d2line += (left >> 17) & ~15; + d3line += (left >> 17) & ~15; + } + else /* is_410 */ + { + d2line += (left >> 18) & ~15; + d3line += (left >> 18) & ~15; + } config->offset.y = d1line & VIF_BUF0_BASE_ADRS_MASK; - config->offset.v = d2line & VIF_BUF1_BASE_ADRS_MASK; - config->offset.u = d3line & VIF_BUF2_BASE_ADRS_MASK; + if(is_400) + { + config->offset.v = 0; + config->offset.u = 0; + } + else + { + config->offset.v = d2line & VIF_BUF1_BASE_ADRS_MASK; + config->offset.u = d3line & VIF_BUF2_BASE_ADRS_MASK; + } for(i=0;i<besr.vid_nbufs;i++) { besr.vid_buf_base_adrs_y[i]=((radeon_overlay_off+config->offsets[i]+config->offset.y)&VIF_BUF0_BASE_ADRS_MASK); - besr.vid_buf_base_adrs_v[i]=((radeon_overlay_off+config->offsets[i]+config->offset.v)&VIF_BUF1_BASE_ADRS_MASK)|VIF_BUF1_PITCH_SEL; - besr.vid_buf_base_adrs_u[i]=((radeon_overlay_off+config->offsets[i]+config->offset.u)&VIF_BUF2_BASE_ADRS_MASK)|VIF_BUF2_PITCH_SEL; + if(is_400) + { + besr.vid_buf_base_adrs_v[i]=0; + besr.vid_buf_base_adrs_u[i]=0; + } + else + { + besr.vid_buf_base_adrs_v[i]=((radeon_overlay_off+config->offsets[i]+config->offset.v)&VIF_BUF1_BASE_ADRS_MASK)|VIF_BUF1_PITCH_SEL; + besr.vid_buf_base_adrs_u[i]=((radeon_overlay_off+config->offsets[i]+config->offset.u)&VIF_BUF2_BASE_ADRS_MASK)|VIF_BUF2_PITCH_SEL; + } } config->offset.y = ((besr.vid_buf_base_adrs_y[0])&VIF_BUF0_BASE_ADRS_MASK) - radeon_overlay_off; - config->offset.v = ((besr.vid_buf_base_adrs_v[0])&VIF_BUF1_BASE_ADRS_MASK) - radeon_overlay_off; - config->offset.u = ((besr.vid_buf_base_adrs_u[0])&VIF_BUF2_BASE_ADRS_MASK) - radeon_overlay_off; + if(is_400) + { + config->offset.v = 0; + config->offset.u = 0; + } + else + { + config->offset.v = ((besr.vid_buf_base_adrs_v[0])&VIF_BUF1_BASE_ADRS_MASK) - radeon_overlay_off; + config->offset.u = ((besr.vid_buf_base_adrs_u[0])&VIF_BUF2_BASE_ADRS_MASK) - radeon_overlay_off; + } if(besr.fourcc == IMGFMT_I420 || besr.fourcc == IMGFMT_IYUV) { uint32_t tmp; @@ -1266,42 +1525,50 @@ static int radeon_vid_init_video( vidix_playback_t *config ) besr.p1_h_accum_init = ((tmp << 4) & 0x000f8000) | ((tmp << 12) & 0xf0000000); - tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc << 2); - besr.p23_h_accum_init = ((tmp << 4) & 0x000f8000) | - ((tmp << 12) & 0x70000000); tmp = (top & 0x0000ffff) + 0x00018000; besr.p1_v_accum_init = ((tmp << 4) & OV0_P1_V_ACCUM_INIT_MASK) |(OV0_P1_MAX_LN_IN_PER_LN_OUT & 1); + tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc << 2); + besr.p23_h_accum_init = ((tmp << 4) & 0x000f8000) | + ((tmp << 12) & 0x70000000); tmp = ((top >> 1) & 0x0000ffff) + 0x00018000; - besr.p23_v_accum_init = is_420 ? ((tmp << 4) & OV0_P23_V_ACCUM_INIT_MASK) + besr.p23_v_accum_init = (is_420||is_410) ? + ((tmp << 4) & OV0_P23_V_ACCUM_INIT_MASK) |(OV0_P23_MAX_LN_IN_PER_LN_OUT & 1) : 0; - - leftUV = (left >> 17) & 15; + leftUV = (left >> (is_410?18:17)) & 15; left = (left >> 16) & 15; - if(is_rgb && !is_rgb32) h_inc<<=1; - if(is_rgb32) - besr.h_inc = (h_inc >> 1) | ((h_inc >> 1) << 16); + if(is_rgb) + besr.h_inc = (h_inc)|(h_inc<<16); + else + if(is_410) + besr.h_inc = h_inc | ((h_inc >> 2) << 16); else besr.h_inc = h_inc | ((h_inc >> 1) << 16); besr.step_by = step_by | (step_by << 8); besr.y_x_start = (config->dest.x+X_ADJUST) | (config->dest.y << 16); besr.y_x_end = (config->dest.x + dest_w+X_ADJUST) | ((config->dest.y + dest_h) << 16); besr.p1_blank_lines_at_top = P1_BLNK_LN_AT_TOP_M1_MASK|((src_h-1)<<16); - if(is_420) + if(is_420 || is_410) { - src_h = (src_h + 1) >> 1; + src_h = (src_h + 1) >> (is_410?2:1); besr.p23_blank_lines_at_top = P23_BLNK_LN_AT_TOP_M1_MASK|((src_h-1)<<16); } else besr.p23_blank_lines_at_top = 0; besr.vid_buf_pitch0_value = pitch; - besr.vid_buf_pitch1_value = is_420 ? pitch>>1 : pitch; + besr.vid_buf_pitch1_value = is_410 ? pitch>>2 : is_420 ? pitch>>1 : pitch; besr.p1_x_start_end = (src_w+left-1)|(left<<16); - src_w>>=1; - besr.p2_x_start_end = (src_w+left-1)|(leftUV<<16); - besr.p3_x_start_end = besr.p2_x_start_end; - - + if(is_400) + { + besr.p2_x_start_end = 0; + besr.p3_x_start_end = 0; + } + else + { + if(is_410||is_420) src_w>>=is_410?2:1; + besr.p2_x_start_end = (src_w+left-1)|(leftUV<<16); + besr.p3_x_start_end = besr.p2_x_start_end; + } return 0; } @@ -1312,6 +1579,15 @@ static void radeon_compute_framesize(vidix_playback_t *info) dbpp = radeon_vid_get_dbpp(); switch(info->fourcc) { + case IMGFMT_Y800: + awidth = (info->src.w + (pitch-1)) & ~(pitch-1); + info->frame_size = awidth*info->src.h; + break; + case IMGFMT_YVU9: + case IMGFMT_IF09: + awidth = (info->src.w + (pitch-1)) & ~(pitch-1); + info->frame_size = awidth*(info->src.h+info->src.h/8); + break; case IMGFMT_I420: case IMGFMT_YV12: case IMGFMT_IYUV: @@ -1329,11 +1605,13 @@ static void radeon_compute_framesize(vidix_playback_t *info) info->frame_size = awidth*info->src.h; break; } + info->frame_size = (info->frame_size+4095)&~4095; } int vixConfigPlayback(vidix_playback_t *info) { unsigned rgb_size,nfr; + uint32_t radeon_video_size; if(!is_supported_fourcc(info->fourcc)) return ENOSYS; if(info->num_frames>VID_PLAY_MAXFRAMES) info->num_frames=VID_PLAY_MAXFRAMES; if(info->num_frames==1) besr.double_buff=0; @@ -1342,9 +1620,20 @@ int vixConfigPlayback(vidix_playback_t *info) rgb_size = radeon_get_xres()*radeon_get_yres()*((radeon_vid_get_dbpp()+7)/8); nfr = info->num_frames; + radeon_video_size = radeon_ram_size; +#ifdef RADEON_ENABLE_BM + if(def_cap.flags & FLAG_DMA) + { + /* every descriptor describes one 4K page and takes 16 bytes in memory + Note: probably it's ont good idea to locate them in video memory + but as initial release it's OK */ + radeon_video_size -= radeon_ram_size * sizeof(bm_list_descriptor) / 4096; + radeon_dma_desc_base = pci_info.base0 + radeon_video_size; + } +#endif for(;nfr>0; nfr--) { - radeon_overlay_off = radeon_ram_size - info->frame_size*nfr; + radeon_overlay_off = radeon_video_size - info->frame_size*nfr; radeon_overlay_off &= 0xffff0000; if(radeon_overlay_off >= (int)rgb_size ) break; } @@ -1353,7 +1642,7 @@ int vixConfigPlayback(vidix_playback_t *info) nfr = info->num_frames; for(;nfr>0; nfr--) { - radeon_overlay_off = radeon_ram_size - info->frame_size*nfr; + radeon_overlay_off = radeon_video_size - info->frame_size*nfr; radeon_overlay_off &= 0xffff0000; if(radeon_overlay_off > 0) break; } @@ -1368,7 +1657,16 @@ int vixConfigPlayback(vidix_playback_t *info) int vixPlaybackOn( void ) { +#ifdef RAGE128 + unsigned dw,dh; +#endif radeon_vid_display_video(); +#ifdef RAGE128 + dh = (besr.y_x_end >> 16) - (besr.y_x_start >> 16); + dw = (besr.y_x_end & 0xFFFF) - (besr.y_x_start & 0xFFFF); + if(dw == radeon_get_xres() || dh == radeon_get_yres()) radeon_vid_exclusive(); + else radeon_vid_non_exclusive(); +#endif return 0; } @@ -1407,7 +1705,7 @@ int vixPlaybackFrameSelect(unsigned frame) OUTREG(OV0_VID_BUF5_BASE_ADRS, off[5]); OUTREG(OV0_REG_LOAD_CNTL, 0); if(besr.vid_nbufs == 2) radeon_wait_vsync(); - if(__verbose > 1) radeon_vid_dump_regs(); + if(__verbose > VERBOSE_LEVEL) radeon_vid_dump_regs(); return 0; } @@ -1456,7 +1754,7 @@ int vixPlaybackSetEq( const vidix_video_eq_t * eq) #ifdef RAGE128 br = equal.brightness * 64 / 1000; if(br < -64) br = -64; if(br > 63) br = 63; - sat = (equal.saturation + 1000) * 16 / 1000; + sat = (equal.saturation*31 + 31000) / 2000; if(sat < 0) sat = 0; if(sat > 31) sat = 31; OUTREG(OV0_COLOUR_CNTL, (br & 0x7f) | (sat << 8) | (sat << 16)); #else @@ -1604,3 +1902,82 @@ int vixSetGrKeys(const vidix_grkey_t *grkey) set_gr_key(); return(0); } + +#ifdef RADEON_ENABLE_BM +static int radeon_setup_frame( vidix_dma_t * dmai ) +{ + bm_list_descriptor * list = (bm_list_descriptor *)radeon_dma_desc_base; + unsigned long dest_ptr; + unsigned i,n,count; + int retval; + if(dmai->dest_offset + dmai->size > radeon_ram_size) return E2BIG; + n = dmai->size / 4096; + if(dmai->size % 4096) n++; + if((retval = bm_virt_to_bus(dmai->src,dmai->size,dma_phys_addrs)) != 0) return retval; + dest_ptr = dmai->dest_offset; + count = dmai->size; + for(i=0;i<n;i++) + { + list[i].framebuf_offset = radeon_overlay_off + dest_ptr; + list[i].sys_addr = dma_phys_addrs[i]; +#ifdef RAGE128 + list[i].command = (count > 4096 ? 4096 : count | BM_END_OF_LIST)|BM_FORCE_TO_PCI; +#else + list[i].command = (count > 4096 ? 4096 : count | DMA_GUI_COMMAND__EOL); +#endif + list[i].reserved = 0; +printf("RADEON_DMA_TABLE[%i] %X %X %X %X\n",i,list[i].framebuf_offset,list[i].sys_addr,list[i].command,list[i].reserved); + dest_ptr += 4096; + count -= 4096; + } + return 0; +} + +static int radeon_transfer_frame( void ) +{ + unsigned i; + radeon_engine_idle(); + for(i=0;i<1000;i++) INREG(BUS_CNTL); /* FlushWriteCombining */ + OUTREG(BUS_CNTL,(INREG(BUS_CNTL) | BUS_STOP_REQ_DIS)&(~BUS_MASTER_DIS)); +#ifdef RAGE128 + OUTREG(BM_CHUNK_0_VAL,0x000000FF | BM_GLOBAL_FORCE_TO_PCI); + OUTREG(BM_CHUNK_1_VAL,0x0F0F0F0F); + OUTREG(BM_VIP0_BUF,bus_addr_dma_desc|SYSTEM_TRIGGER_SYSTEM_TO_VIDEO); +// OUTREG(GEN_INT_STATUS,INREG(GEN_INT_STATUS)|0x00010000); +#else + OUTREG(MC_FB_LOCATION, + ((pci_info.base0>>16)&0xffff)| + ((pci_info.base0+INREG(CONFIG_APER_SIZE)-1)&0xffff0000)); + if((INREG(MC_AGP_LOCATION)&0xffff)!= + (((pci_info.base0+INREG(CONFIG_APER_SIZE))>>16)&0xffff)) + /*Radeon memory controller is misconfigured*/ + return EINVAL; + OUTREG(DMA_VID_ACT_DSCRPTR,bus_addr_dma_desc); +// OUTREG(GEN_INT_STATUS,INREG(GEN_INT_STATUS)|(1<<30)); +#endif + OUTREG(GEN_INT_STATUS,INREG(GEN_INT_STATUS)|0x00010000); + return 0; +} + + +int vixPlaybackCopyFrame( vidix_dma_t * dmai ) +{ + int retval; + if(mlock(dmai->src,dmai->size) != 0) return errno; + retval = radeon_setup_frame(dmai); + if(retval == 0) retval = radeon_transfer_frame(); + munlock(dmai->src,dmai->size); + return retval; +} + +int vixQueryDMAStatus( void ) +{ + int bm_active; +#if 1 //def RAGE128 + bm_active=(INREG(GEN_INT_STATUS)&0x00010000)==0?1:0; +#else + bm_active=(INREG(GEN_INT_STATUS)&(1<<30))==0?1:0; +#endif + return bm_active?1:0; +} +#endif |