sh_mobile_lcdcfb.c revision d2ecbab5960d9814a269d36723647d6ef391ba8f
1/* 2 * SuperH Mobile LCDC Framebuffer 3 * 4 * Copyright (c) 2008 Magnus Damm 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. 9 */ 10 11#include <linux/kernel.h> 12#include <linux/init.h> 13#include <linux/delay.h> 14#include <linux/mm.h> 15#include <linux/clk.h> 16#include <linux/pm_runtime.h> 17#include <linux/platform_device.h> 18#include <linux/dma-mapping.h> 19#include <linux/interrupt.h> 20#include <linux/vmalloc.h> 21#include <linux/ioctl.h> 22#include <linux/slab.h> 23#include <linux/console.h> 24#include <video/sh_mobile_lcdc.h> 25#include <asm/atomic.h> 26 27#include "sh_mobile_lcdcfb.h" 28 29#define SIDE_B_OFFSET 0x1000 30#define MIRROR_OFFSET 0x2000 31 32/* shared registers */ 33#define _LDDCKR 0x410 34#define _LDDCKSTPR 0x414 35#define _LDINTR 0x468 36#define _LDSR 0x46c 37#define _LDCNT1R 0x470 38#define _LDCNT2R 0x474 39#define _LDRCNTR 0x478 40#define _LDDDSR 0x47c 41#define _LDDWD0R 0x800 42#define _LDDRDR 0x840 43#define _LDDWAR 0x900 44#define _LDDRAR 0x904 45 46/* shared registers and their order for context save/restore */ 47static int lcdc_shared_regs[] = { 48 _LDDCKR, 49 _LDDCKSTPR, 50 _LDINTR, 51 _LDDDSR, 52 _LDCNT1R, 53 _LDCNT2R, 54}; 55#define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs) 56 57#define MAX_XRES 1920 58#define MAX_YRES 1080 59 60static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = { 61 [LDDCKPAT1R] = 0x400, 62 [LDDCKPAT2R] = 0x404, 63 [LDMT1R] = 0x418, 64 [LDMT2R] = 0x41c, 65 [LDMT3R] = 0x420, 66 [LDDFR] = 0x424, 67 [LDSM1R] = 0x428, 68 [LDSM2R] = 0x42c, 69 [LDSA1R] = 0x430, 70 [LDMLSR] = 0x438, 71 [LDHCNR] = 0x448, 72 [LDHSYNR] = 0x44c, 73 [LDVLNR] = 0x450, 74 [LDVSYNR] = 0x454, 75 [LDPMR] = 0x460, 76 [LDHAJR] = 0x4a0, 77}; 78 79static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = { 80 [LDDCKPAT1R] = 0x408, 81 [LDDCKPAT2R] = 0x40c, 82 [LDMT1R] = 0x600, 83 [LDMT2R] = 0x604, 84 [LDMT3R] = 0x608, 85 [LDDFR] = 0x60c, 86 [LDSM1R] = 0x610, 87 [LDSM2R] = 0x614, 88 [LDSA1R] = 0x618, 89 [LDMLSR] = 0x620, 90 [LDHCNR] = 0x624, 91 [LDHSYNR] = 0x628, 92 [LDVLNR] = 0x62c, 93 [LDVSYNR] = 0x630, 94 [LDPMR] = 0x63c, 95}; 96 97#define START_LCDC 0x00000001 98#define LCDC_RESET 0x00000100 99#define DISPLAY_BEU 0x00000008 100#define LCDC_ENABLE 0x00000001 101#define LDINTR_FE 0x00000400 102#define LDINTR_VSE 0x00000200 103#define LDINTR_VEE 0x00000100 104#define LDINTR_FS 0x00000004 105#define LDINTR_VSS 0x00000002 106#define LDINTR_VES 0x00000001 107#define LDRCNTR_SRS 0x00020000 108#define LDRCNTR_SRC 0x00010000 109#define LDRCNTR_MRS 0x00000002 110#define LDRCNTR_MRC 0x00000001 111#define LDSR_MRS 0x00000100 112 113static const struct fb_videomode default_720p = { 114 .name = "HDMI 720p", 115 .xres = 1280, 116 .yres = 720, 117 118 .left_margin = 220, 119 .right_margin = 110, 120 .hsync_len = 40, 121 122 .upper_margin = 20, 123 .lower_margin = 5, 124 .vsync_len = 5, 125 126 .pixclock = 13468, 127 .refresh = 60, 128 .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT, 129}; 130 131struct sh_mobile_lcdc_priv { 132 void __iomem *base; 133 int irq; 134 atomic_t hw_usecnt; 135 struct device *dev; 136 struct clk *dot_clk; 137 unsigned long lddckr; 138 struct sh_mobile_lcdc_chan ch[2]; 139 struct notifier_block notifier; 140 unsigned long saved_shared_regs[NR_SHARED_REGS]; 141 int started; 142}; 143 144static bool banked(int reg_nr) 145{ 146 switch (reg_nr) { 147 case LDMT1R: 148 case LDMT2R: 149 case LDMT3R: 150 case LDDFR: 151 case LDSM1R: 152 case LDSA1R: 153 case LDMLSR: 154 case LDHCNR: 155 case LDHSYNR: 156 case LDVLNR: 157 case LDVSYNR: 158 return true; 159 } 160 return false; 161} 162 163static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan, 164 int reg_nr, unsigned long data) 165{ 166 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr]); 167 if (banked(reg_nr)) 168 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] + 169 SIDE_B_OFFSET); 170} 171 172static void lcdc_write_chan_mirror(struct sh_mobile_lcdc_chan *chan, 173 int reg_nr, unsigned long data) 174{ 175 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] + 176 MIRROR_OFFSET); 177} 178 179static unsigned long lcdc_read_chan(struct sh_mobile_lcdc_chan *chan, 180 int reg_nr) 181{ 182 return ioread32(chan->lcdc->base + chan->reg_offs[reg_nr]); 183} 184 185static void lcdc_write(struct sh_mobile_lcdc_priv *priv, 186 unsigned long reg_offs, unsigned long data) 187{ 188 iowrite32(data, priv->base + reg_offs); 189} 190 191static unsigned long lcdc_read(struct sh_mobile_lcdc_priv *priv, 192 unsigned long reg_offs) 193{ 194 return ioread32(priv->base + reg_offs); 195} 196 197static void lcdc_wait_bit(struct sh_mobile_lcdc_priv *priv, 198 unsigned long reg_offs, 199 unsigned long mask, unsigned long until) 200{ 201 while ((lcdc_read(priv, reg_offs) & mask) != until) 202 cpu_relax(); 203} 204 205static int lcdc_chan_is_sublcd(struct sh_mobile_lcdc_chan *chan) 206{ 207 return chan->cfg.chan == LCDC_CHAN_SUBLCD; 208} 209 210static void lcdc_sys_write_index(void *handle, unsigned long data) 211{ 212 struct sh_mobile_lcdc_chan *ch = handle; 213 214 lcdc_write(ch->lcdc, _LDDWD0R, data | 0x10000000); 215 lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0); 216 lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0)); 217 lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0); 218} 219 220static void lcdc_sys_write_data(void *handle, unsigned long data) 221{ 222 struct sh_mobile_lcdc_chan *ch = handle; 223 224 lcdc_write(ch->lcdc, _LDDWD0R, data | 0x11000000); 225 lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0); 226 lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0)); 227 lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0); 228} 229 230static unsigned long lcdc_sys_read_data(void *handle) 231{ 232 struct sh_mobile_lcdc_chan *ch = handle; 233 234 lcdc_write(ch->lcdc, _LDDRDR, 0x01000000); 235 lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0); 236 lcdc_write(ch->lcdc, _LDDRAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0)); 237 udelay(1); 238 lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0); 239 240 return lcdc_read(ch->lcdc, _LDDRDR) & 0x3ffff; 241} 242 243struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = { 244 lcdc_sys_write_index, 245 lcdc_sys_write_data, 246 lcdc_sys_read_data, 247}; 248 249static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv) 250{ 251 if (atomic_inc_and_test(&priv->hw_usecnt)) { 252 pm_runtime_get_sync(priv->dev); 253 if (priv->dot_clk) 254 clk_enable(priv->dot_clk); 255 } 256} 257 258static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv) 259{ 260 if (atomic_sub_return(1, &priv->hw_usecnt) == -1) { 261 if (priv->dot_clk) 262 clk_disable(priv->dot_clk); 263 pm_runtime_put(priv->dev); 264 } 265} 266 267static int sh_mobile_lcdc_sginit(struct fb_info *info, 268 struct list_head *pagelist) 269{ 270 struct sh_mobile_lcdc_chan *ch = info->par; 271 unsigned int nr_pages_max = info->fix.smem_len >> PAGE_SHIFT; 272 struct page *page; 273 int nr_pages = 0; 274 275 sg_init_table(ch->sglist, nr_pages_max); 276 277 list_for_each_entry(page, pagelist, lru) 278 sg_set_page(&ch->sglist[nr_pages++], page, PAGE_SIZE, 0); 279 280 return nr_pages; 281} 282 283static void sh_mobile_lcdc_deferred_io(struct fb_info *info, 284 struct list_head *pagelist) 285{ 286 struct sh_mobile_lcdc_chan *ch = info->par; 287 struct sh_mobile_lcdc_board_cfg *bcfg = &ch->cfg.board_cfg; 288 289 /* enable clocks before accessing hardware */ 290 sh_mobile_lcdc_clk_on(ch->lcdc); 291 292 /* 293 * It's possible to get here without anything on the pagelist via 294 * sh_mobile_lcdc_deferred_io_touch() or via a userspace fsync() 295 * invocation. In the former case, the acceleration routines are 296 * stepped in to when using the framebuffer console causing the 297 * workqueue to be scheduled without any dirty pages on the list. 298 * 299 * Despite this, a panel update is still needed given that the 300 * acceleration routines have their own methods for writing in 301 * that still need to be updated. 302 * 303 * The fsync() and empty pagelist case could be optimized for, 304 * but we don't bother, as any application exhibiting such 305 * behaviour is fundamentally broken anyways. 306 */ 307 if (!list_empty(pagelist)) { 308 unsigned int nr_pages = sh_mobile_lcdc_sginit(info, pagelist); 309 310 /* trigger panel update */ 311 dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE); 312 if (bcfg->start_transfer) 313 bcfg->start_transfer(bcfg->board_data, ch, 314 &sh_mobile_lcdc_sys_bus_ops); 315 lcdc_write_chan(ch, LDSM2R, 1); 316 dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE); 317 } else { 318 if (bcfg->start_transfer) 319 bcfg->start_transfer(bcfg->board_data, ch, 320 &sh_mobile_lcdc_sys_bus_ops); 321 lcdc_write_chan(ch, LDSM2R, 1); 322 } 323} 324 325static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info) 326{ 327 struct fb_deferred_io *fbdefio = info->fbdefio; 328 329 if (fbdefio) 330 schedule_delayed_work(&info->deferred_work, fbdefio->delay); 331} 332 333static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data) 334{ 335 struct sh_mobile_lcdc_priv *priv = data; 336 struct sh_mobile_lcdc_chan *ch; 337 unsigned long tmp; 338 unsigned long ldintr; 339 int is_sub; 340 int k; 341 342 /* acknowledge interrupt */ 343 ldintr = tmp = lcdc_read(priv, _LDINTR); 344 /* 345 * disable further VSYNC End IRQs, preserve all other enabled IRQs, 346 * write 0 to bits 0-6 to ack all triggered IRQs. 347 */ 348 tmp &= 0xffffff00 & ~LDINTR_VEE; 349 lcdc_write(priv, _LDINTR, tmp); 350 351 /* figure out if this interrupt is for main or sub lcd */ 352 is_sub = (lcdc_read(priv, _LDSR) & (1 << 10)) ? 1 : 0; 353 354 /* wake up channel and disable clocks */ 355 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 356 ch = &priv->ch[k]; 357 358 if (!ch->enabled) 359 continue; 360 361 /* Frame Start */ 362 if (ldintr & LDINTR_FS) { 363 if (is_sub == lcdc_chan_is_sublcd(ch)) { 364 ch->frame_end = 1; 365 wake_up(&ch->frame_end_wait); 366 367 sh_mobile_lcdc_clk_off(priv); 368 } 369 } 370 371 /* VSYNC End */ 372 if (ldintr & LDINTR_VES) 373 complete(&ch->vsync_completion); 374 } 375 376 return IRQ_HANDLED; 377} 378 379static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv, 380 int start) 381{ 382 unsigned long tmp = lcdc_read(priv, _LDCNT2R); 383 int k; 384 385 /* start or stop the lcdc */ 386 if (start) 387 lcdc_write(priv, _LDCNT2R, tmp | START_LCDC); 388 else 389 lcdc_write(priv, _LDCNT2R, tmp & ~START_LCDC); 390 391 /* wait until power is applied/stopped on all channels */ 392 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) 393 if (lcdc_read(priv, _LDCNT2R) & priv->ch[k].enabled) 394 while (1) { 395 tmp = lcdc_read_chan(&priv->ch[k], LDPMR) & 3; 396 if (start && tmp == 3) 397 break; 398 if (!start && tmp == 0) 399 break; 400 cpu_relax(); 401 } 402 403 if (!start) 404 lcdc_write(priv, _LDDCKSTPR, 1); /* stop dotclock */ 405} 406 407static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch) 408{ 409 struct fb_var_screeninfo *var = &ch->info->var, *display_var = &ch->display_var; 410 unsigned long h_total, hsync_pos, display_h_total; 411 u32 tmp; 412 413 tmp = ch->ldmt1r_value; 414 tmp |= (var->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1 << 28; 415 tmp |= (var->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1 << 27; 416 tmp |= (ch->cfg.flags & LCDC_FLAGS_DWPOL) ? 1 << 26 : 0; 417 tmp |= (ch->cfg.flags & LCDC_FLAGS_DIPOL) ? 1 << 25 : 0; 418 tmp |= (ch->cfg.flags & LCDC_FLAGS_DAPOL) ? 1 << 24 : 0; 419 tmp |= (ch->cfg.flags & LCDC_FLAGS_HSCNT) ? 1 << 17 : 0; 420 tmp |= (ch->cfg.flags & LCDC_FLAGS_DWCNT) ? 1 << 16 : 0; 421 lcdc_write_chan(ch, LDMT1R, tmp); 422 423 /* setup SYS bus */ 424 lcdc_write_chan(ch, LDMT2R, ch->cfg.sys_bus_cfg.ldmt2r); 425 lcdc_write_chan(ch, LDMT3R, ch->cfg.sys_bus_cfg.ldmt3r); 426 427 /* horizontal configuration */ 428 h_total = display_var->xres + display_var->hsync_len + 429 display_var->left_margin + display_var->right_margin; 430 tmp = h_total / 8; /* HTCN */ 431 tmp |= (min(display_var->xres, var->xres) / 8) << 16; /* HDCN */ 432 lcdc_write_chan(ch, LDHCNR, tmp); 433 434 hsync_pos = display_var->xres + display_var->right_margin; 435 tmp = hsync_pos / 8; /* HSYNP */ 436 tmp |= (display_var->hsync_len / 8) << 16; /* HSYNW */ 437 lcdc_write_chan(ch, LDHSYNR, tmp); 438 439 /* vertical configuration */ 440 tmp = display_var->yres + display_var->vsync_len + 441 display_var->upper_margin + display_var->lower_margin; /* VTLN */ 442 tmp |= min(display_var->yres, var->yres) << 16; /* VDLN */ 443 lcdc_write_chan(ch, LDVLNR, tmp); 444 445 tmp = display_var->yres + display_var->lower_margin; /* VSYNP */ 446 tmp |= display_var->vsync_len << 16; /* VSYNW */ 447 lcdc_write_chan(ch, LDVSYNR, tmp); 448 449 /* Adjust horizontal synchronisation for HDMI */ 450 display_h_total = display_var->xres + display_var->hsync_len + 451 display_var->left_margin + display_var->right_margin; 452 tmp = ((display_var->xres & 7) << 24) | 453 ((display_h_total & 7) << 16) | 454 ((display_var->hsync_len & 7) << 8) | 455 hsync_pos; 456 lcdc_write_chan(ch, LDHAJR, tmp); 457} 458 459static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) 460{ 461 struct sh_mobile_lcdc_chan *ch; 462 struct sh_mobile_lcdc_board_cfg *board_cfg; 463 unsigned long tmp; 464 int k, m; 465 int ret = 0; 466 467 /* enable clocks before accessing the hardware */ 468 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) 469 if (priv->ch[k].enabled) 470 sh_mobile_lcdc_clk_on(priv); 471 472 /* reset */ 473 lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) | LCDC_RESET); 474 lcdc_wait_bit(priv, _LDCNT2R, LCDC_RESET, 0); 475 476 /* enable LCDC channels */ 477 tmp = lcdc_read(priv, _LDCNT2R); 478 tmp |= priv->ch[0].enabled; 479 tmp |= priv->ch[1].enabled; 480 lcdc_write(priv, _LDCNT2R, tmp); 481 482 /* read data from external memory, avoid using the BEU for now */ 483 lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) & ~DISPLAY_BEU); 484 485 /* stop the lcdc first */ 486 sh_mobile_lcdc_start_stop(priv, 0); 487 488 /* configure clocks */ 489 tmp = priv->lddckr; 490 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 491 ch = &priv->ch[k]; 492 493 if (!priv->ch[k].enabled) 494 continue; 495 496 m = ch->cfg.clock_divider; 497 if (!m) 498 continue; 499 500 if (m == 1) 501 m = 1 << 6; 502 tmp |= m << (lcdc_chan_is_sublcd(ch) ? 8 : 0); 503 504 /* FIXME: sh7724 can only use 42, 48, 54 and 60 for the divider denominator */ 505 lcdc_write_chan(ch, LDDCKPAT1R, 0); 506 lcdc_write_chan(ch, LDDCKPAT2R, (1 << (m/2)) - 1); 507 } 508 509 lcdc_write(priv, _LDDCKR, tmp); 510 511 /* start dotclock again */ 512 lcdc_write(priv, _LDDCKSTPR, 0); 513 lcdc_wait_bit(priv, _LDDCKSTPR, ~0, 0); 514 515 /* interrupts are disabled to begin with */ 516 lcdc_write(priv, _LDINTR, 0); 517 518 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 519 ch = &priv->ch[k]; 520 521 if (!ch->enabled) 522 continue; 523 524 sh_mobile_lcdc_geometry(ch); 525 526 /* power supply */ 527 lcdc_write_chan(ch, LDPMR, 0); 528 529 board_cfg = &ch->cfg.board_cfg; 530 if (board_cfg->setup_sys) 531 ret = board_cfg->setup_sys(board_cfg->board_data, ch, 532 &sh_mobile_lcdc_sys_bus_ops); 533 if (ret) 534 return ret; 535 } 536 537 /* word and long word swap */ 538 lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 6); 539 540 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 541 ch = &priv->ch[k]; 542 543 if (!priv->ch[k].enabled) 544 continue; 545 546 /* set bpp format in PKF[4:0] */ 547 tmp = lcdc_read_chan(ch, LDDFR); 548 tmp &= ~0x0001001f; 549 tmp |= (ch->info->var.bits_per_pixel == 16) ? 3 : 0; 550 lcdc_write_chan(ch, LDDFR, tmp); 551 552 /* point out our frame buffer */ 553 lcdc_write_chan(ch, LDSA1R, ch->info->fix.smem_start); 554 555 /* set line size */ 556 lcdc_write_chan(ch, LDMLSR, ch->info->fix.line_length); 557 558 /* setup deferred io if SYS bus */ 559 tmp = ch->cfg.sys_bus_cfg.deferred_io_msec; 560 if (ch->ldmt1r_value & (1 << 12) && tmp) { 561 ch->defio.deferred_io = sh_mobile_lcdc_deferred_io; 562 ch->defio.delay = msecs_to_jiffies(tmp); 563 ch->info->fbdefio = &ch->defio; 564 fb_deferred_io_init(ch->info); 565 566 /* one-shot mode */ 567 lcdc_write_chan(ch, LDSM1R, 1); 568 569 /* enable "Frame End Interrupt Enable" bit */ 570 lcdc_write(priv, _LDINTR, LDINTR_FE); 571 572 } else { 573 /* continuous read mode */ 574 lcdc_write_chan(ch, LDSM1R, 0); 575 } 576 } 577 578 /* display output */ 579 lcdc_write(priv, _LDCNT1R, LCDC_ENABLE); 580 581 /* start the lcdc */ 582 sh_mobile_lcdc_start_stop(priv, 1); 583 priv->started = 1; 584 585 /* tell the board code to enable the panel */ 586 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 587 ch = &priv->ch[k]; 588 if (!ch->enabled) 589 continue; 590 591 board_cfg = &ch->cfg.board_cfg; 592 if (try_module_get(board_cfg->owner) && board_cfg->display_on) { 593 board_cfg->display_on(board_cfg->board_data, ch->info); 594 module_put(board_cfg->owner); 595 } 596 } 597 598 return 0; 599} 600 601static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) 602{ 603 struct sh_mobile_lcdc_chan *ch; 604 struct sh_mobile_lcdc_board_cfg *board_cfg; 605 int k; 606 607 /* clean up deferred io and ask board code to disable panel */ 608 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 609 ch = &priv->ch[k]; 610 if (!ch->enabled) 611 continue; 612 613 /* deferred io mode: 614 * flush frame, and wait for frame end interrupt 615 * clean up deferred io and enable clock 616 */ 617 if (ch->info && ch->info->fbdefio) { 618 ch->frame_end = 0; 619 schedule_delayed_work(&ch->info->deferred_work, 0); 620 wait_event(ch->frame_end_wait, ch->frame_end); 621 fb_deferred_io_cleanup(ch->info); 622 ch->info->fbdefio = NULL; 623 sh_mobile_lcdc_clk_on(priv); 624 } 625 626 board_cfg = &ch->cfg.board_cfg; 627 if (try_module_get(board_cfg->owner) && board_cfg->display_off) { 628 board_cfg->display_off(board_cfg->board_data); 629 module_put(board_cfg->owner); 630 } 631 } 632 633 /* stop the lcdc */ 634 if (priv->started) { 635 sh_mobile_lcdc_start_stop(priv, 0); 636 priv->started = 0; 637 } 638 639 /* stop clocks */ 640 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) 641 if (priv->ch[k].enabled) 642 sh_mobile_lcdc_clk_off(priv); 643} 644 645static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch) 646{ 647 int ifm, miftyp; 648 649 switch (ch->cfg.interface_type) { 650 case RGB8: ifm = 0; miftyp = 0; break; 651 case RGB9: ifm = 0; miftyp = 4; break; 652 case RGB12A: ifm = 0; miftyp = 5; break; 653 case RGB12B: ifm = 0; miftyp = 6; break; 654 case RGB16: ifm = 0; miftyp = 7; break; 655 case RGB18: ifm = 0; miftyp = 10; break; 656 case RGB24: ifm = 0; miftyp = 11; break; 657 case SYS8A: ifm = 1; miftyp = 0; break; 658 case SYS8B: ifm = 1; miftyp = 1; break; 659 case SYS8C: ifm = 1; miftyp = 2; break; 660 case SYS8D: ifm = 1; miftyp = 3; break; 661 case SYS9: ifm = 1; miftyp = 4; break; 662 case SYS12: ifm = 1; miftyp = 5; break; 663 case SYS16A: ifm = 1; miftyp = 7; break; 664 case SYS16B: ifm = 1; miftyp = 8; break; 665 case SYS16C: ifm = 1; miftyp = 9; break; 666 case SYS18: ifm = 1; miftyp = 10; break; 667 case SYS24: ifm = 1; miftyp = 11; break; 668 default: goto bad; 669 } 670 671 /* SUBLCD only supports SYS interface */ 672 if (lcdc_chan_is_sublcd(ch)) { 673 if (ifm == 0) 674 goto bad; 675 else 676 ifm = 0; 677 } 678 679 ch->ldmt1r_value = (ifm << 12) | miftyp; 680 return 0; 681 bad: 682 return -EINVAL; 683} 684 685static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev, 686 int clock_source, 687 struct sh_mobile_lcdc_priv *priv) 688{ 689 char *str; 690 int icksel; 691 692 switch (clock_source) { 693 case LCDC_CLK_BUS: str = "bus_clk"; icksel = 0; break; 694 case LCDC_CLK_PERIPHERAL: str = "peripheral_clk"; icksel = 1; break; 695 case LCDC_CLK_EXTERNAL: str = NULL; icksel = 2; break; 696 default: 697 return -EINVAL; 698 } 699 700 priv->lddckr = icksel << 16; 701 702 if (str) { 703 priv->dot_clk = clk_get(&pdev->dev, str); 704 if (IS_ERR(priv->dot_clk)) { 705 dev_err(&pdev->dev, "cannot get dot clock %s\n", str); 706 return PTR_ERR(priv->dot_clk); 707 } 708 } 709 710 /* Runtime PM support involves two step for this driver: 711 * 1) Enable Runtime PM 712 * 2) Force Runtime PM Resume since hardware is accessed from probe() 713 */ 714 priv->dev = &pdev->dev; 715 pm_runtime_enable(priv->dev); 716 pm_runtime_resume(priv->dev); 717 return 0; 718} 719 720static int sh_mobile_lcdc_setcolreg(u_int regno, 721 u_int red, u_int green, u_int blue, 722 u_int transp, struct fb_info *info) 723{ 724 u32 *palette = info->pseudo_palette; 725 726 if (regno >= PALETTE_NR) 727 return -EINVAL; 728 729 /* only FB_VISUAL_TRUECOLOR supported */ 730 731 red >>= 16 - info->var.red.length; 732 green >>= 16 - info->var.green.length; 733 blue >>= 16 - info->var.blue.length; 734 transp >>= 16 - info->var.transp.length; 735 736 palette[regno] = (red << info->var.red.offset) | 737 (green << info->var.green.offset) | 738 (blue << info->var.blue.offset) | 739 (transp << info->var.transp.offset); 740 741 return 0; 742} 743 744static struct fb_fix_screeninfo sh_mobile_lcdc_fix = { 745 .id = "SH Mobile LCDC", 746 .type = FB_TYPE_PACKED_PIXELS, 747 .visual = FB_VISUAL_TRUECOLOR, 748 .accel = FB_ACCEL_NONE, 749 .xpanstep = 0, 750 .ypanstep = 1, 751 .ywrapstep = 0, 752}; 753 754static void sh_mobile_lcdc_fillrect(struct fb_info *info, 755 const struct fb_fillrect *rect) 756{ 757 sys_fillrect(info, rect); 758 sh_mobile_lcdc_deferred_io_touch(info); 759} 760 761static void sh_mobile_lcdc_copyarea(struct fb_info *info, 762 const struct fb_copyarea *area) 763{ 764 sys_copyarea(info, area); 765 sh_mobile_lcdc_deferred_io_touch(info); 766} 767 768static void sh_mobile_lcdc_imageblit(struct fb_info *info, 769 const struct fb_image *image) 770{ 771 sys_imageblit(info, image); 772 sh_mobile_lcdc_deferred_io_touch(info); 773} 774 775static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var, 776 struct fb_info *info) 777{ 778 struct sh_mobile_lcdc_chan *ch = info->par; 779 struct sh_mobile_lcdc_priv *priv = ch->lcdc; 780 unsigned long ldrcntr; 781 unsigned long new_pan_offset; 782 783 new_pan_offset = (var->yoffset * info->fix.line_length) + 784 (var->xoffset * (info->var.bits_per_pixel / 8)); 785 786 if (new_pan_offset == ch->pan_offset) 787 return 0; /* No change, do nothing */ 788 789 ldrcntr = lcdc_read(priv, _LDRCNTR); 790 791 /* Set the source address for the next refresh */ 792 lcdc_write_chan_mirror(ch, LDSA1R, ch->dma_handle + new_pan_offset); 793 if (lcdc_chan_is_sublcd(ch)) 794 lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_SRS); 795 else 796 lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_MRS); 797 798 ch->pan_offset = new_pan_offset; 799 800 sh_mobile_lcdc_deferred_io_touch(info); 801 802 return 0; 803} 804 805static int sh_mobile_wait_for_vsync(struct fb_info *info) 806{ 807 struct sh_mobile_lcdc_chan *ch = info->par; 808 unsigned long ldintr; 809 int ret; 810 811 /* Enable VSync End interrupt */ 812 ldintr = lcdc_read(ch->lcdc, _LDINTR); 813 ldintr |= LDINTR_VEE; 814 lcdc_write(ch->lcdc, _LDINTR, ldintr); 815 816 ret = wait_for_completion_interruptible_timeout(&ch->vsync_completion, 817 msecs_to_jiffies(100)); 818 if (!ret) 819 return -ETIMEDOUT; 820 821 return 0; 822} 823 824static int sh_mobile_ioctl(struct fb_info *info, unsigned int cmd, 825 unsigned long arg) 826{ 827 int retval; 828 829 switch (cmd) { 830 case FBIO_WAITFORVSYNC: 831 retval = sh_mobile_wait_for_vsync(info); 832 break; 833 834 default: 835 retval = -ENOIOCTLCMD; 836 break; 837 } 838 return retval; 839} 840 841static void sh_mobile_fb_reconfig(struct fb_info *info) 842{ 843 struct sh_mobile_lcdc_chan *ch = info->par; 844 struct fb_videomode mode1, mode2; 845 struct fb_event event; 846 int evnt = FB_EVENT_MODE_CHANGE_ALL; 847 848 if (ch->use_count > 1 || (ch->use_count == 1 && !info->fbcon_par)) 849 /* More framebuffer users are active */ 850 return; 851 852 fb_var_to_videomode(&mode1, &ch->display_var); 853 fb_var_to_videomode(&mode2, &info->var); 854 855 if (fb_mode_is_equal(&mode1, &mode2)) 856 return; 857 858 /* Display has been re-plugged, framebuffer is free now, reconfigure */ 859 if (fb_set_var(info, &ch->display_var) < 0) 860 /* Couldn't reconfigure, hopefully, can continue as before */ 861 return; 862 863 info->fix.line_length = mode2.xres * (ch->cfg.bpp / 8); 864 865 /* 866 * fb_set_var() calls the notifier change internally, only if 867 * FBINFO_MISC_USEREVENT flag is set. Since we do not want to fake a 868 * user event, we have to call the chain ourselves. 869 */ 870 event.info = info; 871 event.data = &mode2; 872 fb_notifier_call_chain(evnt, &event); 873} 874 875/* 876 * Locking: both .fb_release() and .fb_open() are called with info->lock held if 877 * user == 1, or with console sem held, if user == 0. 878 */ 879static int sh_mobile_release(struct fb_info *info, int user) 880{ 881 struct sh_mobile_lcdc_chan *ch = info->par; 882 883 mutex_lock(&ch->open_lock); 884 dev_dbg(info->dev, "%s(): %d users\n", __func__, ch->use_count); 885 886 ch->use_count--; 887 888 /* Nothing to reconfigure, when called from fbcon */ 889 if (user) { 890 acquire_console_sem(); 891 sh_mobile_fb_reconfig(info); 892 release_console_sem(); 893 } 894 895 mutex_unlock(&ch->open_lock); 896 897 return 0; 898} 899 900static int sh_mobile_open(struct fb_info *info, int user) 901{ 902 struct sh_mobile_lcdc_chan *ch = info->par; 903 904 mutex_lock(&ch->open_lock); 905 ch->use_count++; 906 907 dev_dbg(info->dev, "%s(): %d users\n", __func__, ch->use_count); 908 mutex_unlock(&ch->open_lock); 909 910 return 0; 911} 912 913static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 914{ 915 struct sh_mobile_lcdc_chan *ch = info->par; 916 917 if (var->xres > MAX_XRES || var->yres > MAX_YRES || 918 var->xres * var->yres * (ch->cfg.bpp / 8) * 2 > info->fix.smem_len) { 919 dev_warn(info->dev, "Invalid info: %u-%u-%u-%u x %u-%u-%u-%u @ %ukHz!\n", 920 var->left_margin, var->xres, var->right_margin, var->hsync_len, 921 var->upper_margin, var->yres, var->lower_margin, var->vsync_len, 922 PICOS2KHZ(var->pixclock)); 923 return -EINVAL; 924 } 925 return 0; 926} 927 928static struct fb_ops sh_mobile_lcdc_ops = { 929 .owner = THIS_MODULE, 930 .fb_setcolreg = sh_mobile_lcdc_setcolreg, 931 .fb_read = fb_sys_read, 932 .fb_write = fb_sys_write, 933 .fb_fillrect = sh_mobile_lcdc_fillrect, 934 .fb_copyarea = sh_mobile_lcdc_copyarea, 935 .fb_imageblit = sh_mobile_lcdc_imageblit, 936 .fb_pan_display = sh_mobile_fb_pan_display, 937 .fb_ioctl = sh_mobile_ioctl, 938 .fb_open = sh_mobile_open, 939 .fb_release = sh_mobile_release, 940 .fb_check_var = sh_mobile_check_var, 941}; 942 943static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp) 944{ 945 switch (bpp) { 946 case 16: /* PKF[4:0] = 00011 - RGB 565 */ 947 var->red.offset = 11; 948 var->red.length = 5; 949 var->green.offset = 5; 950 var->green.length = 6; 951 var->blue.offset = 0; 952 var->blue.length = 5; 953 var->transp.offset = 0; 954 var->transp.length = 0; 955 break; 956 957 case 32: /* PKF[4:0] = 00000 - RGB 888 958 * sh7722 pdf says 00RRGGBB but reality is GGBB00RR 959 * this may be because LDDDSR has word swap enabled.. 960 */ 961 var->red.offset = 0; 962 var->red.length = 8; 963 var->green.offset = 24; 964 var->green.length = 8; 965 var->blue.offset = 16; 966 var->blue.length = 8; 967 var->transp.offset = 0; 968 var->transp.length = 0; 969 break; 970 default: 971 return -EINVAL; 972 } 973 var->bits_per_pixel = bpp; 974 var->red.msb_right = 0; 975 var->green.msb_right = 0; 976 var->blue.msb_right = 0; 977 var->transp.msb_right = 0; 978 return 0; 979} 980 981static int sh_mobile_lcdc_suspend(struct device *dev) 982{ 983 struct platform_device *pdev = to_platform_device(dev); 984 985 sh_mobile_lcdc_stop(platform_get_drvdata(pdev)); 986 return 0; 987} 988 989static int sh_mobile_lcdc_resume(struct device *dev) 990{ 991 struct platform_device *pdev = to_platform_device(dev); 992 993 return sh_mobile_lcdc_start(platform_get_drvdata(pdev)); 994} 995 996static int sh_mobile_lcdc_runtime_suspend(struct device *dev) 997{ 998 struct platform_device *pdev = to_platform_device(dev); 999 struct sh_mobile_lcdc_priv *p = platform_get_drvdata(pdev); 1000 struct sh_mobile_lcdc_chan *ch; 1001 int k, n; 1002 1003 /* save per-channel registers */ 1004 for (k = 0; k < ARRAY_SIZE(p->ch); k++) { 1005 ch = &p->ch[k]; 1006 if (!ch->enabled) 1007 continue; 1008 for (n = 0; n < NR_CH_REGS; n++) 1009 ch->saved_ch_regs[n] = lcdc_read_chan(ch, n); 1010 } 1011 1012 /* save shared registers */ 1013 for (n = 0; n < NR_SHARED_REGS; n++) 1014 p->saved_shared_regs[n] = lcdc_read(p, lcdc_shared_regs[n]); 1015 1016 /* turn off LCDC hardware */ 1017 lcdc_write(p, _LDCNT1R, 0); 1018 return 0; 1019} 1020 1021static int sh_mobile_lcdc_runtime_resume(struct device *dev) 1022{ 1023 struct platform_device *pdev = to_platform_device(dev); 1024 struct sh_mobile_lcdc_priv *p = platform_get_drvdata(pdev); 1025 struct sh_mobile_lcdc_chan *ch; 1026 int k, n; 1027 1028 /* restore per-channel registers */ 1029 for (k = 0; k < ARRAY_SIZE(p->ch); k++) { 1030 ch = &p->ch[k]; 1031 if (!ch->enabled) 1032 continue; 1033 for (n = 0; n < NR_CH_REGS; n++) 1034 lcdc_write_chan(ch, n, ch->saved_ch_regs[n]); 1035 } 1036 1037 /* restore shared registers */ 1038 for (n = 0; n < NR_SHARED_REGS; n++) 1039 lcdc_write(p, lcdc_shared_regs[n], p->saved_shared_regs[n]); 1040 1041 return 0; 1042} 1043 1044static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = { 1045 .suspend = sh_mobile_lcdc_suspend, 1046 .resume = sh_mobile_lcdc_resume, 1047 .runtime_suspend = sh_mobile_lcdc_runtime_suspend, 1048 .runtime_resume = sh_mobile_lcdc_runtime_resume, 1049}; 1050 1051/* locking: called with info->lock held */ 1052static int sh_mobile_lcdc_notify(struct notifier_block *nb, 1053 unsigned long action, void *data) 1054{ 1055 struct fb_event *event = data; 1056 struct fb_info *info = event->info; 1057 struct sh_mobile_lcdc_chan *ch = info->par; 1058 struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg; 1059 int ret; 1060 1061 if (&ch->lcdc->notifier != nb) 1062 return NOTIFY_DONE; 1063 1064 dev_dbg(info->dev, "%s(): action = %lu, data = %p\n", 1065 __func__, action, event->data); 1066 1067 switch(action) { 1068 case FB_EVENT_SUSPEND: 1069 if (try_module_get(board_cfg->owner) && board_cfg->display_off) { 1070 board_cfg->display_off(board_cfg->board_data); 1071 module_put(board_cfg->owner); 1072 } 1073 pm_runtime_put(info->device); 1074 sh_mobile_lcdc_stop(ch->lcdc); 1075 break; 1076 case FB_EVENT_RESUME: 1077 mutex_lock(&ch->open_lock); 1078 sh_mobile_fb_reconfig(info); 1079 mutex_unlock(&ch->open_lock); 1080 1081 /* HDMI must be enabled before LCDC configuration */ 1082 if (try_module_get(board_cfg->owner) && board_cfg->display_on) { 1083 board_cfg->display_on(board_cfg->board_data, info); 1084 module_put(board_cfg->owner); 1085 } 1086 1087 ret = sh_mobile_lcdc_start(ch->lcdc); 1088 if (!ret) 1089 pm_runtime_get_sync(info->device); 1090 } 1091 1092 return NOTIFY_OK; 1093} 1094 1095static int sh_mobile_lcdc_remove(struct platform_device *pdev); 1096 1097static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) 1098{ 1099 struct fb_info *info; 1100 struct sh_mobile_lcdc_priv *priv; 1101 struct sh_mobile_lcdc_info *pdata = pdev->dev.platform_data; 1102 struct resource *res; 1103 int error; 1104 void *buf; 1105 int i, j; 1106 1107 if (!pdata) { 1108 dev_err(&pdev->dev, "no platform data defined\n"); 1109 return -EINVAL; 1110 } 1111 1112 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1113 i = platform_get_irq(pdev, 0); 1114 if (!res || i < 0) { 1115 dev_err(&pdev->dev, "cannot get platform resources\n"); 1116 return -ENOENT; 1117 } 1118 1119 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 1120 if (!priv) { 1121 dev_err(&pdev->dev, "cannot allocate device data\n"); 1122 return -ENOMEM; 1123 } 1124 1125 platform_set_drvdata(pdev, priv); 1126 1127 error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED, 1128 dev_name(&pdev->dev), priv); 1129 if (error) { 1130 dev_err(&pdev->dev, "unable to request irq\n"); 1131 goto err1; 1132 } 1133 1134 priv->irq = i; 1135 atomic_set(&priv->hw_usecnt, -1); 1136 1137 j = 0; 1138 for (i = 0; i < ARRAY_SIZE(pdata->ch); i++) { 1139 struct sh_mobile_lcdc_chan *ch = priv->ch + j; 1140 1141 ch->lcdc = priv; 1142 memcpy(&ch->cfg, &pdata->ch[i], sizeof(pdata->ch[i])); 1143 1144 error = sh_mobile_lcdc_check_interface(ch); 1145 if (error) { 1146 dev_err(&pdev->dev, "unsupported interface type\n"); 1147 goto err1; 1148 } 1149 init_waitqueue_head(&ch->frame_end_wait); 1150 init_completion(&ch->vsync_completion); 1151 ch->pan_offset = 0; 1152 1153 switch (pdata->ch[i].chan) { 1154 case LCDC_CHAN_MAINLCD: 1155 ch->enabled = 1 << 1; 1156 ch->reg_offs = lcdc_offs_mainlcd; 1157 j++; 1158 break; 1159 case LCDC_CHAN_SUBLCD: 1160 ch->enabled = 1 << 2; 1161 ch->reg_offs = lcdc_offs_sublcd; 1162 j++; 1163 break; 1164 } 1165 } 1166 1167 if (!j) { 1168 dev_err(&pdev->dev, "no channels defined\n"); 1169 error = -EINVAL; 1170 goto err1; 1171 } 1172 1173 priv->base = ioremap_nocache(res->start, resource_size(res)); 1174 if (!priv->base) 1175 goto err1; 1176 1177 error = sh_mobile_lcdc_setup_clocks(pdev, pdata->clock_source, priv); 1178 if (error) { 1179 dev_err(&pdev->dev, "unable to setup clocks\n"); 1180 goto err1; 1181 } 1182 1183 for (i = 0; i < j; i++) { 1184 struct fb_var_screeninfo *var; 1185 const struct fb_videomode *lcd_cfg, *max_cfg = NULL; 1186 struct sh_mobile_lcdc_chan *ch = priv->ch + i; 1187 struct sh_mobile_lcdc_chan_cfg *cfg = &ch->cfg; 1188 const struct fb_videomode *mode = cfg->lcd_cfg; 1189 unsigned long max_size = 0; 1190 int k; 1191 int num_cfg; 1192 1193 ch->info = framebuffer_alloc(0, &pdev->dev); 1194 if (!ch->info) { 1195 dev_err(&pdev->dev, "unable to allocate fb_info\n"); 1196 error = -ENOMEM; 1197 break; 1198 } 1199 1200 info = ch->info; 1201 var = &info->var; 1202 info->fbops = &sh_mobile_lcdc_ops; 1203 info->par = ch; 1204 1205 mutex_init(&ch->open_lock); 1206 1207 for (k = 0, lcd_cfg = mode; 1208 k < cfg->num_cfg && lcd_cfg; 1209 k++, lcd_cfg++) { 1210 unsigned long size = lcd_cfg->yres * lcd_cfg->xres; 1211 1212 if (size > max_size) { 1213 max_cfg = lcd_cfg; 1214 max_size = size; 1215 } 1216 } 1217 1218 if (!mode) 1219 max_size = MAX_XRES * MAX_YRES; 1220 else if (max_cfg) 1221 dev_dbg(&pdev->dev, "Found largest videomode %ux%u\n", 1222 max_cfg->xres, max_cfg->yres); 1223 1224 info->fix = sh_mobile_lcdc_fix; 1225 info->fix.smem_len = max_size * (cfg->bpp / 8) * 2; 1226 1227 if (!mode) { 1228 mode = &default_720p; 1229 num_cfg = 1; 1230 } else { 1231 num_cfg = ch->cfg.num_cfg; 1232 } 1233 1234 fb_videomode_to_modelist(mode, num_cfg, &info->modelist); 1235 1236 fb_videomode_to_var(var, mode); 1237 /* Default Y virtual resolution is 2x panel size */ 1238 var->yres_virtual = var->yres * 2; 1239 var->activate = FB_ACTIVATE_NOW; 1240 1241 error = sh_mobile_lcdc_set_bpp(var, cfg->bpp); 1242 if (error) 1243 break; 1244 1245 buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len, 1246 &ch->dma_handle, GFP_KERNEL); 1247 if (!buf) { 1248 dev_err(&pdev->dev, "unable to allocate buffer\n"); 1249 error = -ENOMEM; 1250 break; 1251 } 1252 1253 info->pseudo_palette = &ch->pseudo_palette; 1254 info->flags = FBINFO_FLAG_DEFAULT; 1255 1256 error = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0); 1257 if (error < 0) { 1258 dev_err(&pdev->dev, "unable to allocate cmap\n"); 1259 dma_free_coherent(&pdev->dev, info->fix.smem_len, 1260 buf, ch->dma_handle); 1261 break; 1262 } 1263 1264 info->fix.smem_start = ch->dma_handle; 1265 info->fix.line_length = var->xres * (cfg->bpp / 8); 1266 info->screen_base = buf; 1267 info->device = &pdev->dev; 1268 ch->display_var = *var; 1269 } 1270 1271 if (error) 1272 goto err1; 1273 1274 error = sh_mobile_lcdc_start(priv); 1275 if (error) { 1276 dev_err(&pdev->dev, "unable to start hardware\n"); 1277 goto err1; 1278 } 1279 1280 for (i = 0; i < j; i++) { 1281 struct sh_mobile_lcdc_chan *ch = priv->ch + i; 1282 1283 info = ch->info; 1284 1285 if (info->fbdefio) { 1286 ch->sglist = vmalloc(sizeof(struct scatterlist) * 1287 info->fix.smem_len >> PAGE_SHIFT); 1288 if (!ch->sglist) { 1289 dev_err(&pdev->dev, "cannot allocate sglist\n"); 1290 goto err1; 1291 } 1292 } 1293 1294 error = register_framebuffer(info); 1295 if (error < 0) 1296 goto err1; 1297 1298 dev_info(info->dev, 1299 "registered %s/%s as %dx%d %dbpp.\n", 1300 pdev->name, 1301 (ch->cfg.chan == LCDC_CHAN_MAINLCD) ? 1302 "mainlcd" : "sublcd", 1303 info->var.xres, info->var.yres, 1304 ch->cfg.bpp); 1305 1306 /* deferred io mode: disable clock to save power */ 1307 if (info->fbdefio || info->state == FBINFO_STATE_SUSPENDED) 1308 sh_mobile_lcdc_clk_off(priv); 1309 } 1310 1311 /* Failure ignored */ 1312 priv->notifier.notifier_call = sh_mobile_lcdc_notify; 1313 fb_register_client(&priv->notifier); 1314 1315 return 0; 1316err1: 1317 sh_mobile_lcdc_remove(pdev); 1318 1319 return error; 1320} 1321 1322static int sh_mobile_lcdc_remove(struct platform_device *pdev) 1323{ 1324 struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev); 1325 struct fb_info *info; 1326 int i; 1327 1328 fb_unregister_client(&priv->notifier); 1329 1330 for (i = 0; i < ARRAY_SIZE(priv->ch); i++) 1331 if (priv->ch[i].info && priv->ch[i].info->dev) 1332 unregister_framebuffer(priv->ch[i].info); 1333 1334 sh_mobile_lcdc_stop(priv); 1335 1336 for (i = 0; i < ARRAY_SIZE(priv->ch); i++) { 1337 info = priv->ch[i].info; 1338 1339 if (!info || !info->device) 1340 continue; 1341 1342 if (priv->ch[i].sglist) 1343 vfree(priv->ch[i].sglist); 1344 1345 if (info->screen_base) 1346 dma_free_coherent(&pdev->dev, info->fix.smem_len, 1347 info->screen_base, 1348 priv->ch[i].dma_handle); 1349 fb_dealloc_cmap(&info->cmap); 1350 framebuffer_release(info); 1351 } 1352 1353 if (priv->dot_clk) 1354 clk_put(priv->dot_clk); 1355 1356 if (priv->dev) 1357 pm_runtime_disable(priv->dev); 1358 1359 if (priv->base) 1360 iounmap(priv->base); 1361 1362 if (priv->irq) 1363 free_irq(priv->irq, priv); 1364 kfree(priv); 1365 return 0; 1366} 1367 1368static struct platform_driver sh_mobile_lcdc_driver = { 1369 .driver = { 1370 .name = "sh_mobile_lcdc_fb", 1371 .owner = THIS_MODULE, 1372 .pm = &sh_mobile_lcdc_dev_pm_ops, 1373 }, 1374 .probe = sh_mobile_lcdc_probe, 1375 .remove = sh_mobile_lcdc_remove, 1376}; 1377 1378static int __init sh_mobile_lcdc_init(void) 1379{ 1380 return platform_driver_register(&sh_mobile_lcdc_driver); 1381} 1382 1383static void __exit sh_mobile_lcdc_exit(void) 1384{ 1385 platform_driver_unregister(&sh_mobile_lcdc_driver); 1386} 1387 1388module_init(sh_mobile_lcdc_init); 1389module_exit(sh_mobile_lcdc_exit); 1390 1391MODULE_DESCRIPTION("SuperH Mobile LCDC Framebuffer driver"); 1392MODULE_AUTHOR("Magnus Damm <damm@opensource.se>"); 1393MODULE_LICENSE("GPL v2"); 1394