📄 matroxfb_dac1064.c
字号:
int i; int tmout; CRITFLAGS CRITBEGIN for (i = 0; i < 3; i++) outDAC1064(PMINFO M1064_XPIXPLLCM + i, hw->DACclk[i]); for (tmout = 500000; tmout; tmout--) { if (inDAC1064(PMINFO M1064_XPIXPLLSTAT) & 0x40) break; udelay(10); }; CRITEND if (!tmout) printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");#undef minfo return 0;}static int m1064_start(void* outdev) { /* nothing */ return 0;}static void m1064_incuse(void* outdev) { /* nothing yet; MODULE_INC_USE in future... */}static void m1064_decuse(void* outdev) { /* nothing yet; MODULE_DEC_USE in future... */}static int m1064_setmode(void* outdev, u_int32_t mode) { if (mode != MATROXFB_OUTPUT_MODE_MONITOR) return -EINVAL; return 0;}static struct matrox_altout m1064 = { m1064_compute, m1064_program, m1064_start, m1064_incuse, m1064_decuse, m1064_setmode};#endif /* NEED_DAC1064 */#ifdef CONFIG_FB_MATROX_MYSTIQUEstatic int MGA1064_init(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) { DBG("MGA1064_init") if (DAC1064_init_1(PMINFO hw, m, p)) return 1; if (matroxfb_vgaHWinit(PMINFO hw, m, p)) return 1; hw->MiscOutReg = 0xCB; if (m->sync & FB_SYNC_HOR_HIGH_ACT) hw->MiscOutReg &= ~0x40; if (m->sync & FB_SYNC_VERT_HIGH_ACT) hw->MiscOutReg &= ~0x80; if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */ hw->CRTCEXT[3] |= 0x40; if (DAC1064_init_2(PMINFO hw, m, p)) return 1; return 0;}#endif#ifdef CONFIG_FB_MATROX_G100static int MGAG100_init(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) { DBG("MGAG100_init") if (DAC1064_init_1(PMINFO hw, m, p)) return 1; hw->MXoptionReg &= ~0x2000; if (matroxfb_vgaHWinit(PMINFO hw, m, p)) return 1; hw->MiscOutReg = 0xEF; if (m->sync & FB_SYNC_HOR_HIGH_ACT) hw->MiscOutReg &= ~0x40; if (m->sync & FB_SYNC_VERT_HIGH_ACT) hw->MiscOutReg &= ~0x80; if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */ hw->CRTCEXT[3] |= 0x40; if (DAC1064_init_2(PMINFO hw, m, p)) return 1; return 0;}#endif /* G100 */#ifdef CONFIG_FB_MATROX_MYSTIQUEstatic void MGA1064_ramdac_init(WPMINFO struct matrox_hw_state* hw){ DBG("MGA1064_ramdac_init"); /* ACCESS_FBINFO(features.DAC1064.vco_freq_min) = 120000; */ ACCESS_FBINFO(features.pll.vco_freq_min) = 62000; ACCESS_FBINFO(features.pll.ref_freq) = 14318; ACCESS_FBINFO(features.pll.feed_div_min) = 100; ACCESS_FBINFO(features.pll.feed_div_max) = 127; ACCESS_FBINFO(features.pll.in_div_min) = 1; ACCESS_FBINFO(features.pll.in_div_max) = 31; ACCESS_FBINFO(features.pll.post_shift_max) = 3; ACCESS_FBINFO(features.DAC1064.xvrefctrl) = DAC1064_XVREFCTRL_EXTERNAL; /* maybe cmdline MCLK= ?, doc says gclk=44MHz, mclk=66MHz... it was 55/83 with old values */ DAC1064_setmclk(PMINFO hw, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PLL, 133333);}#endif#ifdef CONFIG_FB_MATROX_G100/* BIOS environ */static int x7AF4 = 0x10; /* flags, maybe 0x10 = SDRAM, 0x00 = SGRAM??? */ /* G100 wants 0x10, G200 SGRAM does not care... */#if 0static int def50 = 0; /* reg50, & 0x0F, & 0x3000 (only 0x0000, 0x1000, 0x2000 (0x3000 disallowed and treated as 0) */#endifstatic void MGAG100_progPixClock(CPMINFO int flags, int m, int n, int p){ int reg; int selClk; int clk; DBG("MGAG100_progPixClock") outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) | M1064_XPIXCLKCTRL_DIS | M1064_XPIXCLKCTRL_PLL_UP); switch (flags & 3) { case 0: reg = M1064_XPIXPLLAM; break; case 1: reg = M1064_XPIXPLLBM; break; default: reg = M1064_XPIXPLLCM; break; } outDAC1064(PMINFO reg++, m); outDAC1064(PMINFO reg++, n); outDAC1064(PMINFO reg, p); selClk = mga_inb(M_MISC_REG_READ) & ~0xC; /* there should be flags & 0x03 & case 0/1/else */ /* and we should first select source and after that we should wait for PLL */ /* and we are waiting for PLL with oscilator disabled... Is it right? */ switch (flags & 0x03) { case 0x00: break; case 0x01: selClk |= 4; break; default: selClk |= 0x0C; break; } mga_outb(M_MISC_REG, selClk); for (clk = 500000; clk; clk--) { if (inDAC1064(PMINFO M1064_XPIXPLLSTAT) & 0x40) break; udelay(10); }; if (!clk) printk(KERN_ERR "matroxfb: Pixel PLL%c not locked after usual time\n", (reg-M1064_XPIXPLLAM-2)/4 + 'A'); selClk = inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_SRC_MASK; switch (flags & 0x0C) { case 0x00: selClk |= M1064_XPIXCLKCTRL_SRC_PCI; break; case 0x04: selClk |= M1064_XPIXCLKCTRL_SRC_PLL; break; default: selClk |= M1064_XPIXCLKCTRL_SRC_EXT; break; } outDAC1064(PMINFO M1064_XPIXCLKCTRL, selClk); outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_DIS);}static void MGAG100_setPixClock(CPMINFO int flags, int freq){ unsigned int m, n, p; DBG("MGAG100_setPixClock") DAC1064_calcclock(PMINFO freq, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p); MGAG100_progPixClock(PMINFO flags, m, n, p);}#endif#ifdef CONFIG_FB_MATROX_MYSTIQUEstatic int MGA1064_preinit(WPMINFO struct matrox_hw_state* hw){ static const int vxres_mystique[] = { 512, 640, 768, 800, 832, 960, 1024, 1152, 1280, 1600, 1664, 1920, 2048, 0}; DBG("MGA1064_preinit") /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */ ACCESS_FBINFO(capable.text) = 1; ACCESS_FBINFO(capable.vxres) = vxres_mystique; ACCESS_FBINFO(features.accel.has_cacheflush) = 1; ACCESS_FBINFO(cursor.timer.function) = matroxfb_DAC1064_flashcursor; ACCESS_FBINFO(primout) = &m1064; if (ACCESS_FBINFO(devflags.noinit)) return 0; /* do not modify settings */ hw->MXoptionReg &= 0xC0000100; hw->MXoptionReg |= 0x00094E20; if (ACCESS_FBINFO(devflags.novga)) hw->MXoptionReg &= ~0x00000100; if (ACCESS_FBINFO(devflags.nobios)) hw->MXoptionReg &= ~0x40000000; if (ACCESS_FBINFO(devflags.nopciretry)) hw->MXoptionReg |= 0x20000000; pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); mga_setr(M_SEQ_INDEX, 0x01, 0x20); mga_outl(M_CTLWTST, 0x00000000); udelay(200); mga_outl(M_MACCESS, 0x00008000); udelay(100); mga_outl(M_MACCESS, 0x0000C000); return 0;}static void MGA1064_reset(WPMINFO struct matrox_hw_state* hw){ DBG("MGA1064_reset"); ACCESS_FBINFO(features.DAC1064.cursorimage) = ACCESS_FBINFO(video.len_usable) - 1024; if (ACCESS_FBINFO(devflags.hwcursor)) ACCESS_FBINFO(video.len_usable) -= 1024; matroxfb_fastfont_init(MINFO); MGA1064_ramdac_init(PMINFO hw);}#endif#ifdef CONFIG_FB_MATROX_G100static int MGAG100_preinit(WPMINFO struct matrox_hw_state* hw){ static const int vxres_g100[] = { 512, 640, 768, 800, 832, 960, 1024, 1152, 1280, 1600, 1664, 1920, 2048, 0}; u_int32_t reg50;#if 0 u_int32_t q;#endif DBG("MGAG100_preinit") /* there are some instabilities if in_div > 19 && vco < 61000 */ if (ACCESS_FBINFO(devflags.g450dac)) { ACCESS_FBINFO(features.pll.vco_freq_min) = 130000; /* my sample: >118 */ } else { ACCESS_FBINFO(features.pll.vco_freq_min) = 62000; } ACCESS_FBINFO(features.pll.ref_freq) = 27000; ACCESS_FBINFO(features.pll.feed_div_min) = 7; ACCESS_FBINFO(features.pll.feed_div_max) = 127; ACCESS_FBINFO(features.pll.in_div_min) = 1; ACCESS_FBINFO(features.pll.in_div_max) = 31; ACCESS_FBINFO(features.pll.post_shift_max) = 3; ACCESS_FBINFO(features.DAC1064.xvrefctrl) = DAC1064_XVREFCTRL_G100_DEFAULT; /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */ ACCESS_FBINFO(capable.text) = 1; ACCESS_FBINFO(capable.vxres) = vxres_g100; ACCESS_FBINFO(features.accel.has_cacheflush) = 1; ACCESS_FBINFO(cursor.timer.function) = matroxfb_DAC1064_flashcursor; ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100 ? ACCESS_FBINFO(devflags.sgram) : 1; ACCESS_FBINFO(primout) = &m1064; if (ACCESS_FBINFO(devflags.g450dac)) { /* we must do this always, BIOS does not do it for us and accelerator dies without it */ mga_outl(0x1C0C, 0); } if (ACCESS_FBINFO(devflags.noinit)) return 0; hw->MXoptionReg &= 0xC0000100; hw->MXoptionReg |= 0x00000020; if (ACCESS_FBINFO(devflags.novga)) hw->MXoptionReg &= ~0x00000100; if (ACCESS_FBINFO(devflags.nobios)) hw->MXoptionReg &= ~0x40000000; if (ACCESS_FBINFO(devflags.nopciretry)) hw->MXoptionReg |= 0x20000000; pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); DAC1064_setmclk(PMINFO hw, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PCI, 133333); if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100) { pci_read_config_dword(ACCESS_FBINFO(pcidev), 0x50, ®50); reg50 &= ~0x3000; pci_write_config_dword(ACCESS_FBINFO(pcidev), 0x50, reg50); hw->MXoptionReg |= 0x1080; pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); mga_outl(M_CTLWTST, 0x00000300); /* mga_outl(M_CTLWTST, 0x03258A31); */ udelay(100); mga_outb(0x1C05, 0x00); mga_outb(0x1C05, 0x80); udelay(100); mga_outb(0x1C05, 0x40); mga_outb(0x1C05, 0xC0); udelay(100); reg50 &= ~0xFF; reg50 |= 0x07; pci_write_config_dword(ACCESS_FBINFO(pcidev), 0x50, reg50); /* it should help with G100 */ mga_outb(M_GRAPHICS_INDEX, 6); mga_outb(M_GRAPHICS_DATA, (mga_inb(M_GRAPHICS_DATA) & 3) | 4); mga_setr(M_EXTVGA_INDEX, 0x03, 0x81); mga_setr(M_EXTVGA_INDEX, 0x04, 0x00); mga_writeb(ACCESS_FBINFO(video.vbase), 0x0000, 0xAA); mga_writeb(ACCESS_FBINFO(video.vbase), 0x0800, 0x55); mga_writeb(ACCESS_FBINFO(video.vbase), 0x4000, 0x55);#if 0 if (mga_readb(ACCESS_FBINFO(video.vbase), 0x0000) != 0xAA) { hw->MXoptionReg &= ~0x1000; }#endif hw->MXoptionReg |= 0x00078020; } else if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG200) { pci_read_config_dword(ACCESS_FBINFO(pcidev), 0x50, ®50); reg50 &= ~0x3000; pci_write_config_dword(ACCESS_FBINFO(pcidev), 0x50, reg50); if (ACCESS_FBINFO(devflags.memtype) == -1) ACCESS_FBINFO(devflags.memtype) = 3; hw->MXoptionReg |= (ACCESS_FBINFO(devflags.memtype) & 7) << 10; if (ACCESS_FBINFO(devflags.sgram)) hw->MXoptionReg |= 0x4000; mga_outl(M_CTLWTST, 0x042450A1); mga_outl(M_MEMRDBK, 0x00000108); udelay(200); mga_outl(M_MACCESS, 0x00000000); mga_outl(M_MACCESS, 0x00008000); udelay(100); mga_outw(M_MEMRDBK, 0x00000108); hw->MXoptionReg |= 0x00078020; } else { pci_read_config_dword(ACCESS_FBINFO(pcidev), 0x50, ®50); reg50 &= ~0x00000100; reg50 |= 0x00000000; pci_write_config_dword(ACCESS_FBINFO(pcidev), 0x50, reg50); if (ACCESS_FBINFO(devflags.memtype) == -1) ACCESS_FBINFO(devflags.memtype) = 0; hw->MXoptionReg |= (ACCESS_FBINFO(devflags.memtype) & 7) << 10; if (ACCESS_FBINFO(devflags.sgram)) hw->MXoptionReg |= 0x4000; mga_outl(M_CTLWTST, 0x042450A1); mga_outl(M_MEMRDBK, 0x00000108); udelay(200); mga_outl(M_MACCESS, 0x00000000); mga_outl(M_MACCESS, 0x00008000); udelay(100); mga_outl(M_MEMRDBK, 0x00000108); hw->MXoptionReg |= 0x00040020; } pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); return 0;}static void MGAG100_reset(WPMINFO struct matrox_hw_state* hw){ u_int8_t b; DBG("MGAG100_reset") ACCESS_FBINFO(features.DAC1064.cursorimage) = ACCESS_FBINFO(video.len_usable) - 1024; if (ACCESS_FBINFO(devflags.hwcursor)) ACCESS_FBINFO(video.len_usable) -= 1024; matroxfb_fastfont_init(MINFO); {#ifdef G100_BROKEN_IBM_82351 u_int32_t d; find 1014/22 (IBM/82351); /* if found and bridging Matrox, do some strange stuff */ pci_read_config_byte(ibm, PCI_SECONDARY_BUS, &b); if (b == ACCESS_FBINFO(pcidev)->bus->number) { pci_write_config_byte(ibm, PCI_COMMAND+1, 0); /* disable back-to-back & SERR */ pci_write_config_byte(ibm, 0x41, 0xF4); /* ??? */ pci_write_config_byte(ibm, PCI_IO_BASE, 0xF0); /* ??? */ pci_write_config_byte(ibm, PCI_IO_LIMIT, 0x00); /* ??? */ }#endif if (!ACCESS_FBINFO(devflags.noinit)) { if (x7AF4 & 8) { hw->MXoptionReg |= 0x40; pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); } mga_setr(M_EXTVGA_INDEX, 0x06, 0x50); } } DAC1064_setmclk(PMINFO hw, DAC1064_OPT_RESERVED | DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV1 | DAC1064_OPT_SCLK_PLL, 133333); if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) { if (ACCESS_FBINFO(devflags.dfp_type) == -1) { ACCESS_FBINFO(devflags.dfp_type) = inDAC1064(PMINFO 0x1F); } } if (ACCESS_FBINFO(devflags.noinit)) return; MGAG100_setPixClock(PMINFO 4, 25175); MGAG100_setPixClock(PMINFO 5, 28322); if (x7AF4 & 0x10) { b = inDAC1064(PMINFO M1064_XGENIODATA) & ~1; outDAC1064(PMINFO M1064_XGENIODATA, b); b = inDAC1064(PMINFO M1064_XGENIOCTRL) | 1; outDAC1064(PMINFO M1064_XGENIOCTRL, b); }}#endif#ifdef CONFIG_FB_MATROX_MYSTIQUEstatic void MGA1064_restore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw_state* oldhw, struct display* p) { int i; CRITFLAGS DBG("MGA1064_restore") CRITBEGIN pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); mga_outb(M_IEN, 0x00); mga_outb(M_CACHEFLUSH, 0x00); CRITEND DAC1064_restore_1(PMINFO hw, oldhw); matroxfb_vgaHWrestore(PMINFO hw, oldhw); for (i = 0; i < 6; i++) mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]); DAC1064_restore_2(PMINFO hw, oldhw, p);}#endif#ifdef CONFIG_FB_MATROX_G100static void MGAG100_restore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw_state* oldhw, struct display* p) { int i; CRITFLAGS DBG("MGAG100_restore") CRITBEGIN pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); CRITEND DAC1064_restore_1(PMINFO hw, oldhw); matroxfb_vgaHWrestore(PMINFO hw, oldhw);#ifdef CONFIG_FB_MATROX_32MB if (ACCESS_FBINFO(devflags.support32MB)) mga_setr(M_EXTVGA_INDEX, 8, hw->CRTCEXT[8]);#endif for (i = 0; i < 6; i++) mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]); DAC1064_restore_2(PMINFO hw, oldhw, p);}#endif#ifdef CONFIG_FB_MATROX_MYSTIQUEstruct matrox_switch matrox_mystique = { MGA1064_preinit, MGA1064_reset, MGA1064_init, MGA1064_restore, DAC1064_selhwcursor};EXPORT_SYMBOL(matrox_mystique);#endif#ifdef CONFIG_FB_MATROX_G100struct matrox_switch matrox_G100 = { MGAG100_preinit, MGAG100_reset, MGAG100_init, MGAG100_restore, DAC1064_selhwcursor};EXPORT_SYMBOL(matrox_G100);#endif#ifdef NEED_DAC1064EXPORT_SYMBOL(DAC1064_global_init);EXPORT_SYMBOL(DAC1064_global_restore);#endifMODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -