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
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103 #include <linux/version.h>
0104
0105 #include "matroxfb_base.h"
0106 #include "matroxfb_misc.h"
0107 #include "matroxfb_accel.h"
0108 #include "matroxfb_DAC1064.h"
0109 #include "matroxfb_Ti3026.h"
0110 #include "matroxfb_maven.h"
0111 #include "matroxfb_crtc2.h"
0112 #include "matroxfb_g450.h"
0113 #include <linux/matroxfb.h>
0114 #include <linux/interrupt.h>
0115 #include <linux/nvram.h>
0116 #include <linux/slab.h>
0117 #include <linux/uaccess.h>
0118
0119 #ifdef CONFIG_PPC_PMAC
0120 #include <asm/machdep.h>
0121 static int default_vmode = VMODE_NVRAM;
0122 static int default_cmode = CMODE_NVRAM;
0123 #endif
0124
0125 static void matroxfb_unregister_device(struct matrox_fb_info* minfo);
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135 static struct fb_var_screeninfo vesafb_defined = {
0136 640,480,640,480,
0137 0,0,
0138 8,
0139 0,
0140 {0,0,0},
0141 {0,0,0},
0142 {0,0,0},
0143 {0,0,0},
0144 0,
0145 FB_ACTIVATE_NOW,
0146 -1,-1,
0147 FB_ACCELF_TEXT,
0148 39721L,48L,16L,33L,10L,
0149 96L,2L,~0,
0150 FB_VMODE_NONINTERLACED,
0151 };
0152
0153
0154
0155
0156 static void update_crtc2(struct matrox_fb_info *minfo, unsigned int pos)
0157 {
0158 struct matroxfb_dh_fb_info *info = minfo->crtc2.info;
0159
0160
0161 if (info && (info->fbcon.var.bits_per_pixel == minfo->fbcon.var.bits_per_pixel)
0162 && (info->fbcon.var.xres_virtual == minfo->fbcon.var.xres_virtual)
0163 && (info->fbcon.var.green.length == minfo->fbcon.var.green.length)
0164 ) {
0165 switch (minfo->fbcon.var.bits_per_pixel) {
0166 case 16:
0167 case 32:
0168 pos = pos * 8;
0169 if (info->interlaced) {
0170 mga_outl(0x3C2C, pos);
0171 mga_outl(0x3C28, pos + minfo->fbcon.var.xres_virtual * minfo->fbcon.var.bits_per_pixel / 8);
0172 } else {
0173 mga_outl(0x3C28, pos);
0174 }
0175 break;
0176 }
0177 }
0178 }
0179
0180 static void matroxfb_crtc1_panpos(struct matrox_fb_info *minfo)
0181 {
0182 if (minfo->crtc1.panpos >= 0) {
0183 unsigned long flags;
0184 int panpos;
0185
0186 matroxfb_DAC_lock_irqsave(flags);
0187 panpos = minfo->crtc1.panpos;
0188 if (panpos >= 0) {
0189 unsigned int extvga_reg;
0190
0191 minfo->crtc1.panpos = -1;
0192 extvga_reg = mga_inb(M_EXTVGA_INDEX);
0193 mga_setr(M_EXTVGA_INDEX, 0x00, panpos);
0194 if (extvga_reg != 0x00) {
0195 mga_outb(M_EXTVGA_INDEX, extvga_reg);
0196 }
0197 }
0198 matroxfb_DAC_unlock_irqrestore(flags);
0199 }
0200 }
0201
0202 static irqreturn_t matrox_irq(int irq, void *dev_id)
0203 {
0204 u_int32_t status;
0205 int handled = 0;
0206 struct matrox_fb_info *minfo = dev_id;
0207
0208 status = mga_inl(M_STATUS);
0209
0210 if (status & 0x20) {
0211 mga_outl(M_ICLEAR, 0x20);
0212 minfo->crtc1.vsync.cnt++;
0213 matroxfb_crtc1_panpos(minfo);
0214 wake_up_interruptible(&minfo->crtc1.vsync.wait);
0215 handled = 1;
0216 }
0217 if (status & 0x200) {
0218 mga_outl(M_ICLEAR, 0x200);
0219 minfo->crtc2.vsync.cnt++;
0220 wake_up_interruptible(&minfo->crtc2.vsync.wait);
0221 handled = 1;
0222 }
0223 return IRQ_RETVAL(handled);
0224 }
0225
0226 int matroxfb_enable_irq(struct matrox_fb_info *minfo, int reenable)
0227 {
0228 u_int32_t bm;
0229
0230 if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG400)
0231 bm = 0x220;
0232 else
0233 bm = 0x020;
0234
0235 if (!test_and_set_bit(0, &minfo->irq_flags)) {
0236 if (request_irq(minfo->pcidev->irq, matrox_irq,
0237 IRQF_SHARED, "matroxfb", minfo)) {
0238 clear_bit(0, &minfo->irq_flags);
0239 return -EINVAL;
0240 }
0241
0242 mga_outl(M_ICLEAR, bm);
0243 mga_outl(M_IEN, mga_inl(M_IEN) | bm);
0244 } else if (reenable) {
0245 u_int32_t ien;
0246
0247 ien = mga_inl(M_IEN);
0248 if ((ien & bm) != bm) {
0249 printk(KERN_DEBUG "matroxfb: someone disabled IRQ [%08X]\n", ien);
0250 mga_outl(M_IEN, ien | bm);
0251 }
0252 }
0253 return 0;
0254 }
0255
0256 static void matroxfb_disable_irq(struct matrox_fb_info *minfo)
0257 {
0258 if (test_and_clear_bit(0, &minfo->irq_flags)) {
0259
0260 matroxfb_crtc1_panpos(minfo);
0261 if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG400)
0262 mga_outl(M_IEN, mga_inl(M_IEN) & ~0x220);
0263 else
0264 mga_outl(M_IEN, mga_inl(M_IEN) & ~0x20);
0265 free_irq(minfo->pcidev->irq, minfo);
0266 }
0267 }
0268
0269 int matroxfb_wait_for_sync(struct matrox_fb_info *minfo, u_int32_t crtc)
0270 {
0271 struct matrox_vsync *vs;
0272 unsigned int cnt;
0273 int ret;
0274
0275 switch (crtc) {
0276 case 0:
0277 vs = &minfo->crtc1.vsync;
0278 break;
0279 case 1:
0280 if (minfo->devflags.accelerator != FB_ACCEL_MATROX_MGAG400) {
0281 return -ENODEV;
0282 }
0283 vs = &minfo->crtc2.vsync;
0284 break;
0285 default:
0286 return -ENODEV;
0287 }
0288 ret = matroxfb_enable_irq(minfo, 0);
0289 if (ret) {
0290 return ret;
0291 }
0292
0293 cnt = vs->cnt;
0294 ret = wait_event_interruptible_timeout(vs->wait, cnt != vs->cnt, HZ/10);
0295 if (ret < 0) {
0296 return ret;
0297 }
0298 if (ret == 0) {
0299 matroxfb_enable_irq(minfo, 1);
0300 return -ETIMEDOUT;
0301 }
0302 return 0;
0303 }
0304
0305
0306
0307 static void matrox_pan_var(struct matrox_fb_info *minfo,
0308 struct fb_var_screeninfo *var)
0309 {
0310 unsigned int pos;
0311 unsigned short p0, p1, p2;
0312 unsigned int p3;
0313 int vbl;
0314 unsigned long flags;
0315
0316 CRITFLAGS
0317
0318 DBG(__func__)
0319
0320 if (minfo->dead)
0321 return;
0322
0323 minfo->fbcon.var.xoffset = var->xoffset;
0324 minfo->fbcon.var.yoffset = var->yoffset;
0325 pos = (minfo->fbcon.var.yoffset * minfo->fbcon.var.xres_virtual + minfo->fbcon.var.xoffset) * minfo->curr.final_bppShift / 32;
0326 pos += minfo->curr.ydstorg.chunks;
0327 p0 = minfo->hw.CRTC[0x0D] = pos & 0xFF;
0328 p1 = minfo->hw.CRTC[0x0C] = (pos & 0xFF00) >> 8;
0329 p2 = minfo->hw.CRTCEXT[0] = (minfo->hw.CRTCEXT[0] & 0xB0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40);
0330 p3 = minfo->hw.CRTCEXT[8] = pos >> 21;
0331
0332
0333 vbl = (var->activate & FB_ACTIVATE_VBL) && (matroxfb_enable_irq(minfo, 0) == 0);
0334
0335 CRITBEGIN
0336
0337 matroxfb_DAC_lock_irqsave(flags);
0338 mga_setr(M_CRTC_INDEX, 0x0D, p0);
0339 mga_setr(M_CRTC_INDEX, 0x0C, p1);
0340 if (minfo->devflags.support32MB)
0341 mga_setr(M_EXTVGA_INDEX, 0x08, p3);
0342 if (vbl) {
0343 minfo->crtc1.panpos = p2;
0344 } else {
0345
0346 minfo->crtc1.panpos = -1;
0347 mga_setr(M_EXTVGA_INDEX, 0x00, p2);
0348 }
0349 matroxfb_DAC_unlock_irqrestore(flags);
0350
0351 update_crtc2(minfo, pos);
0352
0353 CRITEND
0354 }
0355
0356 static void matroxfb_remove(struct matrox_fb_info *minfo, int dummy)
0357 {
0358
0359
0360
0361
0362
0363
0364
0365
0366 minfo->dead = 1;
0367 if (minfo->usecount) {
0368
0369 return;
0370 }
0371 matroxfb_unregister_device(minfo);
0372 unregister_framebuffer(&minfo->fbcon);
0373 matroxfb_g450_shutdown(minfo);
0374 arch_phys_wc_del(minfo->wc_cookie);
0375 iounmap(minfo->mmio.vbase.vaddr);
0376 iounmap(minfo->video.vbase.vaddr);
0377 release_mem_region(minfo->video.base, minfo->video.len_maximum);
0378 release_mem_region(minfo->mmio.base, 16384);
0379 kfree(minfo);
0380 }
0381
0382
0383
0384
0385
0386 static int matroxfb_open(struct fb_info *info, int user)
0387 {
0388 struct matrox_fb_info *minfo = info2minfo(info);
0389
0390 DBG_LOOP(__func__)
0391
0392 if (minfo->dead) {
0393 return -ENXIO;
0394 }
0395 minfo->usecount++;
0396 if (user) {
0397 minfo->userusecount++;
0398 }
0399 return(0);
0400 }
0401
0402 static int matroxfb_release(struct fb_info *info, int user)
0403 {
0404 struct matrox_fb_info *minfo = info2minfo(info);
0405
0406 DBG_LOOP(__func__)
0407
0408 if (user) {
0409 if (0 == --minfo->userusecount) {
0410 matroxfb_disable_irq(minfo);
0411 }
0412 }
0413 if (!(--minfo->usecount) && minfo->dead) {
0414 matroxfb_remove(minfo, 0);
0415 }
0416 return(0);
0417 }
0418
0419 static int matroxfb_pan_display(struct fb_var_screeninfo *var,
0420 struct fb_info* info) {
0421 struct matrox_fb_info *minfo = info2minfo(info);
0422
0423 DBG(__func__)
0424
0425 matrox_pan_var(minfo, var);
0426 return 0;
0427 }
0428
0429 static int matroxfb_get_final_bppShift(const struct matrox_fb_info *minfo,
0430 int bpp)
0431 {
0432 int bppshft2;
0433
0434 DBG(__func__)
0435
0436 bppshft2 = bpp;
0437 if (!bppshft2) {
0438 return 8;
0439 }
0440 if (isInterleave(minfo))
0441 bppshft2 >>= 1;
0442 if (minfo->devflags.video64bits)
0443 bppshft2 >>= 1;
0444 return bppshft2;
0445 }
0446
0447 static int matroxfb_test_and_set_rounding(const struct matrox_fb_info *minfo,
0448 int xres, int bpp)
0449 {
0450 int over;
0451 int rounding;
0452
0453 DBG(__func__)
0454
0455 switch (bpp) {
0456 case 0: return xres;
0457 case 4: rounding = 128;
0458 break;
0459 case 8: rounding = 64;
0460 break;
0461 case 16: rounding = 32;
0462 break;
0463 case 24: rounding = 64;
0464 break;
0465 default: rounding = 16;
0466
0467 if (minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG400)
0468 rounding = 32;
0469 break;
0470 }
0471 if (isInterleave(minfo)) {
0472 rounding *= 2;
0473 }
0474 over = xres % rounding;
0475 if (over)
0476 xres += rounding-over;
0477 return xres;
0478 }
0479
0480 static int matroxfb_pitch_adjust(const struct matrox_fb_info *minfo, int xres,
0481 int bpp)
0482 {
0483 const int* width;
0484 int xres_new;
0485
0486 DBG(__func__)
0487
0488 if (!bpp) return xres;
0489
0490 width = minfo->capable.vxres;
0491
0492 if (minfo->devflags.precise_width) {
0493 while (*width) {
0494 if ((*width >= xres) && (matroxfb_test_and_set_rounding(minfo, *width, bpp) == *width)) {
0495 break;
0496 }
0497 width++;
0498 }
0499 xres_new = *width;
0500 } else {
0501 xres_new = matroxfb_test_and_set_rounding(minfo, xres, bpp);
0502 }
0503 return xres_new;
0504 }
0505
0506 static int matroxfb_get_cmap_len(struct fb_var_screeninfo *var) {
0507
0508 DBG(__func__)
0509
0510 switch (var->bits_per_pixel) {
0511 case 4:
0512 return 16;
0513 case 8:
0514 return 256;
0515 case 16:
0516 return 16;
0517
0518 case 24:
0519 return 16;
0520
0521 case 32:
0522 return 16;
0523
0524 }
0525 return 16;
0526 }
0527
0528 static int matroxfb_decode_var(const struct matrox_fb_info *minfo,
0529 struct fb_var_screeninfo *var, int *visual,
0530 int *video_cmap_len, unsigned int* ydstorg)
0531 {
0532 struct RGBT {
0533 unsigned char bpp;
0534 struct {
0535 unsigned char offset,
0536 length;
0537 } red,
0538 green,
0539 blue,
0540 transp;
0541 signed char visual;
0542 };
0543 static const struct RGBT table[]= {
0544 { 8,{ 0,8},{0,8},{0,8},{ 0,0},MX_VISUAL_PSEUDOCOLOR},
0545 {15,{10,5},{5,5},{0,5},{15,1},MX_VISUAL_DIRECTCOLOR},
0546 {16,{11,5},{5,6},{0,5},{ 0,0},MX_VISUAL_DIRECTCOLOR},
0547 {24,{16,8},{8,8},{0,8},{ 0,0},MX_VISUAL_DIRECTCOLOR},
0548 {32,{16,8},{8,8},{0,8},{24,8},MX_VISUAL_DIRECTCOLOR}
0549 };
0550 struct RGBT const *rgbt;
0551 unsigned int bpp = var->bits_per_pixel;
0552 unsigned int vramlen;
0553 unsigned int memlen;
0554
0555 DBG(__func__)
0556
0557 switch (bpp) {
0558 case 4: if (!minfo->capable.cfb4) return -EINVAL;
0559 break;
0560 case 8: break;
0561 case 16: break;
0562 case 24: break;
0563 case 32: break;
0564 default: return -EINVAL;
0565 }
0566 *ydstorg = 0;
0567 vramlen = minfo->video.len_usable;
0568 if (var->yres_virtual < var->yres)
0569 var->yres_virtual = var->yres;
0570 if (var->xres_virtual < var->xres)
0571 var->xres_virtual = var->xres;
0572
0573 var->xres_virtual = matroxfb_pitch_adjust(minfo, var->xres_virtual, bpp);
0574 memlen = var->xres_virtual * bpp * var->yres_virtual / 8;
0575 if (memlen > vramlen) {
0576 var->yres_virtual = vramlen * 8 / (var->xres_virtual * bpp);
0577 memlen = var->xres_virtual * bpp * var->yres_virtual / 8;
0578 }
0579
0580
0581
0582 if (!minfo->capable.cross4MB && (memlen > 0x400000)) {
0583 if (bpp == 24) {
0584
0585 } else {
0586 unsigned int linelen;
0587 unsigned int m1 = linelen = var->xres_virtual * bpp / 8;
0588 unsigned int m2 = PAGE_SIZE;
0589 unsigned int max_yres;
0590
0591 while (m1) {
0592 while (m2 >= m1) m2 -= m1;
0593 swap(m1, m2);
0594 }
0595 m2 = linelen * PAGE_SIZE / m2;
0596 *ydstorg = m2 = 0x400000 % m2;
0597 max_yres = (vramlen - m2) / linelen;
0598 if (var->yres_virtual > max_yres)
0599 var->yres_virtual = max_yres;
0600 }
0601 }
0602
0603 if (var->yres_virtual > 32767)
0604 var->yres_virtual = 32767;
0605
0606
0607 if (var->yres_virtual < var->yres)
0608 var->yres = var->yres_virtual;
0609 if (var->xres_virtual < var->xres)
0610 var->xres = var->xres_virtual;
0611 if (var->xoffset + var->xres > var->xres_virtual)
0612 var->xoffset = var->xres_virtual - var->xres;
0613 if (var->yoffset + var->yres > var->yres_virtual)
0614 var->yoffset = var->yres_virtual - var->yres;
0615
0616 if (bpp == 16 && var->green.length == 5) {
0617 bpp--;
0618 }
0619
0620 for (rgbt = table; rgbt->bpp < bpp; rgbt++);
0621 #define SETCLR(clr)\
0622 var->clr.offset = rgbt->clr.offset;\
0623 var->clr.length = rgbt->clr.length
0624 SETCLR(red);
0625 SETCLR(green);
0626 SETCLR(blue);
0627 SETCLR(transp);
0628 #undef SETCLR
0629 *visual = rgbt->visual;
0630
0631 if (bpp > 8)
0632 dprintk("matroxfb: truecolor: "
0633 "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
0634 var->transp.length, var->red.length, var->green.length, var->blue.length,
0635 var->transp.offset, var->red.offset, var->green.offset, var->blue.offset);
0636
0637 *video_cmap_len = matroxfb_get_cmap_len(var);
0638 dprintk(KERN_INFO "requested %d*%d/%dbpp (%d*%d)\n", var->xres, var->yres, var->bits_per_pixel,
0639 var->xres_virtual, var->yres_virtual);
0640 return 0;
0641 }
0642
0643 static int matroxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
0644 unsigned blue, unsigned transp,
0645 struct fb_info *fb_info)
0646 {
0647 struct matrox_fb_info* minfo = container_of(fb_info, struct matrox_fb_info, fbcon);
0648
0649 DBG(__func__)
0650
0651
0652
0653
0654
0655
0656
0657
0658 if (regno >= minfo->curr.cmap_len)
0659 return 1;
0660
0661 if (minfo->fbcon.var.grayscale) {
0662
0663 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
0664 }
0665
0666 red = CNVT_TOHW(red, minfo->fbcon.var.red.length);
0667 green = CNVT_TOHW(green, minfo->fbcon.var.green.length);
0668 blue = CNVT_TOHW(blue, minfo->fbcon.var.blue.length);
0669 transp = CNVT_TOHW(transp, minfo->fbcon.var.transp.length);
0670
0671 switch (minfo->fbcon.var.bits_per_pixel) {
0672 case 4:
0673 case 8:
0674 mga_outb(M_DAC_REG, regno);
0675 mga_outb(M_DAC_VAL, red);
0676 mga_outb(M_DAC_VAL, green);
0677 mga_outb(M_DAC_VAL, blue);
0678 break;
0679 case 16:
0680 if (regno >= 16)
0681 break;
0682 {
0683 u_int16_t col =
0684 (red << minfo->fbcon.var.red.offset) |
0685 (green << minfo->fbcon.var.green.offset) |
0686 (blue << minfo->fbcon.var.blue.offset) |
0687 (transp << minfo->fbcon.var.transp.offset);
0688 minfo->cmap[regno] = col | (col << 16);
0689 }
0690 break;
0691 case 24:
0692 case 32:
0693 if (regno >= 16)
0694 break;
0695 minfo->cmap[regno] =
0696 (red << minfo->fbcon.var.red.offset) |
0697 (green << minfo->fbcon.var.green.offset) |
0698 (blue << minfo->fbcon.var.blue.offset) |
0699 (transp << minfo->fbcon.var.transp.offset);
0700 break;
0701 }
0702 return 0;
0703 }
0704
0705 static void matroxfb_init_fix(struct matrox_fb_info *minfo)
0706 {
0707 struct fb_fix_screeninfo *fix = &minfo->fbcon.fix;
0708 DBG(__func__)
0709
0710 strcpy(fix->id,"MATROX");
0711
0712 fix->xpanstep = 8;
0713 fix->ypanstep = 1;
0714 fix->ywrapstep = 0;
0715 fix->mmio_start = minfo->mmio.base;
0716 fix->mmio_len = minfo->mmio.len;
0717 fix->accel = minfo->devflags.accelerator;
0718 }
0719
0720 static void matroxfb_update_fix(struct matrox_fb_info *minfo)
0721 {
0722 struct fb_fix_screeninfo *fix = &minfo->fbcon.fix;
0723 DBG(__func__)
0724
0725 mutex_lock(&minfo->fbcon.mm_lock);
0726 fix->smem_start = minfo->video.base + minfo->curr.ydstorg.bytes;
0727 fix->smem_len = minfo->video.len_usable - minfo->curr.ydstorg.bytes;
0728 mutex_unlock(&minfo->fbcon.mm_lock);
0729 }
0730
0731 static int matroxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
0732 {
0733 int err;
0734 int visual;
0735 int cmap_len;
0736 unsigned int ydstorg;
0737 struct matrox_fb_info *minfo = info2minfo(info);
0738
0739 if (minfo->dead) {
0740 return -ENXIO;
0741 }
0742 if ((err = matroxfb_decode_var(minfo, var, &visual, &cmap_len, &ydstorg)) != 0)
0743 return err;
0744 return 0;
0745 }
0746
0747 static int matroxfb_set_par(struct fb_info *info)
0748 {
0749 int err;
0750 int visual;
0751 int cmap_len;
0752 unsigned int ydstorg;
0753 struct fb_var_screeninfo *var;
0754 struct matrox_fb_info *minfo = info2minfo(info);
0755
0756 DBG(__func__)
0757
0758 if (minfo->dead) {
0759 return -ENXIO;
0760 }
0761
0762 var = &info->var;
0763 if ((err = matroxfb_decode_var(minfo, var, &visual, &cmap_len, &ydstorg)) != 0)
0764 return err;
0765 minfo->fbcon.screen_base = vaddr_va(minfo->video.vbase) + ydstorg;
0766 matroxfb_update_fix(minfo);
0767 minfo->fbcon.fix.visual = visual;
0768 minfo->fbcon.fix.type = FB_TYPE_PACKED_PIXELS;
0769 minfo->fbcon.fix.type_aux = 0;
0770 minfo->fbcon.fix.line_length = (var->xres_virtual * var->bits_per_pixel) >> 3;
0771 {
0772 unsigned int pos;
0773
0774 minfo->curr.cmap_len = cmap_len;
0775 ydstorg += minfo->devflags.ydstorg;
0776 minfo->curr.ydstorg.bytes = ydstorg;
0777 minfo->curr.ydstorg.chunks = ydstorg >> (isInterleave(minfo) ? 3 : 2);
0778 if (var->bits_per_pixel == 4)
0779 minfo->curr.ydstorg.pixels = ydstorg;
0780 else
0781 minfo->curr.ydstorg.pixels = (ydstorg * 8) / var->bits_per_pixel;
0782 minfo->curr.final_bppShift = matroxfb_get_final_bppShift(minfo, var->bits_per_pixel);
0783 { struct my_timming mt;
0784 struct matrox_hw_state* hw;
0785 int out;
0786
0787 matroxfb_var2my(var, &mt);
0788 mt.crtc = MATROXFB_SRC_CRTC1;
0789
0790 switch (var->bits_per_pixel) {
0791 case 0: mt.delay = 31 + 0; break;
0792 case 16: mt.delay = 21 + 8; break;
0793 case 24: mt.delay = 17 + 8; break;
0794 case 32: mt.delay = 16 + 8; break;
0795 default: mt.delay = 31 + 8; break;
0796 }
0797
0798 hw = &minfo->hw;
0799
0800 down_read(&minfo->altout.lock);
0801 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
0802 if (minfo->outputs[out].src == MATROXFB_SRC_CRTC1 &&
0803 minfo->outputs[out].output->compute) {
0804 minfo->outputs[out].output->compute(minfo->outputs[out].data, &mt);
0805 }
0806 }
0807 up_read(&minfo->altout.lock);
0808 minfo->crtc1.pixclock = mt.pixclock;
0809 minfo->crtc1.mnp = mt.mnp;
0810 minfo->hw_switch->init(minfo, &mt);
0811 pos = (var->yoffset * var->xres_virtual + var->xoffset) * minfo->curr.final_bppShift / 32;
0812 pos += minfo->curr.ydstorg.chunks;
0813
0814 hw->CRTC[0x0D] = pos & 0xFF;
0815 hw->CRTC[0x0C] = (pos & 0xFF00) >> 8;
0816 hw->CRTCEXT[0] = (hw->CRTCEXT[0] & 0xF0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40);
0817 hw->CRTCEXT[8] = pos >> 21;
0818 minfo->hw_switch->restore(minfo);
0819 update_crtc2(minfo, pos);
0820 down_read(&minfo->altout.lock);
0821 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
0822 if (minfo->outputs[out].src == MATROXFB_SRC_CRTC1 &&
0823 minfo->outputs[out].output->program) {
0824 minfo->outputs[out].output->program(minfo->outputs[out].data);
0825 }
0826 }
0827 for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
0828 if (minfo->outputs[out].src == MATROXFB_SRC_CRTC1 &&
0829 minfo->outputs[out].output->start) {
0830 minfo->outputs[out].output->start(minfo->outputs[out].data);
0831 }
0832 }
0833 up_read(&minfo->altout.lock);
0834 matrox_cfbX_init(minfo);
0835 }
0836 }
0837 minfo->initialized = 1;
0838 return 0;
0839 }
0840
0841 static int matroxfb_get_vblank(struct matrox_fb_info *minfo,
0842 struct fb_vblank *vblank)
0843 {
0844 unsigned int sts1;
0845
0846 matroxfb_enable_irq(minfo, 0);
0847 memset(vblank, 0, sizeof(*vblank));
0848 vblank->flags = FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VSYNC |
0849 FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_HBLANK;
0850 sts1 = mga_inb(M_INSTS1);
0851 vblank->vcount = mga_inl(M_VCOUNT);
0852
0853
0854
0855 if (sts1 & 1)
0856 vblank->flags |= FB_VBLANK_HBLANKING;
0857 if (sts1 & 8)
0858 vblank->flags |= FB_VBLANK_VSYNCING;
0859 if (vblank->vcount >= minfo->fbcon.var.yres)
0860 vblank->flags |= FB_VBLANK_VBLANKING;
0861 if (test_bit(0, &minfo->irq_flags)) {
0862 vblank->flags |= FB_VBLANK_HAVE_COUNT;
0863
0864
0865 vblank->count = minfo->crtc1.vsync.cnt;
0866 }
0867 return 0;
0868 }
0869
0870 static struct matrox_altout panellink_output = {
0871 .name = "Panellink output",
0872 };
0873
0874 static int matroxfb_ioctl(struct fb_info *info,
0875 unsigned int cmd, unsigned long arg)
0876 {
0877 void __user *argp = (void __user *)arg;
0878 struct matrox_fb_info *minfo = info2minfo(info);
0879
0880 DBG(__func__)
0881
0882 if (minfo->dead) {
0883 return -ENXIO;
0884 }
0885
0886 switch (cmd) {
0887 case FBIOGET_VBLANK:
0888 {
0889 struct fb_vblank vblank;
0890 int err;
0891
0892 err = matroxfb_get_vblank(minfo, &vblank);
0893 if (err)
0894 return err;
0895 if (copy_to_user(argp, &vblank, sizeof(vblank)))
0896 return -EFAULT;
0897 return 0;
0898 }
0899 case FBIO_WAITFORVSYNC:
0900 {
0901 u_int32_t crt;
0902
0903 if (get_user(crt, (u_int32_t __user *)arg))
0904 return -EFAULT;
0905
0906 return matroxfb_wait_for_sync(minfo, crt);
0907 }
0908 case MATROXFB_SET_OUTPUT_MODE:
0909 {
0910 struct matroxioc_output_mode mom;
0911 struct matrox_altout *oproc;
0912 int val;
0913
0914 if (copy_from_user(&mom, argp, sizeof(mom)))
0915 return -EFAULT;
0916 if (mom.output >= MATROXFB_MAX_OUTPUTS)
0917 return -ENXIO;
0918 down_read(&minfo->altout.lock);
0919 oproc = minfo->outputs[mom.output].output;
0920 if (!oproc) {
0921 val = -ENXIO;
0922 } else if (!oproc->verifymode) {
0923 if (mom.mode == MATROXFB_OUTPUT_MODE_MONITOR) {
0924 val = 0;
0925 } else {
0926 val = -EINVAL;
0927 }
0928 } else {
0929 val = oproc->verifymode(minfo->outputs[mom.output].data, mom.mode);
0930 }
0931 if (!val) {
0932 if (minfo->outputs[mom.output].mode != mom.mode) {
0933 minfo->outputs[mom.output].mode = mom.mode;
0934 val = 1;
0935 }
0936 }
0937 up_read(&minfo->altout.lock);
0938 if (val != 1)
0939 return val;
0940 switch (minfo->outputs[mom.output].src) {
0941 case MATROXFB_SRC_CRTC1:
0942 matroxfb_set_par(info);
0943 break;
0944 case MATROXFB_SRC_CRTC2:
0945 {
0946 struct matroxfb_dh_fb_info* crtc2;
0947
0948 down_read(&minfo->crtc2.lock);
0949 crtc2 = minfo->crtc2.info;
0950 if (crtc2)
0951 crtc2->fbcon.fbops->fb_set_par(&crtc2->fbcon);
0952 up_read(&minfo->crtc2.lock);
0953 }
0954 break;
0955 }
0956 return 0;
0957 }
0958 case MATROXFB_GET_OUTPUT_MODE:
0959 {
0960 struct matroxioc_output_mode mom;
0961 struct matrox_altout *oproc;
0962 int val;
0963
0964 if (copy_from_user(&mom, argp, sizeof(mom)))
0965 return -EFAULT;
0966 if (mom.output >= MATROXFB_MAX_OUTPUTS)
0967 return -ENXIO;
0968 down_read(&minfo->altout.lock);
0969 oproc = minfo->outputs[mom.output].output;
0970 if (!oproc) {
0971 val = -ENXIO;
0972 } else {
0973 mom.mode = minfo->outputs[mom.output].mode;
0974 val = 0;
0975 }
0976 up_read(&minfo->altout.lock);
0977 if (val)
0978 return val;
0979 if (copy_to_user(argp, &mom, sizeof(mom)))
0980 return -EFAULT;
0981 return 0;
0982 }
0983 case MATROXFB_SET_OUTPUT_CONNECTION:
0984 {
0985 u_int32_t tmp;
0986 int i;
0987 int changes;
0988
0989 if (copy_from_user(&tmp, argp, sizeof(tmp)))
0990 return -EFAULT;
0991 for (i = 0; i < 32; i++) {
0992 if (tmp & (1 << i)) {
0993 if (i >= MATROXFB_MAX_OUTPUTS)
0994 return -ENXIO;
0995 if (!minfo->outputs[i].output)
0996 return -ENXIO;
0997 switch (minfo->outputs[i].src) {
0998 case MATROXFB_SRC_NONE:
0999 case MATROXFB_SRC_CRTC1:
1000 break;
1001 default:
1002 return -EBUSY;
1003 }
1004 }
1005 }
1006 if (minfo->devflags.panellink) {
1007 if (tmp & MATROXFB_OUTPUT_CONN_DFP) {
1008 if (tmp & MATROXFB_OUTPUT_CONN_SECONDARY)
1009 return -EINVAL;
1010 for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) {
1011 if (minfo->outputs[i].src == MATROXFB_SRC_CRTC2) {
1012 return -EBUSY;
1013 }
1014 }
1015 }
1016 }
1017 changes = 0;
1018 for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) {
1019 if (tmp & (1 << i)) {
1020 if (minfo->outputs[i].src != MATROXFB_SRC_CRTC1) {
1021 changes = 1;
1022 minfo->outputs[i].src = MATROXFB_SRC_CRTC1;
1023 }
1024 } else if (minfo->outputs[i].src == MATROXFB_SRC_CRTC1) {
1025 changes = 1;
1026 minfo->outputs[i].src = MATROXFB_SRC_NONE;
1027 }
1028 }
1029 if (!changes)
1030 return 0;
1031 matroxfb_set_par(info);
1032 return 0;
1033 }
1034 case MATROXFB_GET_OUTPUT_CONNECTION:
1035 {
1036 u_int32_t conn = 0;
1037 int i;
1038
1039 for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) {
1040 if (minfo->outputs[i].src == MATROXFB_SRC_CRTC1) {
1041 conn |= 1 << i;
1042 }
1043 }
1044 if (put_user(conn, (u_int32_t __user *)arg))
1045 return -EFAULT;
1046 return 0;
1047 }
1048 case MATROXFB_GET_AVAILABLE_OUTPUTS:
1049 {
1050 u_int32_t conn = 0;
1051 int i;
1052
1053 for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) {
1054 if (minfo->outputs[i].output) {
1055 switch (minfo->outputs[i].src) {
1056 case MATROXFB_SRC_NONE:
1057 case MATROXFB_SRC_CRTC1:
1058 conn |= 1 << i;
1059 break;
1060 }
1061 }
1062 }
1063 if (minfo->devflags.panellink) {
1064 if (conn & MATROXFB_OUTPUT_CONN_DFP)
1065 conn &= ~MATROXFB_OUTPUT_CONN_SECONDARY;
1066 if (conn & MATROXFB_OUTPUT_CONN_SECONDARY)
1067 conn &= ~MATROXFB_OUTPUT_CONN_DFP;
1068 }
1069 if (put_user(conn, (u_int32_t __user *)arg))
1070 return -EFAULT;
1071 return 0;
1072 }
1073 case MATROXFB_GET_ALL_OUTPUTS:
1074 {
1075 u_int32_t conn = 0;
1076 int i;
1077
1078 for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) {
1079 if (minfo->outputs[i].output) {
1080 conn |= 1 << i;
1081 }
1082 }
1083 if (put_user(conn, (u_int32_t __user *)arg))
1084 return -EFAULT;
1085 return 0;
1086 }
1087 case VIDIOC_QUERYCAP:
1088 {
1089 struct v4l2_capability r;
1090
1091 memset(&r, 0, sizeof(r));
1092 strcpy(r.driver, "matroxfb");
1093 strcpy(r.card, "Matrox");
1094 sprintf(r.bus_info, "PCI:%s", pci_name(minfo->pcidev));
1095 r.version = KERNEL_VERSION(1,0,0);
1096 r.capabilities = V4L2_CAP_VIDEO_OUTPUT;
1097 if (copy_to_user(argp, &r, sizeof(r)))
1098 return -EFAULT;
1099 return 0;
1100
1101 }
1102 case VIDIOC_QUERYCTRL:
1103 {
1104 struct v4l2_queryctrl qctrl;
1105 int err;
1106
1107 if (copy_from_user(&qctrl, argp, sizeof(qctrl)))
1108 return -EFAULT;
1109
1110 down_read(&minfo->altout.lock);
1111 if (!minfo->outputs[1].output) {
1112 err = -ENXIO;
1113 } else if (minfo->outputs[1].output->getqueryctrl) {
1114 err = minfo->outputs[1].output->getqueryctrl(minfo->outputs[1].data, &qctrl);
1115 } else {
1116 err = -EINVAL;
1117 }
1118 up_read(&minfo->altout.lock);
1119 if (err >= 0 &&
1120 copy_to_user(argp, &qctrl, sizeof(qctrl)))
1121 return -EFAULT;
1122 return err;
1123 }
1124 case VIDIOC_G_CTRL:
1125 {
1126 struct v4l2_control ctrl;
1127 int err;
1128
1129 if (copy_from_user(&ctrl, argp, sizeof(ctrl)))
1130 return -EFAULT;
1131
1132 down_read(&minfo->altout.lock);
1133 if (!minfo->outputs[1].output) {
1134 err = -ENXIO;
1135 } else if (minfo->outputs[1].output->getctrl) {
1136 err = minfo->outputs[1].output->getctrl(minfo->outputs[1].data, &ctrl);
1137 } else {
1138 err = -EINVAL;
1139 }
1140 up_read(&minfo->altout.lock);
1141 if (err >= 0 &&
1142 copy_to_user(argp, &ctrl, sizeof(ctrl)))
1143 return -EFAULT;
1144 return err;
1145 }
1146 case VIDIOC_S_CTRL:
1147 {
1148 struct v4l2_control ctrl;
1149 int err;
1150
1151 if (copy_from_user(&ctrl, argp, sizeof(ctrl)))
1152 return -EFAULT;
1153
1154 down_read(&minfo->altout.lock);
1155 if (!minfo->outputs[1].output) {
1156 err = -ENXIO;
1157 } else if (minfo->outputs[1].output->setctrl) {
1158 err = minfo->outputs[1].output->setctrl(minfo->outputs[1].data, &ctrl);
1159 } else {
1160 err = -EINVAL;
1161 }
1162 up_read(&minfo->altout.lock);
1163 return err;
1164 }
1165 }
1166 return -ENOTTY;
1167 }
1168
1169
1170
1171 static int matroxfb_blank(int blank, struct fb_info *info)
1172 {
1173 int seq;
1174 int crtc;
1175 CRITFLAGS
1176 struct matrox_fb_info *minfo = info2minfo(info);
1177
1178 DBG(__func__)
1179
1180 if (minfo->dead)
1181 return 1;
1182
1183 switch (blank) {
1184 case FB_BLANK_NORMAL: seq = 0x20; crtc = 0x00; break;
1185 case FB_BLANK_VSYNC_SUSPEND: seq = 0x20; crtc = 0x10; break;
1186 case FB_BLANK_HSYNC_SUSPEND: seq = 0x20; crtc = 0x20; break;
1187 case FB_BLANK_POWERDOWN: seq = 0x20; crtc = 0x30; break;
1188 default: seq = 0x00; crtc = 0x00; break;
1189 }
1190
1191 CRITBEGIN
1192
1193 mga_outb(M_SEQ_INDEX, 1);
1194 mga_outb(M_SEQ_DATA, (mga_inb(M_SEQ_DATA) & ~0x20) | seq);
1195 mga_outb(M_EXTVGA_INDEX, 1);
1196 mga_outb(M_EXTVGA_DATA, (mga_inb(M_EXTVGA_DATA) & ~0x30) | crtc);
1197
1198 CRITEND
1199 return 0;
1200 }
1201
1202 static const struct fb_ops matroxfb_ops = {
1203 .owner = THIS_MODULE,
1204 .fb_open = matroxfb_open,
1205 .fb_release = matroxfb_release,
1206 .fb_check_var = matroxfb_check_var,
1207 .fb_set_par = matroxfb_set_par,
1208 .fb_setcolreg = matroxfb_setcolreg,
1209 .fb_pan_display =matroxfb_pan_display,
1210 .fb_blank = matroxfb_blank,
1211 .fb_ioctl = matroxfb_ioctl,
1212
1213
1214
1215
1216 };
1217
1218 #define RSDepth(X) (((X) >> 8) & 0x0F)
1219 #define RS8bpp 0x1
1220 #define RS15bpp 0x2
1221 #define RS16bpp 0x3
1222 #define RS32bpp 0x4
1223 #define RS4bpp 0x5
1224 #define RS24bpp 0x6
1225 #define RSText 0x7
1226 #define RSText8 0x8
1227
1228 static struct { struct fb_bitfield red, green, blue, transp; int bits_per_pixel; } colors[] = {
1229 { { 0, 8, 0}, { 0, 8, 0}, { 0, 8, 0}, { 0, 0, 0}, 8 },
1230 { { 10, 5, 0}, { 5, 5, 0}, { 0, 5, 0}, { 15, 1, 0}, 16 },
1231 { { 11, 5, 0}, { 5, 6, 0}, { 0, 5, 0}, { 0, 0, 0}, 16 },
1232 { { 16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, { 24, 8, 0}, 32 },
1233 { { 0, 8, 0}, { 0, 8, 0}, { 0, 8, 0}, { 0, 0, 0}, 4 },
1234 { { 16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, { 0, 0, 0}, 24 },
1235 { { 0, 6, 0}, { 0, 6, 0}, { 0, 6, 0}, { 0, 0, 0}, 0 },
1236 { { 0, 6, 0}, { 0, 6, 0}, { 0, 6, 0}, { 0, 0, 0}, 0 },
1237 };
1238
1239
1240 static unsigned int mem;
1241 static int option_precise_width = 1;
1242 static int inv24;
1243 static int cross4MB = -1;
1244 static int disabled;
1245 static int noaccel;
1246 static int nopan;
1247 static int no_pci_retry;
1248 static int novga;
1249 static int nobios;
1250 static int noinit = 1;
1251 static int inverse;
1252 static int sgram;
1253 static int mtrr = 1;
1254 static int grayscale;
1255 static int dev = -1;
1256 static unsigned int vesa = ~0;
1257 static int depth = -1;
1258 static unsigned int xres;
1259 static unsigned int yres;
1260 static unsigned int upper = ~0;
1261 static unsigned int lower = ~0;
1262 static unsigned int vslen;
1263 static unsigned int left = ~0;
1264 static unsigned int right = ~0;
1265 static unsigned int hslen;
1266 static unsigned int pixclock;
1267 static int sync = -1;
1268 static unsigned int fv;
1269 static unsigned int fh;
1270 static unsigned int maxclk;
1271 static int dfp;
1272 static int dfp_type = -1;
1273 static int memtype = -1;
1274 static char outputs[8];
1275
1276 #ifndef MODULE
1277 static char videomode[64];
1278 #endif
1279
1280 static int matroxfb_getmemory(struct matrox_fb_info *minfo,
1281 unsigned int maxSize, unsigned int *realSize)
1282 {
1283 vaddr_t vm;
1284 unsigned int offs;
1285 unsigned int offs2;
1286 unsigned char orig;
1287 unsigned char bytes[32];
1288 unsigned char* tmp;
1289
1290 DBG(__func__)
1291
1292 vm = minfo->video.vbase;
1293 maxSize &= ~0x1FFFFF;
1294
1295 if (maxSize < 0x0200000) return 0;
1296 if (maxSize > 0x2000000) maxSize = 0x2000000;
1297
1298 mga_outb(M_EXTVGA_INDEX, 0x03);
1299 orig = mga_inb(M_EXTVGA_DATA);
1300 mga_outb(M_EXTVGA_DATA, orig | 0x80);
1301
1302 tmp = bytes;
1303 for (offs = 0x100000; offs < maxSize; offs += 0x200000)
1304 *tmp++ = mga_readb(vm, offs);
1305 for (offs = 0x100000; offs < maxSize; offs += 0x200000)
1306 mga_writeb(vm, offs, 0x02);
1307 mga_outb(M_CACHEFLUSH, 0x00);
1308 for (offs = 0x100000; offs < maxSize; offs += 0x200000) {
1309 if (mga_readb(vm, offs) != 0x02)
1310 break;
1311 mga_writeb(vm, offs, mga_readb(vm, offs) - 0x02);
1312 if (mga_readb(vm, offs))
1313 break;
1314 }
1315 tmp = bytes;
1316 for (offs2 = 0x100000; offs2 < maxSize; offs2 += 0x200000)
1317 mga_writeb(vm, offs2, *tmp++);
1318
1319 mga_outb(M_EXTVGA_INDEX, 0x03);
1320 mga_outb(M_EXTVGA_DATA, orig);
1321
1322 *realSize = offs - 0x100000;
1323 #ifdef CONFIG_FB_MATROX_MILLENIUM
1324 minfo->interleave = !(!isMillenium(minfo) || ((offs - 0x100000) & 0x3FFFFF));
1325 #endif
1326 return 1;
1327 }
1328
1329 struct video_board {
1330 int maxvram;
1331 int maxdisplayable;
1332 int accelID;
1333 struct matrox_switch* lowlevel;
1334 };
1335 #ifdef CONFIG_FB_MATROX_MILLENIUM
1336 static struct video_board vbMillennium = {
1337 .maxvram = 0x0800000,
1338 .maxdisplayable = 0x0800000,
1339 .accelID = FB_ACCEL_MATROX_MGA2064W,
1340 .lowlevel = &matrox_millennium
1341 };
1342
1343 static struct video_board vbMillennium2 = {
1344 .maxvram = 0x1000000,
1345 .maxdisplayable = 0x0800000,
1346 .accelID = FB_ACCEL_MATROX_MGA2164W,
1347 .lowlevel = &matrox_millennium
1348 };
1349
1350 static struct video_board vbMillennium2A = {
1351 .maxvram = 0x1000000,
1352 .maxdisplayable = 0x0800000,
1353 .accelID = FB_ACCEL_MATROX_MGA2164W_AGP,
1354 .lowlevel = &matrox_millennium
1355 };
1356 #endif
1357 #ifdef CONFIG_FB_MATROX_MYSTIQUE
1358 static struct video_board vbMystique = {
1359 .maxvram = 0x0800000,
1360 .maxdisplayable = 0x0800000,
1361 .accelID = FB_ACCEL_MATROX_MGA1064SG,
1362 .lowlevel = &matrox_mystique
1363 };
1364 #endif
1365 #ifdef CONFIG_FB_MATROX_G
1366 static struct video_board vbG100 = {
1367 .maxvram = 0x0800000,
1368 .maxdisplayable = 0x0800000,
1369 .accelID = FB_ACCEL_MATROX_MGAG100,
1370 .lowlevel = &matrox_G100
1371 };
1372
1373 static struct video_board vbG200 = {
1374 .maxvram = 0x1000000,
1375 .maxdisplayable = 0x1000000,
1376 .accelID = FB_ACCEL_MATROX_MGAG200,
1377 .lowlevel = &matrox_G100
1378 };
1379 static struct video_board vbG200eW = {
1380 .maxvram = 0x100000,
1381 .maxdisplayable = 0x800000,
1382 .accelID = FB_ACCEL_MATROX_MGAG200,
1383 .lowlevel = &matrox_G100
1384 };
1385
1386
1387 static struct video_board vbG400 = {
1388 .maxvram = 0x2000000,
1389 .maxdisplayable = 0x1000000,
1390 .accelID = FB_ACCEL_MATROX_MGAG400,
1391 .lowlevel = &matrox_G100
1392 };
1393 #endif
1394
1395 #define DEVF_VIDEO64BIT 0x0001
1396 #define DEVF_SWAPS 0x0002
1397 #define DEVF_SRCORG 0x0004
1398 #define DEVF_DUALHEAD 0x0008
1399 #define DEVF_CROSS4MB 0x0010
1400 #define DEVF_TEXT4B 0x0020
1401
1402
1403 #define DEVF_SUPPORT32MB 0x0100
1404 #define DEVF_ANY_VXRES 0x0200
1405 #define DEVF_TEXT16B 0x0400
1406 #define DEVF_CRTC2 0x0800
1407 #define DEVF_MAVEN_CAPABLE 0x1000
1408 #define DEVF_PANELLINK_CAPABLE 0x2000
1409 #define DEVF_G450DAC 0x4000
1410
1411 #define DEVF_GCORE (DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB)
1412 #define DEVF_G2CORE (DEVF_GCORE | DEVF_ANY_VXRES | DEVF_MAVEN_CAPABLE | DEVF_PANELLINK_CAPABLE | DEVF_SRCORG | DEVF_DUALHEAD)
1413 #define DEVF_G100 (DEVF_GCORE)
1414 #define DEVF_G200 (DEVF_G2CORE)
1415 #define DEVF_G400 (DEVF_G2CORE | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2)
1416
1417 #define DEVF_G450 (DEVF_GCORE | DEVF_ANY_VXRES | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2 | DEVF_G450DAC | DEVF_SRCORG | DEVF_DUALHEAD)
1418 #define DEVF_G550 (DEVF_G450)
1419
1420 static struct board {
1421 unsigned short vendor, device, rev, svid, sid;
1422 unsigned int flags;
1423 unsigned int maxclk;
1424 enum mga_chip chip;
1425 struct video_board* base;
1426 const char* name;
1427 } dev_list[] = {
1428 #ifdef CONFIG_FB_MATROX_MILLENIUM
1429 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL, 0xFF,
1430 0, 0,
1431 DEVF_TEXT4B,
1432 230000,
1433 MGA_2064,
1434 &vbMillennium,
1435 "Millennium (PCI)"},
1436 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL_2, 0xFF,
1437 0, 0,
1438 DEVF_SWAPS,
1439 220000,
1440 MGA_2164,
1441 &vbMillennium2,
1442 "Millennium II (PCI)"},
1443 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL_2_AGP, 0xFF,
1444 0, 0,
1445 DEVF_SWAPS,
1446 250000,
1447 MGA_2164,
1448 &vbMillennium2A,
1449 "Millennium II (AGP)"},
1450 #endif
1451 #ifdef CONFIG_FB_MATROX_MYSTIQUE
1452 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS, 0x02,
1453 0, 0,
1454 DEVF_VIDEO64BIT | DEVF_CROSS4MB,
1455 180000,
1456 MGA_1064,
1457 &vbMystique,
1458 "Mystique (PCI)"},
1459 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS, 0xFF,
1460 0, 0,
1461 DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
1462 220000,
1463 MGA_1164,
1464 &vbMystique,
1465 "Mystique 220 (PCI)"},
1466 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS_AGP, 0x02,
1467 0, 0,
1468 DEVF_VIDEO64BIT | DEVF_CROSS4MB,
1469 180000,
1470 MGA_1064,
1471 &vbMystique,
1472 "Mystique (AGP)"},
1473 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS_AGP, 0xFF,
1474 0, 0,
1475 DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
1476 220000,
1477 MGA_1164,
1478 &vbMystique,
1479 "Mystique 220 (AGP)"},
1480 #endif
1481 #ifdef CONFIG_FB_MATROX_G
1482 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_MM, 0xFF,
1483 0, 0,
1484 DEVF_G100,
1485 230000,
1486 MGA_G100,
1487 &vbG100,
1488 "MGA-G100 (PCI)"},
1489 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, 0xFF,
1490 0, 0,
1491 DEVF_G100,
1492 230000,
1493 MGA_G100,
1494 &vbG100,
1495 "MGA-G100 (AGP)"},
1496 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, 0xFF,
1497 0, 0,
1498 DEVF_G200,
1499 250000,
1500 MGA_G200,
1501 &vbG200,
1502 "MGA-G200 (PCI)"},
1503 {PCI_VENDOR_ID_MATROX, 0x0532, 0xFF,
1504 0, 0,
1505 DEVF_G200,
1506 250000,
1507 MGA_G200,
1508 &vbG200eW,
1509 "MGA-G200eW (PCI)"},
1510 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF,
1511 PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_GENERIC,
1512 DEVF_G200,
1513 220000,
1514 MGA_G200,
1515 &vbG200,
1516 "MGA-G200 (AGP)"},
1517 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF,
1518 PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MYSTIQUE_G200_AGP,
1519 DEVF_G200,
1520 230000,
1521 MGA_G200,
1522 &vbG200,
1523 "Mystique G200 (AGP)"},
1524 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF,
1525 PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MILLENIUM_G200_AGP,
1526 DEVF_G200,
1527 250000,
1528 MGA_G200,
1529 &vbG200,
1530 "Millennium G200 (AGP)"},
1531 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF,
1532 PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MARVEL_G200_AGP,
1533 DEVF_G200,
1534 230000,
1535 MGA_G200,
1536 &vbG200,
1537 "Marvel G200 (AGP)"},
1538 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF,
1539 PCI_SS_VENDOR_ID_SIEMENS_NIXDORF, PCI_SS_ID_SIEMENS_MGA_G200_AGP,
1540 DEVF_G200,
1541 230000,
1542 MGA_G200,
1543 &vbG200,
1544 "MGA-G200 (AGP)"},
1545 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF,
1546 0, 0,
1547 DEVF_G200,
1548 230000,
1549 MGA_G200,
1550 &vbG200,
1551 "G200 (AGP)"},
1552 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400, 0x80,
1553 PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MILLENNIUM_G400_MAX_AGP,
1554 DEVF_G400,
1555 360000,
1556 MGA_G400,
1557 &vbG400,
1558 "Millennium G400 MAX (AGP)"},
1559 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400, 0x80,
1560 0, 0,
1561 DEVF_G400,
1562 300000,
1563 MGA_G400,
1564 &vbG400,
1565 "G400 (AGP)"},
1566 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400, 0xFF,
1567 0, 0,
1568 DEVF_G450,
1569 360000,
1570 MGA_G450,
1571 &vbG400,
1572 "G450"},
1573 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G550, 0xFF,
1574 0, 0,
1575 DEVF_G550,
1576 360000,
1577 MGA_G550,
1578 &vbG400,
1579 "G550"},
1580 #endif
1581 {0, 0, 0xFF,
1582 0, 0,
1583 0,
1584 0,
1585 0,
1586 NULL,
1587 NULL}};
1588
1589 #ifndef MODULE
1590 static const struct fb_videomode defaultmode = {
1591
1592 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
1593 0, FB_VMODE_NONINTERLACED
1594 };
1595
1596 static int hotplug = 0;
1597 #endif
1598
1599 static void setDefaultOutputs(struct matrox_fb_info *minfo)
1600 {
1601 unsigned int i;
1602 const char* ptr;
1603
1604 minfo->outputs[0].default_src = MATROXFB_SRC_CRTC1;
1605 if (minfo->devflags.g450dac) {
1606 minfo->outputs[1].default_src = MATROXFB_SRC_CRTC1;
1607 minfo->outputs[2].default_src = MATROXFB_SRC_CRTC1;
1608 } else if (dfp) {
1609 minfo->outputs[2].default_src = MATROXFB_SRC_CRTC1;
1610 }
1611 ptr = outputs;
1612 for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) {
1613 char c = *ptr++;
1614
1615 if (c == 0) {
1616 break;
1617 }
1618 if (c == '0') {
1619 minfo->outputs[i].default_src = MATROXFB_SRC_NONE;
1620 } else if (c == '1') {
1621 minfo->outputs[i].default_src = MATROXFB_SRC_CRTC1;
1622 } else if (c == '2' && minfo->devflags.crtc2) {
1623 minfo->outputs[i].default_src = MATROXFB_SRC_CRTC2;
1624 } else {
1625 printk(KERN_ERR "matroxfb: Unknown outputs setting\n");
1626 break;
1627 }
1628 }
1629
1630 outputs[0] = 0;
1631 }
1632
1633 static int initMatrox2(struct matrox_fb_info *minfo, struct board *b)
1634 {
1635 unsigned long ctrlptr_phys = 0;
1636 unsigned long video_base_phys = 0;
1637 unsigned int memsize;
1638 int err;
1639
1640 static const struct pci_device_id intel_82437[] = {
1641 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437) },
1642 { },
1643 };
1644
1645 DBG(__func__)
1646
1647
1648 vesafb_defined.accel_flags = FB_ACCELF_TEXT;
1649
1650 minfo->hw_switch = b->base->lowlevel;
1651 minfo->devflags.accelerator = b->base->accelID;
1652 minfo->max_pixel_clock = b->maxclk;
1653
1654 printk(KERN_INFO "matroxfb: Matrox %s detected\n", b->name);
1655 minfo->capable.plnwt = 1;
1656 minfo->chip = b->chip;
1657 minfo->capable.srcorg = b->flags & DEVF_SRCORG;
1658 minfo->devflags.video64bits = b->flags & DEVF_VIDEO64BIT;
1659 if (b->flags & DEVF_TEXT4B) {
1660 minfo->devflags.vgastep = 4;
1661 minfo->devflags.textmode = 4;
1662 minfo->devflags.text_type_aux = FB_AUX_TEXT_MGA_STEP16;
1663 } else if (b->flags & DEVF_TEXT16B) {
1664 minfo->devflags.vgastep = 16;
1665 minfo->devflags.textmode = 1;
1666 minfo->devflags.text_type_aux = FB_AUX_TEXT_MGA_STEP16;
1667 } else {
1668 minfo->devflags.vgastep = 8;
1669 minfo->devflags.textmode = 1;
1670 minfo->devflags.text_type_aux = FB_AUX_TEXT_MGA_STEP8;
1671 }
1672 minfo->devflags.support32MB = (b->flags & DEVF_SUPPORT32MB) != 0;
1673 minfo->devflags.precise_width = !(b->flags & DEVF_ANY_VXRES);
1674 minfo->devflags.crtc2 = (b->flags & DEVF_CRTC2) != 0;
1675 minfo->devflags.maven_capable = (b->flags & DEVF_MAVEN_CAPABLE) != 0;
1676 minfo->devflags.dualhead = (b->flags & DEVF_DUALHEAD) != 0;
1677 minfo->devflags.dfp_type = dfp_type;
1678 minfo->devflags.g450dac = (b->flags & DEVF_G450DAC) != 0;
1679 minfo->devflags.textstep = minfo->devflags.vgastep * minfo->devflags.textmode;
1680 minfo->devflags.textvram = 65536 / minfo->devflags.textmode;
1681 setDefaultOutputs(minfo);
1682 if (b->flags & DEVF_PANELLINK_CAPABLE) {
1683 minfo->outputs[2].data = minfo;
1684 minfo->outputs[2].output = &panellink_output;
1685 minfo->outputs[2].src = minfo->outputs[2].default_src;
1686 minfo->outputs[2].mode = MATROXFB_OUTPUT_MODE_MONITOR;
1687 minfo->devflags.panellink = 1;
1688 }
1689
1690 if (minfo->capable.cross4MB < 0)
1691 minfo->capable.cross4MB = b->flags & DEVF_CROSS4MB;
1692 if (b->flags & DEVF_SWAPS) {
1693 ctrlptr_phys = pci_resource_start(minfo->pcidev, 1);
1694 video_base_phys = pci_resource_start(minfo->pcidev, 0);
1695 minfo->devflags.fbResource = PCI_BASE_ADDRESS_0;
1696 } else {
1697 ctrlptr_phys = pci_resource_start(minfo->pcidev, 0);
1698 video_base_phys = pci_resource_start(minfo->pcidev, 1);
1699 minfo->devflags.fbResource = PCI_BASE_ADDRESS_1;
1700 }
1701 err = -EINVAL;
1702 if (!ctrlptr_phys) {
1703 printk(KERN_ERR "matroxfb: control registers are not available, matroxfb disabled\n");
1704 goto fail;
1705 }
1706 if (!video_base_phys) {
1707 printk(KERN_ERR "matroxfb: video RAM is not available in PCI address space, matroxfb disabled\n");
1708 goto fail;
1709 }
1710 memsize = b->base->maxvram;
1711 if (!request_mem_region(ctrlptr_phys, 16384, "matroxfb MMIO")) {
1712 goto fail;
1713 }
1714 if (!request_mem_region(video_base_phys, memsize, "matroxfb FB")) {
1715 goto failCtrlMR;
1716 }
1717 minfo->video.len_maximum = memsize;
1718
1719 if (mem < 1024) mem *= 1024;
1720 if (mem < 0x00100000) mem *= 1024;
1721
1722 if (mem && (mem < memsize))
1723 memsize = mem;
1724 err = -ENOMEM;
1725
1726 minfo->mmio.vbase.vaddr = ioremap(ctrlptr_phys, 16384);
1727 if (!minfo->mmio.vbase.vaddr) {
1728 printk(KERN_ERR "matroxfb: cannot ioremap(%lX, 16384), matroxfb disabled\n", ctrlptr_phys);
1729 goto failVideoMR;
1730 }
1731 minfo->mmio.base = ctrlptr_phys;
1732 minfo->mmio.len = 16384;
1733 minfo->video.base = video_base_phys;
1734 minfo->video.vbase.vaddr = ioremap_wc(video_base_phys, memsize);
1735 if (!minfo->video.vbase.vaddr) {
1736 printk(KERN_ERR "matroxfb: cannot ioremap(%lX, %d), matroxfb disabled\n",
1737 video_base_phys, memsize);
1738 goto failCtrlIO;
1739 }
1740 {
1741 u_int32_t cmd;
1742 u_int32_t mga_option;
1743
1744 pci_read_config_dword(minfo->pcidev, PCI_OPTION_REG, &mga_option);
1745 pci_read_config_dword(minfo->pcidev, PCI_COMMAND, &cmd);
1746 mga_option &= 0x7FFFFFFF;
1747 mga_option |= MX_OPTION_BSWAP;
1748
1749 cmd &= ~PCI_COMMAND_VGA_PALETTE;
1750 if (pci_dev_present(intel_82437)) {
1751 if (!(mga_option & 0x20000000) && !minfo->devflags.nopciretry) {
1752 printk(KERN_WARNING "matroxfb: Disabling PCI retries due to i82437 present\n");
1753 }
1754 mga_option |= 0x20000000;
1755 minfo->devflags.nopciretry = 1;
1756 }
1757 pci_write_config_dword(minfo->pcidev, PCI_COMMAND, cmd);
1758 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, mga_option);
1759 minfo->hw.MXoptionReg = mga_option;
1760
1761
1762
1763 pci_write_config_dword(minfo->pcidev, PCI_MGA_INDEX, 0x00003C00);
1764 }
1765
1766 err = -ENXIO;
1767 matroxfb_read_pins(minfo);
1768 if (minfo->hw_switch->preinit(minfo)) {
1769 goto failVideoIO;
1770 }
1771
1772 err = -ENOMEM;
1773 if (!matroxfb_getmemory(minfo, memsize, &minfo->video.len) || !minfo->video.len) {
1774 printk(KERN_ERR "matroxfb: cannot determine memory size\n");
1775 goto failVideoIO;
1776 }
1777 minfo->devflags.ydstorg = 0;
1778
1779 minfo->video.base = video_base_phys;
1780 minfo->video.len_usable = minfo->video.len;
1781 if (minfo->video.len_usable > b->base->maxdisplayable)
1782 minfo->video.len_usable = b->base->maxdisplayable;
1783 if (mtrr)
1784 minfo->wc_cookie = arch_phys_wc_add(video_base_phys,
1785 minfo->video.len);
1786
1787 if (!minfo->devflags.novga)
1788 request_region(0x3C0, 32, "matrox");
1789 matroxfb_g450_connect(minfo);
1790 minfo->hw_switch->reset(minfo);
1791
1792 minfo->fbcon.monspecs.hfmin = 0;
1793 minfo->fbcon.monspecs.hfmax = fh;
1794 minfo->fbcon.monspecs.vfmin = 0;
1795 minfo->fbcon.monspecs.vfmax = fv;
1796 minfo->fbcon.monspecs.dpms = 0;
1797
1798
1799 vesafb_defined.red = colors[depth-1].red;
1800 vesafb_defined.green = colors[depth-1].green;
1801 vesafb_defined.blue = colors[depth-1].blue;
1802 vesafb_defined.bits_per_pixel = colors[depth-1].bits_per_pixel;
1803 vesafb_defined.grayscale = grayscale;
1804 vesafb_defined.vmode = 0;
1805 if (noaccel)
1806 vesafb_defined.accel_flags &= ~FB_ACCELF_TEXT;
1807
1808 minfo->fbops = matroxfb_ops;
1809 minfo->fbcon.fbops = &minfo->fbops;
1810 minfo->fbcon.pseudo_palette = minfo->cmap;
1811 minfo->fbcon.flags = FBINFO_PARTIAL_PAN_OK |
1812 FBINFO_HWACCEL_COPYAREA |
1813 FBINFO_HWACCEL_FILLRECT |
1814 FBINFO_HWACCEL_IMAGEBLIT |
1815 FBINFO_HWACCEL_XPAN |
1816 FBINFO_HWACCEL_YPAN |
1817 FBINFO_READS_FAST;
1818 minfo->video.len_usable &= PAGE_MASK;
1819 fb_alloc_cmap(&minfo->fbcon.cmap, 256, 1);
1820
1821 #ifndef MODULE
1822
1823 if (!hotplug) {
1824 fb_find_mode(&vesafb_defined, &minfo->fbcon, videomode[0] ? videomode : NULL,
1825 NULL, 0, &defaultmode, vesafb_defined.bits_per_pixel);
1826 }
1827 #endif
1828
1829
1830 if (hslen)
1831 vesafb_defined.hsync_len = hslen;
1832 if (vslen)
1833 vesafb_defined.vsync_len = vslen;
1834 if (left != ~0)
1835 vesafb_defined.left_margin = left;
1836 if (right != ~0)
1837 vesafb_defined.right_margin = right;
1838 if (upper != ~0)
1839 vesafb_defined.upper_margin = upper;
1840 if (lower != ~0)
1841 vesafb_defined.lower_margin = lower;
1842 if (xres)
1843 vesafb_defined.xres = xres;
1844 if (yres)
1845 vesafb_defined.yres = yres;
1846 if (sync != -1)
1847 vesafb_defined.sync = sync;
1848 else if (vesafb_defined.sync == ~0) {
1849 vesafb_defined.sync = 0;
1850 if (yres < 400)
1851 vesafb_defined.sync |= FB_SYNC_HOR_HIGH_ACT;
1852 else if (yres < 480)
1853 vesafb_defined.sync |= FB_SYNC_VERT_HIGH_ACT;
1854 }
1855
1856
1857 {
1858 unsigned int tmp;
1859
1860 if (fv) {
1861 tmp = fv * (vesafb_defined.upper_margin + vesafb_defined.yres
1862 + vesafb_defined.lower_margin + vesafb_defined.vsync_len);
1863 if ((tmp < fh) || (fh == 0)) fh = tmp;
1864 }
1865 if (fh) {
1866 tmp = fh * (vesafb_defined.left_margin + vesafb_defined.xres
1867 + vesafb_defined.right_margin + vesafb_defined.hsync_len);
1868 if ((tmp < maxclk) || (maxclk == 0)) maxclk = tmp;
1869 }
1870 tmp = (maxclk + 499) / 500;
1871 if (tmp) {
1872 tmp = (2000000000 + tmp) / tmp;
1873 if (tmp > pixclock) pixclock = tmp;
1874 }
1875 }
1876 if (pixclock) {
1877 if (pixclock < 2000)
1878 pixclock = 4000;
1879 if (pixclock > 1000000)
1880 pixclock = 1000000;
1881 vesafb_defined.pixclock = pixclock;
1882 }
1883
1884
1885 #if defined(CONFIG_PPC_PMAC)
1886 #ifndef MODULE
1887 if (machine_is(powermac)) {
1888 struct fb_var_screeninfo var;
1889
1890 if (default_vmode <= 0 || default_vmode > VMODE_MAX)
1891 default_vmode = VMODE_640_480_60;
1892 #if defined(CONFIG_PPC32)
1893 if (IS_REACHABLE(CONFIG_NVRAM) && default_cmode == CMODE_NVRAM)
1894 default_cmode = nvram_read_byte(NV_CMODE);
1895 #endif
1896 if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
1897 default_cmode = CMODE_8;
1898 if (!mac_vmode_to_var(default_vmode, default_cmode, &var)) {
1899 var.accel_flags = vesafb_defined.accel_flags;
1900 var.xoffset = var.yoffset = 0;
1901
1902 vesafb_defined = var;
1903 }
1904 }
1905 #endif
1906 #endif
1907 vesafb_defined.xres_virtual = vesafb_defined.xres;
1908 if (nopan) {
1909 vesafb_defined.yres_virtual = vesafb_defined.yres;
1910 } else {
1911 vesafb_defined.yres_virtual = 65536;
1912
1913 }
1914 matroxfb_init_fix(minfo);
1915 minfo->fbcon.screen_base = vaddr_va(minfo->video.vbase);
1916
1917 matroxfb_check_var(&vesafb_defined, &minfo->fbcon);
1918
1919
1920
1921
1922 minfo->fbcon.var = vesafb_defined;
1923 err = -EINVAL;
1924
1925 printk(KERN_INFO "matroxfb: %dx%dx%dbpp (virtual: %dx%d)\n",
1926 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel,
1927 vesafb_defined.xres_virtual, vesafb_defined.yres_virtual);
1928 printk(KERN_INFO "matroxfb: framebuffer at 0x%lX, mapped to 0x%p, size %d\n",
1929 minfo->video.base, vaddr_va(minfo->video.vbase), minfo->video.len);
1930
1931
1932
1933
1934 minfo->fbcon.device = &minfo->pcidev->dev;
1935 if (register_framebuffer(&minfo->fbcon) < 0) {
1936 goto failVideoIO;
1937 }
1938 fb_info(&minfo->fbcon, "%s frame buffer device\n", minfo->fbcon.fix.id);
1939
1940
1941
1942 if (!minfo->initialized) {
1943 fb_info(&minfo->fbcon, "initializing hardware\n");
1944
1945
1946 vesafb_defined.activate |= FB_ACTIVATE_FORCE;
1947 fb_set_var(&minfo->fbcon, &vesafb_defined);
1948 }
1949
1950 return 0;
1951 failVideoIO:;
1952 matroxfb_g450_shutdown(minfo);
1953 iounmap(minfo->video.vbase.vaddr);
1954 failCtrlIO:;
1955 iounmap(minfo->mmio.vbase.vaddr);
1956 failVideoMR:;
1957 release_mem_region(video_base_phys, minfo->video.len_maximum);
1958 failCtrlMR:;
1959 release_mem_region(ctrlptr_phys, 16384);
1960 fail:;
1961 return err;
1962 }
1963
1964 static LIST_HEAD(matroxfb_list);
1965 static LIST_HEAD(matroxfb_driver_list);
1966
1967 #define matroxfb_l(x) list_entry(x, struct matrox_fb_info, next_fb)
1968 #define matroxfb_driver_l(x) list_entry(x, struct matroxfb_driver, node)
1969 int matroxfb_register_driver(struct matroxfb_driver* drv) {
1970 struct matrox_fb_info* minfo;
1971
1972 list_add(&drv->node, &matroxfb_driver_list);
1973 list_for_each_entry(minfo, &matroxfb_list, next_fb) {
1974 void* p;
1975
1976 if (minfo->drivers_count == MATROXFB_MAX_FB_DRIVERS)
1977 continue;
1978 p = drv->probe(minfo);
1979 if (p) {
1980 minfo->drivers_data[minfo->drivers_count] = p;
1981 minfo->drivers[minfo->drivers_count++] = drv;
1982 }
1983 }
1984 return 0;
1985 }
1986
1987 void matroxfb_unregister_driver(struct matroxfb_driver* drv) {
1988 struct matrox_fb_info* minfo;
1989
1990 list_del(&drv->node);
1991 list_for_each_entry(minfo, &matroxfb_list, next_fb) {
1992 int i;
1993
1994 for (i = 0; i < minfo->drivers_count; ) {
1995 if (minfo->drivers[i] == drv) {
1996 if (drv && drv->remove)
1997 drv->remove(minfo, minfo->drivers_data[i]);
1998 minfo->drivers[i] = minfo->drivers[--minfo->drivers_count];
1999 minfo->drivers_data[i] = minfo->drivers_data[minfo->drivers_count];
2000 } else
2001 i++;
2002 }
2003 }
2004 }
2005
2006 static void matroxfb_register_device(struct matrox_fb_info* minfo) {
2007 struct matroxfb_driver* drv;
2008 int i = 0;
2009 list_add(&minfo->next_fb, &matroxfb_list);
2010 for (drv = matroxfb_driver_l(matroxfb_driver_list.next);
2011 drv != matroxfb_driver_l(&matroxfb_driver_list);
2012 drv = matroxfb_driver_l(drv->node.next)) {
2013 if (drv->probe) {
2014 void *p = drv->probe(minfo);
2015 if (p) {
2016 minfo->drivers_data[i] = p;
2017 minfo->drivers[i++] = drv;
2018 if (i == MATROXFB_MAX_FB_DRIVERS)
2019 break;
2020 }
2021 }
2022 }
2023 minfo->drivers_count = i;
2024 }
2025
2026 static void matroxfb_unregister_device(struct matrox_fb_info* minfo) {
2027 int i;
2028
2029 list_del(&minfo->next_fb);
2030 for (i = 0; i < minfo->drivers_count; i++) {
2031 struct matroxfb_driver* drv = minfo->drivers[i];
2032
2033 if (drv && drv->remove)
2034 drv->remove(minfo, minfo->drivers_data[i]);
2035 }
2036 }
2037
2038 static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dummy) {
2039 struct board* b;
2040 u_int16_t svid;
2041 u_int16_t sid;
2042 struct matrox_fb_info* minfo;
2043 int err;
2044 u_int32_t cmd;
2045 DBG(__func__)
2046
2047 svid = pdev->subsystem_vendor;
2048 sid = pdev->subsystem_device;
2049 for (b = dev_list; b->vendor; b++) {
2050 if ((b->vendor != pdev->vendor) || (b->device != pdev->device) || (b->rev < pdev->revision)) continue;
2051 if (b->svid)
2052 if ((b->svid != svid) || (b->sid != sid)) continue;
2053 break;
2054 }
2055
2056 if (!b->vendor)
2057 return -ENODEV;
2058 if (dev > 0) {
2059
2060 dev--;
2061 return -ENODEV;
2062 }
2063 pci_read_config_dword(pdev, PCI_COMMAND, &cmd);
2064 if (pci_enable_device(pdev)) {
2065 return -1;
2066 }
2067
2068 minfo = kzalloc(sizeof(*minfo), GFP_KERNEL);
2069 if (!minfo)
2070 return -ENOMEM;
2071
2072 minfo->pcidev = pdev;
2073 minfo->dead = 0;
2074 minfo->usecount = 0;
2075 minfo->userusecount = 0;
2076
2077 pci_set_drvdata(pdev, minfo);
2078
2079 minfo->devflags.memtype = memtype;
2080 if (memtype != -1)
2081 noinit = 0;
2082 if (cmd & PCI_COMMAND_MEMORY) {
2083 minfo->devflags.novga = novga;
2084 minfo->devflags.nobios = nobios;
2085 minfo->devflags.noinit = noinit;
2086
2087 novga = 1;
2088 nobios = 1;
2089 noinit = 0;
2090 } else {
2091 minfo->devflags.novga = 1;
2092 minfo->devflags.nobios = 1;
2093 minfo->devflags.noinit = 0;
2094 }
2095
2096 minfo->devflags.nopciretry = no_pci_retry;
2097 minfo->devflags.mga_24bpp_fix = inv24;
2098 minfo->devflags.precise_width = option_precise_width;
2099 minfo->devflags.sgram = sgram;
2100 minfo->capable.cross4MB = cross4MB;
2101
2102 spin_lock_init(&minfo->lock.DAC);
2103 spin_lock_init(&minfo->lock.accel);
2104 init_rwsem(&minfo->crtc2.lock);
2105 init_rwsem(&minfo->altout.lock);
2106 mutex_init(&minfo->fbcon.mm_lock);
2107 minfo->irq_flags = 0;
2108 init_waitqueue_head(&minfo->crtc1.vsync.wait);
2109 init_waitqueue_head(&minfo->crtc2.vsync.wait);
2110 minfo->crtc1.panpos = -1;
2111
2112 err = initMatrox2(minfo, b);
2113 if (!err) {
2114 matroxfb_register_device(minfo);
2115 return 0;
2116 }
2117 kfree(minfo);
2118 return -1;
2119 }
2120
2121 static void pci_remove_matrox(struct pci_dev* pdev) {
2122 struct matrox_fb_info* minfo;
2123
2124 minfo = pci_get_drvdata(pdev);
2125 matroxfb_remove(minfo, 1);
2126 }
2127
2128 static const struct pci_device_id matroxfb_devices[] = {
2129 #ifdef CONFIG_FB_MATROX_MILLENIUM
2130 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL,
2131 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2132 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL_2,
2133 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2134 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL_2_AGP,
2135 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2136 #endif
2137 #ifdef CONFIG_FB_MATROX_MYSTIQUE
2138 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS,
2139 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2140 #endif
2141 #ifdef CONFIG_FB_MATROX_G
2142 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_MM,
2143 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2144 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP,
2145 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2146 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI,
2147 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2148 {PCI_VENDOR_ID_MATROX, 0x0532,
2149 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2150 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP,
2151 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2152 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400,
2153 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2154 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G550,
2155 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2156 #endif
2157 {0, 0,
2158 0, 0, 0, 0, 0}
2159 };
2160
2161 MODULE_DEVICE_TABLE(pci, matroxfb_devices);
2162
2163
2164 static struct pci_driver matroxfb_driver = {
2165 .name = "matroxfb",
2166 .id_table = matroxfb_devices,
2167 .probe = matroxfb_probe,
2168 .remove = pci_remove_matrox,
2169 };
2170
2171
2172
2173 #define RSResolution(X) ((X) & 0x0F)
2174 #define RS640x400 1
2175 #define RS640x480 2
2176 #define RS800x600 3
2177 #define RS1024x768 4
2178 #define RS1280x1024 5
2179 #define RS1600x1200 6
2180 #define RS768x576 7
2181 #define RS960x720 8
2182 #define RS1152x864 9
2183 #define RS1408x1056 10
2184 #define RS640x350 11
2185 #define RS1056x344 12
2186 #define RS1056x400 13
2187 #define RS1056x480 14
2188 #define RSNoxNo 15
2189
2190 static struct { int xres, yres, left, right, upper, lower, hslen, vslen, vfreq; } timmings[] __initdata = {
2191 { 640, 400, 48, 16, 39, 8, 96, 2, 70 },
2192 { 640, 480, 48, 16, 33, 10, 96, 2, 60 },
2193 { 800, 600, 144, 24, 28, 8, 112, 6, 60 },
2194 { 1024, 768, 160, 32, 30, 4, 128, 4, 60 },
2195 { 1280, 1024, 224, 32, 32, 4, 136, 4, 60 },
2196 { 1600, 1200, 272, 48, 32, 5, 152, 5, 60 },
2197 { 768, 576, 144, 16, 28, 6, 112, 4, 60 },
2198 { 960, 720, 144, 24, 28, 8, 112, 4, 60 },
2199 { 1152, 864, 192, 32, 30, 4, 128, 4, 60 },
2200 { 1408, 1056, 256, 40, 32, 5, 144, 5, 60 },
2201 { 640, 350, 48, 16, 39, 8, 96, 2, 70 },
2202 { 1056, 344, 96, 24, 59, 44, 160, 2, 70 },
2203 { 1056, 400, 96, 24, 39, 8, 160, 2, 70 },
2204 { 1056, 480, 96, 24, 36, 12, 160, 3, 60 },
2205 { 0, 0, ~0, ~0, ~0, ~0, 0, 0, 0 }
2206 };
2207
2208 #define RSCreate(X,Y) ((X) | ((Y) << 8))
2209 static struct { unsigned int vesa; unsigned int info; } *RSptr, vesamap[] __initdata = {
2210
2211 { ~0, RSCreate(RSNoxNo, RS8bpp ) },
2212 { 0x101, RSCreate(RS640x480, RS8bpp ) },
2213 { 0x100, RSCreate(RS640x400, RS8bpp ) },
2214 { 0x180, RSCreate(RS768x576, RS8bpp ) },
2215 { 0x103, RSCreate(RS800x600, RS8bpp ) },
2216 { 0x188, RSCreate(RS960x720, RS8bpp ) },
2217 { 0x105, RSCreate(RS1024x768, RS8bpp ) },
2218 { 0x190, RSCreate(RS1152x864, RS8bpp ) },
2219 { 0x107, RSCreate(RS1280x1024, RS8bpp ) },
2220 { 0x198, RSCreate(RS1408x1056, RS8bpp ) },
2221 { 0x11C, RSCreate(RS1600x1200, RS8bpp ) },
2222 { 0x110, RSCreate(RS640x480, RS15bpp) },
2223 { 0x181, RSCreate(RS768x576, RS15bpp) },
2224 { 0x113, RSCreate(RS800x600, RS15bpp) },
2225 { 0x189, RSCreate(RS960x720, RS15bpp) },
2226 { 0x116, RSCreate(RS1024x768, RS15bpp) },
2227 { 0x191, RSCreate(RS1152x864, RS15bpp) },
2228 { 0x119, RSCreate(RS1280x1024, RS15bpp) },
2229 { 0x199, RSCreate(RS1408x1056, RS15bpp) },
2230 { 0x11D, RSCreate(RS1600x1200, RS15bpp) },
2231 { 0x111, RSCreate(RS640x480, RS16bpp) },
2232 { 0x182, RSCreate(RS768x576, RS16bpp) },
2233 { 0x114, RSCreate(RS800x600, RS16bpp) },
2234 { 0x18A, RSCreate(RS960x720, RS16bpp) },
2235 { 0x117, RSCreate(RS1024x768, RS16bpp) },
2236 { 0x192, RSCreate(RS1152x864, RS16bpp) },
2237 { 0x11A, RSCreate(RS1280x1024, RS16bpp) },
2238 { 0x19A, RSCreate(RS1408x1056, RS16bpp) },
2239 { 0x11E, RSCreate(RS1600x1200, RS16bpp) },
2240 { 0x1B2, RSCreate(RS640x480, RS24bpp) },
2241 { 0x184, RSCreate(RS768x576, RS24bpp) },
2242 { 0x1B5, RSCreate(RS800x600, RS24bpp) },
2243 { 0x18C, RSCreate(RS960x720, RS24bpp) },
2244 { 0x1B8, RSCreate(RS1024x768, RS24bpp) },
2245 { 0x194, RSCreate(RS1152x864, RS24bpp) },
2246 { 0x1BB, RSCreate(RS1280x1024, RS24bpp) },
2247 { 0x19C, RSCreate(RS1408x1056, RS24bpp) },
2248 { 0x1BF, RSCreate(RS1600x1200, RS24bpp) },
2249 { 0x112, RSCreate(RS640x480, RS32bpp) },
2250 { 0x183, RSCreate(RS768x576, RS32bpp) },
2251 { 0x115, RSCreate(RS800x600, RS32bpp) },
2252 { 0x18B, RSCreate(RS960x720, RS32bpp) },
2253 { 0x118, RSCreate(RS1024x768, RS32bpp) },
2254 { 0x193, RSCreate(RS1152x864, RS32bpp) },
2255 { 0x11B, RSCreate(RS1280x1024, RS32bpp) },
2256 { 0x19B, RSCreate(RS1408x1056, RS32bpp) },
2257 { 0x11F, RSCreate(RS1600x1200, RS32bpp) },
2258 { 0x010, RSCreate(RS640x350, RS4bpp ) },
2259 { 0x012, RSCreate(RS640x480, RS4bpp ) },
2260 { 0x102, RSCreate(RS800x600, RS4bpp ) },
2261 { 0x104, RSCreate(RS1024x768, RS4bpp ) },
2262 { 0x106, RSCreate(RS1280x1024, RS4bpp ) },
2263 { 0, 0 }};
2264
2265 static void __init matroxfb_init_params(void) {
2266
2267 if (fh < 1000)
2268 fh *= 1000;
2269
2270 if (maxclk < 1000) maxclk *= 1000;
2271 if (maxclk < 1000000) maxclk *= 1000;
2272
2273 if (vesa != ~0)
2274 vesa &= 0x1DFF;
2275
2276
2277 for (RSptr = vesamap; RSptr->vesa; RSptr++) {
2278 if (RSptr->vesa == vesa) break;
2279 }
2280 if (!RSptr->vesa) {
2281 printk(KERN_ERR "Invalid vesa mode 0x%04X\n", vesa);
2282 RSptr = vesamap;
2283 }
2284 {
2285 int res = RSResolution(RSptr->info)-1;
2286 if (left == ~0)
2287 left = timmings[res].left;
2288 if (!xres)
2289 xres = timmings[res].xres;
2290 if (right == ~0)
2291 right = timmings[res].right;
2292 if (!hslen)
2293 hslen = timmings[res].hslen;
2294 if (upper == ~0)
2295 upper = timmings[res].upper;
2296 if (!yres)
2297 yres = timmings[res].yres;
2298 if (lower == ~0)
2299 lower = timmings[res].lower;
2300 if (!vslen)
2301 vslen = timmings[res].vslen;
2302 if (!(fv||fh||maxclk||pixclock))
2303 fv = timmings[res].vfreq;
2304 if (depth == -1)
2305 depth = RSDepth(RSptr->info);
2306 }
2307 }
2308
2309 static int __init matrox_init(void) {
2310 int err;
2311
2312 matroxfb_init_params();
2313 err = pci_register_driver(&matroxfb_driver);
2314 dev = -1;
2315 return err;
2316 }
2317
2318
2319
2320 static void __exit matrox_done(void) {
2321 pci_unregister_driver(&matroxfb_driver);
2322 }
2323
2324 #ifndef MODULE
2325
2326
2327
2328 static int __init matroxfb_setup(char *options) {
2329 char *this_opt;
2330
2331 DBG(__func__)
2332
2333 if (!options || !*options)
2334 return 0;
2335
2336 while ((this_opt = strsep(&options, ",")) != NULL) {
2337 if (!*this_opt) continue;
2338
2339 dprintk("matroxfb_setup: option %s\n", this_opt);
2340
2341 if (!strncmp(this_opt, "dev:", 4))
2342 dev = simple_strtoul(this_opt+4, NULL, 0);
2343 else if (!strncmp(this_opt, "depth:", 6)) {
2344 switch (simple_strtoul(this_opt+6, NULL, 0)) {
2345 case 0: depth = RSText; break;
2346 case 4: depth = RS4bpp; break;
2347 case 8: depth = RS8bpp; break;
2348 case 15:depth = RS15bpp; break;
2349 case 16:depth = RS16bpp; break;
2350 case 24:depth = RS24bpp; break;
2351 case 32:depth = RS32bpp; break;
2352 default:
2353 printk(KERN_ERR "matroxfb: unsupported color depth\n");
2354 }
2355 } else if (!strncmp(this_opt, "xres:", 5))
2356 xres = simple_strtoul(this_opt+5, NULL, 0);
2357 else if (!strncmp(this_opt, "yres:", 5))
2358 yres = simple_strtoul(this_opt+5, NULL, 0);
2359 else if (!strncmp(this_opt, "vslen:", 6))
2360 vslen = simple_strtoul(this_opt+6, NULL, 0);
2361 else if (!strncmp(this_opt, "hslen:", 6))
2362 hslen = simple_strtoul(this_opt+6, NULL, 0);
2363 else if (!strncmp(this_opt, "left:", 5))
2364 left = simple_strtoul(this_opt+5, NULL, 0);
2365 else if (!strncmp(this_opt, "right:", 6))
2366 right = simple_strtoul(this_opt+6, NULL, 0);
2367 else if (!strncmp(this_opt, "upper:", 6))
2368 upper = simple_strtoul(this_opt+6, NULL, 0);
2369 else if (!strncmp(this_opt, "lower:", 6))
2370 lower = simple_strtoul(this_opt+6, NULL, 0);
2371 else if (!strncmp(this_opt, "pixclock:", 9))
2372 pixclock = simple_strtoul(this_opt+9, NULL, 0);
2373 else if (!strncmp(this_opt, "sync:", 5))
2374 sync = simple_strtoul(this_opt+5, NULL, 0);
2375 else if (!strncmp(this_opt, "vesa:", 5))
2376 vesa = simple_strtoul(this_opt+5, NULL, 0);
2377 else if (!strncmp(this_opt, "maxclk:", 7))
2378 maxclk = simple_strtoul(this_opt+7, NULL, 0);
2379 else if (!strncmp(this_opt, "fh:", 3))
2380 fh = simple_strtoul(this_opt+3, NULL, 0);
2381 else if (!strncmp(this_opt, "fv:", 3))
2382 fv = simple_strtoul(this_opt+3, NULL, 0);
2383 else if (!strncmp(this_opt, "mem:", 4))
2384 mem = simple_strtoul(this_opt+4, NULL, 0);
2385 else if (!strncmp(this_opt, "mode:", 5))
2386 strscpy(videomode, this_opt + 5, sizeof(videomode));
2387 else if (!strncmp(this_opt, "outputs:", 8))
2388 strscpy(outputs, this_opt + 8, sizeof(outputs));
2389 else if (!strncmp(this_opt, "dfp:", 4)) {
2390 dfp_type = simple_strtoul(this_opt+4, NULL, 0);
2391 dfp = 1;
2392 }
2393 #ifdef CONFIG_PPC_PMAC
2394 else if (!strncmp(this_opt, "vmode:", 6)) {
2395 unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
2396 if (vmode > 0 && vmode <= VMODE_MAX)
2397 default_vmode = vmode;
2398 } else if (!strncmp(this_opt, "cmode:", 6)) {
2399 unsigned int cmode = simple_strtoul(this_opt+6, NULL, 0);
2400 switch (cmode) {
2401 case 0:
2402 case 8:
2403 default_cmode = CMODE_8;
2404 break;
2405 case 15:
2406 case 16:
2407 default_cmode = CMODE_16;
2408 break;
2409 case 24:
2410 case 32:
2411 default_cmode = CMODE_32;
2412 break;
2413 }
2414 }
2415 #endif
2416 else if (!strcmp(this_opt, "disabled"))
2417 disabled = 1;
2418 else if (!strcmp(this_opt, "enabled"))
2419 disabled = 0;
2420 else if (!strcmp(this_opt, "sgram"))
2421 sgram = 1;
2422 else if (!strcmp(this_opt, "sdram"))
2423 sgram = 0;
2424 else if (!strncmp(this_opt, "memtype:", 8))
2425 memtype = simple_strtoul(this_opt+8, NULL, 0);
2426 else {
2427 int value = 1;
2428
2429 if (!strncmp(this_opt, "no", 2)) {
2430 value = 0;
2431 this_opt += 2;
2432 }
2433 if (! strcmp(this_opt, "inverse"))
2434 inverse = value;
2435 else if (!strcmp(this_opt, "accel"))
2436 noaccel = !value;
2437 else if (!strcmp(this_opt, "pan"))
2438 nopan = !value;
2439 else if (!strcmp(this_opt, "pciretry"))
2440 no_pci_retry = !value;
2441 else if (!strcmp(this_opt, "vga"))
2442 novga = !value;
2443 else if (!strcmp(this_opt, "bios"))
2444 nobios = !value;
2445 else if (!strcmp(this_opt, "init"))
2446 noinit = !value;
2447 else if (!strcmp(this_opt, "mtrr"))
2448 mtrr = value;
2449 else if (!strcmp(this_opt, "inv24"))
2450 inv24 = value;
2451 else if (!strcmp(this_opt, "cross4MB"))
2452 cross4MB = value;
2453 else if (!strcmp(this_opt, "grayscale"))
2454 grayscale = value;
2455 else if (!strcmp(this_opt, "dfp"))
2456 dfp = value;
2457 else {
2458 strscpy(videomode, this_opt, sizeof(videomode));
2459 }
2460 }
2461 }
2462 return 0;
2463 }
2464
2465 static int __initdata initialized = 0;
2466
2467 static int __init matroxfb_init(void)
2468 {
2469 char *option = NULL;
2470 int err = 0;
2471
2472 DBG(__func__)
2473
2474 if (fb_get_options("matroxfb", &option))
2475 return -ENODEV;
2476 matroxfb_setup(option);
2477
2478 if (disabled)
2479 return -ENXIO;
2480 if (!initialized) {
2481 initialized = 1;
2482 err = matrox_init();
2483 }
2484 hotplug = 1;
2485
2486 return err;
2487 }
2488
2489 #else
2490
2491
2492
2493 MODULE_AUTHOR("(c) 1998-2002 Petr Vandrovec <vandrove@vc.cvut.cz>");
2494 MODULE_DESCRIPTION("Accelerated FBDev driver for Matrox Millennium/Mystique/G100/G200/G400/G450/G550");
2495 MODULE_LICENSE("GPL");
2496
2497 module_param(mem, int, 0);
2498 MODULE_PARM_DESC(mem, "Size of available memory in MB, KB or B (2,4,8,12,16MB, default=autodetect)");
2499 module_param(disabled, int, 0);
2500 MODULE_PARM_DESC(disabled, "Disabled (0 or 1=disabled) (default=0)");
2501 module_param(noaccel, int, 0);
2502 MODULE_PARM_DESC(noaccel, "Do not use accelerating engine (0 or 1=disabled) (default=0)");
2503 module_param(nopan, int, 0);
2504 MODULE_PARM_DESC(nopan, "Disable pan on startup (0 or 1=disabled) (default=0)");
2505 module_param(no_pci_retry, int, 0);
2506 MODULE_PARM_DESC(no_pci_retry, "PCI retries enabled (0 or 1=disabled) (default=0)");
2507 module_param(novga, int, 0);
2508 MODULE_PARM_DESC(novga, "VGA I/O (0x3C0-0x3DF) disabled (0 or 1=disabled) (default=0)");
2509 module_param(nobios, int, 0);
2510 MODULE_PARM_DESC(nobios, "Disables ROM BIOS (0 or 1=disabled) (default=do not change BIOS state)");
2511 module_param(noinit, int, 0);
2512 MODULE_PARM_DESC(noinit, "Disables W/SG/SD-RAM and bus interface initialization (0 or 1=do not initialize) (default=0)");
2513 module_param(memtype, int, 0);
2514 MODULE_PARM_DESC(memtype, "Memory type for G200/G400 (see Documentation/fb/matroxfb.rst for explanation) (default=3 for G200, 0 for G400)");
2515 module_param(mtrr, int, 0);
2516 MODULE_PARM_DESC(mtrr, "This speeds up video memory accesses (0=disabled or 1) (default=1)");
2517 module_param(sgram, int, 0);
2518 MODULE_PARM_DESC(sgram, "Indicates that G100/G200/G400 has SGRAM memory (0=SDRAM, 1=SGRAM) (default=0)");
2519 module_param(inv24, int, 0);
2520 MODULE_PARM_DESC(inv24, "Inverts clock polarity for 24bpp and loop frequency > 100MHz (default=do not invert polarity)");
2521 module_param(inverse, int, 0);
2522 MODULE_PARM_DESC(inverse, "Inverse (0 or 1) (default=0)");
2523 module_param(dev, int, 0);
2524 MODULE_PARM_DESC(dev, "Multihead support, attach to device ID (0..N) (default=all working)");
2525 module_param(vesa, int, 0);
2526 MODULE_PARM_DESC(vesa, "Startup videomode (0x000-0x1FF) (default=0x101)");
2527 module_param(xres, int, 0);
2528 MODULE_PARM_DESC(xres, "Horizontal resolution (px), overrides xres from vesa (default=vesa)");
2529 module_param(yres, int, 0);
2530 MODULE_PARM_DESC(yres, "Vertical resolution (scans), overrides yres from vesa (default=vesa)");
2531 module_param(upper, int, 0);
2532 MODULE_PARM_DESC(upper, "Upper blank space (scans), overrides upper from vesa (default=vesa)");
2533 module_param(lower, int, 0);
2534 MODULE_PARM_DESC(lower, "Lower blank space (scans), overrides lower from vesa (default=vesa)");
2535 module_param(vslen, int, 0);
2536 MODULE_PARM_DESC(vslen, "Vertical sync length (scans), overrides lower from vesa (default=vesa)");
2537 module_param(left, int, 0);
2538 MODULE_PARM_DESC(left, "Left blank space (px), overrides left from vesa (default=vesa)");
2539 module_param(right, int, 0);
2540 MODULE_PARM_DESC(right, "Right blank space (px), overrides right from vesa (default=vesa)");
2541 module_param(hslen, int, 0);
2542 MODULE_PARM_DESC(hslen, "Horizontal sync length (px), overrides hslen from vesa (default=vesa)");
2543 module_param(pixclock, int, 0);
2544 MODULE_PARM_DESC(pixclock, "Pixelclock (ns), overrides pixclock from vesa (default=vesa)");
2545 module_param(sync, int, 0);
2546 MODULE_PARM_DESC(sync, "Sync polarity, overrides sync from vesa (default=vesa)");
2547 module_param(depth, int, 0);
2548 MODULE_PARM_DESC(depth, "Color depth (0=text,8,15,16,24,32) (default=vesa)");
2549 module_param(maxclk, int, 0);
2550 MODULE_PARM_DESC(maxclk, "Startup maximal clock, 0-999MHz, 1000-999999kHz, 1000000-INF Hz");
2551 module_param(fh, int, 0);
2552 MODULE_PARM_DESC(fh, "Startup horizontal frequency, 0-999kHz, 1000-INF Hz");
2553 module_param(fv, int, 0);
2554 MODULE_PARM_DESC(fv, "Startup vertical frequency, 0-INF Hz\n"
2555 "You should specify \"fv:max_monitor_vsync,fh:max_monitor_hsync,maxclk:max_monitor_dotclock\"");
2556 module_param(grayscale, int, 0);
2557 MODULE_PARM_DESC(grayscale, "Sets display into grayscale. Works perfectly with paletized videomode (4, 8bpp), some limitations apply to 16, 24 and 32bpp videomodes (default=nograyscale)");
2558 module_param(cross4MB, int, 0);
2559 MODULE_PARM_DESC(cross4MB, "Specifies that 4MB boundary can be in middle of line. (default=autodetected)");
2560 module_param(dfp, int, 0);
2561 MODULE_PARM_DESC(dfp, "Specifies whether to use digital flat panel interface of G200/G400 (0 or 1) (default=0)");
2562 module_param(dfp_type, int, 0);
2563 MODULE_PARM_DESC(dfp_type, "Specifies DFP interface type (0 to 255) (default=read from hardware)");
2564 module_param_string(outputs, outputs, sizeof(outputs), 0);
2565 MODULE_PARM_DESC(outputs, "Specifies which CRTC is mapped to which output (string of up to three letters, consisting of 0 (disabled), 1 (CRTC1), 2 (CRTC2)) (default=111 for Gx50, 101 for G200/G400 with DFP, and 100 for all other devices)");
2566 #ifdef CONFIG_PPC_PMAC
2567 module_param_named(vmode, default_vmode, int, 0);
2568 MODULE_PARM_DESC(vmode, "Specify the vmode mode number that should be used (640x480 default)");
2569 module_param_named(cmode, default_cmode, int, 0);
2570 MODULE_PARM_DESC(cmode, "Specify the video depth that should be used (8bit default)");
2571 #endif
2572
2573 static int __init matroxfb_init(void){
2574
2575 DBG(__func__)
2576
2577 if (disabled)
2578 return -ENXIO;
2579
2580 if (depth == 0)
2581 depth = RSText;
2582 else if (depth == 4)
2583 depth = RS4bpp;
2584 else if (depth == 8)
2585 depth = RS8bpp;
2586 else if (depth == 15)
2587 depth = RS15bpp;
2588 else if (depth == 16)
2589 depth = RS16bpp;
2590 else if (depth == 24)
2591 depth = RS24bpp;
2592 else if (depth == 32)
2593 depth = RS32bpp;
2594 else if (depth != -1) {
2595 printk(KERN_ERR "matroxfb: depth %d is not supported, using default\n", depth);
2596 depth = -1;
2597 }
2598 matrox_init();
2599
2600 return 0;
2601 }
2602 #endif
2603
2604 module_init(matroxfb_init);
2605 module_exit(matrox_done);
2606 EXPORT_SYMBOL(matroxfb_register_driver);
2607 EXPORT_SYMBOL(matroxfb_unregister_driver);
2608 EXPORT_SYMBOL(matroxfb_wait_for_sync);
2609 EXPORT_SYMBOL(matroxfb_enable_irq);