1/* 2 * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> 3 * JZ4740 SoC LCD framebuffer driver 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License as published by the 7 * Free Software Foundation; either version 2 of the License, or (at your 8 * option) any later version. 9 * 10 * You should have received a copy of the GNU General Public License along 11 * with this program; if not, write to the Free Software Foundation, Inc., 12 * 675 Mass Ave, Cambridge, MA 02139, USA. 13 * 14 */ 15 16#include <linux/kernel.h> 17#include <linux/module.h> 18#include <linux/mutex.h> 19#include <linux/platform_device.h> 20 21#include <linux/clk.h> 22#include <linux/delay.h> 23 24#include <linux/console.h> 25#include <linux/fb.h> 26 27#include <linux/dma-mapping.h> 28 29#include <asm/mach-jz4740/jz4740_fb.h> 30#include <asm/mach-jz4740/gpio.h> 31 32#define JZ_REG_LCD_CFG 0x00 33#define JZ_REG_LCD_VSYNC 0x04 34#define JZ_REG_LCD_HSYNC 0x08 35#define JZ_REG_LCD_VAT 0x0C 36#define JZ_REG_LCD_DAH 0x10 37#define JZ_REG_LCD_DAV 0x14 38#define JZ_REG_LCD_PS 0x18 39#define JZ_REG_LCD_CLS 0x1C 40#define JZ_REG_LCD_SPL 0x20 41#define JZ_REG_LCD_REV 0x24 42#define JZ_REG_LCD_CTRL 0x30 43#define JZ_REG_LCD_STATE 0x34 44#define JZ_REG_LCD_IID 0x38 45#define JZ_REG_LCD_DA0 0x40 46#define JZ_REG_LCD_SA0 0x44 47#define JZ_REG_LCD_FID0 0x48 48#define JZ_REG_LCD_CMD0 0x4C 49#define JZ_REG_LCD_DA1 0x50 50#define JZ_REG_LCD_SA1 0x54 51#define JZ_REG_LCD_FID1 0x58 52#define JZ_REG_LCD_CMD1 0x5C 53 54#define JZ_LCD_CFG_SLCD BIT(31) 55#define JZ_LCD_CFG_PS_DISABLE BIT(23) 56#define JZ_LCD_CFG_CLS_DISABLE BIT(22) 57#define JZ_LCD_CFG_SPL_DISABLE BIT(21) 58#define JZ_LCD_CFG_REV_DISABLE BIT(20) 59#define JZ_LCD_CFG_HSYNCM BIT(19) 60#define JZ_LCD_CFG_PCLKM BIT(18) 61#define JZ_LCD_CFG_INV BIT(17) 62#define JZ_LCD_CFG_SYNC_DIR BIT(16) 63#define JZ_LCD_CFG_PS_POLARITY BIT(15) 64#define JZ_LCD_CFG_CLS_POLARITY BIT(14) 65#define JZ_LCD_CFG_SPL_POLARITY BIT(13) 66#define JZ_LCD_CFG_REV_POLARITY BIT(12) 67#define JZ_LCD_CFG_HSYNC_ACTIVE_LOW BIT(11) 68#define JZ_LCD_CFG_PCLK_FALLING_EDGE BIT(10) 69#define JZ_LCD_CFG_DE_ACTIVE_LOW BIT(9) 70#define JZ_LCD_CFG_VSYNC_ACTIVE_LOW BIT(8) 71#define JZ_LCD_CFG_18_BIT BIT(7) 72#define JZ_LCD_CFG_PDW (BIT(5) | BIT(4)) 73#define JZ_LCD_CFG_MODE_MASK 0xf 74 75#define JZ_LCD_CTRL_BURST_4 (0x0 << 28) 76#define JZ_LCD_CTRL_BURST_8 (0x1 << 28) 77#define JZ_LCD_CTRL_BURST_16 (0x2 << 28) 78#define JZ_LCD_CTRL_RGB555 BIT(27) 79#define JZ_LCD_CTRL_OFUP BIT(26) 80#define JZ_LCD_CTRL_FRC_GRAYSCALE_16 (0x0 << 24) 81#define JZ_LCD_CTRL_FRC_GRAYSCALE_4 (0x1 << 24) 82#define JZ_LCD_CTRL_FRC_GRAYSCALE_2 (0x2 << 24) 83#define JZ_LCD_CTRL_PDD_MASK (0xff << 16) 84#define JZ_LCD_CTRL_EOF_IRQ BIT(13) 85#define JZ_LCD_CTRL_SOF_IRQ BIT(12) 86#define JZ_LCD_CTRL_OFU_IRQ BIT(11) 87#define JZ_LCD_CTRL_IFU0_IRQ BIT(10) 88#define JZ_LCD_CTRL_IFU1_IRQ BIT(9) 89#define JZ_LCD_CTRL_DD_IRQ BIT(8) 90#define JZ_LCD_CTRL_QDD_IRQ BIT(7) 91#define JZ_LCD_CTRL_REVERSE_ENDIAN BIT(6) 92#define JZ_LCD_CTRL_LSB_FISRT BIT(5) 93#define JZ_LCD_CTRL_DISABLE BIT(4) 94#define JZ_LCD_CTRL_ENABLE BIT(3) 95#define JZ_LCD_CTRL_BPP_1 0x0 96#define JZ_LCD_CTRL_BPP_2 0x1 97#define JZ_LCD_CTRL_BPP_4 0x2 98#define JZ_LCD_CTRL_BPP_8 0x3 99#define JZ_LCD_CTRL_BPP_15_16 0x4 100#define JZ_LCD_CTRL_BPP_18_24 0x5 101 102#define JZ_LCD_CMD_SOF_IRQ BIT(31) 103#define JZ_LCD_CMD_EOF_IRQ BIT(30) 104#define JZ_LCD_CMD_ENABLE_PAL BIT(28) 105 106#define JZ_LCD_SYNC_MASK 0x3ff 107 108#define JZ_LCD_STATE_DISABLED BIT(0) 109 110struct jzfb_framedesc { 111 uint32_t next; 112 uint32_t addr; 113 uint32_t id; 114 uint32_t cmd; 115} __packed; 116 117struct jzfb { 118 struct fb_info *fb; 119 struct platform_device *pdev; 120 void __iomem *base; 121 struct resource *mem; 122 struct jz4740_fb_platform_data *pdata; 123 124 size_t vidmem_size; 125 void *vidmem; 126 dma_addr_t vidmem_phys; 127 struct jzfb_framedesc *framedesc; 128 dma_addr_t framedesc_phys; 129 130 struct clk *ldclk; 131 struct clk *lpclk; 132 133 unsigned is_enabled:1; 134 struct mutex lock; 135 136 uint32_t pseudo_palette[16]; 137}; 138 139static const struct fb_fix_screeninfo jzfb_fix = { 140 .id = "JZ4740 FB", 141 .type = FB_TYPE_PACKED_PIXELS, 142 .visual = FB_VISUAL_TRUECOLOR, 143 .xpanstep = 0, 144 .ypanstep = 0, 145 .ywrapstep = 0, 146 .accel = FB_ACCEL_NONE, 147}; 148 149static const struct jz_gpio_bulk_request jz_lcd_ctrl_pins[] = { 150 JZ_GPIO_BULK_PIN(LCD_PCLK), 151 JZ_GPIO_BULK_PIN(LCD_HSYNC), 152 JZ_GPIO_BULK_PIN(LCD_VSYNC), 153 JZ_GPIO_BULK_PIN(LCD_DE), 154 JZ_GPIO_BULK_PIN(LCD_PS), 155 JZ_GPIO_BULK_PIN(LCD_REV), 156 JZ_GPIO_BULK_PIN(LCD_CLS), 157 JZ_GPIO_BULK_PIN(LCD_SPL), 158}; 159 160static const struct jz_gpio_bulk_request jz_lcd_data_pins[] = { 161 JZ_GPIO_BULK_PIN(LCD_DATA0), 162 JZ_GPIO_BULK_PIN(LCD_DATA1), 163 JZ_GPIO_BULK_PIN(LCD_DATA2), 164 JZ_GPIO_BULK_PIN(LCD_DATA3), 165 JZ_GPIO_BULK_PIN(LCD_DATA4), 166 JZ_GPIO_BULK_PIN(LCD_DATA5), 167 JZ_GPIO_BULK_PIN(LCD_DATA6), 168 JZ_GPIO_BULK_PIN(LCD_DATA7), 169 JZ_GPIO_BULK_PIN(LCD_DATA8), 170 JZ_GPIO_BULK_PIN(LCD_DATA9), 171 JZ_GPIO_BULK_PIN(LCD_DATA10), 172 JZ_GPIO_BULK_PIN(LCD_DATA11), 173 JZ_GPIO_BULK_PIN(LCD_DATA12), 174 JZ_GPIO_BULK_PIN(LCD_DATA13), 175 JZ_GPIO_BULK_PIN(LCD_DATA14), 176 JZ_GPIO_BULK_PIN(LCD_DATA15), 177 JZ_GPIO_BULK_PIN(LCD_DATA16), 178 JZ_GPIO_BULK_PIN(LCD_DATA17), 179}; 180 181static unsigned int jzfb_num_ctrl_pins(struct jzfb *jzfb) 182{ 183 unsigned int num; 184 185 switch (jzfb->pdata->lcd_type) { 186 case JZ_LCD_TYPE_GENERIC_16_BIT: 187 num = 4; 188 break; 189 case JZ_LCD_TYPE_GENERIC_18_BIT: 190 num = 4; 191 break; 192 case JZ_LCD_TYPE_8BIT_SERIAL: 193 num = 3; 194 break; 195 case JZ_LCD_TYPE_SPECIAL_TFT_1: 196 case JZ_LCD_TYPE_SPECIAL_TFT_2: 197 case JZ_LCD_TYPE_SPECIAL_TFT_3: 198 num = 8; 199 break; 200 default: 201 num = 0; 202 break; 203 } 204 return num; 205} 206 207static unsigned int jzfb_num_data_pins(struct jzfb *jzfb) 208{ 209 unsigned int num; 210 211 switch (jzfb->pdata->lcd_type) { 212 case JZ_LCD_TYPE_GENERIC_16_BIT: 213 num = 16; 214 break; 215 case JZ_LCD_TYPE_GENERIC_18_BIT: 216 num = 18; 217 break; 218 case JZ_LCD_TYPE_8BIT_SERIAL: 219 num = 8; 220 break; 221 case JZ_LCD_TYPE_SPECIAL_TFT_1: 222 case JZ_LCD_TYPE_SPECIAL_TFT_2: 223 case JZ_LCD_TYPE_SPECIAL_TFT_3: 224 if (jzfb->pdata->bpp == 18) 225 num = 18; 226 else 227 num = 16; 228 break; 229 default: 230 num = 0; 231 break; 232 } 233 return num; 234} 235 236/* Based on CNVT_TOHW macro from skeletonfb.c */ 237static inline uint32_t jzfb_convert_color_to_hw(unsigned val, 238 struct fb_bitfield *bf) 239{ 240 return (((val << bf->length) + 0x7FFF - val) >> 16) << bf->offset; 241} 242 243static int jzfb_setcolreg(unsigned regno, unsigned red, unsigned green, 244 unsigned blue, unsigned transp, struct fb_info *fb) 245{ 246 uint32_t color; 247 248 if (regno >= 16) 249 return -EINVAL; 250 251 color = jzfb_convert_color_to_hw(red, &fb->var.red); 252 color |= jzfb_convert_color_to_hw(green, &fb->var.green); 253 color |= jzfb_convert_color_to_hw(blue, &fb->var.blue); 254 color |= jzfb_convert_color_to_hw(transp, &fb->var.transp); 255 256 ((uint32_t *)(fb->pseudo_palette))[regno] = color; 257 258 return 0; 259} 260 261static int jzfb_get_controller_bpp(struct jzfb *jzfb) 262{ 263 switch (jzfb->pdata->bpp) { 264 case 18: 265 case 24: 266 return 32; 267 case 15: 268 return 16; 269 default: 270 return jzfb->pdata->bpp; 271 } 272} 273 274static struct fb_videomode *jzfb_get_mode(struct jzfb *jzfb, 275 struct fb_var_screeninfo *var) 276{ 277 size_t i; 278 struct fb_videomode *mode = jzfb->pdata->modes; 279 280 for (i = 0; i < jzfb->pdata->num_modes; ++i, ++mode) { 281 if (mode->xres == var->xres && mode->yres == var->yres) 282 return mode; 283 } 284 285 return NULL; 286} 287 288static int jzfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fb) 289{ 290 struct jzfb *jzfb = fb->par; 291 struct fb_videomode *mode; 292 293 if (var->bits_per_pixel != jzfb_get_controller_bpp(jzfb) && 294 var->bits_per_pixel != jzfb->pdata->bpp) 295 return -EINVAL; 296 297 mode = jzfb_get_mode(jzfb, var); 298 if (mode == NULL) 299 return -EINVAL; 300 301 fb_videomode_to_var(var, mode); 302 303 switch (jzfb->pdata->bpp) { 304 case 8: 305 break; 306 case 15: 307 var->red.offset = 10; 308 var->red.length = 5; 309 var->green.offset = 6; 310 var->green.length = 5; 311 var->blue.offset = 0; 312 var->blue.length = 5; 313 break; 314 case 16: 315 var->red.offset = 11; 316 var->red.length = 5; 317 var->green.offset = 5; 318 var->green.length = 6; 319 var->blue.offset = 0; 320 var->blue.length = 5; 321 break; 322 case 18: 323 var->red.offset = 16; 324 var->red.length = 6; 325 var->green.offset = 8; 326 var->green.length = 6; 327 var->blue.offset = 0; 328 var->blue.length = 6; 329 var->bits_per_pixel = 32; 330 break; 331 case 32: 332 case 24: 333 var->transp.offset = 24; 334 var->transp.length = 8; 335 var->red.offset = 16; 336 var->red.length = 8; 337 var->green.offset = 8; 338 var->green.length = 8; 339 var->blue.offset = 0; 340 var->blue.length = 8; 341 var->bits_per_pixel = 32; 342 break; 343 default: 344 break; 345 } 346 347 return 0; 348} 349 350static int jzfb_set_par(struct fb_info *info) 351{ 352 struct jzfb *jzfb = info->par; 353 struct jz4740_fb_platform_data *pdata = jzfb->pdata; 354 struct fb_var_screeninfo *var = &info->var; 355 struct fb_videomode *mode; 356 uint16_t hds, vds; 357 uint16_t hde, vde; 358 uint16_t ht, vt; 359 uint32_t ctrl; 360 uint32_t cfg; 361 unsigned long rate; 362 363 mode = jzfb_get_mode(jzfb, var); 364 if (mode == NULL) 365 return -EINVAL; 366 367 if (mode == info->mode) 368 return 0; 369 370 info->mode = mode; 371 372 hds = mode->hsync_len + mode->left_margin; 373 hde = hds + mode->xres; 374 ht = hde + mode->right_margin; 375 376 vds = mode->vsync_len + mode->upper_margin; 377 vde = vds + mode->yres; 378 vt = vde + mode->lower_margin; 379 380 ctrl = JZ_LCD_CTRL_OFUP | JZ_LCD_CTRL_BURST_16; 381 382 switch (pdata->bpp) { 383 case 1: 384 ctrl |= JZ_LCD_CTRL_BPP_1; 385 break; 386 case 2: 387 ctrl |= JZ_LCD_CTRL_BPP_2; 388 break; 389 case 4: 390 ctrl |= JZ_LCD_CTRL_BPP_4; 391 break; 392 case 8: 393 ctrl |= JZ_LCD_CTRL_BPP_8; 394 break; 395 case 15: 396 ctrl |= JZ_LCD_CTRL_RGB555; /* Falltrough */ 397 case 16: 398 ctrl |= JZ_LCD_CTRL_BPP_15_16; 399 break; 400 case 18: 401 case 24: 402 case 32: 403 ctrl |= JZ_LCD_CTRL_BPP_18_24; 404 break; 405 default: 406 break; 407 } 408 409 cfg = pdata->lcd_type & 0xf; 410 411 if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT)) 412 cfg |= JZ_LCD_CFG_HSYNC_ACTIVE_LOW; 413 414 if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT)) 415 cfg |= JZ_LCD_CFG_VSYNC_ACTIVE_LOW; 416 417 if (pdata->pixclk_falling_edge) 418 cfg |= JZ_LCD_CFG_PCLK_FALLING_EDGE; 419 420 if (pdata->date_enable_active_low) 421 cfg |= JZ_LCD_CFG_DE_ACTIVE_LOW; 422 423 if (pdata->lcd_type == JZ_LCD_TYPE_GENERIC_18_BIT) 424 cfg |= JZ_LCD_CFG_18_BIT; 425 426 if (mode->pixclock) { 427 rate = PICOS2KHZ(mode->pixclock) * 1000; 428 mode->refresh = rate / vt / ht; 429 } else { 430 if (pdata->lcd_type == JZ_LCD_TYPE_8BIT_SERIAL) 431 rate = mode->refresh * (vt + 2 * mode->xres) * ht; 432 else 433 rate = mode->refresh * vt * ht; 434 435 mode->pixclock = KHZ2PICOS(rate / 1000); 436 } 437 438 mutex_lock(&jzfb->lock); 439 if (!jzfb->is_enabled) 440 clk_enable(jzfb->ldclk); 441 else 442 ctrl |= JZ_LCD_CTRL_ENABLE; 443 444 switch (pdata->lcd_type) { 445 case JZ_LCD_TYPE_SPECIAL_TFT_1: 446 case JZ_LCD_TYPE_SPECIAL_TFT_2: 447 case JZ_LCD_TYPE_SPECIAL_TFT_3: 448 writel(pdata->special_tft_config.spl, jzfb->base + JZ_REG_LCD_SPL); 449 writel(pdata->special_tft_config.cls, jzfb->base + JZ_REG_LCD_CLS); 450 writel(pdata->special_tft_config.ps, jzfb->base + JZ_REG_LCD_PS); 451 writel(pdata->special_tft_config.ps, jzfb->base + JZ_REG_LCD_REV); 452 break; 453 default: 454 cfg |= JZ_LCD_CFG_PS_DISABLE; 455 cfg |= JZ_LCD_CFG_CLS_DISABLE; 456 cfg |= JZ_LCD_CFG_SPL_DISABLE; 457 cfg |= JZ_LCD_CFG_REV_DISABLE; 458 break; 459 } 460 461 writel(mode->hsync_len, jzfb->base + JZ_REG_LCD_HSYNC); 462 writel(mode->vsync_len, jzfb->base + JZ_REG_LCD_VSYNC); 463 464 writel((ht << 16) | vt, jzfb->base + JZ_REG_LCD_VAT); 465 466 writel((hds << 16) | hde, jzfb->base + JZ_REG_LCD_DAH); 467 writel((vds << 16) | vde, jzfb->base + JZ_REG_LCD_DAV); 468 469 writel(cfg, jzfb->base + JZ_REG_LCD_CFG); 470 471 writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL); 472 473 if (!jzfb->is_enabled) 474 clk_disable_unprepare(jzfb->ldclk); 475 476 mutex_unlock(&jzfb->lock); 477 478 clk_set_rate(jzfb->lpclk, rate); 479 clk_set_rate(jzfb->ldclk, rate * 3); 480 481 return 0; 482} 483 484static void jzfb_enable(struct jzfb *jzfb) 485{ 486 uint32_t ctrl; 487 488 clk_prepare_enable(jzfb->ldclk); 489 490 jz_gpio_bulk_resume(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb)); 491 jz_gpio_bulk_resume(jz_lcd_data_pins, jzfb_num_data_pins(jzfb)); 492 493 writel(0, jzfb->base + JZ_REG_LCD_STATE); 494 495 writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0); 496 497 ctrl = readl(jzfb->base + JZ_REG_LCD_CTRL); 498 ctrl |= JZ_LCD_CTRL_ENABLE; 499 ctrl &= ~JZ_LCD_CTRL_DISABLE; 500 writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL); 501} 502 503static void jzfb_disable(struct jzfb *jzfb) 504{ 505 uint32_t ctrl; 506 507 ctrl = readl(jzfb->base + JZ_REG_LCD_CTRL); 508 ctrl |= JZ_LCD_CTRL_DISABLE; 509 writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL); 510 do { 511 ctrl = readl(jzfb->base + JZ_REG_LCD_STATE); 512 } while (!(ctrl & JZ_LCD_STATE_DISABLED)); 513 514 jz_gpio_bulk_suspend(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb)); 515 jz_gpio_bulk_suspend(jz_lcd_data_pins, jzfb_num_data_pins(jzfb)); 516 517 clk_disable_unprepare(jzfb->ldclk); 518} 519 520static int jzfb_blank(int blank_mode, struct fb_info *info) 521{ 522 struct jzfb *jzfb = info->par; 523 524 switch (blank_mode) { 525 case FB_BLANK_UNBLANK: 526 mutex_lock(&jzfb->lock); 527 if (jzfb->is_enabled) { 528 mutex_unlock(&jzfb->lock); 529 return 0; 530 } 531 532 jzfb_enable(jzfb); 533 jzfb->is_enabled = 1; 534 535 mutex_unlock(&jzfb->lock); 536 break; 537 default: 538 mutex_lock(&jzfb->lock); 539 if (!jzfb->is_enabled) { 540 mutex_unlock(&jzfb->lock); 541 return 0; 542 } 543 544 jzfb_disable(jzfb); 545 jzfb->is_enabled = 0; 546 547 mutex_unlock(&jzfb->lock); 548 break; 549 } 550 551 return 0; 552} 553 554static int jzfb_alloc_devmem(struct jzfb *jzfb) 555{ 556 int max_videosize = 0; 557 struct fb_videomode *mode = jzfb->pdata->modes; 558 void *page; 559 int i; 560 561 for (i = 0; i < jzfb->pdata->num_modes; ++mode, ++i) { 562 if (max_videosize < mode->xres * mode->yres) 563 max_videosize = mode->xres * mode->yres; 564 } 565 566 max_videosize *= jzfb_get_controller_bpp(jzfb) >> 3; 567 568 jzfb->framedesc = dma_alloc_coherent(&jzfb->pdev->dev, 569 sizeof(*jzfb->framedesc), 570 &jzfb->framedesc_phys, GFP_KERNEL); 571 572 if (!jzfb->framedesc) 573 return -ENOMEM; 574 575 jzfb->vidmem_size = PAGE_ALIGN(max_videosize); 576 jzfb->vidmem = dma_alloc_coherent(&jzfb->pdev->dev, 577 jzfb->vidmem_size, 578 &jzfb->vidmem_phys, GFP_KERNEL); 579 580 if (!jzfb->vidmem) 581 goto err_free_framedesc; 582 583 for (page = jzfb->vidmem; 584 page < jzfb->vidmem + PAGE_ALIGN(jzfb->vidmem_size); 585 page += PAGE_SIZE) { 586 SetPageReserved(virt_to_page(page)); 587 } 588 589 jzfb->framedesc->next = jzfb->framedesc_phys; 590 jzfb->framedesc->addr = jzfb->vidmem_phys; 591 jzfb->framedesc->id = 0xdeafbead; 592 jzfb->framedesc->cmd = 0; 593 jzfb->framedesc->cmd |= max_videosize / 4; 594 595 return 0; 596 597err_free_framedesc: 598 dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc), 599 jzfb->framedesc, jzfb->framedesc_phys); 600 return -ENOMEM; 601} 602 603static void jzfb_free_devmem(struct jzfb *jzfb) 604{ 605 dma_free_coherent(&jzfb->pdev->dev, jzfb->vidmem_size, 606 jzfb->vidmem, jzfb->vidmem_phys); 607 dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc), 608 jzfb->framedesc, jzfb->framedesc_phys); 609} 610 611static struct fb_ops jzfb_ops = { 612 .owner = THIS_MODULE, 613 .fb_check_var = jzfb_check_var, 614 .fb_set_par = jzfb_set_par, 615 .fb_blank = jzfb_blank, 616 .fb_fillrect = sys_fillrect, 617 .fb_copyarea = sys_copyarea, 618 .fb_imageblit = sys_imageblit, 619 .fb_setcolreg = jzfb_setcolreg, 620}; 621 622static int jzfb_probe(struct platform_device *pdev) 623{ 624 int ret; 625 struct jzfb *jzfb; 626 struct fb_info *fb; 627 struct jz4740_fb_platform_data *pdata = pdev->dev.platform_data; 628 struct resource *mem; 629 630 if (!pdata) { 631 dev_err(&pdev->dev, "Missing platform data\n"); 632 return -ENXIO; 633 } 634 635 fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev); 636 if (!fb) { 637 dev_err(&pdev->dev, "Failed to allocate framebuffer device\n"); 638 return -ENOMEM; 639 } 640 641 fb->fbops = &jzfb_ops; 642 fb->flags = FBINFO_DEFAULT; 643 644 jzfb = fb->par; 645 jzfb->pdev = pdev; 646 jzfb->pdata = pdata; 647 648 jzfb->ldclk = devm_clk_get(&pdev->dev, "lcd"); 649 if (IS_ERR(jzfb->ldclk)) { 650 ret = PTR_ERR(jzfb->ldclk); 651 dev_err(&pdev->dev, "Failed to get lcd clock: %d\n", ret); 652 goto err_framebuffer_release; 653 } 654 655 jzfb->lpclk = devm_clk_get(&pdev->dev, "lcd_pclk"); 656 if (IS_ERR(jzfb->lpclk)) { 657 ret = PTR_ERR(jzfb->lpclk); 658 dev_err(&pdev->dev, "Failed to get lcd pixel clock: %d\n", ret); 659 goto err_framebuffer_release; 660 } 661 662 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 663 jzfb->base = devm_ioremap_resource(&pdev->dev, mem); 664 if (IS_ERR(jzfb->base)) { 665 ret = PTR_ERR(jzfb->base); 666 goto err_framebuffer_release; 667 } 668 669 platform_set_drvdata(pdev, jzfb); 670 671 mutex_init(&jzfb->lock); 672 673 fb_videomode_to_modelist(pdata->modes, pdata->num_modes, 674 &fb->modelist); 675 fb_videomode_to_var(&fb->var, pdata->modes); 676 fb->var.bits_per_pixel = pdata->bpp; 677 jzfb_check_var(&fb->var, fb); 678 679 ret = jzfb_alloc_devmem(jzfb); 680 if (ret) { 681 dev_err(&pdev->dev, "Failed to allocate video memory\n"); 682 goto err_framebuffer_release; 683 } 684 685 fb->fix = jzfb_fix; 686 fb->fix.line_length = fb->var.bits_per_pixel * fb->var.xres / 8; 687 fb->fix.mmio_start = mem->start; 688 fb->fix.mmio_len = resource_size(mem); 689 fb->fix.smem_start = jzfb->vidmem_phys; 690 fb->fix.smem_len = fb->fix.line_length * fb->var.yres; 691 fb->screen_base = jzfb->vidmem; 692 fb->pseudo_palette = jzfb->pseudo_palette; 693 694 fb_alloc_cmap(&fb->cmap, 256, 0); 695 696 clk_prepare_enable(jzfb->ldclk); 697 jzfb->is_enabled = 1; 698 699 writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0); 700 701 fb->mode = NULL; 702 jzfb_set_par(fb); 703 704 jz_gpio_bulk_request(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb)); 705 jz_gpio_bulk_request(jz_lcd_data_pins, jzfb_num_data_pins(jzfb)); 706 707 ret = register_framebuffer(fb); 708 if (ret) { 709 dev_err(&pdev->dev, "Failed to register framebuffer: %d\n", ret); 710 goto err_free_devmem; 711 } 712 713 jzfb->fb = fb; 714 715 return 0; 716 717err_free_devmem: 718 jz_gpio_bulk_free(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb)); 719 jz_gpio_bulk_free(jz_lcd_data_pins, jzfb_num_data_pins(jzfb)); 720 721 fb_dealloc_cmap(&fb->cmap); 722 jzfb_free_devmem(jzfb); 723err_framebuffer_release: 724 framebuffer_release(fb); 725 return ret; 726} 727 728static int jzfb_remove(struct platform_device *pdev) 729{ 730 struct jzfb *jzfb = platform_get_drvdata(pdev); 731 732 jzfb_blank(FB_BLANK_POWERDOWN, jzfb->fb); 733 734 jz_gpio_bulk_free(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb)); 735 jz_gpio_bulk_free(jz_lcd_data_pins, jzfb_num_data_pins(jzfb)); 736 737 fb_dealloc_cmap(&jzfb->fb->cmap); 738 jzfb_free_devmem(jzfb); 739 740 framebuffer_release(jzfb->fb); 741 742 return 0; 743} 744 745#ifdef CONFIG_PM 746 747static int jzfb_suspend(struct device *dev) 748{ 749 struct jzfb *jzfb = dev_get_drvdata(dev); 750 751 console_lock(); 752 fb_set_suspend(jzfb->fb, 1); 753 console_unlock(); 754 755 mutex_lock(&jzfb->lock); 756 if (jzfb->is_enabled) 757 jzfb_disable(jzfb); 758 mutex_unlock(&jzfb->lock); 759 760 return 0; 761} 762 763static int jzfb_resume(struct device *dev) 764{ 765 struct jzfb *jzfb = dev_get_drvdata(dev); 766 clk_prepare_enable(jzfb->ldclk); 767 768 mutex_lock(&jzfb->lock); 769 if (jzfb->is_enabled) 770 jzfb_enable(jzfb); 771 mutex_unlock(&jzfb->lock); 772 773 console_lock(); 774 fb_set_suspend(jzfb->fb, 0); 775 console_unlock(); 776 777 return 0; 778} 779 780static const struct dev_pm_ops jzfb_pm_ops = { 781 .suspend = jzfb_suspend, 782 .resume = jzfb_resume, 783 .poweroff = jzfb_suspend, 784 .restore = jzfb_resume, 785}; 786 787#define JZFB_PM_OPS (&jzfb_pm_ops) 788 789#else 790#define JZFB_PM_OPS NULL 791#endif 792 793static struct platform_driver jzfb_driver = { 794 .probe = jzfb_probe, 795 .remove = jzfb_remove, 796 .driver = { 797 .name = "jz4740-fb", 798 .pm = JZFB_PM_OPS, 799 }, 800}; 801module_platform_driver(jzfb_driver); 802 803MODULE_LICENSE("GPL"); 804MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 805MODULE_DESCRIPTION("JZ4740 SoC LCD framebuffer driver"); 806MODULE_ALIAS("platform:jz4740-fb"); 807