1 /* ffb.c: Creator/Elite3D frame buffer driver
 
   3  * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
 
   4  * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz)
 
   6  * Driver layout based loosely on tgafb.c, see that file for credits.
 
   9 #include <linux/module.h>
 
  10 #include <linux/kernel.h>
 
  11 #include <linux/errno.h>
 
  12 #include <linux/string.h>
 
  13 #include <linux/slab.h>
 
  14 #include <linux/delay.h>
 
  15 #include <linux/init.h>
 
  18 #include <linux/timer.h>
 
  19 #include <linux/of_device.h>
 
  31 static int ffb_setcolreg(unsigned, unsigned, unsigned, unsigned,
 
  32                          unsigned, struct fb_info *);
 
  33 static int ffb_blank(int, struct fb_info *);
 
  35 static void ffb_imageblit(struct fb_info *, const struct fb_image *);
 
  36 static void ffb_fillrect(struct fb_info *, const struct fb_fillrect *);
 
  37 static void ffb_copyarea(struct fb_info *, const struct fb_copyarea *);
 
  38 static int ffb_sync(struct fb_info *);
 
  39 static int ffb_mmap(struct fb_info *, struct vm_area_struct *);
 
  40 static int ffb_ioctl(struct fb_info *, unsigned int, unsigned long);
 
  41 static int ffb_pan_display(struct fb_var_screeninfo *, struct fb_info *);
 
  44  *  Frame buffer operations
 
  47 static struct fb_ops ffb_ops = {
 
  49         .fb_setcolreg           = ffb_setcolreg,
 
  50         .fb_blank               = ffb_blank,
 
  51         .fb_pan_display         = ffb_pan_display,
 
  52         .fb_fillrect            = ffb_fillrect,
 
  53         .fb_copyarea            = ffb_copyarea,
 
  54         .fb_imageblit           = ffb_imageblit,
 
  57         .fb_ioctl               = ffb_ioctl,
 
  59         .fb_compat_ioctl        = sbusfb_compat_ioctl,
 
  63 /* Register layout and definitions */
 
  64 #define FFB_SFB8R_VOFF          0x00000000
 
  65 #define FFB_SFB8G_VOFF          0x00400000
 
  66 #define FFB_SFB8B_VOFF          0x00800000
 
  67 #define FFB_SFB8X_VOFF          0x00c00000
 
  68 #define FFB_SFB32_VOFF          0x01000000
 
  69 #define FFB_SFB64_VOFF          0x02000000
 
  70 #define FFB_FBC_REGS_VOFF       0x04000000
 
  71 #define FFB_BM_FBC_REGS_VOFF    0x04002000
 
  72 #define FFB_DFB8R_VOFF          0x04004000
 
  73 #define FFB_DFB8G_VOFF          0x04404000
 
  74 #define FFB_DFB8B_VOFF          0x04804000
 
  75 #define FFB_DFB8X_VOFF          0x04c04000
 
  76 #define FFB_DFB24_VOFF          0x05004000
 
  77 #define FFB_DFB32_VOFF          0x06004000
 
  78 #define FFB_DFB422A_VOFF        0x07004000      /* DFB 422 mode write to A */
 
  79 #define FFB_DFB422AD_VOFF       0x07804000      /* DFB 422 mode with line doubling */
 
  80 #define FFB_DFB24B_VOFF         0x08004000      /* DFB 24bit mode write to B */
 
  81 #define FFB_DFB422B_VOFF        0x09004000      /* DFB 422 mode write to B */
 
  82 #define FFB_DFB422BD_VOFF       0x09804000      /* DFB 422 mode with line doubling */
 
  83 #define FFB_SFB16Z_VOFF         0x0a004000      /* 16bit mode Z planes */
 
  84 #define FFB_SFB8Z_VOFF          0x0a404000      /* 8bit mode Z planes */
 
  85 #define FFB_SFB422_VOFF         0x0ac04000      /* SFB 422 mode write to A/B */
 
  86 #define FFB_SFB422D_VOFF        0x0b404000      /* SFB 422 mode with line doubling */
 
  87 #define FFB_FBC_KREGS_VOFF      0x0bc04000
 
  88 #define FFB_DAC_VOFF            0x0bc06000
 
  89 #define FFB_PROM_VOFF           0x0bc08000
 
  90 #define FFB_EXP_VOFF            0x0bc18000
 
  92 #define FFB_SFB8R_POFF          0x04000000UL
 
  93 #define FFB_SFB8G_POFF          0x04400000UL
 
  94 #define FFB_SFB8B_POFF          0x04800000UL
 
  95 #define FFB_SFB8X_POFF          0x04c00000UL
 
  96 #define FFB_SFB32_POFF          0x05000000UL
 
  97 #define FFB_SFB64_POFF          0x06000000UL
 
  98 #define FFB_FBC_REGS_POFF       0x00600000UL
 
  99 #define FFB_BM_FBC_REGS_POFF    0x00600000UL
 
 100 #define FFB_DFB8R_POFF          0x01000000UL
 
 101 #define FFB_DFB8G_POFF          0x01400000UL
 
 102 #define FFB_DFB8B_POFF          0x01800000UL
 
 103 #define FFB_DFB8X_POFF          0x01c00000UL
 
 104 #define FFB_DFB24_POFF          0x02000000UL
 
 105 #define FFB_DFB32_POFF          0x03000000UL
 
 106 #define FFB_FBC_KREGS_POFF      0x00610000UL
 
 107 #define FFB_DAC_POFF            0x00400000UL
 
 108 #define FFB_PROM_POFF           0x00000000UL
 
 109 #define FFB_EXP_POFF            0x00200000UL
 
 110 #define FFB_DFB422A_POFF        0x09000000UL
 
 111 #define FFB_DFB422AD_POFF       0x09800000UL
 
 112 #define FFB_DFB24B_POFF         0x0a000000UL
 
 113 #define FFB_DFB422B_POFF        0x0b000000UL
 
 114 #define FFB_DFB422BD_POFF       0x0b800000UL
 
 115 #define FFB_SFB16Z_POFF         0x0c800000UL
 
 116 #define FFB_SFB8Z_POFF          0x0c000000UL
 
 117 #define FFB_SFB422_POFF         0x0d000000UL
 
 118 #define FFB_SFB422D_POFF        0x0d800000UL
 
 120 /* Draw operations */
 
 121 #define FFB_DRAWOP_DOT          0x00
 
 122 #define FFB_DRAWOP_AADOT        0x01
 
 123 #define FFB_DRAWOP_BRLINECAP    0x02
 
 124 #define FFB_DRAWOP_BRLINEOPEN   0x03
 
 125 #define FFB_DRAWOP_DDLINE       0x04
 
 126 #define FFB_DRAWOP_AALINE       0x05
 
 127 #define FFB_DRAWOP_TRIANGLE     0x06
 
 128 #define FFB_DRAWOP_POLYGON      0x07
 
 129 #define FFB_DRAWOP_RECTANGLE    0x08
 
 130 #define FFB_DRAWOP_FASTFILL     0x09
 
 131 #define FFB_DRAWOP_BCOPY        0x0a
 
 132 #define FFB_DRAWOP_VSCROLL      0x0b
 
 134 /* Pixel processor control */
 
 136 #define FFB_PPC_FW_DISABLE      0x800000
 
 137 #define FFB_PPC_FW_ENABLE       0xc00000
 
 139 #define FFB_PPC_ACE_DISABLE     0x040000
 
 140 #define FFB_PPC_ACE_AUX_SUB     0x080000
 
 141 #define FFB_PPC_ACE_AUX_ADD     0x0c0000
 
 143 #define FFB_PPC_DCE_DISABLE     0x020000
 
 144 #define FFB_PPC_DCE_ENABLE      0x030000
 
 146 #define FFB_PPC_ABE_DISABLE     0x008000
 
 147 #define FFB_PPC_ABE_ENABLE      0x00c000
 
 149 #define FFB_PPC_VCE_DISABLE     0x001000
 
 150 #define FFB_PPC_VCE_2D          0x002000
 
 151 #define FFB_PPC_VCE_3D          0x003000
 
 153 #define FFB_PPC_APE_DISABLE     0x000800
 
 154 #define FFB_PPC_APE_ENABLE      0x000c00
 
 155 /* Transparent background */
 
 156 #define FFB_PPC_TBE_OPAQUE      0x000200
 
 157 #define FFB_PPC_TBE_TRANSPARENT 0x000300
 
 159 #define FFB_PPC_ZS_VAR          0x000080
 
 160 #define FFB_PPC_ZS_CONST        0x0000c0
 
 162 #define FFB_PPC_YS_VAR          0x000020
 
 163 #define FFB_PPC_YS_CONST        0x000030
 
 165 #define FFB_PPC_XS_WID          0x000004
 
 166 #define FFB_PPC_XS_VAR          0x000008
 
 167 #define FFB_PPC_XS_CONST        0x00000c
 
 168 /* Color (BGR) source */
 
 169 #define FFB_PPC_CS_VAR          0x000002
 
 170 #define FFB_PPC_CS_CONST        0x000003
 
 172 #define FFB_ROP_NEW             0x83
 
 173 #define FFB_ROP_OLD             0x85
 
 174 #define FFB_ROP_NEW_XOR_OLD     0x86
 
 176 #define FFB_UCSR_FIFO_MASK      0x00000fff
 
 177 #define FFB_UCSR_FB_BUSY        0x01000000
 
 178 #define FFB_UCSR_RP_BUSY        0x02000000
 
 179 #define FFB_UCSR_ALL_BUSY       (FFB_UCSR_RP_BUSY|FFB_UCSR_FB_BUSY)
 
 180 #define FFB_UCSR_READ_ERR       0x40000000
 
 181 #define FFB_UCSR_FIFO_OVFL      0x80000000
 
 182 #define FFB_UCSR_ALL_ERRORS     (FFB_UCSR_READ_ERR|FFB_UCSR_FIFO_OVFL)
 
 185         /* Next vertex registers */
 
 215         /* Setup unit vertex state register */
 
 219         /* Control registers */
 
 271         /* New 3dRAM III support regs */
 
 337 #define FFB_DAC_UCTRL           0x1001 /* User Control */
 
 338 #define FFB_DAC_UCTRL_MANREV    0x00000f00 /* 4-bit Manufacturing Revision */
 
 339 #define FFB_DAC_UCTRL_MANREV_SHIFT 8
 
 340 #define FFB_DAC_TGEN            0x6000 /* Timing Generator */
 
 341 #define FFB_DAC_TGEN_VIDE       0x00000001 /* Video Enable */
 
 342 #define FFB_DAC_DID             0x8000 /* Device Identification */
 
 343 #define FFB_DAC_DID_PNUM        0x0ffff000 /* Device Part Number */
 
 344 #define FFB_DAC_DID_PNUM_SHIFT  12
 
 345 #define FFB_DAC_DID_REV         0xf0000000 /* Device Revision */
 
 346 #define FFB_DAC_DID_REV_SHIFT   28
 
 348 #define FFB_DAC_CUR_CTRL        0x100
 
 349 #define FFB_DAC_CUR_CTRL_P0     0x00000001
 
 350 #define FFB_DAC_CUR_CTRL_P1     0x00000002
 
 354         struct ffb_fbc __iomem  *fbc;
 
 355         struct ffb_dac __iomem  *dac;
 
 358 #define FFB_FLAG_AFB            0x00000001 /* AFB m3 or m6 */
 
 359 #define FFB_FLAG_BLANKED        0x00000002 /* screen is blanked */
 
 360 #define FFB_FLAG_INVCURSOR      0x00000004 /* DAC has inverted cursor logic */
 
 362         u32                     fg_cache __attribute__((aligned (8)));
 
 368         unsigned long           physbase;
 
 369         unsigned long           fbsize;
 
 373         u32                     pseudo_palette[16];
 
 376 static void FFBFifo(struct ffb_par *par, int n)
 
 378         struct ffb_fbc __iomem *fbc;
 
 379         int cache = par->fifo_cache;
 
 384                         cache = (upa_readl(&fbc->ucsr) & FFB_UCSR_FIFO_MASK);
 
 386                 } while (cache - n < 0);
 
 388         par->fifo_cache = cache - n;
 
 391 static void FFBWait(struct ffb_par *par)
 
 393         struct ffb_fbc __iomem *fbc;
 
 398                 if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_BUSY) == 0)
 
 400                 if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0) {
 
 401                         upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr);
 
 404         } while (--limit > 0);
 
 407 static int ffb_sync(struct fb_info *p)
 
 409         struct ffb_par *par = (struct ffb_par *)p->par;
 
 415 static __inline__ void ffb_rop(struct ffb_par *par, u32 rop)
 
 417         if (par->rop_cache != rop) {
 
 419                 upa_writel(rop, &par->fbc->rop);
 
 420                 par->rop_cache = rop;
 
 424 static void ffb_switch_from_graph(struct ffb_par *par)
 
 426         struct ffb_fbc __iomem *fbc = par->fbc;
 
 427         struct ffb_dac __iomem *dac = par->dac;
 
 430         spin_lock_irqsave(&par->lock, flags);
 
 434         upa_writel(FFB_PPC_VCE_DISABLE | FFB_PPC_TBE_OPAQUE |
 
 435                    FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST,
 
 437         upa_writel(0x2000707f, &fbc->fbc);
 
 438         upa_writel(par->rop_cache, &fbc->rop);
 
 439         upa_writel(0xffffffff, &fbc->pmask);
 
 440         upa_writel((1 << 16) | (0 << 0), &fbc->fontinc);
 
 441         upa_writel(par->fg_cache, &fbc->fg);
 
 442         upa_writel(par->bg_cache, &fbc->bg);
 
 445         /* Disable cursor.  */
 
 446         upa_writel(FFB_DAC_CUR_CTRL, &dac->type2);
 
 447         if (par->flags & FFB_FLAG_INVCURSOR)
 
 448                 upa_writel(0, &dac->value2);
 
 450                 upa_writel((FFB_DAC_CUR_CTRL_P0 |
 
 451                             FFB_DAC_CUR_CTRL_P1), &dac->value2);
 
 453         spin_unlock_irqrestore(&par->lock, flags);
 
 456 static int ffb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
 
 458         struct ffb_par *par = (struct ffb_par *)info->par;
 
 460         /* We just use this to catch switches out of
 
 463         ffb_switch_from_graph(par);
 
 465         if (var->xoffset || var->yoffset || var->vmode)
 
 471  *      ffb_fillrect - Draws a rectangle on the screen.
 
 473  *      @info: frame buffer structure that represents a single frame buffer
 
 474  *      @rect: structure defining the rectagle and operation.
 
 476 static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 
 478         struct ffb_par *par = (struct ffb_par *)info->par;
 
 479         struct ffb_fbc __iomem *fbc = par->fbc;
 
 483         BUG_ON(rect->rop != ROP_COPY && rect->rop != ROP_XOR);
 
 485         fg = ((u32 *)info->pseudo_palette)[rect->color];
 
 487         spin_lock_irqsave(&par->lock, flags);
 
 489         if (fg != par->fg_cache) {
 
 491                 upa_writel(fg, &fbc->fg);
 
 495         ffb_rop(par, rect->rop == ROP_COPY ?
 
 497                      FFB_ROP_NEW_XOR_OLD);
 
 500         upa_writel(FFB_DRAWOP_RECTANGLE, &fbc->drawop);
 
 501         upa_writel(rect->dy, &fbc->by);
 
 502         upa_writel(rect->dx, &fbc->bx);
 
 503         upa_writel(rect->height, &fbc->bh);
 
 504         upa_writel(rect->width, &fbc->bw);
 
 506         spin_unlock_irqrestore(&par->lock, flags);
 
 510  *      ffb_copyarea - Copies on area of the screen to another area.
 
 512  *      @info: frame buffer structure that represents a single frame buffer
 
 513  *      @area: structure defining the source and destination.
 
 516 static void ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 
 518         struct ffb_par *par = (struct ffb_par *)info->par;
 
 519         struct ffb_fbc __iomem *fbc = par->fbc;
 
 522         if (area->dx != area->sx ||
 
 523             area->dy == area->sy) {
 
 524                 cfb_copyarea(info, area);
 
 528         spin_lock_irqsave(&par->lock, flags);
 
 530         ffb_rop(par, FFB_ROP_OLD);
 
 533         upa_writel(FFB_DRAWOP_VSCROLL, &fbc->drawop);
 
 534         upa_writel(area->sy, &fbc->by);
 
 535         upa_writel(area->sx, &fbc->bx);
 
 536         upa_writel(area->dy, &fbc->dy);
 
 537         upa_writel(area->dx, &fbc->dx);
 
 538         upa_writel(area->height, &fbc->bh);
 
 539         upa_writel(area->width, &fbc->bw);
 
 541         spin_unlock_irqrestore(&par->lock, flags);
 
 545  *      ffb_imageblit - Copies a image from system memory to the screen.
 
 547  *      @info: frame buffer structure that represents a single frame buffer
 
 548  *      @image: structure defining the image.
 
 550 static void ffb_imageblit(struct fb_info *info, const struct fb_image *image)
 
 552         struct ffb_par *par = (struct ffb_par *)info->par;
 
 553         struct ffb_fbc __iomem *fbc = par->fbc;
 
 554         const u8 *data = image->data;
 
 558         int i, width, stride;
 
 560         if (image->depth > 1) {
 
 561                 cfb_imageblit(info, image);
 
 565         fg = ((u32 *)info->pseudo_palette)[image->fg_color];
 
 566         bg = ((u32 *)info->pseudo_palette)[image->bg_color];
 
 567         fgbg = ((u64) fg << 32) | (u64) bg;
 
 568         xy = (image->dy << 16) | image->dx;
 
 569         width = image->width;
 
 570         stride = ((width + 7) >> 3);
 
 572         spin_lock_irqsave(&par->lock, flags);
 
 574         if (fgbg != *(u64 *)&par->fg_cache) {
 
 576                 upa_writeq(fgbg, &fbc->fg);
 
 577                 *(u64 *)&par->fg_cache = fgbg;
 
 582                 upa_writel(32, &fbc->fontw);
 
 585         while (width >= 32) {
 
 586                 const u8 *next_data = data + 4;
 
 589                 upa_writel(xy, &fbc->fontxy);
 
 592                 for (i = 0; i < image->height; i++) {
 
 593                         u32 val = (((u32)data[0] << 24) |
 
 594                                    ((u32)data[1] << 16) |
 
 595                                    ((u32)data[2] <<  8) |
 
 596                                    ((u32)data[3] <<  0));
 
 598                         upa_writel(val, &fbc->font);
 
 609                 upa_writel(width, &fbc->fontw);
 
 610                 upa_writel(xy, &fbc->fontxy);
 
 612                 for (i = 0; i < image->height; i++) {
 
 613                         u32 val = (((u32)data[0] << 24) |
 
 614                                    ((u32)data[1] << 16) |
 
 615                                    ((u32)data[2] <<  8) |
 
 616                                    ((u32)data[3] <<  0));
 
 618                         upa_writel(val, &fbc->font);
 
 624         spin_unlock_irqrestore(&par->lock, flags);
 
 627 static void ffb_fixup_var_rgb(struct fb_var_screeninfo *var)
 
 631         var->green.offset = 8;
 
 632         var->green.length = 8;
 
 633         var->blue.offset = 16;
 
 634         var->blue.length = 8;
 
 635         var->transp.offset = 0;
 
 636         var->transp.length = 0;
 
 640  *      ffb_setcolreg - Sets a color register.
 
 642  *      @regno: boolean, 0 copy local, 1 get_user() function
 
 643  *      @red: frame buffer colormap structure
 
 644  *      @green: The green value which can be up to 16 bits wide
 
 645  *      @blue:  The blue value which can be up to 16 bits wide.
 
 646  *      @transp: If supported the alpha value which can be up to 16 bits wide.
 
 647  *      @info: frame buffer info structure
 
 649 static int ffb_setcolreg(unsigned regno,
 
 650                          unsigned red, unsigned green, unsigned blue,
 
 651                          unsigned transp, struct fb_info *info)
 
 662         value = (blue << 16) | (green << 8) | red;
 
 663         ((u32 *)info->pseudo_palette)[regno] = value;
 
 669  *      ffb_blank - Optional function.  Blanks the display.
 
 670  *      @blank_mode: the blank mode we want.
 
 671  *      @info: frame buffer structure that represents a single frame buffer
 
 673 static int ffb_blank(int blank, struct fb_info *info)
 
 675         struct ffb_par *par = (struct ffb_par *)info->par;
 
 676         struct ffb_dac __iomem *dac = par->dac;
 
 681         spin_lock_irqsave(&par->lock, flags);
 
 685         upa_writel(FFB_DAC_TGEN, &dac->type);
 
 686         val = upa_readl(&dac->value);
 
 688         case FB_BLANK_UNBLANK: /* Unblanking */
 
 689                 val |= FFB_DAC_TGEN_VIDE;
 
 690                 par->flags &= ~FFB_FLAG_BLANKED;
 
 693         case FB_BLANK_NORMAL: /* Normal blanking */
 
 694         case FB_BLANK_VSYNC_SUSPEND: /* VESA blank (vsync off) */
 
 695         case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */
 
 696         case FB_BLANK_POWERDOWN: /* Poweroff */
 
 697                 val &= ~FFB_DAC_TGEN_VIDE;
 
 698                 par->flags |= FFB_FLAG_BLANKED;
 
 701         upa_writel(FFB_DAC_TGEN, &dac->type);
 
 702         upa_writel(val, &dac->value);
 
 703         for (i = 0; i < 10; i++) {
 
 704                 upa_writel(FFB_DAC_TGEN, &dac->type);
 
 705                 upa_readl(&dac->value);
 
 708         spin_unlock_irqrestore(&par->lock, flags);
 
 713 static struct sbus_mmap_map ffb_mmap_map[] = {
 
 715                 .voff   = FFB_SFB8R_VOFF,
 
 716                 .poff   = FFB_SFB8R_POFF,
 
 720                 .voff   = FFB_SFB8G_VOFF,
 
 721                 .poff   = FFB_SFB8G_POFF,
 
 725                 .voff   = FFB_SFB8B_VOFF,
 
 726                 .poff   = FFB_SFB8B_POFF,
 
 730                 .voff   = FFB_SFB8X_VOFF,
 
 731                 .poff   = FFB_SFB8X_POFF,
 
 735                 .voff   = FFB_SFB32_VOFF,
 
 736                 .poff   = FFB_SFB32_POFF,
 
 740                 .voff   = FFB_SFB64_VOFF,
 
 741                 .poff   = FFB_SFB64_POFF,
 
 745                 .voff   = FFB_FBC_REGS_VOFF,
 
 746                 .poff   = FFB_FBC_REGS_POFF,
 
 750                 .voff   = FFB_BM_FBC_REGS_VOFF,
 
 751                 .poff   = FFB_BM_FBC_REGS_POFF,
 
 755                 .voff   = FFB_DFB8R_VOFF,
 
 756                 .poff   = FFB_DFB8R_POFF,
 
 760                 .voff   = FFB_DFB8G_VOFF,
 
 761                 .poff   = FFB_DFB8G_POFF,
 
 765                 .voff   = FFB_DFB8B_VOFF,
 
 766                 .poff   = FFB_DFB8B_POFF,
 
 770                 .voff   = FFB_DFB8X_VOFF,
 
 771                 .poff   = FFB_DFB8X_POFF,
 
 775                 .voff   = FFB_DFB24_VOFF,
 
 776                 .poff   = FFB_DFB24_POFF,
 
 780                 .voff   = FFB_DFB32_VOFF,
 
 781                 .poff   = FFB_DFB32_POFF,
 
 785                 .voff   = FFB_FBC_KREGS_VOFF,
 
 786                 .poff   = FFB_FBC_KREGS_POFF,
 
 790                 .voff   = FFB_DAC_VOFF,
 
 791                 .poff   = FFB_DAC_POFF,
 
 795                 .voff   = FFB_PROM_VOFF,
 
 796                 .poff   = FFB_PROM_POFF,
 
 800                 .voff   = FFB_EXP_VOFF,
 
 801                 .poff   = FFB_EXP_POFF,
 
 805                 .voff   = FFB_DFB422A_VOFF,
 
 806                 .poff   = FFB_DFB422A_POFF,
 
 810                 .voff   = FFB_DFB422AD_VOFF,
 
 811                 .poff   = FFB_DFB422AD_POFF,
 
 815                 .voff   = FFB_DFB24B_VOFF,
 
 816                 .poff   = FFB_DFB24B_POFF,
 
 820                 .voff   = FFB_DFB422B_VOFF,
 
 821                 .poff   = FFB_DFB422B_POFF,
 
 825                 .voff   = FFB_DFB422BD_VOFF,
 
 826                 .poff   = FFB_DFB422BD_POFF,
 
 830                 .voff   = FFB_SFB16Z_VOFF,
 
 831                 .poff   = FFB_SFB16Z_POFF,
 
 835                 .voff   = FFB_SFB8Z_VOFF,
 
 836                 .poff   = FFB_SFB8Z_POFF,
 
 840                 .voff   = FFB_SFB422_VOFF,
 
 841                 .poff   = FFB_SFB422_POFF,
 
 845                 .voff   = FFB_SFB422D_VOFF,
 
 846                 .poff   = FFB_SFB422D_POFF,
 
 852 static int ffb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
 854         struct ffb_par *par = (struct ffb_par *)info->par;
 
 856         return sbusfb_mmap_helper(ffb_mmap_map,
 
 857                                   par->physbase, par->fbsize,
 
 861 static int ffb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
 
 863         struct ffb_par *par = (struct ffb_par *)info->par;
 
 865         return sbusfb_ioctl_helper(cmd, arg, info,
 
 866                                    FBTYPE_CREATOR, 24, par->fbsize);
 
 873 static void ffb_init_fix(struct fb_info *info)
 
 875         struct ffb_par *par = (struct ffb_par *)info->par;
 
 876         const char *ffb_type_name;
 
 878         if (!(par->flags & FFB_FLAG_AFB)) {
 
 879                 if ((par->board_type & 0x7) == 0x3)
 
 880                         ffb_type_name = "Creator 3D";
 
 882                         ffb_type_name = "Creator";
 
 884                 ffb_type_name = "Elite 3D";
 
 886         strlcpy(info->fix.id, ffb_type_name, sizeof(info->fix.id));
 
 888         info->fix.type = FB_TYPE_PACKED_PIXELS;
 
 889         info->fix.visual = FB_VISUAL_TRUECOLOR;
 
 891         /* Framebuffer length is the same regardless of resolution. */
 
 892         info->fix.line_length = 8192;
 
 894         info->fix.accel = FB_ACCEL_SUN_CREATOR;
 
 897 static int __devinit ffb_probe(struct of_device *op,
 
 898                                const struct of_device_id *match)
 
 900         struct device_node *dp = op->node;
 
 901         struct ffb_fbc __iomem *fbc;
 
 902         struct ffb_dac __iomem *dac;
 
 903         struct fb_info *info;
 
 905         u32 dac_pnum, dac_rev, dac_mrev;
 
 908         info = framebuffer_alloc(sizeof(struct ffb_par), &op->dev);
 
 916         spin_lock_init(&par->lock);
 
 917         par->fbc = of_ioremap(&op->resource[2], 0,
 
 918                               sizeof(struct ffb_fbc), "ffb fbc");
 
 922         par->dac = of_ioremap(&op->resource[1], 0,
 
 923                               sizeof(struct ffb_dac), "ffb dac");
 
 927         par->rop_cache = FFB_ROP_NEW;
 
 928         par->physbase = op->resource[0].start;
 
 930         /* Don't mention copyarea, so SCROLL_REDRAW is always
 
 931          * used.  It is the fastest on this chip.
 
 933         info->flags = (FBINFO_DEFAULT |
 
 934                        /* FBINFO_HWACCEL_COPYAREA | */
 
 935                        FBINFO_HWACCEL_FILLRECT |
 
 936                        FBINFO_HWACCEL_IMAGEBLIT);
 
 938         info->fbops = &ffb_ops;
 
 940         info->screen_base = (char *) par->physbase + FFB_DFB24_POFF;
 
 941         info->pseudo_palette = par->pseudo_palette;
 
 943         sbusfb_fill_var(&info->var, dp, 32);
 
 944         par->fbsize = PAGE_ALIGN(info->var.xres * info->var.yres * 4);
 
 945         ffb_fixup_var_rgb(&info->var);
 
 947         info->var.accel_flags = FB_ACCELF_TEXT;
 
 949         if (!strcmp(dp->name, "SUNW,afb"))
 
 950                 par->flags |= FFB_FLAG_AFB;
 
 952         par->board_type = of_getintprop_default(dp, "board_type", 0);
 
 955         if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0)
 
 956                 upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr);
 
 959         upa_writel(FFB_DAC_DID, &dac->type);
 
 960         dac_pnum = upa_readl(&dac->value);
 
 961         dac_rev = (dac_pnum & FFB_DAC_DID_REV) >> FFB_DAC_DID_REV_SHIFT;
 
 962         dac_pnum = (dac_pnum & FFB_DAC_DID_PNUM) >> FFB_DAC_DID_PNUM_SHIFT;
 
 964         upa_writel(FFB_DAC_UCTRL, &dac->type);
 
 965         dac_mrev = upa_readl(&dac->value);
 
 966         dac_mrev = (dac_mrev & FFB_DAC_UCTRL_MANREV) >>
 
 967                 FFB_DAC_UCTRL_MANREV_SHIFT;
 
 969         /* Elite3D has different DAC revision numbering, and no DAC revisions
 
 970          * have the reversed meaning of cursor enable.  Otherwise, Pacifica 1
 
 971          * ramdacs with manufacturing revision less than 3 have inverted
 
 972          * cursor logic.  We identify Pacifica 1 as not Pacifica 2, the
 
 973          * latter having a part number value of 0x236e.
 
 975         if ((par->flags & FFB_FLAG_AFB) || dac_pnum == 0x236e) {
 
 976                 par->flags &= ~FFB_FLAG_INVCURSOR;
 
 979                         par->flags |= FFB_FLAG_INVCURSOR;
 
 982         ffb_switch_from_graph(par);
 
 984         /* Unblank it just to be sure.  When there are multiple
 
 985          * FFB/AFB cards in the system, or it is not the OBP
 
 986          * chosen console, it will have video outputs off in
 
 989         ffb_blank(FB_BLANK_UNBLANK, info);
 
 991         if (fb_alloc_cmap(&info->cmap, 256, 0))
 
 996         err = register_framebuffer(info);
 
 998                 goto out_dealloc_cmap;
 
1000         dev_set_drvdata(&op->dev, info);
 
1002         printk(KERN_INFO "%s: %s at %016lx, type %d, "
 
1003                "DAC pnum[%x] rev[%d] manuf_rev[%d]\n",
 
1005                ((par->flags & FFB_FLAG_AFB) ? "AFB" : "FFB"),
 
1006                par->physbase, par->board_type,
 
1007                dac_pnum, dac_rev, dac_mrev);
 
1012         fb_dealloc_cmap(&info->cmap);
 
1015         of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
 
1018         of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
 
1021         framebuffer_release(info);
 
1027 static int __devexit ffb_remove(struct of_device *op)
 
1029         struct fb_info *info = dev_get_drvdata(&op->dev);
 
1030         struct ffb_par *par = info->par;
 
1032         unregister_framebuffer(info);
 
1033         fb_dealloc_cmap(&info->cmap);
 
1035         of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
 
1036         of_iounmap(&op->resource[1], par->dac, sizeof(struct ffb_dac));
 
1038         framebuffer_release(info);
 
1040         dev_set_drvdata(&op->dev, NULL);
 
1045 static const struct of_device_id ffb_match[] = {
 
1054 MODULE_DEVICE_TABLE(of, ffb_match);
 
1056 static struct of_platform_driver ffb_driver = {
 
1058         .match_table    = ffb_match,
 
1060         .remove         = __devexit_p(ffb_remove),
 
1063 static int __init ffb_init(void)
 
1065         if (fb_get_options("ffb", NULL))
 
1068         return of_register_driver(&ffb_driver, &of_bus_type);
 
1071 static void __exit ffb_exit(void)
 
1073         of_unregister_driver(&ffb_driver);
 
1076 module_init(ffb_init);
 
1077 module_exit(ffb_exit);
 
1079 MODULE_DESCRIPTION("framebuffer driver for Creator/Elite3D chipsets");
 
1080 MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
 
1081 MODULE_VERSION("2.0");
 
1082 MODULE_LICENSE("GPL");