📄 matroxfb_dac1064.c
字号:
default: return 1; /* unsupported depth */ } hw->DACreg[POS1064_XVREFCTRL] = ACCESS_FBINFO(features.DAC1064.xvrefctrl); hw->DACreg[POS1064_XGENCTRL] &= ~M1064_XGENCTRL_SYNC_ON_GREEN_MASK; hw->DACreg[POS1064_XGENCTRL] |= (m->sync & FB_SYNC_ON_GREEN)?M1064_XGENCTRL_SYNC_ON_GREEN:M1064_XGENCTRL_NO_SYNC_ON_GREEN; hw->DACreg[POS1064_XCURADDL] = 0; hw->DACreg[POS1064_XCURADDH] = 0; DAC1064_global_init(PMINFO2); return 0;}static int DAC1064_init_2(WPMINFO struct my_timming* m) { struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); DBG(__FUNCTION__) if (ACCESS_FBINFO(fbcon).var.bits_per_pixel > 16) { /* 256 entries */ int i; for (i = 0; i < 256; i++) { hw->DACpal[i * 3 + 0] = i; hw->DACpal[i * 3 + 1] = i; hw->DACpal[i * 3 + 2] = i; } } else if (ACCESS_FBINFO(fbcon).var.bits_per_pixel > 8) { if (ACCESS_FBINFO(fbcon).var.green.length == 5) { /* 0..31, 128..159 */ int i; for (i = 0; i < 32; i++) { /* with p15 == 0 */ hw->DACpal[i * 3 + 0] = i << 3; hw->DACpal[i * 3 + 1] = i << 3; hw->DACpal[i * 3 + 2] = i << 3; /* with p15 == 1 */ hw->DACpal[(i + 128) * 3 + 0] = i << 3; hw->DACpal[(i + 128) * 3 + 1] = i << 3; hw->DACpal[(i + 128) * 3 + 2] = i << 3; } } else { int i; for (i = 0; i < 64; i++) { /* 0..63 */ hw->DACpal[i * 3 + 0] = i << 3; hw->DACpal[i * 3 + 1] = i << 2; hw->DACpal[i * 3 + 2] = i << 3; } } } else { memset(hw->DACpal, 0, 768); } return 0;}static void DAC1064_restore_1(WPMINFO2) { struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); CRITFLAGS DBG(__FUNCTION__) CRITBEGIN if ((inDAC1064(PMINFO DAC1064_XSYSPLLM) != hw->DACclk[3]) || (inDAC1064(PMINFO DAC1064_XSYSPLLN) != hw->DACclk[4]) || (inDAC1064(PMINFO DAC1064_XSYSPLLP) != hw->DACclk[5])) { outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3]); outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4]); outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5]); } { unsigned int i; for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) { if ((i != POS1064_XPIXCLKCTRL) && (i != POS1064_XMISCCTRL)) outDAC1064(PMINFO MGA1064_DAC_regs[i], hw->DACreg[i]); } } DAC1064_global_restore(PMINFO2); CRITEND};static void DAC1064_restore_2(WPMINFO2) {#ifdef DEBUG unsigned int i;#endif DBG(__FUNCTION__)#ifdef DEBUG dprintk(KERN_DEBUG "DAC1064regs "); for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) { dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], ACCESS_FBINFO(hw).DACreg[i]); if ((i & 0x7) == 0x7) dprintk("\n" KERN_DEBUG "continuing... "); } dprintk("\n" KERN_DEBUG "DAC1064clk "); for (i = 0; i < 6; i++) dprintk("C%02X=%02X ", i, ACCESS_FBINFO(hw).DACclk[i]); dprintk("\n");#endif}static int m1064_compute(void* out, struct my_timming* m) {#define minfo ((struct matrox_fb_info*)out) { int i; int tmout; CRITFLAGS DAC1064_setpclk(PMINFO m->pixclock); CRITBEGIN for (i = 0; i < 3; i++) outDAC1064(PMINFO M1064_XPIXPLLCM + i, ACCESS_FBINFO(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 struct matrox_altout m1064 = { .name = "Primary output", .compute = m1064_compute,};#ifdef CONFIG_FB_MATROX_Gstatic int g450_compute(void* out, struct my_timming* m) {#define minfo ((struct matrox_fb_info*)out) if (m->mnp < 0) { m->mnp = matroxfb_g450_setclk(PMINFO m->pixclock, (m->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL); if (m->mnp >= 0) { m->pixclock = g450_mnp2f(PMINFO m->mnp); } }#undef minfo return 0;}static struct matrox_altout g450out = { .name = "Primary output", .compute = g450_compute,};#endif#endif /* NEED_DAC1064 */#ifdef CONFIG_FB_MATROX_MYSTIQUEstatic int MGA1064_init(WPMINFO struct my_timming* m) { struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); DBG(__FUNCTION__) if (DAC1064_init_1(PMINFO m)) return 1; if (matroxfb_vgaHWinit(PMINFO m)) 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 m)) return 1; return 0;}#endif#ifdef CONFIG_FB_MATROX_Gstatic int MGAG100_init(WPMINFO struct my_timming* m) { struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); DBG(__FUNCTION__) if (DAC1064_init_1(PMINFO m)) return 1; hw->MXoptionReg &= ~0x2000; if (matroxfb_vgaHWinit(PMINFO m)) 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 m)) return 1; return 0;}#endif /* G */#ifdef CONFIG_FB_MATROX_MYSTIQUEstatic void MGA1064_ramdac_init(WPMINFO2) { DBG(__FUNCTION__) /* 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 DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PLL, 133333);}#endif#ifdef CONFIG_FB_MATROX_G/* 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(__FUNCTION__) 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(__FUNCTION__) 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(WPMINFO2) { static const int vxres_mystique[] = { 512, 640, 768, 800, 832, 960, 1024, 1152, 1280, 1600, 1664, 1920, 2048, 0}; struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); DBG(__FUNCTION__) /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */ ACCESS_FBINFO(capable.text) = 1; ACCESS_FBINFO(capable.vxres) = vxres_mystique; ACCESS_FBINFO(outputs[0]).output = &m1064; ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src; ACCESS_FBINFO(outputs[0]).data = MINFO; ACCESS_FBINFO(outputs[0]).mode = MATROXFB_OUTPUT_MODE_MONITOR; 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(WPMINFO2) { DBG(__FUNCTION__); MGA1064_ramdac_init(PMINFO2);}#endif#ifdef CONFIG_FB_MATROX_Gstatic void g450_mclk_init(WPMINFO2) { /* switch all clocks to PCI source */ pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg | 4); pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION3_REG, ACCESS_FBINFO(values).reg.opt3 & ~0x00300C03); pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg); if (((ACCESS_FBINFO(values).reg.opt3 & 0x000003) == 0x000003) || ((ACCESS_FBINFO(values).reg.opt3 & 0x000C00) == 0x000C00) || ((ACCESS_FBINFO(values).reg.opt3 & 0x300000) == 0x300000)) { matroxfb_g450_setclk(PMINFO ACCESS_FBINFO(values.pll.video), M_VIDEO_PLL); } else { unsigned long flags; unsigned int pwr; matroxfb_DAC_lock_irqsave(flags); pwr = inDAC1064(PMINFO M1064_XPWRCTRL) & ~0x02; outDAC1064(PMINFO M1064_XPWRCTRL, pwr); matroxfb_DAC_unlock_irqrestore(flags); } matroxfb_g450_setclk(PMINFO ACCESS_FBINFO(values.pll.system), M_SYSTEM_PLL); /* switch clocks to their real PLL source(s) */ pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg | 4); pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION3_REG, ACCESS_FBINFO(values).reg.opt3); pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);}static void g450_memory_init(WPMINFO2) { /* disable memory refresh */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -