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 break; 301 } 302 /* Now set timming related variables... */ 303 g450_set_plls(minfo); 304 } else 305#endif 306 { 307 if (minfo->outputs[1].src == MATROXFB_SRC_CRTC1) { 308 hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_EXT; 309 hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_MAFC12; 310 } else if (minfo->outputs[1].src == MATROXFB_SRC_CRTC2) { 311 hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_C2_MAFC12; 312 } else if (minfo->outputs[2].src == MATROXFB_SRC_CRTC1) 313 hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_PANELLINK | G400_XMISCCTRL_VDO_MAFC12; 314 else 315 hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_DIS; 316 317 if (minfo->outputs[0].src != MATROXFB_SRC_NONE) 318 hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN; 319 } 320} 321 322void DAC1064_global_restore(struct matrox_fb_info *minfo) 323{ 324 struct matrox_hw_state *hw = &minfo->hw; 325 326 outDAC1064(minfo, M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]); 327 outDAC1064(minfo, M1064_XMISCCTRL, hw->DACreg[POS1064_XMISCCTRL]); 328 if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG400) { 329 outDAC1064(minfo, 0x20, 0x04); 330 outDAC1064(minfo, 0x1F, minfo->devflags.dfp_type); 331 if (minfo->devflags.g450dac) { 332 outDAC1064(minfo, M1064_XSYNCCTRL, 0xCC); 333 outDAC1064(minfo, M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]); 334 outDAC1064(minfo, M1064_XPANMODE, hw->DACreg[POS1064_XPANMODE]); 335 outDAC1064(minfo, M1064_XOUTPUTCONN, hw->DACreg[POS1064_XOUTPUTCONN]); 336 } 337 } 338} 339 340static int DAC1064_init_1(struct matrox_fb_info *minfo, struct my_timming *m) 341{ 342 struct matrox_hw_state *hw = &minfo->hw; 343 344 DBG(__func__) 345 346 memcpy(hw->DACreg, MGA1064_DAC, sizeof(MGA1064_DAC_regs)); 347 switch (minfo->fbcon.var.bits_per_pixel) { 348 /* case 4: not supported by MGA1064 DAC */ 349 case 8: 350 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_8BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED; 351 break; 352 case 16: 353 if (minfo->fbcon.var.green.length == 5) 354 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_15BPP_1BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED; 355 else 356 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_16BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED; 357 break; 358 case 24: 359 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_24BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED; 360 break; 361 case 32: 362 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_32BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED; 363 break; 364 default: 365 return 1; /* unsupported depth */ 366 } 367 hw->DACreg[POS1064_XVREFCTRL] = minfo->features.DAC1064.xvrefctrl; 368 hw->DACreg[POS1064_XGENCTRL] &= ~M1064_XGENCTRL_SYNC_ON_GREEN_MASK; 369 hw->DACreg[POS1064_XGENCTRL] |= (m->sync & FB_SYNC_ON_GREEN)?M1064_XGENCTRL_SYNC_ON_GREEN:M1064_XGENCTRL_NO_SYNC_ON_GREEN; 370 hw->DACreg[POS1064_XCURADDL] = 0; 371 hw->DACreg[POS1064_XCURADDH] = 0; 372 373 DAC1064_global_init(minfo); 374 return 0; 375} 376 377static int DAC1064_init_2(struct matrox_fb_info *minfo, struct my_timming *m) 378{ 379 struct matrox_hw_state *hw = &minfo->hw; 380 381 DBG(__func__) 382 383 if (minfo->fbcon.var.bits_per_pixel > 16) { /* 256 entries */ 384 int i; 385 386 for (i = 0; i < 256; i++) { 387 hw->DACpal[i * 3 + 0] = i; 388 hw->DACpal[i * 3 + 1] = i; 389 hw->DACpal[i * 3 + 2] = i; 390 } 391 } else if (minfo->fbcon.var.bits_per_pixel > 8) { 392 if (minfo->fbcon.var.green.length == 5) { /* 0..31, 128..159 */ 393 int i; 394 395 for (i = 0; i < 32; i++) { 396 /* with p15 == 0 */ 397 hw->DACpal[i * 3 + 0] = i << 3; 398 hw->DACpal[i * 3 + 1] = i << 3; 399 hw->DACpal[i * 3 + 2] = i << 3; 400 /* with p15 == 1 */ 401 hw->DACpal[(i + 128) * 3 + 0] = i << 3; 402 hw->DACpal[(i + 128) * 3 + 1] = i << 3; 403 hw->DACpal[(i + 128) * 3 + 2] = i << 3; 404 } 405 } else { 406 int i; 407 408 for (i = 0; i < 64; i++) { /* 0..63 */ 409 hw->DACpal[i * 3 + 0] = i << 3; 410 hw->DACpal[i * 3 + 1] = i << 2; 411 hw->DACpal[i * 3 + 2] = i << 3; 412 } 413 } 414 } else { 415 memset(hw->DACpal, 0, 768); 416 } 417 return 0; 418} 419 420static void DAC1064_restore_1(struct matrox_fb_info *minfo) 421{ 422 struct matrox_hw_state *hw = &minfo->hw; 423 424 CRITFLAGS 425 426 DBG(__func__) 427 428 CRITBEGIN 429 430 if ((inDAC1064(minfo, DAC1064_XSYSPLLM) != hw->DACclk[3]) || 431 (inDAC1064(minfo, DAC1064_XSYSPLLN) != hw->DACclk[4]) || 432 (inDAC1064(minfo, DAC1064_XSYSPLLP) != hw->DACclk[5])) { 433 outDAC1064(minfo, DAC1064_XSYSPLLM, hw->DACclk[3]); 434 outDAC1064(minfo, DAC1064_XSYSPLLN, hw->DACclk[4]); 435 outDAC1064(minfo, DAC1064_XSYSPLLP, hw->DACclk[5]); 436 } 437 { 438 unsigned int i; 439 440 for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) { 441 if ((i != POS1064_XPIXCLKCTRL) && (i != POS1064_XMISCCTRL)) 442 outDAC1064(minfo, MGA1064_DAC_regs[i], hw->DACreg[i]); 443 } 444 } 445 446 DAC1064_global_restore(minfo); 447 448 CRITEND 449}; 450 451static void DAC1064_restore_2(struct matrox_fb_info *minfo) 452{ 453#ifdef DEBUG 454 unsigned int i; 455#endif 456 457 DBG(__func__) 458 459#ifdef DEBUG 460 dprintk(KERN_DEBUG "DAC1064regs "); 461 for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) { 462 dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], minfo->hw.DACreg[i]); 463 if ((i & 0x7) == 0x7) dprintk(KERN_DEBUG "continuing... "); 464 } 465 dprintk(KERN_DEBUG "DAC1064clk "); 466 for (i = 0; i < 6; i++) 467 dprintk("C%02X=%02X ", i, minfo->hw.DACclk[i]); 468 dprintk("\n"); 469#endif 470} 471 472static int m1064_compute(void* out, struct my_timming* m) { 473#define minfo ((struct matrox_fb_info*)out) 474 { 475 int i; 476 int tmout; 477 CRITFLAGS 478 479 DAC1064_setpclk(minfo, m->pixclock); 480 481 CRITBEGIN 482 483 for (i = 0; i < 3; i++) 484 outDAC1064(minfo, M1064_XPIXPLLCM + i, minfo->hw.DACclk[i]); 485 for (tmout = 500000; tmout; tmout--) { 486 if (inDAC1064(minfo, M1064_XPIXPLLSTAT) & 0x40) 487 break; 488 udelay(10); 489 }; 490 491 CRITEND 492 493 if (!tmout) 494 printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n"); 495 } 496#undef minfo 497 return 0; 498} 499 500static struct matrox_altout m1064 = { 501 .name = "Primary output", 502 .compute = m1064_compute, 503}; 504 505#ifdef CONFIG_FB_MATROX_G 506static int g450_compute(void* out, struct my_timming* m) { 507#define minfo ((struct matrox_fb_info*)out) 508 if (m->mnp < 0) { 509 m->mnp = matroxfb_g450_setclk(minfo, m->pixclock, (m->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL); 510 if (m->mnp >= 0) { 511 m->pixclock = g450_mnp2f(minfo, m->mnp); 512 } 513 } 514#undef minfo 515 return 0; 516} 517 518static struct matrox_altout g450out = { 519 .name = "Primary output", 520 .compute = g450_compute, 521}; 522#endif 523 524#endif /* NEED_DAC1064 */ 525 526#ifdef CONFIG_FB_MATROX_MYSTIQUE 527static int MGA1064_init(struct matrox_fb_info *minfo, struct my_timming *m) 528{ 529 struct matrox_hw_state *hw = &minfo->hw; 530 531 DBG(__func__) 532 533 if (DAC1064_init_1(minfo, m)) return 1; 534 if (matroxfb_vgaHWinit(minfo, m)) return 1; 535 536 hw->MiscOutReg = 0xCB; 537 if (m->sync & FB_SYNC_HOR_HIGH_ACT) 538 hw->MiscOutReg &= ~0x40; 539 if (m->sync & FB_SYNC_VERT_HIGH_ACT) 540 hw->MiscOutReg &= ~0x80; 541 if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */ 542 hw->CRTCEXT[3] |= 0x40; 543 544 if (DAC1064_init_2(minfo, m)) return 1; 545 return 0; 546} 547#endif 548 549#ifdef CONFIG_FB_MATROX_G 550static int MGAG100_init(struct matrox_fb_info *minfo, struct my_timming *m) 551{ 552 struct matrox_hw_state *hw = &minfo->hw; 553 554 DBG(__func__) 555 556 if (DAC1064_init_1(minfo, m)) return 1; 557 hw->MXoptionReg &= ~0x2000; 558 if (matroxfb_vgaHWinit(minfo, m)) return 1; 559 560 hw->MiscOutReg = 0xEF; 561 if (m->sync & FB_SYNC_HOR_HIGH_ACT) 562 hw->MiscOutReg &= ~0x40; 563 if (m->sync & FB_SYNC_VERT_HIGH_ACT) 564 hw->MiscOutReg &= ~0x80; 565 if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */ 566 hw->CRTCEXT[3] |= 0x40; 567 568 if (DAC1064_init_2(minfo, m)) return 1; 569 return 0; 570} 571#endif /* G */ 572 573#ifdef CONFIG_FB_MATROX_MYSTIQUE 574static void MGA1064_ramdac_init(struct matrox_fb_info *minfo) 575{ 576 577 DBG(__func__) 578 579 /* minfo->features.DAC1064.vco_freq_min = 120000; */ 580 minfo->features.pll.vco_freq_min = 62000; 581 minfo->features.pll.ref_freq = 14318; 582 minfo->features.pll.feed_div_min = 100; 583 minfo->features.pll.feed_div_max = 127; 584 minfo->features.pll.in_div_min = 1; 585 minfo->features.pll.in_div_max = 31; 586 minfo->features.pll.post_shift_max = 3; 587 minfo->features.DAC1064.xvrefctrl = DAC1064_XVREFCTRL_EXTERNAL; 588 /* maybe cmdline MCLK= ?, doc says gclk=44MHz, mclk=66MHz... it was 55/83 with old values */ 589 DAC1064_setmclk(minfo, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PLL, 133333); 590} 591#endif 592 593#ifdef CONFIG_FB_MATROX_G 594/* BIOS environ */ 595static int x7AF4 = 0x10; /* flags, maybe 0x10 = SDRAM, 0x00 = SGRAM??? */ 596 /* G100 wants 0x10, G200 SGRAM does not care... */ 597 598static void MGAG100_progPixClock(const struct matrox_fb_info *minfo, int flags, 599 int m, int n, int p) 600{ 601 int reg; 602 int selClk; 603 int clk; 604 605 DBG(__func__) 606 607 outDAC1064(minfo, M1064_XPIXCLKCTRL, inDAC1064(minfo, M1064_XPIXCLKCTRL) | M1064_XPIXCLKCTRL_DIS | 608 M1064_XPIXCLKCTRL_PLL_UP); 609 switch (flags & 3) { 610 case 0: reg = M1064_XPIXPLLAM; break; 611 case 1: reg = M1064_XPIXPLLBM; break; 612 default: reg = M1064_XPIXPLLCM; break; 613 } 614 outDAC1064(minfo, reg++, m); 615 outDAC1064(minfo, reg++, n); 616 outDAC1064(minfo, reg, p); 617 selClk = mga_inb(M_MISC_REG_READ) & ~0xC; 618 /* there should be flags & 0x03 & case 0/1/else */ 619 /* and we should first select source and after that we should wait for PLL */ 620 /* and we are waiting for PLL with oscilator disabled... Is it right? */ 621 switch (flags & 0x03) { 622 case 0x00: break; 623 case 0x01: selClk |= 4; break; 624 default: selClk |= 0x0C; break; 625 } 626 mga_outb(M_MISC_REG, selClk); 627 for (clk = 500000; clk; clk--) { 628 if (inDAC1064(minfo, M1064_XPIXPLLSTAT) & 0x40) 629 break; 630 udelay(10); 631 }; 632 if (!clk) 633 printk(KERN_ERR "matroxfb: Pixel PLL%c not locked after usual time\n", (reg-M1064_XPIXPLLAM-2)/4 + 'A'); 634 selClk = inDAC1064(minfo, M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_SRC_MASK; 635 switch (flags & 0x0C) { 636 case 0x00: selClk |= M1064_XPIXCLKCTRL_SRC_PCI; break; 637 case 0x04: selClk |= M1064_XPIXCLKCTRL_SRC_PLL; break; 638 default: selClk |= M1064_XPIXCLKCTRL_SRC_EXT; break; 639 } 640 outDAC1064(minfo, M1064_XPIXCLKCTRL, selClk); 641 outDAC1064(minfo, M1064_XPIXCLKCTRL, inDAC1064(minfo, M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_DIS); 642} 643 644static void MGAG100_setPixClock(const struct matrox_fb_info *minfo, int flags, 645 int freq) 646{ 647 unsigned int m, n, p; 648 649 DBG(__func__) 650 651 DAC1064_calcclock(minfo, freq, minfo->max_pixel_clock, &m, &n, &p); 652 MGAG100_progPixClock(minfo, flags, m, n, p); 653} 654#endif 655 656#ifdef CONFIG_FB_MATROX_MYSTIQUE 657static int MGA1064_preinit(struct matrox_fb_info *minfo) 658{ 659 static const int vxres_mystique[] = { 512, 640, 768, 800, 832, 960, 660 1024, 1152, 1280, 1600, 1664, 1920, 661 2048, 0}; 662 struct matrox_hw_state *hw = &minfo->hw; 663 664 DBG(__func__) 665 666 /* minfo->capable.cfb4 = 0; ... preinitialized by 0 */ 667 minfo->capable.text = 1; 668 minfo->capable.vxres = vxres_mystique; 669 670 minfo->outputs[0].output = &m1064; 671 minfo->outputs[0].src = minfo->outputs[0].default_src; 672 minfo->outputs[0].data = minfo; 673 minfo->outputs[0].mode = MATROXFB_OUTPUT_MODE_MONITOR; 674 675 if (minfo->devflags.noinit) 676 return 0; /* do not modify settings */ 677 hw->MXoptionReg &= 0xC0000100; 678 hw->MXoptionReg |= 0x00094E20; 679 if (minfo->devflags.novga) 680 hw->MXoptionReg &= ~0x00000100; 681 if (minfo->devflags.nobios) 682 hw->MXoptionReg &= ~0x40000000; 683 if (minfo->devflags.nopciretry) 684 hw->MXoptionReg |= 0x20000000; 685 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg); 686 mga_setr(M_SEQ_INDEX, 0x01, 0x20); 687 mga_outl(M_CTLWTST, 0x00000000); 688 udelay(200); 689 mga_outl(M_MACCESS, 0x00008000); 690 udelay(100); 691 mga_outl(M_MACCESS, 0x0000C000); 692 return 0; 693} 694 695static void MGA1064_reset(struct matrox_fb_info *minfo) 696{ 697 698 DBG(__func__); 699 700 MGA1064_ramdac_init(minfo); 701} 702#endif 703 704#ifdef CONFIG_FB_MATROX_G 705static void g450_mclk_init(struct matrox_fb_info *minfo) 706{ 707 /* switch all clocks to PCI source */ 708 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg | 4); 709 pci_write_config_dword(minfo->pcidev, PCI_OPTION3_REG, minfo->values.reg.opt3 & ~0x00300C03); 710 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg); 711 712 if (((minfo->values.reg.opt3 & 0x000003) == 0x000003) || 713 ((minfo->values.reg.opt3 & 0x000C00) == 0x000C00) || 714 ((minfo->values.reg.opt3 & 0x300000) == 0x300000)) { 715 matroxfb_g450_setclk(minfo, minfo->values.pll.video, M_VIDEO_PLL); 716 } else { 717 unsigned long flags; 718 unsigned int pwr; 719 720 matroxfb_DAC_lock_irqsave(flags); 721 pwr = inDAC1064(minfo, M1064_XPWRCTRL) & ~0x02; 722 outDAC1064(minfo, M1064_XPWRCTRL, pwr); 723 matroxfb_DAC_unlock_irqrestore(flags); 724 } 725 matroxfb_g450_setclk(minfo, minfo->values.pll.system, M_SYSTEM_PLL); 726 727 /* switch clocks to their real PLL source(s) */ 728 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg | 4); 729 pci_write_config_dword(minfo->pcidev, PCI_OPTION3_REG, minfo->values.reg.opt3); 730 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg); 731 732} 733 734static void g450_memory_init(struct matrox_fb_info *minfo) 735{ 736 /* disable memory refresh */ 737 minfo->hw.MXoptionReg &= ~0x001F8000; 738 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg); 739 740 /* set memory interface parameters */ 741 minfo->hw.MXoptionReg &= ~0x00207E00; 742 minfo->hw.MXoptionReg |= 0x00207E00 & minfo->values.reg.opt; 743 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg); 744 pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, minfo->values.reg.opt2); 745 746 mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst); 747 748 /* first set up memory interface with disabled memory interface clocks */ 749 pci_write_config_dword(minfo->pcidev, PCI_MEMMISC_REG, minfo->values.reg.memmisc & ~0x80000000U); 750 mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk); 751 mga_outl(M_MACCESS, minfo->values.reg.maccess); 752 /* start memory clocks */ 753 pci_write_config_dword(minfo->pcidev, PCI_MEMMISC_REG, minfo->values.reg.memmisc | 0x80000000U); 754 755 udelay(200); 756 757 if (minfo->values.memory.ddr && (!minfo->values.memory.emrswen || !minfo->values.memory.dll)) { 758 mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk & ~0x1000); 759 } 760 mga_outl(M_MACCESS, minfo->values.reg.maccess | 0x8000); 761 762 udelay(200); 763 764 minfo->hw.MXoptionReg |= 0x001F8000 & minfo->values.reg.opt; 765 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg); 766 767 /* value is written to memory chips only if old != new */ 768 mga_outl(M_PLNWT, 0); 769 mga_outl(M_PLNWT, ~0); 770 771 if (minfo->values.reg.mctlwtst != minfo->values.reg.mctlwtst_core) { 772 mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst_core); 773 } 774 775} 776 777static void g450_preinit(struct matrox_fb_info *minfo) 778{ 779 u_int32_t c2ctl; 780 u_int8_t curctl; 781 u_int8_t c1ctl; 782 783 /* minfo->hw.MXoptionReg = minfo->values.reg.opt; */ 784 minfo->hw.MXoptionReg &= 0xC0000100; 785 minfo->hw.MXoptionReg |= 0x00000020; 786 if (minfo->devflags.novga) 787 minfo->hw.MXoptionReg &= ~0x00000100; 788 if (minfo->devflags.nobios) 789 minfo->hw.MXoptionReg &= ~0x40000000; 790 if (minfo->devflags.nopciretry) 791 minfo->hw.MXoptionReg |= 0x20000000; 792 minfo->hw.MXoptionReg |= minfo->values.reg.opt & 0x03400040; 793 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg); 794 795 /* Init system clocks */ 796 797 /* stop crtc2 */ 798 c2ctl = mga_inl(M_C2CTL); 799 mga_outl(M_C2CTL, c2ctl & ~1); 800 /* stop cursor */ 801 curctl = inDAC1064(minfo, M1064_XCURCTRL); 802 outDAC1064(minfo, M1064_XCURCTRL, 0); 803 /* stop crtc1 */ 804 c1ctl = mga_readr(M_SEQ_INDEX, 1); 805 mga_setr(M_SEQ_INDEX, 1, c1ctl | 0x20); 806 807 g450_mclk_init(minfo); 808 g450_memory_init(minfo); 809 810 /* set legacy VGA clock sources for DOSEmu or VMware... */ 811 matroxfb_g450_setclk(minfo, 25175, M_PIXEL_PLL_A); 812 matroxfb_g450_setclk(minfo, 28322, M_PIXEL_PLL_B); 813 814 /* restore crtc1 */ 815 mga_setr(M_SEQ_INDEX, 1, c1ctl); 816 817 /* restore cursor */ 818 outDAC1064(minfo, M1064_XCURCTRL, curctl); 819 820 /* restore crtc2 */ 821 mga_outl(M_C2CTL, c2ctl); 822 823 return; 824} 825 826static int MGAG100_preinit(struct matrox_fb_info *minfo) 827{ 828 static const int vxres_g100[] = { 512, 640, 768, 800, 832, 960, 829 1024, 1152, 1280, 1600, 1664, 1920, 830 2048, 0}; 831 struct matrox_hw_state *hw = &minfo->hw; 832 833 u_int32_t reg50; 834 835 DBG(__func__) 836 837 /* there are some instabilities if in_div > 19 && vco < 61000 */ 838 if (minfo->devflags.g450dac) { 839 minfo->features.pll.vco_freq_min = 130000; /* my sample: >118 */ 840 } else { 841 minfo->features.pll.vco_freq_min = 62000; 842 } 843 if (!minfo->features.pll.ref_freq) { 844 minfo->features.pll.ref_freq = 27000; 845 } 846 minfo->features.pll.feed_div_min = 7; 847 minfo->features.pll.feed_div_max = 127; 848 minfo->features.pll.in_div_min = 1; 849 minfo->features.pll.in_div_max = 31; 850 minfo->features.pll.post_shift_max = 3; 851 minfo->features.DAC1064.xvrefctrl = DAC1064_XVREFCTRL_G100_DEFAULT; 852 /* minfo->capable.cfb4 = 0; ... preinitialized by 0 */ 853 minfo->capable.text = 1; 854 minfo->capable.vxres = vxres_g100; 855 minfo->capable.plnwt = minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG100 856 ? minfo->devflags.sgram : 1; 857 858#ifdef CONFIG_FB_MATROX_G 859 if (minfo->devflags.g450dac) { 860 minfo->outputs[0].output = &g450out; 861 } else 862#endif 863 { 864 minfo->outputs[0].output = &m1064; 865 } 866 minfo->outputs[0].src = minfo->outputs[0].default_src; 867 minfo->outputs[0].data = minfo; 868 minfo->outputs[0].mode = MATROXFB_OUTPUT_MODE_MONITOR; 869 870 if (minfo->devflags.g450dac) { 871 /* we must do this always, BIOS does not do it for us 872 and accelerator dies without it */ 873 mga_outl(0x1C0C, 0); 874 } 875 if (minfo->devflags.noinit) 876 return 0; 877 if (minfo->devflags.g450dac) { 878 g450_preinit(minfo); 879 return 0; 880 } 881 hw->MXoptionReg &= 0xC0000100; 882 hw->MXoptionReg |= 0x00000020; 883 if (minfo->devflags.novga) 884 hw->MXoptionReg &= ~0x00000100; 885 if (minfo->devflags.nobios) 886 hw->MXoptionReg &= ~0x40000000; 887 if (minfo->devflags.nopciretry) 888 hw->MXoptionReg |= 0x20000000; 889 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg); 890 DAC1064_setmclk(minfo, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PCI, 133333); 891 892 if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG100) { 893 pci_read_config_dword(minfo->pcidev, PCI_OPTION2_REG, ®50); 894 reg50 &= ~0x3000; 895 pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, reg50); 896 897 hw->MXoptionReg |= 0x1080; 898 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg); 899 mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst); 900 udelay(100); 901 mga_outb(0x1C05, 0x00); 902 mga_outb(0x1C05, 0x80); 903 udelay(100); 904 mga_outb(0x1C05, 0x40); 905 mga_outb(0x1C05, 0xC0); 906 udelay(100); 907 reg50 &= ~0xFF; 908 reg50 |= 0x07; 909 pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, reg50); 910 /* it should help with G100 */ 911 mga_outb(M_GRAPHICS_INDEX, 6); 912 mga_outb(M_GRAPHICS_DATA, (mga_inb(M_GRAPHICS_DATA) & 3) | 4); 913 mga_setr(M_EXTVGA_INDEX, 0x03, 0x81); 914 mga_setr(M_EXTVGA_INDEX, 0x04, 0x00); 915 mga_writeb(minfo->video.vbase, 0x0000, 0xAA); 916 mga_writeb(minfo->video.vbase, 0x0800, 0x55); 917 mga_writeb(minfo->video.vbase, 0x4000, 0x55); 918 hw->MXoptionReg |= 0x00078020; 919 } else if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG200) { 920 pci_read_config_dword(minfo->pcidev, PCI_OPTION2_REG, ®50); 921 reg50 &= ~0x3000; 922 pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, reg50); 923 924 if (minfo->devflags.memtype == -1) 925 hw->MXoptionReg |= minfo->values.reg.opt & 0x1C00; 926 else 927 hw->MXoptionReg |= (minfo->devflags.memtype & 7) << 10; 928 if (minfo->devflags.sgram) 929 hw->MXoptionReg |= 0x4000; 930 mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst); 931 mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk); 932 udelay(200); 933 mga_outl(M_MACCESS, 0x00000000); 934 mga_outl(M_MACCESS, 0x00008000); 935 udelay(100); 936 mga_outw(M_MEMRDBK, minfo->values.reg.memrdbk); 937 hw->MXoptionReg |= 0x00078020; 938 } else { 939 pci_read_config_dword(minfo->pcidev, PCI_OPTION2_REG, ®50); 940 reg50 &= ~0x00000100; 941 reg50 |= 0x00000000; 942 pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, reg50); 943 944 if (minfo->devflags.memtype == -1) 945 hw->MXoptionReg |= minfo->values.reg.opt & 0x1C00; 946 else 947 hw->MXoptionReg |= (minfo->devflags.memtype & 7) << 10; 948 if (minfo->devflags.sgram) 949 hw->MXoptionReg |= 0x4000; 950 mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst); 951 mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk); 952 udelay(200); 953 mga_outl(M_MACCESS, 0x00000000); 954 mga_outl(M_MACCESS, 0x00008000); 955 udelay(100); 956 mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk); 957 hw->MXoptionReg |= 0x00040020; 958 } 959 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg); 960 return 0; 961} 962 963static void MGAG100_reset(struct matrox_fb_info *minfo) 964{ 965 u_int8_t b; 966 struct matrox_hw_state *hw = &minfo->hw; 967 968 DBG(__func__) 969 970 { 971#ifdef G100_BROKEN_IBM_82351 972 u_int32_t d; 973 974 find 1014/22 (IBM/82351); /* if found and bridging Matrox, do some strange stuff */ 975 pci_read_config_byte(ibm, PCI_SECONDARY_BUS, &b); 976 if (b == minfo->pcidev->bus->number) { 977 pci_write_config_byte(ibm, PCI_COMMAND+1, 0); /* disable back-to-back & SERR */ 978 pci_write_config_byte(ibm, 0x41, 0xF4); /* ??? */ 979 pci_write_config_byte(ibm, PCI_IO_BASE, 0xF0); /* ??? */ 980 pci_write_config_byte(ibm, PCI_IO_LIMIT, 0x00); /* ??? */ 981 } 982#endif 983 if (!minfo->devflags.noinit) { 984 if (x7AF4 & 8) { 985 hw->MXoptionReg |= 0x40; 986 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg); 987 } 988 mga_setr(M_EXTVGA_INDEX, 0x06, 0x00); 989 } 990 } 991 if (minfo->devflags.g450dac) { 992 /* either leave MCLK as is... or they were set in preinit */ 993 hw->DACclk[3] = inDAC1064(minfo, DAC1064_XSYSPLLM); 994 hw->DACclk[4] = inDAC1064(minfo, DAC1064_XSYSPLLN); 995 hw->DACclk[5] = inDAC1064(minfo, DAC1064_XSYSPLLP); 996 } else { 997 DAC1064_setmclk(minfo, DAC1064_OPT_RESERVED | DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV1 | DAC1064_OPT_SCLK_PLL, 133333); 998 } 999 if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG400) { 1000 if (minfo->devflags.dfp_type == -1) { 1001 minfo->devflags.dfp_type = inDAC1064(minfo, 0x1F); 1002 } 1003 } 1004 if (minfo->devflags.noinit) 1005 return; 1006 if (minfo->devflags.g450dac) { 1007 } else { 1008 MGAG100_setPixClock(minfo, 4, 25175); 1009 MGAG100_setPixClock(minfo, 5, 28322); 1010 if (x7AF4 & 0x10) { 1011 b = inDAC1064(minfo, M1064_XGENIODATA) & ~1; 1012 outDAC1064(minfo, M1064_XGENIODATA, b); 1013 b = inDAC1064(minfo, M1064_XGENIOCTRL) | 1; 1014 outDAC1064(minfo, M1064_XGENIOCTRL, b); 1015 } 1016 } 1017} 1018#endif 1019 1020#ifdef CONFIG_FB_MATROX_MYSTIQUE 1021static void MGA1064_restore(struct matrox_fb_info *minfo) 1022{ 1023 int i; 1024 struct matrox_hw_state *hw = &minfo->hw; 1025 1026 CRITFLAGS 1027 1028 DBG(__func__) 1029 1030 CRITBEGIN 1031 1032 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg); 1033 mga_outb(M_IEN, 0x00); 1034 mga_outb(M_CACHEFLUSH, 0x00); 1035 1036 CRITEND 1037 1038 DAC1064_restore_1(minfo); 1039 matroxfb_vgaHWrestore(minfo); 1040 minfo->crtc1.panpos = -1; 1041 for (i = 0; i < 6; i++) 1042 mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]); 1043 DAC1064_restore_2(minfo); 1044} 1045#endif 1046 1047#ifdef CONFIG_FB_MATROX_G 1048static void MGAG100_restore(struct matrox_fb_info *minfo) 1049{ 1050 int i; 1051 struct matrox_hw_state *hw = &minfo->hw; 1052 1053 CRITFLAGS 1054 1055 DBG(__func__) 1056 1057 CRITBEGIN 1058 1059 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg); 1060 CRITEND 1061 1062 DAC1064_restore_1(minfo); 1063 matroxfb_vgaHWrestore(minfo); 1064 if (minfo->devflags.support32MB) 1065 mga_setr(M_EXTVGA_INDEX, 8, hw->CRTCEXT[8]); 1066 minfo->crtc1.panpos = -1; 1067 for (i = 0; i < 6; i++) 1068 mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]); 1069 DAC1064_restore_2(minfo); 1070} 1071#endif 1072 1073#ifdef CONFIG_FB_MATROX_MYSTIQUE 1074struct matrox_switch matrox_mystique = { 1075 MGA1064_preinit, MGA1064_reset, MGA1064_init, MGA1064_restore, 1076}; 1077EXPORT_SYMBOL(matrox_mystique); 1078#endif 1079 1080#ifdef CONFIG_FB_MATROX_G 1081struct matrox_switch matrox_G100 = { 1082 MGAG100_preinit, MGAG100_reset, MGAG100_init, MGAG100_restore, 1083}; 1084EXPORT_SYMBOL(matrox_G100); 1085#endif 1086 1087#ifdef NEED_DAC1064 1088EXPORT_SYMBOL(DAC1064_global_init); 1089EXPORT_SYMBOL(DAC1064_global_restore); 1090#endif 1091MODULE_LICENSE("GPL"); 1092