root/drivers/video/fbdev/fm2fb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fm2fb_blank
  2. fm2fb_setcolreg
  3. fm2fb_probe
  4. fm2fb_setup
  5. fm2fb_init

   1 /*
   2  *  linux/drivers/video/fm2fb.c -- BSC FrameMaster II/Rainbow II frame buffer
   3  *                                 device
   4  *
   5  *      Copyright (C) 1998 Steffen A. Mork (linux-dev@morknet.de)
   6  *      Copyright (C) 1999 Geert Uytterhoeven
   7  *
   8  *  Written for 2.0.x by Steffen A. Mork
   9  *  Ported to 2.1.x by Geert Uytterhoeven
  10  *  Ported to new api by James Simmons
  11  *
  12  *  This file is subject to the terms and conditions of the GNU General Public
  13  *  License. See the file COPYING in the main directory of this archive for
  14  *  more details.
  15  */
  16 
  17 #include <linux/module.h>
  18 #include <linux/mm.h>
  19 #include <linux/fb.h>
  20 #include <linux/init.h>
  21 #include <linux/zorro.h>
  22 #include <asm/io.h>
  23 
  24 /*
  25  *      Some technical notes:
  26  *
  27  *      The BSC FrameMaster II (or Rainbow II) is a simple very dumb
  28  *      frame buffer which allows to display 24 bit true color images.
  29  *      Each pixel is 32 bit width so it's very easy to maintain the
  30  *      frame buffer. One long word has the following layout:
  31  *      AARRGGBB which means: AA the alpha channel byte, RR the red
  32  *      channel, GG the green channel and BB the blue channel.
  33  *
  34  *      The FrameMaster II supports the following video modes.
  35  *      - PAL/NTSC
  36  *      - interlaced/non interlaced
  37  *      - composite sync/sync/sync over green
  38  *
  39  *      The resolution is to the following both ones:
  40  *      - 768x576 (PAL)
  41  *      - 768x480 (NTSC)
  42  *
  43  *      This means that pixel access per line is fixed due to the
  44  *      fixed line width. In case of maximal resolution the frame
  45  *      buffer needs an amount of memory of 1.769.472 bytes which
  46  *      is near to 2 MByte (the allocated address space of Zorro2).
  47  *      The memory is channel interleaved. That means every channel
  48  *      owns four VRAMs. Unfortunately most FrameMasters II are
  49  *      not assembled with memory for the alpha channel. In this
  50  *      case it could be possible to add the frame buffer into the
  51  *      normal memory pool.
  52  *
  53  *      At relative address 0x1ffff8 of the frame buffers base address
  54  *      there exists a control register with the number of
  55  *      four control bits. They have the following meaning:
  56  *      bit value meaning
  57  *
  58  *       0    1   0=interlaced/1=non interlaced
  59  *       1    2   0=video out disabled/1=video out enabled
  60  *       2    4   0=normal mode as jumpered via JP8/1=complement mode
  61  *       3    8   0=read  onboard ROM/1 normal operation (required)
  62  *
  63  *      As mentioned above there are several jumper. I think there
  64  *      is not very much information about the FrameMaster II in
  65  *      the world so I add these information for completeness.
  66  *
  67  *      JP1  interlace selection (1-2 non interlaced/2-3 interlaced)
  68  *      JP2  wait state creation (leave as is!)
  69  *      JP3  wait state creation (leave as is!)
  70  *      JP4  modulate composite sync on green output (1-2 composite
  71  *           sync on green channel/2-3 normal composite sync)
  72  *      JP5  create test signal, shorting this jumper will create
  73  *           a white screen
  74  *      JP6  sync creation (1-2 composite sync/2-3 H-sync output)
  75  *      JP8  video mode (1-2 PAL/2-3 NTSC)
  76  *
  77  *      With the following jumpering table you can connect the
  78  *      FrameMaster II to a normal TV via SCART connector:
  79  *      JP1:  2-3
  80  *      JP4:  2-3
  81  *      JP6:  2-3
  82  *      JP8:  1-2 (means PAL for Europe)
  83  *
  84  *      NOTE:
  85  *      There is no other possibility to change the video timings
  86  *      except the interlaced/non interlaced, sync control and the
  87  *      video mode PAL (50 Hz)/NTSC (60 Hz). Inside this
  88  *      FrameMaster II driver are assumed values to avoid anomalies
  89  *      to a future X server. Except the pixel clock is really
  90  *      constant at 30 MHz.
  91  *
  92  *      9 pin female video connector:
  93  *
  94  *      1  analog red 0.7 Vss
  95  *      2  analog green 0.7 Vss
  96  *      3  analog blue 0.7 Vss
  97  *      4  H-sync TTL
  98  *      5  V-sync TTL
  99  *      6  ground
 100  *      7  ground
 101  *      8  ground
 102  *      9  ground
 103  *
 104  *      Some performance notes:
 105  *      The FrameMaster II was not designed to display a console
 106  *      this driver would do! It was designed to display still true
 107  *      color images. Imagine: When scroll up a text line there
 108  *      must copied ca. 1.7 MBytes to another place inside this
 109  *      frame buffer. This means 1.7 MByte read and 1.7 MByte write
 110  *      over the slow 16 bit wide Zorro2 bus! A scroll of one
 111  *      line needs 1 second so do not expect to much from this
 112  *      driver - he is at the limit!
 113  *
 114  */
 115 
 116 /*
 117  *      definitions
 118  */
 119 
 120 #define FRAMEMASTER_SIZE        0x200000
 121 #define FRAMEMASTER_REG         0x1ffff8
 122 
 123 #define FRAMEMASTER_NOLACE      1
 124 #define FRAMEMASTER_ENABLE      2
 125 #define FRAMEMASTER_COMPL       4
 126 #define FRAMEMASTER_ROM         8
 127 
 128 static volatile unsigned char *fm2fb_reg;
 129 
 130 static struct fb_fix_screeninfo fb_fix = {
 131         .smem_len =     FRAMEMASTER_REG,
 132         .type =         FB_TYPE_PACKED_PIXELS,
 133         .visual =       FB_VISUAL_TRUECOLOR,
 134         .line_length =  (768 << 2),
 135         .mmio_len =     (8),
 136         .accel =        FB_ACCEL_NONE,
 137 };
 138 
 139 static int fm2fb_mode = -1;
 140 
 141 #define FM2FB_MODE_PAL  0
 142 #define FM2FB_MODE_NTSC 1
 143 
 144 static struct fb_var_screeninfo fb_var_modes[] = {
 145     {
 146         /* 768 x 576, 32 bpp (PAL) */
 147         768, 576, 768, 576, 0, 0, 32, 0,
 148         { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 24, 8, 0 },
 149         0, FB_ACTIVATE_NOW, -1, -1, FB_ACCEL_NONE,
 150         33333, 10, 102, 10, 5, 80, 34, FB_SYNC_COMP_HIGH_ACT, 0
 151     }, {
 152         /* 768 x 480, 32 bpp (NTSC - not supported yet */
 153         768, 480, 768, 480, 0, 0, 32, 0,
 154         { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 24, 8, 0 },
 155         0, FB_ACTIVATE_NOW, -1, -1, FB_ACCEL_NONE,
 156         33333, 10, 102, 10, 5, 80, 34, FB_SYNC_COMP_HIGH_ACT, 0
 157     }
 158 };
 159 
 160     /*
 161      *  Interface used by the world
 162      */
 163 
 164 static int fm2fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 165                            u_int transp, struct fb_info *info);
 166 static int fm2fb_blank(int blank, struct fb_info *info);
 167 
 168 static struct fb_ops fm2fb_ops = {
 169         .owner          = THIS_MODULE,
 170         .fb_setcolreg   = fm2fb_setcolreg,
 171         .fb_blank       = fm2fb_blank,
 172         .fb_fillrect    = cfb_fillrect,
 173         .fb_copyarea    = cfb_copyarea,
 174         .fb_imageblit   = cfb_imageblit,
 175 };
 176 
 177     /*
 178      *  Blank the display.
 179      */
 180 static int fm2fb_blank(int blank, struct fb_info *info)
 181 {
 182         unsigned char t = FRAMEMASTER_ROM;
 183 
 184         if (!blank)
 185                 t |= FRAMEMASTER_ENABLE | FRAMEMASTER_NOLACE;
 186         fm2fb_reg[0] = t;
 187         return 0;
 188 }
 189 
 190     /*
 191      *  Set a single color register. The values supplied are already
 192      *  rounded down to the hardware's capabilities (according to the
 193      *  entries in the var structure). Return != 0 for invalid regno.
 194      */
 195 static int fm2fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 196                          u_int transp, struct fb_info *info)
 197 {
 198         if (regno < 16) {
 199                 red >>= 8;
 200                 green >>= 8;
 201                 blue >>= 8;
 202 
 203                 ((u32*)(info->pseudo_palette))[regno] = (red << 16) |
 204                         (green << 8) | blue;
 205         }
 206 
 207         return 0;
 208 }
 209 
 210     /*
 211      *  Initialisation
 212      */
 213 
 214 static int fm2fb_probe(struct zorro_dev *z, const struct zorro_device_id *id);
 215 
 216 static const struct zorro_device_id fm2fb_devices[] = {
 217         { ZORRO_PROD_BSC_FRAMEMASTER_II },
 218         { ZORRO_PROD_HELFRICH_RAINBOW_II },
 219         { 0 }
 220 };
 221 MODULE_DEVICE_TABLE(zorro, fm2fb_devices);
 222 
 223 static struct zorro_driver fm2fb_driver = {
 224         .name           = "fm2fb",
 225         .id_table       = fm2fb_devices,
 226         .probe          = fm2fb_probe,
 227 };
 228 
 229 static int fm2fb_probe(struct zorro_dev *z, const struct zorro_device_id *id)
 230 {
 231         struct fb_info *info;
 232         unsigned long *ptr;
 233         int is_fm;
 234         int x, y;
 235 
 236         is_fm = z->id == ZORRO_PROD_BSC_FRAMEMASTER_II;
 237 
 238         if (!zorro_request_device(z,"fm2fb"))
 239                 return -ENXIO;
 240 
 241         info = framebuffer_alloc(16 * sizeof(u32), &z->dev);
 242         if (!info) {
 243                 zorro_release_device(z);
 244                 return -ENOMEM;
 245         }
 246 
 247         if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
 248                 framebuffer_release(info);
 249                 zorro_release_device(z);
 250                 return -ENOMEM;
 251         }
 252 
 253         /* assigning memory to kernel space */
 254         fb_fix.smem_start = zorro_resource_start(z);
 255         info->screen_base = ioremap(fb_fix.smem_start, FRAMEMASTER_SIZE);
 256         fb_fix.mmio_start = fb_fix.smem_start + FRAMEMASTER_REG;
 257         fm2fb_reg  = (unsigned char *)(info->screen_base+FRAMEMASTER_REG);
 258 
 259         strcpy(fb_fix.id, is_fm ? "FrameMaster II" : "Rainbow II");
 260 
 261         /* make EBU color bars on display */
 262         ptr = (unsigned long *)fb_fix.smem_start;
 263         for (y = 0; y < 576; y++) {
 264                 for (x = 0; x < 96; x++) *ptr++ = 0xffffff;/* white */
 265                 for (x = 0; x < 96; x++) *ptr++ = 0xffff00;/* yellow */
 266                 for (x = 0; x < 96; x++) *ptr++ = 0x00ffff;/* cyan */
 267                 for (x = 0; x < 96; x++) *ptr++ = 0x00ff00;/* green */
 268                 for (x = 0; x < 96; x++) *ptr++ = 0xff00ff;/* magenta */
 269                 for (x = 0; x < 96; x++) *ptr++ = 0xff0000;/* red */
 270                 for (x = 0; x < 96; x++) *ptr++ = 0x0000ff;/* blue */
 271                 for (x = 0; x < 96; x++) *ptr++ = 0x000000;/* black */
 272         }
 273         fm2fb_blank(0, info);
 274 
 275         if (fm2fb_mode == -1)
 276                 fm2fb_mode = FM2FB_MODE_PAL;
 277 
 278         info->fbops = &fm2fb_ops;
 279         info->var = fb_var_modes[fm2fb_mode];
 280         info->pseudo_palette = info->par;
 281         info->par = NULL;
 282         info->fix = fb_fix;
 283         info->flags = FBINFO_DEFAULT;
 284 
 285         if (register_framebuffer(info) < 0) {
 286                 fb_dealloc_cmap(&info->cmap);
 287                 iounmap(info->screen_base);
 288                 framebuffer_release(info);
 289                 zorro_release_device(z);
 290                 return -EINVAL;
 291         }
 292         fb_info(info, "%s frame buffer device\n", fb_fix.id);
 293         return 0;
 294 }
 295 
 296 int __init fm2fb_setup(char *options)
 297 {
 298         char *this_opt;
 299 
 300         if (!options || !*options)
 301                 return 0;
 302 
 303         while ((this_opt = strsep(&options, ",")) != NULL) {
 304                 if (!strncmp(this_opt, "pal", 3))
 305                         fm2fb_mode = FM2FB_MODE_PAL;
 306                 else if (!strncmp(this_opt, "ntsc", 4))
 307                         fm2fb_mode = FM2FB_MODE_NTSC;
 308         }
 309         return 0;
 310 }
 311 
 312 int __init fm2fb_init(void)
 313 {
 314         char *option = NULL;
 315 
 316         if (fb_get_options("fm2fb", &option))
 317                 return -ENODEV;
 318         fm2fb_setup(option);
 319         return zorro_register_driver(&fm2fb_driver);
 320 }
 321 
 322 module_init(fm2fb_init);
 323 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */