mga_vid.c

来自「linux下的MPEG1」· C语言 代码 · 共 1,568 行 · 第 1/3 页

C
1,568
字号
    writel(BESA1ORG,    regs.besa1org);    writel(BESA1CORG,   regs.besa1corg);    writel(BESA2ORG,    regs.besa2org);    writel(BESA2CORG,   regs.besa2corg);    writel(BESB1ORG,    regs.besb1org);    writel(BESB1CORG,   regs.besb1corg);    writel(BESB2ORG,    regs.besb2org);    writel(BESB2CORG,   regs.besb2corg);    if(is_g400)    {	writel(BESA1C3ORG, regs.besa1c3org);	writel(BESA2C3ORG, regs.besa2c3org);	writel(BESB1C3ORG, regs.besb1c3org);	writel(BESB2C3ORG, regs.besb2c3org);    }    writel(BESHCOORD,   regs.beshcoord);    writel(BESHISCAL,   regs.beshiscal);    writel(BESHSRCST,   regs.beshsrcst);    writel(BESHSRCEND,  regs.beshsrcend);    writel(BESHSRCLST,  regs.beshsrclst);    writel(BESVCOORD,   regs.besvcoord);    writel(BESVISCAL,   regs.besviscal);    writel(BESV1SRCLST, regs.besv1srclst);    writel(BESV1WGHT,   regs.besv1wght);    writel(BESV2SRCLST, regs.besv2srclst);    writel(BESV2WGHT,   regs.besv2wght);    //update the registers somewhere between 1 and 2 frames from now.    writel(BESGLOBCTL,  regs.besglobctl + ((readl(VCOUNT)+2)<<16));    if (mga_verbose > 1)    {	printf(MGA_MSG" wrote BES registers\n");	printf(MGA_MSG" BESCTL = 0x%08x\n", readl(BESCTL));	printf(MGA_MSG" BESGLOBCTL = 0x%08x\n", readl(BESGLOBCTL));	printf(MGA_MSG" BESSTATUS= 0x%08x\n", readl(BESSTATUS));    }#endif#ifdef CRTC2#if 0    if (cregs_save.c2ctl == 0)    {	//int i;	cregs_save.c2ctl = readl(C2CTL);	cregs_save.c2datactl = readl(C2DATACTL);	cregs_save.c2misc = readl(C2MISC);	//for (i = 0; i <= 8; i++) { writeb(CRTCEXTX, i); printf("CRTCEXT%d  %x\n", i, readb(CRTCEXTD)); }	//printf("c2ctl:0x%08x c2datactl:0x%08x\n", cregs_save.c2ctl, cregs_save.c2datactl);	//printf("c2misc:0x%08x\n", readl(C2MISC));	//printf("c2ctl:0x%08x c2datactl:0x%08x\n", cregs.c2ctl, cregs.c2datactl);    }    if (restore)    {	writel(C2CTL,          cregs_save.c2ctl);        writel(C2DATACTL,      cregs_save.c2datactl);	writel(C2MISC,         cregs_save.c2misc);	return;    }#endif    // writel(C2CTL, cregs.c2ctl);    writel(C2CTL, ((readl(C2CTL) & ~0x03e00000) + (cregs.c2ctl & 0x03e00000)));    writel(C2DATACTL, ((readl(C2DATACTL) & ~0x000000ff) + (cregs.c2datactl & 0x000000ff)));    // ctrc2    // disable CRTC2 acording to specs    //	writel(C2CTL, cregs.c2ctl & 0xfffffff0);    // je to treba ???    //	writeb(XMISCCTRL, (readb(XMISCCTRL) & 0x19) | 0xa2); // MAFC - mfcsel & vdoutsel    //	writeb(XMISCCTRL, (readb(XMISCCTRL) & 0x19) | 0x92);    //	writeb(XMISCCTRL, (readb(XMISCCTRL) & ~0xe9) + 0xa2);    writel(C2DATACTL,   cregs.c2datactl);//    writel(C2HPARAM,    cregs.c2hparam);    writel(C2HSYNC,     cregs.c2hsync);//    writel(C2VPARAM,    cregs.c2vparam);    writel(C2VSYNC,     cregs.c2vsync);    //xx    //writel(C2MISC,      cregs.c2misc);    if (mga_verbose > 1) printf(MGA_MSG" c2offset = %d\n", cregs.c2offset);    writel(C2OFFSET,    cregs.c2offset);    writel(C2STARTADD0, cregs.c2startadd0);    //	writel(C2STARTADD1, cregs.c2startadd1);    writel(C2PL2STARTADD0, cregs.c2pl2startadd0);    //	writel(C2PL2STARTADD1, cregs.c2pl2startadd1);    writel(C2PL3STARTADD0, cregs.c2pl3startadd0);    //	writel(C2PL3STARTADD1, cregs.c2pl3startadd1);    writel(C2SPICSTARTADD0, cregs.c2spicstartadd0);    //xx    //writel(C2SPICSTARTADD1, cregs.c2spicstartadd1);    //set Color Lookup Table for Subpicture Layer    {      unsigned char r, g, b, y, cb, cr;      int i;      for (i = 0; i < 16; i++) {                   r = (i & 0x8) ? 0xff : 0x00;        g = (i & 0x4) ? ((i & 0x2) ? 0xff : 0xaa) : ((i & 0x2) ? 0x55 : 0x00);        b = (i & 0x1) ? 0xff : 0x00;        y  = ((r * 16829 + g *  33039 + b *  6416 + 0x8000) >> 16) + 16;         cb = ((r * -9714 + g * -19071 + b * 28784 + 0x8000) >> 16) + 128;         cr = ((r * 28784 + g * -24103 + b * -4681 + 0x8000) >> 16) + 128;        cregs.c2subpiclut = (cr << 24) | (cb << 16) | (y << 8) | i;        writel(C2SUBPICLUT, cregs.c2subpiclut);      }    }    //writel(C2PRELOAD,   cregs.c2preload);    // finaly enable everything//    writel(C2CTL,       cregs.c2ctl);    //	printf("c2ctl:0x%08x c2datactl:0x%08x\n",readl(C2CTL), readl(C2DATACTL));    //	printf("c2misc:0x%08x\n", readl(C2MISC));#endif}#ifdef MGA_ALLOW_IRQstatic void enable_irq(){    long int cc;    cc = readl(IEN);    //	printf("*** !!! IRQREG = %d\n", (int)(cc&0xff));    writeb(CRTCX, 0x11);    writeb(CRTCD, 0x20);  /* clear 0, enable off */    writeb(CRTCD, 0x00);  /* enable on */    writeb(CRTCD, 0x10);  /* clear = 1 */    writel(BESGLOBCTL, regs.besglobctl);    return;}static void disable_irq(){    writeb(CRTCX, 0x11);    writeb(CRTCD, 0x20);  /* clear 0, enable off */    return;}void mga_handle_irq(int irq, void *dev_id/*, struct pt_regs *pregs*/) {    //	static int frame=0;    //	static int counter=0;    long int cc;    //	if ( ! mga_enabled_flag ) return;    //	printf("vcount = %d\n",readl(VCOUNT));    //printf("mga_interrupt #%d\n", irq);    if ( irq != -1 ) {	cc = readl(STATUS);	if ( ! (cc & 0x10) ) return;  /* vsyncpen */	// 		debug_irqcnt++;    }    //    if ( debug_irqignore ) {    //	debug_irqignore = 0;    /*     if ( mga_conf_deinterlace ) {     if ( mga_first_field ) {     // printf("mga_interrupt first field\n");     if ( syncfb_interrupt() )     mga_first_field = 0;     } else {     // printf("mga_interrupt second field\n");     mga_select_buffer( mga_current_field | 2 );     mga_first_field = 1;     }     } else {     syncfb_interrupt();     }     */    //	frame=(frame+1)&1;    regs.besctl = (regs.besctl & ~0x07000000) + (mga_next_frame << 25);    writel(BESCTL, regs.besctl);#ifdef CRTC2    crtc2_frame_sel(mga_next_frame);#endif#if 0    ++counter;    if(!(counter&63)){	printf("mga irq counter = %d\n",counter);    }#endif    //    } else {    //	debug_irqignore = 1;    //    }    if ( irq != -1 ) {	writeb(CRTCX, 0x11);	writeb(CRTCD, 0);	writeb(CRTCD, 0x10);    }    //writel(BESGLOBCTL, regs.besglobctl);}#endif /* MGA_ALLOW_IRQ */int VIDIX_NAME(vixConfigPlayback)(vidix_playback_t *config){    unsigned int i;    int x, y, sw, sh, dw, dh;    int besleft, bestop, ifactor, ofsleft, ofstop, baseadrofs, weight, weights;#ifdef CRTC2#define right_margin 0#define left_margin 18#define hsync_len 46#define lower_margin 10#define vsync_len 4#define upper_margin 39    unsigned int hdispend = (config->src.w + 31) & ~31;    unsigned int hsyncstart = hdispend + (right_margin & ~7);    unsigned int hsyncend = hsyncstart + (hsync_len & ~7);    unsigned int htotal = hsyncend + (left_margin & ~7);    unsigned int vdispend = config->src.h;    unsigned int vsyncstart = vdispend + lower_margin;    unsigned int vsyncend = vsyncstart + vsync_len;    unsigned int vtotal = vsyncend + upper_margin;#endif    if ((config->num_frames < 1) || (config->num_frames > MGA_DEFAULT_FRAMES))    {	printf(MGA_MSG" illegal num_frames: %d, setting to %d\n",	       config->num_frames, MGA_DEFAULT_FRAMES);	config->num_frames = MGA_DEFAULT_FRAMES;    }    for(;config->num_frames>0;config->num_frames--)    {	/*FIXME: this driver can use more frames but we need to apply	 some tricks to avoid RGB-memory hits*/	mga_src_base = ((mga_ram_size/2)*0x100000-(config->num_frames+1)*config->frame_size);	mga_src_base &= (~0xFFFF); /* 64k boundary */	if(mga_src_base>=0) break;    }    if (mga_verbose > 1) printf(MGA_MSG" YUV buffer base: 0x%x\n", mga_src_base);    config->dga_addr = mga_mem_base + mga_src_base;    x = config->dest.x;    y = config->dest.y;    sw = config->src.w;    sh = config->src.h;    dw = config->dest.w;    dh = config->dest.h;    if (mga_verbose) printf(MGA_MSG" Setting up a %dx%d-%dx%d video window (src %dx%d) format %X\n",			    dw, dh, x, y, sw, sh, config->fourcc);    if ((sw < 4) || (sh < 4) || (dw < 4) || (dh < 4))    {	printf(MGA_MSG" Invalid src/dest dimensions\n");	return(EINVAL);    }    //FIXME check that window is valid and inside desktop    //    printf(MGA_MSG" vcount = %d\n", readl(VCOUNT));    sw += sw & 1;    switch(config->fourcc)    {    case IMGFMT_I420:    case IMGFMT_IYUV:    case IMGFMT_YV12:	sh+=sh&1;	config->dest.pitch.y=config->dest.pitch.u=config->dest.pitch.v=32;	config->frame_size = ((sw + 31) & ~31) * sh + (((sw + 31) & ~31) * sh) / 2;	break;    case IMGFMT_YUY2:    case IMGFMT_UYVY:	config->dest.pitch.y=16;	config->dest.pitch.u=config->dest.pitch.v=0;	config->frame_size = ((sw + 8) & ~8) * sh * 2;	break;    default:	printf(MGA_MSG" Unsupported pixel format: %x\n", config->fourcc);	return(ENOTSUP);    }    config->offsets[0] = 0;    //    config->offsets[1] = config->frame_size;    //    config->offsets[2] = 2*config->frame_size;    //    config->offsets[3] = 3*config->frame_size;    for (i = 1; i < config->num_frames+2; i++)	config->offsets[i] = i*config->frame_size;    config->offset.y=0;    config->offset.v=((sw + 31) & ~31) * sh;    config->offset.u=config->offset.v+((sw + 31) & ~31) * sh /4;    //FIXME figure out a better way to allocate memory on card    //allocate 2 megs    //mga_src_base = mga_mem_base + (MGA_VIDMEM_SIZE-2) * 0x100000;    //mga_src_base = (MGA_VIDMEM_SIZE-3) * 0x100000;    /* for G200 set Interleaved UV planes */    if (!is_g400)	config->flags = VID_PLAY_INTERLEAVED_UV | INTERLEAVING_UV;    //Setup the BES registers for a three plane 4:2:0 video source    regs.besglobctl = 0;    switch(config->fourcc)    {    case IMGFMT_YV12:    case IMGFMT_I420:    case IMGFMT_IYUV:	regs.besctl = 1 // BES enabled	    + (0<<6)    // even start polarity	    + (1<<10)   // x filtering enabled	    + (1<<11)   // y filtering enabled	    + (1<<16)   // chroma upsampling	    + (1<<17)   // 4:2:0 mode	    + (1<<18);  // dither enabled#if 0	if(is_g400)	{	    //zoom disabled, zoom filter disabled, 420 3 plane format, proc amp	    //disabled, rgb mode disabled	    regs.besglobctl = (1<<5);	}	else	{	    //zoom disabled, zoom filter disabled, Cb samples in 0246, Cr	    //in 1357, BES register update on besvcnt	    regs.besglobctl = 0;	}#endif	break;    case IMGFMT_YUY2:	regs.besctl = 1 // BES enabled	    + (0<<6)    // even start polarity	    + (1<<10)   // x filtering enabled	    + (1<<11)   // y filtering enabled	    + (1<<16)   // chroma upsampling	    + (0<<17)   // 4:2:2 mode	    + (1<<18);  // dither enabled	regs.besglobctl = 0;        // YUY2 format selected	break;    case IMGFMT_UYVY:	regs.besctl = 1         // BES enabled	    + (0<<6)    // even start polarity	    + (1<<10)   // x filtering enabled	    + (1<<11)   // y filtering enabled	    + (1<<16)   // chroma upsampling	    + (0<<17)   // 4:2:2 mode	    + (1<<18);  // dither enabled	regs.besglobctl = 1<<6;        // UYVY format selected	break;    }    //Disable contrast and brightness control    regs.besglobctl |= (1<<5) + (1<<7);    // we want to preserver these across restarts    //regs.beslumactl = (0x0 << 16) + 0x80;    //Setup destination window boundaries    besleft = x > 0 ? x : 0;    bestop = y > 0 ? y : 0;    regs.beshcoord = (besleft<<16) + (x + dw-1);    regs.besvcoord = (bestop<<16) + (y + dh-1);    //Setup source dimensions    regs.beshsrclst = (sw - 1) << 16;    switch(config->fourcc)    {    case IMGFMT_YV12:    case IMGFMT_I420:    case IMGFMT_IYUV:	regs.bespitch = (sw + 31) & ~31;	break;    case IMGFMT_YUY2:    case IMGFMT_UYVY:	regs.bespitch = (sw + 8) & ~8;	break;    }    //Setup horizontal scaling    ifactor = ((sw-1)<<14)/(dw-1);    ofsleft = besleft - x;    regs.beshiscal = ifactor<<2;    regs.beshsrcst = (ofsleft*ifactor)<<2;    regs.beshsrcend = regs.beshsrcst + (((dw - ofsleft - 1) * ifactor) << 2);    //Setup vertical scaling    ifactor = ((sh-1)<<14)/(dh-1);    ofstop = bestop - y;    regs.besviscal = ifactor<<2;    baseadrofs = ((ofstop*regs.besviscal)>>16)*regs.bespitch;    //frame_size = ((sw + 31) & ~31) * sh + (((sw + 31) & ~31) * sh) / 2;    regs.besa1org = (uint32_t) mga_src_base + baseadrofs;    regs.besa2org = (uint32_t) mga_src_base + baseadrofs + 1*config->frame_size;    regs.besb1org = (uint32_t) mga_src_base + baseadrofs + 2*config->frame_size;    regs.besb2org = (uint32_t) mga_src_base + baseadrofs + 3*config->frame_size;    if (config->fourcc == IMGFMT_YV12	|| config->fourcc == IMGFMT_IYUV	|| config->fourcc == IMGFMT_I420)    {	// planar YUV frames:	if (is_g400)	    baseadrofs = (((ofstop*regs.besviscal)/4)>>16)*regs.bespitch;	else	    baseadrofs = (((ofstop*regs.besviscal)/2)>>16)*regs.bespitch;	if (config->fourcc == IMGFMT_YV12){	    regs.besa1corg = (uint32_t) mga_src_base + baseadrofs + regs.bespitch * sh ;	    regs.besa2corg = (uint32_t) mga_src_base + baseadrofs + 1*config->frame_size + regs.bespitch * sh;	    regs.besb1corg = (uint32_t) mga_src_base + baseadrofs + 2*config->frame_size + regs.bespitch * sh;	    regs.besb2corg = (uint32_t) mga_src_base + baseadrofs + 3*config->frame_size + regs.bespitch * sh;	    regs.besa1c3org = regs.besa1corg + ((regs.bespitch * sh) / 4);	    regs.besa2c3org = regs.besa2corg + ((regs.bespitch * sh) / 4);	    regs.besb1c3org = regs.besb1corg + ((regs.bespitch * sh) / 4);	    regs.besb2c3org = regs.besb2corg + ((regs.bespitch * sh) / 4);	} else {	    regs.besa1c3org = (uint32_t) mga_src_base + baseadrofs + regs.bespitch * sh ;	    regs.besa2c3org = (uint32_t) mga_src_base + baseadrofs + 1*config->frame_size + regs.bespitch * sh;	    regs.besb1c3org = (uint32_t) mga_src_base + baseadrofs + 2*config->frame_size + regs.bespitch * sh;	    regs.besb2c3org = (uint32_t) mga_src_base + baseadrofs + 3*config->frame_size + regs.bespitch * sh;	    regs.besa1corg = regs.besa1c3org + ((regs.bespitch * sh) / 4);	    regs.besa2corg = regs.besa2c3org + ((regs.bespitch * sh) / 4);	    regs.besb1corg = regs.besb1c3org + ((regs.bespitch * sh) / 4);	    regs.besb2corg = regs.besb2c3org + ((regs.bespitch * sh) / 4);	}    }    weight = ofstop * (regs.besviscal >> 2);    weights = weight < 0 ? 1 : 0;    regs.besv2wght = regs.besv1wght = (weights << 16) + ((weight & 0x3FFF) << 2);    regs.besv2srclst = regs.besv1srclst = sh - 1 - (((ofstop * regs.besviscal) >> 16) & 0x03FF);#ifdef CRTC2    // pridat hlavni registry - tj. casovani ...    switch(config->fourcc){    case IMGFMT_YV12:    case IMGFMT_I420:    case IMGFMT_IYUV:	cregs.c2ctl = 1         // CRTC2 enabled	    + (1<<1)	// external clock	    + (0<<2)	// external clock	    + (1<<3)	// pixel clock enable - not needed ???	    + (0<<4)	// high priority req	    + (1<<5)	// high priority req	    + (0<<6)	// high priority req	    + (1<<8)	// high priority req max	    + (0<<9)	// high priority req max	    + (0<<10)	// high priority req max	    + (0<<20)   // CRTC1 to DAC	    + (1<<21)   // 420 mode	    + (1<<22)   // 420 mode	    + (1<<23)   // 420 mode	    + (0<<24)   // single chroma line for 420 mode - need to be corrected	    + (0<<25)   /*/ interlace mode - need to be corrected*/	    + (0<<26)   // field legth polariry	    + (0<<27)   // field identification polariry	    + (1<<28)   // VIDRST detection mode	    + (0<<29)   // VIDRST detection mode	    + (1<<30)   // Horizontal counter preload	    + (1<<31)   // Vertical counter preload	    ;	cregs.c2datactl = 1         // disable dither - propably not needed, we are already in YUV mode	    + (1<<1)	// Y filter enable	    + (1<<2)	// CbCr filter enable	    + (1<<3)	// subpicture enable (enabled)	    + (0<<4)	// NTSC enable (disabled - PAL)	    + (0<<5)	// C2 static subpicture enable (disabled)	    + (0<<6)	// C2 subpicture offset division (disabled)	    + (0<<7)	// 422 subformat selection !	    /*		    + (0<<8)	// 15 bpp high alpha	     + (0<<9)	// 15 bpp high alpha	     + (0<<10)	// 15 bpp high alpha	     + (0<<11)	// 15 bpp high alpha	     + (0<<12)	// 15 bpp high alpha	     + (0<<13)	// 15 bpp high alpha	     + (0<<14)	// 15 bpp high alpha	     + (0<<15)	// 15 bpp high alpha	     + (0<<16)	// 15 bpp low alpha	     + (0<<17)	// 15 bpp low alpha	     + (0<<18)	// 15 bpp low alpha	     + (0<<19)	// 15 bpp low alpha	     + (0<<20)	// 15 bpp low alpha	     + (0<<21)	// 15 bpp low alpha	     + (0<<22)	// 15 bpp low alpha	     + (0<<23)	// 15 bpp low alpha	     + (0<<24)	// static subpicture key	     + (0<<25)	// static subpicture key	     + (0<<26)	// static subpicture key	     + (0<<27)	// static subpicture key	     + (0<<28)	// static subpicture key

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?