📄 mga_vid.c
字号:
writel(card->cregs.c2pl3startadd0, card->mmio_base + C2PL3STARTADD0);}#endifstatic void mga_vid_frame_sel(mga_card_t * card, int frame){ if ( card->irq != -1 ) { card->next_frame=frame; } else { //we don't need the vcount protection as we're only hitting //one register (and it doesn't seem to be double buffered) card->regs.besctl = (card->regs.besctl & ~0x07000000) + (frame << 25); writel( card->regs.besctl, card->mmio_base + BESCTL ); // writel( card->regs.besglobctl + ((readl(card->mmio_base + VCOUNT)+2)<<16), writel( card->regs.besglobctl + (MGA_VSYNC_POS<<16), card->mmio_base + BESGLOBCTL);#ifdef CRTC2 crtc2_frame_sel(card, frame);#endif }}static void mga_vid_write_regs(mga_card_t * card, int restore){ //Make sure internal registers don't get updated until we're done writel( (readl(card->mmio_base + VCOUNT)-1)<<16, card->mmio_base + BESGLOBCTL); // color or coordinate keying if(restore && card->colkey_saved){ // restore it card->colkey_saved=0;#ifdef MP_DEBUG printk("mga_vid: Restoring colorkey (ON: %d %02X:%02X:%02X)\n", card->colkey_on,card->colkey_color[0],card->colkey_color[1],card->colkey_color[2]);#endif // Set color key registers: writeb( XKEYOPMODE, card->mmio_base + PALWTADD); writeb( card->colkey_on, card->mmio_base + X_DATAREG); writeb( XCOLKEY0RED, card->mmio_base + PALWTADD); writeb( card->colkey_color[0], card->mmio_base + X_DATAREG); writeb( XCOLKEY0GREEN, card->mmio_base + PALWTADD); writeb( card->colkey_color[1], card->mmio_base + X_DATAREG); writeb( XCOLKEY0BLUE, card->mmio_base + PALWTADD); writeb( card->colkey_color[2], card->mmio_base + X_DATAREG); writeb( X_COLKEY, card->mmio_base + PALWTADD); writeb( card->colkey_color[3], card->mmio_base + X_DATAREG); writeb( XCOLMSK0RED, card->mmio_base + PALWTADD); writeb( card->colkey_mask[0], card->mmio_base + X_DATAREG); writeb( XCOLMSK0GREEN, card->mmio_base + PALWTADD); writeb( card->colkey_mask[1], card->mmio_base + X_DATAREG); writeb( XCOLMSK0BLUE, card->mmio_base + PALWTADD); writeb( card->colkey_mask[2], card->mmio_base + X_DATAREG); writeb( XCOLMSK, card->mmio_base + PALWTADD); writeb( card->colkey_mask[3], card->mmio_base + X_DATAREG); } else if(!card->colkey_saved){ // save it card->colkey_saved=1; // Get color key registers: writeb( XKEYOPMODE, card->mmio_base + PALWTADD); card->colkey_on=(unsigned char)readb(card->mmio_base + X_DATAREG) & 1; writeb( XCOLKEY0RED, card->mmio_base + PALWTADD); card->colkey_color[0]=(unsigned char)readb(card->mmio_base + X_DATAREG); writeb( XCOLKEY0GREEN, card->mmio_base + PALWTADD); card->colkey_color[1]=(unsigned char)readb(card->mmio_base + X_DATAREG); writeb( XCOLKEY0BLUE, card->mmio_base + PALWTADD); card->colkey_color[2]=(unsigned char)readb(card->mmio_base + X_DATAREG); writeb( X_COLKEY, card->mmio_base + PALWTADD); card->colkey_color[3]=(unsigned char)readb(card->mmio_base + X_DATAREG); writeb( XCOLMSK0RED, card->mmio_base + PALWTADD); card->colkey_mask[0]=(unsigned char)readb(card->mmio_base + X_DATAREG); writeb( XCOLMSK0GREEN, card->mmio_base + PALWTADD); card->colkey_mask[1]=(unsigned char)readb(card->mmio_base + X_DATAREG); writeb( XCOLMSK0BLUE, card->mmio_base + PALWTADD); card->colkey_mask[2]=(unsigned char)readb(card->mmio_base + X_DATAREG); writeb( XCOLMSK, card->mmio_base + PALWTADD); card->colkey_mask[3]=(unsigned char)readb(card->mmio_base + X_DATAREG);#ifdef MP_DEBUG printk("mga_vid: Saved colorkey (ON: %d %02X:%02X:%02X)\n", card->colkey_on, card->colkey_color[0], card->colkey_color[1], card->colkey_color[2]);#endif } if(!restore){ writeb( XKEYOPMODE, card->mmio_base + PALWTADD); writeb( card->config.colkey_on, card->mmio_base + X_DATAREG); if ( card->config.colkey_on ) { uint32_t r=0, g=0, b=0; writeb( XMULCTRL, card->mmio_base + PALWTADD); switch (readb (card->mmio_base + X_DATAREG)) { case BPP_8: /* Need to look up the color index, just using color 0 for now. */ break; case BPP_15: r = card->config.colkey_red >> 3; g = card->config.colkey_green >> 3; b = card->config.colkey_blue >> 3; break; case BPP_16: r = card->config.colkey_red >> 3; g = card->config.colkey_green >> 2; b = card->config.colkey_blue >> 3; break; case BPP_24: case BPP_32_DIR: case BPP_32_PAL: r = card->config.colkey_red; g = card->config.colkey_green; b = card->config.colkey_blue; break; } // Disable color keying on alpha channel writeb( XCOLMSK, card->mmio_base + PALWTADD); writeb( 0x00, card->mmio_base + X_DATAREG); writeb( X_COLKEY, card->mmio_base + PALWTADD); writeb( 0x00, card->mmio_base + X_DATAREG); // Set up color key registers writeb( XCOLKEY0RED, card->mmio_base + PALWTADD); writeb( r, card->mmio_base + X_DATAREG); writeb( XCOLKEY0GREEN, card->mmio_base + PALWTADD); writeb( g, card->mmio_base + X_DATAREG); writeb( XCOLKEY0BLUE, card->mmio_base + PALWTADD); writeb( b, card->mmio_base + X_DATAREG); // Set up color key mask registers writeb( XCOLMSK0RED, card->mmio_base + PALWTADD); writeb( 0xff, card->mmio_base + X_DATAREG); writeb( XCOLMSK0GREEN, card->mmio_base + PALWTADD); writeb( 0xff, card->mmio_base + X_DATAREG); writeb( XCOLMSK0BLUE, card->mmio_base + PALWTADD); writeb( 0xff, card->mmio_base + X_DATAREG); }} // Backend Scaler writel( card->regs.besctl, card->mmio_base + BESCTL); if(card->is_g400) writel( card->regs.beslumactl, card->mmio_base + BESLUMACTL); writel( card->regs.bespitch, card->mmio_base + BESPITCH); writel( card->regs.besa1org, card->mmio_base + BESA1ORG); writel( card->regs.besa1corg, card->mmio_base + BESA1CORG); writel( card->regs.besa2org, card->mmio_base + BESA2ORG); writel( card->regs.besa2corg, card->mmio_base + BESA2CORG); writel( card->regs.besb1org, card->mmio_base + BESB1ORG); writel( card->regs.besb1corg, card->mmio_base + BESB1CORG); writel( card->regs.besb2org, card->mmio_base + BESB2ORG); writel( card->regs.besb2corg, card->mmio_base + BESB2CORG); if(card->is_g400) { writel( card->regs.besa1c3org, card->mmio_base + BESA1C3ORG); writel( card->regs.besa2c3org, card->mmio_base + BESA2C3ORG); writel( card->regs.besb1c3org, card->mmio_base + BESB1C3ORG); writel( card->regs.besb2c3org, card->mmio_base + BESB2C3ORG); } writel( card->regs.beshcoord, card->mmio_base + BESHCOORD); writel( card->regs.beshiscal, card->mmio_base + BESHISCAL); writel( card->regs.beshsrcst, card->mmio_base + BESHSRCST); writel( card->regs.beshsrcend, card->mmio_base + BESHSRCEND); writel( card->regs.beshsrclst, card->mmio_base + BESHSRCLST); writel( card->regs.besvcoord, card->mmio_base + BESVCOORD); writel( card->regs.besviscal, card->mmio_base + BESVISCAL); writel( card->regs.besv1srclst, card->mmio_base + BESV1SRCLST); writel( card->regs.besv1wght, card->mmio_base + BESV1WGHT); writel( card->regs.besv2srclst, card->mmio_base + BESV2SRCLST); writel( card->regs.besv2wght, card->mmio_base + BESV2WGHT); //update the registers somewhere between 1 and 2 frames from now. writel( card->regs.besglobctl + ((readl(card->mmio_base + VCOUNT)+2)<<16), card->mmio_base + BESGLOBCTL);#if 0 printk(KERN_DEBUG "mga_vid: wrote BES registers\n"); printk(KERN_DEBUG "mga_vid: BESCTL = 0x%08x\n", readl(card->mmio_base + BESCTL)); printk(KERN_DEBUG "mga_vid: BESGLOBCTL = 0x%08x\n", readl(card->mmio_base + BESGLOBCTL)); printk(KERN_DEBUG "mga_vid: BESSTATUS= 0x%08x\n", readl(card->mmio_base + BESSTATUS));#endif#ifdef CRTC2// printk("c2ctl:0x%08x c2datactl:0x%08x\n", readl(card->mmio_base + C2CTL), readl(card->mmio_base + C2DATACTL));// printk("c2misc:0x%08x\n", readl(card->mmio_base + C2MISC));// printk("c2ctl:0x%08x c2datactl:0x%08x\n", card->cregs.c2ctl, card->cregs.c2datactl);// writel(card->cregs.c2ctl, card->mmio_base + C2CTL); writel(((readl(card->mmio_base + C2CTL) & ~0x03e00000) + (card->cregs.c2ctl & 0x03e00000)), card->mmio_base + C2CTL); writel(((readl(card->mmio_base + C2DATACTL) & ~0x000000ff) + (card->cregs.c2datactl & 0x000000ff)), card->mmio_base + C2DATACTL); // ctrc2 // disable CRTC2 acording to specs// writel(card->cregs.c2ctl & 0xfffffff0, card->mmio_base + C2CTL); // je to treba ???// writeb((readb(card->mmio_base + XMISCCTRL) & 0x19) | 0xa2, card->mmio_base + XMISCCTRL); // MAFC - mfcsel & vdoutsel// writeb((readb(card->mmio_base + XMISCCTRL) & 0x19) | 0x92, card->mmio_base + XMISCCTRL);// writeb((readb(card->mmio_base + XMISCCTRL) & ~0xe9) + 0xa2, card->mmio_base + XMISCCTRL);// writel(card->cregs.c2datactl, card->mmio_base + C2DATACTL);// writel(card->cregs.c2hparam, card->mmio_base + C2HPARAM);// writel(card->cregs.c2hsync, card->mmio_base + C2HSYNC);// writel(card->cregs.c2vparam, card->mmio_base + C2VPARAM);// writel(card->cregs.c2vsync, card->mmio_base + C2VSYNC); writel(card->cregs.c2misc, card->mmio_base + C2MISC);#ifdef MP_DEBUG printk("c2offset = %d\n",card->cregs.c2offset);#endif writel(card->cregs.c2offset, card->mmio_base + C2OFFSET); writel(card->cregs.c2startadd0, card->mmio_base + C2STARTADD0);// writel(card->cregs.c2startadd1, card->mmio_base + C2STARTADD1); writel(card->cregs.c2pl2startadd0, card->mmio_base + C2PL2STARTADD0);// writel(card->cregs.c2pl2startadd1, card->mmio_base + C2PL2STARTADD1); writel(card->cregs.c2pl3startadd0, card->mmio_base + C2PL3STARTADD0);// writel(card->cregs.c2pl3startadd1, card->mmio_base + C2PL3STARTADD1); writel(card->cregs.c2spicstartadd0, card->mmio_base + C2SPICSTARTADD0);// writel(card->cregs.c2spicstartadd1, card->mmio_base + C2SPICSTARTADD1);// writel(card->cregs.c2subpiclut, card->mmio_base + C2SUBPICLUT);// writel(card->cregs.c2preload, card->mmio_base + C2PRELOAD); // finaly enable everything// writel(card->cregs.c2ctl, card->mmio_base + C2CTL);// printk("c2ctl:0x%08x c2datactl:0x%08x\n",readl(card->mmio_base + C2CTL),readl(card->mmio_base + C2DATACTL));// printk("c2misc:0x%08x\n", readl(card->mmio_base + C2MISC));#endif }static int mga_vid_set_config(mga_card_t * card){ int x, y, sw, sh, dw, dh; int besleft, bestop, ifactor, ofsleft, ofstop, baseadrofs, weight, weights; mga_vid_config_t *config = &card->config; int frame_size = card->config.frame_size;#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_width + 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_height; unsigned int vsyncstart = vdispend + lower_margin; unsigned int vsyncend = vsyncstart + vsync_len; unsigned int vtotal = vsyncend + upper_margin;#endif x = config->x_org; y = config->y_org; sw = config->src_width; sh = config->src_height; dw = config->dest_width; dh = config->dest_height;#ifdef MP_DEBUG printk(KERN_DEBUG "mga_vid: Setting up a %dx%d+%d+%d video window (src %dx%d) format %X\n", dw, dh, x, y, sw, sh, config->format);#endif if(sw<4 || sh<4 || dw<4 || dh<4){ printk(KERN_ERR "mga_vid: Invalid src/dest dimenstions\n"); return -1; } //FIXME check that window is valid and inside desktop //Setup the BES registers for a three plane 4:2:0 video source card->regs.besglobctl = 0;switch(config->format){ case MGA_VID_FORMAT_YV12: case MGA_VID_FORMAT_I420: case MGA_VID_FORMAT_IYUV: card->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(card->is_g400) { //zoom disabled, zoom filter disabled, 420 3 plane format, proc amp //disabled, rgb mode disabled card->regs.besglobctl = (1<<5); } else { //zoom disabled, zoom filter disabled, Cb samples in 0246, Cr //in 1357, BES register update on besvcnt card->regs.besglobctl = 0; }#endif break; case MGA_VID_FORMAT_YUY2: card->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 card->regs.besglobctl = 0; // YUY2 format selected break; case MGA_VID_FORMAT_UYVY: card->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 card->regs.besglobctl = 1<<6; // UYVY format selected break; default: printk(KERN_ERR "mga_vid: Unsupported pixel format: 0x%X\n",config->format); return -1;} // setting black&white mode card->regs.besctl|=(card->regs.blackie<<20); //Enable contrast and brightness control card->regs.besglobctl |= (1<<5) + (1<<7); // brightness (-128..127) && contrast (0..255) card->regs.beslumactl = (card->brightness << 16) | ((card->contrast+0x80)&0xFFFF); //Setup destination window boundaries besleft = x > 0 ? x : 0; bestop = y > 0 ? y : 0; card->regs.beshcoord = (besleft<<16) + (x + dw-1); card->regs.besvcoord = (bestop<<16) + (y + dh-1); //Setup source dimensions card->regs.beshsrclst = (sw - 1) << 16; card->regs.bespitch = (sw + 31) & ~31 ; //Setup horizontal scaling ifactor = ((sw-1)<<14)/(dw-1); ofsleft = besleft - x; card->regs.beshiscal = ifactor<<2; card->regs.beshsrcst = (ofsleft*ifactor)<<2; card->regs.beshsrcend = card->regs.beshsrcst + (((dw - ofsleft - 1) * ifactor) << 2); //Setup vertical scaling ifactor = ((sh-1)<<14)/(dh-1); ofstop = bestop - y; card->regs.besviscal = ifactor<<2; baseadrofs = ( (ofstop * card->regs.besviscal) >>16) * card->regs.bespitch; //frame_size = ((sw + 31) & ~31) * sh + (((sw + 31) & ~31) * sh) / 2; card->regs.besa1org = (uint32_t) card->src_base + baseadrofs; card->regs.besa2org = (uint32_t) card->src_base + baseadrofs + 1*frame_size; card->regs.besb1org = (uint32_t) card->src_base + baseadrofs + 2*frame_size; card->regs.besb2org = (uint32_t) card->src_base + baseadrofs + 3*frame_size;if(config->format==MGA_VID_FORMAT_YV12 ||config->format==MGA_VID_FORMAT_IYUV ||config->format==MGA_VID_FORMAT_I420 ){ // planar YUV frames: if (card->is_g400) baseadrofs = ( ( (ofstop * card->regs.besviscal ) / 4 ) >> 16 ) * card->regs.bespitch; else baseadrofs = ( ( ( ofstop * card->regs.besviscal ) / 2 ) >> 16 ) * card->regs.bespitch; if(config->format==MGA_VID_FORMAT_YV12 || !card->is_g400){ card->regs.besa1corg = (uint32_t) card->src_base + baseadrofs + card->regs.bespitch * sh ; card->regs.besa2corg = (uint32_t) card->src_base + baseadrofs + 1*frame_size + card->regs.bespitch * sh; card->regs.besb1corg = (uint32_t) card->src_base + baseadrofs + 2*frame_size + card->regs.bespitch * sh; card->regs.besb2corg = (uint32_t) card->src_base + baseadrofs + 3*frame_size + card->regs.bespitch * sh; card->regs.besa1c3org = card->regs.besa1corg + ( (card->regs.bespitch * sh) / 4); card->regs.besa2c3org = card->regs.besa2corg + ( (card->regs.bespitch * sh) / 4); card->regs.besb1c3org = card->regs.besb1corg + ( (card->regs.bespitch * sh) / 4); card->regs.besb2c3org = card->regs.besb2corg + ( (card->regs.bespitch * sh) / 4); } else { card->regs.besa1c3org = (uint32_t) card->src_base + baseadrofs + card->regs.bespitch * sh ; card->regs.besa2c3org = (uint32_t) card->src_base + baseadrofs + 1*frame_size + card->regs.bespitch * sh; card->regs.besb1c3org = (uint32_t) card->src_base + baseadrofs + 2*frame_size + card->regs.bespitch * sh; card->regs.besb2c3org = (uint32_t) card->src_base + baseadrofs + 3*frame_size + card->regs.bespitch * sh; card->regs.besa1corg = card->regs.besa1c3org + ((card->regs.bespitch * sh) / 4); card->regs.besa2corg = card->regs.besa2c3org + ((card->regs.bespitch * sh) / 4); card->regs.besb1corg = card->regs.besb1c3org + ((card->regs.bespitch * sh) / 4); card->regs.besb2corg = card->regs.besb2c3org + ((card->regs.bespitch * sh) / 4); }} weight = ofstop * (card->regs.besviscal >> 2); weights = weight < 0 ? 1 : 0; card->regs.besv2wght = card->regs.besv1wght = (weights << 16) + ((weight & 0x3FFF) << 2); card->regs.besv2srclst = card->regs.besv1srclst = sh - 1 - (((ofstop * card->regs.besviscal) >> 16) & 0x03FF);#ifdef CRTC2 // pridat hlavni registry - tj. casovani ...switch(config->format){ case MGA_VID_FORMAT_YV12: case MGA_VID_FORMAT_I420: case MGA_VID_FORMAT_IYUV: card->cregs.c2ctl = 1 // CRTC2 enabled + (1<<1) // external clock + (0<<2) // external clock + (1<<3) // pixel clock enable - not needed ???
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -