0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083 #include "matroxfb_Ti3026.h"
0084 #include "matroxfb_misc.h"
0085 #include "matroxfb_accel.h"
0086 #include <linux/matroxfb.h>
0087
0088 #ifdef CONFIG_FB_MATROX_MILLENIUM
0089 #define outTi3026 matroxfb_DAC_out
0090 #define inTi3026 matroxfb_DAC_in
0091
0092 #define TVP3026_INDEX 0x00
0093 #define TVP3026_PALWRADD 0x00
0094 #define TVP3026_PALDATA 0x01
0095 #define TVP3026_PIXRDMSK 0x02
0096 #define TVP3026_PALRDADD 0x03
0097 #define TVP3026_CURCOLWRADD 0x04
0098 #define TVP3026_CLOVERSCAN 0x00
0099 #define TVP3026_CLCOLOR0 0x01
0100 #define TVP3026_CLCOLOR1 0x02
0101 #define TVP3026_CLCOLOR2 0x03
0102 #define TVP3026_CURCOLDATA 0x05
0103 #define TVP3026_CURCOLRDADD 0x07
0104 #define TVP3026_CURCTRL 0x09
0105 #define TVP3026_X_DATAREG 0x0A
0106 #define TVP3026_CURRAMDATA 0x0B
0107 #define TVP3026_CURPOSXL 0x0C
0108 #define TVP3026_CURPOSXH 0x0D
0109 #define TVP3026_CURPOSYL 0x0E
0110 #define TVP3026_CURPOSYH 0x0F
0111
0112 #define TVP3026_XSILICONREV 0x01
0113 #define TVP3026_XCURCTRL 0x06
0114 #define TVP3026_XCURCTRL_DIS 0x00
0115 #define TVP3026_XCURCTRL_3COLOR 0x01
0116 #define TVP3026_XCURCTRL_XGA 0x02
0117 #define TVP3026_XCURCTRL_XWIN 0x03
0118 #define TVP3026_XCURCTRL_BLANK2048 0x00
0119 #define TVP3026_XCURCTRL_BLANK4096 0x10
0120 #define TVP3026_XCURCTRL_INTERLACED 0x20
0121 #define TVP3026_XCURCTRL_ODD 0x00
0122 #define TVP3026_XCURCTRL_EVEN 0x40
0123 #define TVP3026_XCURCTRL_INDIRECT 0x00
0124 #define TVP3026_XCURCTRL_DIRECT 0x80
0125 #define TVP3026_XLATCHCTRL 0x0F
0126 #define TVP3026_XLATCHCTRL_1_1 0x06
0127 #define TVP3026_XLATCHCTRL_2_1 0x07
0128 #define TVP3026_XLATCHCTRL_4_1 0x06
0129 #define TVP3026_XLATCHCTRL_8_1 0x06
0130 #define TVP3026_XLATCHCTRL_16_1 0x06
0131 #define TVP3026A_XLATCHCTRL_4_3 0x06
0132 #define TVP3026A_XLATCHCTRL_8_3 0x07
0133 #define TVP3026B_XLATCHCTRL_4_3 0x08
0134 #define TVP3026B_XLATCHCTRL_8_3 0x06
0135 #define TVP3026_XTRUECOLORCTRL 0x18
0136 #define TVP3026_XTRUECOLORCTRL_VRAM_SHIFT_ACCEL 0x00
0137 #define TVP3026_XTRUECOLORCTRL_VRAM_SHIFT_TVP 0x20
0138 #define TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR 0x80
0139 #define TVP3026_XTRUECOLORCTRL_TRUECOLOR 0x40
0140 #define TVP3026_XTRUECOLORCTRL_DIRECTCOLOR 0x00
0141 #define TVP3026_XTRUECOLORCTRL_24_ALTERNATE 0x08
0142 #define TVP3026_XTRUECOLORCTRL_RGB_888 0x16
0143 #define TVP3026_XTRUECOLORCTRL_BGR_888 0x17
0144 #define TVP3026_XTRUECOLORCTRL_ORGB_8888 0x06
0145 #define TVP3026_XTRUECOLORCTRL_BGRO_8888 0x07
0146 #define TVP3026_XTRUECOLORCTRL_RGB_565 0x05
0147 #define TVP3026_XTRUECOLORCTRL_ORGB_1555 0x04
0148 #define TVP3026_XTRUECOLORCTRL_RGB_664 0x03
0149 #define TVP3026_XTRUECOLORCTRL_RGBO_4444 0x01
0150 #define TVP3026_XMUXCTRL 0x19
0151 #define TVP3026_XMUXCTRL_MEMORY_8BIT 0x01
0152 #define TVP3026_XMUXCTRL_MEMORY_16BIT 0x02
0153 #define TVP3026_XMUXCTRL_MEMORY_32BIT 0x03
0154 #define TVP3026_XMUXCTRL_MEMORY_64BIT 0x04
0155 #define TVP3026_XMUXCTRL_PIXEL_4BIT 0x40
0156 #define TVP3026_XMUXCTRL_PIXEL_4BIT_SWAPPED 0x60
0157 #define TVP3026_XMUXCTRL_PIXEL_8BIT 0x48
0158 #define TVP3026_XMUXCTRL_PIXEL_16BIT 0x50
0159 #define TVP3026_XMUXCTRL_PIXEL_32BIT 0x58
0160 #define TVP3026_XMUXCTRL_VGA 0x98
0161 #define TVP3026_XCLKCTRL 0x1A
0162 #define TVP3026_XCLKCTRL_DIV1 0x00
0163 #define TVP3026_XCLKCTRL_DIV2 0x10
0164 #define TVP3026_XCLKCTRL_DIV4 0x20
0165 #define TVP3026_XCLKCTRL_DIV8 0x30
0166 #define TVP3026_XCLKCTRL_DIV16 0x40
0167 #define TVP3026_XCLKCTRL_DIV32 0x50
0168 #define TVP3026_XCLKCTRL_DIV64 0x60
0169 #define TVP3026_XCLKCTRL_CLKSTOPPED 0x70
0170 #define TVP3026_XCLKCTRL_SRC_CLK0 0x00
0171 #define TVP3026_XCLKCTRL_SRC_CLK1 0x01
0172 #define TVP3026_XCLKCTRL_SRC_CLK2 0x02
0173 #define TVP3026_XCLKCTRL_SRC_NCLK2 0x03
0174 #define TVP3026_XCLKCTRL_SRC_ECLK2 0x04
0175 #define TVP3026_XCLKCTRL_SRC_PLL 0x05
0176 #define TVP3026_XCLKCTRL_SRC_DIS 0x06
0177 #define TVP3026_XCLKCTRL_SRC_CLK0VGA 0x07
0178 #define TVP3026_XPALETTEPAGE 0x1C
0179 #define TVP3026_XGENCTRL 0x1D
0180 #define TVP3026_XGENCTRL_HSYNC_POS 0x00
0181 #define TVP3026_XGENCTRL_HSYNC_NEG 0x01
0182 #define TVP3026_XGENCTRL_VSYNC_POS 0x00
0183 #define TVP3026_XGENCTRL_VSYNC_NEG 0x02
0184 #define TVP3026_XGENCTRL_LITTLE_ENDIAN 0x00
0185 #define TVP3026_XGENCTRL_BIG_ENDIAN 0x08
0186 #define TVP3026_XGENCTRL_BLACK_0IRE 0x00
0187 #define TVP3026_XGENCTRL_BLACK_75IRE 0x10
0188 #define TVP3026_XGENCTRL_NO_SYNC_ON_GREEN 0x00
0189 #define TVP3026_XGENCTRL_SYNC_ON_GREEN 0x20
0190 #define TVP3026_XGENCTRL_OVERSCAN_DIS 0x00
0191 #define TVP3026_XGENCTRL_OVERSCAN_EN 0x40
0192 #define TVP3026_XMISCCTRL 0x1E
0193 #define TVP3026_XMISCCTRL_DAC_PUP 0x00
0194 #define TVP3026_XMISCCTRL_DAC_PDOWN 0x01
0195 #define TVP3026_XMISCCTRL_DAC_EXT 0x00
0196 #define TVP3026_XMISCCTRL_DAC_6BIT 0x04
0197 #define TVP3026_XMISCCTRL_DAC_8BIT 0x0C
0198 #define TVP3026_XMISCCTRL_PSEL_DIS 0x00
0199 #define TVP3026_XMISCCTRL_PSEL_EN 0x10
0200 #define TVP3026_XMISCCTRL_PSEL_LOW 0x00
0201 #define TVP3026_XMISCCTRL_PSEL_HIGH 0x20
0202 #define TVP3026_XGENIOCTRL 0x2A
0203 #define TVP3026_XGENIODATA 0x2B
0204 #define TVP3026_XPLLADDR 0x2C
0205 #define TVP3026_XPLLADDR_X(LOOP,MCLK,PIX) (((LOOP)<<4) | ((MCLK)<<2) | (PIX))
0206 #define TVP3026_XPLLDATA_N 0x00
0207 #define TVP3026_XPLLDATA_M 0x01
0208 #define TVP3026_XPLLDATA_P 0x02
0209 #define TVP3026_XPLLDATA_STAT 0x03
0210 #define TVP3026_XPIXPLLDATA 0x2D
0211 #define TVP3026_XMEMPLLDATA 0x2E
0212 #define TVP3026_XLOOPPLLDATA 0x2F
0213 #define TVP3026_XCOLKEYOVRMIN 0x30
0214 #define TVP3026_XCOLKEYOVRMAX 0x31
0215 #define TVP3026_XCOLKEYREDMIN 0x32
0216 #define TVP3026_XCOLKEYREDMAX 0x33
0217 #define TVP3026_XCOLKEYGREENMIN 0x34
0218 #define TVP3026_XCOLKEYGREENMAX 0x35
0219 #define TVP3026_XCOLKEYBLUEMIN 0x36
0220 #define TVP3026_XCOLKEYBLUEMAX 0x37
0221 #define TVP3026_XCOLKEYCTRL 0x38
0222 #define TVP3026_XCOLKEYCTRL_OVR_EN 0x01
0223 #define TVP3026_XCOLKEYCTRL_RED_EN 0x02
0224 #define TVP3026_XCOLKEYCTRL_GREEN_EN 0x04
0225 #define TVP3026_XCOLKEYCTRL_BLUE_EN 0x08
0226 #define TVP3026_XCOLKEYCTRL_NEGATE 0x10
0227 #define TVP3026_XCOLKEYCTRL_ZOOM1 0x00
0228 #define TVP3026_XCOLKEYCTRL_ZOOM2 0x20
0229 #define TVP3026_XCOLKEYCTRL_ZOOM4 0x40
0230 #define TVP3026_XCOLKEYCTRL_ZOOM8 0x60
0231 #define TVP3026_XCOLKEYCTRL_ZOOM16 0x80
0232 #define TVP3026_XCOLKEYCTRL_ZOOM32 0xA0
0233 #define TVP3026_XMEMPLLCTRL 0x39
0234 #define TVP3026_XMEMPLLCTRL_DIV(X) (((X)-1)>>1)
0235 #define TVP3026_XMEMPLLCTRL_STROBEMKC4 0x08
0236 #define TVP3026_XMEMPLLCTRL_MCLK_DOTCLOCK 0x00
0237 #define TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL 0x10
0238 #define TVP3026_XMEMPLLCTRL_RCLK_PIXPLL 0x00
0239 #define TVP3026_XMEMPLLCTRL_RCLK_LOOPPLL 0x20
0240 #define TVP3026_XMEMPLLCTRL_RCLK_DOTDIVN 0x40
0241 #define TVP3026_XSENSETEST 0x3A
0242 #define TVP3026_XTESTMODEDATA 0x3B
0243 #define TVP3026_XCRCREML 0x3C
0244 #define TVP3026_XCRCREMH 0x3D
0245 #define TVP3026_XCRCBITSEL 0x3E
0246 #define TVP3026_XID 0x3F
0247
0248 static const unsigned char DACseq[] =
0249 { TVP3026_XLATCHCTRL, TVP3026_XTRUECOLORCTRL,
0250 TVP3026_XMUXCTRL, TVP3026_XCLKCTRL,
0251 TVP3026_XPALETTEPAGE,
0252 TVP3026_XGENCTRL,
0253 TVP3026_XMISCCTRL,
0254 TVP3026_XGENIOCTRL,
0255 TVP3026_XGENIODATA,
0256 TVP3026_XCOLKEYOVRMIN, TVP3026_XCOLKEYOVRMAX, TVP3026_XCOLKEYREDMIN, TVP3026_XCOLKEYREDMAX,
0257 TVP3026_XCOLKEYGREENMIN, TVP3026_XCOLKEYGREENMAX, TVP3026_XCOLKEYBLUEMIN, TVP3026_XCOLKEYBLUEMAX,
0258 TVP3026_XCOLKEYCTRL,
0259 TVP3026_XMEMPLLCTRL, TVP3026_XSENSETEST, TVP3026_XCURCTRL };
0260
0261 #define POS3026_XLATCHCTRL 0
0262 #define POS3026_XTRUECOLORCTRL 1
0263 #define POS3026_XMUXCTRL 2
0264 #define POS3026_XCLKCTRL 3
0265 #define POS3026_XGENCTRL 5
0266 #define POS3026_XMISCCTRL 6
0267 #define POS3026_XMEMPLLCTRL 18
0268 #define POS3026_XCURCTRL 20
0269
0270 static const unsigned char MGADACbpp32[] =
0271 { TVP3026_XLATCHCTRL_2_1, TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_ORGB_8888,
0272 0x00, TVP3026_XCLKCTRL_DIV1 | TVP3026_XCLKCTRL_SRC_PLL,
0273 0x00,
0274 TVP3026_XGENCTRL_HSYNC_POS | TVP3026_XGENCTRL_VSYNC_POS | TVP3026_XGENCTRL_LITTLE_ENDIAN | TVP3026_XGENCTRL_BLACK_0IRE | TVP3026_XGENCTRL_NO_SYNC_ON_GREEN | TVP3026_XGENCTRL_OVERSCAN_DIS,
0275 TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_8BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_HIGH,
0276 0x00,
0277 0x1E,
0278 0xFF, 0xFF, 0xFF, 0xFF,
0279 0xFF, 0xFF, 0xFF, 0xFF,
0280 TVP3026_XCOLKEYCTRL_ZOOM1,
0281 0x00, 0x00, TVP3026_XCURCTRL_DIS };
0282
0283 static int Ti3026_calcclock(const struct matrox_fb_info *minfo,
0284 unsigned int freq, unsigned int fmax, int *in,
0285 int *feed, int *post)
0286 {
0287 unsigned int fvco;
0288 unsigned int lin, lfeed, lpost;
0289
0290 DBG(__func__)
0291
0292 fvco = PLL_calcclock(minfo, freq, fmax, &lin, &lfeed, &lpost);
0293 fvco >>= (*post = lpost);
0294 *in = 64 - lin;
0295 *feed = 64 - lfeed;
0296 return fvco;
0297 }
0298
0299 static int Ti3026_setpclk(struct matrox_fb_info *minfo, int clk)
0300 {
0301 unsigned int f_pll;
0302 unsigned int pixfeed, pixin, pixpost;
0303 struct matrox_hw_state *hw = &minfo->hw;
0304
0305 DBG(__func__)
0306
0307 f_pll = Ti3026_calcclock(minfo, clk, minfo->max_pixel_clock, &pixin, &pixfeed, &pixpost);
0308
0309 hw->DACclk[0] = pixin | 0xC0;
0310 hw->DACclk[1] = pixfeed;
0311 hw->DACclk[2] = pixpost | 0xB0;
0312
0313 {
0314 unsigned int loopfeed, loopin, looppost, loopdiv, z;
0315 unsigned int Bpp;
0316
0317 Bpp = minfo->curr.final_bppShift;
0318
0319 if (minfo->fbcon.var.bits_per_pixel == 24) {
0320 loopfeed = 3;
0321 loopin = 3 * 32 / Bpp;
0322 } else {
0323 loopfeed = 4;
0324 loopin = 4 * 32 / Bpp;
0325 }
0326 z = (110000 * loopin) / (f_pll * loopfeed);
0327 loopdiv = 0;
0328 if (z < 2)
0329 looppost = 0;
0330 else if (z < 4)
0331 looppost = 1;
0332 else if (z < 8)
0333 looppost = 2;
0334 else {
0335 looppost = 3;
0336 loopdiv = z/16;
0337 }
0338 if (minfo->fbcon.var.bits_per_pixel == 24) {
0339 hw->DACclk[3] = ((65 - loopin) & 0x3F) | 0xC0;
0340 hw->DACclk[4] = (65 - loopfeed) | 0x80;
0341 if (minfo->accel.ramdac_rev > 0x20) {
0342 if (isInterleave(minfo))
0343 hw->DACreg[POS3026_XLATCHCTRL] = TVP3026B_XLATCHCTRL_8_3;
0344 else {
0345 hw->DACclk[4] &= ~0xC0;
0346 hw->DACreg[POS3026_XLATCHCTRL] = TVP3026B_XLATCHCTRL_4_3;
0347 }
0348 } else {
0349 if (isInterleave(minfo))
0350 ;
0351 else {
0352 hw->DACclk[4] ^= 0xC0;
0353 hw->DACreg[POS3026_XLATCHCTRL] = TVP3026A_XLATCHCTRL_4_3;
0354 }
0355 }
0356 hw->DACclk[5] = looppost | 0xF8;
0357 if (minfo->devflags.mga_24bpp_fix)
0358 hw->DACclk[5] ^= 0x40;
0359 } else {
0360 hw->DACclk[3] = ((65 - loopin) & 0x3F) | 0xC0;
0361 hw->DACclk[4] = 65 - loopfeed;
0362 hw->DACclk[5] = looppost | 0xF0;
0363 }
0364 hw->DACreg[POS3026_XMEMPLLCTRL] = loopdiv | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL | TVP3026_XMEMPLLCTRL_RCLK_LOOPPLL;
0365 }
0366 return 0;
0367 }
0368
0369 static int Ti3026_init(struct matrox_fb_info *minfo, struct my_timming *m)
0370 {
0371 u_int8_t muxctrl = isInterleave(minfo) ? TVP3026_XMUXCTRL_MEMORY_64BIT : TVP3026_XMUXCTRL_MEMORY_32BIT;
0372 struct matrox_hw_state *hw = &minfo->hw;
0373
0374 DBG(__func__)
0375
0376 memcpy(hw->DACreg, MGADACbpp32, sizeof(MGADACbpp32));
0377 switch (minfo->fbcon.var.bits_per_pixel) {
0378 case 4: hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_16_1;
0379 hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR;
0380 hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_4BIT;
0381 hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV8;
0382 hw->DACreg[POS3026_XMISCCTRL] = TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_8BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_LOW;
0383 break;
0384 case 8: hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_8_1;
0385 hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR;
0386 hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_8BIT;
0387 hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV4;
0388 hw->DACreg[POS3026_XMISCCTRL] = TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_8BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_LOW;
0389 break;
0390 case 16:
0391
0392 hw->DACreg[POS3026_XTRUECOLORCTRL] = (minfo->fbcon.var.green.length == 5) ? (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_ORGB_1555) : (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_RGB_565);
0393 hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_16BIT;
0394 hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV2;
0395 break;
0396 case 24:
0397
0398 hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_RGB_888;
0399 hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_32BIT;
0400 hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV4;
0401 break;
0402 case 32:
0403
0404 hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_32BIT;
0405 break;
0406 default:
0407 return 1;
0408 }
0409 if (matroxfb_vgaHWinit(minfo, m)) return 1;
0410
0411
0412 hw->MiscOutReg = 0xCB;
0413 if (m->sync & FB_SYNC_HOR_HIGH_ACT)
0414 hw->DACreg[POS3026_XGENCTRL] |= TVP3026_XGENCTRL_HSYNC_NEG;
0415 if (m->sync & FB_SYNC_VERT_HIGH_ACT)
0416 hw->DACreg[POS3026_XGENCTRL] |= TVP3026_XGENCTRL_VSYNC_NEG;
0417 if (m->sync & FB_SYNC_ON_GREEN)
0418 hw->DACreg[POS3026_XGENCTRL] |= TVP3026_XGENCTRL_SYNC_ON_GREEN;
0419
0420
0421 if (minfo->video.len < 0x400000)
0422 hw->CRTCEXT[3] |= 0x08;
0423 else if (minfo->video.len > 0x400000)
0424 hw->CRTCEXT[3] |= 0x10;
0425
0426
0427 if (m->interlaced) {
0428 hw->DACreg[POS3026_XCURCTRL] |= TVP3026_XCURCTRL_INTERLACED;
0429 }
0430 if (m->HTotal >= 1536)
0431 hw->DACreg[POS3026_XCURCTRL] |= TVP3026_XCURCTRL_BLANK4096;
0432
0433
0434 hw->MXoptionReg &= ~0x00001000;
0435 if (isInterleave(minfo)) hw->MXoptionReg |= 0x00001000;
0436
0437
0438 Ti3026_setpclk(minfo, m->pixclock);
0439 return 0;
0440 }
0441
0442 static void ti3026_setMCLK(struct matrox_fb_info *minfo, int fout)
0443 {
0444 unsigned int f_pll;
0445 unsigned int pclk_m, pclk_n, pclk_p;
0446 unsigned int mclk_m, mclk_n, mclk_p;
0447 unsigned int rfhcnt, mclk_ctl;
0448 int tmout;
0449
0450 DBG(__func__)
0451
0452 f_pll = Ti3026_calcclock(minfo, fout, minfo->max_pixel_clock, &mclk_n, &mclk_m, &mclk_p);
0453
0454
0455 outTi3026(minfo, TVP3026_XPLLADDR, 0xFC);
0456 pclk_n = inTi3026(minfo, TVP3026_XPIXPLLDATA);
0457 outTi3026(minfo, TVP3026_XPLLADDR, 0xFD);
0458 pclk_m = inTi3026(minfo, TVP3026_XPIXPLLDATA);
0459 outTi3026(minfo, TVP3026_XPLLADDR, 0xFE);
0460 pclk_p = inTi3026(minfo, TVP3026_XPIXPLLDATA);
0461
0462
0463 outTi3026(minfo, TVP3026_XPLLADDR, 0xFE);
0464 outTi3026(minfo, TVP3026_XPIXPLLDATA, 0x00);
0465
0466
0467 outTi3026(minfo, TVP3026_XPLLADDR, 0xFC);
0468 outTi3026(minfo, TVP3026_XPIXPLLDATA, mclk_n | 0xC0);
0469 outTi3026(minfo, TVP3026_XPIXPLLDATA, mclk_m);
0470 outTi3026(minfo, TVP3026_XPIXPLLDATA, mclk_p | 0xB0);
0471
0472
0473 for (tmout = 500000; tmout; tmout--) {
0474 if (inTi3026(minfo, TVP3026_XPIXPLLDATA) & 0x40)
0475 break;
0476 udelay(10);
0477 }
0478 if (!tmout)
0479 printk(KERN_ERR "matroxfb: Temporary pixel PLL not locked after 5 secs\n");
0480
0481
0482 mclk_ctl = inTi3026(minfo, TVP3026_XMEMPLLCTRL);
0483 outTi3026(minfo, TVP3026_XMEMPLLCTRL, mclk_ctl & 0xE7);
0484 outTi3026(minfo, TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_STROBEMKC4);
0485
0486
0487 outTi3026(minfo, TVP3026_XPLLADDR, 0xFB);
0488 outTi3026(minfo, TVP3026_XMEMPLLDATA, 0x00);
0489
0490
0491 outTi3026(minfo, TVP3026_XPLLADDR, 0xF3);
0492 outTi3026(minfo, TVP3026_XMEMPLLDATA, mclk_n | 0xC0);
0493 outTi3026(minfo, TVP3026_XMEMPLLDATA, mclk_m);
0494 outTi3026(minfo, TVP3026_XMEMPLLDATA, mclk_p | 0xB0);
0495
0496
0497 for (tmout = 500000; tmout; tmout--) {
0498 if (inTi3026(minfo, TVP3026_XMEMPLLDATA) & 0x40)
0499 break;
0500 udelay(10);
0501 }
0502 if (!tmout)
0503 printk(KERN_ERR "matroxfb: Memory PLL not locked after 5 secs\n");
0504
0505 f_pll = f_pll * 333 / (10000 << mclk_p);
0506 if (isMilleniumII(minfo)) {
0507 rfhcnt = (f_pll - 128) / 256;
0508 if (rfhcnt > 15)
0509 rfhcnt = 15;
0510 } else {
0511 rfhcnt = (f_pll - 64) / 128;
0512 if (rfhcnt > 15)
0513 rfhcnt = 0;
0514 }
0515 minfo->hw.MXoptionReg = (minfo->hw.MXoptionReg & ~0x000F0000) | (rfhcnt << 16);
0516 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg);
0517
0518
0519 outTi3026(minfo, TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL);
0520 outTi3026(minfo, TVP3026_XMEMPLLCTRL, (mclk_ctl ) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL | TVP3026_XMEMPLLCTRL_STROBEMKC4);
0521
0522
0523 outTi3026(minfo, TVP3026_XPLLADDR, 0xFE);
0524 outTi3026(minfo, TVP3026_XPIXPLLDATA, 0x00);
0525
0526
0527 outTi3026(minfo, TVP3026_XPLLADDR, 0xFC);
0528 outTi3026(minfo, TVP3026_XPIXPLLDATA, pclk_n);
0529 outTi3026(minfo, TVP3026_XPIXPLLDATA, pclk_m);
0530 outTi3026(minfo, TVP3026_XPIXPLLDATA, pclk_p);
0531
0532
0533 for (tmout = 500000; tmout; tmout--) {
0534 if (inTi3026(minfo, TVP3026_XPIXPLLDATA) & 0x40)
0535 break;
0536 udelay(10);
0537 }
0538 if (!tmout)
0539 printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
0540 }
0541
0542 static void ti3026_ramdac_init(struct matrox_fb_info *minfo)
0543 {
0544 DBG(__func__)
0545
0546 minfo->features.pll.vco_freq_min = 110000;
0547 minfo->features.pll.ref_freq = 114545;
0548 minfo->features.pll.feed_div_min = 2;
0549 minfo->features.pll.feed_div_max = 24;
0550 minfo->features.pll.in_div_min = 2;
0551 minfo->features.pll.in_div_max = 63;
0552 minfo->features.pll.post_shift_max = 3;
0553 if (minfo->devflags.noinit)
0554 return;
0555 ti3026_setMCLK(minfo, 60000);
0556 }
0557
0558 static void Ti3026_restore(struct matrox_fb_info *minfo)
0559 {
0560 int i;
0561 unsigned char progdac[6];
0562 struct matrox_hw_state *hw = &minfo->hw;
0563 CRITFLAGS
0564
0565 DBG(__func__)
0566
0567 #ifdef DEBUG
0568 dprintk(KERN_INFO "EXTVGA regs: ");
0569 for (i = 0; i < 6; i++)
0570 dprintk("%02X:", hw->CRTCEXT[i]);
0571 dprintk("\n");
0572 #endif
0573
0574 CRITBEGIN
0575
0576 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
0577
0578 CRITEND
0579
0580 matroxfb_vgaHWrestore(minfo);
0581
0582 CRITBEGIN
0583
0584 minfo->crtc1.panpos = -1;
0585 for (i = 0; i < 6; i++)
0586 mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
0587
0588 for (i = 0; i < 21; i++) {
0589 outTi3026(minfo, DACseq[i], hw->DACreg[i]);
0590 }
0591
0592 outTi3026(minfo, TVP3026_XPLLADDR, 0x00);
0593 progdac[0] = inTi3026(minfo, TVP3026_XPIXPLLDATA);
0594 progdac[3] = inTi3026(minfo, TVP3026_XLOOPPLLDATA);
0595 outTi3026(minfo, TVP3026_XPLLADDR, 0x15);
0596 progdac[1] = inTi3026(minfo, TVP3026_XPIXPLLDATA);
0597 progdac[4] = inTi3026(minfo, TVP3026_XLOOPPLLDATA);
0598 outTi3026(minfo, TVP3026_XPLLADDR, 0x2A);
0599 progdac[2] = inTi3026(minfo, TVP3026_XPIXPLLDATA);
0600 progdac[5] = inTi3026(minfo, TVP3026_XLOOPPLLDATA);
0601
0602 CRITEND
0603 if (memcmp(hw->DACclk, progdac, 6)) {
0604
0605
0606
0607
0608 CRITBEGIN
0609 outTi3026(minfo, TVP3026_XCLKCTRL, hw->DACreg[POS3026_XCLKCTRL]);
0610 outTi3026(minfo, TVP3026_XPLLADDR, 0x2A);
0611 outTi3026(minfo, TVP3026_XLOOPPLLDATA, 0);
0612 outTi3026(minfo, TVP3026_XPIXPLLDATA, 0);
0613
0614 outTi3026(minfo, TVP3026_XPLLADDR, 0x00);
0615 for (i = 0; i < 3; i++)
0616 outTi3026(minfo, TVP3026_XPIXPLLDATA, hw->DACclk[i]);
0617
0618 if (hw->MiscOutReg & 0x08) {
0619 int tmout;
0620 outTi3026(minfo, TVP3026_XPLLADDR, 0x3F);
0621 for (tmout = 500000; tmout; --tmout) {
0622 if (inTi3026(minfo, TVP3026_XPIXPLLDATA) & 0x40)
0623 break;
0624 udelay(10);
0625 }
0626
0627 CRITEND
0628
0629 if (!tmout)
0630 printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
0631 else
0632 dprintk(KERN_INFO "PixelPLL: %d\n", 500000-tmout);
0633 CRITBEGIN
0634 }
0635 outTi3026(minfo, TVP3026_XMEMPLLCTRL, hw->DACreg[POS3026_XMEMPLLCTRL]);
0636 outTi3026(minfo, TVP3026_XPLLADDR, 0x00);
0637 for (i = 3; i < 6; i++)
0638 outTi3026(minfo, TVP3026_XLOOPPLLDATA, hw->DACclk[i]);
0639 CRITEND
0640 if ((hw->MiscOutReg & 0x08) && ((hw->DACclk[5] & 0x80) == 0x80)) {
0641 int tmout;
0642
0643 CRITBEGIN
0644 outTi3026(minfo, TVP3026_XPLLADDR, 0x3F);
0645 for (tmout = 500000; tmout; --tmout) {
0646 if (inTi3026(minfo, TVP3026_XLOOPPLLDATA) & 0x40)
0647 break;
0648 udelay(10);
0649 }
0650 CRITEND
0651 if (!tmout)
0652 printk(KERN_ERR "matroxfb: Loop PLL not locked after 5 secs\n");
0653 else
0654 dprintk(KERN_INFO "LoopPLL: %d\n", 500000-tmout);
0655 }
0656 }
0657
0658 #ifdef DEBUG
0659 dprintk(KERN_DEBUG "3026DACregs ");
0660 for (i = 0; i < 21; i++) {
0661 dprintk("R%02X=%02X ", DACseq[i], hw->DACreg[i]);
0662 if ((i & 0x7) == 0x7) dprintk(KERN_DEBUG "continuing... ");
0663 }
0664 dprintk(KERN_DEBUG "DACclk ");
0665 for (i = 0; i < 6; i++)
0666 dprintk("C%02X=%02X ", i, hw->DACclk[i]);
0667 dprintk("\n");
0668 #endif
0669 }
0670
0671 static void Ti3026_reset(struct matrox_fb_info *minfo)
0672 {
0673 DBG(__func__)
0674
0675 ti3026_ramdac_init(minfo);
0676 }
0677
0678 static struct matrox_altout ti3026_output = {
0679 .name = "Primary output",
0680 };
0681
0682 static int Ti3026_preinit(struct matrox_fb_info *minfo)
0683 {
0684 static const int vxres_mill2[] = { 512, 640, 768, 800, 832, 960,
0685 1024, 1152, 1280, 1600, 1664, 1920,
0686 2048, 0};
0687 static const int vxres_mill1[] = { 640, 768, 800, 960,
0688 1024, 1152, 1280, 1600, 1920,
0689 2048, 0};
0690 struct matrox_hw_state *hw = &minfo->hw;
0691
0692 DBG(__func__)
0693
0694 minfo->millenium = 1;
0695 minfo->milleniumII = (minfo->pcidev->device != PCI_DEVICE_ID_MATROX_MIL);
0696 minfo->capable.cfb4 = 1;
0697 minfo->capable.text = 1;
0698 minfo->capable.vxres = isMilleniumII(minfo) ? vxres_mill2 : vxres_mill1;
0699
0700 minfo->outputs[0].data = minfo;
0701 minfo->outputs[0].output = &ti3026_output;
0702 minfo->outputs[0].src = minfo->outputs[0].default_src;
0703 minfo->outputs[0].mode = MATROXFB_OUTPUT_MODE_MONITOR;
0704
0705 if (minfo->devflags.noinit)
0706 return 0;
0707
0708 hw->MXoptionReg &= 0xC0000100;
0709 hw->MXoptionReg |= 0x002C0000;
0710 if (minfo->devflags.novga)
0711 hw->MXoptionReg &= ~0x00000100;
0712 if (minfo->devflags.nobios)
0713 hw->MXoptionReg &= ~0x40000000;
0714 if (minfo->devflags.nopciretry)
0715 hw->MXoptionReg |= 0x20000000;
0716 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, hw->MXoptionReg);
0717
0718 minfo->accel.ramdac_rev = inTi3026(minfo, TVP3026_XSILICONREV);
0719
0720 outTi3026(minfo, TVP3026_XCLKCTRL, TVP3026_XCLKCTRL_SRC_CLK0VGA | TVP3026_XCLKCTRL_CLKSTOPPED);
0721 outTi3026(minfo, TVP3026_XTRUECOLORCTRL, TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR);
0722 outTi3026(minfo, TVP3026_XMUXCTRL, TVP3026_XMUXCTRL_VGA);
0723
0724 outTi3026(minfo, TVP3026_XPLLADDR, 0x2A);
0725 outTi3026(minfo, TVP3026_XLOOPPLLDATA, 0x00);
0726 outTi3026(minfo, TVP3026_XPIXPLLDATA, 0x00);
0727
0728 mga_outb(M_MISC_REG, 0x67);
0729
0730 outTi3026(minfo, TVP3026_XMEMPLLCTRL, TVP3026_XMEMPLLCTRL_STROBEMKC4 | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL);
0731
0732 mga_outl(M_RESET, 1);
0733 udelay(250);
0734 mga_outl(M_RESET, 0);
0735 udelay(250);
0736 mga_outl(M_MACCESS, 0x00008000);
0737 udelay(10);
0738 return 0;
0739 }
0740
0741 struct matrox_switch matrox_millennium = {
0742 .preinit = Ti3026_preinit,
0743 .reset = Ti3026_reset,
0744 .init = Ti3026_init,
0745 .restore = Ti3026_restore
0746 };
0747 EXPORT_SYMBOL(matrox_millennium);
0748 #endif
0749 MODULE_LICENSE("GPL");