diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/radeon/radeon.h | 29 | ||||
-rw-r--r-- | drivers/radeon/radeon_vid.c | 148 |
2 files changed, 142 insertions, 35 deletions
diff --git a/drivers/radeon/radeon.h b/drivers/radeon/radeon.h index 3715714074..e2ced1f9c5 100644 --- a/drivers/radeon/radeon.h +++ b/drivers/radeon/radeon.h @@ -519,18 +519,30 @@ # define SCALER_GAMMA_SEL_G14 0x00000060L # define SCALER_COMCORE_SHIFT_UP_ONE 0x00000080L # define SCALER_SURFAC_FORMAT 0x00000f00L +# define SCALER_SOURCE_UNK0 0x00000000L /* 2 bpp ??? */ +# define SCALER_SOURCE_UNK1 0x00000100L /* 4 bpp ??? */ +# define SCALER_SOURCE_UNK2 0x00000200L /* 8 bpp ??? */ # define SCALER_SOURCE_15BPP 0x00000300L # define SCALER_SOURCE_16BPP 0x00000400L # define SCALER_SOURCE_24BPP 0x00000500L # define SCALER_SOURCE_32BPP 0x00000600L -# define SCALER_SOURCE_YUV9 0x00000900L +# define SCALER_SOURCE_UNK3 0x00000700L /* 8BPP_RGB332 ??? */ +# define SCALER_SOURCE_UNK4 0x00000800L /* 8BPP_Y8 ??? */ +# define SCALER_SOURCE_YUV9 0x00000900L /* 8BPP_RGB8 */ # define SCALER_SOURCE_YUV12 0x00000A00L # define SCALER_SOURCE_VYUY422 0x00000B00L # define SCALER_SOURCE_YVYU422 0x00000C00L +# define SCALER_SOURCE_UNK5 0x00000D00L /* ??? */ +# define SCALER_SOURCE_UNK6 0x00000E00L /* 32BPP_AYUV444 */ +# define SCALER_SOURCE_UNK7 0x00000F00L /* 16BPP_ARGB4444 */ # define SCALER_ADAPTIVE_DEINT 0x00001000L +# define SCALER_UNKNOWN_FLAG0 0x00002000L /* ??? */ +# define SCALER_UNKNOWN_FLAG1 0x00004000L /* ??? */ # define SCALER_SMART_SWITCH 0x00008000L # define SCALER_BURST_PER_PLANE 0x00ff0000L # define SCALER_DOUBLE_BUFFER 0x01000000L +# define SCALER_UNKNOWN_FLAG3 0x02000000L /* ??? */ +# define SCALER_UNKNOWN_FLAG4 0x04000000L /* ??? */ # define SCALER_DIS_LIMIT 0x08000000L # define SCALER_PRG_LOAD_START 0x10000000L # define SCALER_INT_EMU 0x20000000L @@ -541,6 +553,8 @@ # define OV0_P1_MAX_LN_IN_PER_LN_OUT 0x00000003L # define OV0_P1_V_ACCUM_INIT_MASK 0x01ff8000L #define OV0_P23_V_ACCUM_INIT 0x042C +# define OV0_P23_MAX_LN_IN_PER_LN_OUT 0x00000003L +# define OV0_P23_V_ACCUM_INIT_MASK 0x01ff8000L #define OV0_P1_BLANK_LINES_AT_TOP 0x0430 # define P1_BLNK_LN_AT_TOP_M1_MASK 0x00000fffL # define P1_ACTIVE_LINES_M1 0x0fff0000L @@ -564,10 +578,23 @@ # define VIF_BUF2_BASE_ADRS_MASK 0x03fffff0L # define VIF_BUF2_1ST_LINE_LSBS_MASK 0x48000000L #define OV0_VID_BUF3_BASE_ADRS 0x044C +# define VIF_BUF3_PITCH_SEL 0x00000001L +# define VIF_BUF3_TILE_ADRS 0x00000002L +# define VIF_BUF3_BASE_ADRS_MASK 0x03fffff0L +# define VIF_BUF3_1ST_LINE_LSBS_MASK 0x48000000L #define OV0_VID_BUF4_BASE_ADRS 0x0450 +# define VIF_BUF4_PITCH_SEL 0x00000001L +# define VIF_BUF4_TILE_ADRS 0x00000002L +# define VIF_BUF4_BASE_ADRS_MASK 0x03fffff0L +# define VIF_BUF4_1ST_LINE_LSBS_MASK 0x48000000L #define OV0_VID_BUF5_BASE_ADRS 0x0454 +# define VIF_BUF5_PITCH_SEL 0x00000001L +# define VIF_BUF5_TILE_ADRS 0x00000002L +# define VIF_BUF5_BASE_ADRS_MASK 0x03fffff0L +# define VIF_BUF5_1ST_LINE_LSBS_MASK 0x48000000L #define OV0_VID_BUF_PITCH0_VALUE 0x0460 #define OV0_VID_BUF_PITCH1_VALUE 0x0464 +#define OV0_VID_BUF_PITCH2_VALUE 0x0468 #define OV0_AUTO_FLIP_CNTL 0x0470 # define OV0_AUTO_FLIP_CNTL_SOFT_BUF_NUM 0x00000007 # define OV0_AUTO_FLIP_CNTL_SOFT_REPEAT_FIELD 0x00000008 diff --git a/drivers/radeon/radeon_vid.c b/drivers/radeon/radeon_vid.c index 4ddcbf7049..0177dd8709 100644 --- a/drivers/radeon/radeon_vid.c +++ b/drivers/radeon/radeon_vid.c @@ -21,17 +21,24 @@ mknod /dev/radeon_vid c 178 0 */ +/* TESTED and WORKING formats: YUY2 */ + /* TODO: - OV0_COLOUR_CNTL brightness saturation - SCALER_GAMMA_SEL_BRIGHT gamma correction ??? - OV0_GRAPHICS_KEY_CLR color key - OV0_AUTO_FLIP_CNTL - OV0_FILTER_CNTL - OV0_VIDEO_KEY_CLR - OV0_KEY_CNTL - - BPP should be known + Highest priority: fbvid.h compatibility and UYVY test + High priority: YV12, I420, IYUV support + Middle priority: + OV0_COLOUR_CNTL brightness saturation + SCALER_GAMMA_SEL_BRIGHT gamma correction ??? + OV0_GRAPHICS_KEY_CLR color key + OV0_AUTO_FLIP_CNTL + OV0_FILTER_CNTL + OV0_VIDEO_KEY_CLR + OV0_KEY_CNTL + Low priority: RGB/BGR 2-32, YVU9, IF09, CLPL, IYU1, IYU2, UYNV, CYUV + YUNV, YVYU, Y41P, Y211, Y41T, Y42T, V422, V655, CLJR + ^^^^ + YUVP, UYVP, Mpeg PES (mpeg-1,2) support */ #include <linux/config.h> @@ -90,6 +97,7 @@ typedef struct bes_registers_s uint32_t p1_x_start_end; uint32_t p2_x_start_end; uint32_t p3_x_start_end; + uint32_t base_addr; uint32_t vid_buf0_base_adrs; /* These ones are for auto flip: maybe in the future */ uint32_t vid_buf1_base_adrs; @@ -135,6 +143,7 @@ static video_registers_t vregs[] = { OV0_P1_X_START_END, 0 }, { OV0_P2_X_START_END, 0 }, { OV0_P3_X_START_END, 0 }, + { OV0_BASE_ADDR, 0 }, { OV0_VID_BUF0_BASE_ADRS, 0 }, { OV0_VID_BUF1_BASE_ADRS, 0 }, { OV0_VID_BUF2_BASE_ADRS, 0 }, @@ -174,6 +183,48 @@ static mga_vid_config_t radeon_config; #define RTRACE(...) ((void)0) #endif +static char *fourcc_format_name(int format) +{ + switch(format) + { + case IMGFMT_RGB8: return("RGB 8-bit"); + case IMGFMT_RGB15: return("RGB 15-bit"); + case IMGFMT_RGB16: return("RGB 16-bit"); + case IMGFMT_RGB24: return("RGB 24-bit"); + case IMGFMT_RGB32: return("RGB 32-bit"); + case IMGFMT_BGR8: return("BGR 8-bit"); + case IMGFMT_BGR15: return("BGR 15-bit"); + case IMGFMT_BGR16: return("BGR 16-bit"); + case IMGFMT_BGR24: return("BGR 24-bit"); + case IMGFMT_BGR32: return("BGR 32-bit"); + case IMGFMT_YVU9: return("Planar YVU9"); + case IMGFMT_IF09: return("Planar IF09"); + case IMGFMT_YV12: return("Planar YV12"); + case IMGFMT_I420: return("Planar I420"); + case IMGFMT_IYUV: return("Planar IYUV"); + case IMGFMT_CLPL: return("Planar CLPL"); + case IMGFMT_IYU1: return("Packed IYU1"); + case IMGFMT_IYU2: return("Packed IYU2"); + case IMGFMT_UYVY: return("Packed UYVY"); + case IMGFMT_UYNV: return("Packed UYNV"); + case IMGFMT_cyuv: return("Packed CYUV"); + case IMGFMT_YUY2: return("Packed YUY2"); + case IMGFMT_YUNV: return("Packed YUNV"); + case IMGFMT_YVYU: return("Packed YVYU"); + case IMGFMT_Y41P: return("Packed Y41P"); + case IMGFMT_Y211: return("Packed Y211"); + case IMGFMT_Y41T: return("Packed Y41T"); + case IMGFMT_Y42T: return("Packed Y42T"); + case IMGFMT_V422: return("Packed V422"); + case IMGFMT_V655: return("Packed V655"); + case IMGFMT_CLJR: return("Packed CLJR"); + case IMGFMT_YUVP: return("Packed YUVP"); + case IMGFMT_UYVP: return("Packed UYVP"); +/* case IMGFMT_MPEGPES: return("Mpeg PES");*/ + } + return("Unknown"); +} + /* * IO macros @@ -247,6 +298,9 @@ RTRACE("radeon_vid: OV0: p1_v_accum_init=%x p1_h_accum_init=%x p23_h_accum_init= OUTREG(OV0_P1_X_START_END, besr.p1_x_start_end); OUTREG(OV0_P2_X_START_END, besr.p2_x_start_end); OUTREG(OV0_P3_X_START_END, besr.p3_x_start_end); +#if 0 + OUTREG(OV0_BASE_ADDR, besr.base_addr); +#endif OUTREG(OV0_VID_BUF0_BASE_ADRS, besr.vid_buf0_base_adrs); OUTREG(OV0_VID_BUF1_BASE_ADRS, besr.vid_buf1_base_adrs); OUTREG(OV0_VID_BUF2_BASE_ADRS, besr.vid_buf2_base_adrs); @@ -275,12 +329,10 @@ RTRACE("radeon_vid: OV0: p1_v_accum_init=%x p1_h_accum_init=%x p23_h_accum_init= case IMGFMT_UYVY: bes_flags |= SCALER_SOURCE_YVYU422; break; case IMGFMT_YVU9: bes_flags |= SCALER_SOURCE_YUV9; break; - case IMGFMT_IYUV: bes_flags |= SCALER_SOURCE_YUV12; break; - + + case IMGFMT_IYUV: case IMGFMT_I420: - case IMGFMT_YV12: bes_flags |= SCALER_SOURCE_YUV12 | - SCALER_PIX_EXPAND | - SCALER_Y2R_TEMP; + case IMGFMT_YV12: bes_flags |= SCALER_SOURCE_YUV12; break; case IMGFMT_YUY2: default: bes_flags |= SCALER_SOURCE_VYUY422; break; @@ -360,7 +412,9 @@ RTRACE("radeon_vid: usr_config: version = %x format=%x card=%x ram=%u src(%ux%u) return -1; } is_420 = 0; - if(config->format == IMGFMT_YV12 || config->format == IMGFMT_I420) is_420 = 1; + if(config->format == IMGFMT_YV12 || + config->format == IMGFMT_I420 || + config->format == IMGFMT_IYUV) is_420 = 1; switch(config->format) { default: @@ -392,17 +446,17 @@ RTRACE("radeon_vid: usr_config: version = %x format=%x card=%x ram=%u src(%ux%u) } /* keep everything in 16.16 */ - + besr.base_addr = radeon_overlay_off; if(is_420) { uint32_t dstPitch,d1line,d2line,d3line; dstPitch = ((src_w + 15) & ~15); /* of luma */ - d1line = top * dstPitch; - d2line = (src_h * dstPitch) + ((top >> 1) * (dstPitch >> 1)); - d3line = d2line + ((src_h >> 1) * (dstPitch >> 1)); - besr.vid_buf0_base_adrs = ((radeon_overlay_off + d1line) & VIF_BUF0_BASE_ADRS_MASK) | VIF_BUF0_PITCH_SEL; - besr.vid_buf1_base_adrs = ((radeon_overlay_off + d2line) & VIF_BUF1_BASE_ADRS_MASK) | VIF_BUF1_PITCH_SEL; - besr.vid_buf2_base_adrs = ((radeon_overlay_off + d3line) & VIF_BUF2_BASE_ADRS_MASK) | VIF_BUF2_PITCH_SEL; + d1line = top*dstPitch; + d2line = src_h*dstPitch+(d1line>>1); + d3line = d2line+((src_h*dstPitch)>>2); + besr.vid_buf0_base_adrs=((radeon_overlay_off+d1line)&VIF_BUF0_BASE_ADRS_MASK)|VIF_BUF0_PITCH_SEL; + besr.vid_buf1_base_adrs=((radeon_overlay_off+d2line)&VIF_BUF1_BASE_ADRS_MASK)|VIF_BUF0_PITCH_SEL; + besr.vid_buf2_base_adrs=((radeon_overlay_off+d3line)&VIF_BUF2_BASE_ADRS_MASK)|VIF_BUF0_PITCH_SEL; } else { @@ -424,11 +478,12 @@ RTRACE("radeon_vid: usr_config: version = %x format=%x card=%x ram=%u src(%ux%u) ((tmp << 12) & 0x70000000); tmp = (top & 0x0000ffff) + 0x00018000; - besr.p1_v_accum_init = ((tmp << 4) & 0x03ff8000) | 0x00000001; - + besr.p1_v_accum_init = ((tmp << 4) & OV0_P1_V_ACCUM_INIT_MASK) + |(OV0_P1_MAX_LN_IN_PER_LN_OUT & 1); tmp = ((top >> 1) & 0x0000ffff) + 0x00018000; - besr.p23_v_accum_init = is_420 ? ((tmp << 4) & 0x01ff8000) | 0x00000001 : 0; + besr.p23_v_accum_init = is_420 ? ((tmp << 4) & OV0_P23_V_ACCUM_INIT_MASK) + |(OV0_P23_MAX_LN_IN_PER_LN_OUT & 1) : 0; leftUV = (left >> 17) & 15; left = (left >> 16) & 15; @@ -437,8 +492,12 @@ RTRACE("radeon_vid: usr_config: version = %x format=%x card=%x ram=%u src(%ux%u) besr.y_x_start = (config->x_org+8) | (config->y_org << 16); besr.y_x_end = (config->x_org + config->dest_width+8) | ((config->y_org + config->dest_height) << 16); besr.p1_blank_lines_at_top = P1_BLNK_LN_AT_TOP_M1_MASK|((src_h-1)<<16); - src_h = (src_h + 1) >> 1; - besr.p23_blank_lines_at_top = is_420 ? P23_BLNK_LN_AT_TOP_M1_MASK|((src_h-1)<<16):0; + if(is_420) + { + src_h = (src_h + 1) >> 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; RTRACE("radeon_vid: BES: v_inc=%x h_inc=%x step_by=%x\n",besr.v_inc,besr.h_inc,besr.step_by); @@ -446,9 +505,25 @@ RTRACE("radeon_vid: BES: vid_buf0_basey=%x\n",besr.vid_buf0_base_adrs); RTRACE("radeon_vid: BES: y_x_start=%x y_x_end=%x blank_at_top=%x pitch0_value=%x\n" ,besr.y_x_start,besr.y_x_end,besr.p1_blank_lines_at_top,besr.vid_buf_pitch0_value); 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_420) + { + if(config->format == IMGFMT_YV12) + { + besr.p3_x_start_end = ((src_w/2)+left-1)|((leftUV)<<16); + besr.p2_x_start_end = (src_w+left-1)|((src_w/2+leftUV)<<16); + } + else + { + besr.p2_x_start_end = ((src_w/2)+left-1)|((leftUV)<<16); + besr.p3_x_start_end = (src_w+left-1)|((src_w/2+leftUV)<<16); + } + } + else + { + src_w>>=1; + besr.p2_x_start_end = (src_w+left-1)|(leftUV<<16); + besr.p3_x_start_end = besr.p2_x_start_end; + } return 0; } @@ -523,6 +598,7 @@ static int radeon_vid_ioctl(struct inode *inode, struct file *file, unsigned int printk( "radeon_vid: failed copy to userspace\n"); return -EFAULT; } + printk("radeon_vid: configuring for '%s' fourcc\n",fourcc_format_name(radeon_config.format)); return radeon_vid_init_video(&radeon_config); break; @@ -582,9 +658,7 @@ static int radeon_vid_config_card(void) for(i=0;i<sizeof(ati_card_ids)/sizeof(struct ati_card_id_s);i++) if((dev=pci_find_device(PCI_VENDOR_ID_ATI, ati_card_ids[i].id, NULL))) break; - if(dev) - printk("radeon_vid: Found %s\n",ati_card_ids[i].name); - else + if(!dev) { printk("radeon_vid: No supported cards found\n"); return FALSE; @@ -596,7 +670,13 @@ static int radeon_vid_config_card(void) RTRACE( "radeon_vid: MMIO at 0x%p\n", radeon_mmio_base); RTRACE( "radeon_vid: Frame Buffer at 0x%08x\n", radeon_mem_base); - radeon_ram_size = pci_resource_len(dev, 0)/0x100000; + /* video memory size */ + radeon_ram_size = INREG(CONFIG_MEMSIZE); + + /* mem size is bits [28:0], mask off the rest */ + radeon_ram_size &= CONFIG_MEMSIZE_MASK; + radeon_ram_size /= 0x100000; + printk("radeon_vid: Found %s (%uMb memory)\n",ati_card_ids[i].name,radeon_ram_size); return TRUE; } |