Mercurial > mplayer.hg
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)®_LD_CTL_LOCK_READBACK)); | 915 while(!(INREG(OV0_REG_LOAD_CNTL)®_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)®_LD_CTL_LOCK_READBACK)); | 1298 while(!(INREG(OV0_REG_LOAD_CNTL)®_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(); |