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