1 /* cg14.c: CGFOURTEEN frame buffer driver
 
   3  * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
 
   4  * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
 
   5  * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
 
   7  * Driver layout based loosely on tgafb.c, see that file for credits.
 
  10 #include <linux/module.h>
 
  11 #include <linux/kernel.h>
 
  12 #include <linux/errno.h>
 
  13 #include <linux/string.h>
 
  14 #include <linux/slab.h>
 
  15 #include <linux/delay.h>
 
  16 #include <linux/init.h>
 
  22 #include <asm/of_device.h>
 
  31 static int cg14_setcolreg(unsigned, unsigned, unsigned, unsigned,
 
  32                          unsigned, struct fb_info *);
 
  34 static int cg14_mmap(struct fb_info *, struct vm_area_struct *);
 
  35 static int cg14_ioctl(struct fb_info *, unsigned int, unsigned long);
 
  36 static int cg14_pan_display(struct fb_var_screeninfo *, struct fb_info *);
 
  39  *  Frame buffer operations
 
  42 static struct fb_ops cg14_ops = {
 
  44         .fb_setcolreg           = cg14_setcolreg,
 
  45         .fb_pan_display         = cg14_pan_display,
 
  46         .fb_fillrect            = cfb_fillrect,
 
  47         .fb_copyarea            = cfb_copyarea,
 
  48         .fb_imageblit           = cfb_imageblit,
 
  50         .fb_ioctl               = cg14_ioctl,
 
  52         .fb_compat_ioctl        = sbusfb_compat_ioctl,
 
  56 #define CG14_MCR_INTENABLE_SHIFT        7
 
  57 #define CG14_MCR_INTENABLE_MASK         0x80
 
  58 #define CG14_MCR_VIDENABLE_SHIFT        6
 
  59 #define CG14_MCR_VIDENABLE_MASK         0x40
 
  60 #define CG14_MCR_PIXMODE_SHIFT          4
 
  61 #define CG14_MCR_PIXMODE_MASK           0x30
 
  62 #define CG14_MCR_TMR_SHIFT              2
 
  63 #define CG14_MCR_TMR_MASK               0x0c
 
  64 #define CG14_MCR_TMENABLE_SHIFT         1
 
  65 #define CG14_MCR_TMENABLE_MASK          0x02
 
  66 #define CG14_MCR_RESET_SHIFT            0
 
  67 #define CG14_MCR_RESET_MASK             0x01
 
  68 #define CG14_REV_REVISION_SHIFT         4
 
  69 #define CG14_REV_REVISION_MASK          0xf0
 
  70 #define CG14_REV_IMPL_SHIFT             0
 
  71 #define CG14_REV_IMPL_MASK              0x0f
 
  72 #define CG14_VBR_FRAMEBASE_SHIFT        12
 
  73 #define CG14_VBR_FRAMEBASE_MASK         0x00fff000
 
  74 #define CG14_VMCR1_SETUP_SHIFT          0
 
  75 #define CG14_VMCR1_SETUP_MASK           0x000001ff
 
  76 #define CG14_VMCR1_VCONFIG_SHIFT        9
 
  77 #define CG14_VMCR1_VCONFIG_MASK         0x00000e00
 
  78 #define CG14_VMCR2_REFRESH_SHIFT        0
 
  79 #define CG14_VMCR2_REFRESH_MASK         0x00000001
 
  80 #define CG14_VMCR2_TESTROWCNT_SHIFT     1
 
  81 #define CG14_VMCR2_TESTROWCNT_MASK      0x00000002
 
  82 #define CG14_VMCR2_FBCONFIG_SHIFT       2
 
  83 #define CG14_VMCR2_FBCONFIG_MASK        0x0000000c
 
  84 #define CG14_VCR_REFRESHREQ_SHIFT       0
 
  85 #define CG14_VCR_REFRESHREQ_MASK        0x000003ff
 
  86 #define CG14_VCR1_REFRESHENA_SHIFT      10
 
  87 #define CG14_VCR1_REFRESHENA_MASK       0x00000400
 
  88 #define CG14_VCA_CAD_SHIFT              0
 
  89 #define CG14_VCA_CAD_MASK               0x000003ff
 
  90 #define CG14_VCA_VERS_SHIFT             10
 
  91 #define CG14_VCA_VERS_MASK              0x00000c00
 
  92 #define CG14_VCA_RAMSPEED_SHIFT         12
 
  93 #define CG14_VCA_RAMSPEED_MASK          0x00001000
 
  94 #define CG14_VCA_8MB_SHIFT              13
 
  95 #define CG14_VCA_8MB_MASK               0x00002000
 
  97 #define CG14_MCR_PIXMODE_8              0
 
  98 #define CG14_MCR_PIXMODE_16             2
 
  99 #define CG14_MCR_PIXMODE_32             3
 
 102         u8 mcr; /* Master Control Reg */
 
 103         u8 ppr; /* Packed Pixel Reg */
 
 104         u8 tms[2];      /* Test Mode Status Regs */
 
 105         u8 msr; /* Master Status Reg */
 
 106         u8 fsr; /* Fault Status Reg */
 
 107         u8 rev; /* Revision & Impl */
 
 108         u8 ccr; /* Clock Control Reg */
 
 109         u32 tmr;        /* Test Mode Read Back */
 
 110         u8 mod; /* Monitor Operation Data Reg */
 
 111         u8 acr; /* Aux Control */
 
 113         u16 hct;        /* Hor Counter */
 
 114         u16 vct;        /* Vert Counter */
 
 115         u16 hbs;        /* Hor Blank Start */
 
 116         u16 hbc;        /* Hor Blank Clear */
 
 117         u16 hss;        /* Hor Sync Start */
 
 118         u16 hsc;        /* Hor Sync Clear */
 
 119         u16 csc;        /* Composite Sync Clear */
 
 120         u16 vbs;        /* Vert Blank Start */
 
 121         u16 vbc;        /* Vert Blank Clear */
 
 122         u16 vss;        /* Vert Sync Start */
 
 123         u16 vsc;        /* Vert Sync Clear */
 
 126         u16 fsa;        /* Fault Status Address */
 
 127         u16 adr;        /* Address Registers */
 
 129         u8 pcg[0x100]; /* Pixel Clock Generator */
 
 130         u32 vbr;        /* Frame Base Row */
 
 131         u32 vmcr;       /* VBC Master Control */
 
 132         u32 vcr;        /* VBC refresh */
 
 133         u32 vca;        /* VBC Config */
 
 136 #define CG14_CCR_ENABLE 0x04
 
 137 #define CG14_CCR_SELECT 0x02    /* HW/Full screen */
 
 140         u32 cpl0[32];   /* Enable plane 0 */
 
 141         u32 cpl1[32];  /* Color selection plane */
 
 142         u8 ccr; /* Cursor Control Reg */
 
 144         u16 cursx;      /* Cursor x,y position */
 
 145         u16 cursy;      /* Cursor x,y position */
 
 149         u32 cpl0i[32];  /* Enable plane 0 autoinc */
 
 150         u32 cpl1i[32]; /* Color selection autoinc */
 
 154         u8 addr;        /* Address Register */
 
 156         u8 glut;        /* Gamma table */
 
 158         u8 select;      /* Register Select */
 
 160         u8 mode;        /* Mode Register */
 
 168         u8 x_xlutd_inc [256];
 
 171 /* Color look up table (clut) */
 
 172 /* Each one of these arrays hold the color lookup table (for 256
 
 173  * colors) for each MDI page (I assume then there should be 4 MDI
 
 174  * pages, I still wonder what they are.  I have seen NeXTStep split
 
 175  * the screen in four parts, while operating in 24 bits mode.  Each
 
 176  * integer holds 4 values: alpha value (transparency channel, thanks
 
 177  * go to John Stone (johns@umr.edu) from OpenBSD), red, green and blue
 
 179  * I currently use the clut instead of the Xlut
 
 183         u32 c_clutd [256];    /* i wonder what the 'd' is for */
 
 184         u32 c_clut_inc [256];
 
 185         u32 c_clutd_inc [256];
 
 188 #define CG14_MMAP_ENTRIES       16
 
 192         struct cg14_regs        __iomem *regs;
 
 193         struct cg14_clut        __iomem *clut;
 
 194         struct cg14_cursor      __iomem *cursor;
 
 197 #define CG14_FLAG_BLANKED       0x00000001
 
 199         unsigned long           physbase;
 
 200         unsigned long           iospace;
 
 201         unsigned long           fbsize;
 
 203         struct sbus_mmap_map    mmap_map[CG14_MMAP_ENTRIES];
 
 209 static void __cg14_reset(struct cg14_par *par)
 
 211         struct cg14_regs __iomem *regs = par->regs;
 
 214         val = sbus_readb(®s->mcr);
 
 215         val &= ~(CG14_MCR_PIXMODE_MASK);
 
 216         sbus_writeb(val, ®s->mcr);
 
 219 static int cg14_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
 
 221         struct cg14_par *par = (struct cg14_par *) info->par;
 
 224         /* We just use this to catch switches out of
 
 227         spin_lock_irqsave(&par->lock, flags);
 
 229         spin_unlock_irqrestore(&par->lock, flags);
 
 231         if (var->xoffset || var->yoffset || var->vmode)
 
 237  *      cg14_setcolreg - Optional function. Sets a color register.
 
 238  *      @regno: boolean, 0 copy local, 1 get_user() function
 
 239  *      @red: frame buffer colormap structure
 
 240  *      @green: The green value which can be up to 16 bits wide
 
 241  *      @blue:  The blue value which can be up to 16 bits wide.
 
 242  *      @transp: If supported the alpha value which can be up to 16 bits wide.
 
 243  *      @info: frame buffer info structure
 
 245 static int cg14_setcolreg(unsigned regno,
 
 246                           unsigned red, unsigned green, unsigned blue,
 
 247                           unsigned transp, struct fb_info *info)
 
 249         struct cg14_par *par = (struct cg14_par *) info->par;
 
 250         struct cg14_clut __iomem *clut = par->clut;
 
 260         val = (red | (green << 8) | (blue << 16));
 
 262         spin_lock_irqsave(&par->lock, flags);
 
 263         sbus_writel(val, &clut->c_clut[regno]);
 
 264         spin_unlock_irqrestore(&par->lock, flags);
 
 269 static int cg14_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
 271         struct cg14_par *par = (struct cg14_par *) info->par;
 
 273         return sbusfb_mmap_helper(par->mmap_map,
 
 274                                   par->physbase, par->fbsize,
 
 278 static int cg14_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
 
 280         struct cg14_par *par = (struct cg14_par *) info->par;
 
 281         struct cg14_regs __iomem *regs = par->regs;
 
 282         struct mdi_cfginfo kmdi, __user *mdii;
 
 284         int cur_mode, mode, ret = 0;
 
 288                 spin_lock_irqsave(&par->lock, flags);
 
 290                 spin_unlock_irqrestore(&par->lock, flags);
 
 293         case MDI_GET_CFGINFO:
 
 294                 memset(&kmdi, 0, sizeof(kmdi));
 
 296                 spin_lock_irqsave(&par->lock, flags);
 
 297                 kmdi.mdi_type = FBTYPE_MDICOLOR;
 
 298                 kmdi.mdi_height = info->var.yres;
 
 299                 kmdi.mdi_width = info->var.xres;
 
 300                 kmdi.mdi_mode = par->mode;
 
 301                 kmdi.mdi_pixfreq = 72; /* FIXME */
 
 302                 kmdi.mdi_size = par->ramsize;
 
 303                 spin_unlock_irqrestore(&par->lock, flags);
 
 305                 mdii = (struct mdi_cfginfo __user *) arg;
 
 306                 if (copy_to_user(mdii, &kmdi, sizeof(kmdi)))
 
 310         case MDI_SET_PIXELMODE:
 
 311                 if (get_user(mode, (int __user *) arg)) {
 
 316                 spin_lock_irqsave(&par->lock, flags);
 
 317                 cur_mode = sbus_readb(®s->mcr);
 
 318                 cur_mode &= ~CG14_MCR_PIXMODE_MASK;
 
 321                         cur_mode |= (CG14_MCR_PIXMODE_32 <<
 
 322                                      CG14_MCR_PIXMODE_SHIFT);
 
 326                         cur_mode |= (CG14_MCR_PIXMODE_16 <<
 
 327                                      CG14_MCR_PIXMODE_SHIFT);
 
 338                         sbus_writeb(cur_mode, ®s->mcr);
 
 341                 spin_unlock_irqrestore(&par->lock, flags);
 
 345                 ret = sbusfb_ioctl_helper(cmd, arg, info,
 
 346                                           FBTYPE_MDICOLOR, 8, par->fbsize);
 
 357 static void __devinit cg14_init_fix(struct fb_info *info, int linebytes,
 
 358                                     struct device_node *dp)
 
 360         const char *name = dp->name;
 
 362         strlcpy(info->fix.id, name, sizeof(info->fix.id));
 
 364         info->fix.type = FB_TYPE_PACKED_PIXELS;
 
 365         info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
 
 367         info->fix.line_length = linebytes;
 
 369         info->fix.accel = FB_ACCEL_SUN_CG14;
 
 372 static struct sbus_mmap_map __cg14_mmap_map[CG14_MMAP_ENTRIES] __devinitdata = {
 
 399                 .voff   = CG3_MMAP_OFFSET - 0x7000,
 
 404                 .voff   = CG3_MMAP_OFFSET,
 
 406                 .size   = SBUS_MMAP_FBSIZE(1)
 
 409                 .voff   = MDI_CURSOR_MAP,
 
 414                 .voff   = MDI_CHUNKY_BGR_MAP,
 
 419                 .voff   = MDI_PLANAR_X16_MAP,
 
 424                 .voff   = MDI_PLANAR_C16_MAP,
 
 429                 .voff   = MDI_PLANAR_X32_MAP,
 
 434                 .voff   = MDI_PLANAR_B32_MAP,
 
 439                 .voff   = MDI_PLANAR_G32_MAP,
 
 444                 .voff   = MDI_PLANAR_R32_MAP,
 
 451 static void cg14_unmap_regs(struct of_device *op, struct fb_info *info,
 
 452                             struct cg14_par *par)
 
 455                 of_iounmap(&op->resource[0],
 
 456                            par->regs, sizeof(struct cg14_regs));
 
 458                 of_iounmap(&op->resource[0],
 
 459                            par->clut, sizeof(struct cg14_clut));
 
 461                 of_iounmap(&op->resource[0],
 
 462                            par->cursor, sizeof(struct cg14_cursor));
 
 463         if (info->screen_base)
 
 464                 of_iounmap(&op->resource[1],
 
 465                            info->screen_base, par->fbsize);
 
 468 static int __devinit cg14_probe(struct of_device *op, const struct of_device_id *match)
 
 470         struct device_node *dp = op->node;
 
 471         struct fb_info *info;
 
 472         struct cg14_par *par;
 
 473         int is_8mb, linebytes, i, err;
 
 475         info = framebuffer_alloc(sizeof(struct cg14_par), &op->dev);
 
 482         spin_lock_init(&par->lock);
 
 484         sbusfb_fill_var(&info->var, dp->node, 8);
 
 485         info->var.red.length = 8;
 
 486         info->var.green.length = 8;
 
 487         info->var.blue.length = 8;
 
 489         linebytes = of_getintprop_default(dp, "linebytes",
 
 491         par->fbsize = PAGE_ALIGN(linebytes * info->var.yres);
 
 493         if (!strcmp(dp->parent->name, "sbus") ||
 
 494             !strcmp(dp->parent->name, "sbi")) {
 
 495                 par->physbase = op->resource[0].start;
 
 496                 par->iospace = op->resource[0].flags & IORESOURCE_BITS;
 
 498                 par->physbase = op->resource[1].start;
 
 499                 par->iospace = op->resource[0].flags & IORESOURCE_BITS;
 
 502         par->regs = of_ioremap(&op->resource[0], 0,
 
 503                                sizeof(struct cg14_regs), "cg14 regs");
 
 504         par->clut = of_ioremap(&op->resource[0], CG14_CLUT1,
 
 505                                sizeof(struct cg14_clut), "cg14 clut");
 
 506         par->cursor = of_ioremap(&op->resource[0], CG14_CURSORREGS,
 
 507                                  sizeof(struct cg14_cursor), "cg14 cursor");
 
 509         info->screen_base = of_ioremap(&op->resource[1], 0,
 
 510                                        par->fbsize, "cg14 ram");
 
 512         if (!par->regs || !par->clut || !par->cursor || !info->screen_base)
 
 515         is_8mb = (((op->resource[1].end - op->resource[1].start) + 1) ==
 
 518         BUILD_BUG_ON(sizeof(par->mmap_map) != sizeof(__cg14_mmap_map));
 
 520         memcpy(&par->mmap_map, &__cg14_mmap_map, sizeof(par->mmap_map));
 
 522         for (i = 0; i < CG14_MMAP_ENTRIES; i++) {
 
 523                 struct sbus_mmap_map *map = &par->mmap_map[i];
 
 527                 if (map->poff & 0x80000000)
 
 528                         map->poff = (map->poff & 0x7fffffff) +
 
 529                                 (op->resource[0].start -
 
 530                                  op->resource[1].start);
 
 532                     map->size >= 0x100000 &&
 
 533                     map->size <= 0x400000)
 
 537         par->mode = MDI_8_PIX;
 
 538         par->ramsize = (is_8mb ? 0x800000 : 0x400000);
 
 540         info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
 
 541         info->fbops = &cg14_ops;
 
 545         if (fb_alloc_cmap(&info->cmap, 256, 0))
 
 548         fb_set_cmap(&info->cmap, info);
 
 550         cg14_init_fix(info, linebytes, dp);
 
 552         err = register_framebuffer(info);
 
 554                 goto out_dealloc_cmap;
 
 556         dev_set_drvdata(&op->dev, info);
 
 558         printk("%s: cgfourteen at %lx:%lx, %dMB\n",
 
 560                par->iospace, par->physbase,
 
 566         fb_dealloc_cmap(&info->cmap);
 
 569         cg14_unmap_regs(op, info, par);
 
 575 static int __devexit cg14_remove(struct of_device *op)
 
 577         struct fb_info *info = dev_get_drvdata(&op->dev);
 
 578         struct cg14_par *par = info->par;
 
 580         unregister_framebuffer(info);
 
 581         fb_dealloc_cmap(&info->cmap);
 
 583         cg14_unmap_regs(op, info, par);
 
 585         framebuffer_release(info);
 
 587         dev_set_drvdata(&op->dev, NULL);
 
 592 static struct of_device_id cg14_match[] = {
 
 594                 .name = "cgfourteen",
 
 598 MODULE_DEVICE_TABLE(of, cg14_match);
 
 600 static struct of_platform_driver cg14_driver = {
 
 602         .match_table    = cg14_match,
 
 604         .remove         = __devexit_p(cg14_remove),
 
 607 int __init cg14_init(void)
 
 609         if (fb_get_options("cg14fb", NULL))
 
 612         return of_register_driver(&cg14_driver, &of_bus_type);
 
 615 void __exit cg14_exit(void)
 
 617         of_unregister_driver(&cg14_driver);
 
 620 module_init(cg14_init);
 
 621 module_exit(cg14_exit);
 
 623 MODULE_DESCRIPTION("framebuffer driver for CGfourteen chipsets");
 
 624 MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
 
 625 MODULE_VERSION("2.0");
 
 626 MODULE_LICENSE("GPL");