How to get current field polarity of interlaced video output?
Thomas Hilber
xorg-driver-ati at toh.cx
Thu Jul 31 07:07:29 PDT 2008
On Wed, Jul 30, 2008 at 11:01:00PM +0200, Thomas Hilber wrote:
> ah, maybe I now found something:
>
> register RADEON_CRTC_VLINE_CRNT_VLINE
>
> alternatively counts from
>
> 0 - 624 and from
> 0 - 622 the next time.
>
> probably I can derive the field polarity from this?
Problem fixed! Please find attached a small test program how
to fiddle this.
Cheers
Thomas
-------------- next part --------------
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/mman.h>
#define RADEON_PHYS_BASE 0xeaf00000
#define RADEON_IO_SIZE 0x10000
#define RADEON_CRTC_VLINE_CRNT_VLINE 0x0210
#define RADEON_CRTC_STATUS 0x005c
#define A(reg) (*(unsigned *)(map_base + (reg)))
/*
* only works with a modeline like this:
*
* Modeline "720x576i" 13.875 720 744 808 888 576 580 585 625 -HSync -Vsync interlace
*
* both RADEON_CRTC_VLINE_CRNT_VLINE and RADEON_CRTC_STATUS give the same
* information about fields.
*
* using RADEON_CRTC_VLINE_CRNT_VLINE you have to wait for
* transition 622/624 -> 0
*
* using RADEON_CRTC_STATUS you can determine the status anytime
*/
main()
{
int fd;
int cnt;
int vline_prev = 0;
u_char *map_base;
if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) {
printf("open /dev/mem: %s\n", strerror(errno)); exit(-1);
}
map_base = mmap(0, RADEON_IO_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, RADEON_PHYS_BASE);
if ((int)map_base == -1) {
printf("mmap hw fails: %s\n", strerror(errno)); exit(-1);
}
cnt = 500000;
while (--cnt) {
int vline = A(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16;
int field = A(RADEON_CRTC_STATUS) >> 3 & 1;
if (vline < vline_prev) {
if (vline_prev == 622 && field) {
printf("ODD\n");
} else if (vline_prev == 624 && !field) {
printf("EVEN\n");
} else {
printf("inconsistency detected, exiting\n"); exit(1);
}
}
vline_prev = vline;
}
}
More information about the xorg-driver-ati
mailing list