root/drivers/video/fbdev/gbefb.c

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

DEFINITIONS

This source file includes following definitions.
  1. gbe_reset
  2. gbe_turn_off
  3. gbe_turn_on
  4. gbe_loadcmap
  5. gbefb_blank
  6. gbefb_setup_flatpanel
  7. compute_gbe_timing
  8. gbe_set_timing_info
  9. gbefb_set_par
  10. gbefb_encode_fix
  11. gbefb_setcolreg
  12. gbefb_check_var
  13. gbefb_mmap
  14. gbefb_show_memsize
  15. gbefb_show_rev
  16. gbefb_remove_sysfs
  17. gbefb_create_sysfs
  18. gbefb_setup
  19. gbefb_probe
  20. gbefb_remove
  21. gbefb_init
  22. gbefb_exit

   1 /*
   2  *  SGI GBE frame buffer driver
   3  *
   4  *  Copyright (C) 1999 Silicon Graphics, Inc. - Jeffrey Newquist
   5  *  Copyright (C) 2002 Vivien Chappelier <vivien.chappelier@linux-mips.org>
   6  *
   7  *  This file is subject to the terms and conditions of the GNU General Public
   8  *  License. See the file COPYING in the main directory of this archive for
   9  *  more details.
  10  */
  11 
  12 #include <linux/delay.h>
  13 #include <linux/platform_device.h>
  14 #include <linux/dma-mapping.h>
  15 #include <linux/errno.h>
  16 #include <linux/gfp.h>
  17 #include <linux/fb.h>
  18 #include <linux/init.h>
  19 #include <linux/interrupt.h>
  20 #include <linux/kernel.h>
  21 #include <linux/mm.h>
  22 #include <linux/module.h>
  23 #include <linux/io.h>
  24 
  25 #ifdef CONFIG_MIPS
  26 #include <asm/addrspace.h>
  27 #endif
  28 #include <asm/byteorder.h>
  29 #include <asm/tlbflush.h>
  30 
  31 #include <video/gbe.h>
  32 
  33 static struct sgi_gbe *gbe;
  34 
  35 struct gbefb_par {
  36         struct fb_var_screeninfo var;
  37         struct gbe_timing_info timing;
  38         int wc_cookie;
  39         int valid;
  40 };
  41 
  42 #define GBE_BASE        0x16000000 /* SGI O2 */
  43 
  44 /* macro for fastest write-though access to the framebuffer */
  45 #ifdef CONFIG_MIPS
  46 #ifdef CONFIG_CPU_R10000
  47 #define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_UNCACHED_ACCELERATED)
  48 #else
  49 #define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_CACHABLE_NO_WA)
  50 #endif
  51 #endif
  52 
  53 /*
  54  *  RAM we reserve for the frame buffer. This defines the maximum screen
  55  *  size
  56  */
  57 #if CONFIG_FB_GBE_MEM > 8
  58 #error GBE Framebuffer cannot use more than 8MB of memory
  59 #endif
  60 
  61 #define TILE_SHIFT 16
  62 #define TILE_SIZE (1 << TILE_SHIFT)
  63 #define TILE_MASK (TILE_SIZE - 1)
  64 
  65 static unsigned int gbe_mem_size = CONFIG_FB_GBE_MEM * 1024*1024;
  66 static void *gbe_mem;
  67 static dma_addr_t gbe_dma_addr;
  68 static unsigned long gbe_mem_phys;
  69 
  70 static struct {
  71         uint16_t *cpu;
  72         dma_addr_t dma;
  73 } gbe_tiles;
  74 
  75 static int gbe_revision;
  76 
  77 static int ypan, ywrap;
  78 
  79 static uint32_t pseudo_palette[16];
  80 static uint32_t gbe_cmap[256];
  81 static int gbe_turned_on; /* 0 turned off, 1 turned on */
  82 
  83 static char *mode_option = NULL;
  84 
  85 /* default CRT mode */
  86 static struct fb_var_screeninfo default_var_CRT = {
  87         /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
  88         .xres           = 640,
  89         .yres           = 480,
  90         .xres_virtual   = 640,
  91         .yres_virtual   = 480,
  92         .xoffset        = 0,
  93         .yoffset        = 0,
  94         .bits_per_pixel = 8,
  95         .grayscale      = 0,
  96         .red            = { 0, 8, 0 },
  97         .green          = { 0, 8, 0 },
  98         .blue           = { 0, 8, 0 },
  99         .transp         = { 0, 0, 0 },
 100         .nonstd         = 0,
 101         .activate       = 0,
 102         .height         = -1,
 103         .width          = -1,
 104         .accel_flags    = 0,
 105         .pixclock       = 39722,        /* picoseconds */
 106         .left_margin    = 48,
 107         .right_margin   = 16,
 108         .upper_margin   = 33,
 109         .lower_margin   = 10,
 110         .hsync_len      = 96,
 111         .vsync_len      = 2,
 112         .sync           = 0,
 113         .vmode          = FB_VMODE_NONINTERLACED,
 114 };
 115 
 116 /* default LCD mode */
 117 static struct fb_var_screeninfo default_var_LCD = {
 118         /* 1600x1024, 8 bpp */
 119         .xres           = 1600,
 120         .yres           = 1024,
 121         .xres_virtual   = 1600,
 122         .yres_virtual   = 1024,
 123         .xoffset        = 0,
 124         .yoffset        = 0,
 125         .bits_per_pixel = 8,
 126         .grayscale      = 0,
 127         .red            = { 0, 8, 0 },
 128         .green          = { 0, 8, 0 },
 129         .blue           = { 0, 8, 0 },
 130         .transp         = { 0, 0, 0 },
 131         .nonstd         = 0,
 132         .activate       = 0,
 133         .height         = -1,
 134         .width          = -1,
 135         .accel_flags    = 0,
 136         .pixclock       = 9353,
 137         .left_margin    = 20,
 138         .right_margin   = 30,
 139         .upper_margin   = 37,
 140         .lower_margin   = 3,
 141         .hsync_len      = 20,
 142         .vsync_len      = 3,
 143         .sync           = 0,
 144         .vmode          = FB_VMODE_NONINTERLACED
 145 };
 146 
 147 /* default modedb mode */
 148 /* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */
 149 static struct fb_videomode default_mode_CRT = {
 150         .refresh        = 60,
 151         .xres           = 640,
 152         .yres           = 480,
 153         .pixclock       = 39722,
 154         .left_margin    = 48,
 155         .right_margin   = 16,
 156         .upper_margin   = 33,
 157         .lower_margin   = 10,
 158         .hsync_len      = 96,
 159         .vsync_len      = 2,
 160         .sync           = 0,
 161         .vmode          = FB_VMODE_NONINTERLACED,
 162 };
 163 /* 1600x1024 SGI flatpanel 1600sw */
 164 static struct fb_videomode default_mode_LCD = {
 165         /* 1600x1024, 8 bpp */
 166         .xres           = 1600,
 167         .yres           = 1024,
 168         .pixclock       = 9353,
 169         .left_margin    = 20,
 170         .right_margin   = 30,
 171         .upper_margin   = 37,
 172         .lower_margin   = 3,
 173         .hsync_len      = 20,
 174         .vsync_len      = 3,
 175         .vmode          = FB_VMODE_NONINTERLACED,
 176 };
 177 
 178 static struct fb_videomode *default_mode = &default_mode_CRT;
 179 static struct fb_var_screeninfo *default_var = &default_var_CRT;
 180 
 181 static int flat_panel_enabled = 0;
 182 
 183 static void gbe_reset(void)
 184 {
 185         /* Turn on dotclock PLL */
 186         gbe->ctrlstat = 0x300aa000;
 187 }
 188 
 189 
 190 /*
 191  * Function:    gbe_turn_off
 192  * Parameters:  (None)
 193  * Description: This should turn off the monitor and gbe.  This is used
 194  *              when switching between the serial console and the graphics
 195  *              console.
 196  */
 197 
 198 static void gbe_turn_off(void)
 199 {
 200         int i;
 201         unsigned int val, x, y, vpixen_off;
 202 
 203         gbe_turned_on = 0;
 204 
 205         /* check if pixel counter is on */
 206         val = gbe->vt_xy;
 207         if (GET_GBE_FIELD(VT_XY, FREEZE, val) == 1)
 208                 return;
 209 
 210         /* turn off DMA */
 211         val = gbe->ovr_control;
 212         SET_GBE_FIELD(OVR_CONTROL, OVR_DMA_ENABLE, val, 0);
 213         gbe->ovr_control = val;
 214         udelay(1000);
 215         val = gbe->frm_control;
 216         SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 0);
 217         gbe->frm_control = val;
 218         udelay(1000);
 219         val = gbe->did_control;
 220         SET_GBE_FIELD(DID_CONTROL, DID_DMA_ENABLE, val, 0);
 221         gbe->did_control = val;
 222         udelay(1000);
 223 
 224         /* We have to wait through two vertical retrace periods before
 225          * the pixel DMA is turned off for sure. */
 226         for (i = 0; i < 10000; i++) {
 227                 val = gbe->frm_inhwctrl;
 228                 if (GET_GBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, val)) {
 229                         udelay(10);
 230                 } else {
 231                         val = gbe->ovr_inhwctrl;
 232                         if (GET_GBE_FIELD(OVR_INHWCTRL, OVR_DMA_ENABLE, val)) {
 233                                 udelay(10);
 234                         } else {
 235                                 val = gbe->did_inhwctrl;
 236                                 if (GET_GBE_FIELD(DID_INHWCTRL, DID_DMA_ENABLE, val)) {
 237                                         udelay(10);
 238                                 } else
 239                                         break;
 240                         }
 241                 }
 242         }
 243         if (i == 10000)
 244                 printk(KERN_ERR "gbefb: turn off DMA timed out\n");
 245 
 246         /* wait for vpixen_off */
 247         val = gbe->vt_vpixen;
 248         vpixen_off = GET_GBE_FIELD(VT_VPIXEN, VPIXEN_OFF, val);
 249 
 250         for (i = 0; i < 100000; i++) {
 251                 val = gbe->vt_xy;
 252                 x = GET_GBE_FIELD(VT_XY, X, val);
 253                 y = GET_GBE_FIELD(VT_XY, Y, val);
 254                 if (y < vpixen_off)
 255                         break;
 256                 udelay(1);
 257         }
 258         if (i == 100000)
 259                 printk(KERN_ERR
 260                        "gbefb: wait for vpixen_off timed out\n");
 261         for (i = 0; i < 10000; i++) {
 262                 val = gbe->vt_xy;
 263                 x = GET_GBE_FIELD(VT_XY, X, val);
 264                 y = GET_GBE_FIELD(VT_XY, Y, val);
 265                 if (y > vpixen_off)
 266                         break;
 267                 udelay(1);
 268         }
 269         if (i == 10000)
 270                 printk(KERN_ERR "gbefb: wait for vpixen_off timed out\n");
 271 
 272         /* turn off pixel counter */
 273         val = 0;
 274         SET_GBE_FIELD(VT_XY, FREEZE, val, 1);
 275         gbe->vt_xy = val;
 276         mdelay(10);
 277         for (i = 0; i < 10000; i++) {
 278                 val = gbe->vt_xy;
 279                 if (GET_GBE_FIELD(VT_XY, FREEZE, val) != 1)
 280                         udelay(10);
 281                 else
 282                         break;
 283         }
 284         if (i == 10000)
 285                 printk(KERN_ERR "gbefb: turn off pixel clock timed out\n");
 286 
 287         /* turn off dot clock */
 288         val = gbe->dotclock;
 289         SET_GBE_FIELD(DOTCLK, RUN, val, 0);
 290         gbe->dotclock = val;
 291         mdelay(10);
 292         for (i = 0; i < 10000; i++) {
 293                 val = gbe->dotclock;
 294                 if (GET_GBE_FIELD(DOTCLK, RUN, val))
 295                         udelay(10);
 296                 else
 297                         break;
 298         }
 299         if (i == 10000)
 300                 printk(KERN_ERR "gbefb: turn off dotclock timed out\n");
 301 
 302         /* reset the frame DMA FIFO */
 303         val = gbe->frm_size_tile;
 304         SET_GBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, val, 1);
 305         gbe->frm_size_tile = val;
 306         SET_GBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, val, 0);
 307         gbe->frm_size_tile = val;
 308 }
 309 
 310 static void gbe_turn_on(void)
 311 {
 312         unsigned int val, i;
 313 
 314         /*
 315          * Check if pixel counter is off, for unknown reason this
 316          * code hangs Visual Workstations
 317          */
 318         if (gbe_revision < 2) {
 319                 val = gbe->vt_xy;
 320                 if (GET_GBE_FIELD(VT_XY, FREEZE, val) == 0)
 321                         return;
 322         }
 323 
 324         /* turn on dot clock */
 325         val = gbe->dotclock;
 326         SET_GBE_FIELD(DOTCLK, RUN, val, 1);
 327         gbe->dotclock = val;
 328         mdelay(10);
 329         for (i = 0; i < 10000; i++) {
 330                 val = gbe->dotclock;
 331                 if (GET_GBE_FIELD(DOTCLK, RUN, val) != 1)
 332                         udelay(10);
 333                 else
 334                         break;
 335         }
 336         if (i == 10000)
 337                 printk(KERN_ERR "gbefb: turn on dotclock timed out\n");
 338 
 339         /* turn on pixel counter */
 340         val = 0;
 341         SET_GBE_FIELD(VT_XY, FREEZE, val, 0);
 342         gbe->vt_xy = val;
 343         mdelay(10);
 344         for (i = 0; i < 10000; i++) {
 345                 val = gbe->vt_xy;
 346                 if (GET_GBE_FIELD(VT_XY, FREEZE, val))
 347                         udelay(10);
 348                 else
 349                         break;
 350         }
 351         if (i == 10000)
 352                 printk(KERN_ERR "gbefb: turn on pixel clock timed out\n");
 353 
 354         /* turn on DMA */
 355         val = gbe->frm_control;
 356         SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 1);
 357         gbe->frm_control = val;
 358         udelay(1000);
 359         for (i = 0; i < 10000; i++) {
 360                 val = gbe->frm_inhwctrl;
 361                 if (GET_GBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, val) != 1)
 362                         udelay(10);
 363                 else
 364                         break;
 365         }
 366         if (i == 10000)
 367                 printk(KERN_ERR "gbefb: turn on DMA timed out\n");
 368 
 369         gbe_turned_on = 1;
 370 }
 371 
 372 static void gbe_loadcmap(void)
 373 {
 374         int i, j;
 375 
 376         for (i = 0; i < 256; i++) {
 377                 for (j = 0; j < 1000 && gbe->cm_fifo >= 63; j++)
 378                         udelay(10);
 379                 if (j == 1000)
 380                         printk(KERN_ERR "gbefb: cmap FIFO timeout\n");
 381 
 382                 gbe->cmap[i] = gbe_cmap[i];
 383         }
 384 }
 385 
 386 /*
 387  *  Blank the display.
 388  */
 389 static int gbefb_blank(int blank, struct fb_info *info)
 390 {
 391         /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
 392         switch (blank) {
 393         case FB_BLANK_UNBLANK:          /* unblank */
 394                 gbe_turn_on();
 395                 gbe_loadcmap();
 396                 break;
 397 
 398         case FB_BLANK_NORMAL:           /* blank */
 399                 gbe_turn_off();
 400                 break;
 401 
 402         default:
 403                 /* Nothing */
 404                 break;
 405         }
 406         return 0;
 407 }
 408 
 409 /*
 410  *  Setup flatpanel related registers.
 411  */
 412 static void gbefb_setup_flatpanel(struct gbe_timing_info *timing)
 413 {
 414         int fp_wid, fp_hgt, fp_vbs, fp_vbe;
 415         u32 outputVal = 0;
 416 
 417         SET_GBE_FIELD(VT_FLAGS, HDRV_INVERT, outputVal,
 418                 (timing->flags & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1);
 419         SET_GBE_FIELD(VT_FLAGS, VDRV_INVERT, outputVal,
 420                 (timing->flags & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1);
 421         gbe->vt_flags = outputVal;
 422 
 423         /* Turn on the flat panel */
 424         fp_wid = 1600;
 425         fp_hgt = 1024;
 426         fp_vbs = 0;
 427         fp_vbe = 1600;
 428         timing->pll_m = 4;
 429         timing->pll_n = 1;
 430         timing->pll_p = 0;
 431 
 432         outputVal = 0;
 433         SET_GBE_FIELD(FP_DE, ON, outputVal, fp_vbs);
 434         SET_GBE_FIELD(FP_DE, OFF, outputVal, fp_vbe);
 435         gbe->fp_de = outputVal;
 436         outputVal = 0;
 437         SET_GBE_FIELD(FP_HDRV, OFF, outputVal, fp_wid);
 438         gbe->fp_hdrv = outputVal;
 439         outputVal = 0;
 440         SET_GBE_FIELD(FP_VDRV, ON, outputVal, 1);
 441         SET_GBE_FIELD(FP_VDRV, OFF, outputVal, fp_hgt + 1);
 442         gbe->fp_vdrv = outputVal;
 443 }
 444 
 445 struct gbe_pll_info {
 446         int clock_rate;
 447         int fvco_min;
 448         int fvco_max;
 449 };
 450 
 451 static struct gbe_pll_info gbe_pll_table[2] = {
 452         { 20, 80, 220 },
 453         { 27, 80, 220 },
 454 };
 455 
 456 static int compute_gbe_timing(struct fb_var_screeninfo *var,
 457                               struct gbe_timing_info *timing)
 458 {
 459         int pll_m, pll_n, pll_p, error, best_m, best_n, best_p, best_error;
 460         int pixclock;
 461         struct gbe_pll_info *gbe_pll;
 462 
 463         if (gbe_revision < 2)
 464                 gbe_pll = &gbe_pll_table[0];
 465         else
 466                 gbe_pll = &gbe_pll_table[1];
 467 
 468         /* Determine valid resolution and timing
 469          * GBE crystal runs at 20Mhz or 27Mhz
 470          * pll_m, pll_n, pll_p define the following frequencies
 471          * fvco = pll_m * 20Mhz / pll_n
 472          * fout = fvco / (2**pll_p) */
 473         best_error = 1000000000;
 474         best_n = best_m = best_p = 0;
 475         for (pll_p = 0; pll_p < 4; pll_p++)
 476                 for (pll_m = 1; pll_m < 256; pll_m++)
 477                         for (pll_n = 1; pll_n < 64; pll_n++) {
 478                                 pixclock = (1000000 / gbe_pll->clock_rate) *
 479                                                 (pll_n << pll_p) / pll_m;
 480 
 481                                 error = var->pixclock - pixclock;
 482 
 483                                 if (error < 0)
 484                                         error = -error;
 485 
 486                                 if (error < best_error &&
 487                                     pll_m / pll_n >
 488                                     gbe_pll->fvco_min / gbe_pll->clock_rate &&
 489                                     pll_m / pll_n <
 490                                     gbe_pll->fvco_max / gbe_pll->clock_rate) {
 491                                         best_error = error;
 492                                         best_m = pll_m;
 493                                         best_n = pll_n;
 494                                         best_p = pll_p;
 495                                 }
 496                         }
 497 
 498         if (!best_n || !best_m)
 499                 return -EINVAL; /* Resolution to high */
 500 
 501         pixclock = (1000000 / gbe_pll->clock_rate) *
 502                 (best_n << best_p) / best_m;
 503 
 504         /* set video timing information */
 505         if (timing) {
 506                 timing->width = var->xres;
 507                 timing->height = var->yres;
 508                 timing->pll_m = best_m;
 509                 timing->pll_n = best_n;
 510                 timing->pll_p = best_p;
 511                 timing->cfreq = gbe_pll->clock_rate * 1000 * timing->pll_m /
 512                         (timing->pll_n << timing->pll_p);
 513                 timing->htotal = var->left_margin + var->xres +
 514                                 var->right_margin + var->hsync_len;
 515                 timing->vtotal = var->upper_margin + var->yres +
 516                                 var->lower_margin + var->vsync_len;
 517                 timing->fields_sec = 1000 * timing->cfreq / timing->htotal *
 518                                 1000 / timing->vtotal;
 519                 timing->hblank_start = var->xres;
 520                 timing->vblank_start = var->yres;
 521                 timing->hblank_end = timing->htotal;
 522                 timing->hsync_start = var->xres + var->right_margin + 1;
 523                 timing->hsync_end = timing->hsync_start + var->hsync_len;
 524                 timing->vblank_end = timing->vtotal;
 525                 timing->vsync_start = var->yres + var->lower_margin + 1;
 526                 timing->vsync_end = timing->vsync_start + var->vsync_len;
 527         }
 528 
 529         return pixclock;
 530 }
 531 
 532 static void gbe_set_timing_info(struct gbe_timing_info *timing)
 533 {
 534         int temp;
 535         unsigned int val;
 536 
 537         /* setup dot clock PLL */
 538         val = 0;
 539         SET_GBE_FIELD(DOTCLK, M, val, timing->pll_m - 1);
 540         SET_GBE_FIELD(DOTCLK, N, val, timing->pll_n - 1);
 541         SET_GBE_FIELD(DOTCLK, P, val, timing->pll_p);
 542         SET_GBE_FIELD(DOTCLK, RUN, val, 0);     /* do not start yet */
 543         gbe->dotclock = val;
 544         mdelay(10);
 545 
 546         /* setup pixel counter */
 547         val = 0;
 548         SET_GBE_FIELD(VT_XYMAX, MAXX, val, timing->htotal);
 549         SET_GBE_FIELD(VT_XYMAX, MAXY, val, timing->vtotal);
 550         gbe->vt_xymax = val;
 551 
 552         /* setup video timing signals */
 553         val = 0;
 554         SET_GBE_FIELD(VT_VSYNC, VSYNC_ON, val, timing->vsync_start);
 555         SET_GBE_FIELD(VT_VSYNC, VSYNC_OFF, val, timing->vsync_end);
 556         gbe->vt_vsync = val;
 557         val = 0;
 558         SET_GBE_FIELD(VT_HSYNC, HSYNC_ON, val, timing->hsync_start);
 559         SET_GBE_FIELD(VT_HSYNC, HSYNC_OFF, val, timing->hsync_end);
 560         gbe->vt_hsync = val;
 561         val = 0;
 562         SET_GBE_FIELD(VT_VBLANK, VBLANK_ON, val, timing->vblank_start);
 563         SET_GBE_FIELD(VT_VBLANK, VBLANK_OFF, val, timing->vblank_end);
 564         gbe->vt_vblank = val;
 565         val = 0;
 566         SET_GBE_FIELD(VT_HBLANK, HBLANK_ON, val,
 567                       timing->hblank_start - 5);
 568         SET_GBE_FIELD(VT_HBLANK, HBLANK_OFF, val,
 569                       timing->hblank_end - 3);
 570         gbe->vt_hblank = val;
 571 
 572         /* setup internal timing signals */
 573         val = 0;
 574         SET_GBE_FIELD(VT_VCMAP, VCMAP_ON, val, timing->vblank_start);
 575         SET_GBE_FIELD(VT_VCMAP, VCMAP_OFF, val, timing->vblank_end);
 576         gbe->vt_vcmap = val;
 577         val = 0;
 578         SET_GBE_FIELD(VT_HCMAP, HCMAP_ON, val, timing->hblank_start);
 579         SET_GBE_FIELD(VT_HCMAP, HCMAP_OFF, val, timing->hblank_end);
 580         gbe->vt_hcmap = val;
 581 
 582         val = 0;
 583         temp = timing->vblank_start - timing->vblank_end - 1;
 584         if (temp > 0)
 585                 temp = -temp;
 586 
 587         if (flat_panel_enabled)
 588                 gbefb_setup_flatpanel(timing);
 589 
 590         SET_GBE_FIELD(DID_START_XY, DID_STARTY, val, (u32) temp);
 591         if (timing->hblank_end >= 20)
 592                 SET_GBE_FIELD(DID_START_XY, DID_STARTX, val,
 593                               timing->hblank_end - 20);
 594         else
 595                 SET_GBE_FIELD(DID_START_XY, DID_STARTX, val,
 596                               timing->htotal - (20 - timing->hblank_end));
 597         gbe->did_start_xy = val;
 598 
 599         val = 0;
 600         SET_GBE_FIELD(CRS_START_XY, CRS_STARTY, val, (u32) (temp + 1));
 601         if (timing->hblank_end >= GBE_CRS_MAGIC)
 602                 SET_GBE_FIELD(CRS_START_XY, CRS_STARTX, val,
 603                               timing->hblank_end - GBE_CRS_MAGIC);
 604         else
 605                 SET_GBE_FIELD(CRS_START_XY, CRS_STARTX, val,
 606                               timing->htotal - (GBE_CRS_MAGIC -
 607                                                 timing->hblank_end));
 608         gbe->crs_start_xy = val;
 609 
 610         val = 0;
 611         SET_GBE_FIELD(VC_START_XY, VC_STARTY, val, (u32) temp);
 612         SET_GBE_FIELD(VC_START_XY, VC_STARTX, val, timing->hblank_end - 4);
 613         gbe->vc_start_xy = val;
 614 
 615         val = 0;
 616         temp = timing->hblank_end - GBE_PIXEN_MAGIC_ON;
 617         if (temp < 0)
 618                 temp += timing->htotal; /* allow blank to wrap around */
 619 
 620         SET_GBE_FIELD(VT_HPIXEN, HPIXEN_ON, val, temp);
 621         SET_GBE_FIELD(VT_HPIXEN, HPIXEN_OFF, val,
 622                       ((temp + timing->width -
 623                         GBE_PIXEN_MAGIC_OFF) % timing->htotal));
 624         gbe->vt_hpixen = val;
 625 
 626         val = 0;
 627         SET_GBE_FIELD(VT_VPIXEN, VPIXEN_ON, val, timing->vblank_end);
 628         SET_GBE_FIELD(VT_VPIXEN, VPIXEN_OFF, val, timing->vblank_start);
 629         gbe->vt_vpixen = val;
 630 
 631         /* turn off sync on green */
 632         val = 0;
 633         SET_GBE_FIELD(VT_FLAGS, SYNC_LOW, val, 1);
 634         gbe->vt_flags = val;
 635 }
 636 
 637 /*
 638  *  Set the hardware according to 'par'.
 639  */
 640 
 641 static int gbefb_set_par(struct fb_info *info)
 642 {
 643         int i;
 644         unsigned int val;
 645         int wholeTilesX, partTilesX, maxPixelsPerTileX;
 646         int height_pix;
 647         int xpmax, ypmax;       /* Monitor resolution */
 648         int bytesPerPixel;      /* Bytes per pixel */
 649         struct gbefb_par *par = (struct gbefb_par *) info->par;
 650 
 651         compute_gbe_timing(&info->var, &par->timing);
 652 
 653         bytesPerPixel = info->var.bits_per_pixel / 8;
 654         info->fix.line_length = info->var.xres_virtual * bytesPerPixel;
 655         xpmax = par->timing.width;
 656         ypmax = par->timing.height;
 657 
 658         /* turn off GBE */
 659         gbe_turn_off();
 660 
 661         /* set timing info */
 662         gbe_set_timing_info(&par->timing);
 663 
 664         /* initialize DIDs */
 665         val = 0;
 666         switch (bytesPerPixel) {
 667         case 1:
 668                 SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_I8);
 669                 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
 670                 break;
 671         case 2:
 672                 SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_ARGB5);
 673                 info->fix.visual = FB_VISUAL_TRUECOLOR;
 674                 break;
 675         case 4:
 676                 SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_RGB8);
 677                 info->fix.visual = FB_VISUAL_TRUECOLOR;
 678                 break;
 679         }
 680         SET_GBE_FIELD(WID, BUF, val, GBE_BMODE_BOTH);
 681 
 682         for (i = 0; i < 32; i++)
 683                 gbe->mode_regs[i] = val;
 684 
 685         /* Initialize interrupts */
 686         gbe->vt_intr01 = 0xffffffff;
 687         gbe->vt_intr23 = 0xffffffff;
 688 
 689         /* HACK:
 690            The GBE hardware uses a tiled memory to screen mapping. Tiles are
 691            blocks of 512x128, 256x128 or 128x128 pixels, respectively for 8bit,
 692            16bit and 32 bit modes (64 kB). They cover the screen with partial
 693            tiles on the right and/or bottom of the screen if needed.
 694            For example in 640x480 8 bit mode the mapping is:
 695 
 696            <-------- 640 ----->
 697            <---- 512 ----><128|384 offscreen>
 698            ^  ^
 699            | 128    [tile 0]        [tile 1]
 700            |  v
 701            ^
 702            4 128    [tile 2]        [tile 3]
 703            8  v
 704            0  ^
 705            128    [tile 4]        [tile 5]
 706            |  v
 707            |  ^
 708            v  96    [tile 6]        [tile 7]
 709            32 offscreen
 710 
 711            Tiles have the advantage that they can be allocated individually in
 712            memory. However, this mapping is not linear at all, which is not
 713            really convenient. In order to support linear addressing, the GBE
 714            DMA hardware is fooled into thinking the screen is only one tile
 715            large and but has a greater height, so that the DMA transfer covers
 716            the same region.
 717            Tiles are still allocated as independent chunks of 64KB of
 718            continuous physical memory and remapped so that the kernel sees the
 719            framebuffer as a continuous virtual memory. The GBE tile table is
 720            set up so that each tile references one of these 64k blocks:
 721 
 722            GBE -> tile list    framebuffer           TLB   <------------ CPU
 723                   [ tile 0 ] -> [ 64KB ]  <- [ 16x 4KB page entries ]     ^
 724                      ...           ...              ...       linear virtual FB
 725                   [ tile n ] -> [ 64KB ]  <- [ 16x 4KB page entries ]     v
 726 
 727 
 728            The GBE hardware is then told that the buffer is 512*tweaked_height,
 729            with tweaked_height = real_width*real_height/pixels_per_tile.
 730            Thus the GBE hardware will scan the first tile, filing the first 64k
 731            covered region of the screen, and then will proceed to the next
 732            tile, until the whole screen is covered.
 733 
 734            Here is what would happen at 640x480 8bit:
 735 
 736            normal tiling               linear
 737            ^   11111111111111112222    11111111111111111111  ^
 738            128 11111111111111112222    11111111111111111111 102 lines
 739                11111111111111112222    11111111111111111111  v
 740            V   11111111111111112222    11111111222222222222
 741                33333333333333334444    22222222222222222222
 742                33333333333333334444    22222222222222222222
 743                <      512     >        <  256 >               102*640+256 = 64k
 744 
 745            NOTE: The only mode for which this is not working is 800x600 8bit,
 746            as 800*600/512 = 937.5 which is not integer and thus causes
 747            flickering.
 748            I guess this is not so important as one can use 640x480 8bit or
 749            800x600 16bit anyway.
 750          */
 751 
 752         /* Tell gbe about the tiles table location */
 753         /* tile_ptr -> [ tile 1 ] -> FB mem */
 754         /*             [ tile 2 ] -> FB mem */
 755         /*               ...                */
 756         val = 0;
 757         SET_GBE_FIELD(FRM_CONTROL, FRM_TILE_PTR, val, gbe_tiles.dma >> 9);
 758         SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 0); /* do not start */
 759         SET_GBE_FIELD(FRM_CONTROL, FRM_LINEAR, val, 0);
 760         gbe->frm_control = val;
 761 
 762         maxPixelsPerTileX = 512 / bytesPerPixel;
 763         wholeTilesX = 1;
 764         partTilesX = 0;
 765 
 766         /* Initialize the framebuffer */
 767         val = 0;
 768         SET_GBE_FIELD(FRM_SIZE_TILE, FRM_WIDTH_TILE, val, wholeTilesX);
 769         SET_GBE_FIELD(FRM_SIZE_TILE, FRM_RHS, val, partTilesX);
 770 
 771         switch (bytesPerPixel) {
 772         case 1:
 773                 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
 774                               GBE_FRM_DEPTH_8);
 775                 break;
 776         case 2:
 777                 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
 778                               GBE_FRM_DEPTH_16);
 779                 break;
 780         case 4:
 781                 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
 782                               GBE_FRM_DEPTH_32);
 783                 break;
 784         }
 785         gbe->frm_size_tile = val;
 786 
 787         /* compute tweaked height */
 788         height_pix = xpmax * ypmax / maxPixelsPerTileX;
 789 
 790         val = 0;
 791         SET_GBE_FIELD(FRM_SIZE_PIXEL, FB_HEIGHT_PIX, val, height_pix);
 792         gbe->frm_size_pixel = val;
 793 
 794         /* turn off DID and overlay DMA */
 795         gbe->did_control = 0;
 796         gbe->ovr_width_tile = 0;
 797 
 798         /* Turn off mouse cursor */
 799         gbe->crs_ctl = 0;
 800 
 801         /* Turn on GBE */
 802         gbe_turn_on();
 803 
 804         /* Initialize the gamma map */
 805         udelay(10);
 806         for (i = 0; i < 256; i++)
 807                 gbe->gmap[i] = (i << 24) | (i << 16) | (i << 8);
 808 
 809         /* Initialize the color map */
 810         for (i = 0; i < 256; i++)
 811                 gbe_cmap[i] = (i << 8) | (i << 16) | (i << 24);
 812 
 813         gbe_loadcmap();
 814 
 815         return 0;
 816 }
 817 
 818 static void gbefb_encode_fix(struct fb_fix_screeninfo *fix,
 819                              struct fb_var_screeninfo *var)
 820 {
 821         memset(fix, 0, sizeof(struct fb_fix_screeninfo));
 822         strcpy(fix->id, "SGI GBE");
 823         fix->smem_start = (unsigned long) gbe_mem;
 824         fix->smem_len = gbe_mem_size;
 825         fix->type = FB_TYPE_PACKED_PIXELS;
 826         fix->type_aux = 0;
 827         fix->accel = FB_ACCEL_NONE;
 828         switch (var->bits_per_pixel) {
 829         case 8:
 830                 fix->visual = FB_VISUAL_PSEUDOCOLOR;
 831                 break;
 832         default:
 833                 fix->visual = FB_VISUAL_TRUECOLOR;
 834                 break;
 835         }
 836         fix->ywrapstep = 0;
 837         fix->xpanstep = 0;
 838         fix->ypanstep = 0;
 839         fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
 840         fix->mmio_start = GBE_BASE;
 841         fix->mmio_len = sizeof(struct sgi_gbe);
 842 }
 843 
 844 /*
 845  *  Set a single color register. The values supplied are already
 846  *  rounded down to the hardware's capabilities (according to the
 847  *  entries in the var structure). Return != 0 for invalid regno.
 848  */
 849 
 850 static int gbefb_setcolreg(unsigned regno, unsigned red, unsigned green,
 851                              unsigned blue, unsigned transp,
 852                              struct fb_info *info)
 853 {
 854         int i;
 855 
 856         if (regno > 255)
 857                 return 1;
 858         red >>= 8;
 859         green >>= 8;
 860         blue >>= 8;
 861 
 862         if (info->var.bits_per_pixel <= 8) {
 863                 gbe_cmap[regno] = (red << 24) | (green << 16) | (blue << 8);
 864                 if (gbe_turned_on) {
 865                         /* wait for the color map FIFO to have a free entry */
 866                         for (i = 0; i < 1000 && gbe->cm_fifo >= 63; i++)
 867                                 udelay(10);
 868                         if (i == 1000) {
 869                                 printk(KERN_ERR "gbefb: cmap FIFO timeout\n");
 870                                 return 1;
 871                         }
 872                         gbe->cmap[regno] = gbe_cmap[regno];
 873                 }
 874         } else if (regno < 16) {
 875                 switch (info->var.bits_per_pixel) {
 876                 case 15:
 877                 case 16:
 878                         red >>= 3;
 879                         green >>= 3;
 880                         blue >>= 3;
 881                         pseudo_palette[regno] =
 882                                 (red << info->var.red.offset) |
 883                                 (green << info->var.green.offset) |
 884                                 (blue << info->var.blue.offset);
 885                         break;
 886                 case 32:
 887                         pseudo_palette[regno] =
 888                                 (red << info->var.red.offset) |
 889                                 (green << info->var.green.offset) |
 890                                 (blue << info->var.blue.offset);
 891                         break;
 892                 }
 893         }
 894 
 895         return 0;
 896 }
 897 
 898 /*
 899  *  Check video mode validity, eventually modify var to best match.
 900  */
 901 static int gbefb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 902 {
 903         unsigned int line_length;
 904         struct gbe_timing_info timing;
 905         int ret;
 906 
 907         /* Limit bpp to 8, 16, and 32 */
 908         if (var->bits_per_pixel <= 8)
 909                 var->bits_per_pixel = 8;
 910         else if (var->bits_per_pixel <= 16)
 911                 var->bits_per_pixel = 16;
 912         else if (var->bits_per_pixel <= 32)
 913                 var->bits_per_pixel = 32;
 914         else
 915                 return -EINVAL;
 916 
 917         /* Check the mode can be mapped linearly with the tile table trick. */
 918         /* This requires width x height x bytes/pixel be a multiple of 512 */
 919         if ((var->xres * var->yres * var->bits_per_pixel) & 4095)
 920                 return -EINVAL;
 921 
 922         var->grayscale = 0;     /* No grayscale for now */
 923 
 924         ret = compute_gbe_timing(var, &timing);
 925         var->pixclock = ret;
 926         if (ret < 0)
 927                 return -EINVAL;
 928 
 929         /* Adjust virtual resolution, if necessary */
 930         if (var->xres > var->xres_virtual || (!ywrap && !ypan))
 931                 var->xres_virtual = var->xres;
 932         if (var->yres > var->yres_virtual || (!ywrap && !ypan))
 933                 var->yres_virtual = var->yres;
 934 
 935         if (var->vmode & FB_VMODE_CONUPDATE) {
 936                 var->vmode |= FB_VMODE_YWRAP;
 937                 var->xoffset = info->var.xoffset;
 938                 var->yoffset = info->var.yoffset;
 939         }
 940 
 941         /* No grayscale for now */
 942         var->grayscale = 0;
 943 
 944         /* Memory limit */
 945         line_length = var->xres_virtual * var->bits_per_pixel / 8;
 946         if (line_length * var->yres_virtual > gbe_mem_size)
 947                 return -ENOMEM; /* Virtual resolution too high */
 948 
 949         switch (var->bits_per_pixel) {
 950         case 8:
 951                 var->red.offset = 0;
 952                 var->red.length = 8;
 953                 var->green.offset = 0;
 954                 var->green.length = 8;
 955                 var->blue.offset = 0;
 956                 var->blue.length = 8;
 957                 var->transp.offset = 0;
 958                 var->transp.length = 0;
 959                 break;
 960         case 16:                /* RGB 1555 */
 961                 var->red.offset = 10;
 962                 var->red.length = 5;
 963                 var->green.offset = 5;
 964                 var->green.length = 5;
 965                 var->blue.offset = 0;
 966                 var->blue.length = 5;
 967                 var->transp.offset = 0;
 968                 var->transp.length = 0;
 969                 break;
 970         case 32:                /* RGB 8888 */
 971                 var->red.offset = 24;
 972                 var->red.length = 8;
 973                 var->green.offset = 16;
 974                 var->green.length = 8;
 975                 var->blue.offset = 8;
 976                 var->blue.length = 8;
 977                 var->transp.offset = 0;
 978                 var->transp.length = 8;
 979                 break;
 980         }
 981         var->red.msb_right = 0;
 982         var->green.msb_right = 0;
 983         var->blue.msb_right = 0;
 984         var->transp.msb_right = 0;
 985 
 986         var->left_margin = timing.htotal - timing.hsync_end;
 987         var->right_margin = timing.hsync_start - timing.width;
 988         var->upper_margin = timing.vtotal - timing.vsync_end;
 989         var->lower_margin = timing.vsync_start - timing.height;
 990         var->hsync_len = timing.hsync_end - timing.hsync_start;
 991         var->vsync_len = timing.vsync_end - timing.vsync_start;
 992 
 993         return 0;
 994 }
 995 
 996 static int gbefb_mmap(struct fb_info *info,
 997                         struct vm_area_struct *vma)
 998 {
 999         unsigned long size = vma->vm_end - vma->vm_start;
1000         unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
1001         unsigned long addr;
1002         unsigned long phys_addr, phys_size;
1003         u16 *tile;
1004 
1005         /* check range */
1006         if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
1007                 return -EINVAL;
1008         if (size > gbe_mem_size)
1009                 return -EINVAL;
1010         if (offset > gbe_mem_size - size)
1011                 return -EINVAL;
1012 
1013         /* remap using the fastest write-through mode on architecture */
1014         /* try not polluting the cache when possible */
1015 #ifdef CONFIG_MIPS
1016         pgprot_val(vma->vm_page_prot) =
1017                 pgprot_fb(pgprot_val(vma->vm_page_prot));
1018 #endif
1019         /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
1020 
1021         /* look for the starting tile */
1022         tile = &gbe_tiles.cpu[offset >> TILE_SHIFT];
1023         addr = vma->vm_start;
1024         offset &= TILE_MASK;
1025 
1026         /* remap each tile separately */
1027         do {
1028                 phys_addr = (((unsigned long) (*tile)) << TILE_SHIFT) + offset;
1029                 if ((offset + size) < TILE_SIZE)
1030                         phys_size = size;
1031                 else
1032                         phys_size = TILE_SIZE - offset;
1033 
1034                 if (remap_pfn_range(vma, addr, phys_addr >> PAGE_SHIFT,
1035                                                 phys_size, vma->vm_page_prot))
1036                         return -EAGAIN;
1037 
1038                 offset = 0;
1039                 size -= phys_size;
1040                 addr += phys_size;
1041                 tile++;
1042         } while (size);
1043 
1044         return 0;
1045 }
1046 
1047 static struct fb_ops gbefb_ops = {
1048         .owner          = THIS_MODULE,
1049         .fb_check_var   = gbefb_check_var,
1050         .fb_set_par     = gbefb_set_par,
1051         .fb_setcolreg   = gbefb_setcolreg,
1052         .fb_mmap        = gbefb_mmap,
1053         .fb_blank       = gbefb_blank,
1054         .fb_fillrect    = cfb_fillrect,
1055         .fb_copyarea    = cfb_copyarea,
1056         .fb_imageblit   = cfb_imageblit,
1057 };
1058 
1059 /*
1060  * sysfs
1061  */
1062 
1063 static ssize_t gbefb_show_memsize(struct device *dev, struct device_attribute *attr, char *buf)
1064 {
1065         return snprintf(buf, PAGE_SIZE, "%u\n", gbe_mem_size);
1066 }
1067 
1068 static DEVICE_ATTR(size, S_IRUGO, gbefb_show_memsize, NULL);
1069 
1070 static ssize_t gbefb_show_rev(struct device *device, struct device_attribute *attr, char *buf)
1071 {
1072         return snprintf(buf, PAGE_SIZE, "%d\n", gbe_revision);
1073 }
1074 
1075 static DEVICE_ATTR(revision, S_IRUGO, gbefb_show_rev, NULL);
1076 
1077 static void gbefb_remove_sysfs(struct device *dev)
1078 {
1079         device_remove_file(dev, &dev_attr_size);
1080         device_remove_file(dev, &dev_attr_revision);
1081 }
1082 
1083 static void gbefb_create_sysfs(struct device *dev)
1084 {
1085         device_create_file(dev, &dev_attr_size);
1086         device_create_file(dev, &dev_attr_revision);
1087 }
1088 
1089 /*
1090  * Initialization
1091  */
1092 
1093 static int gbefb_setup(char *options)
1094 {
1095         char *this_opt;
1096 
1097         if (!options || !*options)
1098                 return 0;
1099 
1100         while ((this_opt = strsep(&options, ",")) != NULL) {
1101                 if (!strncmp(this_opt, "monitor:", 8)) {
1102                         if (!strncmp(this_opt + 8, "crt", 3)) {
1103                                 flat_panel_enabled = 0;
1104                                 default_var = &default_var_CRT;
1105                                 default_mode = &default_mode_CRT;
1106                         } else if (!strncmp(this_opt + 8, "1600sw", 6) ||
1107                                    !strncmp(this_opt + 8, "lcd", 3)) {
1108                                 flat_panel_enabled = 1;
1109                                 default_var = &default_var_LCD;
1110                                 default_mode = &default_mode_LCD;
1111                         }
1112                 } else if (!strncmp(this_opt, "mem:", 4)) {
1113                         gbe_mem_size = memparse(this_opt + 4, &this_opt);
1114                         if (gbe_mem_size > CONFIG_FB_GBE_MEM * 1024 * 1024)
1115                                 gbe_mem_size = CONFIG_FB_GBE_MEM * 1024 * 1024;
1116                         if (gbe_mem_size < TILE_SIZE)
1117                                 gbe_mem_size = TILE_SIZE;
1118                 } else
1119                         mode_option = this_opt;
1120         }
1121         return 0;
1122 }
1123 
1124 static int gbefb_probe(struct platform_device *p_dev)
1125 {
1126         int i, ret = 0;
1127         struct fb_info *info;
1128         struct gbefb_par *par;
1129 #ifndef MODULE
1130         char *options = NULL;
1131 #endif
1132 
1133         info = framebuffer_alloc(sizeof(struct gbefb_par), &p_dev->dev);
1134         if (!info)
1135                 return -ENOMEM;
1136 
1137 #ifndef MODULE
1138         if (fb_get_options("gbefb", &options)) {
1139                 ret = -ENODEV;
1140                 goto out_release_framebuffer;
1141         }
1142         gbefb_setup(options);
1143 #endif
1144 
1145         if (!request_mem_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
1146                 printk(KERN_ERR "gbefb: couldn't reserve mmio region\n");
1147                 ret = -EBUSY;
1148                 goto out_release_framebuffer;
1149         }
1150 
1151         gbe = (struct sgi_gbe *) devm_ioremap(&p_dev->dev, GBE_BASE,
1152                                               sizeof(struct sgi_gbe));
1153         if (!gbe) {
1154                 printk(KERN_ERR "gbefb: couldn't map mmio region\n");
1155                 ret = -ENXIO;
1156                 goto out_release_mem_region;
1157         }
1158         gbe_revision = gbe->ctrlstat & 15;
1159 
1160         gbe_tiles.cpu = dmam_alloc_coherent(&p_dev->dev,
1161                                 GBE_TLB_SIZE * sizeof(uint16_t),
1162                                 &gbe_tiles.dma, GFP_KERNEL);
1163         if (!gbe_tiles.cpu) {
1164                 printk(KERN_ERR "gbefb: couldn't allocate tiles table\n");
1165                 ret = -ENOMEM;
1166                 goto out_release_mem_region;
1167         }
1168 
1169         if (gbe_mem_phys) {
1170                 /* memory was allocated at boot time */
1171                 gbe_mem = devm_ioremap_wc(&p_dev->dev, gbe_mem_phys,
1172                                           gbe_mem_size);
1173                 if (!gbe_mem) {
1174                         printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
1175                         ret = -ENOMEM;
1176                         goto out_release_mem_region;
1177                 }
1178 
1179                 gbe_dma_addr = 0;
1180         } else {
1181                 /* try to allocate memory with the classical allocator
1182                  * this has high chance to fail on low memory machines */
1183                 gbe_mem = dmam_alloc_attrs(&p_dev->dev, gbe_mem_size,
1184                                 &gbe_dma_addr, GFP_KERNEL,
1185                                 DMA_ATTR_WRITE_COMBINE);
1186                 if (!gbe_mem) {
1187                         printk(KERN_ERR "gbefb: couldn't allocate framebuffer memory\n");
1188                         ret = -ENOMEM;
1189                         goto out_release_mem_region;
1190                 }
1191 
1192                 gbe_mem_phys = (unsigned long) gbe_dma_addr;
1193         }
1194 
1195         par = info->par;
1196         par->wc_cookie = arch_phys_wc_add(gbe_mem_phys, gbe_mem_size);
1197 
1198         /* map framebuffer memory into tiles table */
1199         for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++)
1200                 gbe_tiles.cpu[i] = (gbe_mem_phys >> TILE_SHIFT) + i;
1201 
1202         info->fbops = &gbefb_ops;
1203         info->pseudo_palette = pseudo_palette;
1204         info->flags = FBINFO_DEFAULT;
1205         info->screen_base = gbe_mem;
1206         fb_alloc_cmap(&info->cmap, 256, 0);
1207 
1208         /* reset GBE */
1209         gbe_reset();
1210 
1211         /* turn on default video mode */
1212         if (fb_find_mode(&par->var, info, mode_option, NULL, 0,
1213                          default_mode, 8) == 0)
1214                 par->var = *default_var;
1215         info->var = par->var;
1216         gbefb_check_var(&par->var, info);
1217         gbefb_encode_fix(&info->fix, &info->var);
1218 
1219         if (register_framebuffer(info) < 0) {
1220                 printk(KERN_ERR "gbefb: couldn't register framebuffer\n");
1221                 ret = -ENXIO;
1222                 goto out_gbe_unmap;
1223         }
1224 
1225         platform_set_drvdata(p_dev, info);
1226         gbefb_create_sysfs(&p_dev->dev);
1227 
1228         fb_info(info, "%s rev %d @ 0x%08x using %dkB memory\n",
1229                 info->fix.id, gbe_revision, (unsigned)GBE_BASE,
1230                 gbe_mem_size >> 10);
1231 
1232         return 0;
1233 
1234 out_gbe_unmap:
1235         arch_phys_wc_del(par->wc_cookie);
1236 out_release_mem_region:
1237         release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1238 out_release_framebuffer:
1239         framebuffer_release(info);
1240 
1241         return ret;
1242 }
1243 
1244 static int gbefb_remove(struct platform_device* p_dev)
1245 {
1246         struct fb_info *info = platform_get_drvdata(p_dev);
1247         struct gbefb_par *par = info->par;
1248 
1249         unregister_framebuffer(info);
1250         gbe_turn_off();
1251         arch_phys_wc_del(par->wc_cookie);
1252         release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1253         gbefb_remove_sysfs(&p_dev->dev);
1254         framebuffer_release(info);
1255 
1256         return 0;
1257 }
1258 
1259 static struct platform_driver gbefb_driver = {
1260         .probe = gbefb_probe,
1261         .remove = gbefb_remove,
1262         .driver = {
1263                 .name = "gbefb",
1264         },
1265 };
1266 
1267 static struct platform_device *gbefb_device;
1268 
1269 static int __init gbefb_init(void)
1270 {
1271         int ret = platform_driver_register(&gbefb_driver);
1272         if (!ret) {
1273                 gbefb_device = platform_device_alloc("gbefb", 0);
1274                 if (gbefb_device) {
1275                         ret = platform_device_add(gbefb_device);
1276                 } else {
1277                         ret = -ENOMEM;
1278                 }
1279                 if (ret) {
1280                         platform_device_put(gbefb_device);
1281                         platform_driver_unregister(&gbefb_driver);
1282                 }
1283         }
1284         return ret;
1285 }
1286 
1287 static void __exit gbefb_exit(void)
1288 {
1289         platform_device_unregister(gbefb_device);
1290         platform_driver_unregister(&gbefb_driver);
1291 }
1292 
1293 module_init(gbefb_init);
1294 module_exit(gbefb_exit);
1295 
1296 MODULE_LICENSE("GPL");

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