]> git.hungrycats.org Git - linux/commitdiff
[PATCH] visws: framebuffer driver update
authorAndrew Morton <akpm@digeo.com>
Tue, 18 Feb 2003 13:28:16 +0000 (05:28 -0800)
committerLinus Torvalds <torvalds@home.transmeta.com>
Tue, 18 Feb 2003 13:28:16 +0000 (05:28 -0800)
Patch from Andrey Panin <pazke@orbita1.ru>

This patch contains SGI visws framebuffer update. Patch makes it
compile again and brings flatpanel monitor support back.

drivers/video/Kconfig
drivers/video/sgivwfb.c
include/video/sgivw.h

index 77a6f4a82dc4f32130f9c12400dd28551a9c0c10..4e875ace621b03c81130ffccd0feb9c771c87882 100644 (file)
@@ -363,7 +363,7 @@ config VIDEO_SELECT
 
 config FB_SGIVW
        tristate "SGI Visual Workstation framebuffer support"
-       depends on FB && VISWS
+       depends on FB && X86_VISWS
        help
          SGI Visual Workstation support for framebuffer graphics.
 
index fe9cc1d9c5126138b3113c0ef04ee170ecaf147b..e452b1c51c7f9eee9c743d4dac17d243fee6f7f6 100644 (file)
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
 #include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <asm/uaccess.h>
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
@@ -29,7 +22,7 @@
 
 #define INCLUDE_TIMING_TABLE_DATA
 #define DBE_REG_BASE default_par.regs
-#include <asm/sgi-vwdbe.h>
+#include <video/sgivw.h>
 
 struct sgivw_par {
        struct asregs *regs;
@@ -37,6 +30,8 @@ struct sgivw_par {
        u_long timing_num;
 };
 
+#define FLATPANEL_SGI_1600SW   5
+
 /*
  *  RAM we reserve for the frame buffer. This defines the maximum screen
  *  size
@@ -54,26 +49,29 @@ static struct fb_info fb_info;
 static int ypan = 0;
 static int ywrap = 0;
 
+static int flatpanel_id = -1;
+
 static struct fb_fix_screeninfo sgivwfb_fix __initdata = {
        .id             = "SGI Vis WS FB",
        .type           = FB_TYPE_PACKED_PIXELS,
         .visual                = FB_VISUAL_PSEUDOCOLOR,
        .mmio_start     = DBE_REG_PHYS,
        .mmio_len       = DBE_REG_SIZE,
-        .accel         = FB_ACCEL_NONE
+        .accel         = FB_ACCEL_NONE,
+       .line_length    = 640,
 };
 
 static struct fb_var_screeninfo sgivwfb_var __initdata = {
-        /* 640x480, 8 bpp */
-        .xres          = 640,
+       /* 640x480, 8 bpp */
+       .xres           = 640,
        .yres           = 480,
        .xres_virtual   = 640,
        .yres_virtual   = 480,
        .bits_per_pixel = 8,
-        .red           = {0, 8, 0},
-       .green          = {0, 8, 0},
-       .blue           = {0, 8, 0},
-        .height                = -1,
+       .red            = { 0, 8, 0 },
+       .green          = { 0, 8, 0 },
+       .blue           = { 0, 8, 0 },
+       .height         = -1,
        .width          = -1,
        .pixclock       = 20000,
        .left_margin    = 64,
@@ -82,14 +80,35 @@ static struct fb_var_screeninfo sgivwfb_var __initdata = {
        .lower_margin   = 32,
        .hsync_len      = 64,
        .vsync_len      = 2,
-        .vmode         = FB_VMODE_NONINTERLACED
+       .vmode          = FB_VMODE_NONINTERLACED
+};
+
+static struct fb_var_screeninfo sgivwfb_var1600sw __initdata = {
+       /* 1600x1024, 8 bpp */
+       .xres           = 1600,
+       .yres           = 1024,
+       .xres_virtual   = 1600,
+       .yres_virtual   = 1024,
+       .bits_per_pixel = 8,
+       .red            = { 0, 8, 0 },
+       .green          = { 0, 8, 0 },
+       .blue           = { 0, 8, 0 },
+       .height         = -1,
+       .width          = -1,
+       .pixclock       = 9353,
+       .left_margin    = 20,
+       .right_margin   = 30,
+       .upper_margin   = 37,
+       .lower_margin   = 3,
+       .hsync_len      = 20,
+       .vsync_len      = 3,
+       .vmode          = FB_VMODE_NONINTERLACED
 };
 
 /*
  *  Interface used by the world
  */
 int sgivwfb_init(void);
-int sgivwfb_setup(char *);
 
 static int sgivwfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
 static int sgivwfb_set_par(struct fb_info *info);
@@ -114,34 +133,24 @@ static struct fb_ops sgivwfb_ops = {
 /*
  *  Internal routines
  */
-static u_long get_line_length(int xres_virtual, int bpp);
-static unsigned long bytes_per_pixel(int bpp);
-
-static unsigned long get_line_length(int xres_virtual, int bpp)
-{
-       return (xres_virtual * bytes_per_pixel(bpp));
-}
-
 static unsigned long bytes_per_pixel(int bpp)
 {
-       unsigned long length;
-
        switch (bpp) {
-       case 8:
-               length = 1;
-               break;
-       case 16:
-               length = 2;
-               break;
-       case 32:
-               length = 4;
-               break;
-       default:
-               printk(KERN_INFO "sgivwfb: unsupported bpp=%d\n", bpp);
-               length = 0;
-               break;
+               case 8:
+                       return 1;
+               case 16:
+                       return 2;
+               case 32:
+                       return 4;
+               default:
+                       printk(KERN_INFO "sgivwfb: unsupported bpp %d\n", bpp);
+                       return 0;
        }
-       return (length);
+}
+
+static unsigned long get_line_length(int xres_virtual, int bpp)
+{
+       return (xres_virtual * bytes_per_pixel(bpp));
 }
 
 /*
@@ -280,8 +289,7 @@ static int sgivwfb_check_var(struct fb_var_screeninfo *var,
                test_mode--;
        min_mode = test_mode;
        timing = &dbeVTimings[min_mode];
-       printk(KERN_INFO "sgivwfb: granted dot-clock=%d KHz\n",
-              timing->cfreq);
+       printk(KERN_INFO "sgivwfb: granted dot-clock=%d KHz\n", timing->cfreq);
 
        /* Adjust virtual resolution, if necessary */
        if (var->xres > var->xres_virtual || (!ywrap && !ypan))
@@ -292,11 +300,12 @@ static int sgivwfb_check_var(struct fb_var_screeninfo *var,
        /*
         *  Memory limit
         */
-       line_length =
-           get_line_length(var->xres_virtual, var->bits_per_pixel);
+       line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
        if (line_length * var->yres_virtual > sgivwfb_mem_size)
                return -ENOMEM; /* Virtual resolution to high */
 
+       info->fix.line_length = line_length;
+
        switch (var->bits_per_pixel) {
        case 8:
                var->red.offset = 0;
@@ -354,6 +363,48 @@ static int sgivwfb_check_var(struct fb_var_screeninfo *var,
        return 0;
 }
 
+/*
+ *  Setup flatpanel related registers.
+ */
+static void sgivwfb_setup_flatpanel(struct dbe_timing_info *currentTiming)
+{
+       int fp_wid, fp_hgt, fp_vbs, fp_vbe;
+       u32 outputVal = 0;
+
+       SET_DBE_FIELD(VT_FLAGS, HDRV_INVERT, outputVal, 
+               (currentTiming->flags & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1);
+       SET_DBE_FIELD(VT_FLAGS, VDRV_INVERT, outputVal, 
+               (currentTiming->flags & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1);
+       DBE_SETREG(vt_flags, outputVal);
+
+       /* Turn on the flat panel */
+       switch (flatpanel_id) {
+               case FLATPANEL_SGI_1600SW:
+                       fp_wid = 1600;
+                       fp_hgt = 1024;
+                       fp_vbs = 0;
+                       fp_vbe = 1600;
+                       currentTiming->pll_m = 4;
+                       currentTiming->pll_n = 1;
+                       currentTiming->pll_p = 0;
+                       break;
+               default:
+                       fp_wid = fp_hgt = fp_vbs = fp_vbe = 0xfff;
+       }
+
+       outputVal = 0;
+       SET_DBE_FIELD(FP_DE, FP_DE_ON, outputVal, fp_vbs);
+       SET_DBE_FIELD(FP_DE, FP_DE_OFF, outputVal, fp_vbe);
+       DBE_SETREG(fp_de, outputVal);
+       outputVal = 0;
+       SET_DBE_FIELD(FP_HDRV, FP_HDRV_OFF, outputVal, fp_wid);
+       DBE_SETREG(fp_hdrv, outputVal);
+       outputVal = 0;
+       SET_DBE_FIELD(FP_VDRV, FP_VDRV_ON, outputVal, 1);
+       SET_DBE_FIELD(FP_VDRV, FP_VDRV_OFF, outputVal, fp_hgt + 1);
+       DBE_SETREG(fp_vdrv, outputVal);
+}
+
 /*
  *  Set the hardware according to 'par'.
  */
@@ -364,7 +415,7 @@ static int sgivwfb_set_par(struct fb_info *info)
        u32 readVal, outputVal;
        int wholeTilesX, maxPixelsPerTileX;
        int frmWrite1, frmWrite2, frmWrite3b;
-       struct dbe_timing_info_t *currentTiming; /* Current Video Timing */
+       struct dbe_timing_info *currentTiming; /* Current Video Timing */
        int xpmax, ypmax;       // Monitor resolution
        int bytesPerPixel;      // Bytes per pixel
 
@@ -514,6 +565,9 @@ static int sgivwfb_set_par(struct fb_info *info)
                      currentTiming->hblank_end - 3);
        DBE_SETREG(vt_hcmap, outputVal);
 
+       if (flatpanel_id != -1)
+               sgivwfb_setup_flatpanel(currentTiming);
+
        outputVal = 0;
        temp = currentTiming->vblank_start - currentTiming->vblank_end - 1;
        if (temp > 0)
@@ -680,14 +734,16 @@ int __init sgivwfb_setup(char *options)
 {
        char *this_opt;
 
-       fb_info.fontname[0] = '\0';
-
        if (!options || !*options)
                return 0;
 
        while ((this_opt = strsep(&options, ",")) != NULL) {
-               if (!strncmp(this_opt, "font:", 5))
-                       strcpy(fb_info.fontname, this_opt + 5);
+               if (!strncmp(this_opt, "monitor:", 8)) {
+                       if (!strncmp(this_opt + 8, "crt", 3))
+                               flatpanel_id = -1;
+                       else if (!strncmp(this_opt + 8, "1600sw", 6))
+                               flatpanel_id = FLATPANEL_SGI_1600SW;
+               }
        }
        return 0;
 }
@@ -697,12 +753,11 @@ int __init sgivwfb_setup(char *options)
  */
 int __init sgivwfb_init(void)
 {
-       printk(KERN_INFO "sgivwfb: framebuffer at 0x%lx, size %ldk\n",
-              sgivwfb_mem_phys, sgivwfb_mem_size / 1024);
+       char *monitor;
 
        if (!request_mem_region(DBE_REG_PHYS, DBE_REG_SIZE, "sgivwfb")) {
                printk(KERN_ERR "sgivwfb: couldn't reserve mmio region\n");
-               goto fail_request_mem_region;
+               return -EBUSY;
        }
        default_par.regs = (struct asregs *) ioremap_nocache(DBE_REG_PHYS, DBE_REG_SIZE);
        if (!default_par.regs) {
@@ -710,10 +765,7 @@ int __init sgivwfb_init(void)
                goto fail_ioremap_regs;
        }
 
-#ifdef CONFIG_MTRR
-       mtrr_add((unsigned long) sgivwfb_mem_phys, sgivwfb_mem_size,
-                MTRR_TYPE_WRCOMB, 1);
-#endif
+       mtrr_add(sgivwfb_mem_phys, sgivwfb_mem_size, MTRR_TYPE_WRCOMB, 1);
 
        sgivwfb_fix.smem_start = sgivwfb_mem_phys;
        sgivwfb_fix.smem_len = sgivwfb_mem_size;
@@ -722,13 +774,24 @@ int __init sgivwfb_init(void)
 
        fb_info.node = NODEV;
        fb_info.fix = sgivwfb_fix;
-       fb_info.var = sgivwfb_var;
+
+       switch (flatpanel_id) {
+               case FLATPANEL_SGI_1600SW:
+                       fb_info.var = sgivwfb_var1600sw;
+                       monitor = "SGI 1600SW flatpanel";
+                       break;
+               default:
+                       fb_info.var = sgivwfb_var;
+                       monitor = "CRT";
+       }
+
+       printk(KERN_INFO "sgivwfb: %s monitor selected\n", monitor);
+
        fb_info.fbops = &sgivwfb_ops;
        fb_info.pseudo_palette = pseudo_palette;
        fb_info.par = &default_par;
        fb_info.flags = FBINFO_FLAG_DEFAULT;
 
-       fb_info.screen_base =
        fb_info.screen_base = ioremap_nocache((unsigned long) sgivwfb_mem_phys, sgivwfb_mem_size);
        if (!fb_info.screen_base) {
                printk(KERN_ERR "sgivwfb: couldn't ioremap screen_base\n");
@@ -742,14 +805,16 @@ int __init sgivwfb_init(void)
                goto fail_register_framebuffer;
        }
 
-       printk(KERN_INFO "fb%d: SGI BDE frame buffer device, using %ldK of video memory\n", minor(fb_info.node, sgivwfb_mem_size >> 10);
+       printk(KERN_INFO "fb%d: SGI DBE frame buffer device, using %ldK of video memory at %#lx\n",      
+               minor(fb_info.node), sgivwfb_mem_size >> 10, sgivwfb_mem_phys);
        return 0;
 
-      fail_register_framebuffer:
+fail_register_framebuffer:
        iounmap((char *) fb_info.screen_base);
-      fail_ioremap_fbmem:
+fail_ioremap_fbmem:
        iounmap(default_par.regs);
-      fail_ioremap_regs:
+fail_ioremap_regs:
+       release_mem_region(DBE_REG_PHYS, DBE_REG_SIZE);
        return -ENXIO;
 }
 
@@ -767,6 +832,7 @@ void cleanup_module(void)
        dbe_TurnOffDma();
        iounmap(regs);
        iounmap(&fb_info.screen_base);
+       release_mem_region(DBE_REG_PHYS, DBE_REG_SIZE);
 }
 
 #endif                         /* MODULE */
index 8ff8a77f43e2660ae172f14f243492556f25c881..55f2a7c024af2d3c03e3930d576c2617495cbea9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/video/sgivwfb.h -- SGI DBE frame buffer device header
+ *  linux/drivers/video/sgivw.h -- SGI DBE frame buffer device header
  *
  *      Copyright (C) 1999 Silicon Graphics, Inc.
  *      Jeffrey Newquist, newquist@engr.sgi.som
 #ifndef __SGIVWFB_H__
 #define __SGIVWFB_H__
 
-#define DBE_GETREG(reg, dest)       ((dest) = DBE_REG_BASE->##reg)
-#define DBE_SETREG(reg, src)        DBE_REG_BASE->##reg = (src)
-#define DBE_IGETREG(reg, idx, dest) ((dest) = DBE_REG_BASE->##reg##[idx])
-#define DBE_ISETREG(reg, idx, src)  (DBE_REG_BASE->##reg##[idx] = (src))
+#define DBE_GETREG(reg, dest)          ((dest) = DBE_REG_BASE->reg)
+#define DBE_SETREG(reg, src)           DBE_REG_BASE->reg = (src)
+#define DBE_IGETREG(reg, idx, dest)    ((dest) = DBE_REG_BASE->reg[idx])
+#define DBE_ISETREG(reg, idx, src)     (DBE_REG_BASE->reg[idx] = (src))
 
 #define MASK(msb, lsb)          ( (((u32)1<<((msb)-(lsb)+1))-1) << (lsb) )
 #define GET(v, msb, lsb)        ( ((u32)(v) & MASK(msb,lsb)) >> (lsb) )
@@ -29,7 +29,7 @@
 #define DBE_REG_PHYS   0xd0000000
 #define DBE_REG_SIZE        0x01000000
 
-typedef struct {
+struct asregs {
   volatile u32 ctrlstat;     /* 0x000000 general control */
   volatile u32 dotclock;     /* 0x000004 dot clock PLL control */
   volatile u32 i2c;          /* 0x000008 crt I2C control */
@@ -121,7 +121,7 @@ typedef struct {
   volatile u32 vc_6;           /* 0x080018 video capture crtl 3 */
   volatile u32 vc_7;           /* 0x08001c video capture crtl 3 */
   volatile u32 vc_8;           /* 0x08000c video capture crtl 3 */
-} asregs;
+};
 
 /* Bit mask information */
 
@@ -144,6 +144,21 @@ typedef struct {
 #define DBE_VT_XY_VT_FREEZE_MSB     31
 #define DBE_VT_XY_VT_FREEZE_LSB     31
 
+#define DBE_FP_VDRV_FP_VDRV_ON_MSB     23
+#define DBE_FP_VDRV_FP_VDRV_ON_LSB     12
+#define DBE_FP_VDRV_FP_VDRV_OFF_MSB    11
+#define DBE_FP_VDRV_FP_VDRV_OFF_LSB    0
+
+#define DBE_FP_HDRV_FP_HDRV_ON_MSB     23
+#define DBE_FP_HDRV_FP_HDRV_ON_LSB     12
+#define DBE_FP_HDRV_FP_HDRV_OFF_MSB    11
+#define DBE_FP_HDRV_FP_HDRV_OFF_LSB    0
+
+#define DBE_FP_DE_FP_DE_ON_MSB         23
+#define DBE_FP_DE_FP_DE_ON_LSB         12
+#define DBE_FP_DE_FP_DE_OFF_MSB                11
+#define DBE_FP_DE_FP_DE_OFF_LSB                0
+
 #define DBE_VT_VSYNC_VT_VSYNC_ON_MSB        23
 #define DBE_VT_VSYNC_VT_VSYNC_ON_LSB        12
 #define DBE_VT_VSYNC_VT_VSYNC_OFF_MSB       11
@@ -164,6 +179,11 @@ typedef struct {
 #define DBE_VT_HBLANK_VT_HBLANK_OFF_MSB       11
 #define DBE_VT_HBLANK_VT_HBLANK_OFF_LSB       0
 
+#define DBE_VT_FLAGS_VDRV_INVERT_MSB           0
+#define DBE_VT_FLAGS_VDRV_INVERT_LSB           0
+#define DBE_VT_FLAGS_HDRV_INVERT_MSB           2
+#define DBE_VT_FLAGS_HDRV_INVERT_LSB           2
+
 #define DBE_VT_VCMAP_VT_VCMAP_ON_MSB        23
 #define DBE_VT_VCMAP_VT_VCMAP_ON_LSB        12
 #define DBE_VT_VCMAP_VT_VCMAP_OFF_MSB       11
@@ -264,6 +284,8 @@ typedef struct {
 
 #define DBE_CRS_MAGIC       54
 
+#define DBE_CLOCK_REF_KHZ      27000
+
 /* Config Register (DBE Only) Definitions */
 
 #define DBE_CONFIG_VDAC_ENABLE       0x00000001
@@ -326,7 +348,7 @@ typedef enum {
  * Crime Video Timing Data Structure
  */
 
-typedef struct dbe_timing_info
+struct dbe_timing_info
 {
   dbe_timing_t type;
   int flags;                           
@@ -347,7 +369,7 @@ typedef struct dbe_timing_info
   short pll_m;             /* PLL M parameter          */
   short pll_n;             /* PLL P parameter          */
   short pll_p;             /* PLL N parameter          */
-} dbe_timing_info_t;
+};
 
 /* Defines for dbe_vof_info_t flags */