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