Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *
0004  * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450.
0005  *
0006  * (c) 1998-2002 Petr Vandrovec <vandrove@vc.cvut.cz>
0007  *
0008  * Portions Copyright (c) 2001 Matrox Graphics Inc.
0009  *
0010  * Version: 1.65 2002/08/14
0011  *
0012  * See matroxfb_base.c for contributors.
0013  *
0014  */
0015 
0016 
0017 #include "matroxfb_DAC1064.h"
0018 #include "matroxfb_misc.h"
0019 #include "matroxfb_accel.h"
0020 #include "g450_pll.h"
0021 #include <linux/matroxfb.h>
0022 
0023 #ifdef NEED_DAC1064
0024 #define outDAC1064 matroxfb_DAC_out
0025 #define inDAC1064 matroxfb_DAC_in
0026 
0027 #define DAC1064_OPT_SCLK_PCI    0x00
0028 #define DAC1064_OPT_SCLK_PLL    0x01
0029 #define DAC1064_OPT_SCLK_EXT    0x02
0030 #define DAC1064_OPT_SCLK_MASK   0x03
0031 #define DAC1064_OPT_GDIV1   0x04    /* maybe it is GDIV2 on G100 ?! */
0032 #define DAC1064_OPT_GDIV3   0x00
0033 #define DAC1064_OPT_MDIV1   0x08
0034 #define DAC1064_OPT_MDIV2   0x00
0035 #define DAC1064_OPT_RESERVED    0x10
0036 
0037 static void DAC1064_calcclock(const struct matrox_fb_info *minfo,
0038                   unsigned int freq, unsigned int fmax,
0039                   unsigned int *in, unsigned int *feed,
0040                   unsigned int *post)
0041 {
0042     unsigned int fvco;
0043     unsigned int p;
0044 
0045     DBG(__func__)
0046     
0047     /* only for devices older than G450 */
0048 
0049     fvco = PLL_calcclock(minfo, freq, fmax, in, feed, &p);
0050     
0051     p = (1 << p) - 1;
0052     if (fvco <= 100000)
0053         ;
0054     else if (fvco <= 140000)
0055         p |= 0x08;
0056     else if (fvco <= 180000)
0057         p |= 0x10;
0058     else
0059         p |= 0x18;
0060     *post = p;
0061 }
0062 
0063 /* they must be in POS order */
0064 static const unsigned char MGA1064_DAC_regs[] = {
0065         M1064_XCURADDL, M1064_XCURADDH, M1064_XCURCTRL,
0066         M1064_XCURCOL0RED, M1064_XCURCOL0GREEN, M1064_XCURCOL0BLUE,
0067         M1064_XCURCOL1RED, M1064_XCURCOL1GREEN, M1064_XCURCOL1BLUE,
0068         M1064_XCURCOL2RED, M1064_XCURCOL2GREEN, M1064_XCURCOL2BLUE,
0069         DAC1064_XVREFCTRL, M1064_XMULCTRL, M1064_XPIXCLKCTRL, M1064_XGENCTRL,
0070         M1064_XMISCCTRL,
0071         M1064_XGENIOCTRL, M1064_XGENIODATA, M1064_XZOOMCTRL, M1064_XSENSETEST,
0072         M1064_XCRCBITSEL,
0073         M1064_XCOLKEYMASKL, M1064_XCOLKEYMASKH, M1064_XCOLKEYL, M1064_XCOLKEYH };
0074 
0075 static const unsigned char MGA1064_DAC[] = {
0076         0x00, 0x00, M1064_XCURCTRL_DIS,
0077         0x00, 0x00, 0x00,   /* black */
0078         0xFF, 0xFF, 0xFF,   /* white */
0079         0xFF, 0x00, 0x00,   /* red */
0080         0x00, 0,
0081         M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL,
0082         M1064_XGENCTRL_VS_0 | M1064_XGENCTRL_ALPHA_DIS | M1064_XGENCTRL_BLACK_0IRE | M1064_XGENCTRL_NO_SYNC_ON_GREEN,
0083         M1064_XMISCCTRL_DAC_8BIT,
0084         0x00, 0x00, M1064_XZOOMCTRL_1, M1064_XSENSETEST_BCOMP | M1064_XSENSETEST_GCOMP | M1064_XSENSETEST_RCOMP | M1064_XSENSETEST_PDOWN,
0085         0x00,
0086         0x00, 0x00, 0xFF, 0xFF};
0087 
0088 static void DAC1064_setpclk(struct matrox_fb_info *minfo, unsigned long fout)
0089 {
0090     unsigned int m, n, p;
0091 
0092     DBG(__func__)
0093 
0094     DAC1064_calcclock(minfo, fout, minfo->max_pixel_clock, &m, &n, &p);
0095     minfo->hw.DACclk[0] = m;
0096     minfo->hw.DACclk[1] = n;
0097     minfo->hw.DACclk[2] = p;
0098 }
0099 
0100 static void DAC1064_setmclk(struct matrox_fb_info *minfo, int oscinfo,
0101                 unsigned long fmem)
0102 {
0103     u_int32_t mx;
0104     struct matrox_hw_state *hw = &minfo->hw;
0105 
0106     DBG(__func__)
0107 
0108     if (minfo->devflags.noinit) {
0109         /* read MCLK and give up... */
0110         hw->DACclk[3] = inDAC1064(minfo, DAC1064_XSYSPLLM);
0111         hw->DACclk[4] = inDAC1064(minfo, DAC1064_XSYSPLLN);
0112         hw->DACclk[5] = inDAC1064(minfo, DAC1064_XSYSPLLP);
0113         return;
0114     }
0115     mx = hw->MXoptionReg | 0x00000004;
0116     pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mx);
0117     mx &= ~0x000000BB;
0118     if (oscinfo & DAC1064_OPT_GDIV1)
0119         mx |= 0x00000008;
0120     if (oscinfo & DAC1064_OPT_MDIV1)
0121         mx |= 0x00000010;
0122     if (oscinfo & DAC1064_OPT_RESERVED)
0123         mx |= 0x00000080;
0124     if ((oscinfo & DAC1064_OPT_SCLK_MASK) == DAC1064_OPT_SCLK_PLL) {
0125         /* select PCI clock until we have setup oscilator... */
0126         int clk;
0127         unsigned int m, n, p;
0128 
0129         /* powerup system PLL, select PCI clock */
0130         mx |= 0x00000020;
0131         pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mx);
0132         mx &= ~0x00000004;
0133         pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mx);
0134 
0135         /* !!! you must not access device if MCLK is not running !!!
0136            Doing so cause immediate PCI lockup :-( Maybe they should
0137            generate ABORT or I/O (parity...) error and Linux should
0138            recover from this... (kill driver/process). But world is not
0139            perfect... */
0140         /* (bit 2 of PCI_OPTION_REG must be 0... and bits 0,1 must not
0141            select PLL... because of PLL can be stopped at this time) */
0142         DAC1064_calcclock(minfo, fmem, minfo->max_pixel_clock, &m, &n, &p);
0143         outDAC1064(minfo, DAC1064_XSYSPLLM, hw->DACclk[3] = m);
0144         outDAC1064(minfo, DAC1064_XSYSPLLN, hw->DACclk[4] = n);
0145         outDAC1064(minfo, DAC1064_XSYSPLLP, hw->DACclk[5] = p);
0146         for (clk = 65536; clk; --clk) {
0147             if (inDAC1064(minfo, DAC1064_XSYSPLLSTAT) & 0x40)
0148                 break;
0149         }
0150         if (!clk)
0151             printk(KERN_ERR "matroxfb: aiee, SYSPLL not locked\n");
0152         /* select PLL */
0153         mx |= 0x00000005;
0154     } else {
0155         /* select specified system clock source */
0156         mx |= oscinfo & DAC1064_OPT_SCLK_MASK;
0157     }
0158     pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mx);
0159     mx &= ~0x00000004;
0160     pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mx);
0161     hw->MXoptionReg = mx;
0162 }
0163 
0164 #ifdef CONFIG_FB_MATROX_G
0165 static void g450_set_plls(struct matrox_fb_info *minfo)
0166 {
0167     u_int32_t c2_ctl;
0168     unsigned int pxc;
0169     struct matrox_hw_state *hw = &minfo->hw;
0170     int pixelmnp;
0171     int videomnp;
0172     
0173     c2_ctl = hw->crtc2.ctl & ~0x4007;   /* Clear PLL + enable for CRTC2 */
0174     c2_ctl |= 0x0001;           /* Enable CRTC2 */
0175     hw->DACreg[POS1064_XPWRCTRL] &= ~0x02;  /* Stop VIDEO PLL */
0176     pixelmnp = minfo->crtc1.mnp;
0177     videomnp = minfo->crtc2.mnp;
0178     if (videomnp < 0) {
0179         c2_ctl &= ~0x0001;          /* Disable CRTC2 */
0180         hw->DACreg[POS1064_XPWRCTRL] &= ~0x10;  /* Powerdown CRTC2 */
0181     } else if (minfo->crtc2.pixclock == minfo->features.pll.ref_freq) {
0182         c2_ctl |=  0x4002;  /* Use reference directly */
0183     } else if (videomnp == pixelmnp) {
0184         c2_ctl |=  0x0004;  /* Use pixel PLL */
0185     } else {
0186         if (0 == ((videomnp ^ pixelmnp) & 0xFFFFFF00)) {
0187             /* PIXEL and VIDEO PLL must not use same frequency. We modify N
0188                of PIXEL PLL in such case because of VIDEO PLL may be source
0189                of TVO clocks, and chroma subcarrier is derived from its
0190                pixel clocks */
0191             pixelmnp += 0x000100;
0192         }
0193         c2_ctl |=  0x0006;  /* Use video PLL */
0194         hw->DACreg[POS1064_XPWRCTRL] |= 0x02;
0195         
0196         outDAC1064(minfo, M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]);
0197         matroxfb_g450_setpll_cond(minfo, videomnp, M_VIDEO_PLL);
0198     }
0199 
0200     hw->DACreg[POS1064_XPIXCLKCTRL] &= ~M1064_XPIXCLKCTRL_PLL_UP;
0201     if (pixelmnp >= 0) {
0202         hw->DACreg[POS1064_XPIXCLKCTRL] |= M1064_XPIXCLKCTRL_PLL_UP;
0203         
0204         outDAC1064(minfo, M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]);
0205         matroxfb_g450_setpll_cond(minfo, pixelmnp, M_PIXEL_PLL_C);
0206     }
0207     if (c2_ctl != hw->crtc2.ctl) {
0208         hw->crtc2.ctl = c2_ctl;
0209         mga_outl(0x3C10, c2_ctl);
0210     }
0211 
0212     pxc = minfo->crtc1.pixclock;
0213     if (pxc == 0 || minfo->outputs[2].src == MATROXFB_SRC_CRTC2) {
0214         pxc = minfo->crtc2.pixclock;
0215     }
0216     if (minfo->chip == MGA_G550) {
0217         if (pxc < 45000) {
0218             hw->DACreg[POS1064_XPANMODE] = 0x00;    /* 0-50 */
0219         } else if (pxc < 55000) {
0220             hw->DACreg[POS1064_XPANMODE] = 0x08;    /* 34-62 */
0221         } else if (pxc < 70000) {
0222             hw->DACreg[POS1064_XPANMODE] = 0x10;    /* 42-78 */
0223         } else if (pxc < 85000) {
0224             hw->DACreg[POS1064_XPANMODE] = 0x18;    /* 62-92 */
0225         } else if (pxc < 100000) {
0226             hw->DACreg[POS1064_XPANMODE] = 0x20;    /* 74-108 */
0227         } else if (pxc < 115000) {
0228             hw->DACreg[POS1064_XPANMODE] = 0x28;    /* 94-122 */
0229         } else if (pxc < 125000) {
0230             hw->DACreg[POS1064_XPANMODE] = 0x30;    /* 108-132 */
0231         } else {
0232             hw->DACreg[POS1064_XPANMODE] = 0x38;    /* 120-168 */
0233         }
0234     } else {
0235         /* G450 */
0236         if (pxc < 45000) {
0237             hw->DACreg[POS1064_XPANMODE] = 0x00;    /* 0-54 */
0238         } else if (pxc < 65000) {
0239             hw->DACreg[POS1064_XPANMODE] = 0x08;    /* 38-70 */
0240         } else if (pxc < 85000) {
0241             hw->DACreg[POS1064_XPANMODE] = 0x10;    /* 56-96 */
0242         } else if (pxc < 105000) {
0243             hw->DACreg[POS1064_XPANMODE] = 0x18;    /* 80-114 */
0244         } else if (pxc < 135000) {
0245             hw->DACreg[POS1064_XPANMODE] = 0x20;    /* 102-144 */
0246         } else if (pxc < 160000) {
0247             hw->DACreg[POS1064_XPANMODE] = 0x28;    /* 132-166 */
0248         } else if (pxc < 175000) {
0249             hw->DACreg[POS1064_XPANMODE] = 0x30;    /* 154-182 */
0250         } else {
0251             hw->DACreg[POS1064_XPANMODE] = 0x38;    /* 170-204 */
0252         }
0253     }
0254 }
0255 #endif
0256 
0257 void DAC1064_global_init(struct matrox_fb_info *minfo)
0258 {
0259     struct matrox_hw_state *hw = &minfo->hw;
0260 
0261     hw->DACreg[POS1064_XMISCCTRL] &= M1064_XMISCCTRL_DAC_WIDTHMASK;
0262     hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_LUT_EN;
0263     hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL;
0264 #ifdef CONFIG_FB_MATROX_G
0265     if (minfo->devflags.g450dac) {
0266         hw->DACreg[POS1064_XPWRCTRL] = 0x1F;    /* powerup everything */
0267         hw->DACreg[POS1064_XOUTPUTCONN] = 0x00; /* disable outputs */
0268         hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN;
0269         switch (minfo->outputs[0].src) {
0270             case MATROXFB_SRC_CRTC1:
0271             case MATROXFB_SRC_CRTC2:
0272                 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x01;    /* enable output; CRTC1/2 selection is in CRTC2 ctl */
0273                 break;
0274             case MATROXFB_SRC_NONE:
0275                 hw->DACreg[POS1064_XMISCCTRL] &= ~M1064_XMISCCTRL_DAC_EN;
0276                 break;
0277         }
0278         switch (minfo->outputs[1].src) {
0279             case MATROXFB_SRC_CRTC1:
0280                 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x04;
0281                 break;
0282             case MATROXFB_SRC_CRTC2:
0283                 if (minfo->outputs[1].mode == MATROXFB_OUTPUT_MODE_MONITOR) {
0284                     hw->DACreg[POS1064_XOUTPUTCONN] |= 0x08;
0285                 } else {
0286                     hw->DACreg[POS1064_XOUTPUTCONN] |= 0x0C;
0287                 }
0288                 break;
0289             case MATROXFB_SRC_NONE:
0290                 hw->DACreg[POS1064_XPWRCTRL] &= ~0x01;      /* Poweroff DAC2 */
0291                 break;
0292         }
0293         switch (minfo->outputs[2].src) {
0294             case MATROXFB_SRC_CRTC1:
0295                 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x20;
0296                 break;
0297             case MATROXFB_SRC_CRTC2:
0298                 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x40;
0299                 break;
0300             case MATROXFB_SRC_NONE:
0301 #if 0
0302                 /* HELP! If we boot without DFP connected to DVI, we can
0303                    poweroff TMDS. But if we boot with DFP connected,
0304                    TMDS generated clocks are used instead of ALL pixclocks
0305                    available... If someone knows which register
0306                    handles it, please reveal this secret to me... */            
0307                 hw->DACreg[POS1064_XPWRCTRL] &= ~0x04;      /* Poweroff TMDS */
0308 #endif              
0309                 break;
0310         }
0311         /* Now set timming related variables... */
0312         g450_set_plls(minfo);
0313     } else
0314 #endif
0315     {
0316         if (minfo->outputs[1].src == MATROXFB_SRC_CRTC1) {
0317             hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_EXT;
0318             hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_MAFC12;
0319         } else if (minfo->outputs[1].src == MATROXFB_SRC_CRTC2) {
0320             hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_C2_MAFC12;
0321         } else if (minfo->outputs[2].src == MATROXFB_SRC_CRTC1)
0322             hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_PANELLINK | G400_XMISCCTRL_VDO_MAFC12;
0323         else
0324             hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_DIS;
0325 
0326         if (minfo->outputs[0].src != MATROXFB_SRC_NONE)
0327             hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN;
0328     }
0329 }
0330 
0331 void DAC1064_global_restore(struct matrox_fb_info *minfo)
0332 {
0333     struct matrox_hw_state *hw = &minfo->hw;
0334 
0335     outDAC1064(minfo, M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]);
0336     outDAC1064(minfo, M1064_XMISCCTRL, hw->DACreg[POS1064_XMISCCTRL]);
0337     if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG400) {
0338         outDAC1064(minfo, 0x20, 0x04);
0339         outDAC1064(minfo, 0x1F, minfo->devflags.dfp_type);
0340         if (minfo->devflags.g450dac) {
0341             outDAC1064(minfo, M1064_XSYNCCTRL, 0xCC);
0342             outDAC1064(minfo, M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]);
0343             outDAC1064(minfo, M1064_XPANMODE, hw->DACreg[POS1064_XPANMODE]);
0344             outDAC1064(minfo, M1064_XOUTPUTCONN, hw->DACreg[POS1064_XOUTPUTCONN]);
0345         }
0346     }
0347 }
0348 
0349 static int DAC1064_init_1(struct matrox_fb_info *minfo, struct my_timming *m)
0350 {
0351     struct matrox_hw_state *hw = &minfo->hw;
0352 
0353     DBG(__func__)
0354 
0355     memcpy(hw->DACreg, MGA1064_DAC, sizeof(MGA1064_DAC_regs));
0356     switch (minfo->fbcon.var.bits_per_pixel) {
0357         /* case 4: not supported by MGA1064 DAC */
0358         case 8:
0359             hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_8BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
0360             break;
0361         case 16:
0362             if (minfo->fbcon.var.green.length == 5)
0363                 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_15BPP_1BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
0364             else
0365                 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_16BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
0366             break;
0367         case 24:
0368             hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_24BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
0369             break;
0370         case 32:
0371             hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_32BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
0372             break;
0373         default:
0374             return 1;   /* unsupported depth */
0375     }
0376     hw->DACreg[POS1064_XVREFCTRL] = minfo->features.DAC1064.xvrefctrl;
0377     hw->DACreg[POS1064_XGENCTRL] &= ~M1064_XGENCTRL_SYNC_ON_GREEN_MASK;
0378     hw->DACreg[POS1064_XGENCTRL] |= (m->sync & FB_SYNC_ON_GREEN)?M1064_XGENCTRL_SYNC_ON_GREEN:M1064_XGENCTRL_NO_SYNC_ON_GREEN;
0379     hw->DACreg[POS1064_XCURADDL] = 0;
0380     hw->DACreg[POS1064_XCURADDH] = 0;
0381 
0382     DAC1064_global_init(minfo);
0383     return 0;
0384 }
0385 
0386 static int DAC1064_init_2(struct matrox_fb_info *minfo, struct my_timming *m)
0387 {
0388     struct matrox_hw_state *hw = &minfo->hw;
0389 
0390     DBG(__func__)
0391 
0392     if (minfo->fbcon.var.bits_per_pixel > 16) { /* 256 entries */
0393         int i;
0394 
0395         for (i = 0; i < 256; i++) {
0396             hw->DACpal[i * 3 + 0] = i;
0397             hw->DACpal[i * 3 + 1] = i;
0398             hw->DACpal[i * 3 + 2] = i;
0399         }
0400     } else if (minfo->fbcon.var.bits_per_pixel > 8) {
0401         if (minfo->fbcon.var.green.length == 5) {   /* 0..31, 128..159 */
0402             int i;
0403 
0404             for (i = 0; i < 32; i++) {
0405                 /* with p15 == 0 */
0406                 hw->DACpal[i * 3 + 0] = i << 3;
0407                 hw->DACpal[i * 3 + 1] = i << 3;
0408                 hw->DACpal[i * 3 + 2] = i << 3;
0409                 /* with p15 == 1 */
0410                 hw->DACpal[(i + 128) * 3 + 0] = i << 3;
0411                 hw->DACpal[(i + 128) * 3 + 1] = i << 3;
0412                 hw->DACpal[(i + 128) * 3 + 2] = i << 3;
0413             }
0414         } else {
0415             int i;
0416 
0417             for (i = 0; i < 64; i++) {      /* 0..63 */
0418                 hw->DACpal[i * 3 + 0] = i << 3;
0419                 hw->DACpal[i * 3 + 1] = i << 2;
0420                 hw->DACpal[i * 3 + 2] = i << 3;
0421             }
0422         }
0423     } else {
0424         memset(hw->DACpal, 0, 768);
0425     }
0426     return 0;
0427 }
0428 
0429 static void DAC1064_restore_1(struct matrox_fb_info *minfo)
0430 {
0431     struct matrox_hw_state *hw = &minfo->hw;
0432 
0433     CRITFLAGS
0434 
0435     DBG(__func__)
0436 
0437     CRITBEGIN
0438 
0439     if ((inDAC1064(minfo, DAC1064_XSYSPLLM) != hw->DACclk[3]) ||
0440         (inDAC1064(minfo, DAC1064_XSYSPLLN) != hw->DACclk[4]) ||
0441         (inDAC1064(minfo, DAC1064_XSYSPLLP) != hw->DACclk[5])) {
0442         outDAC1064(minfo, DAC1064_XSYSPLLM, hw->DACclk[3]);
0443         outDAC1064(minfo, DAC1064_XSYSPLLN, hw->DACclk[4]);
0444         outDAC1064(minfo, DAC1064_XSYSPLLP, hw->DACclk[5]);
0445     }
0446     {
0447         unsigned int i;
0448 
0449         for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
0450             if ((i != POS1064_XPIXCLKCTRL) && (i != POS1064_XMISCCTRL))
0451                 outDAC1064(minfo, MGA1064_DAC_regs[i], hw->DACreg[i]);
0452         }
0453     }
0454 
0455     DAC1064_global_restore(minfo);
0456 
0457     CRITEND
0458 };
0459 
0460 static void DAC1064_restore_2(struct matrox_fb_info *minfo)
0461 {
0462 #ifdef DEBUG
0463     unsigned int i;
0464 #endif
0465 
0466     DBG(__func__)
0467 
0468 #ifdef DEBUG
0469     dprintk(KERN_DEBUG "DAC1064regs ");
0470     for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
0471         dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], minfo->hw.DACreg[i]);
0472         if ((i & 0x7) == 0x7) dprintk(KERN_DEBUG "continuing... ");
0473     }
0474     dprintk(KERN_DEBUG "DAC1064clk ");
0475     for (i = 0; i < 6; i++)
0476         dprintk("C%02X=%02X ", i, minfo->hw.DACclk[i]);
0477     dprintk("\n");
0478 #endif
0479 }
0480 
0481 static int m1064_compute(void* out, struct my_timming* m) {
0482 #define minfo ((struct matrox_fb_info*)out)
0483     {
0484         int i;
0485         int tmout;
0486         CRITFLAGS
0487 
0488         DAC1064_setpclk(minfo, m->pixclock);
0489 
0490         CRITBEGIN
0491 
0492         for (i = 0; i < 3; i++)
0493             outDAC1064(minfo, M1064_XPIXPLLCM + i, minfo->hw.DACclk[i]);
0494         for (tmout = 500000; tmout; tmout--) {
0495             if (inDAC1064(minfo, M1064_XPIXPLLSTAT) & 0x40)
0496                 break;
0497             udelay(10);
0498         }
0499 
0500         CRITEND
0501 
0502         if (!tmout)
0503             printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
0504     }
0505 #undef minfo
0506     return 0;
0507 }
0508 
0509 static struct matrox_altout m1064 = {
0510     .name    = "Primary output",
0511     .compute = m1064_compute,
0512 };
0513 
0514 #ifdef CONFIG_FB_MATROX_G
0515 static int g450_compute(void* out, struct my_timming* m) {
0516 #define minfo ((struct matrox_fb_info*)out)
0517     if (m->mnp < 0) {
0518         m->mnp = matroxfb_g450_setclk(minfo, m->pixclock, (m->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL);
0519         if (m->mnp >= 0) {
0520             m->pixclock = g450_mnp2f(minfo, m->mnp);
0521         }
0522     }
0523 #undef minfo
0524     return 0;
0525 }
0526 
0527 static struct matrox_altout g450out = {
0528     .name    = "Primary output",
0529     .compute = g450_compute,
0530 };
0531 #endif
0532 
0533 #endif /* NEED_DAC1064 */
0534 
0535 #ifdef CONFIG_FB_MATROX_MYSTIQUE
0536 static int MGA1064_init(struct matrox_fb_info *minfo, struct my_timming *m)
0537 {
0538     struct matrox_hw_state *hw = &minfo->hw;
0539 
0540     DBG(__func__)
0541 
0542     if (DAC1064_init_1(minfo, m)) return 1;
0543     if (matroxfb_vgaHWinit(minfo, m)) return 1;
0544 
0545     hw->MiscOutReg = 0xCB;
0546     if (m->sync & FB_SYNC_HOR_HIGH_ACT)
0547         hw->MiscOutReg &= ~0x40;
0548     if (m->sync & FB_SYNC_VERT_HIGH_ACT)
0549         hw->MiscOutReg &= ~0x80;
0550     if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */
0551         hw->CRTCEXT[3] |= 0x40;
0552 
0553     if (DAC1064_init_2(minfo, m)) return 1;
0554     return 0;
0555 }
0556 #endif
0557 
0558 #ifdef CONFIG_FB_MATROX_G
0559 static int MGAG100_init(struct matrox_fb_info *minfo, struct my_timming *m)
0560 {
0561     struct matrox_hw_state *hw = &minfo->hw;
0562 
0563     DBG(__func__)
0564 
0565     if (DAC1064_init_1(minfo, m)) return 1;
0566     hw->MXoptionReg &= ~0x2000;
0567     if (matroxfb_vgaHWinit(minfo, m)) return 1;
0568 
0569     hw->MiscOutReg = 0xEF;
0570     if (m->sync & FB_SYNC_HOR_HIGH_ACT)
0571         hw->MiscOutReg &= ~0x40;
0572     if (m->sync & FB_SYNC_VERT_HIGH_ACT)
0573         hw->MiscOutReg &= ~0x80;
0574     if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */
0575         hw->CRTCEXT[3] |= 0x40;
0576 
0577     if (DAC1064_init_2(minfo, m)) return 1;
0578     return 0;
0579 }
0580 #endif  /* G */
0581 
0582 #ifdef CONFIG_FB_MATROX_MYSTIQUE
0583 static void MGA1064_ramdac_init(struct matrox_fb_info *minfo)
0584 {
0585 
0586     DBG(__func__)
0587 
0588     /* minfo->features.DAC1064.vco_freq_min = 120000; */
0589     minfo->features.pll.vco_freq_min = 62000;
0590     minfo->features.pll.ref_freq     = 14318;
0591     minfo->features.pll.feed_div_min = 100;
0592     minfo->features.pll.feed_div_max = 127;
0593     minfo->features.pll.in_div_min   = 1;
0594     minfo->features.pll.in_div_max   = 31;
0595     minfo->features.pll.post_shift_max = 3;
0596     minfo->features.DAC1064.xvrefctrl = DAC1064_XVREFCTRL_EXTERNAL;
0597     /* maybe cmdline MCLK= ?, doc says gclk=44MHz, mclk=66MHz... it was 55/83 with old values */
0598     DAC1064_setmclk(minfo, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PLL, 133333);
0599 }
0600 #endif
0601 
0602 #ifdef CONFIG_FB_MATROX_G
0603 /* BIOS environ */
0604 static int x7AF4 = 0x10;    /* flags, maybe 0x10 = SDRAM, 0x00 = SGRAM??? */
0605                 /* G100 wants 0x10, G200 SGRAM does not care... */
0606 #if 0
0607 static int def50 = 0;   /* reg50, & 0x0F, & 0x3000 (only 0x0000, 0x1000, 0x2000 (0x3000 disallowed and treated as 0) */
0608 #endif
0609 
0610 static void MGAG100_progPixClock(const struct matrox_fb_info *minfo, int flags,
0611                  int m, int n, int p)
0612 {
0613     int reg;
0614     int selClk;
0615     int clk;
0616 
0617     DBG(__func__)
0618 
0619     outDAC1064(minfo, M1064_XPIXCLKCTRL, inDAC1064(minfo, M1064_XPIXCLKCTRL) | M1064_XPIXCLKCTRL_DIS |
0620            M1064_XPIXCLKCTRL_PLL_UP);
0621     switch (flags & 3) {
0622         case 0:     reg = M1064_XPIXPLLAM; break;
0623         case 1:     reg = M1064_XPIXPLLBM; break;
0624         default:    reg = M1064_XPIXPLLCM; break;
0625     }
0626     outDAC1064(minfo, reg++, m);
0627     outDAC1064(minfo, reg++, n);
0628     outDAC1064(minfo, reg, p);
0629     selClk = mga_inb(M_MISC_REG_READ) & ~0xC;
0630     /* there should be flags & 0x03 & case 0/1/else */
0631     /* and we should first select source and after that we should wait for PLL */
0632     /* and we are waiting for PLL with oscilator disabled... Is it right? */
0633     switch (flags & 0x03) {
0634         case 0x00:  break;
0635         case 0x01:  selClk |= 4; break;
0636         default:    selClk |= 0x0C; break;
0637     }
0638     mga_outb(M_MISC_REG, selClk);
0639     for (clk = 500000; clk; clk--) {
0640         if (inDAC1064(minfo, M1064_XPIXPLLSTAT) & 0x40)
0641             break;
0642         udelay(10);
0643     }
0644     if (!clk)
0645         printk(KERN_ERR "matroxfb: Pixel PLL%c not locked after usual time\n", (reg-M1064_XPIXPLLAM-2)/4 + 'A');
0646     selClk = inDAC1064(minfo, M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_SRC_MASK;
0647     switch (flags & 0x0C) {
0648         case 0x00:  selClk |= M1064_XPIXCLKCTRL_SRC_PCI; break;
0649         case 0x04:  selClk |= M1064_XPIXCLKCTRL_SRC_PLL; break;
0650         default:    selClk |= M1064_XPIXCLKCTRL_SRC_EXT; break;
0651     }
0652     outDAC1064(minfo, M1064_XPIXCLKCTRL, selClk);
0653     outDAC1064(minfo, M1064_XPIXCLKCTRL, inDAC1064(minfo, M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_DIS);
0654 }
0655 
0656 static void MGAG100_setPixClock(const struct matrox_fb_info *minfo, int flags,
0657                 int freq)
0658 {
0659     unsigned int m, n, p;
0660 
0661     DBG(__func__)
0662 
0663     DAC1064_calcclock(minfo, freq, minfo->max_pixel_clock, &m, &n, &p);
0664     MGAG100_progPixClock(minfo, flags, m, n, p);
0665 }
0666 #endif
0667 
0668 #ifdef CONFIG_FB_MATROX_MYSTIQUE
0669 static int MGA1064_preinit(struct matrox_fb_info *minfo)
0670 {
0671     static const int vxres_mystique[] = { 512,        640, 768,  800,  832,  960,
0672                          1024, 1152, 1280,      1600, 1664, 1920,
0673                          2048,    0};
0674     struct matrox_hw_state *hw = &minfo->hw;
0675 
0676     DBG(__func__)
0677 
0678     /* minfo->capable.cfb4 = 0; ... preinitialized by 0 */
0679     minfo->capable.text = 1;
0680     minfo->capable.vxres = vxres_mystique;
0681 
0682     minfo->outputs[0].output = &m1064;
0683     minfo->outputs[0].src = minfo->outputs[0].default_src;
0684     minfo->outputs[0].data = minfo;
0685     minfo->outputs[0].mode = MATROXFB_OUTPUT_MODE_MONITOR;
0686 
0687     if (minfo->devflags.noinit)
0688         return 0;   /* do not modify settings */
0689     hw->MXoptionReg &= 0xC0000100;
0690     hw->MXoptionReg |= 0x00094E20;
0691     if (minfo->devflags.novga)
0692         hw->MXoptionReg &= ~0x00000100;
0693     if (minfo->devflags.nobios)
0694         hw->MXoptionReg &= ~0x40000000;
0695     if (minfo->devflags.nopciretry)
0696         hw->MXoptionReg |=  0x20000000;
0697     pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
0698     mga_setr(M_SEQ_INDEX, 0x01, 0x20);
0699     mga_outl(M_CTLWTST, 0x00000000);
0700     udelay(200);
0701     mga_outl(M_MACCESS, 0x00008000);
0702     udelay(100);
0703     mga_outl(M_MACCESS, 0x0000C000);
0704     return 0;
0705 }
0706 
0707 static void MGA1064_reset(struct matrox_fb_info *minfo)
0708 {
0709 
0710     DBG(__func__);
0711 
0712     MGA1064_ramdac_init(minfo);
0713 }
0714 #endif
0715 
0716 #ifdef CONFIG_FB_MATROX_G
0717 static void g450_mclk_init(struct matrox_fb_info *minfo)
0718 {
0719     /* switch all clocks to PCI source */
0720     pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg | 4);
0721     pci_write_config_dword(minfo->pcidev, PCI_OPTION3_REG, minfo->values.reg.opt3 & ~0x00300C03);
0722     pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg);
0723 
0724     if (((minfo->values.reg.opt3 & 0x000003) == 0x000003) ||
0725         ((minfo->values.reg.opt3 & 0x000C00) == 0x000C00) ||
0726         ((minfo->values.reg.opt3 & 0x300000) == 0x300000)) {
0727         matroxfb_g450_setclk(minfo, minfo->values.pll.video, M_VIDEO_PLL);
0728     } else {
0729         unsigned long flags;
0730         unsigned int pwr;
0731         
0732         matroxfb_DAC_lock_irqsave(flags);
0733         pwr = inDAC1064(minfo, M1064_XPWRCTRL) & ~0x02;
0734         outDAC1064(minfo, M1064_XPWRCTRL, pwr);
0735         matroxfb_DAC_unlock_irqrestore(flags);
0736     }
0737     matroxfb_g450_setclk(minfo, minfo->values.pll.system, M_SYSTEM_PLL);
0738     
0739     /* switch clocks to their real PLL source(s) */
0740     pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg | 4);
0741     pci_write_config_dword(minfo->pcidev, PCI_OPTION3_REG, minfo->values.reg.opt3);
0742     pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg);
0743 
0744 }
0745 
0746 static void g450_memory_init(struct matrox_fb_info *minfo)
0747 {
0748     /* disable memory refresh */
0749     minfo->hw.MXoptionReg &= ~0x001F8000;
0750     pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg);
0751     
0752     /* set memory interface parameters */
0753     minfo->hw.MXoptionReg &= ~0x00207E00;
0754     minfo->hw.MXoptionReg |= 0x00207E00 & minfo->values.reg.opt;
0755     pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg);
0756     pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, minfo->values.reg.opt2);
0757     
0758     mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst);
0759     
0760     /* first set up memory interface with disabled memory interface clocks */
0761     pci_write_config_dword(minfo->pcidev, PCI_MEMMISC_REG, minfo->values.reg.memmisc & ~0x80000000U);
0762     mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk);
0763     mga_outl(M_MACCESS, minfo->values.reg.maccess);
0764     /* start memory clocks */
0765     pci_write_config_dword(minfo->pcidev, PCI_MEMMISC_REG, minfo->values.reg.memmisc | 0x80000000U);
0766 
0767     udelay(200);
0768     
0769     if (minfo->values.memory.ddr && (!minfo->values.memory.emrswen || !minfo->values.memory.dll)) {
0770         mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk & ~0x1000);
0771     }
0772     mga_outl(M_MACCESS, minfo->values.reg.maccess | 0x8000);
0773     
0774     udelay(200);
0775     
0776     minfo->hw.MXoptionReg |= 0x001F8000 & minfo->values.reg.opt;
0777     pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg);
0778     
0779     /* value is written to memory chips only if old != new */
0780     mga_outl(M_PLNWT, 0);
0781     mga_outl(M_PLNWT, ~0);
0782     
0783     if (minfo->values.reg.mctlwtst != minfo->values.reg.mctlwtst_core) {
0784         mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst_core);
0785     }
0786     
0787 }
0788 
0789 static void g450_preinit(struct matrox_fb_info *minfo)
0790 {
0791     u_int32_t c2ctl;
0792     u_int8_t curctl;
0793     u_int8_t c1ctl;
0794     
0795     /* minfo->hw.MXoptionReg = minfo->values.reg.opt; */
0796     minfo->hw.MXoptionReg &= 0xC0000100;
0797     minfo->hw.MXoptionReg |= 0x00000020;
0798     if (minfo->devflags.novga)
0799         minfo->hw.MXoptionReg &= ~0x00000100;
0800     if (minfo->devflags.nobios)
0801         minfo->hw.MXoptionReg &= ~0x40000000;
0802     if (minfo->devflags.nopciretry)
0803         minfo->hw.MXoptionReg |=  0x20000000;
0804     minfo->hw.MXoptionReg |= minfo->values.reg.opt & 0x03400040;
0805     pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg);
0806 
0807     /* Init system clocks */
0808         
0809     /* stop crtc2 */
0810     c2ctl = mga_inl(M_C2CTL);
0811     mga_outl(M_C2CTL, c2ctl & ~1);
0812     /* stop cursor */
0813     curctl = inDAC1064(minfo, M1064_XCURCTRL);
0814     outDAC1064(minfo, M1064_XCURCTRL, 0);
0815     /* stop crtc1 */
0816     c1ctl = mga_readr(M_SEQ_INDEX, 1);
0817     mga_setr(M_SEQ_INDEX, 1, c1ctl | 0x20);
0818 
0819     g450_mclk_init(minfo);
0820     g450_memory_init(minfo);
0821     
0822     /* set legacy VGA clock sources for DOSEmu or VMware... */
0823     matroxfb_g450_setclk(minfo, 25175, M_PIXEL_PLL_A);
0824     matroxfb_g450_setclk(minfo, 28322, M_PIXEL_PLL_B);
0825 
0826     /* restore crtc1 */
0827     mga_setr(M_SEQ_INDEX, 1, c1ctl);
0828     
0829     /* restore cursor */
0830     outDAC1064(minfo, M1064_XCURCTRL, curctl);
0831 
0832     /* restore crtc2 */
0833     mga_outl(M_C2CTL, c2ctl);
0834     
0835     return;
0836 }
0837 
0838 static int MGAG100_preinit(struct matrox_fb_info *minfo)
0839 {
0840     static const int vxres_g100[] = {  512,        640, 768,  800,  832,  960,
0841                                           1024, 1152, 1280,      1600, 1664, 1920,
0842                                           2048, 0};
0843     struct matrox_hw_state *hw = &minfo->hw;
0844 
0845         u_int32_t reg50;
0846 #if 0
0847     u_int32_t q;
0848 #endif
0849 
0850     DBG(__func__)
0851 
0852     /* there are some instabilities if in_div > 19 && vco < 61000 */
0853     if (minfo->devflags.g450dac) {
0854         minfo->features.pll.vco_freq_min = 130000;  /* my sample: >118 */
0855     } else {
0856         minfo->features.pll.vco_freq_min = 62000;
0857     }
0858     if (!minfo->features.pll.ref_freq) {
0859         minfo->features.pll.ref_freq     = 27000;
0860     }
0861     minfo->features.pll.feed_div_min = 7;
0862     minfo->features.pll.feed_div_max = 127;
0863     minfo->features.pll.in_div_min   = 1;
0864     minfo->features.pll.in_div_max   = 31;
0865     minfo->features.pll.post_shift_max = 3;
0866     minfo->features.DAC1064.xvrefctrl = DAC1064_XVREFCTRL_G100_DEFAULT;
0867     /* minfo->capable.cfb4 = 0; ... preinitialized by 0 */
0868     minfo->capable.text = 1;
0869     minfo->capable.vxres = vxres_g100;
0870     minfo->capable.plnwt = minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG100
0871             ? minfo->devflags.sgram : 1;
0872 
0873     if (minfo->devflags.g450dac) {
0874         minfo->outputs[0].output = &g450out;
0875     } else {
0876         minfo->outputs[0].output = &m1064;
0877     }
0878     minfo->outputs[0].src = minfo->outputs[0].default_src;
0879     minfo->outputs[0].data = minfo;
0880     minfo->outputs[0].mode = MATROXFB_OUTPUT_MODE_MONITOR;
0881 
0882     if (minfo->devflags.g450dac) {
0883         /* we must do this always, BIOS does not do it for us
0884            and accelerator dies without it */
0885         mga_outl(0x1C0C, 0);
0886     }
0887     if (minfo->devflags.noinit)
0888         return 0;
0889     if (minfo->devflags.g450dac) {
0890         g450_preinit(minfo);
0891         return 0;
0892     }
0893     hw->MXoptionReg &= 0xC0000100;
0894     hw->MXoptionReg |= 0x00000020;
0895     if (minfo->devflags.novga)
0896         hw->MXoptionReg &= ~0x00000100;
0897     if (minfo->devflags.nobios)
0898         hw->MXoptionReg &= ~0x40000000;
0899     if (minfo->devflags.nopciretry)
0900         hw->MXoptionReg |=  0x20000000;
0901     pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
0902     DAC1064_setmclk(minfo, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PCI, 133333);
0903 
0904     if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG100) {
0905         pci_read_config_dword(minfo->pcidev, PCI_OPTION2_REG, &reg50);
0906         reg50 &= ~0x3000;
0907         pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, reg50);
0908 
0909         hw->MXoptionReg |= 0x1080;
0910         pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
0911         mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst);
0912         udelay(100);
0913         mga_outb(0x1C05, 0x00);
0914         mga_outb(0x1C05, 0x80);
0915         udelay(100);
0916         mga_outb(0x1C05, 0x40);
0917         mga_outb(0x1C05, 0xC0);
0918         udelay(100);
0919         reg50 &= ~0xFF;
0920         reg50 |=  0x07;
0921         pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, reg50);
0922         /* it should help with G100 */
0923         mga_outb(M_GRAPHICS_INDEX, 6);
0924         mga_outb(M_GRAPHICS_DATA, (mga_inb(M_GRAPHICS_DATA) & 3) | 4);
0925         mga_setr(M_EXTVGA_INDEX, 0x03, 0x81);
0926         mga_setr(M_EXTVGA_INDEX, 0x04, 0x00);
0927         mga_writeb(minfo->video.vbase, 0x0000, 0xAA);
0928         mga_writeb(minfo->video.vbase, 0x0800, 0x55);
0929         mga_writeb(minfo->video.vbase, 0x4000, 0x55);
0930 #if 0
0931         if (mga_readb(minfo->video.vbase, 0x0000) != 0xAA) {
0932             hw->MXoptionReg &= ~0x1000;
0933         }
0934 #endif
0935         hw->MXoptionReg |= 0x00078020;
0936     } else if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG200) {
0937         pci_read_config_dword(minfo->pcidev, PCI_OPTION2_REG, &reg50);
0938         reg50 &= ~0x3000;
0939         pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, reg50);
0940 
0941         if (minfo->devflags.memtype == -1)
0942             hw->MXoptionReg |= minfo->values.reg.opt & 0x1C00;
0943         else
0944             hw->MXoptionReg |= (minfo->devflags.memtype & 7) << 10;
0945         if (minfo->devflags.sgram)
0946             hw->MXoptionReg |= 0x4000;
0947         mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst);
0948         mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk);
0949         udelay(200);
0950         mga_outl(M_MACCESS, 0x00000000);
0951         mga_outl(M_MACCESS, 0x00008000);
0952         udelay(100);
0953         mga_outw(M_MEMRDBK, minfo->values.reg.memrdbk);
0954         hw->MXoptionReg |= 0x00078020;
0955     } else {
0956         pci_read_config_dword(minfo->pcidev, PCI_OPTION2_REG, &reg50);
0957         reg50 &= ~0x00000100;
0958         reg50 |=  0x00000000;
0959         pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, reg50);
0960 
0961         if (minfo->devflags.memtype == -1)
0962             hw->MXoptionReg |= minfo->values.reg.opt & 0x1C00;
0963         else
0964             hw->MXoptionReg |= (minfo->devflags.memtype & 7) << 10;
0965         if (minfo->devflags.sgram)
0966             hw->MXoptionReg |= 0x4000;
0967         mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst);
0968         mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk);
0969         udelay(200);
0970         mga_outl(M_MACCESS, 0x00000000);
0971         mga_outl(M_MACCESS, 0x00008000);
0972         udelay(100);
0973         mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk);
0974         hw->MXoptionReg |= 0x00040020;
0975     }
0976     pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
0977     return 0;
0978 }
0979 
0980 static void MGAG100_reset(struct matrox_fb_info *minfo)
0981 {
0982     u_int8_t b;
0983     struct matrox_hw_state *hw = &minfo->hw;
0984 
0985     DBG(__func__)
0986 
0987     {
0988 #ifdef G100_BROKEN_IBM_82351
0989         u_int32_t d;
0990 
0991         find 1014/22 (IBM/82351); /* if found and bridging Matrox, do some strange stuff */
0992         pci_read_config_byte(ibm, PCI_SECONDARY_BUS, &b);
0993         if (b == minfo->pcidev->bus->number) {
0994             pci_write_config_byte(ibm, PCI_COMMAND+1, 0);   /* disable back-to-back & SERR */
0995             pci_write_config_byte(ibm, 0x41, 0xF4);     /* ??? */
0996             pci_write_config_byte(ibm, PCI_IO_BASE, 0xF0);  /* ??? */
0997             pci_write_config_byte(ibm, PCI_IO_LIMIT, 0x00); /* ??? */
0998         }
0999 #endif
1000         if (!minfo->devflags.noinit) {
1001             if (x7AF4 & 8) {
1002                 hw->MXoptionReg |= 0x40;    /* FIXME... */
1003                 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
1004             }
1005             mga_setr(M_EXTVGA_INDEX, 0x06, 0x00);
1006         }
1007     }
1008     if (minfo->devflags.g450dac) {
1009         /* either leave MCLK as is... or they were set in preinit */
1010         hw->DACclk[3] = inDAC1064(minfo, DAC1064_XSYSPLLM);
1011         hw->DACclk[4] = inDAC1064(minfo, DAC1064_XSYSPLLN);
1012         hw->DACclk[5] = inDAC1064(minfo, DAC1064_XSYSPLLP);
1013     } else {
1014         DAC1064_setmclk(minfo, DAC1064_OPT_RESERVED | DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV1 | DAC1064_OPT_SCLK_PLL, 133333);
1015     }
1016     if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG400) {
1017         if (minfo->devflags.dfp_type == -1) {
1018             minfo->devflags.dfp_type = inDAC1064(minfo, 0x1F);
1019         }
1020     }
1021     if (minfo->devflags.noinit)
1022         return;
1023     if (minfo->devflags.g450dac) {
1024     } else {
1025         MGAG100_setPixClock(minfo, 4, 25175);
1026         MGAG100_setPixClock(minfo, 5, 28322);
1027         if (x7AF4 & 0x10) {
1028             b = inDAC1064(minfo, M1064_XGENIODATA) & ~1;
1029             outDAC1064(minfo, M1064_XGENIODATA, b);
1030             b = inDAC1064(minfo, M1064_XGENIOCTRL) | 1;
1031             outDAC1064(minfo, M1064_XGENIOCTRL, b);
1032         }
1033     }
1034 }
1035 #endif
1036 
1037 #ifdef CONFIG_FB_MATROX_MYSTIQUE
1038 static void MGA1064_restore(struct matrox_fb_info *minfo)
1039 {
1040     int i;
1041     struct matrox_hw_state *hw = &minfo->hw;
1042 
1043     CRITFLAGS
1044 
1045     DBG(__func__)
1046 
1047     CRITBEGIN
1048 
1049     pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
1050     mga_outb(M_IEN, 0x00);
1051     mga_outb(M_CACHEFLUSH, 0x00);
1052 
1053     CRITEND
1054 
1055     DAC1064_restore_1(minfo);
1056     matroxfb_vgaHWrestore(minfo);
1057     minfo->crtc1.panpos = -1;
1058     for (i = 0; i < 6; i++)
1059         mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
1060     DAC1064_restore_2(minfo);
1061 }
1062 #endif
1063 
1064 #ifdef CONFIG_FB_MATROX_G
1065 static void MGAG100_restore(struct matrox_fb_info *minfo)
1066 {
1067     int i;
1068     struct matrox_hw_state *hw = &minfo->hw;
1069 
1070     CRITFLAGS
1071 
1072     DBG(__func__)
1073 
1074     CRITBEGIN
1075 
1076     pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
1077     CRITEND
1078 
1079     DAC1064_restore_1(minfo);
1080     matroxfb_vgaHWrestore(minfo);
1081     if (minfo->devflags.support32MB)
1082         mga_setr(M_EXTVGA_INDEX, 8, hw->CRTCEXT[8]);
1083     minfo->crtc1.panpos = -1;
1084     for (i = 0; i < 6; i++)
1085         mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
1086     DAC1064_restore_2(minfo);
1087 }
1088 #endif
1089 
1090 #ifdef CONFIG_FB_MATROX_MYSTIQUE
1091 struct matrox_switch matrox_mystique = {
1092     .preinit    = MGA1064_preinit,
1093     .reset      = MGA1064_reset,
1094     .init       = MGA1064_init,
1095     .restore    = MGA1064_restore,
1096 };
1097 EXPORT_SYMBOL(matrox_mystique);
1098 #endif
1099 
1100 #ifdef CONFIG_FB_MATROX_G
1101 struct matrox_switch matrox_G100 = {
1102     .preinit    = MGAG100_preinit,
1103     .reset      = MGAG100_reset,
1104     .init       = MGAG100_init,
1105     .restore    = MGAG100_restore,
1106 };
1107 EXPORT_SYMBOL(matrox_G100);
1108 #endif
1109 
1110 #ifdef NEED_DAC1064
1111 EXPORT_SYMBOL(DAC1064_global_init);
1112 EXPORT_SYMBOL(DAC1064_global_restore);
1113 #endif
1114 MODULE_LICENSE("GPL");