sh_mobile_lcdcfb.c revision 9a2985e7f943678154f5761dad753f1987c2fdd0
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/atomic.h> 12#include <linux/backlight.h> 13#include <linux/clk.h> 14#include <linux/console.h> 15#include <linux/dma-mapping.h> 16#include <linux/delay.h> 17#include <linux/gpio.h> 18#include <linux/init.h> 19#include <linux/interrupt.h> 20#include <linux/ioctl.h> 21#include <linux/kernel.h> 22#include <linux/mm.h> 23#include <linux/module.h> 24#include <linux/platform_device.h> 25#include <linux/pm_runtime.h> 26#include <linux/slab.h> 27#include <linux/videodev2.h> 28#include <linux/vmalloc.h> 29 30#include <video/sh_mobile_lcdc.h> 31#include <video/sh_mobile_meram.h> 32 33#include "sh_mobile_lcdcfb.h" 34 35#define SIDE_B_OFFSET 0x1000 36#define MIRROR_OFFSET 0x2000 37 38#define MAX_XRES 1920 39#define MAX_YRES 1080 40 41struct sh_mobile_lcdc_priv { 42 void __iomem *base; 43 int irq; 44 atomic_t hw_usecnt; 45 struct device *dev; 46 struct clk *dot_clk; 47 unsigned long lddckr; 48 struct sh_mobile_lcdc_chan ch[2]; 49 struct notifier_block notifier; 50 int started; 51 int forced_fourcc; /* 2 channel LCDC must share fourcc setting */ 52 struct sh_mobile_meram_info *meram_dev; 53}; 54 55/* ----------------------------------------------------------------------------- 56 * Registers access 57 */ 58 59static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = { 60 [LDDCKPAT1R] = 0x400, 61 [LDDCKPAT2R] = 0x404, 62 [LDMT1R] = 0x418, 63 [LDMT2R] = 0x41c, 64 [LDMT3R] = 0x420, 65 [LDDFR] = 0x424, 66 [LDSM1R] = 0x428, 67 [LDSM2R] = 0x42c, 68 [LDSA1R] = 0x430, 69 [LDSA2R] = 0x434, 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 97static bool banked(int reg_nr) 98{ 99 switch (reg_nr) { 100 case LDMT1R: 101 case LDMT2R: 102 case LDMT3R: 103 case LDDFR: 104 case LDSM1R: 105 case LDSA1R: 106 case LDSA2R: 107 case LDMLSR: 108 case LDHCNR: 109 case LDHSYNR: 110 case LDVLNR: 111 case LDVSYNR: 112 return true; 113 } 114 return false; 115} 116 117static int lcdc_chan_is_sublcd(struct sh_mobile_lcdc_chan *chan) 118{ 119 return chan->cfg.chan == LCDC_CHAN_SUBLCD; 120} 121 122static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan, 123 int reg_nr, unsigned long data) 124{ 125 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr]); 126 if (banked(reg_nr)) 127 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] + 128 SIDE_B_OFFSET); 129} 130 131static void lcdc_write_chan_mirror(struct sh_mobile_lcdc_chan *chan, 132 int reg_nr, unsigned long data) 133{ 134 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] + 135 MIRROR_OFFSET); 136} 137 138static unsigned long lcdc_read_chan(struct sh_mobile_lcdc_chan *chan, 139 int reg_nr) 140{ 141 return ioread32(chan->lcdc->base + chan->reg_offs[reg_nr]); 142} 143 144static void lcdc_write(struct sh_mobile_lcdc_priv *priv, 145 unsigned long reg_offs, unsigned long data) 146{ 147 iowrite32(data, priv->base + reg_offs); 148} 149 150static unsigned long lcdc_read(struct sh_mobile_lcdc_priv *priv, 151 unsigned long reg_offs) 152{ 153 return ioread32(priv->base + reg_offs); 154} 155 156static void lcdc_wait_bit(struct sh_mobile_lcdc_priv *priv, 157 unsigned long reg_offs, 158 unsigned long mask, unsigned long until) 159{ 160 while ((lcdc_read(priv, reg_offs) & mask) != until) 161 cpu_relax(); 162} 163 164/* ----------------------------------------------------------------------------- 165 * Clock management 166 */ 167 168static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv) 169{ 170 if (atomic_inc_and_test(&priv->hw_usecnt)) { 171 if (priv->dot_clk) 172 clk_enable(priv->dot_clk); 173 pm_runtime_get_sync(priv->dev); 174 if (priv->meram_dev && priv->meram_dev->pdev) 175 pm_runtime_get_sync(&priv->meram_dev->pdev->dev); 176 } 177} 178 179static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv) 180{ 181 if (atomic_sub_return(1, &priv->hw_usecnt) == -1) { 182 if (priv->meram_dev && priv->meram_dev->pdev) 183 pm_runtime_put_sync(&priv->meram_dev->pdev->dev); 184 pm_runtime_put(priv->dev); 185 if (priv->dot_clk) 186 clk_disable(priv->dot_clk); 187 } 188} 189 190static int sh_mobile_lcdc_setup_clocks(struct sh_mobile_lcdc_priv *priv, 191 int clock_source) 192{ 193 struct clk *clk; 194 char *str; 195 196 switch (clock_source) { 197 case LCDC_CLK_BUS: 198 str = "bus_clk"; 199 priv->lddckr = LDDCKR_ICKSEL_BUS; 200 break; 201 case LCDC_CLK_PERIPHERAL: 202 str = "peripheral_clk"; 203 priv->lddckr = LDDCKR_ICKSEL_MIPI; 204 break; 205 case LCDC_CLK_EXTERNAL: 206 str = NULL; 207 priv->lddckr = LDDCKR_ICKSEL_HDMI; 208 break; 209 default: 210 return -EINVAL; 211 } 212 213 if (str == NULL) 214 return 0; 215 216 clk = clk_get(priv->dev, str); 217 if (IS_ERR(clk)) { 218 dev_err(priv->dev, "cannot get dot clock %s\n", str); 219 return PTR_ERR(clk); 220 } 221 222 priv->dot_clk = clk; 223 return 0; 224} 225 226/* ----------------------------------------------------------------------------- 227 * Display, panel and deferred I/O 228 */ 229 230static void lcdc_sys_write_index(void *handle, unsigned long data) 231{ 232 struct sh_mobile_lcdc_chan *ch = handle; 233 234 lcdc_write(ch->lcdc, _LDDWD0R, data | LDDWDxR_WDACT); 235 lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0); 236 lcdc_write(ch->lcdc, _LDDWAR, LDDWAR_WA | 237 (lcdc_chan_is_sublcd(ch) ? 2 : 0)); 238 lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0); 239} 240 241static void lcdc_sys_write_data(void *handle, unsigned long data) 242{ 243 struct sh_mobile_lcdc_chan *ch = handle; 244 245 lcdc_write(ch->lcdc, _LDDWD0R, data | LDDWDxR_WDACT | LDDWDxR_RSW); 246 lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0); 247 lcdc_write(ch->lcdc, _LDDWAR, LDDWAR_WA | 248 (lcdc_chan_is_sublcd(ch) ? 2 : 0)); 249 lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0); 250} 251 252static unsigned long lcdc_sys_read_data(void *handle) 253{ 254 struct sh_mobile_lcdc_chan *ch = handle; 255 256 lcdc_write(ch->lcdc, _LDDRDR, LDDRDR_RSR); 257 lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0); 258 lcdc_write(ch->lcdc, _LDDRAR, LDDRAR_RA | 259 (lcdc_chan_is_sublcd(ch) ? 2 : 0)); 260 udelay(1); 261 lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0); 262 263 return lcdc_read(ch->lcdc, _LDDRDR) & LDDRDR_DRD_MASK; 264} 265 266struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = { 267 lcdc_sys_write_index, 268 lcdc_sys_write_data, 269 lcdc_sys_read_data, 270}; 271 272static int sh_mobile_lcdc_sginit(struct fb_info *info, 273 struct list_head *pagelist) 274{ 275 struct sh_mobile_lcdc_chan *ch = info->par; 276 unsigned int nr_pages_max = info->fix.smem_len >> PAGE_SHIFT; 277 struct page *page; 278 int nr_pages = 0; 279 280 sg_init_table(ch->sglist, nr_pages_max); 281 282 list_for_each_entry(page, pagelist, lru) 283 sg_set_page(&ch->sglist[nr_pages++], page, PAGE_SIZE, 0); 284 285 return nr_pages; 286} 287 288static void sh_mobile_lcdc_deferred_io(struct fb_info *info, 289 struct list_head *pagelist) 290{ 291 struct sh_mobile_lcdc_chan *ch = info->par; 292 struct sh_mobile_lcdc_board_cfg *bcfg = &ch->cfg.board_cfg; 293 294 /* enable clocks before accessing hardware */ 295 sh_mobile_lcdc_clk_on(ch->lcdc); 296 297 /* 298 * It's possible to get here without anything on the pagelist via 299 * sh_mobile_lcdc_deferred_io_touch() or via a userspace fsync() 300 * invocation. In the former case, the acceleration routines are 301 * stepped in to when using the framebuffer console causing the 302 * workqueue to be scheduled without any dirty pages on the list. 303 * 304 * Despite this, a panel update is still needed given that the 305 * acceleration routines have their own methods for writing in 306 * that still need to be updated. 307 * 308 * The fsync() and empty pagelist case could be optimized for, 309 * but we don't bother, as any application exhibiting such 310 * behaviour is fundamentally broken anyways. 311 */ 312 if (!list_empty(pagelist)) { 313 unsigned int nr_pages = sh_mobile_lcdc_sginit(info, pagelist); 314 315 /* trigger panel update */ 316 dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE); 317 if (bcfg->start_transfer) 318 bcfg->start_transfer(bcfg->board_data, ch, 319 &sh_mobile_lcdc_sys_bus_ops); 320 lcdc_write_chan(ch, LDSM2R, LDSM2R_OSTRG); 321 dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE); 322 } else { 323 if (bcfg->start_transfer) 324 bcfg->start_transfer(bcfg->board_data, ch, 325 &sh_mobile_lcdc_sys_bus_ops); 326 lcdc_write_chan(ch, LDSM2R, LDSM2R_OSTRG); 327 } 328} 329 330static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info) 331{ 332 struct fb_deferred_io *fbdefio = info->fbdefio; 333 334 if (fbdefio) 335 schedule_delayed_work(&info->deferred_work, fbdefio->delay); 336} 337 338static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan *ch) 339{ 340 struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg; 341 342 if (ch->tx_dev) { 343 if (ch->tx_dev->ops->display_on(ch->tx_dev, ch->info) < 0) 344 return; 345 } 346 347 /* HDMI must be enabled before LCDC configuration */ 348 if (board_cfg->display_on && try_module_get(board_cfg->owner)) { 349 board_cfg->display_on(board_cfg->board_data, ch->info); 350 module_put(board_cfg->owner); 351 } 352} 353 354static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch) 355{ 356 struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg; 357 358 if (board_cfg->display_off && try_module_get(board_cfg->owner)) { 359 board_cfg->display_off(board_cfg->board_data); 360 module_put(board_cfg->owner); 361 } 362 363 if (ch->tx_dev) 364 ch->tx_dev->ops->display_off(ch->tx_dev); 365} 366 367/* ----------------------------------------------------------------------------- 368 * Format helpers 369 */ 370 371static int sh_mobile_format_fourcc(const struct fb_var_screeninfo *var) 372{ 373 if (var->grayscale > 1) 374 return var->grayscale; 375 376 switch (var->bits_per_pixel) { 377 case 16: 378 return V4L2_PIX_FMT_RGB565; 379 case 24: 380 return V4L2_PIX_FMT_BGR24; 381 case 32: 382 return V4L2_PIX_FMT_BGR32; 383 default: 384 return 0; 385 } 386} 387 388static int sh_mobile_format_is_fourcc(const struct fb_var_screeninfo *var) 389{ 390 return var->grayscale > 1; 391} 392 393static bool sh_mobile_format_is_yuv(const struct fb_var_screeninfo *var) 394{ 395 if (var->grayscale <= 1) 396 return false; 397 398 switch (var->grayscale) { 399 case V4L2_PIX_FMT_NV12: 400 case V4L2_PIX_FMT_NV21: 401 case V4L2_PIX_FMT_NV16: 402 case V4L2_PIX_FMT_NV61: 403 case V4L2_PIX_FMT_NV24: 404 case V4L2_PIX_FMT_NV42: 405 return true; 406 407 default: 408 return false; 409 } 410} 411 412/* ----------------------------------------------------------------------------- 413 * Start, stop and IRQ 414 */ 415 416static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data) 417{ 418 struct sh_mobile_lcdc_priv *priv = data; 419 struct sh_mobile_lcdc_chan *ch; 420 unsigned long ldintr; 421 int is_sub; 422 int k; 423 424 /* Acknowledge interrupts and disable further VSYNC End IRQs. */ 425 ldintr = lcdc_read(priv, _LDINTR); 426 lcdc_write(priv, _LDINTR, (ldintr ^ LDINTR_STATUS_MASK) & ~LDINTR_VEE); 427 428 /* figure out if this interrupt is for main or sub lcd */ 429 is_sub = (lcdc_read(priv, _LDSR) & LDSR_MSS) ? 1 : 0; 430 431 /* wake up channel and disable clocks */ 432 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 433 ch = &priv->ch[k]; 434 435 if (!ch->enabled) 436 continue; 437 438 /* Frame End */ 439 if (ldintr & LDINTR_FS) { 440 if (is_sub == lcdc_chan_is_sublcd(ch)) { 441 ch->frame_end = 1; 442 wake_up(&ch->frame_end_wait); 443 444 sh_mobile_lcdc_clk_off(priv); 445 } 446 } 447 448 /* VSYNC End */ 449 if (ldintr & LDINTR_VES) 450 complete(&ch->vsync_completion); 451 } 452 453 return IRQ_HANDLED; 454} 455 456static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv, 457 int start) 458{ 459 unsigned long tmp = lcdc_read(priv, _LDCNT2R); 460 int k; 461 462 /* start or stop the lcdc */ 463 if (start) 464 lcdc_write(priv, _LDCNT2R, tmp | LDCNT2R_DO); 465 else 466 lcdc_write(priv, _LDCNT2R, tmp & ~LDCNT2R_DO); 467 468 /* wait until power is applied/stopped on all channels */ 469 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) 470 if (lcdc_read(priv, _LDCNT2R) & priv->ch[k].enabled) 471 while (1) { 472 tmp = lcdc_read_chan(&priv->ch[k], LDPMR) 473 & LDPMR_LPS; 474 if (start && tmp == LDPMR_LPS) 475 break; 476 if (!start && tmp == 0) 477 break; 478 cpu_relax(); 479 } 480 481 if (!start) 482 lcdc_write(priv, _LDDCKSTPR, 1); /* stop dotclock */ 483} 484 485static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch) 486{ 487 struct fb_var_screeninfo *var = &ch->info->var, *display_var = &ch->display_var; 488 unsigned long h_total, hsync_pos, display_h_total; 489 u32 tmp; 490 491 tmp = ch->ldmt1r_value; 492 tmp |= (var->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : LDMT1R_VPOL; 493 tmp |= (var->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : LDMT1R_HPOL; 494 tmp |= (ch->cfg.flags & LCDC_FLAGS_DWPOL) ? LDMT1R_DWPOL : 0; 495 tmp |= (ch->cfg.flags & LCDC_FLAGS_DIPOL) ? LDMT1R_DIPOL : 0; 496 tmp |= (ch->cfg.flags & LCDC_FLAGS_DAPOL) ? LDMT1R_DAPOL : 0; 497 tmp |= (ch->cfg.flags & LCDC_FLAGS_HSCNT) ? LDMT1R_HSCNT : 0; 498 tmp |= (ch->cfg.flags & LCDC_FLAGS_DWCNT) ? LDMT1R_DWCNT : 0; 499 lcdc_write_chan(ch, LDMT1R, tmp); 500 501 /* setup SYS bus */ 502 lcdc_write_chan(ch, LDMT2R, ch->cfg.sys_bus_cfg.ldmt2r); 503 lcdc_write_chan(ch, LDMT3R, ch->cfg.sys_bus_cfg.ldmt3r); 504 505 /* horizontal configuration */ 506 h_total = display_var->xres + display_var->hsync_len + 507 display_var->left_margin + display_var->right_margin; 508 tmp = h_total / 8; /* HTCN */ 509 tmp |= (min(display_var->xres, var->xres) / 8) << 16; /* HDCN */ 510 lcdc_write_chan(ch, LDHCNR, tmp); 511 512 hsync_pos = display_var->xres + display_var->right_margin; 513 tmp = hsync_pos / 8; /* HSYNP */ 514 tmp |= (display_var->hsync_len / 8) << 16; /* HSYNW */ 515 lcdc_write_chan(ch, LDHSYNR, tmp); 516 517 /* vertical configuration */ 518 tmp = display_var->yres + display_var->vsync_len + 519 display_var->upper_margin + display_var->lower_margin; /* VTLN */ 520 tmp |= min(display_var->yres, var->yres) << 16; /* VDLN */ 521 lcdc_write_chan(ch, LDVLNR, tmp); 522 523 tmp = display_var->yres + display_var->lower_margin; /* VSYNP */ 524 tmp |= display_var->vsync_len << 16; /* VSYNW */ 525 lcdc_write_chan(ch, LDVSYNR, tmp); 526 527 /* Adjust horizontal synchronisation for HDMI */ 528 display_h_total = display_var->xres + display_var->hsync_len + 529 display_var->left_margin + display_var->right_margin; 530 tmp = ((display_var->xres & 7) << 24) | 531 ((display_h_total & 7) << 16) | 532 ((display_var->hsync_len & 7) << 8) | 533 (hsync_pos & 7); 534 lcdc_write_chan(ch, LDHAJR, tmp); 535} 536 537/* 538 * __sh_mobile_lcdc_start - Configure and tart the LCDC 539 * @priv: LCDC device 540 * 541 * Configure all enabled channels and start the LCDC device. All external 542 * devices (clocks, MERAM, panels, ...) are not touched by this function. 543 */ 544static void __sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) 545{ 546 struct sh_mobile_lcdc_chan *ch; 547 unsigned long tmp; 548 int k, m; 549 550 /* Enable LCDC channels. Read data from external memory, avoid using the 551 * BEU for now. 552 */ 553 lcdc_write(priv, _LDCNT2R, priv->ch[0].enabled | priv->ch[1].enabled); 554 555 /* Stop the LCDC first and disable all interrupts. */ 556 sh_mobile_lcdc_start_stop(priv, 0); 557 lcdc_write(priv, _LDINTR, 0); 558 559 /* Configure power supply, dot clocks and start them. */ 560 tmp = priv->lddckr; 561 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 562 ch = &priv->ch[k]; 563 if (!ch->enabled) 564 continue; 565 566 /* Power supply */ 567 lcdc_write_chan(ch, LDPMR, 0); 568 569 m = ch->cfg.clock_divider; 570 if (!m) 571 continue; 572 573 /* FIXME: sh7724 can only use 42, 48, 54 and 60 for the divider 574 * denominator. 575 */ 576 lcdc_write_chan(ch, LDDCKPAT1R, 0); 577 lcdc_write_chan(ch, LDDCKPAT2R, (1 << (m/2)) - 1); 578 579 if (m == 1) 580 m = LDDCKR_MOSEL; 581 tmp |= m << (lcdc_chan_is_sublcd(ch) ? 8 : 0); 582 } 583 584 lcdc_write(priv, _LDDCKR, tmp); 585 lcdc_write(priv, _LDDCKSTPR, 0); 586 lcdc_wait_bit(priv, _LDDCKSTPR, ~0, 0); 587 588 /* Setup geometry, format, frame buffer memory and operation mode. */ 589 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 590 ch = &priv->ch[k]; 591 if (!ch->enabled) 592 continue; 593 594 sh_mobile_lcdc_geometry(ch); 595 596 switch (sh_mobile_format_fourcc(&ch->info->var)) { 597 case V4L2_PIX_FMT_RGB565: 598 tmp = LDDFR_PKF_RGB16; 599 break; 600 case V4L2_PIX_FMT_BGR24: 601 tmp = LDDFR_PKF_RGB24; 602 break; 603 case V4L2_PIX_FMT_BGR32: 604 tmp = LDDFR_PKF_ARGB32; 605 break; 606 case V4L2_PIX_FMT_NV12: 607 case V4L2_PIX_FMT_NV21: 608 tmp = LDDFR_CC | LDDFR_YF_420; 609 break; 610 case V4L2_PIX_FMT_NV16: 611 case V4L2_PIX_FMT_NV61: 612 tmp = LDDFR_CC | LDDFR_YF_422; 613 break; 614 case V4L2_PIX_FMT_NV24: 615 case V4L2_PIX_FMT_NV42: 616 tmp = LDDFR_CC | LDDFR_YF_444; 617 break; 618 } 619 620 if (sh_mobile_format_is_yuv(&ch->info->var)) { 621 switch (ch->info->var.colorspace) { 622 case V4L2_COLORSPACE_REC709: 623 tmp |= LDDFR_CF1; 624 break; 625 case V4L2_COLORSPACE_JPEG: 626 tmp |= LDDFR_CF0; 627 break; 628 } 629 } 630 631 lcdc_write_chan(ch, LDDFR, tmp); 632 lcdc_write_chan(ch, LDMLSR, ch->pitch); 633 lcdc_write_chan(ch, LDSA1R, ch->base_addr_y); 634 if (sh_mobile_format_is_yuv(&ch->info->var)) 635 lcdc_write_chan(ch, LDSA2R, ch->base_addr_c); 636 637 /* When using deferred I/O mode, configure the LCDC for one-shot 638 * operation and enable the frame end interrupt. Otherwise use 639 * continuous read mode. 640 */ 641 if (ch->ldmt1r_value & LDMT1R_IFM && 642 ch->cfg.sys_bus_cfg.deferred_io_msec) { 643 lcdc_write_chan(ch, LDSM1R, LDSM1R_OS); 644 lcdc_write(priv, _LDINTR, LDINTR_FE); 645 } else { 646 lcdc_write_chan(ch, LDSM1R, 0); 647 } 648 } 649 650 /* Word and long word swap. */ 651 switch (sh_mobile_format_fourcc(&priv->ch[0].info->var)) { 652 case V4L2_PIX_FMT_RGB565: 653 case V4L2_PIX_FMT_NV21: 654 case V4L2_PIX_FMT_NV61: 655 case V4L2_PIX_FMT_NV42: 656 tmp = LDDDSR_LS | LDDDSR_WS; 657 break; 658 case V4L2_PIX_FMT_BGR24: 659 case V4L2_PIX_FMT_NV12: 660 case V4L2_PIX_FMT_NV16: 661 case V4L2_PIX_FMT_NV24: 662 tmp = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS; 663 break; 664 case V4L2_PIX_FMT_BGR32: 665 default: 666 tmp = LDDDSR_LS; 667 break; 668 } 669 lcdc_write(priv, _LDDDSR, tmp); 670 671 /* Enable the display output. */ 672 lcdc_write(priv, _LDCNT1R, LDCNT1R_DE); 673 sh_mobile_lcdc_start_stop(priv, 1); 674 priv->started = 1; 675} 676 677static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) 678{ 679 struct sh_mobile_meram_info *mdev = priv->meram_dev; 680 struct sh_mobile_lcdc_chan *ch; 681 unsigned long tmp; 682 int ret; 683 int k; 684 685 /* enable clocks before accessing the hardware */ 686 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 687 if (priv->ch[k].enabled) 688 sh_mobile_lcdc_clk_on(priv); 689 } 690 691 /* reset */ 692 lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) | LDCNT2R_BR); 693 lcdc_wait_bit(priv, _LDCNT2R, LDCNT2R_BR, 0); 694 695 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 696 struct sh_mobile_lcdc_board_cfg *board_cfg; 697 698 ch = &priv->ch[k]; 699 if (!ch->enabled) 700 continue; 701 702 board_cfg = &ch->cfg.board_cfg; 703 if (board_cfg->setup_sys) { 704 ret = board_cfg->setup_sys(board_cfg->board_data, ch, 705 &sh_mobile_lcdc_sys_bus_ops); 706 if (ret) 707 return ret; 708 } 709 } 710 711 /* Compute frame buffer base address and pitch for each channel. */ 712 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 713 struct sh_mobile_meram_cfg *cfg; 714 int pixelformat; 715 716 ch = &priv->ch[k]; 717 if (!ch->enabled) 718 continue; 719 720 ch->base_addr_y = ch->info->fix.smem_start; 721 ch->base_addr_c = ch->base_addr_y 722 + ch->info->var.xres 723 * ch->info->var.yres_virtual; 724 ch->pitch = ch->info->fix.line_length; 725 726 /* Enable MERAM if possible. */ 727 cfg = ch->cfg.meram_cfg; 728 if (mdev == NULL || mdev->ops == NULL || cfg == NULL) 729 continue; 730 731 /* we need to de-init configured ICBs before we can 732 * re-initialize them. 733 */ 734 if (ch->meram_enabled) { 735 mdev->ops->meram_unregister(mdev, cfg); 736 ch->meram_enabled = 0; 737 } 738 739 switch (sh_mobile_format_fourcc(&ch->info->var)) { 740 case V4L2_PIX_FMT_NV12: 741 case V4L2_PIX_FMT_NV21: 742 case V4L2_PIX_FMT_NV16: 743 case V4L2_PIX_FMT_NV61: 744 pixelformat = SH_MOBILE_MERAM_PF_NV; 745 break; 746 case V4L2_PIX_FMT_NV24: 747 case V4L2_PIX_FMT_NV42: 748 pixelformat = SH_MOBILE_MERAM_PF_NV24; 749 break; 750 case V4L2_PIX_FMT_RGB565: 751 case V4L2_PIX_FMT_BGR24: 752 case V4L2_PIX_FMT_BGR32: 753 default: 754 pixelformat = SH_MOBILE_MERAM_PF_RGB; 755 break; 756 } 757 758 ret = mdev->ops->meram_register(mdev, cfg, ch->pitch, 759 ch->info->var.yres, pixelformat, 760 ch->base_addr_y, ch->base_addr_c, 761 &ch->base_addr_y, &ch->base_addr_c, 762 &ch->pitch); 763 if (!ret) 764 ch->meram_enabled = 1; 765 } 766 767 /* Start the LCDC. */ 768 __sh_mobile_lcdc_start(priv); 769 770 /* Setup deferred I/O, tell the board code to enable the panels, and 771 * turn backlight on. 772 */ 773 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 774 ch = &priv->ch[k]; 775 if (!ch->enabled) 776 continue; 777 778 tmp = ch->cfg.sys_bus_cfg.deferred_io_msec; 779 if (ch->ldmt1r_value & LDMT1R_IFM && tmp) { 780 ch->defio.deferred_io = sh_mobile_lcdc_deferred_io; 781 ch->defio.delay = msecs_to_jiffies(tmp); 782 ch->info->fbdefio = &ch->defio; 783 fb_deferred_io_init(ch->info); 784 } 785 786 sh_mobile_lcdc_display_on(ch); 787 788 if (ch->bl) { 789 ch->bl->props.power = FB_BLANK_UNBLANK; 790 backlight_update_status(ch->bl); 791 } 792 } 793 794 return 0; 795} 796 797static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) 798{ 799 struct sh_mobile_lcdc_chan *ch; 800 int k; 801 802 /* clean up deferred io and ask board code to disable panel */ 803 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 804 ch = &priv->ch[k]; 805 if (!ch->enabled) 806 continue; 807 808 /* deferred io mode: 809 * flush frame, and wait for frame end interrupt 810 * clean up deferred io and enable clock 811 */ 812 if (ch->info && ch->info->fbdefio) { 813 ch->frame_end = 0; 814 schedule_delayed_work(&ch->info->deferred_work, 0); 815 wait_event(ch->frame_end_wait, ch->frame_end); 816 fb_deferred_io_cleanup(ch->info); 817 ch->info->fbdefio = NULL; 818 sh_mobile_lcdc_clk_on(priv); 819 } 820 821 if (ch->bl) { 822 ch->bl->props.power = FB_BLANK_POWERDOWN; 823 backlight_update_status(ch->bl); 824 } 825 826 sh_mobile_lcdc_display_off(ch); 827 828 /* disable the meram */ 829 if (ch->meram_enabled) { 830 struct sh_mobile_meram_cfg *cfg; 831 struct sh_mobile_meram_info *mdev; 832 cfg = ch->cfg.meram_cfg; 833 mdev = priv->meram_dev; 834 mdev->ops->meram_unregister(mdev, cfg); 835 ch->meram_enabled = 0; 836 } 837 838 } 839 840 /* stop the lcdc */ 841 if (priv->started) { 842 sh_mobile_lcdc_start_stop(priv, 0); 843 priv->started = 0; 844 } 845 846 /* stop clocks */ 847 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) 848 if (priv->ch[k].enabled) 849 sh_mobile_lcdc_clk_off(priv); 850} 851 852/* ----------------------------------------------------------------------------- 853 * Frame buffer operations 854 */ 855 856static int sh_mobile_lcdc_setcolreg(u_int regno, 857 u_int red, u_int green, u_int blue, 858 u_int transp, struct fb_info *info) 859{ 860 u32 *palette = info->pseudo_palette; 861 862 if (regno >= PALETTE_NR) 863 return -EINVAL; 864 865 /* only FB_VISUAL_TRUECOLOR supported */ 866 867 red >>= 16 - info->var.red.length; 868 green >>= 16 - info->var.green.length; 869 blue >>= 16 - info->var.blue.length; 870 transp >>= 16 - info->var.transp.length; 871 872 palette[regno] = (red << info->var.red.offset) | 873 (green << info->var.green.offset) | 874 (blue << info->var.blue.offset) | 875 (transp << info->var.transp.offset); 876 877 return 0; 878} 879 880static struct fb_fix_screeninfo sh_mobile_lcdc_fix = { 881 .id = "SH Mobile LCDC", 882 .type = FB_TYPE_PACKED_PIXELS, 883 .visual = FB_VISUAL_TRUECOLOR, 884 .accel = FB_ACCEL_NONE, 885 .xpanstep = 0, 886 .ypanstep = 1, 887 .ywrapstep = 0, 888 .capabilities = FB_CAP_FOURCC, 889}; 890 891static void sh_mobile_lcdc_fillrect(struct fb_info *info, 892 const struct fb_fillrect *rect) 893{ 894 sys_fillrect(info, rect); 895 sh_mobile_lcdc_deferred_io_touch(info); 896} 897 898static void sh_mobile_lcdc_copyarea(struct fb_info *info, 899 const struct fb_copyarea *area) 900{ 901 sys_copyarea(info, area); 902 sh_mobile_lcdc_deferred_io_touch(info); 903} 904 905static void sh_mobile_lcdc_imageblit(struct fb_info *info, 906 const struct fb_image *image) 907{ 908 sys_imageblit(info, image); 909 sh_mobile_lcdc_deferred_io_touch(info); 910} 911 912static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var, 913 struct fb_info *info) 914{ 915 struct sh_mobile_lcdc_chan *ch = info->par; 916 struct sh_mobile_lcdc_priv *priv = ch->lcdc; 917 unsigned long ldrcntr; 918 unsigned long new_pan_offset; 919 unsigned long base_addr_y, base_addr_c; 920 unsigned long c_offset; 921 bool yuv = sh_mobile_format_is_yuv(&info->var); 922 923 if (!yuv) 924 new_pan_offset = var->yoffset * info->fix.line_length 925 + var->xoffset * (info->var.bits_per_pixel / 8); 926 else 927 new_pan_offset = var->yoffset * info->fix.line_length 928 + var->xoffset; 929 930 if (new_pan_offset == ch->pan_offset) 931 return 0; /* No change, do nothing */ 932 933 ldrcntr = lcdc_read(priv, _LDRCNTR); 934 935 /* Set the source address for the next refresh */ 936 base_addr_y = ch->dma_handle + new_pan_offset; 937 if (yuv) { 938 /* Set y offset */ 939 c_offset = var->yoffset * info->fix.line_length 940 * (info->var.bits_per_pixel - 8) / 8; 941 base_addr_c = ch->dma_handle 942 + info->var.xres * info->var.yres_virtual 943 + c_offset; 944 /* Set x offset */ 945 if (sh_mobile_format_fourcc(&info->var) == V4L2_PIX_FMT_NV24) 946 base_addr_c += 2 * var->xoffset; 947 else 948 base_addr_c += var->xoffset; 949 } 950 951 if (ch->meram_enabled) { 952 struct sh_mobile_meram_cfg *cfg; 953 struct sh_mobile_meram_info *mdev; 954 int ret; 955 956 cfg = ch->cfg.meram_cfg; 957 mdev = priv->meram_dev; 958 ret = mdev->ops->meram_update(mdev, cfg, 959 base_addr_y, base_addr_c, 960 &base_addr_y, &base_addr_c); 961 if (ret) 962 return ret; 963 } 964 965 ch->base_addr_y = base_addr_y; 966 ch->base_addr_c = base_addr_c; 967 968 lcdc_write_chan_mirror(ch, LDSA1R, base_addr_y); 969 if (yuv) 970 lcdc_write_chan_mirror(ch, LDSA2R, base_addr_c); 971 972 if (lcdc_chan_is_sublcd(ch)) 973 lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_SRS); 974 else 975 lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_MRS); 976 977 ch->pan_offset = new_pan_offset; 978 979 sh_mobile_lcdc_deferred_io_touch(info); 980 981 return 0; 982} 983 984static int sh_mobile_wait_for_vsync(struct fb_info *info) 985{ 986 struct sh_mobile_lcdc_chan *ch = info->par; 987 unsigned long ldintr; 988 int ret; 989 990 /* Enable VSync End interrupt and be careful not to acknowledge any 991 * pending interrupt. 992 */ 993 ldintr = lcdc_read(ch->lcdc, _LDINTR); 994 ldintr |= LDINTR_VEE | LDINTR_STATUS_MASK; 995 lcdc_write(ch->lcdc, _LDINTR, ldintr); 996 997 ret = wait_for_completion_interruptible_timeout(&ch->vsync_completion, 998 msecs_to_jiffies(100)); 999 if (!ret) 1000 return -ETIMEDOUT; 1001 1002 return 0; 1003} 1004 1005static int sh_mobile_ioctl(struct fb_info *info, unsigned int cmd, 1006 unsigned long arg) 1007{ 1008 int retval; 1009 1010 switch (cmd) { 1011 case FBIO_WAITFORVSYNC: 1012 retval = sh_mobile_wait_for_vsync(info); 1013 break; 1014 1015 default: 1016 retval = -ENOIOCTLCMD; 1017 break; 1018 } 1019 return retval; 1020} 1021 1022static void sh_mobile_fb_reconfig(struct fb_info *info) 1023{ 1024 struct sh_mobile_lcdc_chan *ch = info->par; 1025 struct fb_videomode mode1, mode2; 1026 struct fb_event event; 1027 int evnt = FB_EVENT_MODE_CHANGE_ALL; 1028 1029 if (ch->use_count > 1 || (ch->use_count == 1 && !info->fbcon_par)) 1030 /* More framebuffer users are active */ 1031 return; 1032 1033 fb_var_to_videomode(&mode1, &ch->display_var); 1034 fb_var_to_videomode(&mode2, &info->var); 1035 1036 if (fb_mode_is_equal(&mode1, &mode2)) 1037 return; 1038 1039 /* Display has been re-plugged, framebuffer is free now, reconfigure */ 1040 if (fb_set_var(info, &ch->display_var) < 0) 1041 /* Couldn't reconfigure, hopefully, can continue as before */ 1042 return; 1043 1044 /* 1045 * fb_set_var() calls the notifier change internally, only if 1046 * FBINFO_MISC_USEREVENT flag is set. Since we do not want to fake a 1047 * user event, we have to call the chain ourselves. 1048 */ 1049 event.info = info; 1050 event.data = &mode1; 1051 fb_notifier_call_chain(evnt, &event); 1052} 1053 1054/* 1055 * Locking: both .fb_release() and .fb_open() are called with info->lock held if 1056 * user == 1, or with console sem held, if user == 0. 1057 */ 1058static int sh_mobile_release(struct fb_info *info, int user) 1059{ 1060 struct sh_mobile_lcdc_chan *ch = info->par; 1061 1062 mutex_lock(&ch->open_lock); 1063 dev_dbg(info->dev, "%s(): %d users\n", __func__, ch->use_count); 1064 1065 ch->use_count--; 1066 1067 /* Nothing to reconfigure, when called from fbcon */ 1068 if (user) { 1069 console_lock(); 1070 sh_mobile_fb_reconfig(info); 1071 console_unlock(); 1072 } 1073 1074 mutex_unlock(&ch->open_lock); 1075 1076 return 0; 1077} 1078 1079static int sh_mobile_open(struct fb_info *info, int user) 1080{ 1081 struct sh_mobile_lcdc_chan *ch = info->par; 1082 1083 mutex_lock(&ch->open_lock); 1084 ch->use_count++; 1085 1086 dev_dbg(info->dev, "%s(): %d users\n", __func__, ch->use_count); 1087 mutex_unlock(&ch->open_lock); 1088 1089 return 0; 1090} 1091 1092static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 1093{ 1094 struct sh_mobile_lcdc_chan *ch = info->par; 1095 struct sh_mobile_lcdc_priv *p = ch->lcdc; 1096 unsigned int best_dist = (unsigned int)-1; 1097 unsigned int best_xres = 0; 1098 unsigned int best_yres = 0; 1099 unsigned int i; 1100 1101 if (var->xres > MAX_XRES || var->yres > MAX_YRES) 1102 return -EINVAL; 1103 1104 /* If board code provides us with a list of available modes, make sure 1105 * we use one of them. Find the mode closest to the requested one. The 1106 * distance between two modes is defined as the size of the 1107 * non-overlapping parts of the two rectangles. 1108 */ 1109 for (i = 0; i < ch->cfg.num_cfg; ++i) { 1110 const struct fb_videomode *mode = &ch->cfg.lcd_cfg[i]; 1111 unsigned int dist; 1112 1113 /* We can only round up. */ 1114 if (var->xres > mode->xres || var->yres > mode->yres) 1115 continue; 1116 1117 dist = var->xres * var->yres + mode->xres * mode->yres 1118 - 2 * min(var->xres, mode->xres) 1119 * min(var->yres, mode->yres); 1120 1121 if (dist < best_dist) { 1122 best_xres = mode->xres; 1123 best_yres = mode->yres; 1124 best_dist = dist; 1125 } 1126 } 1127 1128 /* If no available mode can be used, return an error. */ 1129 if (ch->cfg.num_cfg != 0) { 1130 if (best_dist == (unsigned int)-1) 1131 return -EINVAL; 1132 1133 var->xres = best_xres; 1134 var->yres = best_yres; 1135 } 1136 1137 /* Make sure the virtual resolution is at least as big as the visible 1138 * resolution. 1139 */ 1140 if (var->xres_virtual < var->xres) 1141 var->xres_virtual = var->xres; 1142 if (var->yres_virtual < var->yres) 1143 var->yres_virtual = var->yres; 1144 1145 if (sh_mobile_format_is_fourcc(var)) { 1146 switch (var->grayscale) { 1147 case V4L2_PIX_FMT_NV12: 1148 case V4L2_PIX_FMT_NV21: 1149 var->bits_per_pixel = 12; 1150 break; 1151 case V4L2_PIX_FMT_RGB565: 1152 case V4L2_PIX_FMT_NV16: 1153 case V4L2_PIX_FMT_NV61: 1154 var->bits_per_pixel = 16; 1155 break; 1156 case V4L2_PIX_FMT_BGR24: 1157 case V4L2_PIX_FMT_NV24: 1158 case V4L2_PIX_FMT_NV42: 1159 var->bits_per_pixel = 24; 1160 break; 1161 case V4L2_PIX_FMT_BGR32: 1162 var->bits_per_pixel = 32; 1163 break; 1164 default: 1165 return -EINVAL; 1166 } 1167 1168 /* Default to RGB and JPEG color-spaces for RGB and YUV formats 1169 * respectively. 1170 */ 1171 if (!sh_mobile_format_is_yuv(var)) 1172 var->colorspace = V4L2_COLORSPACE_SRGB; 1173 else if (var->colorspace != V4L2_COLORSPACE_REC709) 1174 var->colorspace = V4L2_COLORSPACE_JPEG; 1175 } else { 1176 if (var->bits_per_pixel <= 16) { /* RGB 565 */ 1177 var->bits_per_pixel = 16; 1178 var->red.offset = 11; 1179 var->red.length = 5; 1180 var->green.offset = 5; 1181 var->green.length = 6; 1182 var->blue.offset = 0; 1183 var->blue.length = 5; 1184 var->transp.offset = 0; 1185 var->transp.length = 0; 1186 } else if (var->bits_per_pixel <= 24) { /* RGB 888 */ 1187 var->bits_per_pixel = 24; 1188 var->red.offset = 16; 1189 var->red.length = 8; 1190 var->green.offset = 8; 1191 var->green.length = 8; 1192 var->blue.offset = 0; 1193 var->blue.length = 8; 1194 var->transp.offset = 0; 1195 var->transp.length = 0; 1196 } else if (var->bits_per_pixel <= 32) { /* RGBA 888 */ 1197 var->bits_per_pixel = 32; 1198 var->red.offset = 16; 1199 var->red.length = 8; 1200 var->green.offset = 8; 1201 var->green.length = 8; 1202 var->blue.offset = 0; 1203 var->blue.length = 8; 1204 var->transp.offset = 24; 1205 var->transp.length = 8; 1206 } else 1207 return -EINVAL; 1208 1209 var->red.msb_right = 0; 1210 var->green.msb_right = 0; 1211 var->blue.msb_right = 0; 1212 var->transp.msb_right = 0; 1213 } 1214 1215 /* Make sure we don't exceed our allocated memory. */ 1216 if (var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8 > 1217 info->fix.smem_len) 1218 return -EINVAL; 1219 1220 /* only accept the forced_fourcc for dual channel configurations */ 1221 if (p->forced_fourcc && 1222 p->forced_fourcc != sh_mobile_format_fourcc(var)) 1223 return -EINVAL; 1224 1225 return 0; 1226} 1227 1228static int sh_mobile_set_par(struct fb_info *info) 1229{ 1230 struct sh_mobile_lcdc_chan *ch = info->par; 1231 u32 line_length = info->fix.line_length; 1232 int ret; 1233 1234 sh_mobile_lcdc_stop(ch->lcdc); 1235 1236 if (sh_mobile_format_is_yuv(&info->var)) 1237 info->fix.line_length = info->var.xres; 1238 else 1239 info->fix.line_length = info->var.xres 1240 * info->var.bits_per_pixel / 8; 1241 1242 ret = sh_mobile_lcdc_start(ch->lcdc); 1243 if (ret < 0) { 1244 dev_err(info->dev, "%s: unable to restart LCDC\n", __func__); 1245 info->fix.line_length = line_length; 1246 } 1247 1248 if (sh_mobile_format_is_fourcc(&info->var)) { 1249 info->fix.type = FB_TYPE_FOURCC; 1250 info->fix.visual = FB_VISUAL_FOURCC; 1251 } else { 1252 info->fix.type = FB_TYPE_PACKED_PIXELS; 1253 info->fix.visual = FB_VISUAL_TRUECOLOR; 1254 } 1255 1256 return ret; 1257} 1258 1259/* 1260 * Screen blanking. Behavior is as follows: 1261 * FB_BLANK_UNBLANK: screen unblanked, clocks enabled 1262 * FB_BLANK_NORMAL: screen blanked, clocks enabled 1263 * FB_BLANK_VSYNC, 1264 * FB_BLANK_HSYNC, 1265 * FB_BLANK_POWEROFF: screen blanked, clocks disabled 1266 */ 1267static int sh_mobile_lcdc_blank(int blank, struct fb_info *info) 1268{ 1269 struct sh_mobile_lcdc_chan *ch = info->par; 1270 struct sh_mobile_lcdc_priv *p = ch->lcdc; 1271 1272 /* blank the screen? */ 1273 if (blank > FB_BLANK_UNBLANK && ch->blank_status == FB_BLANK_UNBLANK) { 1274 struct fb_fillrect rect = { 1275 .width = info->var.xres, 1276 .height = info->var.yres, 1277 }; 1278 sh_mobile_lcdc_fillrect(info, &rect); 1279 } 1280 /* turn clocks on? */ 1281 if (blank <= FB_BLANK_NORMAL && ch->blank_status > FB_BLANK_NORMAL) { 1282 sh_mobile_lcdc_clk_on(p); 1283 } 1284 /* turn clocks off? */ 1285 if (blank > FB_BLANK_NORMAL && ch->blank_status <= FB_BLANK_NORMAL) { 1286 /* make sure the screen is updated with the black fill before 1287 * switching the clocks off. one vsync is not enough since 1288 * blanking may occur in the middle of a refresh. deferred io 1289 * mode will reenable the clocks and update the screen in time, 1290 * so it does not need this. */ 1291 if (!info->fbdefio) { 1292 sh_mobile_wait_for_vsync(info); 1293 sh_mobile_wait_for_vsync(info); 1294 } 1295 sh_mobile_lcdc_clk_off(p); 1296 } 1297 1298 ch->blank_status = blank; 1299 return 0; 1300} 1301 1302static struct fb_ops sh_mobile_lcdc_ops = { 1303 .owner = THIS_MODULE, 1304 .fb_setcolreg = sh_mobile_lcdc_setcolreg, 1305 .fb_read = fb_sys_read, 1306 .fb_write = fb_sys_write, 1307 .fb_fillrect = sh_mobile_lcdc_fillrect, 1308 .fb_copyarea = sh_mobile_lcdc_copyarea, 1309 .fb_imageblit = sh_mobile_lcdc_imageblit, 1310 .fb_blank = sh_mobile_lcdc_blank, 1311 .fb_pan_display = sh_mobile_fb_pan_display, 1312 .fb_ioctl = sh_mobile_ioctl, 1313 .fb_open = sh_mobile_open, 1314 .fb_release = sh_mobile_release, 1315 .fb_check_var = sh_mobile_check_var, 1316 .fb_set_par = sh_mobile_set_par, 1317}; 1318 1319/* ----------------------------------------------------------------------------- 1320 * Backlight 1321 */ 1322 1323static int sh_mobile_lcdc_update_bl(struct backlight_device *bdev) 1324{ 1325 struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev); 1326 struct sh_mobile_lcdc_board_cfg *cfg = &ch->cfg.board_cfg; 1327 int brightness = bdev->props.brightness; 1328 1329 if (bdev->props.power != FB_BLANK_UNBLANK || 1330 bdev->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK)) 1331 brightness = 0; 1332 1333 return cfg->set_brightness(cfg->board_data, brightness); 1334} 1335 1336static int sh_mobile_lcdc_get_brightness(struct backlight_device *bdev) 1337{ 1338 struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev); 1339 struct sh_mobile_lcdc_board_cfg *cfg = &ch->cfg.board_cfg; 1340 1341 return cfg->get_brightness(cfg->board_data); 1342} 1343 1344static int sh_mobile_lcdc_check_fb(struct backlight_device *bdev, 1345 struct fb_info *info) 1346{ 1347 return (info->bl_dev == bdev); 1348} 1349 1350static struct backlight_ops sh_mobile_lcdc_bl_ops = { 1351 .options = BL_CORE_SUSPENDRESUME, 1352 .update_status = sh_mobile_lcdc_update_bl, 1353 .get_brightness = sh_mobile_lcdc_get_brightness, 1354 .check_fb = sh_mobile_lcdc_check_fb, 1355}; 1356 1357static struct backlight_device *sh_mobile_lcdc_bl_probe(struct device *parent, 1358 struct sh_mobile_lcdc_chan *ch) 1359{ 1360 struct backlight_device *bl; 1361 1362 bl = backlight_device_register(ch->cfg.bl_info.name, parent, ch, 1363 &sh_mobile_lcdc_bl_ops, NULL); 1364 if (IS_ERR(bl)) { 1365 dev_err(parent, "unable to register backlight device: %ld\n", 1366 PTR_ERR(bl)); 1367 return NULL; 1368 } 1369 1370 bl->props.max_brightness = ch->cfg.bl_info.max_brightness; 1371 bl->props.brightness = bl->props.max_brightness; 1372 backlight_update_status(bl); 1373 1374 return bl; 1375} 1376 1377static void sh_mobile_lcdc_bl_remove(struct backlight_device *bdev) 1378{ 1379 backlight_device_unregister(bdev); 1380} 1381 1382/* ----------------------------------------------------------------------------- 1383 * Power management 1384 */ 1385 1386static int sh_mobile_lcdc_suspend(struct device *dev) 1387{ 1388 struct platform_device *pdev = to_platform_device(dev); 1389 1390 sh_mobile_lcdc_stop(platform_get_drvdata(pdev)); 1391 return 0; 1392} 1393 1394static int sh_mobile_lcdc_resume(struct device *dev) 1395{ 1396 struct platform_device *pdev = to_platform_device(dev); 1397 1398 return sh_mobile_lcdc_start(platform_get_drvdata(pdev)); 1399} 1400 1401static int sh_mobile_lcdc_runtime_suspend(struct device *dev) 1402{ 1403 struct platform_device *pdev = to_platform_device(dev); 1404 struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev); 1405 1406 /* turn off LCDC hardware */ 1407 lcdc_write(priv, _LDCNT1R, 0); 1408 1409 return 0; 1410} 1411 1412static int sh_mobile_lcdc_runtime_resume(struct device *dev) 1413{ 1414 struct platform_device *pdev = to_platform_device(dev); 1415 struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev); 1416 1417 __sh_mobile_lcdc_start(priv); 1418 1419 return 0; 1420} 1421 1422static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = { 1423 .suspend = sh_mobile_lcdc_suspend, 1424 .resume = sh_mobile_lcdc_resume, 1425 .runtime_suspend = sh_mobile_lcdc_runtime_suspend, 1426 .runtime_resume = sh_mobile_lcdc_runtime_resume, 1427}; 1428 1429/* ----------------------------------------------------------------------------- 1430 * Framebuffer notifier 1431 */ 1432 1433/* locking: called with info->lock held */ 1434static int sh_mobile_lcdc_notify(struct notifier_block *nb, 1435 unsigned long action, void *data) 1436{ 1437 struct fb_event *event = data; 1438 struct fb_info *info = event->info; 1439 struct sh_mobile_lcdc_chan *ch = info->par; 1440 1441 if (&ch->lcdc->notifier != nb) 1442 return NOTIFY_DONE; 1443 1444 dev_dbg(info->dev, "%s(): action = %lu, data = %p\n", 1445 __func__, action, event->data); 1446 1447 switch(action) { 1448 case FB_EVENT_SUSPEND: 1449 sh_mobile_lcdc_display_off(ch); 1450 sh_mobile_lcdc_stop(ch->lcdc); 1451 break; 1452 case FB_EVENT_RESUME: 1453 mutex_lock(&ch->open_lock); 1454 sh_mobile_fb_reconfig(info); 1455 mutex_unlock(&ch->open_lock); 1456 1457 sh_mobile_lcdc_display_on(ch); 1458 sh_mobile_lcdc_start(ch->lcdc); 1459 } 1460 1461 return NOTIFY_OK; 1462} 1463 1464/* ----------------------------------------------------------------------------- 1465 * Probe/remove and driver init/exit 1466 */ 1467 1468static const struct fb_videomode default_720p __devinitconst = { 1469 .name = "HDMI 720p", 1470 .xres = 1280, 1471 .yres = 720, 1472 1473 .left_margin = 220, 1474 .right_margin = 110, 1475 .hsync_len = 40, 1476 1477 .upper_margin = 20, 1478 .lower_margin = 5, 1479 .vsync_len = 5, 1480 1481 .pixclock = 13468, 1482 .refresh = 60, 1483 .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT, 1484}; 1485 1486static int sh_mobile_lcdc_remove(struct platform_device *pdev) 1487{ 1488 struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev); 1489 struct fb_info *info; 1490 int i; 1491 1492 fb_unregister_client(&priv->notifier); 1493 1494 for (i = 0; i < ARRAY_SIZE(priv->ch); i++) 1495 if (priv->ch[i].info && priv->ch[i].info->dev) 1496 unregister_framebuffer(priv->ch[i].info); 1497 1498 sh_mobile_lcdc_stop(priv); 1499 1500 for (i = 0; i < ARRAY_SIZE(priv->ch); i++) { 1501 struct sh_mobile_lcdc_chan *ch = &priv->ch[i]; 1502 1503 info = ch->info; 1504 if (!info || !info->device) 1505 continue; 1506 1507 if (ch->tx_dev) 1508 module_put(ch->cfg.tx_dev->dev.driver->owner); 1509 1510 if (ch->sglist) 1511 vfree(ch->sglist); 1512 1513 if (info->screen_base) 1514 dma_free_coherent(&pdev->dev, info->fix.smem_len, 1515 info->screen_base, ch->dma_handle); 1516 fb_dealloc_cmap(&info->cmap); 1517 framebuffer_release(info); 1518 } 1519 1520 for (i = 0; i < ARRAY_SIZE(priv->ch); i++) { 1521 if (priv->ch[i].bl) 1522 sh_mobile_lcdc_bl_remove(priv->ch[i].bl); 1523 } 1524 1525 if (priv->dot_clk) { 1526 pm_runtime_disable(&pdev->dev); 1527 clk_put(priv->dot_clk); 1528 } 1529 1530 if (priv->base) 1531 iounmap(priv->base); 1532 1533 if (priv->irq) 1534 free_irq(priv->irq, priv); 1535 kfree(priv); 1536 return 0; 1537} 1538 1539static int __devinit sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch) 1540{ 1541 int interface_type = ch->cfg.interface_type; 1542 1543 switch (interface_type) { 1544 case RGB8: 1545 case RGB9: 1546 case RGB12A: 1547 case RGB12B: 1548 case RGB16: 1549 case RGB18: 1550 case RGB24: 1551 case SYS8A: 1552 case SYS8B: 1553 case SYS8C: 1554 case SYS8D: 1555 case SYS9: 1556 case SYS12: 1557 case SYS16A: 1558 case SYS16B: 1559 case SYS16C: 1560 case SYS18: 1561 case SYS24: 1562 break; 1563 default: 1564 return -EINVAL; 1565 } 1566 1567 /* SUBLCD only supports SYS interface */ 1568 if (lcdc_chan_is_sublcd(ch)) { 1569 if (!(interface_type & LDMT1R_IFM)) 1570 return -EINVAL; 1571 1572 interface_type &= ~LDMT1R_IFM; 1573 } 1574 1575 ch->ldmt1r_value = interface_type; 1576 return 0; 1577} 1578 1579static int __devinit 1580sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv, 1581 struct sh_mobile_lcdc_chan *ch) 1582{ 1583 struct sh_mobile_lcdc_chan_cfg *cfg = &ch->cfg; 1584 const struct fb_videomode *max_mode; 1585 const struct fb_videomode *mode; 1586 struct fb_var_screeninfo *var; 1587 struct fb_info *info; 1588 unsigned int max_size; 1589 int num_cfg; 1590 void *buf; 1591 int ret; 1592 int i; 1593 1594 mutex_init(&ch->open_lock); 1595 1596 /* Allocate the frame buffer device. */ 1597 ch->info = framebuffer_alloc(0, priv->dev); 1598 if (!ch->info) { 1599 dev_err(priv->dev, "unable to allocate fb_info\n"); 1600 return -ENOMEM; 1601 } 1602 1603 info = ch->info; 1604 info->fbops = &sh_mobile_lcdc_ops; 1605 info->par = ch; 1606 info->pseudo_palette = &ch->pseudo_palette; 1607 info->flags = FBINFO_FLAG_DEFAULT; 1608 1609 if (cfg->tx_dev) { 1610 if (!cfg->tx_dev->dev.driver || 1611 !try_module_get(cfg->tx_dev->dev.driver->owner)) { 1612 dev_warn(priv->dev, 1613 "unable to get transmitter device\n"); 1614 return -EINVAL; 1615 } 1616 ch->tx_dev = platform_get_drvdata(cfg->tx_dev); 1617 } 1618 1619 /* Iterate through the modes to validate them and find the highest 1620 * resolution. 1621 */ 1622 max_mode = NULL; 1623 max_size = 0; 1624 1625 for (i = 0, mode = cfg->lcd_cfg; i < cfg->num_cfg; i++, mode++) { 1626 unsigned int size = mode->yres * mode->xres; 1627 1628 /* NV12/NV21 buffers must have even number of lines */ 1629 if ((cfg->fourcc == V4L2_PIX_FMT_NV12 || 1630 cfg->fourcc == V4L2_PIX_FMT_NV21) && (mode->yres & 0x1)) { 1631 dev_err(priv->dev, "yres must be multiple of 2 for " 1632 "YCbCr420 mode.\n"); 1633 return -EINVAL; 1634 } 1635 1636 if (size > max_size) { 1637 max_mode = mode; 1638 max_size = size; 1639 } 1640 } 1641 1642 if (!max_size) 1643 max_size = MAX_XRES * MAX_YRES; 1644 else 1645 dev_dbg(priv->dev, "Found largest videomode %ux%u\n", 1646 max_mode->xres, max_mode->yres); 1647 1648 /* Create the mode list. */ 1649 if (cfg->lcd_cfg == NULL) { 1650 mode = &default_720p; 1651 num_cfg = 1; 1652 } else { 1653 mode = cfg->lcd_cfg; 1654 num_cfg = cfg->num_cfg; 1655 } 1656 1657 fb_videomode_to_modelist(mode, num_cfg, &info->modelist); 1658 1659 /* Initialize variable screen information using the first mode as 1660 * default. The default Y virtual resolution is twice the panel size to 1661 * allow for double-buffering. 1662 */ 1663 var = &info->var; 1664 fb_videomode_to_var(var, mode); 1665 var->width = cfg->lcd_size_cfg.width; 1666 var->height = cfg->lcd_size_cfg.height; 1667 var->yres_virtual = var->yres * 2; 1668 var->activate = FB_ACTIVATE_NOW; 1669 1670 switch (cfg->fourcc) { 1671 case V4L2_PIX_FMT_RGB565: 1672 var->bits_per_pixel = 16; 1673 break; 1674 case V4L2_PIX_FMT_BGR24: 1675 var->bits_per_pixel = 24; 1676 break; 1677 case V4L2_PIX_FMT_BGR32: 1678 var->bits_per_pixel = 32; 1679 break; 1680 default: 1681 var->grayscale = cfg->fourcc; 1682 break; 1683 } 1684 1685 /* Make sure the memory size check won't fail. smem_len is initialized 1686 * later based on var. 1687 */ 1688 info->fix.smem_len = UINT_MAX; 1689 ret = sh_mobile_check_var(var, info); 1690 if (ret) 1691 return ret; 1692 1693 max_size = max_size * var->bits_per_pixel / 8 * 2; 1694 1695 /* Allocate frame buffer memory and color map. */ 1696 buf = dma_alloc_coherent(priv->dev, max_size, &ch->dma_handle, 1697 GFP_KERNEL); 1698 if (!buf) { 1699 dev_err(priv->dev, "unable to allocate buffer\n"); 1700 return -ENOMEM; 1701 } 1702 1703 ret = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0); 1704 if (ret < 0) { 1705 dev_err(priv->dev, "unable to allocate cmap\n"); 1706 dma_free_coherent(priv->dev, max_size, buf, ch->dma_handle); 1707 return ret; 1708 } 1709 1710 /* Initialize fixed screen information. Restrict pan to 2 lines steps 1711 * for NV12 and NV21. 1712 */ 1713 info->fix = sh_mobile_lcdc_fix; 1714 info->fix.smem_start = ch->dma_handle; 1715 info->fix.smem_len = max_size; 1716 if (cfg->fourcc == V4L2_PIX_FMT_NV12 || 1717 cfg->fourcc == V4L2_PIX_FMT_NV21) 1718 info->fix.ypanstep = 2; 1719 1720 if (sh_mobile_format_is_yuv(var)) { 1721 info->fix.line_length = var->xres; 1722 info->fix.visual = FB_VISUAL_FOURCC; 1723 } else { 1724 info->fix.line_length = var->xres * var->bits_per_pixel / 8; 1725 info->fix.visual = FB_VISUAL_TRUECOLOR; 1726 } 1727 1728 info->screen_base = buf; 1729 info->device = priv->dev; 1730 ch->display_var = *var; 1731 1732 return 0; 1733} 1734 1735static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) 1736{ 1737 struct sh_mobile_lcdc_info *pdata = pdev->dev.platform_data; 1738 struct sh_mobile_lcdc_priv *priv; 1739 struct resource *res; 1740 int num_channels; 1741 int error; 1742 int i; 1743 1744 if (!pdata) { 1745 dev_err(&pdev->dev, "no platform data defined\n"); 1746 return -EINVAL; 1747 } 1748 1749 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1750 i = platform_get_irq(pdev, 0); 1751 if (!res || i < 0) { 1752 dev_err(&pdev->dev, "cannot get platform resources\n"); 1753 return -ENOENT; 1754 } 1755 1756 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 1757 if (!priv) { 1758 dev_err(&pdev->dev, "cannot allocate device data\n"); 1759 return -ENOMEM; 1760 } 1761 1762 priv->dev = &pdev->dev; 1763 priv->meram_dev = pdata->meram_dev; 1764 platform_set_drvdata(pdev, priv); 1765 1766 error = request_irq(i, sh_mobile_lcdc_irq, 0, 1767 dev_name(&pdev->dev), priv); 1768 if (error) { 1769 dev_err(&pdev->dev, "unable to request irq\n"); 1770 goto err1; 1771 } 1772 1773 priv->irq = i; 1774 atomic_set(&priv->hw_usecnt, -1); 1775 1776 for (i = 0, num_channels = 0; i < ARRAY_SIZE(pdata->ch); i++) { 1777 struct sh_mobile_lcdc_chan *ch = priv->ch + num_channels; 1778 1779 ch->lcdc = priv; 1780 memcpy(&ch->cfg, &pdata->ch[i], sizeof(pdata->ch[i])); 1781 1782 error = sh_mobile_lcdc_check_interface(ch); 1783 if (error) { 1784 dev_err(&pdev->dev, "unsupported interface type\n"); 1785 goto err1; 1786 } 1787 init_waitqueue_head(&ch->frame_end_wait); 1788 init_completion(&ch->vsync_completion); 1789 ch->pan_offset = 0; 1790 1791 /* probe the backlight is there is one defined */ 1792 if (ch->cfg.bl_info.max_brightness) 1793 ch->bl = sh_mobile_lcdc_bl_probe(&pdev->dev, ch); 1794 1795 switch (pdata->ch[i].chan) { 1796 case LCDC_CHAN_MAINLCD: 1797 ch->enabled = LDCNT2R_ME; 1798 ch->reg_offs = lcdc_offs_mainlcd; 1799 num_channels++; 1800 break; 1801 case LCDC_CHAN_SUBLCD: 1802 ch->enabled = LDCNT2R_SE; 1803 ch->reg_offs = lcdc_offs_sublcd; 1804 num_channels++; 1805 break; 1806 } 1807 } 1808 1809 if (!num_channels) { 1810 dev_err(&pdev->dev, "no channels defined\n"); 1811 error = -EINVAL; 1812 goto err1; 1813 } 1814 1815 /* for dual channel LCDC (MAIN + SUB) force shared format setting */ 1816 if (num_channels == 2) 1817 priv->forced_fourcc = pdata->ch[0].fourcc; 1818 1819 priv->base = ioremap_nocache(res->start, resource_size(res)); 1820 if (!priv->base) 1821 goto err1; 1822 1823 error = sh_mobile_lcdc_setup_clocks(priv, pdata->clock_source); 1824 if (error) { 1825 dev_err(&pdev->dev, "unable to setup clocks\n"); 1826 goto err1; 1827 } 1828 1829 /* Enable runtime PM. */ 1830 pm_runtime_enable(&pdev->dev); 1831 1832 for (i = 0; i < num_channels; i++) { 1833 struct sh_mobile_lcdc_chan *ch = priv->ch + i; 1834 1835 error = sh_mobile_lcdc_channel_init(priv, ch); 1836 if (error) 1837 goto err1; 1838 } 1839 1840 error = sh_mobile_lcdc_start(priv); 1841 if (error) { 1842 dev_err(&pdev->dev, "unable to start hardware\n"); 1843 goto err1; 1844 } 1845 1846 for (i = 0; i < num_channels; i++) { 1847 struct sh_mobile_lcdc_chan *ch = priv->ch + i; 1848 struct fb_info *info = ch->info; 1849 1850 if (info->fbdefio) { 1851 ch->sglist = vmalloc(sizeof(struct scatterlist) * 1852 info->fix.smem_len >> PAGE_SHIFT); 1853 if (!ch->sglist) { 1854 dev_err(&pdev->dev, "cannot allocate sglist\n"); 1855 goto err1; 1856 } 1857 } 1858 1859 info->bl_dev = ch->bl; 1860 1861 error = register_framebuffer(info); 1862 if (error < 0) 1863 goto err1; 1864 1865 dev_info(&pdev->dev, "registered %s/%s as %dx%d %dbpp.\n", 1866 pdev->name, (ch->cfg.chan == LCDC_CHAN_MAINLCD) ? 1867 "mainlcd" : "sublcd", info->var.xres, info->var.yres, 1868 info->var.bits_per_pixel); 1869 1870 /* deferred io mode: disable clock to save power */ 1871 if (info->fbdefio || info->state == FBINFO_STATE_SUSPENDED) 1872 sh_mobile_lcdc_clk_off(priv); 1873 } 1874 1875 /* Failure ignored */ 1876 priv->notifier.notifier_call = sh_mobile_lcdc_notify; 1877 fb_register_client(&priv->notifier); 1878 1879 return 0; 1880err1: 1881 sh_mobile_lcdc_remove(pdev); 1882 1883 return error; 1884} 1885 1886static struct platform_driver sh_mobile_lcdc_driver = { 1887 .driver = { 1888 .name = "sh_mobile_lcdc_fb", 1889 .owner = THIS_MODULE, 1890 .pm = &sh_mobile_lcdc_dev_pm_ops, 1891 }, 1892 .probe = sh_mobile_lcdc_probe, 1893 .remove = sh_mobile_lcdc_remove, 1894}; 1895 1896module_platform_driver(sh_mobile_lcdc_driver); 1897 1898MODULE_DESCRIPTION("SuperH Mobile LCDC Framebuffer driver"); 1899MODULE_AUTHOR("Magnus Damm <damm@opensource.se>"); 1900MODULE_LICENSE("GPL v2"); 1901