1 /* leo.c: LEO frame buffer driver
 
   3  * Copyright (C) 2003 David S. Miller (davem@redhat.com)
 
   4  * Copyright (C) 1996-1999 Jakub Jelinek (jj@ultra.linux.cz)
 
   5  * Copyright (C) 1997 Michal Rehacek (Michal.Rehacek@st.mff.cuni.cz)
 
   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/oplib.h>
 
  31 static int leo_setcolreg(unsigned, unsigned, unsigned, unsigned,
 
  32                          unsigned, struct fb_info *);
 
  33 static int leo_blank(int, struct fb_info *);
 
  35 static int leo_mmap(struct fb_info *, struct vm_area_struct *);
 
  36 static int leo_ioctl(struct fb_info *, unsigned int, unsigned long);
 
  37 static int leo_pan_display(struct fb_var_screeninfo *, struct fb_info *);
 
  40  *  Frame buffer operations
 
  43 static struct fb_ops leo_ops = {
 
  45         .fb_setcolreg           = leo_setcolreg,
 
  46         .fb_blank               = leo_blank,
 
  47         .fb_pan_display         = leo_pan_display,
 
  48         .fb_fillrect            = cfb_fillrect,
 
  49         .fb_copyarea            = cfb_copyarea,
 
  50         .fb_imageblit           = cfb_imageblit,
 
  52         .fb_ioctl               = leo_ioctl,
 
  54         .fb_compat_ioctl        = sbusfb_compat_ioctl,
 
  58 #define LEO_OFF_LC_SS0_KRN      0x00200000UL
 
  59 #define LEO_OFF_LC_SS0_USR      0x00201000UL
 
  60 #define LEO_OFF_LC_SS1_KRN      0x01200000UL
 
  61 #define LEO_OFF_LC_SS1_USR      0x01201000UL
 
  62 #define LEO_OFF_LD_SS0          0x00400000UL
 
  63 #define LEO_OFF_LD_SS1          0x01400000UL
 
  64 #define LEO_OFF_LD_GBL          0x00401000UL
 
  65 #define LEO_OFF_LX_KRN          0x00600000UL
 
  66 #define LEO_OFF_LX_CURSOR       0x00601000UL
 
  67 #define LEO_OFF_SS0             0x00800000UL
 
  68 #define LEO_OFF_SS1             0x01800000UL
 
  69 #define LEO_OFF_UNK             0x00602000UL
 
  70 #define LEO_OFF_UNK2            0x00000000UL
 
  72 #define LEO_CUR_ENABLE          0x00000080
 
  73 #define LEO_CUR_UPDATE          0x00000030
 
  74 #define LEO_CUR_PROGRESS        0x00000006
 
  75 #define LEO_CUR_UPDATECMAP      0x00000003
 
  77 #define LEO_CUR_TYPE_MASK       0x00000000
 
  78 #define LEO_CUR_TYPE_IMAGE      0x00000020
 
  79 #define LEO_CUR_TYPE_CMAP       0x00000050
 
  83         volatile u32    cur_type;
 
  84         volatile u32    cur_misc;
 
  85         volatile u32    cur_cursxy;
 
  86         volatile u32    cur_data;
 
  89 #define LEO_KRN_TYPE_CLUT0      0x00001000
 
  90 #define LEO_KRN_TYPE_CLUT1      0x00001001
 
  91 #define LEO_KRN_TYPE_CLUT2      0x00001002
 
  92 #define LEO_KRN_TYPE_WID        0x00001003
 
  93 #define LEO_KRN_TYPE_UNK        0x00001006
 
  94 #define LEO_KRN_TYPE_VIDEO      0x00002003
 
  95 #define LEO_KRN_TYPE_CLUTDATA   0x00004000
 
  96 #define LEO_KRN_CSR_ENABLE      0x00000008
 
  97 #define LEO_KRN_CSR_PROGRESS    0x00000004
 
  98 #define LEO_KRN_CSR_UNK         0x00000002
 
  99 #define LEO_KRN_CSR_UNK2        0x00000001
 
 102         volatile u32    krn_type;
 
 103         volatile u32    krn_csr;
 
 104         volatile u32    krn_value;
 
 107 struct leo_lc_ss0_krn {
 
 113 struct leo_lc_ss0_usr {
 
 115         volatile u32    addrspace;
 
 116         volatile u32    fontmsk;
 
 125 struct leo_lc_ss1_krn {
 
 129 struct leo_lc_ss1_usr {
 
 138         volatile u32    widclip;
 
 139         volatile u32    vclipmin;
 
 140         volatile u32    vclipmax;
 
 141         volatile u32    pickmin;        /* SS1 only */
 
 142         volatile u32    pickmax;        /* SS1 only */
 
 145         volatile u32    src;            /* Copy/Scroll (SS0 only) */
 
 146         volatile u32    dst;            /* Copy/Scroll/Fill (SS0 only) */
 
 147         volatile u32    extent;         /* Copy/Scroll/Fill size (SS0 only) */
 
 149         volatile u32    setsem;         /* SS1 only */
 
 150         volatile u32    clrsem;         /* SS1 only */
 
 151         volatile u32    clrpick;        /* SS1 only */
 
 152         volatile u32    clrdat;         /* SS1 only */
 
 153         volatile u32    alpha;          /* SS1 only */
 
 156         volatile u32    planemask;
 
 159         volatile u32    dczf;           /* SS1 only */
 
 160         volatile u32    dczb;           /* SS1 only */
 
 161         volatile u32    dcs;            /* SS1 only */
 
 162         volatile u32    dczs;           /* SS1 only */
 
 163         volatile u32    pickfb;         /* SS1 only */
 
 164         volatile u32    pickbb;         /* SS1 only */
 
 165         volatile u32    dcfc;           /* SS1 only */
 
 166         volatile u32    forcecol;       /* SS1 only */
 
 167         volatile u32    door[8];        /* SS1 only */
 
 168         volatile u32    pick[5];        /* SS1 only */
 
 171 #define LEO_SS1_MISC_ENABLE     0x00000001
 
 172 #define LEO_SS1_MISC_STEREO     0x00000002
 
 175         volatile u32    ss1_misc;
 
 184         struct leo_lx_krn       __iomem *lx_krn;
 
 185         struct leo_lc_ss0_usr   __iomem *lc_ss0_usr;
 
 186         struct leo_ld_ss0       __iomem *ld_ss0;
 
 187         struct leo_ld_ss1       __iomem *ld_ss1;
 
 188         struct leo_cursor       __iomem *cursor;
 
 193 #define LEO_FLAG_BLANKED        0x00000001
 
 195         unsigned long           physbase;
 
 196         unsigned long           fbsize;
 
 198         struct sbus_dev         *sdev;
 
 201 static void leo_wait(struct leo_lx_krn __iomem *lx_krn)
 
 206              (sbus_readl(&lx_krn->krn_csr) & LEO_KRN_CSR_PROGRESS) && i < 300000;
 
 208                 udelay (1); /* Busy wait at most 0.3 sec */
 
 213  *      leo_setcolreg - Optional function. Sets a color register.
 
 214  *      @regno: boolean, 0 copy local, 1 get_user() function
 
 215  *      @red: frame buffer colormap structure
 
 216  *      @green: The green value which can be up to 16 bits wide
 
 217  *      @blue:  The blue value which can be up to 16 bits wide.
 
 218  *      @transp: If supported the alpha value which can be up to 16 bits wide.
 
 219  *      @info: frame buffer info structure
 
 221 static int leo_setcolreg(unsigned regno,
 
 222                          unsigned red, unsigned green, unsigned blue,
 
 223                          unsigned transp, struct fb_info *info)
 
 225         struct leo_par *par = (struct leo_par *) info->par;
 
 226         struct leo_lx_krn __iomem *lx_krn = par->lx_krn;
 
 238         par->clut_data[regno] = red | (green << 8) | (blue << 16);
 
 240         spin_lock_irqsave(&par->lock, flags);
 
 244         sbus_writel(LEO_KRN_TYPE_CLUTDATA, &lx_krn->krn_type);
 
 245         for (i = 0; i < 256; i++)
 
 246                 sbus_writel(par->clut_data[i], &lx_krn->krn_value);
 
 247         sbus_writel(LEO_KRN_TYPE_CLUT0, &lx_krn->krn_type);
 
 249         val = sbus_readl(&lx_krn->krn_csr);
 
 250         val |= (LEO_KRN_CSR_UNK | LEO_KRN_CSR_UNK2);
 
 251         sbus_writel(val, &lx_krn->krn_csr);
 
 253         spin_unlock_irqrestore(&par->lock, flags);
 
 259  *      leo_blank - Optional function.  Blanks the display.
 
 260  *      @blank_mode: the blank mode we want.
 
 261  *      @info: frame buffer structure that represents a single frame buffer
 
 263 static int leo_blank(int blank, struct fb_info *info)
 
 265         struct leo_par *par = (struct leo_par *) info->par;
 
 266         struct leo_lx_krn __iomem *lx_krn = par->lx_krn;
 
 270         spin_lock_irqsave(&par->lock, flags);
 
 273         case FB_BLANK_UNBLANK: /* Unblanking */
 
 274                 val = sbus_readl(&lx_krn->krn_csr);
 
 275                 val |= LEO_KRN_CSR_ENABLE;
 
 276                 sbus_writel(val, &lx_krn->krn_csr);
 
 277                 par->flags &= ~LEO_FLAG_BLANKED;
 
 280         case FB_BLANK_NORMAL: /* Normal blanking */
 
 281         case FB_BLANK_VSYNC_SUSPEND: /* VESA blank (vsync off) */
 
 282         case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */
 
 283         case FB_BLANK_POWERDOWN: /* Poweroff */
 
 284                 val = sbus_readl(&lx_krn->krn_csr);
 
 285                 val &= ~LEO_KRN_CSR_ENABLE;
 
 286                 sbus_writel(val, &lx_krn->krn_csr);
 
 287                 par->flags |= LEO_FLAG_BLANKED;
 
 291         spin_unlock_irqrestore(&par->lock, flags);
 
 296 static struct sbus_mmap_map leo_mmap_map[] = {
 
 303                 .voff   = LEO_LC_SS0_USR_MAP,
 
 304                 .poff   = LEO_OFF_LC_SS0_USR,
 
 308                 .voff   = LEO_LD_SS0_MAP,
 
 309                 .poff   = LEO_OFF_LD_SS0,
 
 313                 .voff   = LEO_LX_CURSOR_MAP,
 
 314                 .poff   = LEO_OFF_LX_CURSOR,
 
 323                 .voff   = LEO_LC_SS1_USR_MAP,
 
 324                 .poff   = LEO_OFF_LC_SS1_USR,
 
 328                 .voff   = LEO_LD_SS1_MAP,
 
 329                 .poff   = LEO_OFF_LD_SS1,
 
 338                 .voff   = LEO_LX_KRN_MAP,
 
 339                 .poff   = LEO_OFF_LX_KRN,
 
 343                 .voff   = LEO_LC_SS0_KRN_MAP,
 
 344                 .poff   = LEO_OFF_LC_SS0_KRN,
 
 348                 .voff   = LEO_LC_SS1_KRN_MAP,
 
 349                 .poff   = LEO_OFF_LC_SS1_KRN,
 
 353                 .voff   = LEO_LD_GBL_MAP,
 
 354                 .poff   = LEO_OFF_LD_GBL,
 
 358                 .voff   = LEO_UNK2_MAP,
 
 359                 .poff   = LEO_OFF_UNK2,
 
 365 static int leo_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
 367         struct leo_par *par = (struct leo_par *)info->par;
 
 369         return sbusfb_mmap_helper(leo_mmap_map,
 
 370                                   par->physbase, par->fbsize,
 
 371                                   par->sdev->reg_addrs[0].which_io,
 
 375 static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
 
 377         struct leo_par *par = (struct leo_par *) info->par;
 
 379         return sbusfb_ioctl_helper(cmd, arg, info,
 
 380                                    FBTYPE_SUNLEO, 32, par->fbsize);
 
 388 leo_init_fix(struct fb_info *info)
 
 390         struct leo_par *par = (struct leo_par *)info->par;
 
 392         strlcpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id));
 
 394         info->fix.type = FB_TYPE_PACKED_PIXELS;
 
 395         info->fix.visual = FB_VISUAL_TRUECOLOR;
 
 397         info->fix.line_length = 8192;
 
 399         info->fix.accel = FB_ACCEL_SUN_LEO;
 
 402 static void leo_wid_put(struct fb_info *info, struct fb_wid_list *wl)
 
 404         struct leo_par *par = (struct leo_par *) info->par;
 
 405         struct leo_lx_krn __iomem *lx_krn = par->lx_krn;
 
 406         struct fb_wid_item *wi;
 
 411         spin_lock_irqsave(&par->lock, flags);
 
 415         for (i = 0, wi = wl->wl_list; i < wl->wl_count; i++, wi++) {
 
 416                 switch(wi->wi_type) {
 
 418                         j = (wi->wi_index & 0xf) + 0x40;
 
 422                         j = wi->wi_index & 0x3f;
 
 428                 sbus_writel(0x5800 + j, &lx_krn->krn_type);
 
 429                 sbus_writel(wi->wi_values[0], &lx_krn->krn_value);
 
 431         sbus_writel(LEO_KRN_TYPE_WID, &lx_krn->krn_type);
 
 433         val = sbus_readl(&lx_krn->krn_csr);
 
 434         val |= (LEO_KRN_CSR_UNK | LEO_KRN_CSR_UNK2);
 
 435         sbus_writel(val, &lx_krn->krn_csr);
 
 437         spin_unlock_irqrestore(&par->lock, flags);
 
 440 static void leo_init_wids(struct fb_info *info)
 
 442         struct fb_wid_item wi;
 
 443         struct fb_wid_list wl;
 
 447         wi.wi_type = FB_WID_DBL_8;
 
 449         wi.wi_values [0] = 0x2c0;
 
 450         leo_wid_put(info, &wl);
 
 452         wi.wi_values [0] = 0x30;
 
 453         leo_wid_put(info, &wl);
 
 455         wi.wi_values [0] = 0x20;
 
 456         leo_wid_put(info, &wl);
 
 457         wi.wi_type = FB_WID_DBL_24;
 
 459         wi.wi_values [0] = 0x30;
 
 460         leo_wid_put(info, &wl);
 
 464 static void leo_switch_from_graph(struct fb_info *info)
 
 466         struct leo_par *par = (struct leo_par *) info->par;
 
 467         struct leo_ld __iomem *ss = (struct leo_ld __iomem *) par->ld_ss0;
 
 471         spin_lock_irqsave(&par->lock, flags);
 
 473         par->extent = ((info->var.xres - 1) |
 
 474                        ((info->var.yres - 1) << 16));
 
 476         sbus_writel(0xffffffff, &ss->wid);
 
 477         sbus_writel(0xffff, &ss->wmask);
 
 478         sbus_writel(0, &ss->vclipmin);
 
 479         sbus_writel(par->extent, &ss->vclipmax);
 
 480         sbus_writel(0, &ss->fg);
 
 481         sbus_writel(0xff000000, &ss->planemask);
 
 482         sbus_writel(0x310850, &ss->rop);
 
 483         sbus_writel(0, &ss->widclip);
 
 484         sbus_writel((info->var.xres-1) | ((info->var.yres-1) << 11),
 
 485                     &par->lc_ss0_usr->extent);
 
 486         sbus_writel(4, &par->lc_ss0_usr->addrspace);
 
 487         sbus_writel(0x80000000, &par->lc_ss0_usr->fill);
 
 488         sbus_writel(0, &par->lc_ss0_usr->fontt);
 
 490                 val = sbus_readl(&par->lc_ss0_usr->csr);
 
 491         } while (val & 0x20000000);
 
 493         spin_unlock_irqrestore(&par->lock, flags);
 
 496 static int leo_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
 
 498         /* We just use this to catch switches out of
 
 501         leo_switch_from_graph(info);
 
 503         if (var->xoffset || var->yoffset || var->vmode)
 
 508 static void leo_init_hw(struct fb_info *info)
 
 510         struct leo_par *par = (struct leo_par *) info->par;
 
 513         val = sbus_readl(&par->ld_ss1->ss1_misc);
 
 514         val |= LEO_SS1_MISC_ENABLE;
 
 515         sbus_writel(val, &par->ld_ss1->ss1_misc);
 
 517         leo_switch_from_graph(info);
 
 520 static void leo_fixup_var_rgb(struct fb_var_screeninfo *var)
 
 524         var->green.offset = 8;
 
 525         var->green.length = 8;
 
 526         var->blue.offset = 16;
 
 527         var->blue.length = 8;
 
 528         var->transp.offset = 0;
 
 529         var->transp.length = 0;
 
 535         struct list_head list;
 
 537 static LIST_HEAD(leo_list);
 
 539 static void leo_init_one(struct sbus_dev *sdev)
 
 541         struct all_info *all;
 
 544         all = kmalloc(sizeof(*all), GFP_KERNEL);
 
 546                 printk(KERN_ERR "leo: Cannot allocate memory.\n");
 
 549         memset(all, 0, sizeof(*all));
 
 551         INIT_LIST_HEAD(&all->list);
 
 553         spin_lock_init(&all->par.lock);
 
 554         all->par.sdev = sdev;
 
 556         all->par.physbase = sdev->reg_addrs[0].phys_addr;
 
 558         sbusfb_fill_var(&all->info.var, sdev->prom_node, 32);
 
 559         leo_fixup_var_rgb(&all->info.var);
 
 561         linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
 
 563         all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
 
 565 #ifdef CONFIG_SPARC32
 
 566         all->info.screen_base = (char __iomem *)
 
 567                 prom_getintdefault(sdev->prom_node, "address", 0);
 
 569         if (!all->info.screen_base)
 
 570                 all->info.screen_base = 
 
 571                         sbus_ioremap(&sdev->resource[0], LEO_OFF_SS0,
 
 572                                      0x800000, "leo ram");
 
 574         all->par.lc_ss0_usr =
 
 575                 sbus_ioremap(&sdev->resource[0], LEO_OFF_LC_SS0_USR,
 
 576                              0x1000, "leolc ss0usr");
 
 578                 sbus_ioremap(&sdev->resource[0], LEO_OFF_LD_SS0,
 
 579                              0x1000, "leold ss0");
 
 581                 sbus_ioremap(&sdev->resource[0], LEO_OFF_LD_SS1,
 
 582                              0x1000, "leold ss1");
 
 584                 sbus_ioremap(&sdev->resource[0], LEO_OFF_LX_KRN,
 
 585                              0x1000, "leolx krn");
 
 587                 sbus_ioremap(&sdev->resource[0], LEO_OFF_LX_CURSOR,
 
 588                              sizeof(struct leo_cursor), "leolx cursor");
 
 590         all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
 
 591         all->info.fbops = &leo_ops;
 
 592         all->info.par = &all->par;
 
 594         leo_init_wids(&all->info);
 
 595         leo_init_hw(&all->info);
 
 597         leo_blank(0, &all->info);
 
 599         if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
 
 600                 printk(KERN_ERR "leo: Could not allocate color map.\n");
 
 605         leo_init_fix(&all->info);
 
 607         if (register_framebuffer(&all->info) < 0) {
 
 608                 printk(KERN_ERR "leo: Could not register framebuffer.\n");
 
 609                 fb_dealloc_cmap(&all->info.cmap);
 
 614         list_add(&all->list, &leo_list);
 
 616         printk("leo: %s at %lx:%lx\n",
 
 618                (long) sdev->reg_addrs[0].which_io,
 
 619                (long) sdev->reg_addrs[0].phys_addr);
 
 622 int __init leo_init(void)
 
 624         struct sbus_bus *sbus;
 
 625         struct sbus_dev *sdev;
 
 627         if (fb_get_options("leofb", NULL))
 
 630         for_all_sbusdev(sdev, sbus) {
 
 631                 if (!strcmp(sdev->prom_name, "leo"))
 
 638 void __exit leo_exit(void)
 
 640         struct list_head *pos, *tmp;
 
 642         list_for_each_safe(pos, tmp, &leo_list) {
 
 643                 struct all_info *all = list_entry(pos, typeof(*all), list);
 
 645                 unregister_framebuffer(&all->info);
 
 646                 fb_dealloc_cmap(&all->info.cmap);
 
 654         /* No cmdline options yet... */
 
 658 module_init(leo_init);
 
 660 module_exit(leo_exit);
 
 663 MODULE_DESCRIPTION("framebuffer driver for LEO chipsets");
 
 664 MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
 
 665 MODULE_LICENSE("GPL");