summaryrefslogtreecommitdiffstats
path: root/vidix/drivers/radeon_vid.c
diff options
context:
space:
mode:
Diffstat (limited to 'vidix/drivers/radeon_vid.c')
-rw-r--r--vidix/drivers/radeon_vid.c136
1 files changed, 113 insertions, 23 deletions
diff --git a/vidix/drivers/radeon_vid.c b/vidix/drivers/radeon_vid.c
index c085781b14..1393a49e5f 100644
--- a/vidix/drivers/radeon_vid.c
+++ b/vidix/drivers/radeon_vid.c
@@ -280,6 +280,49 @@ static void radeon_wait_vsync(void)
}
}
+#ifdef RAGE128
+static void _radeon_engine_idle(void);
+static void _radeon_fifo_wait(unsigned);
+#define radeon_engine_idle() _radeon_engine_idle()
+#define radeon_fifo_wait(entries) _radeon_fifo_wait(entries)
+/* Flush all dirty data in the Pixel Cache to memory. */
+static __inline__ void radeon_engine_flush ( void )
+{
+ unsigned i;
+
+ OUTREGP(PC_NGUI_CTLSTAT, PC_FLUSH_ALL, ~PC_FLUSH_ALL);
+ for (i = 0; i < 2000000; i++) {
+ if (!(INREG(PC_NGUI_CTLSTAT) & PC_BUSY)) break;
+ }
+}
+
+/* Reset graphics card to known state. */
+static void radeon_engine_reset( void )
+{
+ uint32_t clock_cntl_index;
+ uint32_t mclk_cntl;
+ uint32_t gen_reset_cntl;
+
+ radeon_engine_flush();
+
+ clock_cntl_index = INREG(CLOCK_CNTL_INDEX);
+ mclk_cntl = INPLL(MCLK_CNTL);
+
+ OUTPLL(MCLK_CNTL, mclk_cntl | FORCE_GCP | FORCE_PIPE3D_CP);
+
+ gen_reset_cntl = INREG(GEN_RESET_CNTL);
+
+ OUTREG(GEN_RESET_CNTL, gen_reset_cntl | SOFT_RESET_GUI);
+ INREG(GEN_RESET_CNTL);
+ OUTREG(GEN_RESET_CNTL,
+ gen_reset_cntl & (uint32_t)(~SOFT_RESET_GUI));
+ INREG(GEN_RESET_CNTL);
+
+ OUTPLL(MCLK_CNTL, mclk_cntl);
+ OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
+ OUTREG(GEN_RESET_CNTL, gen_reset_cntl);
+}
+#else
static __inline__ void radeon_engine_flush ( void )
{
@@ -345,9 +388,10 @@ static void radeon_engine_reset( void )
return;
}
-
+#endif
static void radeon_engine_restore( void )
{
+#ifndef RAGE128
int pitch64;
uint32_t xres,yres,bpp;
radeon_fifo_wait(1);
@@ -389,16 +433,17 @@ static void radeon_engine_restore( void )
OUTREG(DP_WRITE_MASK, 0xffffffff);
radeon_engine_idle();
+#endif
}
-
+#ifdef RAGE128
static void _radeon_fifo_wait (unsigned entries)
{
- int i;
+ unsigned i;
for(;;)
{
for (i=0; i<2000000; i++)
- if ((INREG(RBBM_STATUS) & RBBM_FIFOCNT_MASK) >= entries)
+ if ((INREG(GUI_STAT) & GUI_FIFOCNT_MASK) >= entries)
return;
radeon_engine_reset();
radeon_engine_restore();
@@ -407,14 +452,14 @@ static void _radeon_fifo_wait (unsigned entries)
static void _radeon_engine_idle ( void )
{
- int i;
+ unsigned i;
/* ensure FIFO is empty before waiting for idle */
radeon_fifo_wait (64);
for(;;)
{
for (i=0; i<2000000; i++) {
- if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
+ if ((INREG(GUI_STAT) & GUI_ACTIVE) == 0) {
radeon_engine_flush ();
return;
}
@@ -423,8 +468,39 @@ static void _radeon_engine_idle ( void )
radeon_engine_restore();
}
}
+#else
+static void _radeon_fifo_wait (unsigned entries)
+{
+ unsigned i;
+ for(;;)
+ {
+ for (i=0; i<2000000; i++)
+ if ((INREG(RBBM_STATUS) & RBBM_FIFOCNT_MASK) >= entries)
+ return;
+ radeon_engine_reset();
+ radeon_engine_restore();
+ }
+}
+static void _radeon_engine_idle ( void )
+{
+ int i;
+ /* ensure FIFO is empty before waiting for idle */
+ radeon_fifo_wait (64);
+ for(;;)
+ {
+ for (i=0; i<2000000; i++) {
+ if (((INREG(RBBM_STATUS) & RBBM_ACTIVE)) == 0) {
+ radeon_engine_flush ();
+ return;
+ }
+ }
+ radeon_engine_reset();
+ radeon_engine_restore();
+ }
+}
+#endif
#ifndef RAGE128
/* Reference color space transform data */
@@ -1064,6 +1140,10 @@ 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_YVU9:
+ if(spy > 32 && spu == spy/4 && spv == spy/4) pitch = spy;
+ else pitch = 64;
+ break;
default:
if(spy >= 16) pitch = spy;
else pitch = 16;
@@ -1099,6 +1179,7 @@ static int radeon_vid_init_video( vidix_playback_t *config )
mpitch = best_pitch-1;
switch(config->fourcc)
{
+ case IMGFMT_YVU9:
/* 4:2:0 */
case IMGFMT_IYUV:
case IMGFMT_YV12:
@@ -1125,11 +1206,10 @@ static int radeon_vid_init_video( vidix_playback_t *config )
dest_w = config->dest.w;
dest_h = config->dest.h;
if(radeon_is_dbl_scan()) dest_h *= 2;
- else
- if(radeon_is_interlace()) dest_h /= 2;
besr.dest_bpp = radeon_vid_get_dbpp();
besr.fourcc = config->fourcc;
besr.v_inc = (src_h << 20) / dest_h;
+ if(radeon_is_interlace()) besr.v_inc *= 2;
h_inc = (src_w << 12) / dest_w;
step_by = 1;
while(h_inc >= (2 << 12)) {
@@ -1236,46 +1316,50 @@ static void radeon_compute_framesize(vidix_playback_t *info)
case IMGFMT_YV12:
case IMGFMT_IYUV:
awidth = (info->src.w + (pitch-1)) & ~(pitch-1);
- info->frame_size = (awidth*(info->src.h+info->src.h/2)+dbpp-1)/dbpp;
+ info->frame_size = awidth*(info->src.h+info->src.h/2);
break;
case IMGFMT_RGB32:
case IMGFMT_BGR32:
awidth = (info->src.w*4 + (pitch-1)) & ~(pitch-1);
- info->frame_size = ((awidth*info->src.h)+dbpp-1)/dbpp;
+ info->frame_size = awidth*info->src.h;
break;
/* YUY2 YVYU, RGB15, RGB16 */
default:
awidth = (info->src.w*2 + (pitch-1)) & ~(pitch-1);
- info->frame_size = ((awidth*info->src.h)+dbpp-1)/dbpp;
+ info->frame_size = awidth*info->src.h;
break;
}
- info->frame_size *= dbpp;
}
int vixConfigPlayback(vidix_playback_t *info)
{
- unsigned rgb_size;
+ unsigned rgb_size,nfr;
if(!is_supported_fourcc(info->fourcc)) return ENOSYS;
- if(info->num_frames>=VID_PLAY_MAXFRAMES) info->num_frames=VID_PLAY_MAXFRAMES-1;
+ if(info->num_frames>VID_PLAY_MAXFRAMES) info->num_frames=VID_PLAY_MAXFRAMES;
if(info->num_frames==1) besr.double_buff=0;
else besr.double_buff=1;
radeon_compute_framesize(info);
- rgb_size = radeon_get_xres()*radeon_get_yres()*radeon_vid_get_dbpp();
- for(;info->num_frames>0; info->num_frames--)
+ rgb_size = radeon_get_xres()*radeon_get_yres()*((radeon_vid_get_dbpp()+7)/8);
+ nfr = info->num_frames;
+ for(;nfr>0; nfr--)
{
- radeon_overlay_off = radeon_ram_size - info->frame_size*info->num_frames;
+ radeon_overlay_off = radeon_ram_size - info->frame_size*nfr;
radeon_overlay_off &= 0xffff0000;
if(radeon_overlay_off >= (int)rgb_size ) break;
}
- if(info->num_frames <= 3)
- for(;info->num_frames>0; info->num_frames--)
+ if(nfr <= 3)
+ {
+ nfr = info->num_frames;
+ for(;nfr>0; nfr--)
{
- radeon_overlay_off = radeon_ram_size - info->frame_size*info->num_frames;
+ radeon_overlay_off = radeon_ram_size - info->frame_size*nfr;
radeon_overlay_off &= 0xffff0000;
if(radeon_overlay_off > 0) break;
}
- if(info->num_frames <= 0) return EINVAL;
+ }
+ if(nfr <= 0) return EINVAL;
+ info->num_frames = nfr;
besr.vid_nbufs = info->num_frames;
info->dga_addr = (char *)radeon_mem_base + radeon_overlay_off;
radeon_vid_init_video(info);
@@ -1453,9 +1537,10 @@ static void set_gr_key( void )
{
if(radeon_grkey.ckey.op == CKEY_TRUE)
{
+ int dbpp=radeon_vid_get_dbpp();
besr.ckey_on=1;
- switch(radeon_vid_get_dbpp())
+ switch(dbpp)
{
case 15:
besr.graphics_key_clr=
@@ -1486,8 +1571,13 @@ static void set_gr_key( void )
besr.graphics_key_msk=0;
besr.graphics_key_clr=0;
}
- besr.graphics_key_msk = besr.graphics_key_clr;
+#ifdef RAGE128
+ besr.graphics_key_msk=(1<<dbpp)-1;
+ besr.ckey_cntl = VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_NE|CMP_MIX_AND;
+#else
+ besr.graphics_key_msk=besr.graphics_key_clr;
besr.ckey_cntl = VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_EQ|CMP_MIX_AND;
+#endif
}
else
{