📄 stradis.c
字号:
if (loadfile != 1 && loadfile != 2) { continue; /* skip to next card */ } if (saa->boardcfg[0] && loadfile == 1 ) continue; /* skip to next card */ if (saa->boardcfg[0] != 1 && loadfile == 2) continue; /* skip to next card */ saa->boardcfg[0]++; /* mark fpga handled */ printk("stradis%d: loading %s\n", saa->nr, bitdata->loadwhat); if (loadtwo && loadfile == 2) goto send_fpga_stuff; /* turn on the Audio interface to set PROG low */ saawrite(0x00400040, SAA7146_GPIO_CTRL); saaread(SAA7146_PSR); /* ensure posted write */ /* wait for everyone to reset */ mdelay(10); saawrite(0x00400000, SAA7146_GPIO_CTRL); } else { /* original card */ if (strncmp(bitdata->loadwhat, "decoder2", 8)) continue; /* fpga not for this card */ /* Pull the Xilinx PROG signal WS3 low */ saawrite(0x02000200, SAA7146_MC1); /* Turn on the Audio interface so can set PROG low */ saawrite(0x000000c0, SAA7146_ACON1); /* Pull the Xilinx INIT signal (GPIO2) low */ saawrite(0x00400000, SAA7146_GPIO_CTRL); /* Make sure everybody resets */ saaread(SAA7146_PSR); /* ensure posted write */ mdelay(10); /* Release the Xilinx PROG signal */ saawrite(0x00000000, SAA7146_ACON1); /* Turn off the Audio interface */ saawrite(0x02000000, SAA7146_MC1); } /* Release Xilinx INIT signal (WS2) */ saawrite(0x00000000, SAA7146_GPIO_CTRL); /* Wait for the INIT to go High */ for (i = 0; i < 10000 && !(saaread(SAA7146_PSR) & SAA7146_PSR_PIN2); i++) schedule(); if (i == 1000) { printk(KERN_INFO "stradis%d: no fpga INIT\n", saa->nr); return -1; }send_fpga_stuff: if (NewCard) { for (i = startindex; i < bitdata->datasize; i++) newdma[i - startindex] = bitmangler[bitdata->data[i]]; debiwrite(saa, 0x01420000, 0, 0, ((bitdata->datasize - startindex) + 5)); if (loadtwo) { if (loadfile == 1) { printk("stradis%d: " "awaiting 2nd FPGA bitfile\n", saa->nr); continue; /* skip to next card */ } } } else { for (i = startindex; i < bitdata->datasize; i++) dmabuf[i - startindex] = bitmangler[bitdata->data[i]]; debiwrite(saa, 0x014a0000, 0, 0, ((bitdata->datasize - startindex) + 5) * 2); } for (i = 0; i < 1000 && !(saaread(SAA7146_PSR) & SAA7146_PSR_PIN2); i++) schedule(); if (i == 1000) { printk(KERN_INFO "stradis%d: FPGA load failed\n", saa->nr); failure++; continue; } if (!NewCard) { /* Pull the Xilinx INIT signal (GPIO2) low */ saawrite(0x00400000, SAA7146_GPIO_CTRL); saaread(SAA7146_PSR); /* ensure posted write */ mdelay(2); saawrite(0x00000000, SAA7146_GPIO_CTRL); mdelay(2); } printk(KERN_INFO "stradis%d: FPGA Loaded\n", saa->nr); saa->boardcfg[0] = 26; /* mark fpga programmed */ /* set VXCO to its lowest frequency */ debiwrite(saa, debNormal, XILINX_PWM, 0, 2); if (NewCard) { /* mute CS3310 */ if (HaveCS3310) debiwrite(saa, debNormal, XILINX_CS3310_CMPLT, 0, 2); /* set VXCO to PWM mode, release reset, blank on */ debiwrite(saa, debNormal, XILINX_CTL0, 0xffc4, 2); mdelay(10); /* unmute CS3310 */ if (HaveCS3310) debiwrite(saa, debNormal, XILINX_CTL0, 0x2020, 2); } /* set source Black */ debiwrite(saa, debNormal, XILINX_CTL0, 0x1707, 2); saa->boardcfg[4] = 22; /* set NTSC First Active Line */ saa->boardcfg[5] = 23; /* set PAL First Active Line */ saa->boardcfg[54] = 2; /* set NTSC Last Active Line - 256 */ saa->boardcfg[55] = 54; /* set PAL Last Active Line - 256 */ set_out_format(saa, VIDEO_MODE_NTSC); mdelay(50); /* begin IBM chip init */ debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 4, 2); saaread(SAA7146_PSR); /* wait for reset */ mdelay(5); debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0, 2); debiread(saa, debNormal, IBM_MP2_CHIP_CONTROL, 2); debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0x10, 2); debiwrite(saa, debNormal, IBM_MP2_CMD_ADDR, 0, 2); debiwrite(saa, debNormal, IBM_MP2_CHIP_MODE, 0x2e, 2); if (NewCard) { mdelay(5); /* set i2s rate converter to 48KHz */ debiwrite(saa, debNormal, 0x80c0, 6, 2); /* we must init CS8420 first since rev b pulls i2s */ /* master clock low and CS4341 needs i2s master to */ /* run the i2c port. */ if (HaveCS8420) { /* 0=consumer, 1=pro */ initialize_cs8420(saa, 0); } mdelay(5); if (HaveCS4341) initialize_cs4341(saa); } debiwrite(saa, debNormal, IBM_MP2_INFC_CTL, 0x48, 2); debiwrite(saa, debNormal, IBM_MP2_BEEP_CTL, 0xa000, 2); debiwrite(saa, debNormal, IBM_MP2_DISP_LBOR, 0, 2); debiwrite(saa, debNormal, IBM_MP2_DISP_TBOR, 0, 2); if (NewCard) set_genlock_offset(saa, 0); debiwrite(saa, debNormal, IBM_MP2_FRNT_ATTEN, 0, 2);#if 0 /* enable genlock */ debiwrite(saa, debNormal, XILINX_CTL0, 0x8000, 2);#else /* disable genlock */ debiwrite(saa, debNormal, XILINX_CTL0, 0x8080, 2);#endif } return failure;}static int do_ibm_reset(struct saa7146 *saa){ /* failure if decoder not previously programmed */ if (saa->boardcfg[0] < 37) return -EIO; /* mute CS3310 */ if (HaveCS3310) debiwrite(saa, debNormal, XILINX_CS3310_CMPLT, 0, 2); /* disable interrupts */ saawrite(0, SAA7146_IER); saa->audhead = saa->audtail = 0; saa->vidhead = saa->vidtail = 0; /* tristate debi bus, disable debi transfers */ saawrite(0x00880000, SAA7146_MC1); /* ensure posted write */ saaread(SAA7146_MC1); mdelay(50); /* re-enable debi transfers */ saawrite(0x00880088, SAA7146_MC1); /* set source Black */ debiwrite(saa, debNormal, XILINX_CTL0, 0x1707, 2); /* begin IBM chip init */ set_out_format(saa, CurrentMode); debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 4, 2); saaread(SAA7146_PSR); /* wait for reset */ mdelay(5); debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0, 2); debiread(saa, debNormal, IBM_MP2_CHIP_CONTROL, 2); debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, ChipControl, 2); debiwrite(saa, debNormal, IBM_MP2_CHIP_MODE, 0x2e, 2); if (NewCard) { mdelay(5); /* set i2s rate converter to 48KHz */ debiwrite(saa, debNormal, 0x80c0, 6, 2); /* we must init CS8420 first since rev b pulls i2s */ /* master clock low and CS4341 needs i2s master to */ /* run the i2c port. */ if (HaveCS8420) { /* 0=consumer, 1=pro */ initialize_cs8420(saa, 1); } mdelay(5); if (HaveCS4341) initialize_cs4341(saa); } debiwrite(saa, debNormal, IBM_MP2_INFC_CTL, 0x48, 2); debiwrite(saa, debNormal, IBM_MP2_BEEP_CTL, 0xa000, 2); debiwrite(saa, debNormal, IBM_MP2_DISP_LBOR, 0, 2); debiwrite(saa, debNormal, IBM_MP2_DISP_TBOR, 0, 2); if (NewCard) set_genlock_offset(saa, 0); debiwrite(saa, debNormal, IBM_MP2_FRNT_ATTEN, 0, 2); debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0x2000, 2); debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4552, 2); if (ibm_send_command(saa, IBM_MP2_CONFIG_DECODER, (ChipControl == 0x43 ? 0xe800 : 0xe000), 1)) { printk(KERN_ERR "stradis%d: IBM config failed\n", saa->nr); } if (HaveCS3310) { int i = CS3310MaxLvl; debiwrite(saa, debNormal, XILINX_CS3310_CMPLT, ((i<<8)|i), 2); } /* start video decoder */ debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, ChipControl, 2); /* 256k vid, 3520 bytes aud */ debiwrite(saa, debNormal, IBM_MP2_RB_THRESHOLD, 0x4037, 2); debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4573, 2); ibm_send_command(saa, IBM_MP2_PLAY, 0, 0); /* enable buffer threshold irq */ debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2); /* clear pending interrupts */ debiread(saa, debNormal, IBM_MP2_HOST_INT, 2); debiwrite(saa, debNormal, XILINX_CTL0, 0x1711, 2); return 0;}/* load the decoder microcode */static int initialize_ibmmpeg2(struct video_code *microcode){ int i, num; struct saa7146 *saa; for (num = 0; num < saa_num; num++) { saa = &saa7146s[num]; /* check that FPGA is loaded */ debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0xa55a, 2); if ((i = debiread(saa, debNormal, IBM_MP2_OSD_SIZE, 2)) != 0xa55a) { printk(KERN_INFO "stradis%d: %04x != 0xa55a\n", saa->nr, i);#if 0 return -1;#endif } if (!strncmp(microcode->loadwhat, "decoder.vid", 11)) { if (saa->boardcfg[0] > 27) continue; /* skip to next card */ /* load video control store */ saa->boardcfg[1] = 0x13; /* no-sync default */ debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 1, 2); debiwrite(saa, debNormal, IBM_MP2_PROC_IADDR, 0, 2); for (i = 0; i < microcode->datasize / 2; i++) debiwrite(saa, debNormal, IBM_MP2_PROC_IDATA, (microcode->data[i * 2] << 8) | microcode->data[i * 2 + 1], 2); debiwrite(saa, debNormal, IBM_MP2_PROC_IADDR, 0, 2); debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 0, 2); debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, ChipControl, 2); saa->boardcfg[0] = 28; } if (!strncmp(microcode->loadwhat, "decoder.aud", 11)) { if (saa->boardcfg[0] > 35) continue; /* skip to next card */ /* load audio control store */ debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 1, 2); debiwrite(saa, debNormal, IBM_MP2_AUD_IADDR, 0, 2); for (i = 0; i < microcode->datasize; i++) debiwrite(saa, debNormal, IBM_MP2_AUD_IDATA, microcode->data[i], 1); debiwrite(saa, debNormal, IBM_MP2_AUD_IADDR, 0, 2); debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 0, 2); debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0x2000, 2); debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4552, 2); if (ibm_send_command(saa, IBM_MP2_CONFIG_DECODER, 0xe000, 1)) { printk(KERN_ERR "stradis%d: IBM config failed\n", saa->nr); return -1; } /* set PWM to center value */ if (NewCard) { debiwrite(saa, debNormal, XILINX_PWM, saa->boardcfg[14] + (saa->boardcfg[13]<<8), 2); } else debiwrite(saa, debNormal, XILINX_PWM, 0x46, 2); if (HaveCS3310) { i = CS3310MaxLvl; debiwrite(saa, debNormal, XILINX_CS3310_CMPLT, ((i<<8)|i), 2); } printk(KERN_INFO "stradis%d: IBM MPEGCD%d Initialized\n", saa->nr, 18 + (debiread(saa, debNormal, IBM_MP2_CHIP_CONTROL, 2) >> 12)); /* start video decoder */ debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, ChipControl, 2); debiwrite(saa, debNormal, IBM_MP2_RB_THRESHOLD, 0x4037, 2); /* 256k vid, 3520 bytes aud */ debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4573, 2); ibm_send_command(saa, IBM_MP2_PLAY, 0, 0); /* enable buffer threshold irq */ debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2); debiread(saa, debNormal, IBM_MP2_HOST_INT, 2); /* enable gpio irq */ saawrite(0x00002000, SAA7146_GPIO_CTRL); /* enable decoder output to HPS */ debiwrite(saa, debNormal, XILINX_CTL0, 0x1711, 2); saa->boardcfg[0] = 37; } } return 0;}static u32 palette2fmt[] ={ /* some of these YUV translations are wrong */ 0xffffffff, 0x86000000, 0x87000000, 0x80000000, 0x8100000, 0x82000000, 0x83000000, 0x00000000, 0x03000000, 0x03000000, 0x0a00000, 0x03000000, 0x06000000, 0x00000000, 0x03000000, 0x0a000000, 0x0300000};static int bpp2fmt[4] ={ VIDEO_PALETTE_HI240, VIDEO_PALETTE_RGB565, VIDEO_PALETTE_RGB24, VIDEO_PALETTE_RGB32};/* I wish I could find a formula to calculate these... */static u32 h_prescale[64] ={ 0x10000000, 0x18040202, 0x18080000, 0x380c0606, 0x38100204, 0x38140808, 0x38180000, 0x381c0000, 0x3820161c, 0x38242a3b, 0x38281230, 0x382c4460, 0x38301040, 0x38340080, 0x38380000, 0x383c0000, 0x3840fefe, 0x3844ee9f, 0x3848ee9f, 0x384cee9f, 0x3850ee9f, 0x38542a3b, 0x38581230, 0x385c0000, 0x38600000, 0x38640000, 0x38680000, 0x386c0000, 0x38700000, 0x38740000, 0x38780000, 0x387c0000, 0x30800000, 0x38840000, 0x38880000, 0x388c0000, 0x38900000, 0x38940000, 0x38980000, 0x389c0000, 0x38a00000, 0x38a40000, 0x38a80000, 0x38ac0000, 0x38b00000, 0x38b40000, 0x38b80000, 0x38bc0000, 0x38c00000, 0x38c40000, 0x38c80000, 0x38cc0000, 0x38d00000, 0x38d40000, 0x38d80000, 0x38dc0000, 0x38e00000, 0x38e40000, 0x38e80000, 0x38ec0000, 0x38f00000, 0x38f40000, 0x38f80000, 0x38fc0000,};static u32 v_gain[64] ={ 0x016000ff, 0x016100ff, 0x016100ff, 0x016200ff, 0x016200ff, 0x016200ff, 0x016200ff, 0x016300ff, 0x016300ff, 0x016300ff, 0x016300ff, 0x016300ff, 0x016300ff, 0x016300ff, 0x016300ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,};static void saa7146_set_winsize(struct saa7146 *saa){ u32 format; int offset, yacl, ysci; saa->win.color_fmt = format = (saa->win.depth == 15) ? palette2fmt[VIDEO_PALETTE_RGB555] : palette2fmt[bpp2fmt[(saa->win.bpp - 1) & 3]]; offset = saa->win.x * saa->win.bpp + saa->win.y * saa->win.bpl; saawrite(saa->win.vidadr + offset, SAA7146_BASE_EVEN1); saawrite(saa->win.vidadr + offset + saa->win.bpl, SAA7146_BASE_ODD1); saawrite(saa->win.bpl * 2, SAA7146_PITCH1); saawrite(saa->win.vidadr + saa->win.bpl * saa->win.sheight, SAA7146_PROT_ADDR1); saawrite(0, SAA7146_PAGE1); saawrite(format|0x60, SAA7146_CLIP_FORMAT_CTRL); offset = (704 / (saa->win.width - 1)) & 0x3f; saawrite(h_prescale[offset], SAA7146_HPS_H_PRESCALE); offset = (720896 / saa->win.width) / (offset + 1); saawrite((offset<<12)|0x0c, SAA7146_HPS_H_SCALE); if (CurrentMode == VIDEO_MODE_NTSC) { yacl = /*(480 / saa->win.height - 1) & 0x3f*/ 0; ysci = 1024 - (saa->win.height * 1024 / 480); } else { yacl = /*(576 / saa->win.height - 1) & 0x3f*/ 0; ysci = 1024 - (saa->win.height * 1024 / 576); } saawrite((1<<31)|(ysci<<21)|(yacl<<15), SAA7146_HPS_V_SCALE); saawrite(v_gain[yacl], SAA7146_HPS_V_GAIN); saawrite(((SAA7146_MC2_UPLD_DMA1 | SAA7146_MC2_UPLD_HPS_V | SAA7146_MC2_UPLD_HPS_H) << 16) | (SAA7146_MC2_UPLD_DMA1 | SAA7146_MC2_UPLD_HPS_V | SAA7146_MC2_UPLD_HPS_H), SAA7146_MC2);}/* clip_draw_rectangle(cm,x,y,w,h) -- handle clipping an area * bitmap is fixed width, 128 bytes (1024 pixels represented) * arranged most-sigificant-bit-left in 32-bit words * based on saa7146 clipping hardware, it swaps bytes if LE * much of this makes up for egcs brain damage -- so if you * are wondering "why did he do this?" it is because the C * was adjusted to generate the optimal asm output without * writing non-portable __asm__ directives. */static void clip_draw_rectangle(u32 *clipmap, int x, int y, int w, int h){ register int startword, endword; register u32 bitsleft, bitsright; u32 *temp; if (x < 0) { w += x; x = 0; } if (y < 0) { h += y; y = 0; } if (w <= 0 || h <= 0 || x > 1023 || y > 639) return; /* throw away bad clips */ if (x + w > 1024) w = 1024 - x; if (y + h > 640) h = 640 - y; startword = (x >> 5); endword = ((x + w) >> 5); bitsleft = (0xffffffff >> (x & 31)); bitsright = (0xffffffff << (~((x + w) - (endword<<5)))); temp = &clipmap[(y<<5) + startword]; w = endword - startword; if (!w) { bitsleft |= bitsright; for (y = 0; y < h; y++) { *temp |= bitsleft;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -