X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fvideo%2Fmatrox%2Fmatroxfb_base.c;h=cb2aa402ddfd93eb0b180f9a05c74909c2be859a;hb=refs%2Fheads%2Fvserver;hp=1388470cc33c1ef49453ec3b7b6d8856edb58fef;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c index 1388470cc..cb2aa402d 100644 --- a/drivers/video/matrox/matroxfb_base.c +++ b/drivers/video/matrox/matroxfb_base.c @@ -99,10 +99,10 @@ * */ -/* make checkconfig does not check included files... */ -#include #include +#define __OLD_VIDIOC_ + #include "matroxfb_base.h" #include "matroxfb_misc.h" #include "matroxfb_accel.h" @@ -116,6 +116,7 @@ #include #ifdef CONFIG_PPC_PMAC +#include unsigned char nvram_read_byte(int); static int default_vmode = VMODE_NVRAM; static int default_cmode = CMODE_NVRAM; @@ -158,9 +159,9 @@ static void update_crtc2(WPMINFO unsigned int pos) { /* Make sure that displays are compatible */ if (info && (info->fbcon.var.bits_per_pixel == ACCESS_FBINFO(fbcon).var.bits_per_pixel) - && (info->fbcon.var.xres_virtual == ACCESS_FBINFO(fbcon).var.xres_virtual) - && (info->fbcon.var.green.length == ACCESS_FBINFO(fbcon).var.green.length) - ) { + && (info->fbcon.var.xres_virtual == ACCESS_FBINFO(fbcon).var.xres_virtual) + && (info->fbcon.var.green.length == ACCESS_FBINFO(fbcon).var.green.length) + ) { switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) { case 16: case 32: @@ -197,7 +198,7 @@ static void matroxfb_crtc1_panpos(WPMINFO2) { } } -static irqreturn_t matrox_irq(int irq, void *dev_id, struct pt_regs *fp) +static irqreturn_t matrox_irq(int irq, void *dev_id) { u_int32_t status; int handled = 0; @@ -224,7 +225,7 @@ static irqreturn_t matrox_irq(int irq, void *dev_id, struct pt_regs *fp) int matroxfb_enable_irq(WPMINFO int reenable) { u_int32_t bm; - + if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) bm = 0x220; else @@ -232,7 +233,7 @@ int matroxfb_enable_irq(WPMINFO int reenable) { if (!test_and_set_bit(0, &ACCESS_FBINFO(irq_flags))) { if (request_irq(ACCESS_FBINFO(pcidev)->irq, matrox_irq, - SA_SHIRQ, "matroxfb", MINFO)) { + IRQF_SHARED, "matroxfb", MINFO)) { clear_bit(0, &ACCESS_FBINFO(irq_flags)); return -EINVAL; } @@ -241,7 +242,7 @@ int matroxfb_enable_irq(WPMINFO int reenable) { mga_outl(M_IEN, mga_inl(M_IEN) | bm); } else if (reenable) { u_int32_t ien; - + ien = mga_inl(M_IEN); if ((ien & bm) != bm) { printk(KERN_DEBUG "matroxfb: someone disabled IRQ [%08X]\n", ien); @@ -264,7 +265,6 @@ static void matroxfb_disable_irq(WPMINFO2) { } int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) { - wait_queue_t __wait; struct matrox_vsync *vs; unsigned int cnt; int ret; @@ -286,7 +286,6 @@ int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) { if (ret) { return ret; } - init_waitqueue_entry(&__wait, current); cnt = vs->cnt; ret = wait_event_interruptible_timeout(vs->wait, cnt != vs->cnt, HZ/10); @@ -349,7 +348,7 @@ static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) { mga_setr(M_EXTVGA_INDEX, 0x00, p2); } matroxfb_DAC_unlock_irqrestore(flags); - + update_crtc2(PMINFO pos); CRITEND @@ -392,7 +391,7 @@ static void matroxfb_remove(WPMINFO int dummy) { static int matroxfb_open(struct fb_info *info, int user) { MINFO_FROM_INFO(info); - + DBG_LOOP(__FUNCTION__) if (ACCESS_FBINFO(dead)) { @@ -408,7 +407,7 @@ static int matroxfb_open(struct fb_info *info, int user) static int matroxfb_release(struct fb_info *info, int user) { MINFO_FROM_INFO(info); - + DBG_LOOP(__FUNCTION__) if (user) { @@ -500,10 +499,6 @@ static int matroxfb_pitch_adjust(CPMINFO int xres, int bpp) { } else { xres_new = matroxfb_test_and_set_rounding(PMINFO xres, bpp); } - if (!xres_new) return 0; - if (xres != xres_new) { - printk(KERN_INFO "matroxfb: cannot set xres to %d, rounded up to %d\n", xres, xres_new); - } return xres_new; } @@ -835,6 +830,7 @@ static int matroxfb_set_par(struct fb_info *info) matrox_cfbX_init(PMINFO2); } } + ACCESS_FBINFO(initialized) = 1; return 0; } @@ -859,7 +855,7 @@ static int matroxfb_get_vblank(WPMINFO struct fb_vblank *vblank) vblank->flags |= FB_VBLANK_VBLANKING; if (test_bit(0, &ACCESS_FBINFO(irq_flags))) { vblank->flags |= FB_VBLANK_HAVE_COUNT; - /* Only one writer, aligned int value... + /* Only one writer, aligned int value... it should work without lock and without atomic_t */ vblank->count = ACCESS_FBINFO(crtc1).vsync.cnt; } @@ -870,12 +866,12 @@ static struct matrox_altout panellink_output = { .name = "Panellink output", }; -static int matroxfb_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg, - struct fb_info *info) +static int matroxfb_ioctl(struct fb_info *info, + unsigned int cmd, unsigned long arg) { + void __user *argp = (void __user *)arg; MINFO_FROM_INFO(info); - + DBG(__FUNCTION__) if (ACCESS_FBINFO(dead)) { @@ -891,7 +887,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file, err = matroxfb_get_vblank(PMINFO &vblank); if (err) return err; - if (copy_to_user((struct fb_vblank*)arg, &vblank, sizeof(vblank))) + if (copy_to_user(argp, &vblank, sizeof(vblank))) return -EFAULT; return 0; } @@ -899,7 +895,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file, { u_int32_t crt; - if (get_user(crt, (u_int32_t *)arg)) + if (get_user(crt, (u_int32_t __user *)arg)) return -EFAULT; return matroxfb_wait_for_sync(PMINFO crt); @@ -910,7 +906,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file, struct matrox_altout *oproc; int val; - if (copy_from_user(&mom, (struct matroxioc_output_mode*)arg, sizeof(mom))) + if (copy_from_user(&mom, argp, sizeof(mom))) return -EFAULT; if (mom.output >= MATROXFB_MAX_OUTPUTS) return -ENXIO; @@ -960,7 +956,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file, struct matrox_altout *oproc; int val; - if (copy_from_user(&mom, (struct matroxioc_output_mode*)arg, sizeof(mom))) + if (copy_from_user(&mom, argp, sizeof(mom))) return -EFAULT; if (mom.output >= MATROXFB_MAX_OUTPUTS) return -ENXIO; @@ -975,7 +971,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file, up_read(&ACCESS_FBINFO(altout.lock)); if (val) return val; - if (copy_to_user((struct matroxioc_output_mode*)arg, &mom, sizeof(mom))) + if (copy_to_user(argp, &mom, sizeof(mom))) return -EFAULT; return 0; } @@ -985,7 +981,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file, int i; int changes; - if (copy_from_user(&tmp, (u_int32_t*)arg, sizeof(tmp))) + if (copy_from_user(&tmp, argp, sizeof(tmp))) return -EFAULT; for (i = 0; i < 32; i++) { if (tmp & (1 << i)) { @@ -1040,7 +1036,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file, conn |= 1 << i; } } - if (put_user(conn, (u_int32_t*)arg)) + if (put_user(conn, (u_int32_t __user *)arg)) return -EFAULT; return 0; } @@ -1065,7 +1061,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file, if (conn & MATROXFB_OUTPUT_CONN_SECONDARY) conn &= ~MATROXFB_OUTPUT_CONN_DFP; } - if (put_user(conn, (u_int32_t*)arg)) + if (put_user(conn, (u_int32_t __user *)arg)) return -EFAULT; return 0; } @@ -1079,31 +1075,31 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file, conn |= 1 << i; } } - if (put_user(conn, (u_int32_t*)arg)) + if (put_user(conn, (u_int32_t __user *)arg)) return -EFAULT; return 0; } case VIDIOC_QUERYCAP: { struct v4l2_capability r; - + memset(&r, 0, sizeof(r)); strcpy(r.driver, "matroxfb"); strcpy(r.card, "Matrox"); sprintf(r.bus_info, "PCI:%s", pci_name(ACCESS_FBINFO(pcidev))); r.version = KERNEL_VERSION(1,0,0); r.capabilities = V4L2_CAP_VIDEO_OUTPUT; - if (copy_to_user((void*)arg, &r, sizeof(r))) + if (copy_to_user(argp, &r, sizeof(r))) return -EFAULT; return 0; - + } case VIDIOC_QUERYCTRL: { struct v4l2_queryctrl qctrl; int err; - if (copy_from_user(&qctrl, (struct v4l2_queryctrl*)arg, sizeof(qctrl))) + if (copy_from_user(&qctrl, argp, sizeof(qctrl))) return -EFAULT; down_read(&ACCESS_FBINFO(altout).lock); @@ -1116,7 +1112,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file, } up_read(&ACCESS_FBINFO(altout).lock); if (err >= 0 && - copy_to_user((struct v4l2_queryctrl*)arg, &qctrl, sizeof(qctrl))) + copy_to_user(argp, &qctrl, sizeof(qctrl))) return -EFAULT; return err; } @@ -1125,7 +1121,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file, struct v4l2_control ctrl; int err; - if (copy_from_user(&ctrl, (struct v4l2_control*)arg, sizeof(ctrl))) + if (copy_from_user(&ctrl, argp, sizeof(ctrl))) return -EFAULT; down_read(&ACCESS_FBINFO(altout).lock); @@ -1138,16 +1134,17 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file, } up_read(&ACCESS_FBINFO(altout).lock); if (err >= 0 && - copy_to_user((struct v4l2_control*)arg, &ctrl, sizeof(ctrl))) + copy_to_user(argp, &ctrl, sizeof(ctrl))) return -EFAULT; return err; } + case VIDIOC_S_CTRL_OLD: case VIDIOC_S_CTRL: { struct v4l2_control ctrl; int err; - if (copy_from_user(&ctrl, (struct v4l2_control*)arg, sizeof(ctrl))) + if (copy_from_user(&ctrl, argp, sizeof(ctrl))) return -EFAULT; down_read(&ACCESS_FBINFO(altout).lock); @@ -1180,11 +1177,11 @@ static int matroxfb_blank(int blank, struct fb_info *info) return 1; switch (blank) { - case 1: seq = 0x20; crtc = 0x00; break; /* works ??? */ - case 2: seq = 0x20; crtc = 0x10; break; - case 3: seq = 0x20; crtc = 0x20; break; - case 4: seq = 0x20; crtc = 0x30; break; - default: seq = 0x00; crtc = 0x00; break; + case FB_BLANK_NORMAL: seq = 0x20; crtc = 0x00; break; /* works ??? */ + case FB_BLANK_VSYNC_SUSPEND: seq = 0x20; crtc = 0x10; break; + case FB_BLANK_HSYNC_SUSPEND: seq = 0x20; crtc = 0x20; break; + case FB_BLANK_POWERDOWN: seq = 0x20; crtc = 0x30; break; + default: seq = 0x00; crtc = 0x00; break; } CRITBEGIN @@ -1272,6 +1269,7 @@ static unsigned int maxclk; /* "matrox:maxclk:xxxxM" */ static int dfp; /* "matrox:dfp */ static int dfp_type = -1; /* "matrox:dfp:xxx */ static int memtype = -1; /* "matrox:memtype:xxx" */ +static char outputs[8]; /* "matrox:outputs:xxx" */ #ifndef MODULE static char videomode[64]; /* "matrox:mode:xxxxx" or "matrox:xxxxx" */ @@ -1281,7 +1279,7 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi vaddr_t vm; unsigned int offs; unsigned int offs2; - unsigned char store; + unsigned char orig; unsigned char bytes[32]; unsigned char* tmp; @@ -1294,18 +1292,15 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi if (maxSize > 0x2000000) maxSize = 0x2000000; mga_outb(M_EXTVGA_INDEX, 0x03); - mga_outb(M_EXTVGA_DATA, mga_inb(M_EXTVGA_DATA) | 0x80); + orig = mga_inb(M_EXTVGA_DATA); + mga_outb(M_EXTVGA_DATA, orig | 0x80); - store = mga_readb(vm, 0x1234); tmp = bytes; for (offs = 0x100000; offs < maxSize; offs += 0x200000) *tmp++ = mga_readb(vm, offs); for (offs = 0x100000; offs < maxSize; offs += 0x200000) mga_writeb(vm, offs, 0x02); - if (ACCESS_FBINFO(features.accel.has_cacheflush)) - mga_outb(M_CACHEFLUSH, 0x00); - else - mga_writeb(vm, 0x1234, 0x99); + mga_outb(M_CACHEFLUSH, 0x00); for (offs = 0x100000; offs < maxSize; offs += 0x200000) { if (mga_readb(vm, offs) != 0x02) break; @@ -1316,10 +1311,9 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi tmp = bytes; for (offs2 = 0x100000; offs2 < maxSize; offs2 += 0x200000) mga_writeb(vm, offs2, *tmp++); - mga_writeb(vm, 0x1234, store); mga_outb(M_EXTVGA_INDEX, 0x03); - mga_outb(M_EXTVGA_DATA, mga_inb(M_EXTVGA_DATA) & ~0x80); + mga_outb(M_EXTVGA_DATA, orig); *realSize = offs - 0x100000; #ifdef CONFIG_FB_MATROX_MILLENIUM @@ -1342,7 +1336,7 @@ static struct video_board vbMillennium2A = {0x1000000, 0x0800000, FB_ACCEL_MATRO #ifdef CONFIG_FB_MATROX_MYSTIQUE static struct video_board vbMystique = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGA1064SG, &matrox_mystique}; #endif /* CONFIG_FB_MATROX_MYSTIQUE */ -#ifdef CONFIG_FB_MATROX_G100 +#ifdef CONFIG_FB_MATROX_G static struct video_board vbG100 = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGAG100, &matrox_G100}; static struct video_board vbG200 = {0x1000000, 0x1000000, FB_ACCEL_MATROX_MGAG200, &matrox_G100}; #ifdef CONFIG_FB_MATROX_32MB @@ -1425,8 +1419,22 @@ static struct board { MGA_1164, &vbMystique, "Mystique 220 (PCI)"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS_AGP, 0x02, + 0, 0, + DEVF_VIDEO64BIT | DEVF_CROSS4MB, + 180000, + MGA_1064, + &vbMystique, + "Mystique (AGP)"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS_AGP, 0xFF, + 0, 0, + DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB, + 220000, + MGA_1164, + &vbMystique, + "Mystique 220 (AGP)"}, #endif -#ifdef CONFIG_FB_MATROX_G100 +#ifdef CONFIG_FB_MATROX_G {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_MM, 0xFF, 0, 0, DEVF_G100, @@ -1537,12 +1545,50 @@ static struct fb_videomode defaultmode = { static int hotplug = 0; +static void setDefaultOutputs(WPMINFO2) { + unsigned int i; + const char* ptr; + + ACCESS_FBINFO(outputs[0]).default_src = MATROXFB_SRC_CRTC1; + if (ACCESS_FBINFO(devflags.g450dac)) { + ACCESS_FBINFO(outputs[1]).default_src = MATROXFB_SRC_CRTC1; + ACCESS_FBINFO(outputs[2]).default_src = MATROXFB_SRC_CRTC1; + } else if (dfp) { + ACCESS_FBINFO(outputs[2]).default_src = MATROXFB_SRC_CRTC1; + } + ptr = outputs; + for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { + char c = *ptr++; + + if (c == 0) { + break; + } + if (c == '0') { + ACCESS_FBINFO(outputs[i]).default_src = MATROXFB_SRC_NONE; + } else if (c == '1') { + ACCESS_FBINFO(outputs[i]).default_src = MATROXFB_SRC_CRTC1; + } else if (c == '2' && ACCESS_FBINFO(devflags.crtc2)) { + ACCESS_FBINFO(outputs[i]).default_src = MATROXFB_SRC_CRTC2; + } else { + printk(KERN_ERR "matroxfb: Unknown outputs setting\n"); + break; + } + } + /* Nullify this option for subsequent adapters */ + outputs[0] = 0; +} + static int initMatrox2(WPMINFO struct board* b){ unsigned long ctrlptr_phys = 0; unsigned long video_base_phys = 0; unsigned int memsize; int err; + static struct pci_device_id intel_82437[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437) }, + { }, + }; + DBG(__FUNCTION__) /* set default values... */ @@ -1577,20 +1623,18 @@ static int initMatrox2(WPMINFO struct board* b){ ACCESS_FBINFO(devflags.crtc2) = (b->flags & DEVF_CRTC2) != 0; ACCESS_FBINFO(devflags.maven_capable) = (b->flags & DEVF_MAVEN_CAPABLE) != 0; ACCESS_FBINFO(devflags.dualhead) = (b->flags & DEVF_DUALHEAD) != 0; + ACCESS_FBINFO(devflags.dfp_type) = dfp_type; + ACCESS_FBINFO(devflags.g450dac) = (b->flags & DEVF_G450DAC) != 0; + ACCESS_FBINFO(devflags.textstep) = ACCESS_FBINFO(devflags.vgastep) * ACCESS_FBINFO(devflags.textmode); + ACCESS_FBINFO(devflags.textvram) = 65536 / ACCESS_FBINFO(devflags.textmode); + setDefaultOutputs(PMINFO2); if (b->flags & DEVF_PANELLINK_CAPABLE) { ACCESS_FBINFO(outputs[2]).data = MINFO; ACCESS_FBINFO(outputs[2]).output = &panellink_output; - if (dfp) - ACCESS_FBINFO(outputs[2]).src = MATROXFB_SRC_CRTC1; - else - ACCESS_FBINFO(outputs[2]).src = MATROXFB_SRC_NONE; + ACCESS_FBINFO(outputs[2]).src = ACCESS_FBINFO(outputs[2]).default_src; ACCESS_FBINFO(outputs[2]).mode = MATROXFB_OUTPUT_MODE_MONITOR; ACCESS_FBINFO(devflags.panellink) = 1; } - ACCESS_FBINFO(devflags.dfp_type) = dfp_type; - ACCESS_FBINFO(devflags.g450dac) = (b->flags & DEVF_G450DAC) != 0; - ACCESS_FBINFO(devflags.textstep) = ACCESS_FBINFO(devflags.vgastep) * ACCESS_FBINFO(devflags.textmode); - ACCESS_FBINFO(devflags.textvram) = 65536 / ACCESS_FBINFO(devflags.textmode); if (ACCESS_FBINFO(capable.cross4MB) < 0) ACCESS_FBINFO(capable.cross4MB) = b->flags & DEVF_CROSS4MB; @@ -1647,9 +1691,9 @@ static int initMatrox2(WPMINFO struct board* b){ pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_COMMAND, &cmd); mga_option &= 0x7FFFFFFF; /* clear BIG_ENDIAN */ mga_option |= MX_OPTION_BSWAP; - /* disable palette snooping */ - cmd &= ~PCI_COMMAND_VGA_PALETTE; - if (pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437, NULL)) { + /* disable palette snooping */ + cmd &= ~PCI_COMMAND_VGA_PALETTE; + if (pci_dev_present(intel_82437)) { if (!(mga_option & 0x20000000) && !ACCESS_FBINFO(devflags.nopciretry)) { printk(KERN_WARNING "matroxfb: Disabling PCI retries due to i82437 present\n"); } @@ -1678,7 +1722,6 @@ static int initMatrox2(WPMINFO struct board* b){ } ACCESS_FBINFO(devflags.ydstorg) = 0; - ACCESS_FBINFO(fbcon.currcon) = -1; ACCESS_FBINFO(video.base) = video_base_phys; ACCESS_FBINFO(video.len_usable) = ACCESS_FBINFO(video.len); if (ACCESS_FBINFO(video.len_usable) > b->base->maxdisplayable) @@ -1717,6 +1760,12 @@ static int initMatrox2(WPMINFO struct board* b){ ACCESS_FBINFO(fbcon.pseudo_palette) = ACCESS_FBINFO(cmap); /* after __init time we are like module... no logo */ ACCESS_FBINFO(fbcon.flags) = hotplug ? FBINFO_FLAG_MODULE : FBINFO_FLAG_DEFAULT; + ACCESS_FBINFO(fbcon.flags) |= FBINFO_PARTIAL_PAN_OK | /* Prefer panning for scroll under MC viewer/edit */ + FBINFO_HWACCEL_COPYAREA | /* We have hw-assisted bmove */ + FBINFO_HWACCEL_FILLRECT | /* And fillrect */ + FBINFO_HWACCEL_IMAGEBLIT | /* And imageblit */ + FBINFO_HWACCEL_XPAN | /* And we support both horizontal */ + FBINFO_HWACCEL_YPAN; /* And vertical panning */ ACCESS_FBINFO(video.len_usable) &= PAGE_MASK; fb_alloc_cmap(&ACCESS_FBINFO(fbcon.cmap), 256, 1); @@ -1761,12 +1810,12 @@ static int initMatrox2(WPMINFO struct board* b){ if (fv) { tmp = fv * (vesafb_defined.upper_margin + vesafb_defined.yres - + vesafb_defined.lower_margin + vesafb_defined.vsync_len); + + vesafb_defined.lower_margin + vesafb_defined.vsync_len); if ((tmp < fh) || (fh == 0)) fh = tmp; } if (fh) { tmp = fh * (vesafb_defined.left_margin + vesafb_defined.xres - + vesafb_defined.right_margin + vesafb_defined.hsync_len); + + vesafb_defined.right_margin + vesafb_defined.hsync_len); if ((tmp < maxclk) || (maxclk == 0)) maxclk = tmp; } tmp = (maxclk + 499) / 500; @@ -1786,7 +1835,7 @@ static int initMatrox2(WPMINFO struct board* b){ /* FIXME: Where to move this?! */ #if defined(CONFIG_PPC_PMAC) #ifndef MODULE - if (_machine == _MACH_Pmac) { + if (machine_is(powermac)) { struct fb_var_screeninfo var; if (default_vmode <= 0 || default_vmode > VMODE_MAX) default_vmode = VMODE_640_480_60; @@ -1813,6 +1862,15 @@ static int initMatrox2(WPMINFO struct board* b){ to yres_virtual * xres_virtual < 2^32 */ } matroxfb_init_fix(PMINFO2); + ACCESS_FBINFO(fbcon.screen_base) = vaddr_va(ACCESS_FBINFO(video.vbase)); + matroxfb_update_fix(PMINFO2); + /* Normalize values (namely yres_virtual) */ + matroxfb_check_var(&vesafb_defined, &ACCESS_FBINFO(fbcon)); + /* And put it into "current" var. Do NOT program hardware yet, or we'll not take over + * vgacon correctly. fbcon_startup will call fb_set_par for us, WITHOUT check_var, + * and unfortunately it will do it BEFORE vgacon contents is saved, so it won't work + * anyway. But we at least tried... */ + ACCESS_FBINFO(fbcon.var) = vesafb_defined; err = -EINVAL; printk(KERN_INFO "matroxfb: %dx%dx%dbpp (virtual: %dx%d)\n", @@ -1824,18 +1882,24 @@ static int initMatrox2(WPMINFO struct board* b){ /* We do not have to set currcon to 0... register_framebuffer do it for us on first console * and we do not want currcon == 0 for subsequent framebuffers */ + ACCESS_FBINFO(fbcon).device = &ACCESS_FBINFO(pcidev)->dev; if (register_framebuffer(&ACCESS_FBINFO(fbcon)) < 0) { goto failVideoIO; } printk("fb%d: %s frame buffer device\n", ACCESS_FBINFO(fbcon.node), ACCESS_FBINFO(fbcon.fix.id)); - if (ACCESS_FBINFO(fbcon.currcon) < 0) { - /* there is no console on this fb... but we have to initialize hardware - * until someone tells me what is proper thing to do */ + + /* there is no console on this fb... but we have to initialize hardware + * until someone tells me what is proper thing to do */ + if (!ACCESS_FBINFO(initialized)) { printk(KERN_INFO "fb%d: initializing hardware\n", - ACCESS_FBINFO(fbcon.node)); + ACCESS_FBINFO(fbcon.node)); + /* We have to use FB_ACTIVATE_FORCE, as we had to put vesafb_defined to the fbcon.var + * already before, so register_framebuffer works correctly. */ + vesafb_defined.activate |= FB_ACTIVATE_FORCE; fb_set_var(&ACCESS_FBINFO(fbcon), &vesafb_defined); } + return 0; failVideoIO:; matroxfb_g450_shutdown(PMINFO2); @@ -1850,8 +1914,8 @@ fail:; return err; } -LIST_HEAD(matroxfb_list); -LIST_HEAD(matroxfb_driver_list); +static LIST_HEAD(matroxfb_list); +static LIST_HEAD(matroxfb_driver_list); #define matroxfb_l(x) list_entry(x, struct matrox_fb_info, next_fb) #define matroxfb_driver_l(x) list_entry(x, struct matroxfb_driver, node) @@ -1952,11 +2016,11 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm } /* not match... */ if (!b->vendor) - return -1; + return -ENODEV; if (dev > 0) { /* not requested one... */ dev--; - return -1; + return -ENODEV; } pci_read_config_dword(pdev, PCI_COMMAND, &cmd); if (pci_enable_device(pdev)) { @@ -1964,7 +2028,7 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm } #ifdef CONFIG_FB_MATROX_MULTIHEAD - minfo = (struct matrox_fb_info*)kmalloc(sizeof(*minfo), GFP_KERNEL); + minfo = kmalloc(sizeof(*minfo), GFP_KERNEL); if (!minfo) return -1; #else @@ -2047,7 +2111,7 @@ static struct pci_device_id matroxfb_devices[] = { {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, #endif -#ifdef CONFIG_FB_MATROX_G100 +#ifdef CONFIG_FB_MATROX_G {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_MM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, @@ -2213,10 +2277,13 @@ static void __init matroxfb_init_params(void) { } } -static void __init matrox_init(void) { +static int __init matrox_init(void) { + int err; + matroxfb_init_params(); - pci_register_driver(&matroxfb_driver); + err = pci_register_driver(&matroxfb_driver); dev = -1; /* accept all new devices... */ + return err; } /* **************************** exit-time only **************************** */ @@ -2229,7 +2296,7 @@ static void __exit matrox_done(void) { /* ************************* init in-kernel code ************************** */ -int __init matroxfb_setup(char *options) { +static int __init matroxfb_setup(char *options) { char *this_opt; DBG(__FUNCTION__) @@ -2288,10 +2355,12 @@ int __init matroxfb_setup(char *options) { mem = simple_strtoul(this_opt+4, NULL, 0); else if (!strncmp(this_opt, "mode:", 5)) strlcpy(videomode, this_opt+5, sizeof(videomode)); + else if (!strncmp(this_opt, "outputs:", 8)) + strlcpy(outputs, this_opt+8, sizeof(outputs)); else if (!strncmp(this_opt, "dfp:", 4)) { dfp_type = simple_strtoul(this_opt+4, NULL, 0); dfp = 1; - } + } #ifdef CONFIG_PPC_PMAC else if (!strncmp(this_opt, "vmode:", 6)) { unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0); @@ -2368,21 +2437,30 @@ int __init matroxfb_setup(char *options) { static int __initdata initialized = 0; -int __init matroxfb_init(void) +static int __init matroxfb_init(void) { + char *option = NULL; + int err = 0; + DBG(__FUNCTION__) + if (fb_get_options("matroxfb", &option)) + return -ENODEV; + matroxfb_setup(option); + if (disabled) return -ENXIO; if (!initialized) { initialized = 1; - matrox_init(); + err = matrox_init(); } hotplug = 1; /* never return failure, user can hotplug matrox later... */ - return 0; + return err; } +module_init(matroxfb_init); + #else /* *************************** init module code **************************** */ @@ -2391,82 +2469,86 @@ MODULE_AUTHOR("(c) 1998-2002 Petr Vandrovec "); MODULE_DESCRIPTION("Accelerated FBDev driver for Matrox Millennium/Mystique/G100/G200/G400/G450/G550"); MODULE_LICENSE("GPL"); -MODULE_PARM(mem, "i"); +module_param(mem, int, 0); MODULE_PARM_DESC(mem, "Size of available memory in MB, KB or B (2,4,8,12,16MB, default=autodetect)"); -MODULE_PARM(disabled, "i"); +module_param(disabled, int, 0); MODULE_PARM_DESC(disabled, "Disabled (0 or 1=disabled) (default=0)"); -MODULE_PARM(noaccel, "i"); +module_param(noaccel, int, 0); MODULE_PARM_DESC(noaccel, "Do not use accelerating engine (0 or 1=disabled) (default=0)"); -MODULE_PARM(nopan, "i"); +module_param(nopan, int, 0); MODULE_PARM_DESC(nopan, "Disable pan on startup (0 or 1=disabled) (default=0)"); -MODULE_PARM(no_pci_retry, "i"); +module_param(no_pci_retry, int, 0); MODULE_PARM_DESC(no_pci_retry, "PCI retries enabled (0 or 1=disabled) (default=0)"); -MODULE_PARM(novga, "i"); +module_param(novga, int, 0); MODULE_PARM_DESC(novga, "VGA I/O (0x3C0-0x3DF) disabled (0 or 1=disabled) (default=0)"); -MODULE_PARM(nobios, "i"); +module_param(nobios, int, 0); MODULE_PARM_DESC(nobios, "Disables ROM BIOS (0 or 1=disabled) (default=do not change BIOS state)"); -MODULE_PARM(noinit, "i"); +module_param(noinit, int, 0); MODULE_PARM_DESC(noinit, "Disables W/SG/SD-RAM and bus interface initialization (0 or 1=do not initialize) (default=0)"); -MODULE_PARM(memtype, "i"); +module_param(memtype, int, 0); MODULE_PARM_DESC(memtype, "Memory type for G200/G400 (see Documentation/fb/matroxfb.txt for explanation) (default=3 for G200, 0 for G400)"); -MODULE_PARM(mtrr, "i"); +#ifdef CONFIG_MTRR +module_param(mtrr, int, 0); MODULE_PARM_DESC(mtrr, "This speeds up video memory accesses (0=disabled or 1) (default=1)"); -MODULE_PARM(sgram, "i"); +#endif +module_param(sgram, int, 0); MODULE_PARM_DESC(sgram, "Indicates that G100/G200/G400 has SGRAM memory (0=SDRAM, 1=SGRAM) (default=0)"); -MODULE_PARM(inv24, "i"); +module_param(inv24, int, 0); MODULE_PARM_DESC(inv24, "Inverts clock polarity for 24bpp and loop frequency > 100MHz (default=do not invert polarity)"); -MODULE_PARM(inverse, "i"); +module_param(inverse, int, 0); MODULE_PARM_DESC(inverse, "Inverse (0 or 1) (default=0)"); #ifdef CONFIG_FB_MATROX_MULTIHEAD -MODULE_PARM(dev, "i"); +module_param(dev, int, 0); MODULE_PARM_DESC(dev, "Multihead support, attach to device ID (0..N) (default=all working)"); #else -MODULE_PARM(dev, "i"); +module_param(dev, int, 0); MODULE_PARM_DESC(dev, "Multihead support, attach to device ID (0..N) (default=first working)"); #endif -MODULE_PARM(vesa, "i"); +module_param(vesa, int, 0); MODULE_PARM_DESC(vesa, "Startup videomode (0x000-0x1FF) (default=0x101)"); -MODULE_PARM(xres, "i"); +module_param(xres, int, 0); MODULE_PARM_DESC(xres, "Horizontal resolution (px), overrides xres from vesa (default=vesa)"); -MODULE_PARM(yres, "i"); +module_param(yres, int, 0); MODULE_PARM_DESC(yres, "Vertical resolution (scans), overrides yres from vesa (default=vesa)"); -MODULE_PARM(upper, "i"); +module_param(upper, int, 0); MODULE_PARM_DESC(upper, "Upper blank space (scans), overrides upper from vesa (default=vesa)"); -MODULE_PARM(lower, "i"); +module_param(lower, int, 0); MODULE_PARM_DESC(lower, "Lower blank space (scans), overrides lower from vesa (default=vesa)"); -MODULE_PARM(vslen, "i"); +module_param(vslen, int, 0); MODULE_PARM_DESC(vslen, "Vertical sync length (scans), overrides lower from vesa (default=vesa)"); -MODULE_PARM(left, "i"); +module_param(left, int, 0); MODULE_PARM_DESC(left, "Left blank space (px), overrides left from vesa (default=vesa)"); -MODULE_PARM(right, "i"); +module_param(right, int, 0); MODULE_PARM_DESC(right, "Right blank space (px), overrides right from vesa (default=vesa)"); -MODULE_PARM(hslen, "i"); +module_param(hslen, int, 0); MODULE_PARM_DESC(hslen, "Horizontal sync length (px), overrides hslen from vesa (default=vesa)"); -MODULE_PARM(pixclock, "i"); +module_param(pixclock, int, 0); MODULE_PARM_DESC(pixclock, "Pixelclock (ns), overrides pixclock from vesa (default=vesa)"); -MODULE_PARM(sync, "i"); +module_param(sync, int, 0); MODULE_PARM_DESC(sync, "Sync polarity, overrides sync from vesa (default=vesa)"); -MODULE_PARM(depth, "i"); +module_param(depth, int, 0); MODULE_PARM_DESC(depth, "Color depth (0=text,8,15,16,24,32) (default=vesa)"); -MODULE_PARM(maxclk, "i"); +module_param(maxclk, int, 0); MODULE_PARM_DESC(maxclk, "Startup maximal clock, 0-999MHz, 1000-999999kHz, 1000000-INF Hz"); -MODULE_PARM(fh, "i"); +module_param(fh, int, 0); MODULE_PARM_DESC(fh, "Startup horizontal frequency, 0-999kHz, 1000-INF Hz"); -MODULE_PARM(fv, "i"); +module_param(fv, int, 0); MODULE_PARM_DESC(fv, "Startup vertical frequency, 0-INF Hz\n" "You should specify \"fv:max_monitor_vsync,fh:max_monitor_hsync,maxclk:max_monitor_dotclock\"\n"); -MODULE_PARM(grayscale, "i"); +module_param(grayscale, int, 0); 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)"); -MODULE_PARM(cross4MB, "i"); +module_param(cross4MB, int, 0); MODULE_PARM_DESC(cross4MB, "Specifies that 4MB boundary can be in middle of line. (default=autodetected)"); -MODULE_PARM(dfp, "i"); +module_param(dfp, int, 0); MODULE_PARM_DESC(dfp, "Specifies whether to use digital flat panel interface of G200/G400 (0 or 1) (default=0)"); -MODULE_PARM(dfp_type, "i"); +module_param(dfp_type, int, 0); MODULE_PARM_DESC(dfp_type, "Specifies DFP interface type (0 to 255) (default=read from hardware)"); +module_param_string(outputs, outputs, sizeof(outputs), 0); +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)"); #ifdef CONFIG_PPC_PMAC -MODULE_PARM(vmode, "i"); +module_param_named(vmode, default_vmode, int, 0); MODULE_PARM_DESC(vmode, "Specify the vmode mode number that should be used (640x480 default)"); -MODULE_PARM(cmode, "i"); +module_param_named(cmode, default_cmode, int, 0); MODULE_PARM_DESC(cmode, "Specify the video depth that should be used (8bit default)"); #endif