Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.10 2861 lines 73 kB view raw
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/ctype.h> 16#include <linux/dma-mapping.h> 17#include <linux/delay.h> 18#include <linux/gpio.h> 19#include <linux/init.h> 20#include <linux/interrupt.h> 21#include <linux/ioctl.h> 22#include <linux/kernel.h> 23#include <linux/mm.h> 24#include <linux/module.h> 25#include <linux/platform_device.h> 26#include <linux/pm_runtime.h> 27#include <linux/slab.h> 28#include <linux/videodev2.h> 29#include <linux/vmalloc.h> 30 31#include <video/sh_mobile_lcdc.h> 32#include <video/sh_mobile_meram.h> 33 34#include "sh_mobile_lcdcfb.h" 35 36/* ---------------------------------------------------------------------------- 37 * Overlay register definitions 38 */ 39 40#define LDBCR 0xb00 41#define LDBCR_UPC(n) (1 << ((n) + 16)) 42#define LDBCR_UPF(n) (1 << ((n) + 8)) 43#define LDBCR_UPD(n) (1 << ((n) + 0)) 44#define LDBnBSIFR(n) (0xb20 + (n) * 0x20 + 0x00) 45#define LDBBSIFR_EN (1 << 31) 46#define LDBBSIFR_VS (1 << 29) 47#define LDBBSIFR_BRSEL (1 << 28) 48#define LDBBSIFR_MX (1 << 27) 49#define LDBBSIFR_MY (1 << 26) 50#define LDBBSIFR_CV3 (3 << 24) 51#define LDBBSIFR_CV2 (2 << 24) 52#define LDBBSIFR_CV1 (1 << 24) 53#define LDBBSIFR_CV0 (0 << 24) 54#define LDBBSIFR_CV_MASK (3 << 24) 55#define LDBBSIFR_LAY_MASK (0xff << 16) 56#define LDBBSIFR_LAY_SHIFT 16 57#define LDBBSIFR_ROP3_MASK (0xff << 16) 58#define LDBBSIFR_ROP3_SHIFT 16 59#define LDBBSIFR_AL_PL8 (3 << 14) 60#define LDBBSIFR_AL_PL1 (2 << 14) 61#define LDBBSIFR_AL_PK (1 << 14) 62#define LDBBSIFR_AL_1 (0 << 14) 63#define LDBBSIFR_AL_MASK (3 << 14) 64#define LDBBSIFR_SWPL (1 << 10) 65#define LDBBSIFR_SWPW (1 << 9) 66#define LDBBSIFR_SWPB (1 << 8) 67#define LDBBSIFR_RY (1 << 7) 68#define LDBBSIFR_CHRR_420 (2 << 0) 69#define LDBBSIFR_CHRR_422 (1 << 0) 70#define LDBBSIFR_CHRR_444 (0 << 0) 71#define LDBBSIFR_RPKF_ARGB32 (0x00 << 0) 72#define LDBBSIFR_RPKF_RGB16 (0x03 << 0) 73#define LDBBSIFR_RPKF_RGB24 (0x0b << 0) 74#define LDBBSIFR_RPKF_MASK (0x1f << 0) 75#define LDBnBSSZR(n) (0xb20 + (n) * 0x20 + 0x04) 76#define LDBBSSZR_BVSS_MASK (0xfff << 16) 77#define LDBBSSZR_BVSS_SHIFT 16 78#define LDBBSSZR_BHSS_MASK (0xfff << 0) 79#define LDBBSSZR_BHSS_SHIFT 0 80#define LDBnBLOCR(n) (0xb20 + (n) * 0x20 + 0x08) 81#define LDBBLOCR_CVLC_MASK (0xfff << 16) 82#define LDBBLOCR_CVLC_SHIFT 16 83#define LDBBLOCR_CHLC_MASK (0xfff << 0) 84#define LDBBLOCR_CHLC_SHIFT 0 85#define LDBnBSMWR(n) (0xb20 + (n) * 0x20 + 0x0c) 86#define LDBBSMWR_BSMWA_MASK (0xffff << 16) 87#define LDBBSMWR_BSMWA_SHIFT 16 88#define LDBBSMWR_BSMW_MASK (0xffff << 0) 89#define LDBBSMWR_BSMW_SHIFT 0 90#define LDBnBSAYR(n) (0xb20 + (n) * 0x20 + 0x10) 91#define LDBBSAYR_FG1A_MASK (0xff << 24) 92#define LDBBSAYR_FG1A_SHIFT 24 93#define LDBBSAYR_FG1R_MASK (0xff << 16) 94#define LDBBSAYR_FG1R_SHIFT 16 95#define LDBBSAYR_FG1G_MASK (0xff << 8) 96#define LDBBSAYR_FG1G_SHIFT 8 97#define LDBBSAYR_FG1B_MASK (0xff << 0) 98#define LDBBSAYR_FG1B_SHIFT 0 99#define LDBnBSACR(n) (0xb20 + (n) * 0x20 + 0x14) 100#define LDBBSACR_FG2A_MASK (0xff << 24) 101#define LDBBSACR_FG2A_SHIFT 24 102#define LDBBSACR_FG2R_MASK (0xff << 16) 103#define LDBBSACR_FG2R_SHIFT 16 104#define LDBBSACR_FG2G_MASK (0xff << 8) 105#define LDBBSACR_FG2G_SHIFT 8 106#define LDBBSACR_FG2B_MASK (0xff << 0) 107#define LDBBSACR_FG2B_SHIFT 0 108#define LDBnBSAAR(n) (0xb20 + (n) * 0x20 + 0x18) 109#define LDBBSAAR_AP_MASK (0xff << 24) 110#define LDBBSAAR_AP_SHIFT 24 111#define LDBBSAAR_R_MASK (0xff << 16) 112#define LDBBSAAR_R_SHIFT 16 113#define LDBBSAAR_GY_MASK (0xff << 8) 114#define LDBBSAAR_GY_SHIFT 8 115#define LDBBSAAR_B_MASK (0xff << 0) 116#define LDBBSAAR_B_SHIFT 0 117#define LDBnBPPCR(n) (0xb20 + (n) * 0x20 + 0x1c) 118#define LDBBPPCR_AP_MASK (0xff << 24) 119#define LDBBPPCR_AP_SHIFT 24 120#define LDBBPPCR_R_MASK (0xff << 16) 121#define LDBBPPCR_R_SHIFT 16 122#define LDBBPPCR_GY_MASK (0xff << 8) 123#define LDBBPPCR_GY_SHIFT 8 124#define LDBBPPCR_B_MASK (0xff << 0) 125#define LDBBPPCR_B_SHIFT 0 126#define LDBnBBGCL(n) (0xb10 + (n) * 0x04) 127#define LDBBBGCL_BGA_MASK (0xff << 24) 128#define LDBBBGCL_BGA_SHIFT 24 129#define LDBBBGCL_BGR_MASK (0xff << 16) 130#define LDBBBGCL_BGR_SHIFT 16 131#define LDBBBGCL_BGG_MASK (0xff << 8) 132#define LDBBBGCL_BGG_SHIFT 8 133#define LDBBBGCL_BGB_MASK (0xff << 0) 134#define LDBBBGCL_BGB_SHIFT 0 135 136#define SIDE_B_OFFSET 0x1000 137#define MIRROR_OFFSET 0x2000 138 139#define MAX_XRES 1920 140#define MAX_YRES 1080 141 142enum sh_mobile_lcdc_overlay_mode { 143 LCDC_OVERLAY_BLEND, 144 LCDC_OVERLAY_ROP3, 145}; 146 147/* 148 * struct sh_mobile_lcdc_overlay - LCDC display overlay 149 * 150 * @channel: LCDC channel this overlay belongs to 151 * @cfg: Overlay configuration 152 * @info: Frame buffer device 153 * @index: Overlay index (0-3) 154 * @base: Overlay registers base address 155 * @enabled: True if the overlay is enabled 156 * @mode: Overlay blending mode (alpha blend or ROP3) 157 * @alpha: Global alpha blending value (0-255, for alpha blending mode) 158 * @rop3: Raster operation (for ROP3 mode) 159 * @fb_mem: Frame buffer virtual memory address 160 * @fb_size: Frame buffer size in bytes 161 * @dma_handle: Frame buffer DMA address 162 * @base_addr_y: Overlay base address (RGB or luma component) 163 * @base_addr_c: Overlay base address (chroma component) 164 * @pan_y_offset: Panning linear offset in bytes (luma component) 165 * @format: Current pixelf format 166 * @xres: Horizontal visible resolution 167 * @xres_virtual: Horizontal total resolution 168 * @yres: Vertical visible resolution 169 * @yres_virtual: Vertical total resolution 170 * @pitch: Overlay line pitch 171 * @pos_x: Horizontal overlay position 172 * @pos_y: Vertical overlay position 173 */ 174struct sh_mobile_lcdc_overlay { 175 struct sh_mobile_lcdc_chan *channel; 176 177 const struct sh_mobile_lcdc_overlay_cfg *cfg; 178 struct fb_info *info; 179 180 unsigned int index; 181 unsigned long base; 182 183 bool enabled; 184 enum sh_mobile_lcdc_overlay_mode mode; 185 unsigned int alpha; 186 unsigned int rop3; 187 188 void *fb_mem; 189 unsigned long fb_size; 190 191 dma_addr_t dma_handle; 192 unsigned long base_addr_y; 193 unsigned long base_addr_c; 194 unsigned long pan_y_offset; 195 196 const struct sh_mobile_lcdc_format_info *format; 197 unsigned int xres; 198 unsigned int xres_virtual; 199 unsigned int yres; 200 unsigned int yres_virtual; 201 unsigned int pitch; 202 int pos_x; 203 int pos_y; 204}; 205 206struct sh_mobile_lcdc_priv { 207 void __iomem *base; 208 int irq; 209 atomic_t hw_usecnt; 210 struct device *dev; 211 struct clk *dot_clk; 212 unsigned long lddckr; 213 214 struct sh_mobile_lcdc_chan ch[2]; 215 struct sh_mobile_lcdc_overlay overlays[4]; 216 217 struct notifier_block notifier; 218 int started; 219 int forced_fourcc; /* 2 channel LCDC must share fourcc setting */ 220 struct sh_mobile_meram_info *meram_dev; 221}; 222 223/* ----------------------------------------------------------------------------- 224 * Registers access 225 */ 226 227static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = { 228 [LDDCKPAT1R] = 0x400, 229 [LDDCKPAT2R] = 0x404, 230 [LDMT1R] = 0x418, 231 [LDMT2R] = 0x41c, 232 [LDMT3R] = 0x420, 233 [LDDFR] = 0x424, 234 [LDSM1R] = 0x428, 235 [LDSM2R] = 0x42c, 236 [LDSA1R] = 0x430, 237 [LDSA2R] = 0x434, 238 [LDMLSR] = 0x438, 239 [LDHCNR] = 0x448, 240 [LDHSYNR] = 0x44c, 241 [LDVLNR] = 0x450, 242 [LDVSYNR] = 0x454, 243 [LDPMR] = 0x460, 244 [LDHAJR] = 0x4a0, 245}; 246 247static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = { 248 [LDDCKPAT1R] = 0x408, 249 [LDDCKPAT2R] = 0x40c, 250 [LDMT1R] = 0x600, 251 [LDMT2R] = 0x604, 252 [LDMT3R] = 0x608, 253 [LDDFR] = 0x60c, 254 [LDSM1R] = 0x610, 255 [LDSM2R] = 0x614, 256 [LDSA1R] = 0x618, 257 [LDMLSR] = 0x620, 258 [LDHCNR] = 0x624, 259 [LDHSYNR] = 0x628, 260 [LDVLNR] = 0x62c, 261 [LDVSYNR] = 0x630, 262 [LDPMR] = 0x63c, 263}; 264 265static bool banked(int reg_nr) 266{ 267 switch (reg_nr) { 268 case LDMT1R: 269 case LDMT2R: 270 case LDMT3R: 271 case LDDFR: 272 case LDSM1R: 273 case LDSA1R: 274 case LDSA2R: 275 case LDMLSR: 276 case LDHCNR: 277 case LDHSYNR: 278 case LDVLNR: 279 case LDVSYNR: 280 return true; 281 } 282 return false; 283} 284 285static int lcdc_chan_is_sublcd(struct sh_mobile_lcdc_chan *chan) 286{ 287 return chan->cfg->chan == LCDC_CHAN_SUBLCD; 288} 289 290static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan, 291 int reg_nr, unsigned long data) 292{ 293 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr]); 294 if (banked(reg_nr)) 295 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] + 296 SIDE_B_OFFSET); 297} 298 299static void lcdc_write_chan_mirror(struct sh_mobile_lcdc_chan *chan, 300 int reg_nr, unsigned long data) 301{ 302 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] + 303 MIRROR_OFFSET); 304} 305 306static unsigned long lcdc_read_chan(struct sh_mobile_lcdc_chan *chan, 307 int reg_nr) 308{ 309 return ioread32(chan->lcdc->base + chan->reg_offs[reg_nr]); 310} 311 312static void lcdc_write_overlay(struct sh_mobile_lcdc_overlay *ovl, 313 int reg, unsigned long data) 314{ 315 iowrite32(data, ovl->channel->lcdc->base + reg); 316 iowrite32(data, ovl->channel->lcdc->base + reg + SIDE_B_OFFSET); 317} 318 319static void lcdc_write(struct sh_mobile_lcdc_priv *priv, 320 unsigned long reg_offs, unsigned long data) 321{ 322 iowrite32(data, priv->base + reg_offs); 323} 324 325static unsigned long lcdc_read(struct sh_mobile_lcdc_priv *priv, 326 unsigned long reg_offs) 327{ 328 return ioread32(priv->base + reg_offs); 329} 330 331static void lcdc_wait_bit(struct sh_mobile_lcdc_priv *priv, 332 unsigned long reg_offs, 333 unsigned long mask, unsigned long until) 334{ 335 while ((lcdc_read(priv, reg_offs) & mask) != until) 336 cpu_relax(); 337} 338 339/* ----------------------------------------------------------------------------- 340 * Clock management 341 */ 342 343static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv) 344{ 345 if (atomic_inc_and_test(&priv->hw_usecnt)) { 346 if (priv->dot_clk) 347 clk_enable(priv->dot_clk); 348 pm_runtime_get_sync(priv->dev); 349 if (priv->meram_dev && priv->meram_dev->pdev) 350 pm_runtime_get_sync(&priv->meram_dev->pdev->dev); 351 } 352} 353 354static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv) 355{ 356 if (atomic_sub_return(1, &priv->hw_usecnt) == -1) { 357 if (priv->meram_dev && priv->meram_dev->pdev) 358 pm_runtime_put_sync(&priv->meram_dev->pdev->dev); 359 pm_runtime_put(priv->dev); 360 if (priv->dot_clk) 361 clk_disable(priv->dot_clk); 362 } 363} 364 365static int sh_mobile_lcdc_setup_clocks(struct sh_mobile_lcdc_priv *priv, 366 int clock_source) 367{ 368 struct clk *clk; 369 char *str; 370 371 switch (clock_source) { 372 case LCDC_CLK_BUS: 373 str = "bus_clk"; 374 priv->lddckr = LDDCKR_ICKSEL_BUS; 375 break; 376 case LCDC_CLK_PERIPHERAL: 377 str = "peripheral_clk"; 378 priv->lddckr = LDDCKR_ICKSEL_MIPI; 379 break; 380 case LCDC_CLK_EXTERNAL: 381 str = NULL; 382 priv->lddckr = LDDCKR_ICKSEL_HDMI; 383 break; 384 default: 385 return -EINVAL; 386 } 387 388 if (str == NULL) 389 return 0; 390 391 clk = clk_get(priv->dev, str); 392 if (IS_ERR(clk)) { 393 dev_err(priv->dev, "cannot get dot clock %s\n", str); 394 return PTR_ERR(clk); 395 } 396 397 priv->dot_clk = clk; 398 return 0; 399} 400 401/* ----------------------------------------------------------------------------- 402 * Display, panel and deferred I/O 403 */ 404 405static void lcdc_sys_write_index(void *handle, unsigned long data) 406{ 407 struct sh_mobile_lcdc_chan *ch = handle; 408 409 lcdc_write(ch->lcdc, _LDDWD0R, data | LDDWDxR_WDACT); 410 lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0); 411 lcdc_write(ch->lcdc, _LDDWAR, LDDWAR_WA | 412 (lcdc_chan_is_sublcd(ch) ? 2 : 0)); 413 lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0); 414} 415 416static void lcdc_sys_write_data(void *handle, unsigned long data) 417{ 418 struct sh_mobile_lcdc_chan *ch = handle; 419 420 lcdc_write(ch->lcdc, _LDDWD0R, data | LDDWDxR_WDACT | LDDWDxR_RSW); 421 lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0); 422 lcdc_write(ch->lcdc, _LDDWAR, LDDWAR_WA | 423 (lcdc_chan_is_sublcd(ch) ? 2 : 0)); 424 lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0); 425} 426 427static unsigned long lcdc_sys_read_data(void *handle) 428{ 429 struct sh_mobile_lcdc_chan *ch = handle; 430 431 lcdc_write(ch->lcdc, _LDDRDR, LDDRDR_RSR); 432 lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0); 433 lcdc_write(ch->lcdc, _LDDRAR, LDDRAR_RA | 434 (lcdc_chan_is_sublcd(ch) ? 2 : 0)); 435 udelay(1); 436 lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0); 437 438 return lcdc_read(ch->lcdc, _LDDRDR) & LDDRDR_DRD_MASK; 439} 440 441static struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = { 442 lcdc_sys_write_index, 443 lcdc_sys_write_data, 444 lcdc_sys_read_data, 445}; 446 447static int sh_mobile_lcdc_sginit(struct fb_info *info, 448 struct list_head *pagelist) 449{ 450 struct sh_mobile_lcdc_chan *ch = info->par; 451 unsigned int nr_pages_max = ch->fb_size >> PAGE_SHIFT; 452 struct page *page; 453 int nr_pages = 0; 454 455 sg_init_table(ch->sglist, nr_pages_max); 456 457 list_for_each_entry(page, pagelist, lru) 458 sg_set_page(&ch->sglist[nr_pages++], page, PAGE_SIZE, 0); 459 460 return nr_pages; 461} 462 463static void sh_mobile_lcdc_deferred_io(struct fb_info *info, 464 struct list_head *pagelist) 465{ 466 struct sh_mobile_lcdc_chan *ch = info->par; 467 const struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg->panel_cfg; 468 469 /* enable clocks before accessing hardware */ 470 sh_mobile_lcdc_clk_on(ch->lcdc); 471 472 /* 473 * It's possible to get here without anything on the pagelist via 474 * sh_mobile_lcdc_deferred_io_touch() or via a userspace fsync() 475 * invocation. In the former case, the acceleration routines are 476 * stepped in to when using the framebuffer console causing the 477 * workqueue to be scheduled without any dirty pages on the list. 478 * 479 * Despite this, a panel update is still needed given that the 480 * acceleration routines have their own methods for writing in 481 * that still need to be updated. 482 * 483 * The fsync() and empty pagelist case could be optimized for, 484 * but we don't bother, as any application exhibiting such 485 * behaviour is fundamentally broken anyways. 486 */ 487 if (!list_empty(pagelist)) { 488 unsigned int nr_pages = sh_mobile_lcdc_sginit(info, pagelist); 489 490 /* trigger panel update */ 491 dma_map_sg(ch->lcdc->dev, ch->sglist, nr_pages, DMA_TO_DEVICE); 492 if (panel->start_transfer) 493 panel->start_transfer(ch, &sh_mobile_lcdc_sys_bus_ops); 494 lcdc_write_chan(ch, LDSM2R, LDSM2R_OSTRG); 495 dma_unmap_sg(ch->lcdc->dev, ch->sglist, nr_pages, 496 DMA_TO_DEVICE); 497 } else { 498 if (panel->start_transfer) 499 panel->start_transfer(ch, &sh_mobile_lcdc_sys_bus_ops); 500 lcdc_write_chan(ch, LDSM2R, LDSM2R_OSTRG); 501 } 502} 503 504static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info) 505{ 506 struct fb_deferred_io *fbdefio = info->fbdefio; 507 508 if (fbdefio) 509 schedule_delayed_work(&info->deferred_work, fbdefio->delay); 510} 511 512static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan *ch) 513{ 514 const struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg->panel_cfg; 515 516 if (ch->tx_dev) { 517 int ret; 518 519 ret = ch->tx_dev->ops->display_on(ch->tx_dev); 520 if (ret < 0) 521 return; 522 523 if (ret == SH_MOBILE_LCDC_DISPLAY_DISCONNECTED) 524 ch->info->state = FBINFO_STATE_SUSPENDED; 525 } 526 527 /* HDMI must be enabled before LCDC configuration */ 528 if (panel->display_on) 529 panel->display_on(); 530} 531 532static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch) 533{ 534 const struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg->panel_cfg; 535 536 if (panel->display_off) 537 panel->display_off(); 538 539 if (ch->tx_dev) 540 ch->tx_dev->ops->display_off(ch->tx_dev); 541} 542 543static bool 544sh_mobile_lcdc_must_reconfigure(struct sh_mobile_lcdc_chan *ch, 545 const struct fb_videomode *new_mode) 546{ 547 dev_dbg(ch->info->dev, "Old %ux%u, new %ux%u\n", 548 ch->display.mode.xres, ch->display.mode.yres, 549 new_mode->xres, new_mode->yres); 550 551 /* It can be a different monitor with an equal video-mode */ 552 if (fb_mode_is_equal(&ch->display.mode, new_mode)) 553 return false; 554 555 dev_dbg(ch->info->dev, "Switching %u -> %u lines\n", 556 ch->display.mode.yres, new_mode->yres); 557 ch->display.mode = *new_mode; 558 559 return true; 560} 561 562static int sh_mobile_lcdc_check_var(struct fb_var_screeninfo *var, 563 struct fb_info *info); 564 565static int sh_mobile_lcdc_display_notify(struct sh_mobile_lcdc_chan *ch, 566 enum sh_mobile_lcdc_entity_event event, 567 const struct fb_videomode *mode, 568 const struct fb_monspecs *monspec) 569{ 570 struct fb_info *info = ch->info; 571 struct fb_var_screeninfo var; 572 int ret = 0; 573 574 switch (event) { 575 case SH_MOBILE_LCDC_EVENT_DISPLAY_CONNECT: 576 /* HDMI plug in */ 577 if (lock_fb_info(info)) { 578 console_lock(); 579 580 ch->display.width = monspec->max_x * 10; 581 ch->display.height = monspec->max_y * 10; 582 583 if (!sh_mobile_lcdc_must_reconfigure(ch, mode) && 584 info->state == FBINFO_STATE_RUNNING) { 585 /* First activation with the default monitor. 586 * Just turn on, if we run a resume here, the 587 * logo disappears. 588 */ 589 info->var.width = ch->display.width; 590 info->var.height = ch->display.height; 591 sh_mobile_lcdc_display_on(ch); 592 } else { 593 /* New monitor or have to wake up */ 594 fb_set_suspend(info, 0); 595 } 596 597 console_unlock(); 598 unlock_fb_info(info); 599 } 600 break; 601 602 case SH_MOBILE_LCDC_EVENT_DISPLAY_DISCONNECT: 603 /* HDMI disconnect */ 604 if (lock_fb_info(info)) { 605 console_lock(); 606 fb_set_suspend(info, 1); 607 console_unlock(); 608 unlock_fb_info(info); 609 } 610 break; 611 612 case SH_MOBILE_LCDC_EVENT_DISPLAY_MODE: 613 /* Validate a proposed new mode */ 614 fb_videomode_to_var(&var, mode); 615 var.bits_per_pixel = info->var.bits_per_pixel; 616 var.grayscale = info->var.grayscale; 617 ret = sh_mobile_lcdc_check_var(&var, info); 618 break; 619 } 620 621 return ret; 622} 623 624/* ----------------------------------------------------------------------------- 625 * Format helpers 626 */ 627 628struct sh_mobile_lcdc_format_info { 629 u32 fourcc; 630 unsigned int bpp; 631 bool yuv; 632 u32 lddfr; 633}; 634 635static const struct sh_mobile_lcdc_format_info sh_mobile_format_infos[] = { 636 { 637 .fourcc = V4L2_PIX_FMT_RGB565, 638 .bpp = 16, 639 .yuv = false, 640 .lddfr = LDDFR_PKF_RGB16, 641 }, { 642 .fourcc = V4L2_PIX_FMT_BGR24, 643 .bpp = 24, 644 .yuv = false, 645 .lddfr = LDDFR_PKF_RGB24, 646 }, { 647 .fourcc = V4L2_PIX_FMT_BGR32, 648 .bpp = 32, 649 .yuv = false, 650 .lddfr = LDDFR_PKF_ARGB32, 651 }, { 652 .fourcc = V4L2_PIX_FMT_NV12, 653 .bpp = 12, 654 .yuv = true, 655 .lddfr = LDDFR_CC | LDDFR_YF_420, 656 }, { 657 .fourcc = V4L2_PIX_FMT_NV21, 658 .bpp = 12, 659 .yuv = true, 660 .lddfr = LDDFR_CC | LDDFR_YF_420, 661 }, { 662 .fourcc = V4L2_PIX_FMT_NV16, 663 .bpp = 16, 664 .yuv = true, 665 .lddfr = LDDFR_CC | LDDFR_YF_422, 666 }, { 667 .fourcc = V4L2_PIX_FMT_NV61, 668 .bpp = 16, 669 .yuv = true, 670 .lddfr = LDDFR_CC | LDDFR_YF_422, 671 }, { 672 .fourcc = V4L2_PIX_FMT_NV24, 673 .bpp = 24, 674 .yuv = true, 675 .lddfr = LDDFR_CC | LDDFR_YF_444, 676 }, { 677 .fourcc = V4L2_PIX_FMT_NV42, 678 .bpp = 24, 679 .yuv = true, 680 .lddfr = LDDFR_CC | LDDFR_YF_444, 681 }, 682}; 683 684static const struct sh_mobile_lcdc_format_info * 685sh_mobile_format_info(u32 fourcc) 686{ 687 unsigned int i; 688 689 for (i = 0; i < ARRAY_SIZE(sh_mobile_format_infos); ++i) { 690 if (sh_mobile_format_infos[i].fourcc == fourcc) 691 return &sh_mobile_format_infos[i]; 692 } 693 694 return NULL; 695} 696 697static int sh_mobile_format_fourcc(const struct fb_var_screeninfo *var) 698{ 699 if (var->grayscale > 1) 700 return var->grayscale; 701 702 switch (var->bits_per_pixel) { 703 case 16: 704 return V4L2_PIX_FMT_RGB565; 705 case 24: 706 return V4L2_PIX_FMT_BGR24; 707 case 32: 708 return V4L2_PIX_FMT_BGR32; 709 default: 710 return 0; 711 } 712} 713 714static int sh_mobile_format_is_fourcc(const struct fb_var_screeninfo *var) 715{ 716 return var->grayscale > 1; 717} 718 719/* ----------------------------------------------------------------------------- 720 * Start, stop and IRQ 721 */ 722 723static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data) 724{ 725 struct sh_mobile_lcdc_priv *priv = data; 726 struct sh_mobile_lcdc_chan *ch; 727 unsigned long ldintr; 728 int is_sub; 729 int k; 730 731 /* Acknowledge interrupts and disable further VSYNC End IRQs. */ 732 ldintr = lcdc_read(priv, _LDINTR); 733 lcdc_write(priv, _LDINTR, (ldintr ^ LDINTR_STATUS_MASK) & ~LDINTR_VEE); 734 735 /* figure out if this interrupt is for main or sub lcd */ 736 is_sub = (lcdc_read(priv, _LDSR) & LDSR_MSS) ? 1 : 0; 737 738 /* wake up channel and disable clocks */ 739 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 740 ch = &priv->ch[k]; 741 742 if (!ch->enabled) 743 continue; 744 745 /* Frame End */ 746 if (ldintr & LDINTR_FS) { 747 if (is_sub == lcdc_chan_is_sublcd(ch)) { 748 ch->frame_end = 1; 749 wake_up(&ch->frame_end_wait); 750 751 sh_mobile_lcdc_clk_off(priv); 752 } 753 } 754 755 /* VSYNC End */ 756 if (ldintr & LDINTR_VES) 757 complete(&ch->vsync_completion); 758 } 759 760 return IRQ_HANDLED; 761} 762 763static int sh_mobile_lcdc_wait_for_vsync(struct sh_mobile_lcdc_chan *ch) 764{ 765 unsigned long ldintr; 766 int ret; 767 768 /* Enable VSync End interrupt and be careful not to acknowledge any 769 * pending interrupt. 770 */ 771 ldintr = lcdc_read(ch->lcdc, _LDINTR); 772 ldintr |= LDINTR_VEE | LDINTR_STATUS_MASK; 773 lcdc_write(ch->lcdc, _LDINTR, ldintr); 774 775 ret = wait_for_completion_interruptible_timeout(&ch->vsync_completion, 776 msecs_to_jiffies(100)); 777 if (!ret) 778 return -ETIMEDOUT; 779 780 return 0; 781} 782 783static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv, 784 int start) 785{ 786 unsigned long tmp = lcdc_read(priv, _LDCNT2R); 787 int k; 788 789 /* start or stop the lcdc */ 790 if (start) 791 lcdc_write(priv, _LDCNT2R, tmp | LDCNT2R_DO); 792 else 793 lcdc_write(priv, _LDCNT2R, tmp & ~LDCNT2R_DO); 794 795 /* wait until power is applied/stopped on all channels */ 796 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) 797 if (lcdc_read(priv, _LDCNT2R) & priv->ch[k].enabled) 798 while (1) { 799 tmp = lcdc_read_chan(&priv->ch[k], LDPMR) 800 & LDPMR_LPS; 801 if (start && tmp == LDPMR_LPS) 802 break; 803 if (!start && tmp == 0) 804 break; 805 cpu_relax(); 806 } 807 808 if (!start) 809 lcdc_write(priv, _LDDCKSTPR, 1); /* stop dotclock */ 810} 811 812static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch) 813{ 814 const struct fb_var_screeninfo *var = &ch->info->var; 815 const struct fb_videomode *mode = &ch->display.mode; 816 unsigned long h_total, hsync_pos, display_h_total; 817 u32 tmp; 818 819 tmp = ch->ldmt1r_value; 820 tmp |= (var->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : LDMT1R_VPOL; 821 tmp |= (var->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : LDMT1R_HPOL; 822 tmp |= (ch->cfg->flags & LCDC_FLAGS_DWPOL) ? LDMT1R_DWPOL : 0; 823 tmp |= (ch->cfg->flags & LCDC_FLAGS_DIPOL) ? LDMT1R_DIPOL : 0; 824 tmp |= (ch->cfg->flags & LCDC_FLAGS_DAPOL) ? LDMT1R_DAPOL : 0; 825 tmp |= (ch->cfg->flags & LCDC_FLAGS_HSCNT) ? LDMT1R_HSCNT : 0; 826 tmp |= (ch->cfg->flags & LCDC_FLAGS_DWCNT) ? LDMT1R_DWCNT : 0; 827 lcdc_write_chan(ch, LDMT1R, tmp); 828 829 /* setup SYS bus */ 830 lcdc_write_chan(ch, LDMT2R, ch->cfg->sys_bus_cfg.ldmt2r); 831 lcdc_write_chan(ch, LDMT3R, ch->cfg->sys_bus_cfg.ldmt3r); 832 833 /* horizontal configuration */ 834 h_total = mode->xres + mode->hsync_len + mode->left_margin 835 + mode->right_margin; 836 tmp = h_total / 8; /* HTCN */ 837 tmp |= (min(mode->xres, ch->xres) / 8) << 16; /* HDCN */ 838 lcdc_write_chan(ch, LDHCNR, tmp); 839 840 hsync_pos = mode->xres + mode->right_margin; 841 tmp = hsync_pos / 8; /* HSYNP */ 842 tmp |= (mode->hsync_len / 8) << 16; /* HSYNW */ 843 lcdc_write_chan(ch, LDHSYNR, tmp); 844 845 /* vertical configuration */ 846 tmp = mode->yres + mode->vsync_len + mode->upper_margin 847 + mode->lower_margin; /* VTLN */ 848 tmp |= min(mode->yres, ch->yres) << 16; /* VDLN */ 849 lcdc_write_chan(ch, LDVLNR, tmp); 850 851 tmp = mode->yres + mode->lower_margin; /* VSYNP */ 852 tmp |= mode->vsync_len << 16; /* VSYNW */ 853 lcdc_write_chan(ch, LDVSYNR, tmp); 854 855 /* Adjust horizontal synchronisation for HDMI */ 856 display_h_total = mode->xres + mode->hsync_len + mode->left_margin 857 + mode->right_margin; 858 tmp = ((mode->xres & 7) << 24) | ((display_h_total & 7) << 16) 859 | ((mode->hsync_len & 7) << 8) | (hsync_pos & 7); 860 lcdc_write_chan(ch, LDHAJR, tmp); 861 lcdc_write_chan_mirror(ch, LDHAJR, tmp); 862} 863 864static void sh_mobile_lcdc_overlay_setup(struct sh_mobile_lcdc_overlay *ovl) 865{ 866 u32 format = 0; 867 868 if (!ovl->enabled) { 869 lcdc_write(ovl->channel->lcdc, LDBCR, LDBCR_UPC(ovl->index)); 870 lcdc_write_overlay(ovl, LDBnBSIFR(ovl->index), 0); 871 lcdc_write(ovl->channel->lcdc, LDBCR, 872 LDBCR_UPF(ovl->index) | LDBCR_UPD(ovl->index)); 873 return; 874 } 875 876 ovl->base_addr_y = ovl->dma_handle; 877 ovl->base_addr_c = ovl->dma_handle 878 + ovl->xres_virtual * ovl->yres_virtual; 879 880 switch (ovl->mode) { 881 case LCDC_OVERLAY_BLEND: 882 format = LDBBSIFR_EN | (ovl->alpha << LDBBSIFR_LAY_SHIFT); 883 break; 884 885 case LCDC_OVERLAY_ROP3: 886 format = LDBBSIFR_EN | LDBBSIFR_BRSEL 887 | (ovl->rop3 << LDBBSIFR_ROP3_SHIFT); 888 break; 889 } 890 891 switch (ovl->format->fourcc) { 892 case V4L2_PIX_FMT_RGB565: 893 case V4L2_PIX_FMT_NV21: 894 case V4L2_PIX_FMT_NV61: 895 case V4L2_PIX_FMT_NV42: 896 format |= LDBBSIFR_SWPL | LDBBSIFR_SWPW; 897 break; 898 case V4L2_PIX_FMT_BGR24: 899 case V4L2_PIX_FMT_NV12: 900 case V4L2_PIX_FMT_NV16: 901 case V4L2_PIX_FMT_NV24: 902 format |= LDBBSIFR_SWPL | LDBBSIFR_SWPW | LDBBSIFR_SWPB; 903 break; 904 case V4L2_PIX_FMT_BGR32: 905 default: 906 format |= LDBBSIFR_SWPL; 907 break; 908 } 909 910 switch (ovl->format->fourcc) { 911 case V4L2_PIX_FMT_RGB565: 912 format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB16; 913 break; 914 case V4L2_PIX_FMT_BGR24: 915 format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB24; 916 break; 917 case V4L2_PIX_FMT_BGR32: 918 format |= LDBBSIFR_AL_PK | LDBBSIFR_RY | LDDFR_PKF_ARGB32; 919 break; 920 case V4L2_PIX_FMT_NV12: 921 case V4L2_PIX_FMT_NV21: 922 format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_420; 923 break; 924 case V4L2_PIX_FMT_NV16: 925 case V4L2_PIX_FMT_NV61: 926 format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_422; 927 break; 928 case V4L2_PIX_FMT_NV24: 929 case V4L2_PIX_FMT_NV42: 930 format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_444; 931 break; 932 } 933 934 lcdc_write(ovl->channel->lcdc, LDBCR, LDBCR_UPC(ovl->index)); 935 936 lcdc_write_overlay(ovl, LDBnBSIFR(ovl->index), format); 937 938 lcdc_write_overlay(ovl, LDBnBSSZR(ovl->index), 939 (ovl->yres << LDBBSSZR_BVSS_SHIFT) | 940 (ovl->xres << LDBBSSZR_BHSS_SHIFT)); 941 lcdc_write_overlay(ovl, LDBnBLOCR(ovl->index), 942 (ovl->pos_y << LDBBLOCR_CVLC_SHIFT) | 943 (ovl->pos_x << LDBBLOCR_CHLC_SHIFT)); 944 lcdc_write_overlay(ovl, LDBnBSMWR(ovl->index), 945 ovl->pitch << LDBBSMWR_BSMW_SHIFT); 946 947 lcdc_write_overlay(ovl, LDBnBSAYR(ovl->index), ovl->base_addr_y); 948 lcdc_write_overlay(ovl, LDBnBSACR(ovl->index), ovl->base_addr_c); 949 950 lcdc_write(ovl->channel->lcdc, LDBCR, 951 LDBCR_UPF(ovl->index) | LDBCR_UPD(ovl->index)); 952} 953 954/* 955 * __sh_mobile_lcdc_start - Configure and start the LCDC 956 * @priv: LCDC device 957 * 958 * Configure all enabled channels and start the LCDC device. All external 959 * devices (clocks, MERAM, panels, ...) are not touched by this function. 960 */ 961static void __sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) 962{ 963 struct sh_mobile_lcdc_chan *ch; 964 unsigned long tmp; 965 int k, m; 966 967 /* Enable LCDC channels. Read data from external memory, avoid using the 968 * BEU for now. 969 */ 970 lcdc_write(priv, _LDCNT2R, priv->ch[0].enabled | priv->ch[1].enabled); 971 972 /* Stop the LCDC first and disable all interrupts. */ 973 sh_mobile_lcdc_start_stop(priv, 0); 974 lcdc_write(priv, _LDINTR, 0); 975 976 /* Configure power supply, dot clocks and start them. */ 977 tmp = priv->lddckr; 978 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 979 ch = &priv->ch[k]; 980 if (!ch->enabled) 981 continue; 982 983 /* Power supply */ 984 lcdc_write_chan(ch, LDPMR, 0); 985 986 m = ch->cfg->clock_divider; 987 if (!m) 988 continue; 989 990 /* FIXME: sh7724 can only use 42, 48, 54 and 60 for the divider 991 * denominator. 992 */ 993 lcdc_write_chan(ch, LDDCKPAT1R, 0); 994 lcdc_write_chan(ch, LDDCKPAT2R, (1 << (m/2)) - 1); 995 996 if (m == 1) 997 m = LDDCKR_MOSEL; 998 tmp |= m << (lcdc_chan_is_sublcd(ch) ? 8 : 0); 999 } 1000 1001 lcdc_write(priv, _LDDCKR, tmp); 1002 lcdc_write(priv, _LDDCKSTPR, 0); 1003 lcdc_wait_bit(priv, _LDDCKSTPR, ~0, 0); 1004 1005 /* Setup geometry, format, frame buffer memory and operation mode. */ 1006 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 1007 ch = &priv->ch[k]; 1008 if (!ch->enabled) 1009 continue; 1010 1011 sh_mobile_lcdc_geometry(ch); 1012 1013 tmp = ch->format->lddfr; 1014 1015 if (ch->format->yuv) { 1016 switch (ch->colorspace) { 1017 case V4L2_COLORSPACE_REC709: 1018 tmp |= LDDFR_CF1; 1019 break; 1020 case V4L2_COLORSPACE_JPEG: 1021 tmp |= LDDFR_CF0; 1022 break; 1023 } 1024 } 1025 1026 lcdc_write_chan(ch, LDDFR, tmp); 1027 lcdc_write_chan(ch, LDMLSR, ch->line_size); 1028 lcdc_write_chan(ch, LDSA1R, ch->base_addr_y); 1029 if (ch->format->yuv) 1030 lcdc_write_chan(ch, LDSA2R, ch->base_addr_c); 1031 1032 /* When using deferred I/O mode, configure the LCDC for one-shot 1033 * operation and enable the frame end interrupt. Otherwise use 1034 * continuous read mode. 1035 */ 1036 if (ch->ldmt1r_value & LDMT1R_IFM && 1037 ch->cfg->sys_bus_cfg.deferred_io_msec) { 1038 lcdc_write_chan(ch, LDSM1R, LDSM1R_OS); 1039 lcdc_write(priv, _LDINTR, LDINTR_FE); 1040 } else { 1041 lcdc_write_chan(ch, LDSM1R, 0); 1042 } 1043 } 1044 1045 /* Word and long word swap. */ 1046 switch (priv->ch[0].format->fourcc) { 1047 case V4L2_PIX_FMT_RGB565: 1048 case V4L2_PIX_FMT_NV21: 1049 case V4L2_PIX_FMT_NV61: 1050 case V4L2_PIX_FMT_NV42: 1051 tmp = LDDDSR_LS | LDDDSR_WS; 1052 break; 1053 case V4L2_PIX_FMT_BGR24: 1054 case V4L2_PIX_FMT_NV12: 1055 case V4L2_PIX_FMT_NV16: 1056 case V4L2_PIX_FMT_NV24: 1057 tmp = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS; 1058 break; 1059 case V4L2_PIX_FMT_BGR32: 1060 default: 1061 tmp = LDDDSR_LS; 1062 break; 1063 } 1064 lcdc_write(priv, _LDDDSR, tmp); 1065 1066 /* Enable the display output. */ 1067 lcdc_write(priv, _LDCNT1R, LDCNT1R_DE); 1068 sh_mobile_lcdc_start_stop(priv, 1); 1069 priv->started = 1; 1070} 1071 1072static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) 1073{ 1074 struct sh_mobile_meram_info *mdev = priv->meram_dev; 1075 struct sh_mobile_lcdc_chan *ch; 1076 unsigned long tmp; 1077 int ret; 1078 int k; 1079 1080 /* enable clocks before accessing the hardware */ 1081 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 1082 if (priv->ch[k].enabled) 1083 sh_mobile_lcdc_clk_on(priv); 1084 } 1085 1086 /* reset */ 1087 lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) | LDCNT2R_BR); 1088 lcdc_wait_bit(priv, _LDCNT2R, LDCNT2R_BR, 0); 1089 1090 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 1091 const struct sh_mobile_lcdc_panel_cfg *panel; 1092 1093 ch = &priv->ch[k]; 1094 if (!ch->enabled) 1095 continue; 1096 1097 panel = &ch->cfg->panel_cfg; 1098 if (panel->setup_sys) { 1099 ret = panel->setup_sys(ch, &sh_mobile_lcdc_sys_bus_ops); 1100 if (ret) 1101 return ret; 1102 } 1103 } 1104 1105 /* Compute frame buffer base address and pitch for each channel. */ 1106 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 1107 int pixelformat; 1108 void *cache; 1109 1110 ch = &priv->ch[k]; 1111 if (!ch->enabled) 1112 continue; 1113 1114 ch->base_addr_y = ch->dma_handle; 1115 ch->base_addr_c = ch->dma_handle 1116 + ch->xres_virtual * ch->yres_virtual; 1117 ch->line_size = ch->pitch; 1118 1119 /* Enable MERAM if possible. */ 1120 if (mdev == NULL || ch->cfg->meram_cfg == NULL) 1121 continue; 1122 1123 /* Free the allocated MERAM cache. */ 1124 if (ch->cache) { 1125 sh_mobile_meram_cache_free(mdev, ch->cache); 1126 ch->cache = NULL; 1127 } 1128 1129 switch (ch->format->fourcc) { 1130 case V4L2_PIX_FMT_NV12: 1131 case V4L2_PIX_FMT_NV21: 1132 case V4L2_PIX_FMT_NV16: 1133 case V4L2_PIX_FMT_NV61: 1134 pixelformat = SH_MOBILE_MERAM_PF_NV; 1135 break; 1136 case V4L2_PIX_FMT_NV24: 1137 case V4L2_PIX_FMT_NV42: 1138 pixelformat = SH_MOBILE_MERAM_PF_NV24; 1139 break; 1140 case V4L2_PIX_FMT_RGB565: 1141 case V4L2_PIX_FMT_BGR24: 1142 case V4L2_PIX_FMT_BGR32: 1143 default: 1144 pixelformat = SH_MOBILE_MERAM_PF_RGB; 1145 break; 1146 } 1147 1148 cache = sh_mobile_meram_cache_alloc(mdev, ch->cfg->meram_cfg, 1149 ch->pitch, ch->yres, pixelformat, 1150 &ch->line_size); 1151 if (!IS_ERR(cache)) { 1152 sh_mobile_meram_cache_update(mdev, cache, 1153 ch->base_addr_y, ch->base_addr_c, 1154 &ch->base_addr_y, &ch->base_addr_c); 1155 ch->cache = cache; 1156 } 1157 } 1158 1159 for (k = 0; k < ARRAY_SIZE(priv->overlays); ++k) { 1160 struct sh_mobile_lcdc_overlay *ovl = &priv->overlays[k]; 1161 sh_mobile_lcdc_overlay_setup(ovl); 1162 } 1163 1164 /* Start the LCDC. */ 1165 __sh_mobile_lcdc_start(priv); 1166 1167 /* Setup deferred I/O, tell the board code to enable the panels, and 1168 * turn backlight on. 1169 */ 1170 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 1171 ch = &priv->ch[k]; 1172 if (!ch->enabled) 1173 continue; 1174 1175 tmp = ch->cfg->sys_bus_cfg.deferred_io_msec; 1176 if (ch->ldmt1r_value & LDMT1R_IFM && tmp) { 1177 ch->defio.deferred_io = sh_mobile_lcdc_deferred_io; 1178 ch->defio.delay = msecs_to_jiffies(tmp); 1179 ch->info->fbdefio = &ch->defio; 1180 fb_deferred_io_init(ch->info); 1181 } 1182 1183 sh_mobile_lcdc_display_on(ch); 1184 1185 if (ch->bl) { 1186 ch->bl->props.power = FB_BLANK_UNBLANK; 1187 backlight_update_status(ch->bl); 1188 } 1189 } 1190 1191 return 0; 1192} 1193 1194static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) 1195{ 1196 struct sh_mobile_lcdc_chan *ch; 1197 int k; 1198 1199 /* clean up deferred io and ask board code to disable panel */ 1200 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 1201 ch = &priv->ch[k]; 1202 if (!ch->enabled) 1203 continue; 1204 1205 /* deferred io mode: 1206 * flush frame, and wait for frame end interrupt 1207 * clean up deferred io and enable clock 1208 */ 1209 if (ch->info && ch->info->fbdefio) { 1210 ch->frame_end = 0; 1211 schedule_delayed_work(&ch->info->deferred_work, 0); 1212 wait_event(ch->frame_end_wait, ch->frame_end); 1213 fb_deferred_io_cleanup(ch->info); 1214 ch->info->fbdefio = NULL; 1215 sh_mobile_lcdc_clk_on(priv); 1216 } 1217 1218 if (ch->bl) { 1219 ch->bl->props.power = FB_BLANK_POWERDOWN; 1220 backlight_update_status(ch->bl); 1221 } 1222 1223 sh_mobile_lcdc_display_off(ch); 1224 1225 /* Free the MERAM cache. */ 1226 if (ch->cache) { 1227 sh_mobile_meram_cache_free(priv->meram_dev, ch->cache); 1228 ch->cache = 0; 1229 } 1230 1231 } 1232 1233 /* stop the lcdc */ 1234 if (priv->started) { 1235 sh_mobile_lcdc_start_stop(priv, 0); 1236 priv->started = 0; 1237 } 1238 1239 /* stop clocks */ 1240 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) 1241 if (priv->ch[k].enabled) 1242 sh_mobile_lcdc_clk_off(priv); 1243} 1244 1245static int __sh_mobile_lcdc_check_var(struct fb_var_screeninfo *var, 1246 struct fb_info *info) 1247{ 1248 if (var->xres > MAX_XRES || var->yres > MAX_YRES) 1249 return -EINVAL; 1250 1251 /* Make sure the virtual resolution is at least as big as the visible 1252 * resolution. 1253 */ 1254 if (var->xres_virtual < var->xres) 1255 var->xres_virtual = var->xres; 1256 if (var->yres_virtual < var->yres) 1257 var->yres_virtual = var->yres; 1258 1259 if (sh_mobile_format_is_fourcc(var)) { 1260 const struct sh_mobile_lcdc_format_info *format; 1261 1262 format = sh_mobile_format_info(var->grayscale); 1263 if (format == NULL) 1264 return -EINVAL; 1265 var->bits_per_pixel = format->bpp; 1266 1267 /* Default to RGB and JPEG color-spaces for RGB and YUV formats 1268 * respectively. 1269 */ 1270 if (!format->yuv) 1271 var->colorspace = V4L2_COLORSPACE_SRGB; 1272 else if (var->colorspace != V4L2_COLORSPACE_REC709) 1273 var->colorspace = V4L2_COLORSPACE_JPEG; 1274 } else { 1275 if (var->bits_per_pixel <= 16) { /* RGB 565 */ 1276 var->bits_per_pixel = 16; 1277 var->red.offset = 11; 1278 var->red.length = 5; 1279 var->green.offset = 5; 1280 var->green.length = 6; 1281 var->blue.offset = 0; 1282 var->blue.length = 5; 1283 var->transp.offset = 0; 1284 var->transp.length = 0; 1285 } else if (var->bits_per_pixel <= 24) { /* RGB 888 */ 1286 var->bits_per_pixel = 24; 1287 var->red.offset = 16; 1288 var->red.length = 8; 1289 var->green.offset = 8; 1290 var->green.length = 8; 1291 var->blue.offset = 0; 1292 var->blue.length = 8; 1293 var->transp.offset = 0; 1294 var->transp.length = 0; 1295 } else if (var->bits_per_pixel <= 32) { /* RGBA 888 */ 1296 var->bits_per_pixel = 32; 1297 var->red.offset = 16; 1298 var->red.length = 8; 1299 var->green.offset = 8; 1300 var->green.length = 8; 1301 var->blue.offset = 0; 1302 var->blue.length = 8; 1303 var->transp.offset = 24; 1304 var->transp.length = 8; 1305 } else 1306 return -EINVAL; 1307 1308 var->red.msb_right = 0; 1309 var->green.msb_right = 0; 1310 var->blue.msb_right = 0; 1311 var->transp.msb_right = 0; 1312 } 1313 1314 /* Make sure we don't exceed our allocated memory. */ 1315 if (var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8 > 1316 info->fix.smem_len) 1317 return -EINVAL; 1318 1319 return 0; 1320} 1321 1322/* ----------------------------------------------------------------------------- 1323 * Frame buffer operations - Overlays 1324 */ 1325 1326static ssize_t 1327overlay_alpha_show(struct device *dev, struct device_attribute *attr, char *buf) 1328{ 1329 struct fb_info *info = dev_get_drvdata(dev); 1330 struct sh_mobile_lcdc_overlay *ovl = info->par; 1331 1332 return scnprintf(buf, PAGE_SIZE, "%u\n", ovl->alpha); 1333} 1334 1335static ssize_t 1336overlay_alpha_store(struct device *dev, struct device_attribute *attr, 1337 const char *buf, size_t count) 1338{ 1339 struct fb_info *info = dev_get_drvdata(dev); 1340 struct sh_mobile_lcdc_overlay *ovl = info->par; 1341 unsigned int alpha; 1342 char *endp; 1343 1344 alpha = simple_strtoul(buf, &endp, 10); 1345 if (isspace(*endp)) 1346 endp++; 1347 1348 if (endp - buf != count) 1349 return -EINVAL; 1350 1351 if (alpha > 255) 1352 return -EINVAL; 1353 1354 if (ovl->alpha != alpha) { 1355 ovl->alpha = alpha; 1356 1357 if (ovl->mode == LCDC_OVERLAY_BLEND && ovl->enabled) 1358 sh_mobile_lcdc_overlay_setup(ovl); 1359 } 1360 1361 return count; 1362} 1363 1364static ssize_t 1365overlay_mode_show(struct device *dev, struct device_attribute *attr, char *buf) 1366{ 1367 struct fb_info *info = dev_get_drvdata(dev); 1368 struct sh_mobile_lcdc_overlay *ovl = info->par; 1369 1370 return scnprintf(buf, PAGE_SIZE, "%u\n", ovl->mode); 1371} 1372 1373static ssize_t 1374overlay_mode_store(struct device *dev, struct device_attribute *attr, 1375 const char *buf, size_t count) 1376{ 1377 struct fb_info *info = dev_get_drvdata(dev); 1378 struct sh_mobile_lcdc_overlay *ovl = info->par; 1379 unsigned int mode; 1380 char *endp; 1381 1382 mode = simple_strtoul(buf, &endp, 10); 1383 if (isspace(*endp)) 1384 endp++; 1385 1386 if (endp - buf != count) 1387 return -EINVAL; 1388 1389 if (mode != LCDC_OVERLAY_BLEND && mode != LCDC_OVERLAY_ROP3) 1390 return -EINVAL; 1391 1392 if (ovl->mode != mode) { 1393 ovl->mode = mode; 1394 1395 if (ovl->enabled) 1396 sh_mobile_lcdc_overlay_setup(ovl); 1397 } 1398 1399 return count; 1400} 1401 1402static ssize_t 1403overlay_position_show(struct device *dev, struct device_attribute *attr, 1404 char *buf) 1405{ 1406 struct fb_info *info = dev_get_drvdata(dev); 1407 struct sh_mobile_lcdc_overlay *ovl = info->par; 1408 1409 return scnprintf(buf, PAGE_SIZE, "%d,%d\n", ovl->pos_x, ovl->pos_y); 1410} 1411 1412static ssize_t 1413overlay_position_store(struct device *dev, struct device_attribute *attr, 1414 const char *buf, size_t count) 1415{ 1416 struct fb_info *info = dev_get_drvdata(dev); 1417 struct sh_mobile_lcdc_overlay *ovl = info->par; 1418 char *endp; 1419 int pos_x; 1420 int pos_y; 1421 1422 pos_x = simple_strtol(buf, &endp, 10); 1423 if (*endp != ',') 1424 return -EINVAL; 1425 1426 pos_y = simple_strtol(endp + 1, &endp, 10); 1427 if (isspace(*endp)) 1428 endp++; 1429 1430 if (endp - buf != count) 1431 return -EINVAL; 1432 1433 if (ovl->pos_x != pos_x || ovl->pos_y != pos_y) { 1434 ovl->pos_x = pos_x; 1435 ovl->pos_y = pos_y; 1436 1437 if (ovl->enabled) 1438 sh_mobile_lcdc_overlay_setup(ovl); 1439 } 1440 1441 return count; 1442} 1443 1444static ssize_t 1445overlay_rop3_show(struct device *dev, struct device_attribute *attr, char *buf) 1446{ 1447 struct fb_info *info = dev_get_drvdata(dev); 1448 struct sh_mobile_lcdc_overlay *ovl = info->par; 1449 1450 return scnprintf(buf, PAGE_SIZE, "%u\n", ovl->rop3); 1451} 1452 1453static ssize_t 1454overlay_rop3_store(struct device *dev, struct device_attribute *attr, 1455 const char *buf, size_t count) 1456{ 1457 struct fb_info *info = dev_get_drvdata(dev); 1458 struct sh_mobile_lcdc_overlay *ovl = info->par; 1459 unsigned int rop3; 1460 char *endp; 1461 1462 rop3 = !!simple_strtoul(buf, &endp, 10); 1463 if (isspace(*endp)) 1464 endp++; 1465 1466 if (endp - buf != count) 1467 return -EINVAL; 1468 1469 if (rop3 > 255) 1470 return -EINVAL; 1471 1472 if (ovl->rop3 != rop3) { 1473 ovl->rop3 = rop3; 1474 1475 if (ovl->mode == LCDC_OVERLAY_ROP3 && ovl->enabled) 1476 sh_mobile_lcdc_overlay_setup(ovl); 1477 } 1478 1479 return count; 1480} 1481 1482static const struct device_attribute overlay_sysfs_attrs[] = { 1483 __ATTR(ovl_alpha, S_IRUGO|S_IWUSR, 1484 overlay_alpha_show, overlay_alpha_store), 1485 __ATTR(ovl_mode, S_IRUGO|S_IWUSR, 1486 overlay_mode_show, overlay_mode_store), 1487 __ATTR(ovl_position, S_IRUGO|S_IWUSR, 1488 overlay_position_show, overlay_position_store), 1489 __ATTR(ovl_rop3, S_IRUGO|S_IWUSR, 1490 overlay_rop3_show, overlay_rop3_store), 1491}; 1492 1493static const struct fb_fix_screeninfo sh_mobile_lcdc_overlay_fix = { 1494 .id = "SH Mobile LCDC", 1495 .type = FB_TYPE_PACKED_PIXELS, 1496 .visual = FB_VISUAL_TRUECOLOR, 1497 .accel = FB_ACCEL_NONE, 1498 .xpanstep = 1, 1499 .ypanstep = 1, 1500 .ywrapstep = 0, 1501 .capabilities = FB_CAP_FOURCC, 1502}; 1503 1504static int sh_mobile_lcdc_overlay_pan(struct fb_var_screeninfo *var, 1505 struct fb_info *info) 1506{ 1507 struct sh_mobile_lcdc_overlay *ovl = info->par; 1508 unsigned long base_addr_y; 1509 unsigned long base_addr_c; 1510 unsigned long y_offset; 1511 unsigned long c_offset; 1512 1513 if (!ovl->format->yuv) { 1514 y_offset = (var->yoffset * ovl->xres_virtual + var->xoffset) 1515 * ovl->format->bpp / 8; 1516 c_offset = 0; 1517 } else { 1518 unsigned int xsub = ovl->format->bpp < 24 ? 2 : 1; 1519 unsigned int ysub = ovl->format->bpp < 16 ? 2 : 1; 1520 1521 y_offset = var->yoffset * ovl->xres_virtual + var->xoffset; 1522 c_offset = var->yoffset / ysub * ovl->xres_virtual * 2 / xsub 1523 + var->xoffset * 2 / xsub; 1524 } 1525 1526 /* If the Y offset hasn't changed, the C offset hasn't either. There's 1527 * nothing to do in that case. 1528 */ 1529 if (y_offset == ovl->pan_y_offset) 1530 return 0; 1531 1532 /* Set the source address for the next refresh */ 1533 base_addr_y = ovl->dma_handle + y_offset; 1534 base_addr_c = ovl->dma_handle + ovl->xres_virtual * ovl->yres_virtual 1535 + c_offset; 1536 1537 ovl->base_addr_y = base_addr_y; 1538 ovl->base_addr_c = base_addr_c; 1539 ovl->pan_y_offset = y_offset; 1540 1541 lcdc_write(ovl->channel->lcdc, LDBCR, LDBCR_UPC(ovl->index)); 1542 1543 lcdc_write_overlay(ovl, LDBnBSAYR(ovl->index), ovl->base_addr_y); 1544 lcdc_write_overlay(ovl, LDBnBSACR(ovl->index), ovl->base_addr_c); 1545 1546 lcdc_write(ovl->channel->lcdc, LDBCR, 1547 LDBCR_UPF(ovl->index) | LDBCR_UPD(ovl->index)); 1548 1549 return 0; 1550} 1551 1552static int sh_mobile_lcdc_overlay_ioctl(struct fb_info *info, unsigned int cmd, 1553 unsigned long arg) 1554{ 1555 struct sh_mobile_lcdc_overlay *ovl = info->par; 1556 1557 switch (cmd) { 1558 case FBIO_WAITFORVSYNC: 1559 return sh_mobile_lcdc_wait_for_vsync(ovl->channel); 1560 1561 default: 1562 return -ENOIOCTLCMD; 1563 } 1564} 1565 1566static int sh_mobile_lcdc_overlay_check_var(struct fb_var_screeninfo *var, 1567 struct fb_info *info) 1568{ 1569 return __sh_mobile_lcdc_check_var(var, info); 1570} 1571 1572static int sh_mobile_lcdc_overlay_set_par(struct fb_info *info) 1573{ 1574 struct sh_mobile_lcdc_overlay *ovl = info->par; 1575 1576 ovl->format = 1577 sh_mobile_format_info(sh_mobile_format_fourcc(&info->var)); 1578 1579 ovl->xres = info->var.xres; 1580 ovl->xres_virtual = info->var.xres_virtual; 1581 ovl->yres = info->var.yres; 1582 ovl->yres_virtual = info->var.yres_virtual; 1583 1584 if (ovl->format->yuv) 1585 ovl->pitch = info->var.xres_virtual; 1586 else 1587 ovl->pitch = info->var.xres_virtual * ovl->format->bpp / 8; 1588 1589 sh_mobile_lcdc_overlay_setup(ovl); 1590 1591 info->fix.line_length = ovl->pitch; 1592 1593 if (sh_mobile_format_is_fourcc(&info->var)) { 1594 info->fix.type = FB_TYPE_FOURCC; 1595 info->fix.visual = FB_VISUAL_FOURCC; 1596 } else { 1597 info->fix.type = FB_TYPE_PACKED_PIXELS; 1598 info->fix.visual = FB_VISUAL_TRUECOLOR; 1599 } 1600 1601 return 0; 1602} 1603 1604/* Overlay blanking. Disable the overlay when blanked. */ 1605static int sh_mobile_lcdc_overlay_blank(int blank, struct fb_info *info) 1606{ 1607 struct sh_mobile_lcdc_overlay *ovl = info->par; 1608 1609 ovl->enabled = !blank; 1610 sh_mobile_lcdc_overlay_setup(ovl); 1611 1612 /* Prevent the backlight from receiving a blanking event by returning 1613 * a non-zero value. 1614 */ 1615 return 1; 1616} 1617 1618static int 1619sh_mobile_lcdc_overlay_mmap(struct fb_info *info, struct vm_area_struct *vma) 1620{ 1621 struct sh_mobile_lcdc_overlay *ovl = info->par; 1622 1623 return dma_mmap_coherent(ovl->channel->lcdc->dev, vma, ovl->fb_mem, 1624 ovl->dma_handle, ovl->fb_size); 1625} 1626 1627static struct fb_ops sh_mobile_lcdc_overlay_ops = { 1628 .owner = THIS_MODULE, 1629 .fb_read = fb_sys_read, 1630 .fb_write = fb_sys_write, 1631 .fb_fillrect = sys_fillrect, 1632 .fb_copyarea = sys_copyarea, 1633 .fb_imageblit = sys_imageblit, 1634 .fb_blank = sh_mobile_lcdc_overlay_blank, 1635 .fb_pan_display = sh_mobile_lcdc_overlay_pan, 1636 .fb_ioctl = sh_mobile_lcdc_overlay_ioctl, 1637 .fb_check_var = sh_mobile_lcdc_overlay_check_var, 1638 .fb_set_par = sh_mobile_lcdc_overlay_set_par, 1639 .fb_mmap = sh_mobile_lcdc_overlay_mmap, 1640}; 1641 1642static void 1643sh_mobile_lcdc_overlay_fb_unregister(struct sh_mobile_lcdc_overlay *ovl) 1644{ 1645 struct fb_info *info = ovl->info; 1646 1647 if (info == NULL || info->dev == NULL) 1648 return; 1649 1650 unregister_framebuffer(ovl->info); 1651} 1652 1653static int 1654sh_mobile_lcdc_overlay_fb_register(struct sh_mobile_lcdc_overlay *ovl) 1655{ 1656 struct sh_mobile_lcdc_priv *lcdc = ovl->channel->lcdc; 1657 struct fb_info *info = ovl->info; 1658 unsigned int i; 1659 int ret; 1660 1661 if (info == NULL) 1662 return 0; 1663 1664 ret = register_framebuffer(info); 1665 if (ret < 0) 1666 return ret; 1667 1668 dev_info(lcdc->dev, "registered %s/overlay %u as %dx%d %dbpp.\n", 1669 dev_name(lcdc->dev), ovl->index, info->var.xres, 1670 info->var.yres, info->var.bits_per_pixel); 1671 1672 for (i = 0; i < ARRAY_SIZE(overlay_sysfs_attrs); ++i) { 1673 ret = device_create_file(info->dev, &overlay_sysfs_attrs[i]); 1674 if (ret < 0) 1675 return ret; 1676 } 1677 1678 return 0; 1679} 1680 1681static void 1682sh_mobile_lcdc_overlay_fb_cleanup(struct sh_mobile_lcdc_overlay *ovl) 1683{ 1684 struct fb_info *info = ovl->info; 1685 1686 if (info == NULL || info->device == NULL) 1687 return; 1688 1689 framebuffer_release(info); 1690} 1691 1692static int 1693sh_mobile_lcdc_overlay_fb_init(struct sh_mobile_lcdc_overlay *ovl) 1694{ 1695 struct sh_mobile_lcdc_priv *priv = ovl->channel->lcdc; 1696 struct fb_var_screeninfo *var; 1697 struct fb_info *info; 1698 1699 /* Allocate and initialize the frame buffer device. */ 1700 info = framebuffer_alloc(0, priv->dev); 1701 if (info == NULL) { 1702 dev_err(priv->dev, "unable to allocate fb_info\n"); 1703 return -ENOMEM; 1704 } 1705 1706 ovl->info = info; 1707 1708 info->flags = FBINFO_FLAG_DEFAULT; 1709 info->fbops = &sh_mobile_lcdc_overlay_ops; 1710 info->device = priv->dev; 1711 info->screen_base = ovl->fb_mem; 1712 info->par = ovl; 1713 1714 /* Initialize fixed screen information. Restrict pan to 2 lines steps 1715 * for NV12 and NV21. 1716 */ 1717 info->fix = sh_mobile_lcdc_overlay_fix; 1718 snprintf(info->fix.id, sizeof(info->fix.id), 1719 "SH Mobile LCDC Overlay %u", ovl->index); 1720 info->fix.smem_start = ovl->dma_handle; 1721 info->fix.smem_len = ovl->fb_size; 1722 info->fix.line_length = ovl->pitch; 1723 1724 if (ovl->format->yuv) 1725 info->fix.visual = FB_VISUAL_FOURCC; 1726 else 1727 info->fix.visual = FB_VISUAL_TRUECOLOR; 1728 1729 switch (ovl->format->fourcc) { 1730 case V4L2_PIX_FMT_NV12: 1731 case V4L2_PIX_FMT_NV21: 1732 info->fix.ypanstep = 2; 1733 case V4L2_PIX_FMT_NV16: 1734 case V4L2_PIX_FMT_NV61: 1735 info->fix.xpanstep = 2; 1736 } 1737 1738 /* Initialize variable screen information. */ 1739 var = &info->var; 1740 memset(var, 0, sizeof(*var)); 1741 var->xres = ovl->xres; 1742 var->yres = ovl->yres; 1743 var->xres_virtual = ovl->xres_virtual; 1744 var->yres_virtual = ovl->yres_virtual; 1745 var->activate = FB_ACTIVATE_NOW; 1746 1747 /* Use the legacy API by default for RGB formats, and the FOURCC API 1748 * for YUV formats. 1749 */ 1750 if (!ovl->format->yuv) 1751 var->bits_per_pixel = ovl->format->bpp; 1752 else 1753 var->grayscale = ovl->format->fourcc; 1754 1755 return sh_mobile_lcdc_overlay_check_var(var, info); 1756} 1757 1758/* ----------------------------------------------------------------------------- 1759 * Frame buffer operations - main frame buffer 1760 */ 1761 1762static int sh_mobile_lcdc_setcolreg(u_int regno, 1763 u_int red, u_int green, u_int blue, 1764 u_int transp, struct fb_info *info) 1765{ 1766 u32 *palette = info->pseudo_palette; 1767 1768 if (regno >= PALETTE_NR) 1769 return -EINVAL; 1770 1771 /* only FB_VISUAL_TRUECOLOR supported */ 1772 1773 red >>= 16 - info->var.red.length; 1774 green >>= 16 - info->var.green.length; 1775 blue >>= 16 - info->var.blue.length; 1776 transp >>= 16 - info->var.transp.length; 1777 1778 palette[regno] = (red << info->var.red.offset) | 1779 (green << info->var.green.offset) | 1780 (blue << info->var.blue.offset) | 1781 (transp << info->var.transp.offset); 1782 1783 return 0; 1784} 1785 1786static const struct fb_fix_screeninfo sh_mobile_lcdc_fix = { 1787 .id = "SH Mobile LCDC", 1788 .type = FB_TYPE_PACKED_PIXELS, 1789 .visual = FB_VISUAL_TRUECOLOR, 1790 .accel = FB_ACCEL_NONE, 1791 .xpanstep = 1, 1792 .ypanstep = 1, 1793 .ywrapstep = 0, 1794 .capabilities = FB_CAP_FOURCC, 1795}; 1796 1797static void sh_mobile_lcdc_fillrect(struct fb_info *info, 1798 const struct fb_fillrect *rect) 1799{ 1800 sys_fillrect(info, rect); 1801 sh_mobile_lcdc_deferred_io_touch(info); 1802} 1803 1804static void sh_mobile_lcdc_copyarea(struct fb_info *info, 1805 const struct fb_copyarea *area) 1806{ 1807 sys_copyarea(info, area); 1808 sh_mobile_lcdc_deferred_io_touch(info); 1809} 1810 1811static void sh_mobile_lcdc_imageblit(struct fb_info *info, 1812 const struct fb_image *image) 1813{ 1814 sys_imageblit(info, image); 1815 sh_mobile_lcdc_deferred_io_touch(info); 1816} 1817 1818static int sh_mobile_lcdc_pan(struct fb_var_screeninfo *var, 1819 struct fb_info *info) 1820{ 1821 struct sh_mobile_lcdc_chan *ch = info->par; 1822 struct sh_mobile_lcdc_priv *priv = ch->lcdc; 1823 unsigned long ldrcntr; 1824 unsigned long base_addr_y, base_addr_c; 1825 unsigned long y_offset; 1826 unsigned long c_offset; 1827 1828 if (!ch->format->yuv) { 1829 y_offset = (var->yoffset * ch->xres_virtual + var->xoffset) 1830 * ch->format->bpp / 8; 1831 c_offset = 0; 1832 } else { 1833 unsigned int xsub = ch->format->bpp < 24 ? 2 : 1; 1834 unsigned int ysub = ch->format->bpp < 16 ? 2 : 1; 1835 1836 y_offset = var->yoffset * ch->xres_virtual + var->xoffset; 1837 c_offset = var->yoffset / ysub * ch->xres_virtual * 2 / xsub 1838 + var->xoffset * 2 / xsub; 1839 } 1840 1841 /* If the Y offset hasn't changed, the C offset hasn't either. There's 1842 * nothing to do in that case. 1843 */ 1844 if (y_offset == ch->pan_y_offset) 1845 return 0; 1846 1847 /* Set the source address for the next refresh */ 1848 base_addr_y = ch->dma_handle + y_offset; 1849 base_addr_c = ch->dma_handle + ch->xres_virtual * ch->yres_virtual 1850 + c_offset; 1851 1852 if (ch->cache) 1853 sh_mobile_meram_cache_update(priv->meram_dev, ch->cache, 1854 base_addr_y, base_addr_c, 1855 &base_addr_y, &base_addr_c); 1856 1857 ch->base_addr_y = base_addr_y; 1858 ch->base_addr_c = base_addr_c; 1859 ch->pan_y_offset = y_offset; 1860 1861 lcdc_write_chan_mirror(ch, LDSA1R, base_addr_y); 1862 if (ch->format->yuv) 1863 lcdc_write_chan_mirror(ch, LDSA2R, base_addr_c); 1864 1865 ldrcntr = lcdc_read(priv, _LDRCNTR); 1866 if (lcdc_chan_is_sublcd(ch)) 1867 lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_SRS); 1868 else 1869 lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_MRS); 1870 1871 1872 sh_mobile_lcdc_deferred_io_touch(info); 1873 1874 return 0; 1875} 1876 1877static int sh_mobile_lcdc_ioctl(struct fb_info *info, unsigned int cmd, 1878 unsigned long arg) 1879{ 1880 struct sh_mobile_lcdc_chan *ch = info->par; 1881 int retval; 1882 1883 switch (cmd) { 1884 case FBIO_WAITFORVSYNC: 1885 retval = sh_mobile_lcdc_wait_for_vsync(ch); 1886 break; 1887 1888 default: 1889 retval = -ENOIOCTLCMD; 1890 break; 1891 } 1892 return retval; 1893} 1894 1895static void sh_mobile_fb_reconfig(struct fb_info *info) 1896{ 1897 struct sh_mobile_lcdc_chan *ch = info->par; 1898 struct fb_var_screeninfo var; 1899 struct fb_videomode mode; 1900 struct fb_event event; 1901 int evnt = FB_EVENT_MODE_CHANGE_ALL; 1902 1903 if (ch->use_count > 1 || (ch->use_count == 1 && !info->fbcon_par)) 1904 /* More framebuffer users are active */ 1905 return; 1906 1907 fb_var_to_videomode(&mode, &info->var); 1908 1909 if (fb_mode_is_equal(&ch->display.mode, &mode)) 1910 return; 1911 1912 /* Display has been re-plugged, framebuffer is free now, reconfigure */ 1913 var = info->var; 1914 fb_videomode_to_var(&var, &ch->display.mode); 1915 var.width = ch->display.width; 1916 var.height = ch->display.height; 1917 var.activate = FB_ACTIVATE_NOW; 1918 1919 if (fb_set_var(info, &var) < 0) 1920 /* Couldn't reconfigure, hopefully, can continue as before */ 1921 return; 1922 1923 /* 1924 * fb_set_var() calls the notifier change internally, only if 1925 * FBINFO_MISC_USEREVENT flag is set. Since we do not want to fake a 1926 * user event, we have to call the chain ourselves. 1927 */ 1928 event.info = info; 1929 event.data = &ch->display.mode; 1930 fb_notifier_call_chain(evnt, &event); 1931} 1932 1933/* 1934 * Locking: both .fb_release() and .fb_open() are called with info->lock held if 1935 * user == 1, or with console sem held, if user == 0. 1936 */ 1937static int sh_mobile_lcdc_release(struct fb_info *info, int user) 1938{ 1939 struct sh_mobile_lcdc_chan *ch = info->par; 1940 1941 mutex_lock(&ch->open_lock); 1942 dev_dbg(info->dev, "%s(): %d users\n", __func__, ch->use_count); 1943 1944 ch->use_count--; 1945 1946 /* Nothing to reconfigure, when called from fbcon */ 1947 if (user) { 1948 console_lock(); 1949 sh_mobile_fb_reconfig(info); 1950 console_unlock(); 1951 } 1952 1953 mutex_unlock(&ch->open_lock); 1954 1955 return 0; 1956} 1957 1958static int sh_mobile_lcdc_open(struct fb_info *info, int user) 1959{ 1960 struct sh_mobile_lcdc_chan *ch = info->par; 1961 1962 mutex_lock(&ch->open_lock); 1963 ch->use_count++; 1964 1965 dev_dbg(info->dev, "%s(): %d users\n", __func__, ch->use_count); 1966 mutex_unlock(&ch->open_lock); 1967 1968 return 0; 1969} 1970 1971static int sh_mobile_lcdc_check_var(struct fb_var_screeninfo *var, 1972 struct fb_info *info) 1973{ 1974 struct sh_mobile_lcdc_chan *ch = info->par; 1975 struct sh_mobile_lcdc_priv *p = ch->lcdc; 1976 unsigned int best_dist = (unsigned int)-1; 1977 unsigned int best_xres = 0; 1978 unsigned int best_yres = 0; 1979 unsigned int i; 1980 int ret; 1981 1982 /* If board code provides us with a list of available modes, make sure 1983 * we use one of them. Find the mode closest to the requested one. The 1984 * distance between two modes is defined as the size of the 1985 * non-overlapping parts of the two rectangles. 1986 */ 1987 for (i = 0; i < ch->cfg->num_modes; ++i) { 1988 const struct fb_videomode *mode = &ch->cfg->lcd_modes[i]; 1989 unsigned int dist; 1990 1991 /* We can only round up. */ 1992 if (var->xres > mode->xres || var->yres > mode->yres) 1993 continue; 1994 1995 dist = var->xres * var->yres + mode->xres * mode->yres 1996 - 2 * min(var->xres, mode->xres) 1997 * min(var->yres, mode->yres); 1998 1999 if (dist < best_dist) { 2000 best_xres = mode->xres; 2001 best_yres = mode->yres; 2002 best_dist = dist; 2003 } 2004 } 2005 2006 /* If no available mode can be used, return an error. */ 2007 if (ch->cfg->num_modes != 0) { 2008 if (best_dist == (unsigned int)-1) 2009 return -EINVAL; 2010 2011 var->xres = best_xres; 2012 var->yres = best_yres; 2013 } 2014 2015 ret = __sh_mobile_lcdc_check_var(var, info); 2016 if (ret < 0) 2017 return ret; 2018 2019 /* only accept the forced_fourcc for dual channel configurations */ 2020 if (p->forced_fourcc && 2021 p->forced_fourcc != sh_mobile_format_fourcc(var)) 2022 return -EINVAL; 2023 2024 return 0; 2025} 2026 2027static int sh_mobile_lcdc_set_par(struct fb_info *info) 2028{ 2029 struct sh_mobile_lcdc_chan *ch = info->par; 2030 int ret; 2031 2032 sh_mobile_lcdc_stop(ch->lcdc); 2033 2034 ch->format = sh_mobile_format_info(sh_mobile_format_fourcc(&info->var)); 2035 ch->colorspace = info->var.colorspace; 2036 2037 ch->xres = info->var.xres; 2038 ch->xres_virtual = info->var.xres_virtual; 2039 ch->yres = info->var.yres; 2040 ch->yres_virtual = info->var.yres_virtual; 2041 2042 if (ch->format->yuv) 2043 ch->pitch = info->var.xres_virtual; 2044 else 2045 ch->pitch = info->var.xres_virtual * ch->format->bpp / 8; 2046 2047 ret = sh_mobile_lcdc_start(ch->lcdc); 2048 if (ret < 0) 2049 dev_err(info->dev, "%s: unable to restart LCDC\n", __func__); 2050 2051 info->fix.line_length = ch->pitch; 2052 2053 if (sh_mobile_format_is_fourcc(&info->var)) { 2054 info->fix.type = FB_TYPE_FOURCC; 2055 info->fix.visual = FB_VISUAL_FOURCC; 2056 } else { 2057 info->fix.type = FB_TYPE_PACKED_PIXELS; 2058 info->fix.visual = FB_VISUAL_TRUECOLOR; 2059 } 2060 2061 return ret; 2062} 2063 2064/* 2065 * Screen blanking. Behavior is as follows: 2066 * FB_BLANK_UNBLANK: screen unblanked, clocks enabled 2067 * FB_BLANK_NORMAL: screen blanked, clocks enabled 2068 * FB_BLANK_VSYNC, 2069 * FB_BLANK_HSYNC, 2070 * FB_BLANK_POWEROFF: screen blanked, clocks disabled 2071 */ 2072static int sh_mobile_lcdc_blank(int blank, struct fb_info *info) 2073{ 2074 struct sh_mobile_lcdc_chan *ch = info->par; 2075 struct sh_mobile_lcdc_priv *p = ch->lcdc; 2076 2077 /* blank the screen? */ 2078 if (blank > FB_BLANK_UNBLANK && ch->blank_status == FB_BLANK_UNBLANK) { 2079 struct fb_fillrect rect = { 2080 .width = ch->xres, 2081 .height = ch->yres, 2082 }; 2083 sh_mobile_lcdc_fillrect(info, &rect); 2084 } 2085 /* turn clocks on? */ 2086 if (blank <= FB_BLANK_NORMAL && ch->blank_status > FB_BLANK_NORMAL) { 2087 sh_mobile_lcdc_clk_on(p); 2088 } 2089 /* turn clocks off? */ 2090 if (blank > FB_BLANK_NORMAL && ch->blank_status <= FB_BLANK_NORMAL) { 2091 /* make sure the screen is updated with the black fill before 2092 * switching the clocks off. one vsync is not enough since 2093 * blanking may occur in the middle of a refresh. deferred io 2094 * mode will reenable the clocks and update the screen in time, 2095 * so it does not need this. */ 2096 if (!info->fbdefio) { 2097 sh_mobile_lcdc_wait_for_vsync(ch); 2098 sh_mobile_lcdc_wait_for_vsync(ch); 2099 } 2100 sh_mobile_lcdc_clk_off(p); 2101 } 2102 2103 ch->blank_status = blank; 2104 return 0; 2105} 2106 2107static int 2108sh_mobile_lcdc_mmap(struct fb_info *info, struct vm_area_struct *vma) 2109{ 2110 struct sh_mobile_lcdc_chan *ch = info->par; 2111 2112 return dma_mmap_coherent(ch->lcdc->dev, vma, ch->fb_mem, 2113 ch->dma_handle, ch->fb_size); 2114} 2115 2116static struct fb_ops sh_mobile_lcdc_ops = { 2117 .owner = THIS_MODULE, 2118 .fb_setcolreg = sh_mobile_lcdc_setcolreg, 2119 .fb_read = fb_sys_read, 2120 .fb_write = fb_sys_write, 2121 .fb_fillrect = sh_mobile_lcdc_fillrect, 2122 .fb_copyarea = sh_mobile_lcdc_copyarea, 2123 .fb_imageblit = sh_mobile_lcdc_imageblit, 2124 .fb_blank = sh_mobile_lcdc_blank, 2125 .fb_pan_display = sh_mobile_lcdc_pan, 2126 .fb_ioctl = sh_mobile_lcdc_ioctl, 2127 .fb_open = sh_mobile_lcdc_open, 2128 .fb_release = sh_mobile_lcdc_release, 2129 .fb_check_var = sh_mobile_lcdc_check_var, 2130 .fb_set_par = sh_mobile_lcdc_set_par, 2131 .fb_mmap = sh_mobile_lcdc_mmap, 2132}; 2133 2134static void 2135sh_mobile_lcdc_channel_fb_unregister(struct sh_mobile_lcdc_chan *ch) 2136{ 2137 if (ch->info && ch->info->dev) 2138 unregister_framebuffer(ch->info); 2139} 2140 2141static int 2142sh_mobile_lcdc_channel_fb_register(struct sh_mobile_lcdc_chan *ch) 2143{ 2144 struct fb_info *info = ch->info; 2145 int ret; 2146 2147 if (info->fbdefio) { 2148 ch->sglist = vmalloc(sizeof(struct scatterlist) * 2149 ch->fb_size >> PAGE_SHIFT); 2150 if (!ch->sglist) { 2151 dev_err(ch->lcdc->dev, "cannot allocate sglist\n"); 2152 return -ENOMEM; 2153 } 2154 } 2155 2156 info->bl_dev = ch->bl; 2157 2158 ret = register_framebuffer(info); 2159 if (ret < 0) 2160 return ret; 2161 2162 dev_info(ch->lcdc->dev, "registered %s/%s as %dx%d %dbpp.\n", 2163 dev_name(ch->lcdc->dev), (ch->cfg->chan == LCDC_CHAN_MAINLCD) ? 2164 "mainlcd" : "sublcd", info->var.xres, info->var.yres, 2165 info->var.bits_per_pixel); 2166 2167 /* deferred io mode: disable clock to save power */ 2168 if (info->fbdefio || info->state == FBINFO_STATE_SUSPENDED) 2169 sh_mobile_lcdc_clk_off(ch->lcdc); 2170 2171 return ret; 2172} 2173 2174static void 2175sh_mobile_lcdc_channel_fb_cleanup(struct sh_mobile_lcdc_chan *ch) 2176{ 2177 struct fb_info *info = ch->info; 2178 2179 if (!info || !info->device) 2180 return; 2181 2182 if (ch->sglist) 2183 vfree(ch->sglist); 2184 2185 fb_dealloc_cmap(&info->cmap); 2186 framebuffer_release(info); 2187} 2188 2189static int 2190sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch, 2191 const struct fb_videomode *modes, 2192 unsigned int num_modes) 2193{ 2194 struct sh_mobile_lcdc_priv *priv = ch->lcdc; 2195 struct fb_var_screeninfo *var; 2196 struct fb_info *info; 2197 int ret; 2198 2199 /* Allocate and initialize the frame buffer device. Create the modes 2200 * list and allocate the color map. 2201 */ 2202 info = framebuffer_alloc(0, priv->dev); 2203 if (info == NULL) { 2204 dev_err(priv->dev, "unable to allocate fb_info\n"); 2205 return -ENOMEM; 2206 } 2207 2208 ch->info = info; 2209 2210 info->flags = FBINFO_FLAG_DEFAULT; 2211 info->fbops = &sh_mobile_lcdc_ops; 2212 info->device = priv->dev; 2213 info->screen_base = ch->fb_mem; 2214 info->pseudo_palette = &ch->pseudo_palette; 2215 info->par = ch; 2216 2217 fb_videomode_to_modelist(modes, num_modes, &info->modelist); 2218 2219 ret = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0); 2220 if (ret < 0) { 2221 dev_err(priv->dev, "unable to allocate cmap\n"); 2222 return ret; 2223 } 2224 2225 /* Initialize fixed screen information. Restrict pan to 2 lines steps 2226 * for NV12 and NV21. 2227 */ 2228 info->fix = sh_mobile_lcdc_fix; 2229 info->fix.smem_start = ch->dma_handle; 2230 info->fix.smem_len = ch->fb_size; 2231 info->fix.line_length = ch->pitch; 2232 2233 if (ch->format->yuv) 2234 info->fix.visual = FB_VISUAL_FOURCC; 2235 else 2236 info->fix.visual = FB_VISUAL_TRUECOLOR; 2237 2238 switch (ch->format->fourcc) { 2239 case V4L2_PIX_FMT_NV12: 2240 case V4L2_PIX_FMT_NV21: 2241 info->fix.ypanstep = 2; 2242 case V4L2_PIX_FMT_NV16: 2243 case V4L2_PIX_FMT_NV61: 2244 info->fix.xpanstep = 2; 2245 } 2246 2247 /* Initialize variable screen information using the first mode as 2248 * default. 2249 */ 2250 var = &info->var; 2251 fb_videomode_to_var(var, modes); 2252 var->width = ch->display.width; 2253 var->height = ch->display.height; 2254 var->xres_virtual = ch->xres_virtual; 2255 var->yres_virtual = ch->yres_virtual; 2256 var->activate = FB_ACTIVATE_NOW; 2257 2258 /* Use the legacy API by default for RGB formats, and the FOURCC API 2259 * for YUV formats. 2260 */ 2261 if (!ch->format->yuv) 2262 var->bits_per_pixel = ch->format->bpp; 2263 else 2264 var->grayscale = ch->format->fourcc; 2265 2266 ret = sh_mobile_lcdc_check_var(var, info); 2267 if (ret) 2268 return ret; 2269 2270 return 0; 2271} 2272 2273/* ----------------------------------------------------------------------------- 2274 * Backlight 2275 */ 2276 2277static int sh_mobile_lcdc_update_bl(struct backlight_device *bdev) 2278{ 2279 struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev); 2280 int brightness = bdev->props.brightness; 2281 2282 if (bdev->props.power != FB_BLANK_UNBLANK || 2283 bdev->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK)) 2284 brightness = 0; 2285 2286 ch->bl_brightness = brightness; 2287 return ch->cfg->bl_info.set_brightness(brightness); 2288} 2289 2290static int sh_mobile_lcdc_get_brightness(struct backlight_device *bdev) 2291{ 2292 struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev); 2293 2294 return ch->bl_brightness; 2295} 2296 2297static int sh_mobile_lcdc_check_fb(struct backlight_device *bdev, 2298 struct fb_info *info) 2299{ 2300 return (info->bl_dev == bdev); 2301} 2302 2303static struct backlight_ops sh_mobile_lcdc_bl_ops = { 2304 .options = BL_CORE_SUSPENDRESUME, 2305 .update_status = sh_mobile_lcdc_update_bl, 2306 .get_brightness = sh_mobile_lcdc_get_brightness, 2307 .check_fb = sh_mobile_lcdc_check_fb, 2308}; 2309 2310static struct backlight_device *sh_mobile_lcdc_bl_probe(struct device *parent, 2311 struct sh_mobile_lcdc_chan *ch) 2312{ 2313 struct backlight_device *bl; 2314 2315 bl = backlight_device_register(ch->cfg->bl_info.name, parent, ch, 2316 &sh_mobile_lcdc_bl_ops, NULL); 2317 if (IS_ERR(bl)) { 2318 dev_err(parent, "unable to register backlight device: %ld\n", 2319 PTR_ERR(bl)); 2320 return NULL; 2321 } 2322 2323 bl->props.max_brightness = ch->cfg->bl_info.max_brightness; 2324 bl->props.brightness = bl->props.max_brightness; 2325 backlight_update_status(bl); 2326 2327 return bl; 2328} 2329 2330static void sh_mobile_lcdc_bl_remove(struct backlight_device *bdev) 2331{ 2332 backlight_device_unregister(bdev); 2333} 2334 2335/* ----------------------------------------------------------------------------- 2336 * Power management 2337 */ 2338 2339static int sh_mobile_lcdc_suspend(struct device *dev) 2340{ 2341 struct platform_device *pdev = to_platform_device(dev); 2342 2343 sh_mobile_lcdc_stop(platform_get_drvdata(pdev)); 2344 return 0; 2345} 2346 2347static int sh_mobile_lcdc_resume(struct device *dev) 2348{ 2349 struct platform_device *pdev = to_platform_device(dev); 2350 2351 return sh_mobile_lcdc_start(platform_get_drvdata(pdev)); 2352} 2353 2354static int sh_mobile_lcdc_runtime_suspend(struct device *dev) 2355{ 2356 struct platform_device *pdev = to_platform_device(dev); 2357 struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev); 2358 2359 /* turn off LCDC hardware */ 2360 lcdc_write(priv, _LDCNT1R, 0); 2361 2362 return 0; 2363} 2364 2365static int sh_mobile_lcdc_runtime_resume(struct device *dev) 2366{ 2367 struct platform_device *pdev = to_platform_device(dev); 2368 struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev); 2369 2370 __sh_mobile_lcdc_start(priv); 2371 2372 return 0; 2373} 2374 2375static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = { 2376 .suspend = sh_mobile_lcdc_suspend, 2377 .resume = sh_mobile_lcdc_resume, 2378 .runtime_suspend = sh_mobile_lcdc_runtime_suspend, 2379 .runtime_resume = sh_mobile_lcdc_runtime_resume, 2380}; 2381 2382/* ----------------------------------------------------------------------------- 2383 * Framebuffer notifier 2384 */ 2385 2386/* locking: called with info->lock held */ 2387static int sh_mobile_lcdc_notify(struct notifier_block *nb, 2388 unsigned long action, void *data) 2389{ 2390 struct fb_event *event = data; 2391 struct fb_info *info = event->info; 2392 struct sh_mobile_lcdc_chan *ch = info->par; 2393 2394 if (&ch->lcdc->notifier != nb) 2395 return NOTIFY_DONE; 2396 2397 dev_dbg(info->dev, "%s(): action = %lu, data = %p\n", 2398 __func__, action, event->data); 2399 2400 switch(action) { 2401 case FB_EVENT_SUSPEND: 2402 sh_mobile_lcdc_display_off(ch); 2403 sh_mobile_lcdc_stop(ch->lcdc); 2404 break; 2405 case FB_EVENT_RESUME: 2406 mutex_lock(&ch->open_lock); 2407 sh_mobile_fb_reconfig(info); 2408 mutex_unlock(&ch->open_lock); 2409 2410 sh_mobile_lcdc_display_on(ch); 2411 sh_mobile_lcdc_start(ch->lcdc); 2412 } 2413 2414 return NOTIFY_OK; 2415} 2416 2417/* ----------------------------------------------------------------------------- 2418 * Probe/remove and driver init/exit 2419 */ 2420 2421static const struct fb_videomode default_720p = { 2422 .name = "HDMI 720p", 2423 .xres = 1280, 2424 .yres = 720, 2425 2426 .left_margin = 220, 2427 .right_margin = 110, 2428 .hsync_len = 40, 2429 2430 .upper_margin = 20, 2431 .lower_margin = 5, 2432 .vsync_len = 5, 2433 2434 .pixclock = 13468, 2435 .refresh = 60, 2436 .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT, 2437}; 2438 2439static int sh_mobile_lcdc_remove(struct platform_device *pdev) 2440{ 2441 struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev); 2442 unsigned int i; 2443 2444 fb_unregister_client(&priv->notifier); 2445 2446 for (i = 0; i < ARRAY_SIZE(priv->overlays); i++) 2447 sh_mobile_lcdc_overlay_fb_unregister(&priv->overlays[i]); 2448 for (i = 0; i < ARRAY_SIZE(priv->ch); i++) 2449 sh_mobile_lcdc_channel_fb_unregister(&priv->ch[i]); 2450 2451 sh_mobile_lcdc_stop(priv); 2452 2453 for (i = 0; i < ARRAY_SIZE(priv->overlays); i++) { 2454 struct sh_mobile_lcdc_overlay *ovl = &priv->overlays[i]; 2455 2456 sh_mobile_lcdc_overlay_fb_cleanup(ovl); 2457 2458 if (ovl->fb_mem) 2459 dma_free_coherent(&pdev->dev, ovl->fb_size, 2460 ovl->fb_mem, ovl->dma_handle); 2461 } 2462 2463 for (i = 0; i < ARRAY_SIZE(priv->ch); i++) { 2464 struct sh_mobile_lcdc_chan *ch = &priv->ch[i]; 2465 2466 if (ch->tx_dev) { 2467 ch->tx_dev->lcdc = NULL; 2468 module_put(ch->cfg->tx_dev->dev.driver->owner); 2469 } 2470 2471 sh_mobile_lcdc_channel_fb_cleanup(ch); 2472 2473 if (ch->fb_mem) 2474 dma_free_coherent(&pdev->dev, ch->fb_size, 2475 ch->fb_mem, ch->dma_handle); 2476 } 2477 2478 for (i = 0; i < ARRAY_SIZE(priv->ch); i++) { 2479 struct sh_mobile_lcdc_chan *ch = &priv->ch[i]; 2480 2481 if (ch->bl) 2482 sh_mobile_lcdc_bl_remove(ch->bl); 2483 mutex_destroy(&ch->open_lock); 2484 } 2485 2486 if (priv->dot_clk) { 2487 pm_runtime_disable(&pdev->dev); 2488 clk_put(priv->dot_clk); 2489 } 2490 2491 if (priv->base) 2492 iounmap(priv->base); 2493 2494 if (priv->irq) 2495 free_irq(priv->irq, priv); 2496 kfree(priv); 2497 return 0; 2498} 2499 2500static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch) 2501{ 2502 int interface_type = ch->cfg->interface_type; 2503 2504 switch (interface_type) { 2505 case RGB8: 2506 case RGB9: 2507 case RGB12A: 2508 case RGB12B: 2509 case RGB16: 2510 case RGB18: 2511 case RGB24: 2512 case SYS8A: 2513 case SYS8B: 2514 case SYS8C: 2515 case SYS8D: 2516 case SYS9: 2517 case SYS12: 2518 case SYS16A: 2519 case SYS16B: 2520 case SYS16C: 2521 case SYS18: 2522 case SYS24: 2523 break; 2524 default: 2525 return -EINVAL; 2526 } 2527 2528 /* SUBLCD only supports SYS interface */ 2529 if (lcdc_chan_is_sublcd(ch)) { 2530 if (!(interface_type & LDMT1R_IFM)) 2531 return -EINVAL; 2532 2533 interface_type &= ~LDMT1R_IFM; 2534 } 2535 2536 ch->ldmt1r_value = interface_type; 2537 return 0; 2538} 2539 2540static int 2541sh_mobile_lcdc_overlay_init(struct sh_mobile_lcdc_overlay *ovl) 2542{ 2543 const struct sh_mobile_lcdc_format_info *format; 2544 struct device *dev = ovl->channel->lcdc->dev; 2545 int ret; 2546 2547 if (ovl->cfg->fourcc == 0) 2548 return 0; 2549 2550 /* Validate the format. */ 2551 format = sh_mobile_format_info(ovl->cfg->fourcc); 2552 if (format == NULL) { 2553 dev_err(dev, "Invalid FOURCC %08x\n", ovl->cfg->fourcc); 2554 return -EINVAL; 2555 } 2556 2557 ovl->enabled = false; 2558 ovl->mode = LCDC_OVERLAY_BLEND; 2559 ovl->alpha = 255; 2560 ovl->rop3 = 0; 2561 ovl->pos_x = 0; 2562 ovl->pos_y = 0; 2563 2564 /* The default Y virtual resolution is twice the panel size to allow for 2565 * double-buffering. 2566 */ 2567 ovl->format = format; 2568 ovl->xres = ovl->cfg->max_xres; 2569 ovl->xres_virtual = ovl->xres; 2570 ovl->yres = ovl->cfg->max_yres; 2571 ovl->yres_virtual = ovl->yres * 2; 2572 2573 if (!format->yuv) 2574 ovl->pitch = ovl->xres_virtual * format->bpp / 8; 2575 else 2576 ovl->pitch = ovl->xres_virtual; 2577 2578 /* Allocate frame buffer memory. */ 2579 ovl->fb_size = ovl->cfg->max_xres * ovl->cfg->max_yres 2580 * format->bpp / 8 * 2; 2581 ovl->fb_mem = dma_alloc_coherent(dev, ovl->fb_size, &ovl->dma_handle, 2582 GFP_KERNEL); 2583 if (!ovl->fb_mem) { 2584 dev_err(dev, "unable to allocate buffer\n"); 2585 return -ENOMEM; 2586 } 2587 2588 ret = sh_mobile_lcdc_overlay_fb_init(ovl); 2589 if (ret < 0) 2590 return ret; 2591 2592 return 0; 2593} 2594 2595static int 2596sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch) 2597{ 2598 const struct sh_mobile_lcdc_format_info *format; 2599 const struct sh_mobile_lcdc_chan_cfg *cfg = ch->cfg; 2600 struct device *dev = ch->lcdc->dev; 2601 const struct fb_videomode *max_mode; 2602 const struct fb_videomode *mode; 2603 unsigned int num_modes; 2604 unsigned int max_size; 2605 unsigned int i; 2606 2607 mutex_init(&ch->open_lock); 2608 ch->notify = sh_mobile_lcdc_display_notify; 2609 2610 /* Validate the format. */ 2611 format = sh_mobile_format_info(cfg->fourcc); 2612 if (format == NULL) { 2613 dev_err(dev, "Invalid FOURCC %08x.\n", cfg->fourcc); 2614 return -EINVAL; 2615 } 2616 2617 /* Iterate through the modes to validate them and find the highest 2618 * resolution. 2619 */ 2620 max_mode = NULL; 2621 max_size = 0; 2622 2623 for (i = 0, mode = cfg->lcd_modes; i < cfg->num_modes; i++, mode++) { 2624 unsigned int size = mode->yres * mode->xres; 2625 2626 /* NV12/NV21 buffers must have even number of lines */ 2627 if ((cfg->fourcc == V4L2_PIX_FMT_NV12 || 2628 cfg->fourcc == V4L2_PIX_FMT_NV21) && (mode->yres & 0x1)) { 2629 dev_err(dev, "yres must be multiple of 2 for " 2630 "YCbCr420 mode.\n"); 2631 return -EINVAL; 2632 } 2633 2634 if (size > max_size) { 2635 max_mode = mode; 2636 max_size = size; 2637 } 2638 } 2639 2640 if (!max_size) 2641 max_size = MAX_XRES * MAX_YRES; 2642 else 2643 dev_dbg(dev, "Found largest videomode %ux%u\n", 2644 max_mode->xres, max_mode->yres); 2645 2646 if (cfg->lcd_modes == NULL) { 2647 mode = &default_720p; 2648 num_modes = 1; 2649 } else { 2650 mode = cfg->lcd_modes; 2651 num_modes = cfg->num_modes; 2652 } 2653 2654 /* Use the first mode as default. The default Y virtual resolution is 2655 * twice the panel size to allow for double-buffering. 2656 */ 2657 ch->format = format; 2658 ch->xres = mode->xres; 2659 ch->xres_virtual = mode->xres; 2660 ch->yres = mode->yres; 2661 ch->yres_virtual = mode->yres * 2; 2662 2663 if (!format->yuv) { 2664 ch->colorspace = V4L2_COLORSPACE_SRGB; 2665 ch->pitch = ch->xres_virtual * format->bpp / 8; 2666 } else { 2667 ch->colorspace = V4L2_COLORSPACE_REC709; 2668 ch->pitch = ch->xres_virtual; 2669 } 2670 2671 ch->display.width = cfg->panel_cfg.width; 2672 ch->display.height = cfg->panel_cfg.height; 2673 ch->display.mode = *mode; 2674 2675 /* Allocate frame buffer memory. */ 2676 ch->fb_size = max_size * format->bpp / 8 * 2; 2677 ch->fb_mem = dma_alloc_coherent(dev, ch->fb_size, &ch->dma_handle, 2678 GFP_KERNEL); 2679 if (ch->fb_mem == NULL) { 2680 dev_err(dev, "unable to allocate buffer\n"); 2681 return -ENOMEM; 2682 } 2683 2684 /* Initialize the transmitter device if present. */ 2685 if (cfg->tx_dev) { 2686 if (!cfg->tx_dev->dev.driver || 2687 !try_module_get(cfg->tx_dev->dev.driver->owner)) { 2688 dev_warn(dev, "unable to get transmitter device\n"); 2689 return -EINVAL; 2690 } 2691 ch->tx_dev = platform_get_drvdata(cfg->tx_dev); 2692 ch->tx_dev->lcdc = ch; 2693 ch->tx_dev->def_mode = *mode; 2694 } 2695 2696 return sh_mobile_lcdc_channel_fb_init(ch, mode, num_modes); 2697} 2698 2699static int sh_mobile_lcdc_probe(struct platform_device *pdev) 2700{ 2701 struct sh_mobile_lcdc_info *pdata = pdev->dev.platform_data; 2702 struct sh_mobile_lcdc_priv *priv; 2703 struct resource *res; 2704 int num_channels; 2705 int error; 2706 int i; 2707 2708 if (!pdata) { 2709 dev_err(&pdev->dev, "no platform data defined\n"); 2710 return -EINVAL; 2711 } 2712 2713 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2714 i = platform_get_irq(pdev, 0); 2715 if (!res || i < 0) { 2716 dev_err(&pdev->dev, "cannot get platform resources\n"); 2717 return -ENOENT; 2718 } 2719 2720 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 2721 if (!priv) { 2722 dev_err(&pdev->dev, "cannot allocate device data\n"); 2723 return -ENOMEM; 2724 } 2725 2726 priv->dev = &pdev->dev; 2727 priv->meram_dev = pdata->meram_dev; 2728 platform_set_drvdata(pdev, priv); 2729 2730 error = request_irq(i, sh_mobile_lcdc_irq, 0, 2731 dev_name(&pdev->dev), priv); 2732 if (error) { 2733 dev_err(&pdev->dev, "unable to request irq\n"); 2734 goto err1; 2735 } 2736 2737 priv->irq = i; 2738 atomic_set(&priv->hw_usecnt, -1); 2739 2740 for (i = 0, num_channels = 0; i < ARRAY_SIZE(pdata->ch); i++) { 2741 struct sh_mobile_lcdc_chan *ch = priv->ch + num_channels; 2742 2743 ch->lcdc = priv; 2744 ch->cfg = &pdata->ch[i]; 2745 2746 error = sh_mobile_lcdc_check_interface(ch); 2747 if (error) { 2748 dev_err(&pdev->dev, "unsupported interface type\n"); 2749 goto err1; 2750 } 2751 init_waitqueue_head(&ch->frame_end_wait); 2752 init_completion(&ch->vsync_completion); 2753 2754 /* probe the backlight is there is one defined */ 2755 if (ch->cfg->bl_info.max_brightness) 2756 ch->bl = sh_mobile_lcdc_bl_probe(&pdev->dev, ch); 2757 2758 switch (pdata->ch[i].chan) { 2759 case LCDC_CHAN_MAINLCD: 2760 ch->enabled = LDCNT2R_ME; 2761 ch->reg_offs = lcdc_offs_mainlcd; 2762 num_channels++; 2763 break; 2764 case LCDC_CHAN_SUBLCD: 2765 ch->enabled = LDCNT2R_SE; 2766 ch->reg_offs = lcdc_offs_sublcd; 2767 num_channels++; 2768 break; 2769 } 2770 } 2771 2772 if (!num_channels) { 2773 dev_err(&pdev->dev, "no channels defined\n"); 2774 error = -EINVAL; 2775 goto err1; 2776 } 2777 2778 /* for dual channel LCDC (MAIN + SUB) force shared format setting */ 2779 if (num_channels == 2) 2780 priv->forced_fourcc = pdata->ch[0].fourcc; 2781 2782 priv->base = ioremap_nocache(res->start, resource_size(res)); 2783 if (!priv->base) 2784 goto err1; 2785 2786 error = sh_mobile_lcdc_setup_clocks(priv, pdata->clock_source); 2787 if (error) { 2788 dev_err(&pdev->dev, "unable to setup clocks\n"); 2789 goto err1; 2790 } 2791 2792 /* Enable runtime PM. */ 2793 pm_runtime_enable(&pdev->dev); 2794 2795 for (i = 0; i < num_channels; i++) { 2796 struct sh_mobile_lcdc_chan *ch = &priv->ch[i]; 2797 2798 error = sh_mobile_lcdc_channel_init(ch); 2799 if (error) 2800 goto err1; 2801 } 2802 2803 for (i = 0; i < ARRAY_SIZE(pdata->overlays); i++) { 2804 struct sh_mobile_lcdc_overlay *ovl = &priv->overlays[i]; 2805 2806 ovl->cfg = &pdata->overlays[i]; 2807 ovl->channel = &priv->ch[0]; 2808 2809 error = sh_mobile_lcdc_overlay_init(ovl); 2810 if (error) 2811 goto err1; 2812 } 2813 2814 error = sh_mobile_lcdc_start(priv); 2815 if (error) { 2816 dev_err(&pdev->dev, "unable to start hardware\n"); 2817 goto err1; 2818 } 2819 2820 for (i = 0; i < num_channels; i++) { 2821 struct sh_mobile_lcdc_chan *ch = priv->ch + i; 2822 2823 error = sh_mobile_lcdc_channel_fb_register(ch); 2824 if (error) 2825 goto err1; 2826 } 2827 2828 for (i = 0; i < ARRAY_SIZE(pdata->overlays); i++) { 2829 struct sh_mobile_lcdc_overlay *ovl = &priv->overlays[i]; 2830 2831 error = sh_mobile_lcdc_overlay_fb_register(ovl); 2832 if (error) 2833 goto err1; 2834 } 2835 2836 /* Failure ignored */ 2837 priv->notifier.notifier_call = sh_mobile_lcdc_notify; 2838 fb_register_client(&priv->notifier); 2839 2840 return 0; 2841err1: 2842 sh_mobile_lcdc_remove(pdev); 2843 2844 return error; 2845} 2846 2847static struct platform_driver sh_mobile_lcdc_driver = { 2848 .driver = { 2849 .name = "sh_mobile_lcdc_fb", 2850 .owner = THIS_MODULE, 2851 .pm = &sh_mobile_lcdc_dev_pm_ops, 2852 }, 2853 .probe = sh_mobile_lcdc_probe, 2854 .remove = sh_mobile_lcdc_remove, 2855}; 2856 2857module_platform_driver(sh_mobile_lcdc_driver); 2858 2859MODULE_DESCRIPTION("SuperH Mobile LCDC Framebuffer driver"); 2860MODULE_AUTHOR("Magnus Damm <damm@opensource.se>"); 2861MODULE_LICENSE("GPL v2");