comparison vidix/drivers/radeon_vid.c @ 4666:a093bb34b723

- Shutdown capturing before playback - More correct waiting for vsync (Note: "quaking" is still there (unlike GATOS)) :(
author nick
date Tue, 12 Feb 2002 10:36:43 +0000
parents 7b793875a640
children 61f4b8fd380e
comparison
equal deleted inserted replaced
4665:80256840ff29 4666:a093bb34b723
209 _tmp &= (mask); \ 209 _tmp &= (mask); \
210 _tmp |= (val); \ 210 _tmp |= (val); \
211 OUTREG(addr, _tmp); \ 211 OUTREG(addr, _tmp); \
212 } while (0) 212 } while (0)
213 213
214 static __inline__ uint32_t INPLL(uint32_t addr)
215 {
216 OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000001f);
217 return (INREG(CLOCK_CNTL_DATA));
218 }
219
220 #define OUTPLL(addr,val) OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000001f) | 0x00000080); \
221 OUTREG(CLOCK_CNTL_DATA, val)
222 #define OUTPLLP(addr,val,mask) \
223 do { \
224 unsigned int _tmp = INPLL(addr); \
225 _tmp &= (mask); \
226 _tmp |= (val); \
227 OUTPLL(addr, _tmp); \
228 } while (0)
229
214 static uint32_t radeon_vid_get_dbpp( void ) 230 static uint32_t radeon_vid_get_dbpp( void )
215 { 231 {
216 uint32_t dbpp,retval; 232 uint32_t dbpp,retval;
217 dbpp = (INREG(CRTC_GEN_CNTL)>>8)& 0xF; 233 dbpp = (INREG(CRTC_GEN_CNTL)>>8)& 0xF;
218 switch(dbpp) 234 switch(dbpp)
234 static int radeon_is_interlace( void ) 250 static int radeon_is_interlace( void )
235 { 251 {
236 return (INREG(CRTC_GEN_CNTL))&CRTC_INTERLACE_EN; 252 return (INREG(CRTC_GEN_CNTL))&CRTC_INTERLACE_EN;
237 } 253 }
238 254
255 static uint32_t radeon_get_xres( void )
256 {
257 /* FIXME: currently we extract that from CRTC!!!*/
258 uint32_t xres,h_total;
259 h_total = INREG(CRTC_H_TOTAL_DISP);
260 xres = (h_total >> 16) & 0xffff;
261 return (xres + 1)*8;
262 }
263
264 static uint32_t radeon_get_yres( void )
265 {
266 /* FIXME: currently we extract that from CRTC!!!*/
267 uint32_t yres,v_total;
268 v_total = INREG(CRTC_V_TOTAL_DISP);
269 yres = (v_total >> 16) & 0xffff;
270 return yres + 1;
271 }
272
239 static __inline__ void radeon_engine_flush ( void ) 273 static __inline__ void radeon_engine_flush ( void )
240 { 274 {
241 int i; 275 int i;
242 276
243 /* initiate flush */ 277 /* initiate flush */
248 if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY)) 282 if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
249 break; 283 break;
250 } 284 }
251 } 285 }
252 286
253 287 static void _radeon_engine_idle(void);
254 static __inline__ void _radeon_fifo_wait (unsigned entries) 288 static void _radeon_fifo_wait(unsigned);
255 { 289 #define radeon_engine_idle() _radeon_engine_idle()
256 int i; 290 #define radeon_fifo_wait(entries) _radeon_fifo_wait(entries)
257 291
292 static void radeon_engine_reset( void )
293 {
294 uint32_t clock_cntl_index, mclk_cntl, rbbm_soft_reset;
295
296 radeon_engine_flush ();
297
298 clock_cntl_index = INREG(CLOCK_CNTL_INDEX);
299 mclk_cntl = INPLL(MCLK_CNTL);
300
301 OUTPLL(MCLK_CNTL, (mclk_cntl |
302 FORCEON_MCLKA |
303 FORCEON_MCLKB |
304 FORCEON_YCLKA |
305 FORCEON_YCLKB |
306 FORCEON_MC |
307 FORCEON_AIC));
308 rbbm_soft_reset = INREG(RBBM_SOFT_RESET);
309
310 OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset |
311 SOFT_RESET_CP |
312 SOFT_RESET_HI |
313 SOFT_RESET_SE |
314 SOFT_RESET_RE |
315 SOFT_RESET_PP |
316 SOFT_RESET_E2 |
317 SOFT_RESET_RB |
318 SOFT_RESET_HDP);
319 INREG(RBBM_SOFT_RESET);
320 OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset & (uint32_t)
321 ~(SOFT_RESET_CP |
322 SOFT_RESET_HI |
323 SOFT_RESET_SE |
324 SOFT_RESET_RE |
325 SOFT_RESET_PP |
326 SOFT_RESET_E2 |
327 SOFT_RESET_RB |
328 SOFT_RESET_HDP));
329 INREG(RBBM_SOFT_RESET);
330
331 OUTPLL(MCLK_CNTL, mclk_cntl);
332 OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
333 OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
334
335 return;
336 }
337
338 static void radeon_engine_restore( void )
339 {
340 int pitch64;
341 uint32_t xres,yres,bpp;
342 radeon_fifo_wait(1);
343 xres = radeon_get_xres();
344 yres = radeon_get_yres();
345 bpp = radeon_vid_get_dbpp();
346 /* turn of all automatic flushing - we'll do it all */
347 OUTREG(RB2D_DSTCACHE_MODE, 0);
348
349 pitch64 = ((xres * (bpp / 8) + 0x3f)) >> 6;
350
351 radeon_fifo_wait(1);
352 OUTREG(DEFAULT_OFFSET, (INREG(DEFAULT_OFFSET) & 0xC0000000) |
353 (pitch64 << 22));
354
355 radeon_fifo_wait(1);
356 #if defined(__BIG_ENDIAN)
357 OUTREGP(DP_DATATYPE,
358 HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN);
359 #else
360 OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
361 #endif
362
363 radeon_fifo_wait(1);
364 OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX
365 | DEFAULT_SC_BOTTOM_MAX));
366 radeon_fifo_wait(1);
367 OUTREG(DP_GUI_MASTER_CNTL, (INREG(DP_GUI_MASTER_CNTL)
368 | GMC_BRUSH_SOLID_COLOR
369 | GMC_SRC_DATATYPE_COLOR));
370
371 radeon_fifo_wait(7);
372 OUTREG(DST_LINE_START, 0);
373 OUTREG(DST_LINE_END, 0);
374 OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff);
375 OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000);
376 OUTREG(DP_SRC_FRGD_CLR, 0xffffffff);
377 OUTREG(DP_SRC_BKGD_CLR, 0x00000000);
378 OUTREG(DP_WRITE_MASK, 0xffffffff);
379
380 radeon_engine_idle();
381 }
382
383 static void _radeon_fifo_wait (unsigned entries)
384 {
385 int i;
386
387 for(;;)
388 {
258 for (i=0; i<2000000; i++) 389 for (i=0; i<2000000; i++)
259 if ((INREG(RBBM_STATUS) & 0x7f) >= entries) 390 if ((INREG(RBBM_STATUS) & RBBM_FIFOCNT_MASK) >= entries)
260 return; 391 return;
261 } 392 radeon_engine_reset();
262 393 radeon_engine_restore();
263 394 }
264 static __inline__ void _radeon_engine_idle ( void ) 395 }
265 { 396
266 int i; 397 static void _radeon_engine_idle ( void )
267 398 {
268 /* ensure FIFO is empty before waiting for idle */ 399 int i;
269 _radeon_fifo_wait (64); 400
270 401 /* ensure FIFO is empty before waiting for idle */
402 radeon_fifo_wait (64);
403 for(;;)
404 {
271 for (i=0; i<2000000; i++) { 405 for (i=0; i<2000000; i++) {
272 if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) { 406 if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
273 radeon_engine_flush (); 407 radeon_engine_flush ();
274 return; 408 return;
275 } 409 }
276 } 410 }
277 } 411 radeon_engine_reset();
278 412 radeon_engine_restore();
279 #define radeon_engine_idle() _radeon_engine_idle() 413 }
280 #define radeon_fifo_wait(entries) _radeon_fifo_wait(entries) 414 }
415
281 416
282 417
283 #ifndef RAGE128 418 #ifndef RAGE128
284 /* Reference color space transform data */ 419 /* Reference color space transform data */
285 typedef struct tagREF_TRANSFORM 420 typedef struct tagREF_TRANSFORM
751 printf(RADEON_MSG"*** Begin of DRIVER variables dump ***\n"); 886 printf(RADEON_MSG"*** Begin of DRIVER variables dump ***\n");
752 printf(RADEON_MSG"radeon_mmio_base=%p\n",radeon_mmio_base); 887 printf(RADEON_MSG"radeon_mmio_base=%p\n",radeon_mmio_base);
753 printf(RADEON_MSG"radeon_mem_base=%p\n",radeon_mem_base); 888 printf(RADEON_MSG"radeon_mem_base=%p\n",radeon_mem_base);
754 printf(RADEON_MSG"radeon_overlay_off=%08X\n",radeon_overlay_off); 889 printf(RADEON_MSG"radeon_overlay_off=%08X\n",radeon_overlay_off);
755 printf(RADEON_MSG"radeon_ram_size=%08X\n",radeon_ram_size); 890 printf(RADEON_MSG"radeon_ram_size=%08X\n",radeon_ram_size);
891 printf(RADEON_MSG"video mode: %ux%u@%u\n",radeon_get_xres(),radeon_get_yres(),radeon_vid_get_dbpp());
756 printf(RADEON_MSG"*** Begin of OV0 registers dump ***\n"); 892 printf(RADEON_MSG"*** Begin of OV0 registers dump ***\n");
757 for(i=0;i<sizeof(vregs)/sizeof(video_registers_t);i++) 893 for(i=0;i<sizeof(vregs)/sizeof(video_registers_t);i++)
758 printf(RADEON_MSG"%s = %08X\n",vregs[i].sname,INREG(vregs[i].name)); 894 printf(RADEON_MSG"%s = %08X\n",vregs[i].sname,INREG(vregs[i].name));
759 printf(RADEON_MSG"*** End of OV0 registers dump ***\n"); 895 printf(RADEON_MSG"*** End of OV0 registers dump ***\n");
760 } 896 }
776 radeon_fifo_wait(2); 912 radeon_fifo_wait(2);
777 OUTREG(OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK); 913 OUTREG(OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK);
778 radeon_engine_idle(); 914 radeon_engine_idle();
779 while(!(INREG(OV0_REG_LOAD_CNTL)&REG_LD_CTL_LOCK_READBACK)); 915 while(!(INREG(OV0_REG_LOAD_CNTL)&REG_LD_CTL_LOCK_READBACK));
780 radeon_fifo_wait(15); 916 radeon_fifo_wait(15);
917
918 /* Shutdown capturing */
919 OUTREG(FCP_CNTL, FCP_CNTL__GND);
920 OUTREG(CAP0_TRIG_CNTL, 0);
921
922
781 OUTREG(OV0_AUTO_FLIP_CNTL,OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD); 923 OUTREG(OV0_AUTO_FLIP_CNTL,OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD);
782 OUTREG(OV0_AUTO_FLIP_CNTL,(INREG(OV0_AUTO_FLIP_CNTL)^OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE));
783 OUTREG(OV0_AUTO_FLIP_CNTL,(INREG(OV0_AUTO_FLIP_CNTL)^OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE));
784 924
785 if(besr.deinterlace_on) OUTREG(OV0_DEINTERLACE_PATTERN,besr.deinterlace_pattern); 925 if(besr.deinterlace_on) OUTREG(OV0_DEINTERLACE_PATTERN,besr.deinterlace_pattern);
786 #ifdef RAGE128 926 #ifdef RAGE128
787 OUTREG(OV0_COLOUR_CNTL, (besr.brightness & 0x7f) | 927 OUTREG(OV0_COLOUR_CNTL, (besr.brightness & 0x7f) |
788 (besr.saturation << 8) | 928 (besr.saturation << 8) |
830 OUTREG(OV0_P23_V_ACCUM_INIT, besr.p23_v_accum_init); 970 OUTREG(OV0_P23_V_ACCUM_INIT, besr.p23_v_accum_init);
831 971
832 bes_flags = SCALER_ENABLE | 972 bes_flags = SCALER_ENABLE |
833 SCALER_SMART_SWITCH | 973 SCALER_SMART_SWITCH |
834 #ifdef RADEON 974 #ifdef RADEON
835 SCALER_HORZ_PICK_NEAREST; 975 SCALER_HORZ_PICK_NEAREST |
836 #else 976 #endif
837 SCALER_Y2R_TEMP | 977 SCALER_Y2R_TEMP |
838 SCALER_PIX_EXPAND; 978 SCALER_PIX_EXPAND;
839 #endif
840 if(besr.double_buff) bes_flags |= SCALER_DOUBLE_BUFFER; 979 if(besr.double_buff) bes_flags |= SCALER_DOUBLE_BUFFER;
841 if(besr.deinterlace_on) bes_flags |= SCALER_ADAPTIVE_DEINT; 980 if(besr.deinterlace_on) bes_flags |= SCALER_ADAPTIVE_DEINT;
842 #ifdef RAGE128 981 #ifdef RAGE128
843 bes_flags |= SCALER_BURST_PER_PLANE; 982 bes_flags |= SCALER_BURST_PER_PLANE;
844 #endif 983 #endif
868 case IMGFMT_YUY2: 1007 case IMGFMT_YUY2:
869 default: bes_flags |= SCALER_SOURCE_VYUY422; break; 1008 default: bes_flags |= SCALER_SOURCE_VYUY422; break;
870 } 1009 }
871 OUTREG(OV0_SCALE_CNTL, bes_flags); 1010 OUTREG(OV0_SCALE_CNTL, bes_flags);
872 OUTREG(OV0_REG_LOAD_CNTL, 0); 1011 OUTREG(OV0_REG_LOAD_CNTL, 0);
1012 if(__verbose > 1) printf(RADEON_MSG"we wanted: scaler=%08X\n",bes_flags);
873 if(__verbose > 1) radeon_vid_dump_regs(); 1013 if(__verbose > 1) radeon_vid_dump_regs();
874 } 1014 }
875 1015
876 static unsigned radeon_query_pitch(unsigned fourcc,const vidix_yuv_t *spitch) 1016 static unsigned radeon_query_pitch(unsigned fourcc,const vidix_yuv_t *spitch)
877 { 1017 {
986 h_inc >>= 1; 1126 h_inc >>= 1;
987 } 1127 }
988 1128
989 /* keep everything in 16.16 */ 1129 /* keep everything in 16.16 */
990 besr.base_addr = INREG(DISPLAY_BASE_ADDR); 1130 besr.base_addr = INREG(DISPLAY_BASE_ADDR);
1131 config->offsets[0] = 0;
1132 config->offsets[1] = config->frame_size;
991 if(is_420) 1133 if(is_420)
992 { 1134 {
993 uint32_t d1line,d2line,d3line; 1135 uint32_t d1line,d2line,d3line;
994 d1line = top*pitch; 1136 d1line = top*pitch;
995 d2line = src_h*pitch+(d1line>>1); 1137 d2line = src_h*pitch+(d1line>>2);
996 d3line = d2line+((src_h*pitch)>>2); 1138 d3line = d2line+((src_h*pitch)>>2);
997 d1line += (left >> 16) & ~15; 1139 d1line += (left >> 16) & ~15;
998 d2line += (left >> 17) & ~15; 1140 d2line += (left >> 17) & ~15;
999 d3line += (left >> 17) & ~15; 1141 d3line += (left >> 17) & ~15;
1000 config->offset.y = d1line & VIF_BUF0_BASE_ADRS_MASK; 1142 config->offset.y = d1line & VIF_BUF0_BASE_ADRS_MASK;
1001 config->offset.v = d2line & VIF_BUF1_BASE_ADRS_MASK; 1143 config->offset.v = d2line & VIF_BUF1_BASE_ADRS_MASK;
1002 config->offset.u = d3line & VIF_BUF2_BASE_ADRS_MASK; 1144 config->offset.u = d3line & VIF_BUF2_BASE_ADRS_MASK;
1003 besr.vid_buf0_base_adrs=(radeon_overlay_off+config->offset.y); 1145 besr.vid_buf0_base_adrs=((radeon_overlay_off+config->offsets[0]+config->offset.y)&VIF_BUF0_BASE_ADRS_MASK);
1004 besr.vid_buf1_base_adrs=(radeon_overlay_off+config->offset.v)|VIF_BUF1_PITCH_SEL; 1146 besr.vid_buf1_base_adrs=((radeon_overlay_off+config->offsets[0]+config->offset.v)&VIF_BUF1_BASE_ADRS_MASK)|VIF_BUF1_PITCH_SEL;
1005 besr.vid_buf2_base_adrs=(radeon_overlay_off+config->offset.u)|VIF_BUF2_PITCH_SEL; 1147 besr.vid_buf2_base_adrs=((radeon_overlay_off+config->offsets[0]+config->offset.u)&VIF_BUF2_BASE_ADRS_MASK)|VIF_BUF2_PITCH_SEL;
1148 besr.vid_buf3_base_adrs=((radeon_overlay_off+config->offsets[1]+config->offset.y)&VIF_BUF0_BASE_ADRS_MASK);
1149 besr.vid_buf4_base_adrs=((radeon_overlay_off+config->offsets[1]+config->offset.v)&VIF_BUF1_BASE_ADRS_MASK)|VIF_BUF1_PITCH_SEL;
1150 besr.vid_buf5_base_adrs=((radeon_overlay_off+config->offsets[1]+config->offset.u)&VIF_BUF2_BASE_ADRS_MASK)|VIF_BUF2_PITCH_SEL;
1151 config->offset.y = ((besr.vid_buf0_base_adrs)&VIF_BUF0_BASE_ADRS_MASK) - radeon_overlay_off;
1152 config->offset.v = ((besr.vid_buf1_base_adrs)&VIF_BUF1_BASE_ADRS_MASK) - radeon_overlay_off;
1153 config->offset.u = ((besr.vid_buf2_base_adrs)&VIF_BUF2_BASE_ADRS_MASK) - radeon_overlay_off;
1006 if(besr.fourcc == IMGFMT_I420 || besr.fourcc == IMGFMT_IYUV) 1154 if(besr.fourcc == IMGFMT_I420 || besr.fourcc == IMGFMT_IYUV)
1007 { 1155 {
1008 uint32_t tmp; 1156 uint32_t tmp;
1009 tmp = config->offset.u; 1157 tmp = config->offset.u;
1010 config->offset.u = config->offset.v; 1158 config->offset.u = config->offset.v;
1011 config->offset.v = tmp; 1159 config->offset.v = tmp;
1012 } 1160 }
1013 besr.vid_buf3_base_adrs = besr.vid_buf0_base_adrs+config->frame_size;
1014 besr.vid_buf4_base_adrs = besr.vid_buf1_base_adrs+config->frame_size;
1015 besr.vid_buf5_base_adrs = besr.vid_buf2_base_adrs+config->frame_size;
1016 } 1161 }
1017 else 1162 else
1018 { 1163 {
1019 besr.vid_buf0_base_adrs = radeon_overlay_off; 1164 besr.vid_buf0_base_adrs = radeon_overlay_off;
1020 config->offset.y = config->offset.u = config->offset.v = ((left & ~7) << 1)&VIF_BUF0_BASE_ADRS_MASK; 1165 config->offset.y = config->offset.u = config->offset.v = ((left & ~7) << 1)&VIF_BUF0_BASE_ADRS_MASK;
1021 besr.vid_buf0_base_adrs += config->offset.y; 1166 besr.vid_buf0_base_adrs += config->offset.y;
1022 besr.vid_buf1_base_adrs = besr.vid_buf0_base_adrs+config->frame_size; 1167 besr.vid_buf1_base_adrs = besr.vid_buf0_base_adrs;
1023 besr.vid_buf2_base_adrs = besr.vid_buf0_base_adrs; 1168 besr.vid_buf2_base_adrs = besr.vid_buf0_base_adrs;
1024 besr.vid_buf3_base_adrs = besr.vid_buf0_base_adrs+config->frame_size; 1169 besr.vid_buf3_base_adrs = besr.vid_buf0_base_adrs+config->frame_size;
1025 besr.vid_buf4_base_adrs = besr.vid_buf0_base_adrs; 1170 besr.vid_buf4_base_adrs = besr.vid_buf0_base_adrs+config->frame_size;
1026 besr.vid_buf5_base_adrs = besr.vid_buf0_base_adrs+config->frame_size; 1171 besr.vid_buf5_base_adrs = besr.vid_buf0_base_adrs+config->frame_size;
1027 } 1172 }
1028 config->offsets[0] = 0;
1029 config->offsets[1] = config->frame_size;
1030 1173
1031 tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3); 1174 tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3);
1032 besr.p1_h_accum_init = ((tmp << 4) & 0x000f8000) | 1175 besr.p1_h_accum_init = ((tmp << 4) & 0x000f8000) |
1033 ((tmp << 12) & 0xf0000000); 1176 ((tmp << 12) & 0xf0000000);
1034 1177
1069 return 0; 1212 return 0;
1070 } 1213 }
1071 1214
1072 static void radeon_compute_framesize(vidix_playback_t *info) 1215 static void radeon_compute_framesize(vidix_playback_t *info)
1073 { 1216 {
1074 unsigned pitch,awidth; 1217 unsigned pitch,awidth,dbpp;
1075 pitch = radeon_query_pitch(info->fourcc,&info->src.pitch); 1218 pitch = radeon_query_pitch(info->fourcc,&info->src.pitch);
1076 awidth = (info->src.w + (pitch-1)) & ~(pitch-1); 1219 dbpp = radeon_vid_get_dbpp();
1077 switch(info->fourcc) 1220 switch(info->fourcc)
1078 { 1221 {
1079 case IMGFMT_I420: 1222 case IMGFMT_I420:
1080 case IMGFMT_YV12: 1223 case IMGFMT_YV12:
1081 case IMGFMT_IYUV: 1224 case IMGFMT_IYUV:
1082 info->frame_size = awidth*info->src.h+(awidth*info->src.h)/2; 1225 awidth = (info->src.w + (pitch-1)) & ~(pitch-1);
1226 info->frame_size = (awidth*(info->src.h+info->src.h/2)+dbpp-1)/dbpp;
1083 break; 1227 break;
1084 case IMGFMT_RGB32: 1228 case IMGFMT_RGB32:
1085 case IMGFMT_BGR32: 1229 case IMGFMT_BGR32:
1086 info->frame_size = awidth*info->src.h*4; 1230 awidth = (info->src.w*4 + (pitch-1)) & ~(pitch-1);
1231 info->frame_size = ((awidth*info->src.h)+dbpp-1)/dbpp;
1087 break; 1232 break;
1088 /* YUY2 YVYU, RGB15, RGB16 */ 1233 /* YUY2 YVYU, RGB15, RGB16 */
1089 default: info->frame_size = awidth*info->src.h*2; 1234 default:
1235 awidth = (info->src.w*2 + (pitch-1)) & ~(pitch-1);
1236 info->frame_size = ((awidth*info->src.h)+dbpp-1)/dbpp;
1090 break; 1237 break;
1091 } 1238 }
1239 info->frame_size *= dbpp;
1092 } 1240 }
1093 1241
1094 int vixConfigPlayback(vidix_playback_t *info) 1242 int vixConfigPlayback(vidix_playback_t *info)
1095 { 1243 {
1096 if(!is_supported_fourcc(info->fourcc)) return ENOSYS; 1244 if(!is_supported_fourcc(info->fourcc)) return ENOSYS;
1097 if(info->num_frames>2) info->num_frames=2; 1245 if(info->num_frames>2) info->num_frames=2;
1246 if(info->num_frames==1) besr.double_buff=0;
1247 else besr.double_buff=1;
1098 radeon_compute_framesize(info); 1248 radeon_compute_framesize(info);
1099 radeon_overlay_off = radeon_ram_size - info->frame_size*info->num_frames; 1249 radeon_overlay_off = radeon_ram_size - info->frame_size*info->num_frames;
1100 radeon_overlay_off &= 0xffff0000; 1250 radeon_overlay_off &= 0xffff0000;
1101 if(radeon_overlay_off < 0) return EINVAL; 1251 if(radeon_overlay_off < 0) return EINVAL;
1102 info->dga_addr = (char *)radeon_mem_base + radeon_overlay_off; 1252 info->dga_addr = (char *)radeon_mem_base + radeon_overlay_off;
1121 uint32_t off[6]; 1271 uint32_t off[6];
1122 /* 1272 /*
1123 buf3-5 always should point onto second buffer for better 1273 buf3-5 always should point onto second buffer for better
1124 deinterlacing and TV-in 1274 deinterlacing and TV-in
1125 */ 1275 */
1126 if(frame%2) 1276 if(!besr.double_buff) return 0;
1277 if((frame%2))
1127 { 1278 {
1128 off[0] = besr.vid_buf3_base_adrs; 1279 off[0] = besr.vid_buf3_base_adrs;
1129 off[1] = besr.vid_buf4_base_adrs; 1280 off[1] = besr.vid_buf4_base_adrs;
1130 off[2] = besr.vid_buf5_base_adrs; 1281 off[2] = besr.vid_buf5_base_adrs;
1131 off[3] = besr.vid_buf0_base_adrs; 1282 off[3] = besr.vid_buf0_base_adrs;
1139 off[2] = besr.vid_buf2_base_adrs; 1290 off[2] = besr.vid_buf2_base_adrs;
1140 off[3] = besr.vid_buf3_base_adrs; 1291 off[3] = besr.vid_buf3_base_adrs;
1141 off[4] = besr.vid_buf4_base_adrs; 1292 off[4] = besr.vid_buf4_base_adrs;
1142 off[5] = besr.vid_buf5_base_adrs; 1293 off[5] = besr.vid_buf5_base_adrs;
1143 } 1294 }
1295 radeon_fifo_wait(2);
1144 OUTREG(OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK); 1296 OUTREG(OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK);
1297 radeon_engine_idle();
1145 while(!(INREG(OV0_REG_LOAD_CNTL)&REG_LD_CTL_LOCK_READBACK)); 1298 while(!(INREG(OV0_REG_LOAD_CNTL)&REG_LD_CTL_LOCK_READBACK));
1146 OUTREG(OV0_VID_BUF0_BASE_ADRS, off[0]); 1299 OUTREG(OV0_VID_BUF0_BASE_ADRS, off[0]);
1147 OUTREG(OV0_VID_BUF1_BASE_ADRS, off[1]); 1300 OUTREG(OV0_VID_BUF1_BASE_ADRS, off[1]);
1148 OUTREG(OV0_VID_BUF2_BASE_ADRS, off[2]); 1301 OUTREG(OV0_VID_BUF2_BASE_ADRS, off[2]);
1302 radeon_fifo_wait(9);
1149 OUTREG(OV0_VID_BUF3_BASE_ADRS, off[3]); 1303 OUTREG(OV0_VID_BUF3_BASE_ADRS, off[3]);
1150 OUTREG(OV0_VID_BUF4_BASE_ADRS, off[4]); 1304 OUTREG(OV0_VID_BUF4_BASE_ADRS, off[4]);
1151 OUTREG(OV0_VID_BUF5_BASE_ADRS, off[5]); 1305 OUTREG(OV0_VID_BUF5_BASE_ADRS, off[5]);
1152 OUTREG(OV0_REG_LOAD_CNTL, 0); 1306 OUTREG(OV0_REG_LOAD_CNTL, 0);
1153 if(__verbose > 1) radeon_vid_dump_regs(); 1307 if(__verbose > 1) radeon_vid_dump_regs();