aboutsummaryrefslogtreecommitdiff
path: root/drivers/video/matrox/matroxfb_crtc2.c
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2014-02-13 15:31:38 +0200
committerTomi Valkeinen <tomi.valkeinen@ti.com>2014-04-17 08:10:19 +0300
commitf7018c21350204c4cf628462f229d44d03545254 (patch)
tree408787177164cf51cc06f7aabdb04fcff8d2b6aa /drivers/video/matrox/matroxfb_crtc2.c
parentc26ef3eb3c11274bad1b64498d0a134f85755250 (diff)
video: move fbdev to drivers/video/fbdev
The drivers/video directory is a mess. It contains generic video related files, directories for backlight, console, linux logo, lots of fbdev device drivers, fbdev framework files. Make some order into the chaos by creating drivers/video/fbdev directory, and move all fbdev related files there. No functionality is changed, although I guess it is possible that some subtle Makefile build order related issue could be created by this patch. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Geert Uytterhoeven <geert@linux-m68k.org> Acked-by: Rob Clark <robdclark@gmail.com> Acked-by: Jingoo Han <jg1.han@samsung.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/video/matrox/matroxfb_crtc2.c')
-rw-r--r--drivers/video/matrox/matroxfb_crtc2.c739
1 files changed, 0 insertions, 739 deletions
diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c
deleted file mode 100644
index 02796a4317a..00000000000
--- a/drivers/video/matrox/matroxfb_crtc2.c
+++ /dev/null
@@ -1,739 +0,0 @@
-/*
- *
- * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450.
- *
- * (c) 1998-2002 Petr Vandrovec <vandrove@vc.cvut.cz>
- *
- * Portions Copyright (c) 2001 Matrox Graphics Inc.
- *
- * Version: 1.65 2002/08/14
- *
- */
-
-#include "matroxfb_maven.h"
-#include "matroxfb_crtc2.h"
-#include "matroxfb_misc.h"
-#include "matroxfb_DAC1064.h"
-#include <linux/matroxfb.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-
-/* **************************************************** */
-
-static int mem = 8192;
-
-module_param(mem, int, 0);
-MODULE_PARM_DESC(mem, "Memory size reserved for dualhead (default=8MB)");
-
-/* **************************************************** */
-
-static int matroxfb_dh_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp, struct fb_info* info) {
- u_int32_t col;
-#define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
-
- if (regno >= 16)
- return 1;
- if (m2info->fbcon.var.grayscale) {
- /* gray = 0.30*R + 0.59*G + 0.11*B */
- red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
- }
- red = CNVT_TOHW(red, m2info->fbcon.var.red.length);
- green = CNVT_TOHW(green, m2info->fbcon.var.green.length);
- blue = CNVT_TOHW(blue, m2info->fbcon.var.blue.length);
- transp = CNVT_TOHW(transp, m2info->fbcon.var.transp.length);
-
- col = (red << m2info->fbcon.var.red.offset) |
- (green << m2info->fbcon.var.green.offset) |
- (blue << m2info->fbcon.var.blue.offset) |
- (transp << m2info->fbcon.var.transp.offset);
-
- switch (m2info->fbcon.var.bits_per_pixel) {
- case 16:
- m2info->cmap[regno] = col | (col << 16);
- break;
- case 32:
- m2info->cmap[regno] = col;
- break;
- }
- return 0;
-#undef m2info
-}
-
-static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
- struct my_timming* mt,
- int mode,
- unsigned int pos) {
- u_int32_t tmp;
- u_int32_t datactl;
- struct matrox_fb_info *minfo = m2info->primary_dev;
-
- switch (mode) {
- case 15:
- tmp = 0x00200000;
- break;
- case 16:
- tmp = 0x00400000;
- break;
-/* case 32: */
- default:
- tmp = 0x00800000;
- break;
- }
- tmp |= 0x00000001; /* enable CRTC2 */
- datactl = 0;
- if (minfo->outputs[1].src == MATROXFB_SRC_CRTC2) {
- if (minfo->devflags.g450dac) {
- tmp |= 0x00000006; /* source from secondary pixel PLL */
- /* no vidrst when in monitor mode */
- if (minfo->outputs[1].mode != MATROXFB_OUTPUT_MODE_MONITOR) {
- tmp |= 0xC0001000; /* Enable H/V vidrst */
- }
- } else {
- tmp |= 0x00000002; /* source from VDOCLK */
- tmp |= 0xC0000000; /* enable vvidrst & hvidrst */
- /* MGA TVO is our clock source */
- }
- } else if (minfo->outputs[0].src == MATROXFB_SRC_CRTC2) {
- tmp |= 0x00000004; /* source from pixclock */
- /* PIXPLL is our clock source */
- }
- if (minfo->outputs[0].src == MATROXFB_SRC_CRTC2) {
- tmp |= 0x00100000; /* connect CRTC2 to DAC */
- }
- if (mt->interlaced) {
- tmp |= 0x02000000; /* interlaced, second field is bigger, as G450 apparently ignores it */
- mt->VDisplay >>= 1;
- mt->VSyncStart >>= 1;
- mt->VSyncEnd >>= 1;
- mt->VTotal >>= 1;
- }
- if ((mt->HTotal & 7) == 2) {
- datactl |= 0x00000010;
- mt->HTotal &= ~7;
- }
- tmp |= 0x10000000; /* 0x10000000 is VIDRST polarity */
- mga_outl(0x3C14, ((mt->HDisplay - 8) << 16) | (mt->HTotal - 8));
- mga_outl(0x3C18, ((mt->HSyncEnd - 8) << 16) | (mt->HSyncStart - 8));
- mga_outl(0x3C1C, ((mt->VDisplay - 1) << 16) | (mt->VTotal - 1));
- mga_outl(0x3C20, ((mt->VSyncEnd - 1) << 16) | (mt->VSyncStart - 1));
- mga_outl(0x3C24, ((mt->VSyncStart) << 16) | (mt->HSyncStart)); /* preload */
- {
- u_int32_t linelen = m2info->fbcon.var.xres_virtual * (m2info->fbcon.var.bits_per_pixel >> 3);
- if (tmp & 0x02000000) {
- /* field #0 is smaller, so... */
- mga_outl(0x3C2C, pos); /* field #1 vmemory start */
- mga_outl(0x3C28, pos + linelen); /* field #0 vmemory start */
- linelen <<= 1;
- m2info->interlaced = 1;
- } else {
- mga_outl(0x3C28, pos); /* vmemory start */
- m2info->interlaced = 0;
- }
- mga_outl(0x3C40, linelen);
- }
- mga_outl(0x3C4C, datactl); /* data control */
- if (tmp & 0x02000000) {
- int i;
-
- mga_outl(0x3C10, tmp & ~0x02000000);
- for (i = 0; i < 2; i++) {
- unsigned int nl;
- unsigned int lastl = 0;
-
- while ((nl = mga_inl(0x3C48) & 0xFFF) >= lastl) {
- lastl = nl;
- }
- }
- }
- mga_outl(0x3C10, tmp);
- minfo->hw.crtc2.ctl = tmp;
-
- tmp = mt->VDisplay << 16; /* line compare */
- if (mt->sync & FB_SYNC_HOR_HIGH_ACT)
- tmp |= 0x00000100;
- if (mt->sync & FB_SYNC_VERT_HIGH_ACT)
- tmp |= 0x00000200;
- mga_outl(0x3C44, tmp);
-}
-
-static void matroxfb_dh_disable(struct matroxfb_dh_fb_info* m2info) {
- struct matrox_fb_info *minfo = m2info->primary_dev;
-
- mga_outl(0x3C10, 0x00000004); /* disable CRTC2, CRTC1->DAC1, PLL as clock source */
- minfo->hw.crtc2.ctl = 0x00000004;
-}
-
-static void matroxfb_dh_pan_var(struct matroxfb_dh_fb_info* m2info,
- struct fb_var_screeninfo* var) {
- unsigned int pos;
- unsigned int linelen;
- unsigned int pixelsize;
- struct matrox_fb_info *minfo = m2info->primary_dev;
-
- m2info->fbcon.var.xoffset = var->xoffset;
- m2info->fbcon.var.yoffset = var->yoffset;
- pixelsize = m2info->fbcon.var.bits_per_pixel >> 3;
- linelen = m2info->fbcon.var.xres_virtual * pixelsize;
- pos = m2info->fbcon.var.yoffset * linelen + m2info->fbcon.var.xoffset * pixelsize;
- pos += m2info->video.offbase;
- if (m2info->interlaced) {
- mga_outl(0x3C2C, pos);
- mga_outl(0x3C28, pos + linelen);
- } else {
- mga_outl(0x3C28, pos);
- }
-}
-
-static int matroxfb_dh_decode_var(struct matroxfb_dh_fb_info* m2info,
- struct fb_var_screeninfo* var,
- int *visual,
- int *video_cmap_len,
- int *mode) {
- unsigned int mask;
- unsigned int memlen;
- unsigned int vramlen;
-
- switch (var->bits_per_pixel) {
- case 16: mask = 0x1F;
- break;
- case 32: mask = 0x0F;
- break;
- default: return -EINVAL;
- }
- vramlen = m2info->video.len_usable;
- if (var->yres_virtual < var->yres)
- var->yres_virtual = var->yres;
- if (var->xres_virtual < var->xres)
- var->xres_virtual = var->xres;
- var->xres_virtual = (var->xres_virtual + mask) & ~mask;
- if (var->yres_virtual > 32767)
- return -EINVAL;
- memlen = var->xres_virtual * var->yres_virtual * (var->bits_per_pixel >> 3);
- if (memlen > vramlen)
- return -EINVAL;
- if (var->xoffset + var->xres > var->xres_virtual)
- var->xoffset = var->xres_virtual - var->xres;
- if (var->yoffset + var->yres > var->yres_virtual)
- var->yoffset = var->yres_virtual - var->yres;
-
- var->xres &= ~7;
- var->left_margin &= ~7;
- var->right_margin &= ~7;
- var->hsync_len &= ~7;
-
- *mode = var->bits_per_pixel;
- if (var->bits_per_pixel == 16) {
- if (var->green.length == 5) {
- var->red.offset = 10;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 5;
- var->blue.offset = 0;
- var->blue.length = 5;
- var->transp.offset = 15;
- var->transp.length = 1;
- *mode = 15;
- } else {
- var->red.offset = 11;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 6;
- var->blue.offset = 0;
- var->blue.length = 5;
- var->transp.offset = 0;
- var->transp.length = 0;
- }
- } else {
- var->red.offset = 16;
- var->red.length = 8;
- var->green.offset = 8;
- var->green.length = 8;
- var->blue.offset = 0;
- var->blue.length = 8;
- var->transp.offset = 24;
- var->transp.length = 8;
- }
- *visual = FB_VISUAL_TRUECOLOR;
- *video_cmap_len = 16;
- return 0;
-}
-
-static int matroxfb_dh_open(struct fb_info* info, int user) {
-#define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
- struct matrox_fb_info *minfo = m2info->primary_dev;
-
- if (minfo) {
- int err;
-
- if (minfo->dead) {
- return -ENXIO;
- }
- err = minfo->fbops.fb_open(&minfo->fbcon, user);
- if (err) {
- return err;
- }
- }
- return 0;
-#undef m2info
-}
-
-static int matroxfb_dh_release(struct fb_info* info, int user) {
-#define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
- int err = 0;
- struct matrox_fb_info *minfo = m2info->primary_dev;
-
- if (minfo) {
- err = minfo->fbops.fb_release(&minfo->fbcon, user);
- }
- return err;
-#undef m2info
-}
-
-/*
- * This function is called before the register_framebuffer so
- * no locking is needed.
- */
-static void matroxfb_dh_init_fix(struct matroxfb_dh_fb_info *m2info)
-{
- struct fb_fix_screeninfo *fix = &m2info->fbcon.fix;
-
- strcpy(fix->id, "MATROX DH");
-
- fix->smem_start = m2info->video.base;
- fix->smem_len = m2info->video.len_usable;
- fix->ypanstep = 1;
- fix->ywrapstep = 0;
- fix->xpanstep = 8; /* TBD */
- fix->mmio_start = m2info->mmio.base;
- fix->mmio_len = m2info->mmio.len;
- fix->accel = 0; /* no accel... */
-}
-
-static int matroxfb_dh_check_var(struct fb_var_screeninfo* var, struct fb_info* info) {
-#define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
- int visual;
- int cmap_len;
- int mode;
-
- return matroxfb_dh_decode_var(m2info, var, &visual, &cmap_len, &mode);
-#undef m2info
-}
-
-static int matroxfb_dh_set_par(struct fb_info* info) {
-#define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
- int visual;
- int cmap_len;
- int mode;
- int err;
- struct fb_var_screeninfo* var = &info->var;
- struct matrox_fb_info *minfo = m2info->primary_dev;
-
- if ((err = matroxfb_dh_decode_var(m2info, var, &visual, &cmap_len, &mode)) != 0)
- return err;
- /* cmap */
- {
- m2info->fbcon.screen_base = vaddr_va(m2info->video.vbase);
- m2info->fbcon.fix.visual = visual;
- m2info->fbcon.fix.type = FB_TYPE_PACKED_PIXELS;
- m2info->fbcon.fix.type_aux = 0;
- m2info->fbcon.fix.line_length = (var->xres_virtual * var->bits_per_pixel) >> 3;
- }
- {
- struct my_timming mt;
- unsigned int pos;
- int out;
- int cnt;
-
- matroxfb_var2my(&m2info->fbcon.var, &mt);
- mt.crtc = MATROXFB_SRC_CRTC2;
- /* CRTC2 delay */
- mt.delay = 34;
-
- pos = (m2info->fbcon.var.yoffset * m2info->fbcon.var.xres_virtual + m2info->fbcon.var.xoffset) * m2info->fbcon.var.bits_per_pixel >> 3;
- pos += m2info->video.offbase;
- cnt = 0;
- down_read(&minfo->altout.lock);
- for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
- if (minfo->outputs[out].src == MATROXFB_SRC_CRTC2) {
- cnt++;
- if (minfo->outputs[out].output->compute) {
- minfo->outputs[out].output->compute(minfo->outputs[out].data, &mt);
- }
- }
- }
- minfo->crtc2.pixclock = mt.pixclock;
- minfo->crtc2.mnp = mt.mnp;
- up_read(&minfo->altout.lock);
- if (cnt) {
- matroxfb_dh_restore(m2info, &mt, mode, pos);
- } else {
- matroxfb_dh_disable(m2info);
- }
- DAC1064_global_init(minfo);
- DAC1064_global_restore(minfo);
- down_read(&minfo->altout.lock);
- for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
- if (minfo->outputs[out].src == MATROXFB_SRC_CRTC2 &&
- minfo->outputs[out].output->program) {
- minfo->outputs[out].output->program(minfo->outputs[out].data);
- }
- }
- for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
- if (minfo->outputs[out].src == MATROXFB_SRC_CRTC2 &&
- minfo->outputs[out].output->start) {
- minfo->outputs[out].output->start(minfo->outputs[out].data);
- }
- }
- up_read(&minfo->altout.lock);
- }
- m2info->initialized = 1;
- return 0;
-#undef m2info
-}
-
-static int matroxfb_dh_pan_display(struct fb_var_screeninfo* var, struct fb_info* info) {
-#define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
- matroxfb_dh_pan_var(m2info, var);
- return 0;
-#undef m2info
-}
-
-static int matroxfb_dh_get_vblank(const struct matroxfb_dh_fb_info* m2info, struct fb_vblank* vblank) {
- struct matrox_fb_info *minfo = m2info->primary_dev;
-
- matroxfb_enable_irq(minfo, 0);
- memset(vblank, 0, sizeof(*vblank));
- vblank->flags = FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VBLANK;
- /* mask out reserved bits + field number (odd/even) */
- vblank->vcount = mga_inl(0x3C48) & 0x000007FF;
- /* compatibility stuff */
- if (vblank->vcount >= m2info->fbcon.var.yres)
- vblank->flags |= FB_VBLANK_VBLANKING;
- if (test_bit(0, &minfo->irq_flags)) {
- vblank->flags |= FB_VBLANK_HAVE_COUNT;
- /* Only one writer, aligned int value...
- it should work without lock and without atomic_t */
- vblank->count = minfo->crtc2.vsync.cnt;
- }
- return 0;
-}
-
-static int matroxfb_dh_ioctl(struct fb_info *info,
- unsigned int cmd,
- unsigned long arg)
-{
-#define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
- struct matrox_fb_info *minfo = m2info->primary_dev;
-
- DBG(__func__)
-
- switch (cmd) {
- case FBIOGET_VBLANK:
- {
- struct fb_vblank vblank;
- int err;
-
- err = matroxfb_dh_get_vblank(m2info, &vblank);
- if (err)
- return err;
- if (copy_to_user((void __user *)arg, &vblank, sizeof(vblank)))
- return -EFAULT;
- return 0;
- }
- case FBIO_WAITFORVSYNC:
- {
- u_int32_t crt;
-
- if (get_user(crt, (u_int32_t __user *)arg))
- return -EFAULT;
-
- if (crt != 0)
- return -ENODEV;
- return matroxfb_wait_for_sync(minfo, 1);
- }
- case MATROXFB_SET_OUTPUT_MODE:
- case MATROXFB_GET_OUTPUT_MODE:
- case MATROXFB_GET_ALL_OUTPUTS:
- {
- return minfo->fbcon.fbops->fb_ioctl(&minfo->fbcon, cmd, arg);
- }
- case MATROXFB_SET_OUTPUT_CONNECTION:
- {
- u_int32_t tmp;
- int out;
- int changes;
-
- if (get_user(tmp, (u_int32_t __user *)arg))
- return -EFAULT;
- for (out = 0; out < 32; out++) {
- if (tmp & (1 << out)) {
- if (out >= MATROXFB_MAX_OUTPUTS)
- return -ENXIO;
- if (!minfo->outputs[out].output)
- return -ENXIO;
- switch (minfo->outputs[out].src) {
- case MATROXFB_SRC_NONE:
- case MATROXFB_SRC_CRTC2:
- break;
- default:
- return -EBUSY;
- }
- }
- }
- if (minfo->devflags.panellink) {
- if (tmp & MATROXFB_OUTPUT_CONN_DFP)
- return -EINVAL;
- if ((minfo->outputs[2].src == MATROXFB_SRC_CRTC1) && tmp)
- return -EBUSY;
- }
- changes = 0;
- for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
- if (tmp & (1 << out)) {
- if (minfo->outputs[out].src != MATROXFB_SRC_CRTC2) {
- changes = 1;
- minfo->outputs[out].src = MATROXFB_SRC_CRTC2;
- }
- } else if (minfo->outputs[out].src == MATROXFB_SRC_CRTC2) {
- changes = 1;
- minfo->outputs[out].src = MATROXFB_SRC_NONE;
- }
- }
- if (!changes)
- return 0;
- matroxfb_dh_set_par(info);
- return 0;
- }
- case MATROXFB_GET_OUTPUT_CONNECTION:
- {
- u_int32_t conn = 0;
- int out;
-
- for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
- if (minfo->outputs[out].src == MATROXFB_SRC_CRTC2) {
- conn |= 1 << out;
- }
- }
- if (put_user(conn, (u_int32_t __user *)arg))
- return -EFAULT;
- return 0;
- }
- case MATROXFB_GET_AVAILABLE_OUTPUTS:
- {
- u_int32_t tmp = 0;
- int out;
-
- for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
- if (minfo->outputs[out].output) {
- switch (minfo->outputs[out].src) {
- case MATROXFB_SRC_NONE:
- case MATROXFB_SRC_CRTC2:
- tmp |= 1 << out;
- break;
- }
- }
- }
- if (minfo->devflags.panellink) {
- tmp &= ~MATROXFB_OUTPUT_CONN_DFP;
- if (minfo->outputs[2].src == MATROXFB_SRC_CRTC1) {
- tmp = 0;
- }
- }
- if (put_user(tmp, (u_int32_t __user *)arg))
- return -EFAULT;
- return 0;
- }
- }
- return -ENOTTY;
-#undef m2info
-}
-
-static int matroxfb_dh_blank(int blank, struct fb_info* info) {
-#define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
- switch (blank) {
- case 1:
- case 2:
- case 3:
- case 4:
- default:;
- }
- /* do something... */
- return 0;
-#undef m2info
-}
-
-static struct fb_ops matroxfb_dh_ops = {
- .owner = THIS_MODULE,
- .fb_open = matroxfb_dh_open,
- .fb_release = matroxfb_dh_release,
- .fb_check_var = matroxfb_dh_check_var,
- .fb_set_par = matroxfb_dh_set_par,
- .fb_setcolreg = matroxfb_dh_setcolreg,
- .fb_pan_display =matroxfb_dh_pan_display,
- .fb_blank = matroxfb_dh_blank,
- .fb_ioctl = matroxfb_dh_ioctl,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
-};
-
-static struct fb_var_screeninfo matroxfb_dh_defined = {
- 640,480,640,480,/* W,H, virtual W,H */
- 0,0, /* offset */
- 32, /* depth */
- 0, /* gray */
- {0,0,0}, /* R */
- {0,0,0}, /* G */
- {0,0,0}, /* B */
- {0,0,0}, /* alpha */
- 0, /* nonstd */
- FB_ACTIVATE_NOW,
- -1,-1, /* display size */
- 0, /* accel flags */
- 39721L,48L,16L,33L,10L,
- 96L,2,0, /* no sync info */
- FB_VMODE_NONINTERLACED,
-};
-
-static int matroxfb_dh_regit(const struct matrox_fb_info *minfo,
- struct matroxfb_dh_fb_info *m2info)
-{
-#define minfo (m2info->primary_dev)
- void* oldcrtc2;
-
- m2info->fbcon.fbops = &matroxfb_dh_ops;
- m2info->fbcon.flags = FBINFO_FLAG_DEFAULT;
- m2info->fbcon.flags |= FBINFO_HWACCEL_XPAN |
- FBINFO_HWACCEL_YPAN;
- m2info->fbcon.pseudo_palette = m2info->cmap;
- fb_alloc_cmap(&m2info->fbcon.cmap, 256, 1);
-
- if (mem < 64)
- mem *= 1024;
- if (mem < 64*1024)
- mem *= 1024;
- mem &= ~0x00000FFF; /* PAGE_MASK? */
- if (minfo->video.len_usable + mem <= minfo->video.len)
- m2info->video.offbase = minfo->video.len - mem;
- else if (minfo->video.len < mem) {
- return -ENOMEM;
- } else { /* check yres on first head... */
- m2info->video.borrowed = mem;
- minfo->video.len_usable -= mem;
- m2info->video.offbase = minfo->video.len_usable;
- }
- m2info->video.base = minfo->video.base + m2info->video.offbase;
- m2info->video.len = m2info->video.len_usable = m2info->video.len_maximum = mem;
- m2info->video.vbase.vaddr = vaddr_va(minfo->video.vbase) + m2info->video.offbase;
- m2info->mmio.base = minfo->mmio.base;
- m2info->mmio.vbase = minfo->mmio.vbase;
- m2info->mmio.len = minfo->mmio.len;
-
- matroxfb_dh_init_fix(m2info);
- if (register_framebuffer(&m2info->fbcon)) {
- return -ENXIO;
- }
- if (!m2info->initialized)
- fb_set_var(&m2info->fbcon, &matroxfb_dh_defined);
- down_write(&minfo->crtc2.lock);
- oldcrtc2 = minfo->crtc2.info;
- minfo->crtc2.info = m2info;
- up_write(&minfo->crtc2.lock);
- if (oldcrtc2) {
- printk(KERN_ERR "matroxfb_crtc2: Internal consistency check failed: crtc2 already present: %p\n",
- oldcrtc2);
- }
- return 0;
-#undef minfo
-}
-
-/* ************************** */
-
-static int matroxfb_dh_registerfb(struct matroxfb_dh_fb_info* m2info) {
-#define minfo (m2info->primary_dev)
- if (matroxfb_dh_regit(minfo, m2info)) {
- printk(KERN_ERR "matroxfb_crtc2: secondary head failed to register\n");
- return -1;
- }
- printk(KERN_INFO "matroxfb_crtc2: secondary head of fb%u was registered as fb%u\n",
- minfo->fbcon.node, m2info->fbcon.node);
- m2info->fbcon_registered = 1;
- return 0;
-#undef minfo
-}
-
-static void matroxfb_dh_deregisterfb(struct matroxfb_dh_fb_info* m2info) {
-#define minfo (m2info->primary_dev)
- if (m2info->fbcon_registered) {
- int id;
- struct matroxfb_dh_fb_info* crtc2;
-
- down_write(&minfo->crtc2.lock);
- crtc2 = minfo->crtc2.info;
- if (crtc2 == m2info)
- minfo->crtc2.info = NULL;
- up_write(&minfo->crtc2.lock);
- if (crtc2 != m2info) {
- printk(KERN_ERR "matroxfb_crtc2: Internal consistency check failed: crtc2 mismatch at unload: %p != %p\n",
- crtc2, m2info);
- printk(KERN_ERR "matroxfb_crtc2: Expect kernel crash after module unload.\n");
- return;
- }
- id = m2info->fbcon.node;
- unregister_framebuffer(&m2info->fbcon);
- /* return memory back to primary head */
- minfo->video.len_usable += m2info->video.borrowed;
- printk(KERN_INFO "matroxfb_crtc2: fb%u unregistered\n", id);
- m2info->fbcon_registered = 0;
- }
-#undef minfo
-}
-
-static void* matroxfb_crtc2_probe(struct matrox_fb_info* minfo) {
- struct matroxfb_dh_fb_info* m2info;
-
- /* hardware is CRTC2 incapable... */
- if (!minfo->devflags.crtc2)
- return NULL;
- m2info = kzalloc(sizeof(*m2info), GFP_KERNEL);
- if (!m2info) {
- printk(KERN_ERR "matroxfb_crtc2: Not enough memory for CRTC2 control structs\n");
- return NULL;
- }
- m2info->primary_dev = minfo;
- if (matroxfb_dh_registerfb(m2info)) {
- kfree(m2info);
- printk(KERN_ERR "matroxfb_crtc2: CRTC2 framebuffer failed to register\n");
- return NULL;
- }
- return m2info;
-}
-
-static void matroxfb_crtc2_remove(struct matrox_fb_info* minfo, void* crtc2) {
- matroxfb_dh_deregisterfb(crtc2);
- kfree(crtc2);
-}
-
-static struct matroxfb_driver crtc2 = {
- .name = "Matrox G400 CRTC2",
- .probe = matroxfb_crtc2_probe,
- .remove = matroxfb_crtc2_remove };
-
-static int matroxfb_crtc2_init(void) {
- if (fb_get_options("matrox_crtc2fb", NULL))
- return -ENODEV;
-
- matroxfb_register_driver(&crtc2);
- return 0;
-}
-
-static void matroxfb_crtc2_exit(void) {
- matroxfb_unregister_driver(&crtc2);
-}
-
-MODULE_AUTHOR("(c) 1999-2002 Petr Vandrovec <vandrove@vc.cvut.cz>");
-MODULE_DESCRIPTION("Matrox G400 CRTC2 driver");
-MODULE_LICENSE("GPL");
-module_init(matroxfb_crtc2_init);
-module_exit(matroxfb_crtc2_exit);
-/* we do not have __setup() yet */