0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/delay.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/dma-mapping.h>
0015 #include <linux/errno.h>
0016 #include <linux/gfp.h>
0017 #include <linux/fb.h>
0018 #include <linux/init.h>
0019 #include <linux/interrupt.h>
0020 #include <linux/kernel.h>
0021 #include <linux/mm.h>
0022 #include <linux/module.h>
0023 #include <linux/io.h>
0024
0025 #ifdef CONFIG_MIPS
0026 #include <asm/addrspace.h>
0027 #endif
0028 #include <asm/byteorder.h>
0029 #include <asm/tlbflush.h>
0030
0031 #include <video/gbe.h>
0032
0033 static struct sgi_gbe *gbe;
0034
0035 struct gbefb_par {
0036 struct fb_var_screeninfo var;
0037 struct gbe_timing_info timing;
0038 int wc_cookie;
0039 int valid;
0040 };
0041
0042 #define GBE_BASE 0x16000000
0043
0044
0045 #ifdef CONFIG_MIPS
0046 #ifdef CONFIG_CPU_R10000
0047 #define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_UNCACHED_ACCELERATED)
0048 #else
0049 #define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_CACHABLE_NO_WA)
0050 #endif
0051 #endif
0052
0053
0054
0055
0056
0057 #if CONFIG_FB_GBE_MEM > 8
0058 #error GBE Framebuffer cannot use more than 8MB of memory
0059 #endif
0060
0061 #define TILE_SHIFT 16
0062 #define TILE_SIZE (1 << TILE_SHIFT)
0063 #define TILE_MASK (TILE_SIZE - 1)
0064
0065 static unsigned int gbe_mem_size = CONFIG_FB_GBE_MEM * 1024*1024;
0066 static void *gbe_mem;
0067 static dma_addr_t gbe_dma_addr;
0068 static unsigned long gbe_mem_phys;
0069
0070 static struct {
0071 uint16_t *cpu;
0072 dma_addr_t dma;
0073 } gbe_tiles;
0074
0075 static int gbe_revision;
0076
0077 static int ypan, ywrap;
0078
0079 static uint32_t pseudo_palette[16];
0080 static uint32_t gbe_cmap[256];
0081 static int gbe_turned_on;
0082
0083 static char *mode_option = NULL;
0084
0085
0086 static struct fb_var_screeninfo default_var_CRT = {
0087
0088 .xres = 640,
0089 .yres = 480,
0090 .xres_virtual = 640,
0091 .yres_virtual = 480,
0092 .xoffset = 0,
0093 .yoffset = 0,
0094 .bits_per_pixel = 8,
0095 .grayscale = 0,
0096 .red = { 0, 8, 0 },
0097 .green = { 0, 8, 0 },
0098 .blue = { 0, 8, 0 },
0099 .transp = { 0, 0, 0 },
0100 .nonstd = 0,
0101 .activate = 0,
0102 .height = -1,
0103 .width = -1,
0104 .accel_flags = 0,
0105 .pixclock = 39722,
0106 .left_margin = 48,
0107 .right_margin = 16,
0108 .upper_margin = 33,
0109 .lower_margin = 10,
0110 .hsync_len = 96,
0111 .vsync_len = 2,
0112 .sync = 0,
0113 .vmode = FB_VMODE_NONINTERLACED,
0114 };
0115
0116
0117 static struct fb_var_screeninfo default_var_LCD = {
0118
0119 .xres = 1600,
0120 .yres = 1024,
0121 .xres_virtual = 1600,
0122 .yres_virtual = 1024,
0123 .xoffset = 0,
0124 .yoffset = 0,
0125 .bits_per_pixel = 8,
0126 .grayscale = 0,
0127 .red = { 0, 8, 0 },
0128 .green = { 0, 8, 0 },
0129 .blue = { 0, 8, 0 },
0130 .transp = { 0, 0, 0 },
0131 .nonstd = 0,
0132 .activate = 0,
0133 .height = -1,
0134 .width = -1,
0135 .accel_flags = 0,
0136 .pixclock = 9353,
0137 .left_margin = 20,
0138 .right_margin = 30,
0139 .upper_margin = 37,
0140 .lower_margin = 3,
0141 .hsync_len = 20,
0142 .vsync_len = 3,
0143 .sync = 0,
0144 .vmode = FB_VMODE_NONINTERLACED
0145 };
0146
0147
0148
0149 static struct fb_videomode default_mode_CRT = {
0150 .refresh = 60,
0151 .xres = 640,
0152 .yres = 480,
0153 .pixclock = 39722,
0154 .left_margin = 48,
0155 .right_margin = 16,
0156 .upper_margin = 33,
0157 .lower_margin = 10,
0158 .hsync_len = 96,
0159 .vsync_len = 2,
0160 .sync = 0,
0161 .vmode = FB_VMODE_NONINTERLACED,
0162 };
0163
0164 static struct fb_videomode default_mode_LCD = {
0165
0166 .xres = 1600,
0167 .yres = 1024,
0168 .pixclock = 9353,
0169 .left_margin = 20,
0170 .right_margin = 30,
0171 .upper_margin = 37,
0172 .lower_margin = 3,
0173 .hsync_len = 20,
0174 .vsync_len = 3,
0175 .vmode = FB_VMODE_NONINTERLACED,
0176 };
0177
0178 static struct fb_videomode *default_mode = &default_mode_CRT;
0179 static struct fb_var_screeninfo *default_var = &default_var_CRT;
0180
0181 static int flat_panel_enabled = 0;
0182
0183 static void gbe_reset(void)
0184 {
0185
0186 gbe->ctrlstat = 0x300aa000;
0187 }
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198 static void gbe_turn_off(void)
0199 {
0200 int i;
0201 unsigned int val, y, vpixen_off;
0202
0203 gbe_turned_on = 0;
0204
0205
0206 val = gbe->vt_xy;
0207 if (GET_GBE_FIELD(VT_XY, FREEZE, val) == 1)
0208 return;
0209
0210
0211 val = gbe->ovr_control;
0212 SET_GBE_FIELD(OVR_CONTROL, OVR_DMA_ENABLE, val, 0);
0213 gbe->ovr_control = val;
0214 udelay(1000);
0215 val = gbe->frm_control;
0216 SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 0);
0217 gbe->frm_control = val;
0218 udelay(1000);
0219 val = gbe->did_control;
0220 SET_GBE_FIELD(DID_CONTROL, DID_DMA_ENABLE, val, 0);
0221 gbe->did_control = val;
0222 udelay(1000);
0223
0224
0225
0226 for (i = 0; i < 10000; i++) {
0227 val = gbe->frm_inhwctrl;
0228 if (GET_GBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, val)) {
0229 udelay(10);
0230 } else {
0231 val = gbe->ovr_inhwctrl;
0232 if (GET_GBE_FIELD(OVR_INHWCTRL, OVR_DMA_ENABLE, val)) {
0233 udelay(10);
0234 } else {
0235 val = gbe->did_inhwctrl;
0236 if (GET_GBE_FIELD(DID_INHWCTRL, DID_DMA_ENABLE, val)) {
0237 udelay(10);
0238 } else
0239 break;
0240 }
0241 }
0242 }
0243 if (i == 10000)
0244 printk(KERN_ERR "gbefb: turn off DMA timed out\n");
0245
0246
0247 val = gbe->vt_vpixen;
0248 vpixen_off = GET_GBE_FIELD(VT_VPIXEN, VPIXEN_OFF, val);
0249
0250 for (i = 0; i < 100000; i++) {
0251 val = gbe->vt_xy;
0252 y = GET_GBE_FIELD(VT_XY, Y, val);
0253 if (y < vpixen_off)
0254 break;
0255 udelay(1);
0256 }
0257 if (i == 100000)
0258 printk(KERN_ERR
0259 "gbefb: wait for vpixen_off timed out\n");
0260 for (i = 0; i < 10000; i++) {
0261 val = gbe->vt_xy;
0262 y = GET_GBE_FIELD(VT_XY, Y, val);
0263 if (y > vpixen_off)
0264 break;
0265 udelay(1);
0266 }
0267 if (i == 10000)
0268 printk(KERN_ERR "gbefb: wait for vpixen_off timed out\n");
0269
0270
0271 val = 0;
0272 SET_GBE_FIELD(VT_XY, FREEZE, val, 1);
0273 gbe->vt_xy = val;
0274 mdelay(10);
0275 for (i = 0; i < 10000; i++) {
0276 val = gbe->vt_xy;
0277 if (GET_GBE_FIELD(VT_XY, FREEZE, val) != 1)
0278 udelay(10);
0279 else
0280 break;
0281 }
0282 if (i == 10000)
0283 printk(KERN_ERR "gbefb: turn off pixel clock timed out\n");
0284
0285
0286 val = gbe->dotclock;
0287 SET_GBE_FIELD(DOTCLK, RUN, val, 0);
0288 gbe->dotclock = val;
0289 mdelay(10);
0290 for (i = 0; i < 10000; i++) {
0291 val = gbe->dotclock;
0292 if (GET_GBE_FIELD(DOTCLK, RUN, val))
0293 udelay(10);
0294 else
0295 break;
0296 }
0297 if (i == 10000)
0298 printk(KERN_ERR "gbefb: turn off dotclock timed out\n");
0299
0300
0301 val = gbe->frm_size_tile;
0302 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, val, 1);
0303 gbe->frm_size_tile = val;
0304 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, val, 0);
0305 gbe->frm_size_tile = val;
0306 }
0307
0308 static void gbe_turn_on(void)
0309 {
0310 unsigned int val, i;
0311
0312
0313
0314
0315
0316 if (gbe_revision < 2) {
0317 val = gbe->vt_xy;
0318 if (GET_GBE_FIELD(VT_XY, FREEZE, val) == 0)
0319 return;
0320 }
0321
0322
0323 val = gbe->dotclock;
0324 SET_GBE_FIELD(DOTCLK, RUN, val, 1);
0325 gbe->dotclock = val;
0326 mdelay(10);
0327 for (i = 0; i < 10000; i++) {
0328 val = gbe->dotclock;
0329 if (GET_GBE_FIELD(DOTCLK, RUN, val) != 1)
0330 udelay(10);
0331 else
0332 break;
0333 }
0334 if (i == 10000)
0335 printk(KERN_ERR "gbefb: turn on dotclock timed out\n");
0336
0337
0338 val = 0;
0339 SET_GBE_FIELD(VT_XY, FREEZE, val, 0);
0340 gbe->vt_xy = val;
0341 mdelay(10);
0342 for (i = 0; i < 10000; i++) {
0343 val = gbe->vt_xy;
0344 if (GET_GBE_FIELD(VT_XY, FREEZE, val))
0345 udelay(10);
0346 else
0347 break;
0348 }
0349 if (i == 10000)
0350 printk(KERN_ERR "gbefb: turn on pixel clock timed out\n");
0351
0352
0353 val = gbe->frm_control;
0354 SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 1);
0355 gbe->frm_control = val;
0356 udelay(1000);
0357 for (i = 0; i < 10000; i++) {
0358 val = gbe->frm_inhwctrl;
0359 if (GET_GBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, val) != 1)
0360 udelay(10);
0361 else
0362 break;
0363 }
0364 if (i == 10000)
0365 printk(KERN_ERR "gbefb: turn on DMA timed out\n");
0366
0367 gbe_turned_on = 1;
0368 }
0369
0370 static void gbe_loadcmap(void)
0371 {
0372 int i, j;
0373
0374 for (i = 0; i < 256; i++) {
0375 for (j = 0; j < 1000 && gbe->cm_fifo >= 63; j++)
0376 udelay(10);
0377 if (j == 1000)
0378 printk(KERN_ERR "gbefb: cmap FIFO timeout\n");
0379
0380 gbe->cmap[i] = gbe_cmap[i];
0381 }
0382 }
0383
0384
0385
0386
0387 static int gbefb_blank(int blank, struct fb_info *info)
0388 {
0389
0390 switch (blank) {
0391 case FB_BLANK_UNBLANK:
0392 gbe_turn_on();
0393 gbe_loadcmap();
0394 break;
0395
0396 case FB_BLANK_NORMAL:
0397 gbe_turn_off();
0398 break;
0399
0400 default:
0401
0402 break;
0403 }
0404 return 0;
0405 }
0406
0407
0408
0409
0410 static void gbefb_setup_flatpanel(struct gbe_timing_info *timing)
0411 {
0412 int fp_wid, fp_hgt, fp_vbs, fp_vbe;
0413 u32 outputVal = 0;
0414
0415 SET_GBE_FIELD(VT_FLAGS, HDRV_INVERT, outputVal,
0416 (timing->flags & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1);
0417 SET_GBE_FIELD(VT_FLAGS, VDRV_INVERT, outputVal,
0418 (timing->flags & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1);
0419 gbe->vt_flags = outputVal;
0420
0421
0422 fp_wid = 1600;
0423 fp_hgt = 1024;
0424 fp_vbs = 0;
0425 fp_vbe = 1600;
0426 timing->pll_m = 4;
0427 timing->pll_n = 1;
0428 timing->pll_p = 0;
0429
0430 outputVal = 0;
0431 SET_GBE_FIELD(FP_DE, ON, outputVal, fp_vbs);
0432 SET_GBE_FIELD(FP_DE, OFF, outputVal, fp_vbe);
0433 gbe->fp_de = outputVal;
0434 outputVal = 0;
0435 SET_GBE_FIELD(FP_HDRV, OFF, outputVal, fp_wid);
0436 gbe->fp_hdrv = outputVal;
0437 outputVal = 0;
0438 SET_GBE_FIELD(FP_VDRV, ON, outputVal, 1);
0439 SET_GBE_FIELD(FP_VDRV, OFF, outputVal, fp_hgt + 1);
0440 gbe->fp_vdrv = outputVal;
0441 }
0442
0443 struct gbe_pll_info {
0444 int clock_rate;
0445 int fvco_min;
0446 int fvco_max;
0447 };
0448
0449 static struct gbe_pll_info gbe_pll_table[2] = {
0450 { 20, 80, 220 },
0451 { 27, 80, 220 },
0452 };
0453
0454 static int compute_gbe_timing(struct fb_var_screeninfo *var,
0455 struct gbe_timing_info *timing)
0456 {
0457 int pll_m, pll_n, pll_p, error, best_m, best_n, best_p, best_error;
0458 int pixclock;
0459 struct gbe_pll_info *gbe_pll;
0460
0461 if (gbe_revision < 2)
0462 gbe_pll = &gbe_pll_table[0];
0463 else
0464 gbe_pll = &gbe_pll_table[1];
0465
0466
0467
0468
0469
0470
0471 best_error = 1000000000;
0472 best_n = best_m = best_p = 0;
0473 for (pll_p = 0; pll_p < 4; pll_p++)
0474 for (pll_m = 1; pll_m < 256; pll_m++)
0475 for (pll_n = 1; pll_n < 64; pll_n++) {
0476 pixclock = (1000000 / gbe_pll->clock_rate) *
0477 (pll_n << pll_p) / pll_m;
0478
0479 error = var->pixclock - pixclock;
0480
0481 if (error < 0)
0482 error = -error;
0483
0484 if (error < best_error &&
0485 pll_m / pll_n >
0486 gbe_pll->fvco_min / gbe_pll->clock_rate &&
0487 pll_m / pll_n <
0488 gbe_pll->fvco_max / gbe_pll->clock_rate) {
0489 best_error = error;
0490 best_m = pll_m;
0491 best_n = pll_n;
0492 best_p = pll_p;
0493 }
0494 }
0495
0496 if (!best_n || !best_m)
0497 return -EINVAL;
0498
0499 pixclock = (1000000 / gbe_pll->clock_rate) *
0500 (best_n << best_p) / best_m;
0501
0502
0503 if (timing) {
0504 timing->width = var->xres;
0505 timing->height = var->yres;
0506 timing->pll_m = best_m;
0507 timing->pll_n = best_n;
0508 timing->pll_p = best_p;
0509 timing->cfreq = gbe_pll->clock_rate * 1000 * timing->pll_m /
0510 (timing->pll_n << timing->pll_p);
0511 timing->htotal = var->left_margin + var->xres +
0512 var->right_margin + var->hsync_len;
0513 timing->vtotal = var->upper_margin + var->yres +
0514 var->lower_margin + var->vsync_len;
0515 timing->fields_sec = 1000 * timing->cfreq / timing->htotal *
0516 1000 / timing->vtotal;
0517 timing->hblank_start = var->xres;
0518 timing->vblank_start = var->yres;
0519 timing->hblank_end = timing->htotal;
0520 timing->hsync_start = var->xres + var->right_margin + 1;
0521 timing->hsync_end = timing->hsync_start + var->hsync_len;
0522 timing->vblank_end = timing->vtotal;
0523 timing->vsync_start = var->yres + var->lower_margin + 1;
0524 timing->vsync_end = timing->vsync_start + var->vsync_len;
0525 }
0526
0527 return pixclock;
0528 }
0529
0530 static void gbe_set_timing_info(struct gbe_timing_info *timing)
0531 {
0532 int temp;
0533 unsigned int val;
0534
0535
0536 val = 0;
0537 SET_GBE_FIELD(DOTCLK, M, val, timing->pll_m - 1);
0538 SET_GBE_FIELD(DOTCLK, N, val, timing->pll_n - 1);
0539 SET_GBE_FIELD(DOTCLK, P, val, timing->pll_p);
0540 SET_GBE_FIELD(DOTCLK, RUN, val, 0);
0541 gbe->dotclock = val;
0542 mdelay(10);
0543
0544
0545 val = 0;
0546 SET_GBE_FIELD(VT_XYMAX, MAXX, val, timing->htotal);
0547 SET_GBE_FIELD(VT_XYMAX, MAXY, val, timing->vtotal);
0548 gbe->vt_xymax = val;
0549
0550
0551 val = 0;
0552 SET_GBE_FIELD(VT_VSYNC, VSYNC_ON, val, timing->vsync_start);
0553 SET_GBE_FIELD(VT_VSYNC, VSYNC_OFF, val, timing->vsync_end);
0554 gbe->vt_vsync = val;
0555 val = 0;
0556 SET_GBE_FIELD(VT_HSYNC, HSYNC_ON, val, timing->hsync_start);
0557 SET_GBE_FIELD(VT_HSYNC, HSYNC_OFF, val, timing->hsync_end);
0558 gbe->vt_hsync = val;
0559 val = 0;
0560 SET_GBE_FIELD(VT_VBLANK, VBLANK_ON, val, timing->vblank_start);
0561 SET_GBE_FIELD(VT_VBLANK, VBLANK_OFF, val, timing->vblank_end);
0562 gbe->vt_vblank = val;
0563 val = 0;
0564 SET_GBE_FIELD(VT_HBLANK, HBLANK_ON, val,
0565 timing->hblank_start - 5);
0566 SET_GBE_FIELD(VT_HBLANK, HBLANK_OFF, val,
0567 timing->hblank_end - 3);
0568 gbe->vt_hblank = val;
0569
0570
0571 val = 0;
0572 SET_GBE_FIELD(VT_VCMAP, VCMAP_ON, val, timing->vblank_start);
0573 SET_GBE_FIELD(VT_VCMAP, VCMAP_OFF, val, timing->vblank_end);
0574 gbe->vt_vcmap = val;
0575 val = 0;
0576 SET_GBE_FIELD(VT_HCMAP, HCMAP_ON, val, timing->hblank_start);
0577 SET_GBE_FIELD(VT_HCMAP, HCMAP_OFF, val, timing->hblank_end);
0578 gbe->vt_hcmap = val;
0579
0580 val = 0;
0581 temp = timing->vblank_start - timing->vblank_end - 1;
0582 if (temp > 0)
0583 temp = -temp;
0584
0585 if (flat_panel_enabled)
0586 gbefb_setup_flatpanel(timing);
0587
0588 SET_GBE_FIELD(DID_START_XY, DID_STARTY, val, (u32) temp);
0589 if (timing->hblank_end >= 20)
0590 SET_GBE_FIELD(DID_START_XY, DID_STARTX, val,
0591 timing->hblank_end - 20);
0592 else
0593 SET_GBE_FIELD(DID_START_XY, DID_STARTX, val,
0594 timing->htotal - (20 - timing->hblank_end));
0595 gbe->did_start_xy = val;
0596
0597 val = 0;
0598 SET_GBE_FIELD(CRS_START_XY, CRS_STARTY, val, (u32) (temp + 1));
0599 if (timing->hblank_end >= GBE_CRS_MAGIC)
0600 SET_GBE_FIELD(CRS_START_XY, CRS_STARTX, val,
0601 timing->hblank_end - GBE_CRS_MAGIC);
0602 else
0603 SET_GBE_FIELD(CRS_START_XY, CRS_STARTX, val,
0604 timing->htotal - (GBE_CRS_MAGIC -
0605 timing->hblank_end));
0606 gbe->crs_start_xy = val;
0607
0608 val = 0;
0609 SET_GBE_FIELD(VC_START_XY, VC_STARTY, val, (u32) temp);
0610 SET_GBE_FIELD(VC_START_XY, VC_STARTX, val, timing->hblank_end - 4);
0611 gbe->vc_start_xy = val;
0612
0613 val = 0;
0614 temp = timing->hblank_end - GBE_PIXEN_MAGIC_ON;
0615 if (temp < 0)
0616 temp += timing->htotal;
0617
0618 SET_GBE_FIELD(VT_HPIXEN, HPIXEN_ON, val, temp);
0619 SET_GBE_FIELD(VT_HPIXEN, HPIXEN_OFF, val,
0620 ((temp + timing->width -
0621 GBE_PIXEN_MAGIC_OFF) % timing->htotal));
0622 gbe->vt_hpixen = val;
0623
0624 val = 0;
0625 SET_GBE_FIELD(VT_VPIXEN, VPIXEN_ON, val, timing->vblank_end);
0626 SET_GBE_FIELD(VT_VPIXEN, VPIXEN_OFF, val, timing->vblank_start);
0627 gbe->vt_vpixen = val;
0628
0629
0630 val = 0;
0631 SET_GBE_FIELD(VT_FLAGS, SYNC_LOW, val, 1);
0632 gbe->vt_flags = val;
0633 }
0634
0635
0636
0637
0638
0639 static int gbefb_set_par(struct fb_info *info)
0640 {
0641 int i;
0642 unsigned int val;
0643 int wholeTilesX, partTilesX, maxPixelsPerTileX;
0644 int height_pix;
0645 int xpmax, ypmax;
0646 int bytesPerPixel;
0647 struct gbefb_par *par = (struct gbefb_par *) info->par;
0648
0649 compute_gbe_timing(&info->var, &par->timing);
0650
0651 bytesPerPixel = info->var.bits_per_pixel / 8;
0652 info->fix.line_length = info->var.xres_virtual * bytesPerPixel;
0653 xpmax = par->timing.width;
0654 ypmax = par->timing.height;
0655
0656
0657 gbe_turn_off();
0658
0659
0660 gbe_set_timing_info(&par->timing);
0661
0662
0663 val = 0;
0664 switch (bytesPerPixel) {
0665 case 1:
0666 SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_I8);
0667 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
0668 break;
0669 case 2:
0670 SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_ARGB5);
0671 info->fix.visual = FB_VISUAL_TRUECOLOR;
0672 break;
0673 case 4:
0674 SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_RGB8);
0675 info->fix.visual = FB_VISUAL_TRUECOLOR;
0676 break;
0677 }
0678 SET_GBE_FIELD(WID, BUF, val, GBE_BMODE_BOTH);
0679
0680 for (i = 0; i < 32; i++)
0681 gbe->mode_regs[i] = val;
0682
0683
0684 gbe->vt_intr01 = 0xffffffff;
0685 gbe->vt_intr23 = 0xffffffff;
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720
0721
0722
0723
0724
0725
0726
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754 val = 0;
0755 SET_GBE_FIELD(FRM_CONTROL, FRM_TILE_PTR, val, gbe_tiles.dma >> 9);
0756 SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 0);
0757 SET_GBE_FIELD(FRM_CONTROL, FRM_LINEAR, val, 0);
0758 gbe->frm_control = val;
0759
0760 maxPixelsPerTileX = 512 / bytesPerPixel;
0761 wholeTilesX = 1;
0762 partTilesX = 0;
0763
0764
0765 val = 0;
0766 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_WIDTH_TILE, val, wholeTilesX);
0767 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_RHS, val, partTilesX);
0768
0769 switch (bytesPerPixel) {
0770 case 1:
0771 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
0772 GBE_FRM_DEPTH_8);
0773 break;
0774 case 2:
0775 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
0776 GBE_FRM_DEPTH_16);
0777 break;
0778 case 4:
0779 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
0780 GBE_FRM_DEPTH_32);
0781 break;
0782 }
0783 gbe->frm_size_tile = val;
0784
0785
0786 height_pix = xpmax * ypmax / maxPixelsPerTileX;
0787
0788 val = 0;
0789 SET_GBE_FIELD(FRM_SIZE_PIXEL, FB_HEIGHT_PIX, val, height_pix);
0790 gbe->frm_size_pixel = val;
0791
0792
0793 gbe->did_control = 0;
0794 gbe->ovr_width_tile = 0;
0795
0796
0797 gbe->crs_ctl = 0;
0798
0799
0800 gbe_turn_on();
0801
0802
0803 udelay(10);
0804 for (i = 0; i < 256; i++)
0805 gbe->gmap[i] = (i << 24) | (i << 16) | (i << 8);
0806
0807
0808 for (i = 0; i < 256; i++)
0809 gbe_cmap[i] = (i << 8) | (i << 16) | (i << 24);
0810
0811 gbe_loadcmap();
0812
0813 return 0;
0814 }
0815
0816 static void gbefb_encode_fix(struct fb_fix_screeninfo *fix,
0817 struct fb_var_screeninfo *var)
0818 {
0819 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
0820 strcpy(fix->id, "SGI GBE");
0821 fix->smem_start = (unsigned long) gbe_mem;
0822 fix->smem_len = gbe_mem_size;
0823 fix->type = FB_TYPE_PACKED_PIXELS;
0824 fix->type_aux = 0;
0825 fix->accel = FB_ACCEL_NONE;
0826 switch (var->bits_per_pixel) {
0827 case 8:
0828 fix->visual = FB_VISUAL_PSEUDOCOLOR;
0829 break;
0830 default:
0831 fix->visual = FB_VISUAL_TRUECOLOR;
0832 break;
0833 }
0834 fix->ywrapstep = 0;
0835 fix->xpanstep = 0;
0836 fix->ypanstep = 0;
0837 fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
0838 fix->mmio_start = GBE_BASE;
0839 fix->mmio_len = sizeof(struct sgi_gbe);
0840 }
0841
0842
0843
0844
0845
0846
0847
0848 static int gbefb_setcolreg(unsigned regno, unsigned red, unsigned green,
0849 unsigned blue, unsigned transp,
0850 struct fb_info *info)
0851 {
0852 int i;
0853
0854 if (regno > 255)
0855 return 1;
0856 red >>= 8;
0857 green >>= 8;
0858 blue >>= 8;
0859
0860 if (info->var.bits_per_pixel <= 8) {
0861 gbe_cmap[regno] = (red << 24) | (green << 16) | (blue << 8);
0862 if (gbe_turned_on) {
0863
0864 for (i = 0; i < 1000 && gbe->cm_fifo >= 63; i++)
0865 udelay(10);
0866 if (i == 1000) {
0867 printk(KERN_ERR "gbefb: cmap FIFO timeout\n");
0868 return 1;
0869 }
0870 gbe->cmap[regno] = gbe_cmap[regno];
0871 }
0872 } else if (regno < 16) {
0873 switch (info->var.bits_per_pixel) {
0874 case 15:
0875 case 16:
0876 red >>= 3;
0877 green >>= 3;
0878 blue >>= 3;
0879 pseudo_palette[regno] =
0880 (red << info->var.red.offset) |
0881 (green << info->var.green.offset) |
0882 (blue << info->var.blue.offset);
0883 break;
0884 case 32:
0885 pseudo_palette[regno] =
0886 (red << info->var.red.offset) |
0887 (green << info->var.green.offset) |
0888 (blue << info->var.blue.offset);
0889 break;
0890 }
0891 }
0892
0893 return 0;
0894 }
0895
0896
0897
0898
0899 static int gbefb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
0900 {
0901 unsigned int line_length;
0902 struct gbe_timing_info timing;
0903 int ret;
0904
0905
0906 if (var->bits_per_pixel <= 8)
0907 var->bits_per_pixel = 8;
0908 else if (var->bits_per_pixel <= 16)
0909 var->bits_per_pixel = 16;
0910 else if (var->bits_per_pixel <= 32)
0911 var->bits_per_pixel = 32;
0912 else
0913 return -EINVAL;
0914
0915
0916
0917 if ((var->xres * var->yres * var->bits_per_pixel) & 4095)
0918 return -EINVAL;
0919
0920 var->grayscale = 0;
0921
0922 ret = compute_gbe_timing(var, &timing);
0923 var->pixclock = ret;
0924 if (ret < 0)
0925 return -EINVAL;
0926
0927
0928 if (var->xres > var->xres_virtual || (!ywrap && !ypan))
0929 var->xres_virtual = var->xres;
0930 if (var->yres > var->yres_virtual || (!ywrap && !ypan))
0931 var->yres_virtual = var->yres;
0932
0933 if (var->vmode & FB_VMODE_CONUPDATE) {
0934 var->vmode |= FB_VMODE_YWRAP;
0935 var->xoffset = info->var.xoffset;
0936 var->yoffset = info->var.yoffset;
0937 }
0938
0939
0940 var->grayscale = 0;
0941
0942
0943 line_length = var->xres_virtual * var->bits_per_pixel / 8;
0944 if (line_length * var->yres_virtual > gbe_mem_size)
0945 return -ENOMEM;
0946
0947 switch (var->bits_per_pixel) {
0948 case 8:
0949 var->red.offset = 0;
0950 var->red.length = 8;
0951 var->green.offset = 0;
0952 var->green.length = 8;
0953 var->blue.offset = 0;
0954 var->blue.length = 8;
0955 var->transp.offset = 0;
0956 var->transp.length = 0;
0957 break;
0958 case 16:
0959 var->red.offset = 10;
0960 var->red.length = 5;
0961 var->green.offset = 5;
0962 var->green.length = 5;
0963 var->blue.offset = 0;
0964 var->blue.length = 5;
0965 var->transp.offset = 0;
0966 var->transp.length = 0;
0967 break;
0968 case 32:
0969 var->red.offset = 24;
0970 var->red.length = 8;
0971 var->green.offset = 16;
0972 var->green.length = 8;
0973 var->blue.offset = 8;
0974 var->blue.length = 8;
0975 var->transp.offset = 0;
0976 var->transp.length = 8;
0977 break;
0978 }
0979 var->red.msb_right = 0;
0980 var->green.msb_right = 0;
0981 var->blue.msb_right = 0;
0982 var->transp.msb_right = 0;
0983
0984 var->left_margin = timing.htotal - timing.hsync_end;
0985 var->right_margin = timing.hsync_start - timing.width;
0986 var->upper_margin = timing.vtotal - timing.vsync_end;
0987 var->lower_margin = timing.vsync_start - timing.height;
0988 var->hsync_len = timing.hsync_end - timing.hsync_start;
0989 var->vsync_len = timing.vsync_end - timing.vsync_start;
0990
0991 return 0;
0992 }
0993
0994 static int gbefb_mmap(struct fb_info *info,
0995 struct vm_area_struct *vma)
0996 {
0997 unsigned long size = vma->vm_end - vma->vm_start;
0998 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
0999 unsigned long addr;
1000 unsigned long phys_addr, phys_size;
1001 u16 *tile;
1002
1003
1004 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
1005 return -EINVAL;
1006 if (size > gbe_mem_size)
1007 return -EINVAL;
1008 if (offset > gbe_mem_size - size)
1009 return -EINVAL;
1010
1011
1012
1013 #ifdef CONFIG_MIPS
1014 pgprot_val(vma->vm_page_prot) =
1015 pgprot_fb(pgprot_val(vma->vm_page_prot));
1016 #endif
1017
1018
1019
1020 tile = &gbe_tiles.cpu[offset >> TILE_SHIFT];
1021 addr = vma->vm_start;
1022 offset &= TILE_MASK;
1023
1024
1025 do {
1026 phys_addr = (((unsigned long) (*tile)) << TILE_SHIFT) + offset;
1027 if ((offset + size) < TILE_SIZE)
1028 phys_size = size;
1029 else
1030 phys_size = TILE_SIZE - offset;
1031
1032 if (remap_pfn_range(vma, addr, phys_addr >> PAGE_SHIFT,
1033 phys_size, vma->vm_page_prot))
1034 return -EAGAIN;
1035
1036 offset = 0;
1037 size -= phys_size;
1038 addr += phys_size;
1039 tile++;
1040 } while (size);
1041
1042 return 0;
1043 }
1044
1045 static const struct fb_ops gbefb_ops = {
1046 .owner = THIS_MODULE,
1047 .fb_check_var = gbefb_check_var,
1048 .fb_set_par = gbefb_set_par,
1049 .fb_setcolreg = gbefb_setcolreg,
1050 .fb_mmap = gbefb_mmap,
1051 .fb_blank = gbefb_blank,
1052 .fb_fillrect = cfb_fillrect,
1053 .fb_copyarea = cfb_copyarea,
1054 .fb_imageblit = cfb_imageblit,
1055 };
1056
1057
1058
1059
1060
1061 static ssize_t gbefb_show_memsize(struct device *dev, struct device_attribute *attr, char *buf)
1062 {
1063 return snprintf(buf, PAGE_SIZE, "%u\n", gbe_mem_size);
1064 }
1065
1066 static DEVICE_ATTR(size, S_IRUGO, gbefb_show_memsize, NULL);
1067
1068 static ssize_t gbefb_show_rev(struct device *device, struct device_attribute *attr, char *buf)
1069 {
1070 return snprintf(buf, PAGE_SIZE, "%d\n", gbe_revision);
1071 }
1072
1073 static DEVICE_ATTR(revision, S_IRUGO, gbefb_show_rev, NULL);
1074
1075 static void gbefb_remove_sysfs(struct device *dev)
1076 {
1077 device_remove_file(dev, &dev_attr_size);
1078 device_remove_file(dev, &dev_attr_revision);
1079 }
1080
1081 static void gbefb_create_sysfs(struct device *dev)
1082 {
1083 device_create_file(dev, &dev_attr_size);
1084 device_create_file(dev, &dev_attr_revision);
1085 }
1086
1087
1088
1089
1090
1091 static int gbefb_setup(char *options)
1092 {
1093 char *this_opt;
1094
1095 if (!options || !*options)
1096 return 0;
1097
1098 while ((this_opt = strsep(&options, ",")) != NULL) {
1099 if (!strncmp(this_opt, "monitor:", 8)) {
1100 if (!strncmp(this_opt + 8, "crt", 3)) {
1101 flat_panel_enabled = 0;
1102 default_var = &default_var_CRT;
1103 default_mode = &default_mode_CRT;
1104 } else if (!strncmp(this_opt + 8, "1600sw", 6) ||
1105 !strncmp(this_opt + 8, "lcd", 3)) {
1106 flat_panel_enabled = 1;
1107 default_var = &default_var_LCD;
1108 default_mode = &default_mode_LCD;
1109 }
1110 } else if (!strncmp(this_opt, "mem:", 4)) {
1111 gbe_mem_size = memparse(this_opt + 4, &this_opt);
1112 if (gbe_mem_size > CONFIG_FB_GBE_MEM * 1024 * 1024)
1113 gbe_mem_size = CONFIG_FB_GBE_MEM * 1024 * 1024;
1114 if (gbe_mem_size < TILE_SIZE)
1115 gbe_mem_size = TILE_SIZE;
1116 } else
1117 mode_option = this_opt;
1118 }
1119 return 0;
1120 }
1121
1122 static int gbefb_probe(struct platform_device *p_dev)
1123 {
1124 int i, ret = 0;
1125 struct fb_info *info;
1126 struct gbefb_par *par;
1127 #ifndef MODULE
1128 char *options = NULL;
1129 #endif
1130
1131 info = framebuffer_alloc(sizeof(struct gbefb_par), &p_dev->dev);
1132 if (!info)
1133 return -ENOMEM;
1134
1135 #ifndef MODULE
1136 if (fb_get_options("gbefb", &options)) {
1137 ret = -ENODEV;
1138 goto out_release_framebuffer;
1139 }
1140 gbefb_setup(options);
1141 #endif
1142
1143 if (!request_mem_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
1144 printk(KERN_ERR "gbefb: couldn't reserve mmio region\n");
1145 ret = -EBUSY;
1146 goto out_release_framebuffer;
1147 }
1148
1149 gbe = (struct sgi_gbe *) devm_ioremap(&p_dev->dev, GBE_BASE,
1150 sizeof(struct sgi_gbe));
1151 if (!gbe) {
1152 printk(KERN_ERR "gbefb: couldn't map mmio region\n");
1153 ret = -ENXIO;
1154 goto out_release_mem_region;
1155 }
1156 gbe_revision = gbe->ctrlstat & 15;
1157
1158 gbe_tiles.cpu = dmam_alloc_coherent(&p_dev->dev,
1159 GBE_TLB_SIZE * sizeof(uint16_t),
1160 &gbe_tiles.dma, GFP_KERNEL);
1161 if (!gbe_tiles.cpu) {
1162 printk(KERN_ERR "gbefb: couldn't allocate tiles table\n");
1163 ret = -ENOMEM;
1164 goto out_release_mem_region;
1165 }
1166
1167 if (gbe_mem_phys) {
1168
1169 gbe_mem = devm_ioremap_wc(&p_dev->dev, gbe_mem_phys,
1170 gbe_mem_size);
1171 if (!gbe_mem) {
1172 printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
1173 ret = -ENOMEM;
1174 goto out_release_mem_region;
1175 }
1176
1177 gbe_dma_addr = 0;
1178 } else {
1179
1180
1181 gbe_mem = dmam_alloc_attrs(&p_dev->dev, gbe_mem_size,
1182 &gbe_dma_addr, GFP_KERNEL,
1183 DMA_ATTR_WRITE_COMBINE);
1184 if (!gbe_mem) {
1185 printk(KERN_ERR "gbefb: couldn't allocate framebuffer memory\n");
1186 ret = -ENOMEM;
1187 goto out_release_mem_region;
1188 }
1189
1190 gbe_mem_phys = (unsigned long) gbe_dma_addr;
1191 }
1192
1193 par = info->par;
1194 par->wc_cookie = arch_phys_wc_add(gbe_mem_phys, gbe_mem_size);
1195
1196
1197 for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++)
1198 gbe_tiles.cpu[i] = (gbe_mem_phys >> TILE_SHIFT) + i;
1199
1200 info->fbops = &gbefb_ops;
1201 info->pseudo_palette = pseudo_palette;
1202 info->flags = FBINFO_DEFAULT;
1203 info->screen_base = gbe_mem;
1204 fb_alloc_cmap(&info->cmap, 256, 0);
1205
1206
1207 gbe_reset();
1208
1209
1210 if (fb_find_mode(&par->var, info, mode_option, NULL, 0,
1211 default_mode, 8) == 0)
1212 par->var = *default_var;
1213 info->var = par->var;
1214 gbefb_check_var(&par->var, info);
1215 gbefb_encode_fix(&info->fix, &info->var);
1216
1217 if (register_framebuffer(info) < 0) {
1218 printk(KERN_ERR "gbefb: couldn't register framebuffer\n");
1219 ret = -ENXIO;
1220 goto out_gbe_unmap;
1221 }
1222
1223 platform_set_drvdata(p_dev, info);
1224 gbefb_create_sysfs(&p_dev->dev);
1225
1226 fb_info(info, "%s rev %d @ 0x%08x using %dkB memory\n",
1227 info->fix.id, gbe_revision, (unsigned)GBE_BASE,
1228 gbe_mem_size >> 10);
1229
1230 return 0;
1231
1232 out_gbe_unmap:
1233 arch_phys_wc_del(par->wc_cookie);
1234 out_release_mem_region:
1235 release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1236 out_release_framebuffer:
1237 framebuffer_release(info);
1238
1239 return ret;
1240 }
1241
1242 static int gbefb_remove(struct platform_device* p_dev)
1243 {
1244 struct fb_info *info = platform_get_drvdata(p_dev);
1245 struct gbefb_par *par = info->par;
1246
1247 unregister_framebuffer(info);
1248 gbe_turn_off();
1249 arch_phys_wc_del(par->wc_cookie);
1250 release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1251 gbefb_remove_sysfs(&p_dev->dev);
1252 framebuffer_release(info);
1253
1254 return 0;
1255 }
1256
1257 static struct platform_driver gbefb_driver = {
1258 .probe = gbefb_probe,
1259 .remove = gbefb_remove,
1260 .driver = {
1261 .name = "gbefb",
1262 },
1263 };
1264
1265 static struct platform_device *gbefb_device;
1266
1267 static int __init gbefb_init(void)
1268 {
1269 int ret = platform_driver_register(&gbefb_driver);
1270 if (IS_ENABLED(CONFIG_SGI_IP32) && !ret) {
1271 gbefb_device = platform_device_alloc("gbefb", 0);
1272 if (gbefb_device) {
1273 ret = platform_device_add(gbefb_device);
1274 } else {
1275 ret = -ENOMEM;
1276 }
1277 if (ret) {
1278 platform_device_put(gbefb_device);
1279 platform_driver_unregister(&gbefb_driver);
1280 }
1281 }
1282 return ret;
1283 }
1284
1285 static void __exit gbefb_exit(void)
1286 {
1287 platform_device_unregister(gbefb_device);
1288 platform_driver_unregister(&gbefb_driver);
1289 }
1290
1291 module_init(gbefb_init);
1292 module_exit(gbefb_exit);
1293
1294 MODULE_LICENSE("GPL");