Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *
0004  * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
0005  *
0006  * (c) 1998-2002 Petr Vandrovec <vandrove@vc.cvut.cz>
0007  *
0008  * Portions Copyright (c) 2001 Matrox Graphics Inc.
0009  *
0010  * Version: 1.65 2002/08/14
0011  *
0012  * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
0013  *
0014  * Contributors: "menion?" <menion@mindless.com>
0015  *                     Betatesting, fixes, ideas
0016  *
0017  *               "Kurt Garloff" <garloff@suse.de>
0018  *                     Betatesting, fixes, ideas, videomodes, videomodes timmings
0019  *
0020  *               "Tom Rini" <trini@kernel.crashing.org>
0021  *                     MTRR stuff, PPC cleanups, betatesting, fixes, ideas
0022  *
0023  *               "Bibek Sahu" <scorpio@dodds.net>
0024  *                     Access device through readb|w|l and write b|w|l
0025  *                     Extensive debugging stuff
0026  *
0027  *               "Daniel Haun" <haund@usa.net>
0028  *                     Testing, hardware cursor fixes
0029  *
0030  *               "Scott Wood" <sawst46+@pitt.edu>
0031  *                     Fixes
0032  *
0033  *               "Gerd Knorr" <kraxel@goldbach.isdn.cs.tu-berlin.de>
0034  *                     Betatesting
0035  *
0036  *               "Kelly French" <targon@hazmat.com>
0037  *               "Fernando Herrera" <fherrera@eurielec.etsit.upm.es>
0038  *                     Betatesting, bug reporting
0039  *
0040  *               "Pablo Bianucci" <pbian@pccp.com.ar>
0041  *                     Fixes, ideas, betatesting
0042  *
0043  *               "Inaky Perez Gonzalez" <inaky@peloncho.fis.ucm.es>
0044  *                     Fixes, enhandcements, ideas, betatesting
0045  *
0046  *               "Ryuichi Oikawa" <roikawa@rr.iiij4u.or.jp>
0047  *                     PPC betatesting, PPC support, backward compatibility
0048  *
0049  *               "Paul Womar" <Paul@pwomar.demon.co.uk>
0050  *               "Owen Waller" <O.Waller@ee.qub.ac.uk>
0051  *                     PPC betatesting
0052  *
0053  *               "Thomas Pornin" <pornin@bolet.ens.fr>
0054  *                     Alpha betatesting
0055  *
0056  *               "Pieter van Leuven" <pvl@iae.nl>
0057  *               "Ulf Jaenicke-Roessler" <ujr@physik.phy.tu-dresden.de>
0058  *                     G100 testing
0059  *
0060  *               "H. Peter Arvin" <hpa@transmeta.com>
0061  *                     Ideas
0062  *
0063  *               "Cort Dougan" <cort@cs.nmt.edu>
0064  *                     CHRP fixes and PReP cleanup
0065  *
0066  *               "Mark Vojkovich" <mvojkovi@ucsd.edu>
0067  *                     G400 support
0068  *
0069  *               "Samuel Hocevar" <sam@via.ecp.fr>
0070  *                     Fixes
0071  *
0072  *               "Anton Altaparmakov" <AntonA@bigfoot.com>
0073  *                     G400 MAX/non-MAX distinction
0074  *
0075  *               "Ken Aaker" <kdaaker@rchland.vnet.ibm.com>
0076  *                     memtype extension (needed for GXT130P RS/6000 adapter)
0077  *
0078  *               "Uns Lider" <unslider@miranda.org>
0079  *                     G100 PLNWT fixes
0080  *
0081  *               "Denis Zaitsev" <zzz@cd-club.ru>
0082  *                     Fixes
0083  *
0084  *               "Mike Pieper" <mike@pieper-family.de>
0085  *                     TVOut enhandcements, V4L2 control interface.
0086  *
0087  *               "Diego Biurrun" <diego@biurrun.de>
0088  *                     DFP testing
0089  *
0090  * (following author is not in any relation with this code, but his code
0091  *  is included in this driver)
0092  *
0093  * Based on framebuffer driver for VBE 2.0 compliant graphic boards
0094  *     (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
0095  *
0096  * (following author is not in any relation with this code, but his ideas
0097  *  were used when writing this driver)
0098  *
0099  *       FreeVBE/AF (Matrox), "Shawn Hargreaves" <shawn@talula.demon.co.uk>
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  * card parameters
0131  */
0132 
0133 /* --------------------------------------------------------------------- */
0134 
0135 static struct fb_var_screeninfo vesafb_defined = {
0136     640,480,640,480,/* W,H, W, H (virtual) load xres,xres_virtual*/
0137     0,0,        /* virtual -> visible no offset */
0138     8,      /* depth -> load bits_per_pixel */
0139     0,      /* greyscale ? */
0140     {0,0,0},    /* R */
0141     {0,0,0},    /* G */
0142     {0,0,0},    /* B */
0143     {0,0,0},    /* transparency */
0144     0,      /* standard pixel format */
0145     FB_ACTIVATE_NOW,
0146     -1,-1,
0147     FB_ACCELF_TEXT, /* accel flags */
0148     39721L,48L,16L,33L,10L,
0149     96L,2L,~0,  /* No sync info */
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     /* Make sure that displays are compatible */
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; /* No update pending anymore */
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         /* Clear any pending field interrupts */
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         /* Flush pending pan-at-vbl request... */
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     /* FB_ACTIVATE_VBL and we can acquire interrupts? Honor FB_ACTIVATE_VBL then... */
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         /* Abort any pending change */
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     /* Currently we are holding big kernel lock on all dead & usecount updates.
0359      * Destroy everything after all users release it. Especially do not unregister
0360      * framebuffer and iounmap memory, neither fbmem nor fbcon-cfb* does not check
0361      * for device unplugged when in use.
0362      * In future we should point mmio.vbase & video.vbase somewhere where we can
0363      * write data without causing too much damage...
0364      */
0365 
0366     minfo->dead = 1;
0367     if (minfo->usecount) {
0368         /* destroy it later */
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      * Open/Release the frame buffer device
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;  /* doc says 64; 32 is OK for G400 */
0460                 break;
0461         case 16:    rounding = 32;
0462                 break;
0463         case 24:    rounding = 64;  /* doc says 64; 32 is OK for G400 */
0464                 break;
0465         default:    rounding = 16;
0466                 /* on G400, 16 really does not work */
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;  /* pseudocolor... 16 entries HW palette */
0513         case 8:
0514             return 256; /* pseudocolor... 256 entries HW palette */
0515         case 16:
0516             return 16;  /* directcolor... 16 entries SW palette */
0517                     /* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
0518         case 24:
0519             return 16;  /* directcolor... 16 entries SW palette */
0520                     /* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
0521         case 32:
0522             return 16;  /* directcolor... 16 entries SW palette */
0523                     /* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
0524     }
0525     return 16;  /* return something reasonable... or panic()? */
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     /* There is hardware bug that no line can cross 4MB boundary */
0580     /* give up for CFB24, it is impossible to easy workaround it */
0581     /* for other try to do something */
0582     if (!minfo->capable.cross4MB && (memlen > 0x400000)) {
0583         if (bpp == 24) {
0584             /* sorry */
0585         } else {
0586             unsigned int linelen;
0587             unsigned int m1 = linelen = var->xres_virtual * bpp / 8;
0588             unsigned int m2 = PAGE_SIZE;    /* or 128 if you do not need PAGE ALIGNED address */
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     /* YDSTLEN contains only signed 16bit value */
0603     if (var->yres_virtual > 32767)
0604         var->yres_virtual = 32767;
0605     /* we must round yres/xres down, we already rounded y/xres_virtual up
0606        if it was possible. We should return -EINVAL, but I disagree */
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--; /* an artificial value - 15 */
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      *  Set a single color register. The values supplied are
0653      *  already rounded down to the hardware's capabilities
0654      *  (according to the entries in the `var' structure). Return
0655      *  != 0 for invalid regno.
0656      */
0657 
0658     if (regno >= minfo->curr.cmap_len)
0659         return 1;
0660 
0661     if (minfo->fbcon.var.grayscale) {
0662         /* gray = 0.30*R + 0.59*G + 0.11*B */
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); /* for 1:5:5:5 */
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); /* 8:8:8:8 */
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;  /* 8 for 8bpp, 4 for 16bpp, 2 for 32bpp */
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             /* CRTC1 delays */
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     /* BTW, on my PIII/450 with G400, reading M_INSTS1
0853        byte makes this call about 12% slower (1.70 vs. 2.05 us
0854        per ioctl()) */
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         /* Only one writer, aligned int value...
0864            it should work without lock and without atomic_t */
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 /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
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; /* works ??? */
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 /*  .fb_fillrect =  <set by matrox_cfbX_init>, */
1213 /*  .fb_copyarea =  <set by matrox_cfbX_init>, */
1214 /*  .fb_imageblit = <set by matrox_cfbX_init>, */
1215 /*  .fb_cursor =    <set by matrox_cfbX_init>, */
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 /* 9-F */
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 },   /* textmode with (default) VGA8x16 */
1236     { {  0, 6, 0}, { 0, 6, 0}, { 0, 6, 0}, {  0, 0, 0},  0 },   /* textmode hardwired to VGA8x8 */
1237 };
1238 
1239 /* initialized by setup, see explanation at end of file (search for MODULE_PARM_DESC) */
1240 static unsigned int mem;        /* "matroxfb:mem:xxxxxM" */
1241 static int option_precise_width = 1;    /* cannot be changed, option_precise_width==0 must imply noaccel */
1242 static int inv24;           /* "matroxfb:inv24" */
1243 static int cross4MB = -1;       /* "matroxfb:cross4MB" */
1244 static int disabled;            /* "matroxfb:disabled" */
1245 static int noaccel;         /* "matroxfb:noaccel" */
1246 static int nopan;           /* "matroxfb:nopan" */
1247 static int no_pci_retry;        /* "matroxfb:nopciretry" */
1248 static int novga;           /* "matroxfb:novga" */
1249 static int nobios;          /* "matroxfb:nobios" */
1250 static int noinit = 1;          /* "matroxfb:init" */
1251 static int inverse;         /* "matroxfb:inverse" */
1252 static int sgram;           /* "matroxfb:sgram" */
1253 static int mtrr = 1;            /* "matroxfb:nomtrr" */
1254 static int grayscale;           /* "matroxfb:grayscale" */
1255 static int dev = -1;            /* "matroxfb:dev:xxxxx" */
1256 static unsigned int vesa = ~0;      /* "matroxfb:vesa:xxxxx" */
1257 static int depth = -1;          /* "matroxfb:depth:xxxxx" */
1258 static unsigned int xres;       /* "matroxfb:xres:xxxxx" */
1259 static unsigned int yres;       /* "matroxfb:yres:xxxxx" */
1260 static unsigned int upper = ~0;     /* "matroxfb:upper:xxxxx" */
1261 static unsigned int lower = ~0;     /* "matroxfb:lower:xxxxx" */
1262 static unsigned int vslen;      /* "matroxfb:vslen:xxxxx" */
1263 static unsigned int left = ~0;      /* "matroxfb:left:xxxxx" */
1264 static unsigned int right = ~0;     /* "matroxfb:right:xxxxx" */
1265 static unsigned int hslen;      /* "matroxfb:hslen:xxxxx" */
1266 static unsigned int pixclock;       /* "matroxfb:pixclock:xxxxx" */
1267 static int sync = -1;           /* "matroxfb:sync:xxxxx" */
1268 static unsigned int fv;         /* "matroxfb:fv:xxxxx" */
1269 static unsigned int fh;         /* "matroxfb:fh:xxxxxk" */
1270 static unsigned int maxclk;     /* "matroxfb:maxclk:xxxxM" */
1271 static int dfp;             /* "matroxfb:dfp */
1272 static int dfp_type = -1;       /* "matroxfb:dfp:xxx */
1273 static int memtype = -1;        /* "matroxfb:memtype:xxx" */
1274 static char outputs[8];         /* "matroxfb:outputs:xxx" */
1275 
1276 #ifndef MODULE
1277 static char videomode[64];      /* "matroxfb:mode:xxxxx" or "matroxfb:xxxxx" */
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;   /* must be X*2MB (really it must be 2 or X*4MB) */
1294     /* at least 2MB */
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  /* CONFIG_FB_MATROX_MILLENIUM */
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  /* CONFIG_FB_MATROX_MYSTIQUE */
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 /* from doc it looks like that accelerator can draw only to low 16MB :-( Direct accesses & displaying are OK for
1386    whole 32MB */
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 /* #define DEVF_recycled    0x0040  */
1402 /* #define DEVF_recycled    0x0080  */
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) /* no doc, no vxres... */
1414 #define DEVF_G200   (DEVF_G2CORE)
1415 #define DEVF_G400   (DEVF_G2CORE | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2)
1416 /* if you'll find how to drive DFP... */
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     /* 640x480 @ 60Hz, 31.5 kHz */
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 /* !MODULE */
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     /* Nullify this option for subsequent adapters */
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     /* set default values... */
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     /* convert mem (autodetect k, M) */
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; /* clear BIG_ENDIAN */
1747         mga_option |= MX_OPTION_BSWAP;
1748         /* disable palette snooping */
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         /* select non-DMA memory for PCI_MGA_DATA, otherwise dump of PCI cfg space can lock PCI bus */
1762         /* maybe preinit() candidate, but it is same... for all devices... at this time... */
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; /* TBD */
1797 
1798     /* static settings */
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 |     /* Prefer panning for scroll under MC viewer/edit */
1812                       FBINFO_HWACCEL_COPYAREA |  /* We have hw-assisted bmove */
1813                       FBINFO_HWACCEL_FILLRECT |  /* And fillrect */
1814                       FBINFO_HWACCEL_IMAGEBLIT | /* And imageblit */
1815                       FBINFO_HWACCEL_XPAN |      /* And we support both horizontal */
1816                       FBINFO_HWACCEL_YPAN |      /* And vertical panning */
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     /* mode database is marked __init!!! */
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 /* !MODULE */
1828 
1829     /* mode modifiers */
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     /* fv, fh, maxclk limits was specified */
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)        /* > 500MHz */
1878             pixclock = 4000;    /* 250MHz */
1879         if (pixclock > 1000000)
1880             pixclock = 1000000; /* 1MHz */
1881         vesafb_defined.pixclock = pixclock;
1882     }
1883 
1884     /* FIXME: Where to move this?! */
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             /* Note: mac_vmode_to_var() does not set all parameters */
1902             vesafb_defined = var;
1903         }
1904     }
1905 #endif /* !MODULE */
1906 #endif /* CONFIG_PPC_PMAC */
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; /* large enough to be INF, but small enough
1912                             to yres_virtual * xres_virtual < 2^32 */
1913     }
1914     matroxfb_init_fix(minfo);
1915     minfo->fbcon.screen_base = vaddr_va(minfo->video.vbase);
1916     /* Normalize values (namely yres_virtual) */
1917     matroxfb_check_var(&vesafb_defined, &minfo->fbcon);
1918     /* And put it into "current" var. Do NOT program hardware yet, or we'll not take over
1919      * vgacon correctly. fbcon_startup will call fb_set_par for us, WITHOUT check_var,
1920      * and unfortunately it will do it BEFORE vgacon contents is saved, so it won't work
1921      * anyway. But we at least tried... */
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 /* We do not have to set currcon to 0... register_framebuffer do it for us on first console
1932  * and we do not want currcon == 0 for subsequent framebuffers */
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     /* there is no console on this fb... but we have to initialize hardware
1941      * until someone tells me what is proper thing to do */
1942     if (!minfo->initialized) {
1943         fb_info(&minfo->fbcon, "initializing hardware\n");
1944         /* We have to use FB_ACTIVATE_FORCE, as we had to put vesafb_defined to the fbcon.var
1945          * already before, so register_framebuffer works correctly. */
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     /* not match... */
2056     if (!b->vendor)
2057         return -ENODEV;
2058     if (dev > 0) {
2059         /* not requested one... */
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     /* DEVFLAGS */
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         /* subsequent heads always needs initialization and must not enable BIOS */
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 /* **************************** init-time only **************************** */
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  /* 132 x 43 text */
2186 #define RS1056x400  13  /* 132 x 50 text */
2187 #define RS1056x480  14  /* 132 x 60 text */
2188 #define RSNoxNo     15
2189 /* 10-FF */
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 /* default must be first */
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     /* fh from kHz to Hz */
2267     if (fh < 1000)
2268         fh *= 1000; /* 1kHz minimum */
2269     /* maxclk */
2270     if (maxclk < 1000) maxclk *= 1000;  /* kHz -> Hz, MHz -> kHz */
2271     if (maxclk < 1000000) maxclk *= 1000;   /* kHz -> Hz, 1MHz minimum */
2272     /* fix VESA number */
2273     if (vesa != ~0)
2274         vesa &= 0x1DFF;     /* mask out clearscreen, acceleration and so on */
2275 
2276     /* static settings */
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;   /* accept all new devices... */
2315     return err;
2316 }
2317 
2318 /* **************************** exit-time only **************************** */
2319 
2320 static void __exit matrox_done(void) {
2321     pci_unregister_driver(&matroxfb_driver);
2322 }
2323 
2324 #ifndef MODULE
2325 
2326 /* ************************* init in-kernel code ************************** */
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")) /* nodisabled does not exist */
2417             disabled = 1;
2418         else if (!strcmp(this_opt, "enabled"))  /* noenabled does not exist */
2419             disabled = 0;
2420         else if (!strcmp(this_opt, "sgram"))    /* nosgram == sdram */
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     /* never return failure, user can hotplug matrox later... */
2486     return err;
2487 }
2488 
2489 #else
2490 
2491 /* *************************** init module code **************************** */
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     /* never return failure; user can hotplug matrox later... */
2600     return 0;
2601 }
2602 #endif  /* MODULE */
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);