1/* 2 * drivers/mb862xx/mb862xxfb.c 3 * 4 * Fujitsu Carmine/Coral-P(A)/Lime framebuffer driver 5 * 6 * (C) 2008 Anatolij Gustschin <agust@denx.de> 7 * DENX Software Engineering 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 * 13 */ 14 15#undef DEBUG 16 17#include <linux/fb.h> 18#include <linux/delay.h> 19#include <linux/init.h> 20#include <linux/interrupt.h> 21#include <linux/pci.h> 22#if defined(CONFIG_OF) 23#include <linux/of_platform.h> 24#endif 25#include "mb862xxfb.h" 26#include "mb862xx_reg.h" 27 28#define NR_PALETTE 256 29#define MB862XX_MEM_SIZE 0x1000000 30#define CORALP_MEM_SIZE 0x4000000 31#define CARMINE_MEM_SIZE 0x8000000 32#define DRV_NAME "mb862xxfb" 33 34#if defined(CONFIG_SOCRATES) 35static struct mb862xx_gc_mode socrates_gc_mode = { 36 /* Mode for Prime View PM070WL4 TFT LCD Panel */ 37 { "800x480", 45, 800, 480, 40000, 86, 42, 33, 10, 128, 2, 0, 0, 0 }, 38 /* 16 bits/pixel, 16MB, 133MHz, SDRAM memory mode value */ 39 16, 0x1000000, GC_CCF_COT_133, 0x4157ba63 40}; 41#endif 42 43/* Helpers */ 44static inline int h_total(struct fb_var_screeninfo *var) 45{ 46 return var->xres + var->left_margin + 47 var->right_margin + var->hsync_len; 48} 49 50static inline int v_total(struct fb_var_screeninfo *var) 51{ 52 return var->yres + var->upper_margin + 53 var->lower_margin + var->vsync_len; 54} 55 56static inline int hsp(struct fb_var_screeninfo *var) 57{ 58 return var->xres + var->right_margin - 1; 59} 60 61static inline int vsp(struct fb_var_screeninfo *var) 62{ 63 return var->yres + var->lower_margin - 1; 64} 65 66static inline int d_pitch(struct fb_var_screeninfo *var) 67{ 68 return var->xres * var->bits_per_pixel / 8; 69} 70 71static inline unsigned int chan_to_field(unsigned int chan, 72 struct fb_bitfield *bf) 73{ 74 chan &= 0xffff; 75 chan >>= 16 - bf->length; 76 return chan << bf->offset; 77} 78 79static int mb862xxfb_setcolreg(unsigned regno, 80 unsigned red, unsigned green, unsigned blue, 81 unsigned transp, struct fb_info *info) 82{ 83 struct mb862xxfb_par *par = info->par; 84 unsigned int val; 85 86 switch (info->fix.visual) { 87 case FB_VISUAL_TRUECOLOR: 88 if (regno < 16) { 89 val = chan_to_field(red, &info->var.red); 90 val |= chan_to_field(green, &info->var.green); 91 val |= chan_to_field(blue, &info->var.blue); 92 par->pseudo_palette[regno] = val; 93 } 94 break; 95 case FB_VISUAL_PSEUDOCOLOR: 96 if (regno < 256) { 97 val = (red >> 8) << 16; 98 val |= (green >> 8) << 8; 99 val |= blue >> 8; 100 outreg(disp, GC_L0PAL0 + (regno * 4), val); 101 } 102 break; 103 default: 104 return 1; /* unsupported type */ 105 } 106 return 0; 107} 108 109static int mb862xxfb_check_var(struct fb_var_screeninfo *var, 110 struct fb_info *fbi) 111{ 112 unsigned long tmp; 113 114 if (fbi->dev) 115 dev_dbg(fbi->dev, "%s\n", __func__); 116 117 /* check if these values fit into the registers */ 118 if (var->hsync_len > 255 || var->vsync_len > 255) 119 return -EINVAL; 120 121 if ((var->xres + var->right_margin) >= 4096) 122 return -EINVAL; 123 124 if ((var->yres + var->lower_margin) > 4096) 125 return -EINVAL; 126 127 if (h_total(var) > 4096 || v_total(var) > 4096) 128 return -EINVAL; 129 130 if (var->xres_virtual > 4096 || var->yres_virtual > 4096) 131 return -EINVAL; 132 133 if (var->bits_per_pixel <= 8) 134 var->bits_per_pixel = 8; 135 else if (var->bits_per_pixel <= 16) 136 var->bits_per_pixel = 16; 137 else if (var->bits_per_pixel <= 32) 138 var->bits_per_pixel = 32; 139 140 /* 141 * can cope with 8,16 or 24/32bpp if resulting 142 * pitch is divisible by 64 without remainder 143 */ 144 if (d_pitch(&fbi->var) % GC_L0M_L0W_UNIT) { 145 int r; 146 147 var->bits_per_pixel = 0; 148 do { 149 var->bits_per_pixel += 8; 150 r = d_pitch(&fbi->var) % GC_L0M_L0W_UNIT; 151 } while (r && var->bits_per_pixel <= 32); 152 153 if (d_pitch(&fbi->var) % GC_L0M_L0W_UNIT) 154 return -EINVAL; 155 } 156 157 /* line length is going to be 128 bit aligned */ 158 tmp = (var->xres * var->bits_per_pixel) / 8; 159 if ((tmp & 15) != 0) 160 return -EINVAL; 161 162 /* set r/g/b positions and validate bpp */ 163 switch (var->bits_per_pixel) { 164 case 8: 165 var->red.length = var->bits_per_pixel; 166 var->green.length = var->bits_per_pixel; 167 var->blue.length = var->bits_per_pixel; 168 var->red.offset = 0; 169 var->green.offset = 0; 170 var->blue.offset = 0; 171 var->transp.length = 0; 172 break; 173 case 16: 174 var->red.length = 5; 175 var->green.length = 5; 176 var->blue.length = 5; 177 var->red.offset = 10; 178 var->green.offset = 5; 179 var->blue.offset = 0; 180 var->transp.length = 0; 181 break; 182 case 24: 183 case 32: 184 var->transp.length = 8; 185 var->red.length = 8; 186 var->green.length = 8; 187 var->blue.length = 8; 188 var->transp.offset = 24; 189 var->red.offset = 16; 190 var->green.offset = 8; 191 var->blue.offset = 0; 192 break; 193 default: 194 return -EINVAL; 195 } 196 return 0; 197} 198 199/* 200 * set display parameters 201 */ 202static int mb862xxfb_set_par(struct fb_info *fbi) 203{ 204 struct mb862xxfb_par *par = fbi->par; 205 unsigned long reg, sc; 206 207 dev_dbg(par->dev, "%s\n", __func__); 208 if (par->type == BT_CORALP) 209 mb862xxfb_init_accel(fbi, fbi->var.xres); 210 211 if (par->pre_init) 212 return 0; 213 214 /* disp off */ 215 reg = inreg(disp, GC_DCM1); 216 reg &= ~GC_DCM01_DEN; 217 outreg(disp, GC_DCM1, reg); 218 219 /* set display reference clock div. */ 220 sc = par->refclk / (1000000 / fbi->var.pixclock) - 1; 221 reg = inreg(disp, GC_DCM1); 222 reg &= ~(GC_DCM01_CKS | GC_DCM01_RESV | GC_DCM01_SC); 223 reg |= sc << 8; 224 outreg(disp, GC_DCM1, reg); 225 dev_dbg(par->dev, "SC 0x%lx\n", sc); 226 227 /* disp dimension, format */ 228 reg = pack(d_pitch(&fbi->var) / GC_L0M_L0W_UNIT, 229 (fbi->var.yres - 1)); 230 if (fbi->var.bits_per_pixel == 16) 231 reg |= GC_L0M_L0C_16; 232 outreg(disp, GC_L0M, reg); 233 234 if (fbi->var.bits_per_pixel == 32) { 235 reg = inreg(disp, GC_L0EM); 236 outreg(disp, GC_L0EM, reg | GC_L0EM_L0EC_24); 237 } 238 outreg(disp, GC_WY_WX, 0); 239 reg = pack(fbi->var.yres - 1, fbi->var.xres); 240 outreg(disp, GC_WH_WW, reg); 241 outreg(disp, GC_L0OA0, 0); 242 outreg(disp, GC_L0DA0, 0); 243 outreg(disp, GC_L0DY_L0DX, 0); 244 outreg(disp, GC_L0WY_L0WX, 0); 245 outreg(disp, GC_L0WH_L0WW, reg); 246 247 /* both HW-cursors off */ 248 reg = inreg(disp, GC_CPM_CUTC); 249 reg &= ~(GC_CPM_CEN0 | GC_CPM_CEN1); 250 outreg(disp, GC_CPM_CUTC, reg); 251 252 /* timings */ 253 reg = pack(fbi->var.xres - 1, fbi->var.xres - 1); 254 outreg(disp, GC_HDB_HDP, reg); 255 reg = pack((fbi->var.yres - 1), vsp(&fbi->var)); 256 outreg(disp, GC_VDP_VSP, reg); 257 reg = ((fbi->var.vsync_len - 1) << 24) | 258 pack((fbi->var.hsync_len - 1), hsp(&fbi->var)); 259 outreg(disp, GC_VSW_HSW_HSP, reg); 260 outreg(disp, GC_HTP, pack(h_total(&fbi->var) - 1, 0)); 261 outreg(disp, GC_VTR, pack(v_total(&fbi->var) - 1, 0)); 262 263 /* display on */ 264 reg = inreg(disp, GC_DCM1); 265 reg |= GC_DCM01_DEN | GC_DCM01_L0E; 266 reg &= ~GC_DCM01_ESY; 267 outreg(disp, GC_DCM1, reg); 268 return 0; 269} 270 271static int mb862xxfb_pan(struct fb_var_screeninfo *var, 272 struct fb_info *info) 273{ 274 struct mb862xxfb_par *par = info->par; 275 unsigned long reg; 276 277 reg = pack(var->yoffset, var->xoffset); 278 outreg(disp, GC_L0WY_L0WX, reg); 279 280 reg = pack(var->yres_virtual, var->xres_virtual); 281 outreg(disp, GC_L0WH_L0WW, reg); 282 return 0; 283} 284 285static int mb862xxfb_blank(int mode, struct fb_info *fbi) 286{ 287 struct mb862xxfb_par *par = fbi->par; 288 unsigned long reg; 289 290 dev_dbg(fbi->dev, "blank mode=%d\n", mode); 291 292 switch (mode) { 293 case FB_BLANK_POWERDOWN: 294 reg = inreg(disp, GC_DCM1); 295 reg &= ~GC_DCM01_DEN; 296 outreg(disp, GC_DCM1, reg); 297 break; 298 case FB_BLANK_UNBLANK: 299 reg = inreg(disp, GC_DCM1); 300 reg |= GC_DCM01_DEN; 301 outreg(disp, GC_DCM1, reg); 302 break; 303 case FB_BLANK_NORMAL: 304 case FB_BLANK_VSYNC_SUSPEND: 305 case FB_BLANK_HSYNC_SUSPEND: 306 default: 307 return 1; 308 } 309 return 0; 310} 311 312/* framebuffer ops */ 313static struct fb_ops mb862xxfb_ops = { 314 .owner = THIS_MODULE, 315 .fb_check_var = mb862xxfb_check_var, 316 .fb_set_par = mb862xxfb_set_par, 317 .fb_setcolreg = mb862xxfb_setcolreg, 318 .fb_blank = mb862xxfb_blank, 319 .fb_pan_display = mb862xxfb_pan, 320 .fb_fillrect = cfb_fillrect, 321 .fb_copyarea = cfb_copyarea, 322 .fb_imageblit = cfb_imageblit, 323}; 324 325/* initialize fb_info data */ 326static int mb862xxfb_init_fbinfo(struct fb_info *fbi) 327{ 328 struct mb862xxfb_par *par = fbi->par; 329 struct mb862xx_gc_mode *mode = par->gc_mode; 330 unsigned long reg; 331 332 fbi->fbops = &mb862xxfb_ops; 333 fbi->pseudo_palette = par->pseudo_palette; 334 fbi->screen_base = par->fb_base; 335 fbi->screen_size = par->mapped_vram; 336 337 strcpy(fbi->fix.id, DRV_NAME); 338 fbi->fix.smem_start = (unsigned long)par->fb_base_phys; 339 fbi->fix.smem_len = par->mapped_vram; 340 fbi->fix.mmio_start = (unsigned long)par->mmio_base_phys; 341 fbi->fix.mmio_len = par->mmio_len; 342 fbi->fix.accel = FB_ACCEL_NONE; 343 fbi->fix.type = FB_TYPE_PACKED_PIXELS; 344 fbi->fix.type_aux = 0; 345 fbi->fix.xpanstep = 1; 346 fbi->fix.ypanstep = 1; 347 fbi->fix.ywrapstep = 0; 348 349 reg = inreg(disp, GC_DCM1); 350 if (reg & GC_DCM01_DEN && reg & GC_DCM01_L0E) { 351 /* get the disp mode from active display cfg */ 352 unsigned long sc = ((reg & GC_DCM01_SC) >> 8) + 1; 353 unsigned long hsp, vsp, ht, vt; 354 355 dev_dbg(par->dev, "using bootloader's disp. mode\n"); 356 fbi->var.pixclock = (sc * 1000000) / par->refclk; 357 fbi->var.xres = (inreg(disp, GC_HDB_HDP) & 0x0fff) + 1; 358 reg = inreg(disp, GC_VDP_VSP); 359 fbi->var.yres = ((reg >> 16) & 0x0fff) + 1; 360 vsp = (reg & 0x0fff) + 1; 361 fbi->var.xres_virtual = fbi->var.xres; 362 fbi->var.yres_virtual = fbi->var.yres; 363 reg = inreg(disp, GC_L0EM); 364 if (reg & GC_L0EM_L0EC_24) { 365 fbi->var.bits_per_pixel = 32; 366 } else { 367 reg = inreg(disp, GC_L0M); 368 if (reg & GC_L0M_L0C_16) 369 fbi->var.bits_per_pixel = 16; 370 else 371 fbi->var.bits_per_pixel = 8; 372 } 373 reg = inreg(disp, GC_VSW_HSW_HSP); 374 fbi->var.hsync_len = ((reg & 0xff0000) >> 16) + 1; 375 fbi->var.vsync_len = ((reg & 0x3f000000) >> 24) + 1; 376 hsp = (reg & 0xffff) + 1; 377 ht = ((inreg(disp, GC_HTP) & 0xfff0000) >> 16) + 1; 378 fbi->var.right_margin = hsp - fbi->var.xres; 379 fbi->var.left_margin = ht - hsp - fbi->var.hsync_len; 380 vt = ((inreg(disp, GC_VTR) & 0xfff0000) >> 16) + 1; 381 fbi->var.lower_margin = vsp - fbi->var.yres; 382 fbi->var.upper_margin = vt - vsp - fbi->var.vsync_len; 383 } else if (mode) { 384 dev_dbg(par->dev, "using supplied mode\n"); 385 fb_videomode_to_var(&fbi->var, (struct fb_videomode *)mode); 386 fbi->var.bits_per_pixel = mode->def_bpp ? mode->def_bpp : 8; 387 } else { 388 int ret; 389 390 ret = fb_find_mode(&fbi->var, fbi, "640x480-16@60", 391 NULL, 0, NULL, 16); 392 if (ret == 0 || ret == 4) { 393 dev_err(par->dev, 394 "failed to get initial mode\n"); 395 return -EINVAL; 396 } 397 } 398 399 fbi->var.xoffset = 0; 400 fbi->var.yoffset = 0; 401 fbi->var.grayscale = 0; 402 fbi->var.nonstd = 0; 403 fbi->var.height = -1; 404 fbi->var.width = -1; 405 fbi->var.accel_flags = 0; 406 fbi->var.vmode = FB_VMODE_NONINTERLACED; 407 fbi->var.activate = FB_ACTIVATE_NOW; 408 fbi->flags = FBINFO_DEFAULT | 409#ifdef __BIG_ENDIAN 410 FBINFO_FOREIGN_ENDIAN | 411#endif 412 FBINFO_HWACCEL_XPAN | 413 FBINFO_HWACCEL_YPAN; 414 415 /* check and possibly fix bpp */ 416 if ((fbi->fbops->fb_check_var)(&fbi->var, fbi)) 417 dev_err(par->dev, "check_var() failed on initial setup?\n"); 418 419 fbi->fix.visual = fbi->var.bits_per_pixel == 8 ? 420 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; 421 fbi->fix.line_length = (fbi->var.xres_virtual * 422 fbi->var.bits_per_pixel) / 8; 423 return 0; 424} 425 426/* 427 * show some display controller and cursor registers 428 */ 429static ssize_t mb862xxfb_show_dispregs(struct device *dev, 430 struct device_attribute *attr, char *buf) 431{ 432 struct fb_info *fbi = dev_get_drvdata(dev); 433 struct mb862xxfb_par *par = fbi->par; 434 char *ptr = buf; 435 unsigned int reg; 436 437 for (reg = GC_DCM0; reg <= GC_L0DY_L0DX; reg += 4) 438 ptr += sprintf(ptr, "%08x = %08x\n", 439 reg, inreg(disp, reg)); 440 441 for (reg = GC_CPM_CUTC; reg <= GC_CUY1_CUX1; reg += 4) 442 ptr += sprintf(ptr, "%08x = %08x\n", 443 reg, inreg(disp, reg)); 444 445 for (reg = GC_DCM1; reg <= GC_L0WH_L0WW; reg += 4) 446 ptr += sprintf(ptr, "%08x = %08x\n", 447 reg, inreg(disp, reg)); 448 449 for (reg = 0x400; reg <= 0x410; reg += 4) 450 ptr += sprintf(ptr, "geo %08x = %08x\n", 451 reg, inreg(geo, reg)); 452 453 for (reg = 0x400; reg <= 0x410; reg += 4) 454 ptr += sprintf(ptr, "draw %08x = %08x\n", 455 reg, inreg(draw, reg)); 456 457 for (reg = 0x440; reg <= 0x450; reg += 4) 458 ptr += sprintf(ptr, "draw %08x = %08x\n", 459 reg, inreg(draw, reg)); 460 461 return ptr - buf; 462} 463 464static DEVICE_ATTR(dispregs, 0444, mb862xxfb_show_dispregs, NULL); 465 466irqreturn_t mb862xx_intr(int irq, void *dev_id) 467{ 468 struct mb862xxfb_par *par = (struct mb862xxfb_par *) dev_id; 469 unsigned long reg_ist, mask; 470 471 if (!par) 472 return IRQ_NONE; 473 474 if (par->type == BT_CARMINE) { 475 /* Get Interrupt Status */ 476 reg_ist = inreg(ctrl, GC_CTRL_STATUS); 477 mask = inreg(ctrl, GC_CTRL_INT_MASK); 478 if (reg_ist == 0) 479 return IRQ_HANDLED; 480 481 reg_ist &= mask; 482 if (reg_ist == 0) 483 return IRQ_HANDLED; 484 485 /* Clear interrupt status */ 486 outreg(ctrl, 0x0, reg_ist); 487 } else { 488 /* Get status */ 489 reg_ist = inreg(host, GC_IST); 490 mask = inreg(host, GC_IMASK); 491 492 reg_ist &= mask; 493 if (reg_ist == 0) 494 return IRQ_HANDLED; 495 496 /* Clear status */ 497 outreg(host, GC_IST, ~reg_ist); 498 } 499 return IRQ_HANDLED; 500} 501 502#if defined(CONFIG_FB_MB862XX_LIME) 503/* 504 * GDC (Lime, Coral(B/Q), Mint, ...) on host bus 505 */ 506static int mb862xx_gdc_init(struct mb862xxfb_par *par) 507{ 508 unsigned long ccf, mmr; 509 unsigned long ver, rev; 510 511 if (!par) 512 return -ENODEV; 513 514#if defined(CONFIG_FB_PRE_INIT_FB) 515 par->pre_init = 1; 516#endif 517 par->host = par->mmio_base; 518 par->i2c = par->mmio_base + MB862XX_I2C_BASE; 519 par->disp = par->mmio_base + MB862XX_DISP_BASE; 520 par->cap = par->mmio_base + MB862XX_CAP_BASE; 521 par->draw = par->mmio_base + MB862XX_DRAW_BASE; 522 par->geo = par->mmio_base + MB862XX_GEO_BASE; 523 par->pio = par->mmio_base + MB862XX_PIO_BASE; 524 525 par->refclk = GC_DISP_REFCLK_400; 526 527 ver = inreg(host, GC_CID); 528 rev = inreg(pio, GC_REVISION); 529 if ((ver == 0x303) && (rev & 0xffffff00) == 0x20050100) { 530 dev_info(par->dev, "Fujitsu Lime v1.%d found\n", 531 (int)rev & 0xff); 532 par->type = BT_LIME; 533 ccf = par->gc_mode ? par->gc_mode->ccf : GC_CCF_COT_100; 534 mmr = par->gc_mode ? par->gc_mode->mmr : 0x414fb7f2; 535 } else { 536 dev_info(par->dev, "? GDC, CID/Rev.: 0x%lx/0x%lx \n", ver, rev); 537 return -ENODEV; 538 } 539 540 if (!par->pre_init) { 541 outreg(host, GC_CCF, ccf); 542 udelay(200); 543 outreg(host, GC_MMR, mmr); 544 udelay(10); 545 } 546 547 /* interrupt status */ 548 outreg(host, GC_IST, 0); 549 outreg(host, GC_IMASK, GC_INT_EN); 550 return 0; 551} 552 553static int __devinit of_platform_mb862xx_probe(struct platform_device *ofdev, 554 const struct of_device_id *id) 555{ 556 struct device_node *np = ofdev->dev.of_node; 557 struct device *dev = &ofdev->dev; 558 struct mb862xxfb_par *par; 559 struct fb_info *info; 560 struct resource res; 561 resource_size_t res_size; 562 unsigned long ret = -ENODEV; 563 564 if (of_address_to_resource(np, 0, &res)) { 565 dev_err(dev, "Invalid address\n"); 566 return -ENXIO; 567 } 568 569 info = framebuffer_alloc(sizeof(struct mb862xxfb_par), dev); 570 if (info == NULL) { 571 dev_err(dev, "cannot allocate framebuffer\n"); 572 return -ENOMEM; 573 } 574 575 par = info->par; 576 par->info = info; 577 par->dev = dev; 578 579 par->irq = irq_of_parse_and_map(np, 0); 580 if (par->irq == NO_IRQ) { 581 dev_err(dev, "failed to map irq\n"); 582 ret = -ENODEV; 583 goto fbrel; 584 } 585 586 res_size = 1 + res.end - res.start; 587 par->res = request_mem_region(res.start, res_size, DRV_NAME); 588 if (par->res == NULL) { 589 dev_err(dev, "Cannot claim framebuffer/mmio\n"); 590 ret = -ENXIO; 591 goto irqdisp; 592 } 593 594#if defined(CONFIG_SOCRATES) 595 par->gc_mode = &socrates_gc_mode; 596#endif 597 598 par->fb_base_phys = res.start; 599 par->mmio_base_phys = res.start + MB862XX_MMIO_BASE; 600 par->mmio_len = MB862XX_MMIO_SIZE; 601 if (par->gc_mode) 602 par->mapped_vram = par->gc_mode->max_vram; 603 else 604 par->mapped_vram = MB862XX_MEM_SIZE; 605 606 par->fb_base = ioremap(par->fb_base_phys, par->mapped_vram); 607 if (par->fb_base == NULL) { 608 dev_err(dev, "Cannot map framebuffer\n"); 609 goto rel_reg; 610 } 611 612 par->mmio_base = ioremap(par->mmio_base_phys, par->mmio_len); 613 if (par->mmio_base == NULL) { 614 dev_err(dev, "Cannot map registers\n"); 615 goto fb_unmap; 616 } 617 618 dev_dbg(dev, "fb phys 0x%llx 0x%lx\n", 619 (u64)par->fb_base_phys, (ulong)par->mapped_vram); 620 dev_dbg(dev, "mmio phys 0x%llx 0x%lx, (irq = %d)\n", 621 (u64)par->mmio_base_phys, (ulong)par->mmio_len, par->irq); 622 623 if (mb862xx_gdc_init(par)) 624 goto io_unmap; 625 626 if (request_irq(par->irq, mb862xx_intr, IRQF_DISABLED, 627 DRV_NAME, (void *)par)) { 628 dev_err(dev, "Cannot request irq\n"); 629 goto io_unmap; 630 } 631 632 mb862xxfb_init_fbinfo(info); 633 634 if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0) < 0) { 635 dev_err(dev, "Could not allocate cmap for fb_info.\n"); 636 goto free_irq; 637 } 638 639 if ((info->fbops->fb_set_par)(info)) 640 dev_err(dev, "set_var() failed on initial setup?\n"); 641 642 if (register_framebuffer(info)) { 643 dev_err(dev, "failed to register framebuffer\n"); 644 goto rel_cmap; 645 } 646 647 dev_set_drvdata(dev, info); 648 649 if (device_create_file(dev, &dev_attr_dispregs)) 650 dev_err(dev, "Can't create sysfs regdump file\n"); 651 return 0; 652 653rel_cmap: 654 fb_dealloc_cmap(&info->cmap); 655free_irq: 656 outreg(host, GC_IMASK, 0); 657 free_irq(par->irq, (void *)par); 658io_unmap: 659 iounmap(par->mmio_base); 660fb_unmap: 661 iounmap(par->fb_base); 662rel_reg: 663 release_mem_region(res.start, res_size); 664irqdisp: 665 irq_dispose_mapping(par->irq); 666fbrel: 667 dev_set_drvdata(dev, NULL); 668 framebuffer_release(info); 669 return ret; 670} 671 672static int __devexit of_platform_mb862xx_remove(struct platform_device *ofdev) 673{ 674 struct fb_info *fbi = dev_get_drvdata(&ofdev->dev); 675 struct mb862xxfb_par *par = fbi->par; 676 resource_size_t res_size = 1 + par->res->end - par->res->start; 677 unsigned long reg; 678 679 dev_dbg(fbi->dev, "%s release\n", fbi->fix.id); 680 681 /* display off */ 682 reg = inreg(disp, GC_DCM1); 683 reg &= ~(GC_DCM01_DEN | GC_DCM01_L0E); 684 outreg(disp, GC_DCM1, reg); 685 686 /* disable interrupts */ 687 outreg(host, GC_IMASK, 0); 688 689 free_irq(par->irq, (void *)par); 690 irq_dispose_mapping(par->irq); 691 692 device_remove_file(&ofdev->dev, &dev_attr_dispregs); 693 694 unregister_framebuffer(fbi); 695 fb_dealloc_cmap(&fbi->cmap); 696 697 iounmap(par->mmio_base); 698 iounmap(par->fb_base); 699 700 dev_set_drvdata(&ofdev->dev, NULL); 701 release_mem_region(par->res->start, res_size); 702 framebuffer_release(fbi); 703 return 0; 704} 705 706/* 707 * common types 708 */ 709static struct of_device_id __devinitdata of_platform_mb862xx_tbl[] = { 710 { .compatible = "fujitsu,MB86276", }, 711 { .compatible = "fujitsu,lime", }, 712 { .compatible = "fujitsu,MB86277", }, 713 { .compatible = "fujitsu,mint", }, 714 { .compatible = "fujitsu,MB86293", }, 715 { .compatible = "fujitsu,MB86294", }, 716 { .compatible = "fujitsu,coral", }, 717 { /* end */ } 718}; 719 720static struct of_platform_driver of_platform_mb862xxfb_driver = { 721 .driver = { 722 .name = DRV_NAME, 723 .owner = THIS_MODULE, 724 .of_match_table = of_platform_mb862xx_tbl, 725 }, 726 .probe = of_platform_mb862xx_probe, 727 .remove = __devexit_p(of_platform_mb862xx_remove), 728}; 729#endif 730 731#if defined(CONFIG_FB_MB862XX_PCI_GDC) 732static int coralp_init(struct mb862xxfb_par *par) 733{ 734 int cn, ver; 735 736 par->host = par->mmio_base; 737 par->i2c = par->mmio_base + MB862XX_I2C_BASE; 738 par->disp = par->mmio_base + MB862XX_DISP_BASE; 739 par->cap = par->mmio_base + MB862XX_CAP_BASE; 740 par->draw = par->mmio_base + MB862XX_DRAW_BASE; 741 par->geo = par->mmio_base + MB862XX_GEO_BASE; 742 par->pio = par->mmio_base + MB862XX_PIO_BASE; 743 744 par->refclk = GC_DISP_REFCLK_400; 745 746 ver = inreg(host, GC_CID); 747 cn = (ver & GC_CID_CNAME_MSK) >> 8; 748 ver = ver & GC_CID_VERSION_MSK; 749 if (cn == 3) { 750 dev_info(par->dev, "Fujitsu Coral-%s GDC Rev.%d found\n",\ 751 (ver == 6) ? "P" : (ver == 8) ? "PA" : "?", 752 par->pdev->revision); 753 outreg(host, GC_CCF, GC_CCF_CGE_166 | GC_CCF_COT_133); 754 udelay(200); 755 outreg(host, GC_MMR, GC_MMR_CORALP_EVB_VAL); 756 udelay(10); 757 /* Clear interrupt status */ 758 outreg(host, GC_IST, 0); 759 } else { 760 return -ENODEV; 761 } 762 return 0; 763} 764 765static int init_dram_ctrl(struct mb862xxfb_par *par) 766{ 767 unsigned long i = 0; 768 769 /* 770 * Set io mode first! Spec. says IC may be destroyed 771 * if not set to SSTL2/LVCMOS before init. 772 */ 773 outreg(dram_ctrl, GC_DCTL_IOCONT1_IOCONT0, GC_EVB_DCTL_IOCONT1_IOCONT0); 774 775 /* DRAM init */ 776 outreg(dram_ctrl, GC_DCTL_MODE_ADD, GC_EVB_DCTL_MODE_ADD); 777 outreg(dram_ctrl, GC_DCTL_SETTIME1_EMODE, GC_EVB_DCTL_SETTIME1_EMODE); 778 outreg(dram_ctrl, GC_DCTL_REFRESH_SETTIME2, 779 GC_EVB_DCTL_REFRESH_SETTIME2); 780 outreg(dram_ctrl, GC_DCTL_RSV2_RSV1, GC_EVB_DCTL_RSV2_RSV1); 781 outreg(dram_ctrl, GC_DCTL_DDRIF2_DDRIF1, GC_EVB_DCTL_DDRIF2_DDRIF1); 782 outreg(dram_ctrl, GC_DCTL_RSV0_STATES, GC_EVB_DCTL_RSV0_STATES); 783 784 /* DLL reset done? */ 785 while ((inreg(dram_ctrl, GC_DCTL_RSV0_STATES) & GC_DCTL_STATES_MSK)) { 786 udelay(GC_DCTL_INIT_WAIT_INTERVAL); 787 if (i++ > GC_DCTL_INIT_WAIT_CNT) { 788 dev_err(par->dev, "VRAM init failed.\n"); 789 return -EINVAL; 790 } 791 } 792 outreg(dram_ctrl, GC_DCTL_MODE_ADD, GC_EVB_DCTL_MODE_ADD_AFT_RST); 793 outreg(dram_ctrl, GC_DCTL_RSV0_STATES, GC_EVB_DCTL_RSV0_STATES_AFT_RST); 794 return 0; 795} 796 797static int carmine_init(struct mb862xxfb_par *par) 798{ 799 unsigned long reg; 800 801 par->ctrl = par->mmio_base + MB86297_CTRL_BASE; 802 par->i2c = par->mmio_base + MB86297_I2C_BASE; 803 par->disp = par->mmio_base + MB86297_DISP0_BASE; 804 par->disp1 = par->mmio_base + MB86297_DISP1_BASE; 805 par->cap = par->mmio_base + MB86297_CAP0_BASE; 806 par->cap1 = par->mmio_base + MB86297_CAP1_BASE; 807 par->draw = par->mmio_base + MB86297_DRAW_BASE; 808 par->dram_ctrl = par->mmio_base + MB86297_DRAMCTRL_BASE; 809 par->wrback = par->mmio_base + MB86297_WRBACK_BASE; 810 811 par->refclk = GC_DISP_REFCLK_533; 812 813 /* warm up */ 814 reg = GC_CTRL_CLK_EN_DRAM | GC_CTRL_CLK_EN_2D3D | GC_CTRL_CLK_EN_DISP0; 815 outreg(ctrl, GC_CTRL_CLK_ENABLE, reg); 816 817 /* check for engine module revision */ 818 if (inreg(draw, GC_2D3D_REV) == GC_RE_REVISION) 819 dev_info(par->dev, "Fujitsu Carmine GDC Rev.%d found\n", 820 par->pdev->revision); 821 else 822 goto err_init; 823 824 reg &= ~GC_CTRL_CLK_EN_2D3D; 825 outreg(ctrl, GC_CTRL_CLK_ENABLE, reg); 826 827 /* set up vram */ 828 if (init_dram_ctrl(par) < 0) 829 goto err_init; 830 831 outreg(ctrl, GC_CTRL_INT_MASK, 0); 832 return 0; 833 834err_init: 835 outreg(ctrl, GC_CTRL_CLK_ENABLE, 0); 836 return -EINVAL; 837} 838 839static inline int mb862xx_pci_gdc_init(struct mb862xxfb_par *par) 840{ 841 switch (par->type) { 842 case BT_CORALP: 843 return coralp_init(par); 844 case BT_CARMINE: 845 return carmine_init(par); 846 default: 847 return -ENODEV; 848 } 849} 850 851#define CHIP_ID(id) \ 852 { PCI_DEVICE(PCI_VENDOR_ID_FUJITSU_LIMITED, id) } 853 854static struct pci_device_id mb862xx_pci_tbl[] __devinitdata = { 855 /* MB86295/MB86296 */ 856 CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALP), 857 CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALPA), 858 /* MB86297 */ 859 CHIP_ID(PCI_DEVICE_ID_FUJITSU_CARMINE), 860 { 0, } 861}; 862 863MODULE_DEVICE_TABLE(pci, mb862xx_pci_tbl); 864 865static int __devinit mb862xx_pci_probe(struct pci_dev *pdev, 866 const struct pci_device_id *ent) 867{ 868 struct mb862xxfb_par *par; 869 struct fb_info *info; 870 struct device *dev = &pdev->dev; 871 int ret; 872 873 ret = pci_enable_device(pdev); 874 if (ret < 0) { 875 dev_err(dev, "Cannot enable PCI device\n"); 876 goto out; 877 } 878 879 info = framebuffer_alloc(sizeof(struct mb862xxfb_par), dev); 880 if (!info) { 881 dev_err(dev, "framebuffer alloc failed\n"); 882 ret = -ENOMEM; 883 goto dis_dev; 884 } 885 886 par = info->par; 887 par->info = info; 888 par->dev = dev; 889 par->pdev = pdev; 890 par->irq = pdev->irq; 891 892 ret = pci_request_regions(pdev, DRV_NAME); 893 if (ret < 0) { 894 dev_err(dev, "Cannot reserve region(s) for PCI device\n"); 895 goto rel_fb; 896 } 897 898 switch (pdev->device) { 899 case PCI_DEVICE_ID_FUJITSU_CORALP: 900 case PCI_DEVICE_ID_FUJITSU_CORALPA: 901 par->fb_base_phys = pci_resource_start(par->pdev, 0); 902 par->mapped_vram = CORALP_MEM_SIZE; 903 par->mmio_base_phys = par->fb_base_phys + MB862XX_MMIO_BASE; 904 par->mmio_len = MB862XX_MMIO_SIZE; 905 par->type = BT_CORALP; 906 break; 907 case PCI_DEVICE_ID_FUJITSU_CARMINE: 908 par->fb_base_phys = pci_resource_start(par->pdev, 2); 909 par->mmio_base_phys = pci_resource_start(par->pdev, 3); 910 par->mmio_len = pci_resource_len(par->pdev, 3); 911 par->mapped_vram = CARMINE_MEM_SIZE; 912 par->type = BT_CARMINE; 913 break; 914 default: 915 /* should never occur */ 916 goto rel_reg; 917 } 918 919 par->fb_base = ioremap(par->fb_base_phys, par->mapped_vram); 920 if (par->fb_base == NULL) { 921 dev_err(dev, "Cannot map framebuffer\n"); 922 goto rel_reg; 923 } 924 925 par->mmio_base = ioremap(par->mmio_base_phys, par->mmio_len); 926 if (par->mmio_base == NULL) { 927 dev_err(dev, "Cannot map registers\n"); 928 ret = -EIO; 929 goto fb_unmap; 930 } 931 932 dev_dbg(dev, "fb phys 0x%llx 0x%lx\n", 933 (unsigned long long)par->fb_base_phys, (ulong)par->mapped_vram); 934 dev_dbg(dev, "mmio phys 0x%llx 0x%lx\n", 935 (unsigned long long)par->mmio_base_phys, (ulong)par->mmio_len); 936 937 if (mb862xx_pci_gdc_init(par)) 938 goto io_unmap; 939 940 if (request_irq(par->irq, mb862xx_intr, IRQF_DISABLED | IRQF_SHARED, 941 DRV_NAME, (void *)par)) { 942 dev_err(dev, "Cannot request irq\n"); 943 goto io_unmap; 944 } 945 946 mb862xxfb_init_fbinfo(info); 947 948 if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0) < 0) { 949 dev_err(dev, "Could not allocate cmap for fb_info.\n"); 950 ret = -ENOMEM; 951 goto free_irq; 952 } 953 954 if ((info->fbops->fb_set_par)(info)) 955 dev_err(dev, "set_var() failed on initial setup?\n"); 956 957 ret = register_framebuffer(info); 958 if (ret < 0) { 959 dev_err(dev, "failed to register framebuffer\n"); 960 goto rel_cmap; 961 } 962 963 pci_set_drvdata(pdev, info); 964 965 if (device_create_file(dev, &dev_attr_dispregs)) 966 dev_err(dev, "Can't create sysfs regdump file\n"); 967 968 if (par->type == BT_CARMINE) 969 outreg(ctrl, GC_CTRL_INT_MASK, GC_CARMINE_INT_EN); 970 else 971 outreg(host, GC_IMASK, GC_INT_EN); 972 973 return 0; 974 975rel_cmap: 976 fb_dealloc_cmap(&info->cmap); 977free_irq: 978 free_irq(par->irq, (void *)par); 979io_unmap: 980 iounmap(par->mmio_base); 981fb_unmap: 982 iounmap(par->fb_base); 983rel_reg: 984 pci_release_regions(pdev); 985rel_fb: 986 framebuffer_release(info); 987dis_dev: 988 pci_disable_device(pdev); 989out: 990 return ret; 991} 992 993static void __devexit mb862xx_pci_remove(struct pci_dev *pdev) 994{ 995 struct fb_info *fbi = pci_get_drvdata(pdev); 996 struct mb862xxfb_par *par = fbi->par; 997 unsigned long reg; 998 999 dev_dbg(fbi->dev, "%s release\n", fbi->fix.id); 1000 1001 /* display off */ 1002 reg = inreg(disp, GC_DCM1); 1003 reg &= ~(GC_DCM01_DEN | GC_DCM01_L0E); 1004 outreg(disp, GC_DCM1, reg); 1005 1006 if (par->type == BT_CARMINE) { 1007 outreg(ctrl, GC_CTRL_INT_MASK, 0); 1008 outreg(ctrl, GC_CTRL_CLK_ENABLE, 0); 1009 } else { 1010 outreg(host, GC_IMASK, 0); 1011 } 1012 1013 device_remove_file(&pdev->dev, &dev_attr_dispregs); 1014 1015 pci_set_drvdata(pdev, NULL); 1016 unregister_framebuffer(fbi); 1017 fb_dealloc_cmap(&fbi->cmap); 1018 1019 free_irq(par->irq, (void *)par); 1020 iounmap(par->mmio_base); 1021 iounmap(par->fb_base); 1022 1023 pci_release_regions(pdev); 1024 framebuffer_release(fbi); 1025 pci_disable_device(pdev); 1026} 1027 1028static struct pci_driver mb862xxfb_pci_driver = { 1029 .name = DRV_NAME, 1030 .id_table = mb862xx_pci_tbl, 1031 .probe = mb862xx_pci_probe, 1032 .remove = __devexit_p(mb862xx_pci_remove), 1033}; 1034#endif 1035 1036static int __devinit mb862xxfb_init(void) 1037{ 1038 int ret = -ENODEV; 1039 1040#if defined(CONFIG_FB_MB862XX_LIME) 1041 ret = of_register_platform_driver(&of_platform_mb862xxfb_driver); 1042#endif 1043#if defined(CONFIG_FB_MB862XX_PCI_GDC) 1044 ret = pci_register_driver(&mb862xxfb_pci_driver); 1045#endif 1046 return ret; 1047} 1048 1049static void __exit mb862xxfb_exit(void) 1050{ 1051#if defined(CONFIG_FB_MB862XX_LIME) 1052 of_unregister_platform_driver(&of_platform_mb862xxfb_driver); 1053#endif 1054#if defined(CONFIG_FB_MB862XX_PCI_GDC) 1055 pci_unregister_driver(&mb862xxfb_pci_driver); 1056#endif 1057} 1058 1059module_init(mb862xxfb_init); 1060module_exit(mb862xxfb_exit); 1061 1062MODULE_DESCRIPTION("Fujitsu MB862xx Framebuffer driver"); 1063MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>"); 1064MODULE_LICENSE("GPL v2"); 1065