linux/drivers/video/fbdev/matrox/matroxfb_DAC1064.c
<<
>>
Prefs
   1/*
   2 *
   3 * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450.
   4 *
   5 * (c) 1998-2002 Petr Vandrovec <vandrove@vc.cvut.cz>
   6 *
   7 * Portions Copyright (c) 2001 Matrox Graphics Inc.
   8 *
   9 * Version: 1.65 2002/08/14
  10 *
  11 * See matroxfb_base.c for contributors.
  12 *
  13 */
  14
  15
  16#include "matroxfb_DAC1064.h"
  17#include "matroxfb_misc.h"
  18#include "matroxfb_accel.h"
  19#include "g450_pll.h"
  20#include <linux/matroxfb.h>
  21
  22#ifdef NEED_DAC1064
  23#define outDAC1064 matroxfb_DAC_out
  24#define inDAC1064 matroxfb_DAC_in
  25
  26#define DAC1064_OPT_SCLK_PCI    0x00
  27#define DAC1064_OPT_SCLK_PLL    0x01
  28#define DAC1064_OPT_SCLK_EXT    0x02
  29#define DAC1064_OPT_SCLK_MASK   0x03
  30#define DAC1064_OPT_GDIV1       0x04    /* maybe it is GDIV2 on G100 ?! */
  31#define DAC1064_OPT_GDIV3       0x00
  32#define DAC1064_OPT_MDIV1       0x08
  33#define DAC1064_OPT_MDIV2       0x00
  34#define DAC1064_OPT_RESERVED    0x10
  35
  36static void DAC1064_calcclock(const struct matrox_fb_info *minfo,
  37                              unsigned int freq, unsigned int fmax,
  38                              unsigned int *in, unsigned int *feed,
  39                              unsigned int *post)
  40{
  41        unsigned int fvco;
  42        unsigned int p;
  43
  44        DBG(__func__)
  45        
  46        /* only for devices older than G450 */
  47
  48        fvco = PLL_calcclock(minfo, freq, fmax, in, feed, &p);
  49        
  50        p = (1 << p) - 1;
  51        if (fvco <= 100000)
  52                ;
  53        else if (fvco <= 140000)
  54                p |= 0x08;
  55        else if (fvco <= 180000)
  56                p |= 0x10;
  57        else
  58                p |= 0x18;
  59        *post = p;
  60}
  61
  62/* they must be in POS order */
  63static const unsigned char MGA1064_DAC_regs[] = {
  64                M1064_XCURADDL, M1064_XCURADDH, M1064_XCURCTRL,
  65                M1064_XCURCOL0RED, M1064_XCURCOL0GREEN, M1064_XCURCOL0BLUE,
  66                M1064_XCURCOL1RED, M1064_XCURCOL1GREEN, M1064_XCURCOL1BLUE,
  67                M1064_XCURCOL2RED, M1064_XCURCOL2GREEN, M1064_XCURCOL2BLUE,
  68                DAC1064_XVREFCTRL, M1064_XMULCTRL, M1064_XPIXCLKCTRL, M1064_XGENCTRL,
  69                M1064_XMISCCTRL,
  70                M1064_XGENIOCTRL, M1064_XGENIODATA, M1064_XZOOMCTRL, M1064_XSENSETEST,
  71                M1064_XCRCBITSEL,
  72                M1064_XCOLKEYMASKL, M1064_XCOLKEYMASKH, M1064_XCOLKEYL, M1064_XCOLKEYH };
  73
  74static const unsigned char MGA1064_DAC[] = {
  75                0x00, 0x00, M1064_XCURCTRL_DIS,
  76                0x00, 0x00, 0x00,       /* black */
  77                0xFF, 0xFF, 0xFF,       /* white */
  78                0xFF, 0x00, 0x00,       /* red */
  79                0x00, 0,
  80                M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL,
  81                M1064_XGENCTRL_VS_0 | M1064_XGENCTRL_ALPHA_DIS | M1064_XGENCTRL_BLACK_0IRE | M1064_XGENCTRL_NO_SYNC_ON_GREEN,
  82                M1064_XMISCCTRL_DAC_8BIT,
  83                0x00, 0x00, M1064_XZOOMCTRL_1, M1064_XSENSETEST_BCOMP | M1064_XSENSETEST_GCOMP | M1064_XSENSETEST_RCOMP | M1064_XSENSETEST_PDOWN,
  84                0x00,
  85                0x00, 0x00, 0xFF, 0xFF};
  86
  87static void DAC1064_setpclk(struct matrox_fb_info *minfo, unsigned long fout)
  88{
  89        unsigned int m, n, p;
  90
  91        DBG(__func__)
  92
  93        DAC1064_calcclock(minfo, fout, minfo->max_pixel_clock, &m, &n, &p);
  94        minfo->hw.DACclk[0] = m;
  95        minfo->hw.DACclk[1] = n;
  96        minfo->hw.DACclk[2] = p;
  97}
  98
  99static void DAC1064_setmclk(struct matrox_fb_info *minfo, int oscinfo,
 100                            unsigned long fmem)
 101{
 102        u_int32_t mx;
 103        struct matrox_hw_state *hw = &minfo->hw;
 104
 105        DBG(__func__)
 106
 107        if (minfo->devflags.noinit) {
 108                /* read MCLK and give up... */
 109                hw->DACclk[3] = inDAC1064(minfo, DAC1064_XSYSPLLM);
 110                hw->DACclk[4] = inDAC1064(minfo, DAC1064_XSYSPLLN);
 111                hw->DACclk[5] = inDAC1064(minfo, DAC1064_XSYSPLLP);
 112                return;
 113        }
 114        mx = hw->MXoptionReg | 0x00000004;
 115        pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mx);
 116        mx &= ~0x000000BB;
 117        if (oscinfo & DAC1064_OPT_GDIV1)
 118                mx |= 0x00000008;
 119        if (oscinfo & DAC1064_OPT_MDIV1)
 120                mx |= 0x00000010;
 121        if (oscinfo & DAC1064_OPT_RESERVED)
 122                mx |= 0x00000080;
 123        if ((oscinfo & DAC1064_OPT_SCLK_MASK) == DAC1064_OPT_SCLK_PLL) {
 124                /* select PCI clock until we have setup oscilator... */
 125                int clk;
 126                unsigned int m, n, p;
 127
 128                /* powerup system PLL, select PCI clock */
 129                mx |= 0x00000020;
 130                pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mx);
 131                mx &= ~0x00000004;
 132                pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mx);
 133
 134                /* !!! you must not access device if MCLK is not running !!!
 135                   Doing so cause immediate PCI lockup :-( Maybe they should
 136                   generate ABORT or I/O (parity...) error and Linux should
 137                   recover from this... (kill driver/process). But world is not
 138                   perfect... */
 139                /* (bit 2 of PCI_OPTION_REG must be 0... and bits 0,1 must not
 140                   select PLL... because of PLL can be stopped at this time) */
 141                DAC1064_calcclock(minfo, fmem, minfo->max_pixel_clock, &m, &n, &p);
 142                outDAC1064(minfo, DAC1064_XSYSPLLM, hw->DACclk[3] = m);
 143                outDAC1064(minfo, DAC1064_XSYSPLLN, hw->DACclk[4] = n);
 144                outDAC1064(minfo, DAC1064_XSYSPLLP, hw->DACclk[5] = p);
 145                for (clk = 65536; clk; --clk) {
 146                        if (inDAC1064(minfo, DAC1064_XSYSPLLSTAT) & 0x40)
 147                                break;
 148                }
 149                if (!clk)
 150                        printk(KERN_ERR "matroxfb: aiee, SYSPLL not locked\n");
 151                /* select PLL */
 152                mx |= 0x00000005;
 153        } else {
 154                /* select specified system clock source */
 155                mx |= oscinfo & DAC1064_OPT_SCLK_MASK;
 156        }
 157        pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mx);
 158        mx &= ~0x00000004;
 159        pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mx);
 160        hw->MXoptionReg = mx;
 161}
 162
 163#ifdef CONFIG_FB_MATROX_G
 164static void g450_set_plls(struct matrox_fb_info *minfo)
 165{
 166        u_int32_t c2_ctl;
 167        unsigned int pxc;
 168        struct matrox_hw_state *hw = &minfo->hw;
 169        int pixelmnp;
 170        int videomnp;
 171        
 172        c2_ctl = hw->crtc2.ctl & ~0x4007;       /* Clear PLL + enable for CRTC2 */
 173        c2_ctl |= 0x0001;                       /* Enable CRTC2 */
 174        hw->DACreg[POS1064_XPWRCTRL] &= ~0x02;  /* Stop VIDEO PLL */
 175        pixelmnp = minfo->crtc1.mnp;
 176        videomnp = minfo->crtc2.mnp;
 177        if (videomnp < 0) {
 178                c2_ctl &= ~0x0001;                      /* Disable CRTC2 */
 179                hw->DACreg[POS1064_XPWRCTRL] &= ~0x10;  /* Powerdown CRTC2 */
 180        } else if (minfo->crtc2.pixclock == minfo->features.pll.ref_freq) {
 181                c2_ctl |=  0x4002;      /* Use reference directly */
 182        } else if (videomnp == pixelmnp) {
 183                c2_ctl |=  0x0004;      /* Use pixel PLL */
 184        } else {
 185                if (0 == ((videomnp ^ pixelmnp) & 0xFFFFFF00)) {
 186                        /* PIXEL and VIDEO PLL must not use same frequency. We modify N
 187                           of PIXEL PLL in such case because of VIDEO PLL may be source
 188                           of TVO clocks, and chroma subcarrier is derived from its
 189                           pixel clocks */
 190                        pixelmnp += 0x000100;
 191                }
 192                c2_ctl |=  0x0006;      /* Use video PLL */
 193                hw->DACreg[POS1064_XPWRCTRL] |= 0x02;
 194                
 195                outDAC1064(minfo, M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]);
 196                matroxfb_g450_setpll_cond(minfo, videomnp, M_VIDEO_PLL);
 197        }
 198
 199        hw->DACreg[POS1064_XPIXCLKCTRL] &= ~M1064_XPIXCLKCTRL_PLL_UP;
 200        if (pixelmnp >= 0) {
 201                hw->DACreg[POS1064_XPIXCLKCTRL] |= M1064_XPIXCLKCTRL_PLL_UP;
 202                
 203                outDAC1064(minfo, M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]);
 204                matroxfb_g450_setpll_cond(minfo, pixelmnp, M_PIXEL_PLL_C);
 205        }
 206        if (c2_ctl != hw->crtc2.ctl) {
 207                hw->crtc2.ctl = c2_ctl;
 208                mga_outl(0x3C10, c2_ctl);
 209        }
 210
 211        pxc = minfo->crtc1.pixclock;
 212        if (pxc == 0 || minfo->outputs[2].src == MATROXFB_SRC_CRTC2) {
 213                pxc = minfo->crtc2.pixclock;
 214        }
 215        if (minfo->chip == MGA_G550) {
 216                if (pxc < 45000) {
 217                        hw->DACreg[POS1064_XPANMODE] = 0x00;    /* 0-50 */
 218                } else if (pxc < 55000) {
 219                        hw->DACreg[POS1064_XPANMODE] = 0x08;    /* 34-62 */
 220                } else if (pxc < 70000) {
 221                        hw->DACreg[POS1064_XPANMODE] = 0x10;    /* 42-78 */
 222                } else if (pxc < 85000) {
 223                        hw->DACreg[POS1064_XPANMODE] = 0x18;    /* 62-92 */
 224                } else if (pxc < 100000) {
 225                        hw->DACreg[POS1064_XPANMODE] = 0x20;    /* 74-108 */
 226                } else if (pxc < 115000) {
 227                        hw->DACreg[POS1064_XPANMODE] = 0x28;    /* 94-122 */
 228                } else if (pxc < 125000) {
 229                        hw->DACreg[POS1064_XPANMODE] = 0x30;    /* 108-132 */
 230                } else {
 231                        hw->DACreg[POS1064_XPANMODE] = 0x38;    /* 120-168 */
 232                }
 233        } else {
 234                /* G450 */
 235                if (pxc < 45000) {
 236                        hw->DACreg[POS1064_XPANMODE] = 0x00;    /* 0-54 */
 237                } else if (pxc < 65000) {
 238                        hw->DACreg[POS1064_XPANMODE] = 0x08;    /* 38-70 */
 239                } else if (pxc < 85000) {
 240                        hw->DACreg[POS1064_XPANMODE] = 0x10;    /* 56-96 */
 241                } else if (pxc < 105000) {
 242                        hw->DACreg[POS1064_XPANMODE] = 0x18;    /* 80-114 */
 243                } else if (pxc < 135000) {
 244                        hw->DACreg[POS1064_XPANMODE] = 0x20;    /* 102-144 */
 245                } else if (pxc < 160000) {
 246                        hw->DACreg[POS1064_XPANMODE] = 0x28;    /* 132-166 */
 247                } else if (pxc < 175000) {
 248                        hw->DACreg[POS1064_XPANMODE] = 0x30;    /* 154-182 */
 249                } else {
 250                        hw->DACreg[POS1064_XPANMODE] = 0x38;    /* 170-204 */
 251                }
 252        }
 253}
 254#endif
 255
 256void DAC1064_global_init(struct matrox_fb_info *minfo)
 257{
 258        struct matrox_hw_state *hw = &minfo->hw;
 259
 260        hw->DACreg[POS1064_XMISCCTRL] &= M1064_XMISCCTRL_DAC_WIDTHMASK;
 261        hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_LUT_EN;
 262        hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL;
 263#ifdef CONFIG_FB_MATROX_G
 264        if (minfo->devflags.g450dac) {
 265                hw->DACreg[POS1064_XPWRCTRL] = 0x1F;    /* powerup everything */
 266                hw->DACreg[POS1064_XOUTPUTCONN] = 0x00; /* disable outputs */
 267                hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN;
 268                switch (minfo->outputs[0].src) {
 269                        case MATROXFB_SRC_CRTC1:
 270                        case MATROXFB_SRC_CRTC2:
 271                                hw->DACreg[POS1064_XOUTPUTCONN] |= 0x01;        /* enable output; CRTC1/2 selection is in CRTC2 ctl */
 272                                break;
 273                        case MATROXFB_SRC_NONE:
 274                                hw->DACreg[POS1064_XMISCCTRL] &= ~M1064_XMISCCTRL_DAC_EN;
 275                                break;
 276                }
 277                switch (minfo->outputs[1].src) {
 278                        case MATROXFB_SRC_CRTC1:
 279                                hw->DACreg[POS1064_XOUTPUTCONN] |= 0x04;
 280                                break;
 281                        case MATROXFB_SRC_CRTC2:
 282                                if (minfo->outputs[1].mode == MATROXFB_OUTPUT_MODE_MONITOR) {
 283                                        hw->DACreg[POS1064_XOUTPUTCONN] |= 0x08;
 284                                } else {
 285                                        hw->DACreg[POS1064_XOUTPUTCONN] |= 0x0C;
 286                                }
 287                                break;
 288                        case MATROXFB_SRC_NONE:
 289                                hw->DACreg[POS1064_XPWRCTRL] &= ~0x01;          /* Poweroff DAC2 */
 290                                break;
 291                }
 292                switch (minfo->outputs[2].src) {
 293                        case MATROXFB_SRC_CRTC1:
 294                                hw->DACreg[POS1064_XOUTPUTCONN] |= 0x20;
 295                                break;
 296                        case MATROXFB_SRC_CRTC2:
 297                                hw->DACreg[POS1064_XOUTPUTCONN] |= 0x40;
 298                                break;
 299                        case MATROXFB_SRC_NONE:
 300#if 0
 301                                /* HELP! If we boot without DFP connected to DVI, we can
 302                                   poweroff TMDS. But if we boot with DFP connected,
 303                                   TMDS generated clocks are used instead of ALL pixclocks
 304                                   available... If someone knows which register
 305                                   handles it, please reveal this secret to me... */                    
 306                                hw->DACreg[POS1064_XPWRCTRL] &= ~0x04;          /* Poweroff TMDS */
 307#endif                          
 308                                break;
 309                }
 310                /* Now set timming related variables... */
 311                g450_set_plls(minfo);
 312        } else
 313#endif
 314        {
 315                if (minfo->outputs[1].src == MATROXFB_SRC_CRTC1) {
 316                        hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_EXT;
 317                        hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_MAFC12;
 318                } else if (minfo->outputs[1].src == MATROXFB_SRC_CRTC2) {
 319                        hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_C2_MAFC12;
 320                } else if (minfo->outputs[2].src == MATROXFB_SRC_CRTC1)
 321                        hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_PANELLINK | G400_XMISCCTRL_VDO_MAFC12;
 322                else
 323                        hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_DIS;
 324
 325                if (minfo->outputs[0].src != MATROXFB_SRC_NONE)
 326                        hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN;
 327        }
 328}
 329
 330void DAC1064_global_restore(struct matrox_fb_info *minfo)
 331{
 332        struct matrox_hw_state *hw = &minfo->hw;
 333
 334        outDAC1064(minfo, M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]);
 335        outDAC1064(minfo, M1064_XMISCCTRL, hw->DACreg[POS1064_XMISCCTRL]);
 336        if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG400) {
 337                outDAC1064(minfo, 0x20, 0x04);
 338                outDAC1064(minfo, 0x1F, minfo->devflags.dfp_type);
 339                if (minfo->devflags.g450dac) {
 340                        outDAC1064(minfo, M1064_XSYNCCTRL, 0xCC);
 341                        outDAC1064(minfo, M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]);
 342                        outDAC1064(minfo, M1064_XPANMODE, hw->DACreg[POS1064_XPANMODE]);
 343                        outDAC1064(minfo, M1064_XOUTPUTCONN, hw->DACreg[POS1064_XOUTPUTCONN]);
 344                }
 345        }
 346}
 347
 348static int DAC1064_init_1(struct matrox_fb_info *minfo, struct my_timming *m)
 349{
 350        struct matrox_hw_state *hw = &minfo->hw;
 351
 352        DBG(__func__)
 353
 354        memcpy(hw->DACreg, MGA1064_DAC, sizeof(MGA1064_DAC_regs));
 355        switch (minfo->fbcon.var.bits_per_pixel) {
 356                /* case 4: not supported by MGA1064 DAC */
 357                case 8:
 358                        hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_8BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
 359                        break;
 360                case 16:
 361                        if (minfo->fbcon.var.green.length == 5)
 362                                hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_15BPP_1BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
 363                        else
 364                                hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_16BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
 365                        break;
 366                case 24:
 367                        hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_24BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
 368                        break;
 369                case 32:
 370                        hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_32BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
 371                        break;
 372                default:
 373                        return 1;       /* unsupported depth */
 374        }
 375        hw->DACreg[POS1064_XVREFCTRL] = minfo->features.DAC1064.xvrefctrl;
 376        hw->DACreg[POS1064_XGENCTRL] &= ~M1064_XGENCTRL_SYNC_ON_GREEN_MASK;
 377        hw->DACreg[POS1064_XGENCTRL] |= (m->sync & FB_SYNC_ON_GREEN)?M1064_XGENCTRL_SYNC_ON_GREEN:M1064_XGENCTRL_NO_SYNC_ON_GREEN;
 378        hw->DACreg[POS1064_XCURADDL] = 0;
 379        hw->DACreg[POS1064_XCURADDH] = 0;
 380
 381        DAC1064_global_init(minfo);
 382        return 0;
 383}
 384
 385static int DAC1064_init_2(struct matrox_fb_info *minfo, struct my_timming *m)
 386{
 387        struct matrox_hw_state *hw = &minfo->hw;
 388
 389        DBG(__func__)
 390
 391        if (minfo->fbcon.var.bits_per_pixel > 16) {     /* 256 entries */
 392                int i;
 393
 394                for (i = 0; i < 256; i++) {
 395                        hw->DACpal[i * 3 + 0] = i;
 396                        hw->DACpal[i * 3 + 1] = i;
 397                        hw->DACpal[i * 3 + 2] = i;
 398                }
 399        } else if (minfo->fbcon.var.bits_per_pixel > 8) {
 400                if (minfo->fbcon.var.green.length == 5) {       /* 0..31, 128..159 */
 401                        int i;
 402
 403                        for (i = 0; i < 32; i++) {
 404                                /* with p15 == 0 */
 405                                hw->DACpal[i * 3 + 0] = i << 3;
 406                                hw->DACpal[i * 3 + 1] = i << 3;
 407                                hw->DACpal[i * 3 + 2] = i << 3;
 408                                /* with p15 == 1 */
 409                                hw->DACpal[(i + 128) * 3 + 0] = i << 3;
 410                                hw->DACpal[(i + 128) * 3 + 1] = i << 3;
 411                                hw->DACpal[(i + 128) * 3 + 2] = i << 3;
 412                        }
 413                } else {
 414                        int i;
 415
 416                        for (i = 0; i < 64; i++) {              /* 0..63 */
 417                                hw->DACpal[i * 3 + 0] = i << 3;
 418                                hw->DACpal[i * 3 + 1] = i << 2;
 419                                hw->DACpal[i * 3 + 2] = i << 3;
 420                        }
 421                }
 422        } else {
 423                memset(hw->DACpal, 0, 768);
 424        }
 425        return 0;
 426}
 427
 428static void DAC1064_restore_1(struct matrox_fb_info *minfo)
 429{
 430        struct matrox_hw_state *hw = &minfo->hw;
 431
 432        CRITFLAGS
 433
 434        DBG(__func__)
 435
 436        CRITBEGIN
 437
 438        if ((inDAC1064(minfo, DAC1064_XSYSPLLM) != hw->DACclk[3]) ||
 439            (inDAC1064(minfo, DAC1064_XSYSPLLN) != hw->DACclk[4]) ||
 440            (inDAC1064(minfo, DAC1064_XSYSPLLP) != hw->DACclk[5])) {
 441                outDAC1064(minfo, DAC1064_XSYSPLLM, hw->DACclk[3]);
 442                outDAC1064(minfo, DAC1064_XSYSPLLN, hw->DACclk[4]);
 443                outDAC1064(minfo, DAC1064_XSYSPLLP, hw->DACclk[5]);
 444        }
 445        {
 446                unsigned int i;
 447
 448                for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
 449                        if ((i != POS1064_XPIXCLKCTRL) && (i != POS1064_XMISCCTRL))
 450                                outDAC1064(minfo, MGA1064_DAC_regs[i], hw->DACreg[i]);
 451                }
 452        }
 453
 454        DAC1064_global_restore(minfo);
 455
 456        CRITEND
 457};
 458
 459static void DAC1064_restore_2(struct matrox_fb_info *minfo)
 460{
 461#ifdef DEBUG
 462        unsigned int i;
 463#endif
 464
 465        DBG(__func__)
 466
 467#ifdef DEBUG
 468        dprintk(KERN_DEBUG "DAC1064regs ");
 469        for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
 470                dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], minfo->hw.DACreg[i]);
 471                if ((i & 0x7) == 0x7) dprintk(KERN_DEBUG "continuing... ");
 472        }
 473        dprintk(KERN_DEBUG "DAC1064clk ");
 474        for (i = 0; i < 6; i++)
 475                dprintk("C%02X=%02X ", i, minfo->hw.DACclk[i]);
 476        dprintk("\n");
 477#endif
 478}
 479
 480static int m1064_compute(void* out, struct my_timming* m) {
 481#define minfo ((struct matrox_fb_info*)out)
 482        {
 483                int i;
 484                int tmout;
 485                CRITFLAGS
 486
 487                DAC1064_setpclk(minfo, m->pixclock);
 488
 489                CRITBEGIN
 490
 491                for (i = 0; i < 3; i++)
 492                        outDAC1064(minfo, M1064_XPIXPLLCM + i, minfo->hw.DACclk[i]);
 493                for (tmout = 500000; tmout; tmout--) {
 494                        if (inDAC1064(minfo, M1064_XPIXPLLSTAT) & 0x40)
 495                                break;
 496                        udelay(10);
 497                }
 498
 499                CRITEND
 500
 501                if (!tmout)
 502                        printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
 503        }
 504#undef minfo
 505        return 0;
 506}
 507
 508static struct matrox_altout m1064 = {
 509        .name    = "Primary output",
 510        .compute = m1064_compute,
 511};
 512
 513#ifdef CONFIG_FB_MATROX_G
 514static int g450_compute(void* out, struct my_timming* m) {
 515#define minfo ((struct matrox_fb_info*)out)
 516        if (m->mnp < 0) {
 517                m->mnp = matroxfb_g450_setclk(minfo, m->pixclock, (m->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL);
 518                if (m->mnp >= 0) {
 519                        m->pixclock = g450_mnp2f(minfo, m->mnp);
 520                }
 521        }
 522#undef minfo
 523        return 0;
 524}
 525
 526static struct matrox_altout g450out = {
 527        .name    = "Primary output",
 528        .compute = g450_compute,
 529};
 530#endif
 531
 532#endif /* NEED_DAC1064 */
 533
 534#ifdef CONFIG_FB_MATROX_MYSTIQUE
 535static int MGA1064_init(struct matrox_fb_info *minfo, struct my_timming *m)
 536{
 537        struct matrox_hw_state *hw = &minfo->hw;
 538
 539        DBG(__func__)
 540
 541        if (DAC1064_init_1(minfo, m)) return 1;
 542        if (matroxfb_vgaHWinit(minfo, m)) return 1;
 543
 544        hw->MiscOutReg = 0xCB;
 545        if (m->sync & FB_SYNC_HOR_HIGH_ACT)
 546                hw->MiscOutReg &= ~0x40;
 547        if (m->sync & FB_SYNC_VERT_HIGH_ACT)
 548                hw->MiscOutReg &= ~0x80;
 549        if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */
 550                hw->CRTCEXT[3] |= 0x40;
 551
 552        if (DAC1064_init_2(minfo, m)) return 1;
 553        return 0;
 554}
 555#endif
 556
 557#ifdef CONFIG_FB_MATROX_G
 558static int MGAG100_init(struct matrox_fb_info *minfo, struct my_timming *m)
 559{
 560        struct matrox_hw_state *hw = &minfo->hw;
 561
 562        DBG(__func__)
 563
 564        if (DAC1064_init_1(minfo, m)) return 1;
 565        hw->MXoptionReg &= ~0x2000;
 566        if (matroxfb_vgaHWinit(minfo, m)) return 1;
 567
 568        hw->MiscOutReg = 0xEF;
 569        if (m->sync & FB_SYNC_HOR_HIGH_ACT)
 570                hw->MiscOutReg &= ~0x40;
 571        if (m->sync & FB_SYNC_VERT_HIGH_ACT)
 572                hw->MiscOutReg &= ~0x80;
 573        if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */
 574                hw->CRTCEXT[3] |= 0x40;
 575
 576        if (DAC1064_init_2(minfo, m)) return 1;
 577        return 0;
 578}
 579#endif  /* G */
 580
 581#ifdef CONFIG_FB_MATROX_MYSTIQUE
 582static void MGA1064_ramdac_init(struct matrox_fb_info *minfo)
 583{
 584
 585        DBG(__func__)
 586
 587        /* minfo->features.DAC1064.vco_freq_min = 120000; */
 588        minfo->features.pll.vco_freq_min = 62000;
 589        minfo->features.pll.ref_freq     = 14318;
 590        minfo->features.pll.feed_div_min = 100;
 591        minfo->features.pll.feed_div_max = 127;
 592        minfo->features.pll.in_div_min   = 1;
 593        minfo->features.pll.in_div_max   = 31;
 594        minfo->features.pll.post_shift_max = 3;
 595        minfo->features.DAC1064.xvrefctrl = DAC1064_XVREFCTRL_EXTERNAL;
 596        /* maybe cmdline MCLK= ?, doc says gclk=44MHz, mclk=66MHz... it was 55/83 with old values */
 597        DAC1064_setmclk(minfo, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PLL, 133333);
 598}
 599#endif
 600
 601#ifdef CONFIG_FB_MATROX_G
 602/* BIOS environ */
 603static int x7AF4 = 0x10;        /* flags, maybe 0x10 = SDRAM, 0x00 = SGRAM??? */
 604                                /* G100 wants 0x10, G200 SGRAM does not care... */
 605#if 0
 606static int def50 = 0;   /* reg50, & 0x0F, & 0x3000 (only 0x0000, 0x1000, 0x2000 (0x3000 disallowed and treated as 0) */
 607#endif
 608
 609static void MGAG100_progPixClock(const struct matrox_fb_info *minfo, int flags,
 610                                 int m, int n, int p)
 611{
 612        int reg;
 613        int selClk;
 614        int clk;
 615
 616        DBG(__func__)
 617
 618        outDAC1064(minfo, M1064_XPIXCLKCTRL, inDAC1064(minfo, M1064_XPIXCLKCTRL) | M1064_XPIXCLKCTRL_DIS |
 619                   M1064_XPIXCLKCTRL_PLL_UP);
 620        switch (flags & 3) {
 621                case 0:         reg = M1064_XPIXPLLAM; break;
 622                case 1:         reg = M1064_XPIXPLLBM; break;
 623                default:        reg = M1064_XPIXPLLCM; break;
 624        }
 625        outDAC1064(minfo, reg++, m);
 626        outDAC1064(minfo, reg++, n);
 627        outDAC1064(minfo, reg, p);
 628        selClk = mga_inb(M_MISC_REG_READ) & ~0xC;
 629        /* there should be flags & 0x03 & case 0/1/else */
 630        /* and we should first select source and after that we should wait for PLL */
 631        /* and we are waiting for PLL with oscilator disabled... Is it right? */
 632        switch (flags & 0x03) {
 633                case 0x00:      break;
 634                case 0x01:      selClk |= 4; break;
 635                default:        selClk |= 0x0C; break;
 636        }
 637        mga_outb(M_MISC_REG, selClk);
 638        for (clk = 500000; clk; clk--) {
 639                if (inDAC1064(minfo, M1064_XPIXPLLSTAT) & 0x40)
 640                        break;
 641                udelay(10);
 642        }
 643        if (!clk)
 644                printk(KERN_ERR "matroxfb: Pixel PLL%c not locked after usual time\n", (reg-M1064_XPIXPLLAM-2)/4 + 'A');
 645        selClk = inDAC1064(minfo, M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_SRC_MASK;
 646        switch (flags & 0x0C) {
 647                case 0x00:      selClk |= M1064_XPIXCLKCTRL_SRC_PCI; break;
 648                case 0x04:      selClk |= M1064_XPIXCLKCTRL_SRC_PLL; break;
 649                default:        selClk |= M1064_XPIXCLKCTRL_SRC_EXT; break;
 650        }
 651        outDAC1064(minfo, M1064_XPIXCLKCTRL, selClk);
 652        outDAC1064(minfo, M1064_XPIXCLKCTRL, inDAC1064(minfo, M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_DIS);
 653}
 654
 655static void MGAG100_setPixClock(const struct matrox_fb_info *minfo, int flags,
 656                                int freq)
 657{
 658        unsigned int m, n, p;
 659
 660        DBG(__func__)
 661
 662        DAC1064_calcclock(minfo, freq, minfo->max_pixel_clock, &m, &n, &p);
 663        MGAG100_progPixClock(minfo, flags, m, n, p);
 664}
 665#endif
 666
 667#ifdef CONFIG_FB_MATROX_MYSTIQUE
 668static int MGA1064_preinit(struct matrox_fb_info *minfo)
 669{
 670        static const int vxres_mystique[] = { 512,        640, 768,  800,  832,  960,
 671                                             1024, 1152, 1280,      1600, 1664, 1920,
 672                                             2048,    0};
 673        struct matrox_hw_state *hw = &minfo->hw;
 674
 675        DBG(__func__)
 676
 677        /* minfo->capable.cfb4 = 0; ... preinitialized by 0 */
 678        minfo->capable.text = 1;
 679        minfo->capable.vxres = vxres_mystique;
 680
 681        minfo->outputs[0].output = &m1064;
 682        minfo->outputs[0].src = minfo->outputs[0].default_src;
 683        minfo->outputs[0].data = minfo;
 684        minfo->outputs[0].mode = MATROXFB_OUTPUT_MODE_MONITOR;
 685
 686        if (minfo->devflags.noinit)
 687                return 0;       /* do not modify settings */
 688        hw->MXoptionReg &= 0xC0000100;
 689        hw->MXoptionReg |= 0x00094E20;
 690        if (minfo->devflags.novga)
 691                hw->MXoptionReg &= ~0x00000100;
 692        if (minfo->devflags.nobios)
 693                hw->MXoptionReg &= ~0x40000000;
 694        if (minfo->devflags.nopciretry)
 695                hw->MXoptionReg |=  0x20000000;
 696        pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
 697        mga_setr(M_SEQ_INDEX, 0x01, 0x20);
 698        mga_outl(M_CTLWTST, 0x00000000);
 699        udelay(200);
 700        mga_outl(M_MACCESS, 0x00008000);
 701        udelay(100);
 702        mga_outl(M_MACCESS, 0x0000C000);
 703        return 0;
 704}
 705
 706static void MGA1064_reset(struct matrox_fb_info *minfo)
 707{
 708
 709        DBG(__func__);
 710
 711        MGA1064_ramdac_init(minfo);
 712}
 713#endif
 714
 715#ifdef CONFIG_FB_MATROX_G
 716static void g450_mclk_init(struct matrox_fb_info *minfo)
 717{
 718        /* switch all clocks to PCI source */
 719        pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg | 4);
 720        pci_write_config_dword(minfo->pcidev, PCI_OPTION3_REG, minfo->values.reg.opt3 & ~0x00300C03);
 721        pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg);
 722
 723        if (((minfo->values.reg.opt3 & 0x000003) == 0x000003) ||
 724            ((minfo->values.reg.opt3 & 0x000C00) == 0x000C00) ||
 725            ((minfo->values.reg.opt3 & 0x300000) == 0x300000)) {
 726                matroxfb_g450_setclk(minfo, minfo->values.pll.video, M_VIDEO_PLL);
 727        } else {
 728                unsigned long flags;
 729                unsigned int pwr;
 730                
 731                matroxfb_DAC_lock_irqsave(flags);
 732                pwr = inDAC1064(minfo, M1064_XPWRCTRL) & ~0x02;
 733                outDAC1064(minfo, M1064_XPWRCTRL, pwr);
 734                matroxfb_DAC_unlock_irqrestore(flags);
 735        }
 736        matroxfb_g450_setclk(minfo, minfo->values.pll.system, M_SYSTEM_PLL);
 737        
 738        /* switch clocks to their real PLL source(s) */
 739        pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg | 4);
 740        pci_write_config_dword(minfo->pcidev, PCI_OPTION3_REG, minfo->values.reg.opt3);
 741        pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg);
 742
 743}
 744
 745static void g450_memory_init(struct matrox_fb_info *minfo)
 746{
 747        /* disable memory refresh */
 748        minfo->hw.MXoptionReg &= ~0x001F8000;
 749        pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg);
 750        
 751        /* set memory interface parameters */
 752        minfo->hw.MXoptionReg &= ~0x00207E00;
 753        minfo->hw.MXoptionReg |= 0x00207E00 & minfo->values.reg.opt;
 754        pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg);
 755        pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, minfo->values.reg.opt2);
 756        
 757        mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst);
 758        
 759        /* first set up memory interface with disabled memory interface clocks */
 760        pci_write_config_dword(minfo->pcidev, PCI_MEMMISC_REG, minfo->values.reg.memmisc & ~0x80000000U);
 761        mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk);
 762        mga_outl(M_MACCESS, minfo->values.reg.maccess);
 763        /* start memory clocks */
 764        pci_write_config_dword(minfo->pcidev, PCI_MEMMISC_REG, minfo->values.reg.memmisc | 0x80000000U);
 765
 766        udelay(200);
 767        
 768        if (minfo->values.memory.ddr && (!minfo->values.memory.emrswen || !minfo->values.memory.dll)) {
 769                mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk & ~0x1000);
 770        }
 771        mga_outl(M_MACCESS, minfo->values.reg.maccess | 0x8000);
 772        
 773        udelay(200);
 774        
 775        minfo->hw.MXoptionReg |= 0x001F8000 & minfo->values.reg.opt;
 776        pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg);
 777        
 778        /* value is written to memory chips only if old != new */
 779        mga_outl(M_PLNWT, 0);
 780        mga_outl(M_PLNWT, ~0);
 781        
 782        if (minfo->values.reg.mctlwtst != minfo->values.reg.mctlwtst_core) {
 783                mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst_core);
 784        }
 785        
 786}
 787
 788static void g450_preinit(struct matrox_fb_info *minfo)
 789{
 790        u_int32_t c2ctl;
 791        u_int8_t curctl;
 792        u_int8_t c1ctl;
 793        
 794        /* minfo->hw.MXoptionReg = minfo->values.reg.opt; */
 795        minfo->hw.MXoptionReg &= 0xC0000100;
 796        minfo->hw.MXoptionReg |= 0x00000020;
 797        if (minfo->devflags.novga)
 798                minfo->hw.MXoptionReg &= ~0x00000100;
 799        if (minfo->devflags.nobios)
 800                minfo->hw.MXoptionReg &= ~0x40000000;
 801        if (minfo->devflags.nopciretry)
 802                minfo->hw.MXoptionReg |=  0x20000000;
 803        minfo->hw.MXoptionReg |= minfo->values.reg.opt & 0x03400040;
 804        pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg);
 805
 806        /* Init system clocks */
 807                
 808        /* stop crtc2 */
 809        c2ctl = mga_inl(M_C2CTL);
 810        mga_outl(M_C2CTL, c2ctl & ~1);
 811        /* stop cursor */
 812        curctl = inDAC1064(minfo, M1064_XCURCTRL);
 813        outDAC1064(minfo, M1064_XCURCTRL, 0);
 814        /* stop crtc1 */
 815        c1ctl = mga_readr(M_SEQ_INDEX, 1);
 816        mga_setr(M_SEQ_INDEX, 1, c1ctl | 0x20);
 817
 818        g450_mclk_init(minfo);
 819        g450_memory_init(minfo);
 820        
 821        /* set legacy VGA clock sources for DOSEmu or VMware... */
 822        matroxfb_g450_setclk(minfo, 25175, M_PIXEL_PLL_A);
 823        matroxfb_g450_setclk(minfo, 28322, M_PIXEL_PLL_B);
 824
 825        /* restore crtc1 */
 826        mga_setr(M_SEQ_INDEX, 1, c1ctl);
 827        
 828        /* restore cursor */
 829        outDAC1064(minfo, M1064_XCURCTRL, curctl);
 830
 831        /* restore crtc2 */
 832        mga_outl(M_C2CTL, c2ctl);
 833        
 834        return;
 835}
 836
 837static int MGAG100_preinit(struct matrox_fb_info *minfo)
 838{
 839        static const int vxres_g100[] = {  512,        640, 768,  800,  832,  960,
 840                                          1024, 1152, 1280,      1600, 1664, 1920,
 841                                          2048, 0};
 842        struct matrox_hw_state *hw = &minfo->hw;
 843
 844        u_int32_t reg50;
 845#if 0
 846        u_int32_t q;
 847#endif
 848
 849        DBG(__func__)
 850
 851        /* there are some instabilities if in_div > 19 && vco < 61000 */
 852        if (minfo->devflags.g450dac) {
 853                minfo->features.pll.vco_freq_min = 130000;      /* my sample: >118 */
 854        } else {
 855                minfo->features.pll.vco_freq_min = 62000;
 856        }
 857        if (!minfo->features.pll.ref_freq) {
 858                minfo->features.pll.ref_freq     = 27000;
 859        }
 860        minfo->features.pll.feed_div_min = 7;
 861        minfo->features.pll.feed_div_max = 127;
 862        minfo->features.pll.in_div_min   = 1;
 863        minfo->features.pll.in_div_max   = 31;
 864        minfo->features.pll.post_shift_max = 3;
 865        minfo->features.DAC1064.xvrefctrl = DAC1064_XVREFCTRL_G100_DEFAULT;
 866        /* minfo->capable.cfb4 = 0; ... preinitialized by 0 */
 867        minfo->capable.text = 1;
 868        minfo->capable.vxres = vxres_g100;
 869        minfo->capable.plnwt = minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG100
 870                        ? minfo->devflags.sgram : 1;
 871
 872        if (minfo->devflags.g450dac) {
 873                minfo->outputs[0].output = &g450out;
 874        } else {
 875                minfo->outputs[0].output = &m1064;
 876        }
 877        minfo->outputs[0].src = minfo->outputs[0].default_src;
 878        minfo->outputs[0].data = minfo;
 879        minfo->outputs[0].mode = MATROXFB_OUTPUT_MODE_MONITOR;
 880
 881        if (minfo->devflags.g450dac) {
 882                /* we must do this always, BIOS does not do it for us
 883                   and accelerator dies without it */
 884                mga_outl(0x1C0C, 0);
 885        }
 886        if (minfo->devflags.noinit)
 887                return 0;
 888        if (minfo->devflags.g450dac) {
 889                g450_preinit(minfo);
 890                return 0;
 891        }
 892        hw->MXoptionReg &= 0xC0000100;
 893        hw->MXoptionReg |= 0x00000020;
 894        if (minfo->devflags.novga)
 895                hw->MXoptionReg &= ~0x00000100;
 896        if (minfo->devflags.nobios)
 897                hw->MXoptionReg &= ~0x40000000;
 898        if (minfo->devflags.nopciretry)
 899                hw->MXoptionReg |=  0x20000000;
 900        pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
 901        DAC1064_setmclk(minfo, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PCI, 133333);
 902
 903        if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG100) {
 904                pci_read_config_dword(minfo->pcidev, PCI_OPTION2_REG, &reg50);
 905                reg50 &= ~0x3000;
 906                pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, reg50);
 907
 908                hw->MXoptionReg |= 0x1080;
 909                pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
 910                mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst);
 911                udelay(100);
 912                mga_outb(0x1C05, 0x00);
 913                mga_outb(0x1C05, 0x80);
 914                udelay(100);
 915                mga_outb(0x1C05, 0x40);
 916                mga_outb(0x1C05, 0xC0);
 917                udelay(100);
 918                reg50 &= ~0xFF;
 919                reg50 |=  0x07;
 920                pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, reg50);
 921                /* it should help with G100 */
 922                mga_outb(M_GRAPHICS_INDEX, 6);
 923                mga_outb(M_GRAPHICS_DATA, (mga_inb(M_GRAPHICS_DATA) & 3) | 4);
 924                mga_setr(M_EXTVGA_INDEX, 0x03, 0x81);
 925                mga_setr(M_EXTVGA_INDEX, 0x04, 0x00);
 926                mga_writeb(minfo->video.vbase, 0x0000, 0xAA);
 927                mga_writeb(minfo->video.vbase, 0x0800, 0x55);
 928                mga_writeb(minfo->video.vbase, 0x4000, 0x55);
 929#if 0
 930                if (mga_readb(minfo->video.vbase, 0x0000) != 0xAA) {
 931                        hw->MXoptionReg &= ~0x1000;
 932                }
 933#endif
 934                hw->MXoptionReg |= 0x00078020;
 935        } else if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG200) {
 936                pci_read_config_dword(minfo->pcidev, PCI_OPTION2_REG, &reg50);
 937                reg50 &= ~0x3000;
 938                pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, reg50);
 939
 940                if (minfo->devflags.memtype == -1)
 941                        hw->MXoptionReg |= minfo->values.reg.opt & 0x1C00;
 942                else
 943                        hw->MXoptionReg |= (minfo->devflags.memtype & 7) << 10;
 944                if (minfo->devflags.sgram)
 945                        hw->MXoptionReg |= 0x4000;
 946                mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst);
 947                mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk);
 948                udelay(200);
 949                mga_outl(M_MACCESS, 0x00000000);
 950                mga_outl(M_MACCESS, 0x00008000);
 951                udelay(100);
 952                mga_outw(M_MEMRDBK, minfo->values.reg.memrdbk);
 953                hw->MXoptionReg |= 0x00078020;
 954        } else {
 955                pci_read_config_dword(minfo->pcidev, PCI_OPTION2_REG, &reg50);
 956                reg50 &= ~0x00000100;
 957                reg50 |=  0x00000000;
 958                pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, reg50);
 959
 960                if (minfo->devflags.memtype == -1)
 961                        hw->MXoptionReg |= minfo->values.reg.opt & 0x1C00;
 962                else
 963                        hw->MXoptionReg |= (minfo->devflags.memtype & 7) << 10;
 964                if (minfo->devflags.sgram)
 965                        hw->MXoptionReg |= 0x4000;
 966                mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst);
 967                mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk);
 968                udelay(200);
 969                mga_outl(M_MACCESS, 0x00000000);
 970                mga_outl(M_MACCESS, 0x00008000);
 971                udelay(100);
 972                mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk);
 973                hw->MXoptionReg |= 0x00040020;
 974        }
 975        pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
 976        return 0;
 977}
 978
 979static void MGAG100_reset(struct matrox_fb_info *minfo)
 980{
 981        u_int8_t b;
 982        struct matrox_hw_state *hw = &minfo->hw;
 983
 984        DBG(__func__)
 985
 986        {
 987#ifdef G100_BROKEN_IBM_82351
 988                u_int32_t d;
 989
 990                find 1014/22 (IBM/82351); /* if found and bridging Matrox, do some strange stuff */
 991                pci_read_config_byte(ibm, PCI_SECONDARY_BUS, &b);
 992                if (b == minfo->pcidev->bus->number) {
 993                        pci_write_config_byte(ibm, PCI_COMMAND+1, 0);   /* disable back-to-back & SERR */
 994                        pci_write_config_byte(ibm, 0x41, 0xF4);         /* ??? */
 995                        pci_write_config_byte(ibm, PCI_IO_BASE, 0xF0);  /* ??? */
 996                        pci_write_config_byte(ibm, PCI_IO_LIMIT, 0x00); /* ??? */
 997                }
 998#endif
 999                if (!minfo->devflags.noinit) {
1000                        if (x7AF4 & 8) {
1001                                hw->MXoptionReg |= 0x40;        /* FIXME... */
1002                                pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
1003                        }
1004                        mga_setr(M_EXTVGA_INDEX, 0x06, 0x00);
1005                }
1006        }
1007        if (minfo->devflags.g450dac) {
1008                /* either leave MCLK as is... or they were set in preinit */
1009                hw->DACclk[3] = inDAC1064(minfo, DAC1064_XSYSPLLM);
1010                hw->DACclk[4] = inDAC1064(minfo, DAC1064_XSYSPLLN);
1011                hw->DACclk[5] = inDAC1064(minfo, DAC1064_XSYSPLLP);
1012        } else {
1013                DAC1064_setmclk(minfo, DAC1064_OPT_RESERVED | DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV1 | DAC1064_OPT_SCLK_PLL, 133333);
1014        }
1015        if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG400) {
1016                if (minfo->devflags.dfp_type == -1) {
1017                        minfo->devflags.dfp_type = inDAC1064(minfo, 0x1F);
1018                }
1019        }
1020        if (minfo->devflags.noinit)
1021                return;
1022        if (minfo->devflags.g450dac) {
1023        } else {
1024                MGAG100_setPixClock(minfo, 4, 25175);
1025                MGAG100_setPixClock(minfo, 5, 28322);
1026                if (x7AF4 & 0x10) {
1027                        b = inDAC1064(minfo, M1064_XGENIODATA) & ~1;
1028                        outDAC1064(minfo, M1064_XGENIODATA, b);
1029                        b = inDAC1064(minfo, M1064_XGENIOCTRL) | 1;
1030                        outDAC1064(minfo, M1064_XGENIOCTRL, b);
1031                }
1032        }
1033}
1034#endif
1035
1036#ifdef CONFIG_FB_MATROX_MYSTIQUE
1037static void MGA1064_restore(struct matrox_fb_info *minfo)
1038{
1039        int i;
1040        struct matrox_hw_state *hw = &minfo->hw;
1041
1042        CRITFLAGS
1043
1044        DBG(__func__)
1045
1046        CRITBEGIN
1047
1048        pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
1049        mga_outb(M_IEN, 0x00);
1050        mga_outb(M_CACHEFLUSH, 0x00);
1051
1052        CRITEND
1053
1054        DAC1064_restore_1(minfo);
1055        matroxfb_vgaHWrestore(minfo);
1056        minfo->crtc1.panpos = -1;
1057        for (i = 0; i < 6; i++)
1058                mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
1059        DAC1064_restore_2(minfo);
1060}
1061#endif
1062
1063#ifdef CONFIG_FB_MATROX_G
1064static void MGAG100_restore(struct matrox_fb_info *minfo)
1065{
1066        int i;
1067        struct matrox_hw_state *hw = &minfo->hw;
1068
1069        CRITFLAGS
1070
1071        DBG(__func__)
1072
1073        CRITBEGIN
1074
1075        pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
1076        CRITEND
1077
1078        DAC1064_restore_1(minfo);
1079        matroxfb_vgaHWrestore(minfo);
1080        if (minfo->devflags.support32MB)
1081                mga_setr(M_EXTVGA_INDEX, 8, hw->CRTCEXT[8]);
1082        minfo->crtc1.panpos = -1;
1083        for (i = 0; i < 6; i++)
1084                mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
1085        DAC1064_restore_2(minfo);
1086}
1087#endif
1088
1089#ifdef CONFIG_FB_MATROX_MYSTIQUE
1090struct matrox_switch matrox_mystique = {
1091        .preinit        = MGA1064_preinit,
1092        .reset          = MGA1064_reset,
1093        .init           = MGA1064_init,
1094        .restore        = MGA1064_restore,
1095};
1096EXPORT_SYMBOL(matrox_mystique);
1097#endif
1098
1099#ifdef CONFIG_FB_MATROX_G
1100struct matrox_switch matrox_G100 = {
1101        .preinit        = MGAG100_preinit,
1102        .reset          = MGAG100_reset,
1103        .init           = MGAG100_init,
1104        .restore        = MGAG100_restore,
1105};
1106EXPORT_SYMBOL(matrox_G100);
1107#endif
1108
1109#ifdef NEED_DAC1064
1110EXPORT_SYMBOL(DAC1064_global_init);
1111EXPORT_SYMBOL(DAC1064_global_restore);
1112#endif
1113MODULE_LICENSE("GPL");
1114