From owner-freebsd-multimedia Tue May 27 07:04:52 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.5/8.8.5) id HAA14926 for multimedia-outgoing; Tue, 27 May 1997 07:04:52 -0700 (PDT) Received: from info.iet.unipi.it (info.iet.unipi.it [131.114.9.184]) by hub.freebsd.org (8.8.5/8.8.5) with ESMTP id HAA14858 for ; Tue, 27 May 1997 07:03:08 -0700 (PDT) Received: (from root@localhost) by info.iet.unipi.it (8.8.5/8.8.5) id QAA00791 for multimedia@freebsd.org; Tue, 27 May 1997 16:00:27 GMT Date: Tue, 27 May 1997 16:00:27 GMT From: Luigi Rizzo Message-Id: <199705271600.QAA00791@info.iet.unipi.it> To: multimedia@freebsd.org Subject: bt848 status, comments and diffs Sender: owner-multimedia@freebsd.org X-Loop: FreeBSD.org Precedence: bulk Guys, I was looking at solving my problems (missing odd frames etc.) with the YUV* modes, and I noticed that there are some inconsistencies in the handling of SYNC instructions at the end of each frame etc, especially for what regards IRQ generation. This would explain why continuous capture modes work whereas single capture mode dont (and perhaps signals would not work either, although tv does not use them). To clean up things, and before investigating further on the problem, I defined a few macros (OP_IRQ, OP_RESYNC) for commands which are generally used in instructions. I also defined a macro, I2(a,b) which I used for all occurrence of 2-word instructions. This makes the code shorter and especially risc instructions easier to read. Before going on I would like to know (from Amancio perhaps): - what is the meaning of the 'interlace' variable ? What corresponds to the various values (1,2,3) which it can assume ? - is it ok to generate an IRQ on every SYNC instruction, and let the handler ignore it if not required ? This seems to me the safest option (and, even if for continuous capture to the frame buffer it might not be necessary to generate 60 irq/s, the overhead should not be so terrible considering the amount of bus traffic this capture generates). - why, in some SYNC instructions, you use 0xC << 24 ? Those are reserved bits, but probably are SOL/EOL. Are you following some application note, or trying to circumvent problems, or what ? - in modes which require full frames, I think it would be worthwile to make frames always start on the same field (probably odd), i.e. include an OP_SYNC | BKTR_VRO instruction at the beginning. This would make the output more predictable and probably also remove some artifacts which people are seeing and which might be related to some frames starting with the odd field, some with the even field. In the current code you start with OP_SYNC | BKTR_FM1 (or FM3) which does not let you know which frame are you starting with. I could derive the above info from the sources, but because of some inconsistencies I would prefer a word on how things should be, rather than look at what they are. Once the above things have been sorted out, it will probably be relatively easy to fix the driver (and maybe also make it shorter). The diffs follow (relative to today's version from amancio). Cheers Luigi --- brooktree848.c.amancio Tue May 27 14:05:03 1997 +++ brooktree848.c Tue May 27 15:38:43 1997 @@ -2179,7 +2179,7 @@ #define BKTR_FM3 0xe #define BKTR_VRE 0x4 #define BKTR_VRO 0xC -#define BKTR_PXV 0x0 +#define BKTR_PXV 0x0 /* never used */ #define BKTR_EOL 0x1 #define BKTR_SOL 0x2 @@ -2193,6 +2193,11 @@ #define OP_SOL (1 << 27) #define OP_EOL (1 << 26) +#define OP_IRQ (1 << 24) +#define OP_RESYNC (1 << 15) + +#define I2(a, b) { *dma_prog++ = a ; *dma_prog++ = b ; } + bool_t notclipped (bktr_reg_t * bktr, int x, int width) { int i; bktr_clip_t * clip_node; @@ -2369,11 +2374,9 @@ buffer = target_buffer; if (interlace == 2 && rows < 320 ) target_buffer += pitch; - /* contruct sync : for video packet format */ - *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM1; + /* contruct sync : for video packed format */ + I2( OP_SYNC | OP_RESYNC | BKTR_FM1, 0 ); - /* sync, mode indicator packed data */ - *dma_prog++ = 0; /* NULL WORD */ width = cols; for (i = 0; i < (rows/interlace); i++) { target = target_buffer; @@ -2406,28 +2409,20 @@ switch (i_flag) { case 1: /* sync vre */ - *dma_prog++ = OP_SYNC | 0xC << 24 | 1 << 24 | BKTR_VRE; - *dma_prog++ = 0; /* NULL WORD */ - - *dma_prog++ = OP_JUMP | 0xC << 24; - *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); + I2( OP_SYNC | 0xC << 24 | OP_IRQ | BKTR_VRE, 0 ); + I2( OP_JUMP | 0xC << 24, (u_long ) vtophys(bktr->dma_prog) ); return; case 2: /* sync vro */ - *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 20 | BKTR_VRO; - *dma_prog++ = 0; /* NULL WORD */ - - *dma_prog++ = OP_JUMP; - *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); + I2( OP_SYNC | OP_IRQ | 1 << 20 | BKTR_VRO, 0 ); + I2( OP_JUMP, (u_long ) vtophys(bktr->dma_prog) ); return; case 3: /* sync vro */ - *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO; - *dma_prog++ = 0; /* NULL WORD */ - *dma_prog++ = OP_JUMP | 0xc << 24 ; - *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog); + I2(OP_SYNC | OP_IRQ | OP_RESYNC | BKTR_VRO, 0 ); + I2(OP_JUMP | 0xc << 24, (u_long) vtophys(bktr->odd_dma_prog)); break; } @@ -2441,8 +2436,7 @@ /* sync vre IRQ bit */ - *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM1; - *dma_prog++ = 0; /* NULL WORD */ + I2( OP_SYNC | OP_RESYNC | BKTR_FM1, 0 ); width = cols; for (i = 0; i < (rows/interlace); i++) { target = target_buffer; @@ -2474,10 +2468,8 @@ } /* sync vre IRQ bit */ - *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE; - *dma_prog++ = 0; /* NULL WORD */ - *dma_prog++ = OP_JUMP ; - *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ; + I2( OP_SYNC | OP_IRQ | OP_RESYNC | BKTR_VRE, 0 ); + I2( OP_JUMP , (u_long ) vtophys(bktr->dma_prog) ); *dma_prog++ = 0; /* NULL WORD */ } @@ -2531,43 +2523,34 @@ /* contruct sync : for video packet format */ /* sync, mode indicator packed data */ - *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM1; - *dma_prog++ = 0; /* NULL WORD */ + I2( OP_SYNC | OP_RESYNC | BKTR_FM1, 0 ); b = cols; for (i = 0; i < (rows/interlace); i++) { - *dma_prog++ = inst; - *dma_prog++ = target_buffer; - *dma_prog++ = inst3; - *dma_prog++ = target_buffer + b; + /* XXX I don't understand why 2 instructions since b = cols */ + I2( inst, target_buffer ); + I2( inst3, target_buffer + b ); target_buffer += interlace*(cols * 2); } switch (i_flag) { case 1: /* sync vre */ - *dma_prog++ = OP_SYNC | 0xC << 24 | BKTR_VRE; - *dma_prog++ = 0; /* NULL WORD */ - - *dma_prog++ = OP_JUMP; - *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); + I2( OP_SYNC | 0xC << 24 | BKTR_VRE, 0 ); + I2( OP_JUMP, (u_long ) vtophys(bktr->dma_prog) ); return; case 2: /* sync vro */ - *dma_prog++ = OP_SYNC | 0xC << 24 | BKTR_VRO; - *dma_prog++ = 0; /* NULL WORD */ - *dma_prog++ = OP_JUMP; - *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); + I2( OP_SYNC | 0xC << 24 | BKTR_VRO, 0 ); + I2( OP_JUMP, (u_long ) vtophys(bktr->dma_prog) ); return; case 3: /* sync vre */ - *dma_prog++ = OP_SYNC | BKTR_VRE; - *dma_prog++ = 0; /* NULL WORD */ - *dma_prog++ = OP_JUMP ; - *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog); + I2( OP_SYNC | BKTR_VRE, 0 ); + I2( OP_JUMP,(u_long ) vtophys(bktr->odd_dma_prog) ); break; } @@ -2578,26 +2561,20 @@ dma_prog = (u_long * ) bktr->odd_dma_prog; /* sync vre */ - *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_FM1; - *dma_prog++ = 0; /* NULL WORD */ + I2( OP_SYNC | OP_IRQ | OP_RESYNC | BKTR_FM1, 0 ); for (i = 0; i < (rows/interlace) ; i++) { - *dma_prog++ = inst; - *dma_prog++ = target_buffer; - *dma_prog++ = inst3; - *dma_prog++ = target_buffer + b; + I2( inst, target_buffer ); + I2( inst3, target_buffer + b ); target_buffer += interlace * ( cols*2); } } /* sync vro IRQ bit */ - *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; - *dma_prog++ = 0; /* NULL WORD */ - *dma_prog++ = OP_JUMP ; - *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); + I2( OP_SYNC | OP_IRQ | BKTR_VRE, 0 ); + I2( OP_JUMP , (u_long ) vtophys(bktr->dma_prog) ); - *dma_prog++ = OP_JUMP; - *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); + I2( OP_JUMP, (u_long ) vtophys(bktr->dma_prog) ); /* XXX ??? */ *dma_prog++ = 0; /* NULL WORD */ } @@ -2655,8 +2632,7 @@ t1 = target_buffer; /* contruct sync : for video packet format */ - *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/ - *dma_prog++ = 0; /* NULL WORD */ + I2( OP_SYNC | OP_RESYNC | BKTR_FM3, 0 ); for (i = 0; i < (rows/interlace ) - 1; i++) { *dma_prog++ = inst; @@ -2669,27 +2645,18 @@ switch (i_flag) { case 1: - *dma_prog++ = OP_SYNC | 0xC << 24 | 1 << 24 | BKTR_VRE; /*sync vre*/ - *dma_prog++ = 0; /* NULL WORD */ - - *dma_prog++ = OP_JUMP | 0xc << 24; - *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); + I2( OP_SYNC | 0xC << 24 | OP_IRQ | BKTR_VRE, 0); /*sync vre*/ + I2( OP_JUMP | 0xc << 24, (u_long ) vtophys(bktr->dma_prog) ); return; case 2: - *dma_prog++ = OP_SYNC | 0xC << 24 | 1 << 24 | BKTR_VRO; /*sync vre*/ - *dma_prog++ = 0; /* NULL WORD */ - - *dma_prog++ = OP_JUMP; - *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); + I2( OP_SYNC | 0xC << 24 | OP_IRQ | BKTR_VRO, 0); /*sync vre*/ + I2( OP_JUMP, (u_long ) vtophys(bktr->dma_prog) ); return; case 3: - *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_VRO; - *dma_prog++ = 0; /* NULL WORD */ - - *dma_prog++ = OP_JUMP ; - *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog); + I2( OP_SYNC | OP_RESYNC | BKTR_VRO, 0 ); + I2( OP_JUMP, (u_long ) vtophys(bktr->odd_dma_prog) ); break; } @@ -2699,8 +2666,7 @@ target_buffer = (u_long) buffer + cols; t1 = target_buffer + cols/2; - *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; - *dma_prog++ = 0; /* NULL WORD */ + I2( OP_SYNC | OP_RESYNC | BKTR_FM3, 0 ); for (i = 0; i < (rows/interlace ) - 1; i++) { *dma_prog++ = inst; @@ -2712,10 +2678,8 @@ } } - *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; - *dma_prog++ = 0; /* NULL WORD */ - *dma_prog++ = OP_JUMP ; - *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ; + I2( OP_SYNC | OP_IRQ | BKTR_VRE, 0 ); + I2( OP_JUMP , (u_long ) vtophys(bktr->dma_prog) ) ; *dma_prog++ = 0; /* NULL WORD */ }