2 * SuperH Mobile LCDC Framebuffer
4 * Copyright (c) 2008 Magnus Damm
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
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/fbcon.h>
19 #include <linux/init.h>
20 #include <linux/interrupt.h>
21 #include <linux/ioctl.h>
22 #include <linux/kernel.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>
31 #include <video/sh_mobile_lcdc.h>
33 #include "sh_mobile_lcdcfb.h"
35 /* ----------------------------------------------------------------------------
36 * Overlay register definitions
40 #define LDBCR_UPC(n) (1 << ((n) + 16))
41 #define LDBCR_UPF(n) (1 << ((n) + 8))
42 #define LDBCR_UPD(n) (1 << ((n) + 0))
43 #define LDBnBSIFR(n) (0xb20 + (n) * 0x20 + 0x00)
44 #define LDBBSIFR_EN (1 << 31)
45 #define LDBBSIFR_VS (1 << 29)
46 #define LDBBSIFR_BRSEL (1 << 28)
47 #define LDBBSIFR_MX (1 << 27)
48 #define LDBBSIFR_MY (1 << 26)
49 #define LDBBSIFR_CV3 (3 << 24)
50 #define LDBBSIFR_CV2 (2 << 24)
51 #define LDBBSIFR_CV1 (1 << 24)
52 #define LDBBSIFR_CV0 (0 << 24)
53 #define LDBBSIFR_CV_MASK (3 << 24)
54 #define LDBBSIFR_LAY_MASK (0xff << 16)
55 #define LDBBSIFR_LAY_SHIFT 16
56 #define LDBBSIFR_ROP3_MASK (0xff << 16)
57 #define LDBBSIFR_ROP3_SHIFT 16
58 #define LDBBSIFR_AL_PL8 (3 << 14)
59 #define LDBBSIFR_AL_PL1 (2 << 14)
60 #define LDBBSIFR_AL_PK (1 << 14)
61 #define LDBBSIFR_AL_1 (0 << 14)
62 #define LDBBSIFR_AL_MASK (3 << 14)
63 #define LDBBSIFR_SWPL (1 << 10)
64 #define LDBBSIFR_SWPW (1 << 9)
65 #define LDBBSIFR_SWPB (1 << 8)
66 #define LDBBSIFR_RY (1 << 7)
67 #define LDBBSIFR_CHRR_420 (2 << 0)
68 #define LDBBSIFR_CHRR_422 (1 << 0)
69 #define LDBBSIFR_CHRR_444 (0 << 0)
70 #define LDBBSIFR_RPKF_ARGB32 (0x00 << 0)
71 #define LDBBSIFR_RPKF_RGB16 (0x03 << 0)
72 #define LDBBSIFR_RPKF_RGB24 (0x0b << 0)
73 #define LDBBSIFR_RPKF_MASK (0x1f << 0)
74 #define LDBnBSSZR(n) (0xb20 + (n) * 0x20 + 0x04)
75 #define LDBBSSZR_BVSS_MASK (0xfff << 16)
76 #define LDBBSSZR_BVSS_SHIFT 16
77 #define LDBBSSZR_BHSS_MASK (0xfff << 0)
78 #define LDBBSSZR_BHSS_SHIFT 0
79 #define LDBnBLOCR(n) (0xb20 + (n) * 0x20 + 0x08)
80 #define LDBBLOCR_CVLC_MASK (0xfff << 16)
81 #define LDBBLOCR_CVLC_SHIFT 16
82 #define LDBBLOCR_CHLC_MASK (0xfff << 0)
83 #define LDBBLOCR_CHLC_SHIFT 0
84 #define LDBnBSMWR(n) (0xb20 + (n) * 0x20 + 0x0c)
85 #define LDBBSMWR_BSMWA_MASK (0xffff << 16)
86 #define LDBBSMWR_BSMWA_SHIFT 16
87 #define LDBBSMWR_BSMW_MASK (0xffff << 0)
88 #define LDBBSMWR_BSMW_SHIFT 0
89 #define LDBnBSAYR(n) (0xb20 + (n) * 0x20 + 0x10)
90 #define LDBBSAYR_FG1A_MASK (0xff << 24)
91 #define LDBBSAYR_FG1A_SHIFT 24
92 #define LDBBSAYR_FG1R_MASK (0xff << 16)
93 #define LDBBSAYR_FG1R_SHIFT 16
94 #define LDBBSAYR_FG1G_MASK (0xff << 8)
95 #define LDBBSAYR_FG1G_SHIFT 8
96 #define LDBBSAYR_FG1B_MASK (0xff << 0)
97 #define LDBBSAYR_FG1B_SHIFT 0
98 #define LDBnBSACR(n) (0xb20 + (n) * 0x20 + 0x14)
99 #define LDBBSACR_FG2A_MASK (0xff << 24)
100 #define LDBBSACR_FG2A_SHIFT 24
101 #define LDBBSACR_FG2R_MASK (0xff << 16)
102 #define LDBBSACR_FG2R_SHIFT 16
103 #define LDBBSACR_FG2G_MASK (0xff << 8)
104 #define LDBBSACR_FG2G_SHIFT 8
105 #define LDBBSACR_FG2B_MASK (0xff << 0)
106 #define LDBBSACR_FG2B_SHIFT 0
107 #define LDBnBSAAR(n) (0xb20 + (n) * 0x20 + 0x18)
108 #define LDBBSAAR_AP_MASK (0xff << 24)
109 #define LDBBSAAR_AP_SHIFT 24
110 #define LDBBSAAR_R_MASK (0xff << 16)
111 #define LDBBSAAR_R_SHIFT 16
112 #define LDBBSAAR_GY_MASK (0xff << 8)
113 #define LDBBSAAR_GY_SHIFT 8
114 #define LDBBSAAR_B_MASK (0xff << 0)
115 #define LDBBSAAR_B_SHIFT 0
116 #define LDBnBPPCR(n) (0xb20 + (n) * 0x20 + 0x1c)
117 #define LDBBPPCR_AP_MASK (0xff << 24)
118 #define LDBBPPCR_AP_SHIFT 24
119 #define LDBBPPCR_R_MASK (0xff << 16)
120 #define LDBBPPCR_R_SHIFT 16
121 #define LDBBPPCR_GY_MASK (0xff << 8)
122 #define LDBBPPCR_GY_SHIFT 8
123 #define LDBBPPCR_B_MASK (0xff << 0)
124 #define LDBBPPCR_B_SHIFT 0
125 #define LDBnBBGCL(n) (0xb10 + (n) * 0x04)
126 #define LDBBBGCL_BGA_MASK (0xff << 24)
127 #define LDBBBGCL_BGA_SHIFT 24
128 #define LDBBBGCL_BGR_MASK (0xff << 16)
129 #define LDBBBGCL_BGR_SHIFT 16
130 #define LDBBBGCL_BGG_MASK (0xff << 8)
131 #define LDBBBGCL_BGG_SHIFT 8
132 #define LDBBBGCL_BGB_MASK (0xff << 0)
133 #define LDBBBGCL_BGB_SHIFT 0
135 #define SIDE_B_OFFSET 0x1000
136 #define MIRROR_OFFSET 0x2000
138 #define MAX_XRES 1920
139 #define MAX_YRES 1080
141 enum sh_mobile_lcdc_overlay_mode
{
147 * struct sh_mobile_lcdc_overlay - LCDC display overlay
149 * @channel: LCDC channel this overlay belongs to
150 * @cfg: Overlay configuration
151 * @info: Frame buffer device
152 * @index: Overlay index (0-3)
153 * @base: Overlay registers base address
154 * @enabled: True if the overlay is enabled
155 * @mode: Overlay blending mode (alpha blend or ROP3)
156 * @alpha: Global alpha blending value (0-255, for alpha blending mode)
157 * @rop3: Raster operation (for ROP3 mode)
158 * @fb_mem: Frame buffer virtual memory address
159 * @fb_size: Frame buffer size in bytes
160 * @dma_handle: Frame buffer DMA address
161 * @base_addr_y: Overlay base address (RGB or luma component)
162 * @base_addr_c: Overlay base address (chroma component)
163 * @pan_y_offset: Panning linear offset in bytes (luma component)
164 * @format: Current pixelf format
165 * @xres: Horizontal visible resolution
166 * @xres_virtual: Horizontal total resolution
167 * @yres: Vertical visible resolution
168 * @yres_virtual: Vertical total resolution
169 * @pitch: Overlay line pitch
170 * @pos_x: Horizontal overlay position
171 * @pos_y: Vertical overlay position
173 struct sh_mobile_lcdc_overlay
{
174 struct sh_mobile_lcdc_chan
*channel
;
176 const struct sh_mobile_lcdc_overlay_cfg
*cfg
;
177 struct fb_info
*info
;
183 enum sh_mobile_lcdc_overlay_mode mode
;
188 unsigned long fb_size
;
190 dma_addr_t dma_handle
;
191 unsigned long base_addr_y
;
192 unsigned long base_addr_c
;
193 unsigned long pan_y_offset
;
195 const struct sh_mobile_lcdc_format_info
*format
;
197 unsigned int xres_virtual
;
199 unsigned int yres_virtual
;
205 struct sh_mobile_lcdc_priv
{
211 unsigned long lddckr
;
213 struct sh_mobile_lcdc_chan ch
[2];
214 struct sh_mobile_lcdc_overlay overlays
[4];
217 int forced_fourcc
; /* 2 channel LCDC must share fourcc setting */
220 /* -----------------------------------------------------------------------------
224 static unsigned long lcdc_offs_mainlcd
[NR_CH_REGS
] = {
225 [LDDCKPAT1R
] = 0x400,
226 [LDDCKPAT2R
] = 0x404,
244 static unsigned long lcdc_offs_sublcd
[NR_CH_REGS
] = {
245 [LDDCKPAT1R
] = 0x408,
246 [LDDCKPAT2R
] = 0x40c,
262 static bool banked(int reg_nr
)
282 static int lcdc_chan_is_sublcd(struct sh_mobile_lcdc_chan
*chan
)
284 return chan
->cfg
->chan
== LCDC_CHAN_SUBLCD
;
287 static void lcdc_write_chan(struct sh_mobile_lcdc_chan
*chan
,
288 int reg_nr
, unsigned long data
)
290 iowrite32(data
, chan
->lcdc
->base
+ chan
->reg_offs
[reg_nr
]);
292 iowrite32(data
, chan
->lcdc
->base
+ chan
->reg_offs
[reg_nr
] +
296 static void lcdc_write_chan_mirror(struct sh_mobile_lcdc_chan
*chan
,
297 int reg_nr
, unsigned long data
)
299 iowrite32(data
, chan
->lcdc
->base
+ chan
->reg_offs
[reg_nr
] +
303 static unsigned long lcdc_read_chan(struct sh_mobile_lcdc_chan
*chan
,
306 return ioread32(chan
->lcdc
->base
+ chan
->reg_offs
[reg_nr
]);
309 static void lcdc_write_overlay(struct sh_mobile_lcdc_overlay
*ovl
,
310 int reg
, unsigned long data
)
312 iowrite32(data
, ovl
->channel
->lcdc
->base
+ reg
);
313 iowrite32(data
, ovl
->channel
->lcdc
->base
+ reg
+ SIDE_B_OFFSET
);
316 static void lcdc_write(struct sh_mobile_lcdc_priv
*priv
,
317 unsigned long reg_offs
, unsigned long data
)
319 iowrite32(data
, priv
->base
+ reg_offs
);
322 static unsigned long lcdc_read(struct sh_mobile_lcdc_priv
*priv
,
323 unsigned long reg_offs
)
325 return ioread32(priv
->base
+ reg_offs
);
328 static void lcdc_wait_bit(struct sh_mobile_lcdc_priv
*priv
,
329 unsigned long reg_offs
,
330 unsigned long mask
, unsigned long until
)
332 while ((lcdc_read(priv
, reg_offs
) & mask
) != until
)
336 /* -----------------------------------------------------------------------------
340 static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv
*priv
)
342 if (atomic_inc_and_test(&priv
->hw_usecnt
)) {
343 clk_prepare_enable(priv
->dot_clk
);
344 pm_runtime_get_sync(priv
->dev
);
348 static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv
*priv
)
350 if (atomic_sub_return(1, &priv
->hw_usecnt
) == -1) {
351 pm_runtime_put(priv
->dev
);
352 clk_disable_unprepare(priv
->dot_clk
);
356 static int sh_mobile_lcdc_setup_clocks(struct sh_mobile_lcdc_priv
*priv
,
362 switch (clock_source
) {
365 priv
->lddckr
= LDDCKR_ICKSEL_BUS
;
367 case LCDC_CLK_PERIPHERAL
:
368 str
= "peripheral_clk";
369 priv
->lddckr
= LDDCKR_ICKSEL_MIPI
;
371 case LCDC_CLK_EXTERNAL
:
373 priv
->lddckr
= LDDCKR_ICKSEL_HDMI
;
382 clk
= clk_get(priv
->dev
, str
);
384 dev_err(priv
->dev
, "cannot get dot clock %s\n", str
);
392 /* -----------------------------------------------------------------------------
393 * Display, panel and deferred I/O
396 static void lcdc_sys_write_index(void *handle
, unsigned long data
)
398 struct sh_mobile_lcdc_chan
*ch
= handle
;
400 lcdc_write(ch
->lcdc
, _LDDWD0R
, data
| LDDWDxR_WDACT
);
401 lcdc_wait_bit(ch
->lcdc
, _LDSR
, LDSR_AS
, 0);
402 lcdc_write(ch
->lcdc
, _LDDWAR
, LDDWAR_WA
|
403 (lcdc_chan_is_sublcd(ch
) ? 2 : 0));
404 lcdc_wait_bit(ch
->lcdc
, _LDSR
, LDSR_AS
, 0);
407 static void lcdc_sys_write_data(void *handle
, unsigned long data
)
409 struct sh_mobile_lcdc_chan
*ch
= handle
;
411 lcdc_write(ch
->lcdc
, _LDDWD0R
, data
| LDDWDxR_WDACT
| LDDWDxR_RSW
);
412 lcdc_wait_bit(ch
->lcdc
, _LDSR
, LDSR_AS
, 0);
413 lcdc_write(ch
->lcdc
, _LDDWAR
, LDDWAR_WA
|
414 (lcdc_chan_is_sublcd(ch
) ? 2 : 0));
415 lcdc_wait_bit(ch
->lcdc
, _LDSR
, LDSR_AS
, 0);
418 static unsigned long lcdc_sys_read_data(void *handle
)
420 struct sh_mobile_lcdc_chan
*ch
= handle
;
422 lcdc_write(ch
->lcdc
, _LDDRDR
, LDDRDR_RSR
);
423 lcdc_wait_bit(ch
->lcdc
, _LDSR
, LDSR_AS
, 0);
424 lcdc_write(ch
->lcdc
, _LDDRAR
, LDDRAR_RA
|
425 (lcdc_chan_is_sublcd(ch
) ? 2 : 0));
427 lcdc_wait_bit(ch
->lcdc
, _LDSR
, LDSR_AS
, 0);
429 return lcdc_read(ch
->lcdc
, _LDDRDR
) & LDDRDR_DRD_MASK
;
432 static struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops
= {
433 .write_index
= lcdc_sys_write_index
,
434 .write_data
= lcdc_sys_write_data
,
435 .read_data
= lcdc_sys_read_data
,
438 static int sh_mobile_lcdc_sginit(struct fb_info
*info
,
439 struct list_head
*pagelist
)
441 struct sh_mobile_lcdc_chan
*ch
= info
->par
;
442 unsigned int nr_pages_max
= ch
->fb_size
>> PAGE_SHIFT
;
446 sg_init_table(ch
->sglist
, nr_pages_max
);
448 list_for_each_entry(page
, pagelist
, lru
)
449 sg_set_page(&ch
->sglist
[nr_pages
++], page
, PAGE_SIZE
, 0);
454 static void sh_mobile_lcdc_deferred_io(struct fb_info
*info
,
455 struct list_head
*pagelist
)
457 struct sh_mobile_lcdc_chan
*ch
= info
->par
;
458 const struct sh_mobile_lcdc_panel_cfg
*panel
= &ch
->cfg
->panel_cfg
;
460 /* enable clocks before accessing hardware */
461 sh_mobile_lcdc_clk_on(ch
->lcdc
);
464 * It's possible to get here without anything on the pagelist via
465 * sh_mobile_lcdc_deferred_io_touch() or via a userspace fsync()
466 * invocation. In the former case, the acceleration routines are
467 * stepped in to when using the framebuffer console causing the
468 * workqueue to be scheduled without any dirty pages on the list.
470 * Despite this, a panel update is still needed given that the
471 * acceleration routines have their own methods for writing in
472 * that still need to be updated.
474 * The fsync() and empty pagelist case could be optimized for,
475 * but we don't bother, as any application exhibiting such
476 * behaviour is fundamentally broken anyways.
478 if (!list_empty(pagelist
)) {
479 unsigned int nr_pages
= sh_mobile_lcdc_sginit(info
, pagelist
);
481 /* trigger panel update */
482 dma_map_sg(ch
->lcdc
->dev
, ch
->sglist
, nr_pages
, DMA_TO_DEVICE
);
483 if (panel
->start_transfer
)
484 panel
->start_transfer(ch
, &sh_mobile_lcdc_sys_bus_ops
);
485 lcdc_write_chan(ch
, LDSM2R
, LDSM2R_OSTRG
);
486 dma_unmap_sg(ch
->lcdc
->dev
, ch
->sglist
, nr_pages
,
489 if (panel
->start_transfer
)
490 panel
->start_transfer(ch
, &sh_mobile_lcdc_sys_bus_ops
);
491 lcdc_write_chan(ch
, LDSM2R
, LDSM2R_OSTRG
);
495 static void sh_mobile_lcdc_deferred_io_touch(struct fb_info
*info
)
497 struct fb_deferred_io
*fbdefio
= info
->fbdefio
;
500 schedule_delayed_work(&info
->deferred_work
, fbdefio
->delay
);
503 static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan
*ch
)
505 const struct sh_mobile_lcdc_panel_cfg
*panel
= &ch
->cfg
->panel_cfg
;
510 ret
= ch
->tx_dev
->ops
->display_on(ch
->tx_dev
);
514 if (ret
== SH_MOBILE_LCDC_DISPLAY_DISCONNECTED
)
515 ch
->info
->state
= FBINFO_STATE_SUSPENDED
;
518 /* HDMI must be enabled before LCDC configuration */
519 if (panel
->display_on
)
523 static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan
*ch
)
525 const struct sh_mobile_lcdc_panel_cfg
*panel
= &ch
->cfg
->panel_cfg
;
527 if (panel
->display_off
)
528 panel
->display_off();
531 ch
->tx_dev
->ops
->display_off(ch
->tx_dev
);
534 static int sh_mobile_lcdc_check_var(struct fb_var_screeninfo
*var
,
535 struct fb_info
*info
);
537 /* -----------------------------------------------------------------------------
541 struct sh_mobile_lcdc_format_info
{
548 static const struct sh_mobile_lcdc_format_info sh_mobile_format_infos
[] = {
550 .fourcc
= V4L2_PIX_FMT_RGB565
,
553 .lddfr
= LDDFR_PKF_RGB16
,
555 .fourcc
= V4L2_PIX_FMT_BGR24
,
558 .lddfr
= LDDFR_PKF_RGB24
,
560 .fourcc
= V4L2_PIX_FMT_BGR32
,
563 .lddfr
= LDDFR_PKF_ARGB32
,
565 .fourcc
= V4L2_PIX_FMT_NV12
,
568 .lddfr
= LDDFR_CC
| LDDFR_YF_420
,
570 .fourcc
= V4L2_PIX_FMT_NV21
,
573 .lddfr
= LDDFR_CC
| LDDFR_YF_420
,
575 .fourcc
= V4L2_PIX_FMT_NV16
,
578 .lddfr
= LDDFR_CC
| LDDFR_YF_422
,
580 .fourcc
= V4L2_PIX_FMT_NV61
,
583 .lddfr
= LDDFR_CC
| LDDFR_YF_422
,
585 .fourcc
= V4L2_PIX_FMT_NV24
,
588 .lddfr
= LDDFR_CC
| LDDFR_YF_444
,
590 .fourcc
= V4L2_PIX_FMT_NV42
,
593 .lddfr
= LDDFR_CC
| LDDFR_YF_444
,
597 static const struct sh_mobile_lcdc_format_info
*
598 sh_mobile_format_info(u32 fourcc
)
602 for (i
= 0; i
< ARRAY_SIZE(sh_mobile_format_infos
); ++i
) {
603 if (sh_mobile_format_infos
[i
].fourcc
== fourcc
)
604 return &sh_mobile_format_infos
[i
];
610 static int sh_mobile_format_fourcc(const struct fb_var_screeninfo
*var
)
612 if (var
->grayscale
> 1)
613 return var
->grayscale
;
615 switch (var
->bits_per_pixel
) {
617 return V4L2_PIX_FMT_RGB565
;
619 return V4L2_PIX_FMT_BGR24
;
621 return V4L2_PIX_FMT_BGR32
;
627 static int sh_mobile_format_is_fourcc(const struct fb_var_screeninfo
*var
)
629 return var
->grayscale
> 1;
632 /* -----------------------------------------------------------------------------
633 * Start, stop and IRQ
636 static irqreturn_t
sh_mobile_lcdc_irq(int irq
, void *data
)
638 struct sh_mobile_lcdc_priv
*priv
= data
;
639 struct sh_mobile_lcdc_chan
*ch
;
640 unsigned long ldintr
;
644 /* Acknowledge interrupts and disable further VSYNC End IRQs. */
645 ldintr
= lcdc_read(priv
, _LDINTR
);
646 lcdc_write(priv
, _LDINTR
, (ldintr
^ LDINTR_STATUS_MASK
) & ~LDINTR_VEE
);
648 /* figure out if this interrupt is for main or sub lcd */
649 is_sub
= (lcdc_read(priv
, _LDSR
) & LDSR_MSS
) ? 1 : 0;
651 /* wake up channel and disable clocks */
652 for (k
= 0; k
< ARRAY_SIZE(priv
->ch
); k
++) {
659 if (ldintr
& LDINTR_FS
) {
660 if (is_sub
== lcdc_chan_is_sublcd(ch
)) {
662 wake_up(&ch
->frame_end_wait
);
664 sh_mobile_lcdc_clk_off(priv
);
669 if (ldintr
& LDINTR_VES
)
670 complete(&ch
->vsync_completion
);
676 static int sh_mobile_lcdc_wait_for_vsync(struct sh_mobile_lcdc_chan
*ch
)
678 unsigned long ldintr
;
681 /* Enable VSync End interrupt and be careful not to acknowledge any
684 ldintr
= lcdc_read(ch
->lcdc
, _LDINTR
);
685 ldintr
|= LDINTR_VEE
| LDINTR_STATUS_MASK
;
686 lcdc_write(ch
->lcdc
, _LDINTR
, ldintr
);
688 ret
= wait_for_completion_interruptible_timeout(&ch
->vsync_completion
,
689 msecs_to_jiffies(100));
696 static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv
*priv
,
699 unsigned long tmp
= lcdc_read(priv
, _LDCNT2R
);
702 /* start or stop the lcdc */
704 lcdc_write(priv
, _LDCNT2R
, tmp
| LDCNT2R_DO
);
706 lcdc_write(priv
, _LDCNT2R
, tmp
& ~LDCNT2R_DO
);
708 /* wait until power is applied/stopped on all channels */
709 for (k
= 0; k
< ARRAY_SIZE(priv
->ch
); k
++)
710 if (lcdc_read(priv
, _LDCNT2R
) & priv
->ch
[k
].enabled
)
712 tmp
= lcdc_read_chan(&priv
->ch
[k
], LDPMR
)
714 if (start
&& tmp
== LDPMR_LPS
)
716 if (!start
&& tmp
== 0)
722 lcdc_write(priv
, _LDDCKSTPR
, 1); /* stop dotclock */
725 static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan
*ch
)
727 const struct fb_var_screeninfo
*var
= &ch
->info
->var
;
728 const struct fb_videomode
*mode
= &ch
->display
.mode
;
729 unsigned long h_total
, hsync_pos
, display_h_total
;
732 tmp
= ch
->ldmt1r_value
;
733 tmp
|= (var
->sync
& FB_SYNC_VERT_HIGH_ACT
) ? 0 : LDMT1R_VPOL
;
734 tmp
|= (var
->sync
& FB_SYNC_HOR_HIGH_ACT
) ? 0 : LDMT1R_HPOL
;
735 tmp
|= (ch
->cfg
->flags
& LCDC_FLAGS_DWPOL
) ? LDMT1R_DWPOL
: 0;
736 tmp
|= (ch
->cfg
->flags
& LCDC_FLAGS_DIPOL
) ? LDMT1R_DIPOL
: 0;
737 tmp
|= (ch
->cfg
->flags
& LCDC_FLAGS_DAPOL
) ? LDMT1R_DAPOL
: 0;
738 tmp
|= (ch
->cfg
->flags
& LCDC_FLAGS_HSCNT
) ? LDMT1R_HSCNT
: 0;
739 tmp
|= (ch
->cfg
->flags
& LCDC_FLAGS_DWCNT
) ? LDMT1R_DWCNT
: 0;
740 lcdc_write_chan(ch
, LDMT1R
, tmp
);
743 lcdc_write_chan(ch
, LDMT2R
, ch
->cfg
->sys_bus_cfg
.ldmt2r
);
744 lcdc_write_chan(ch
, LDMT3R
, ch
->cfg
->sys_bus_cfg
.ldmt3r
);
746 /* horizontal configuration */
747 h_total
= mode
->xres
+ mode
->hsync_len
+ mode
->left_margin
748 + mode
->right_margin
;
749 tmp
= h_total
/ 8; /* HTCN */
750 tmp
|= (min(mode
->xres
, ch
->xres
) / 8) << 16; /* HDCN */
751 lcdc_write_chan(ch
, LDHCNR
, tmp
);
753 hsync_pos
= mode
->xres
+ mode
->right_margin
;
754 tmp
= hsync_pos
/ 8; /* HSYNP */
755 tmp
|= (mode
->hsync_len
/ 8) << 16; /* HSYNW */
756 lcdc_write_chan(ch
, LDHSYNR
, tmp
);
758 /* vertical configuration */
759 tmp
= mode
->yres
+ mode
->vsync_len
+ mode
->upper_margin
760 + mode
->lower_margin
; /* VTLN */
761 tmp
|= min(mode
->yres
, ch
->yres
) << 16; /* VDLN */
762 lcdc_write_chan(ch
, LDVLNR
, tmp
);
764 tmp
= mode
->yres
+ mode
->lower_margin
; /* VSYNP */
765 tmp
|= mode
->vsync_len
<< 16; /* VSYNW */
766 lcdc_write_chan(ch
, LDVSYNR
, tmp
);
768 /* Adjust horizontal synchronisation for HDMI */
769 display_h_total
= mode
->xres
+ mode
->hsync_len
+ mode
->left_margin
770 + mode
->right_margin
;
771 tmp
= ((mode
->xres
& 7) << 24) | ((display_h_total
& 7) << 16)
772 | ((mode
->hsync_len
& 7) << 8) | (hsync_pos
& 7);
773 lcdc_write_chan(ch
, LDHAJR
, tmp
);
774 lcdc_write_chan_mirror(ch
, LDHAJR
, tmp
);
777 static void sh_mobile_lcdc_overlay_setup(struct sh_mobile_lcdc_overlay
*ovl
)
782 lcdc_write(ovl
->channel
->lcdc
, LDBCR
, LDBCR_UPC(ovl
->index
));
783 lcdc_write_overlay(ovl
, LDBnBSIFR(ovl
->index
), 0);
784 lcdc_write(ovl
->channel
->lcdc
, LDBCR
,
785 LDBCR_UPF(ovl
->index
) | LDBCR_UPD(ovl
->index
));
789 ovl
->base_addr_y
= ovl
->dma_handle
;
790 ovl
->base_addr_c
= ovl
->dma_handle
791 + ovl
->xres_virtual
* ovl
->yres_virtual
;
794 case LCDC_OVERLAY_BLEND
:
795 format
= LDBBSIFR_EN
| (ovl
->alpha
<< LDBBSIFR_LAY_SHIFT
);
798 case LCDC_OVERLAY_ROP3
:
799 format
= LDBBSIFR_EN
| LDBBSIFR_BRSEL
800 | (ovl
->rop3
<< LDBBSIFR_ROP3_SHIFT
);
804 switch (ovl
->format
->fourcc
) {
805 case V4L2_PIX_FMT_RGB565
:
806 case V4L2_PIX_FMT_NV21
:
807 case V4L2_PIX_FMT_NV61
:
808 case V4L2_PIX_FMT_NV42
:
809 format
|= LDBBSIFR_SWPL
| LDBBSIFR_SWPW
;
811 case V4L2_PIX_FMT_BGR24
:
812 case V4L2_PIX_FMT_NV12
:
813 case V4L2_PIX_FMT_NV16
:
814 case V4L2_PIX_FMT_NV24
:
815 format
|= LDBBSIFR_SWPL
| LDBBSIFR_SWPW
| LDBBSIFR_SWPB
;
817 case V4L2_PIX_FMT_BGR32
:
819 format
|= LDBBSIFR_SWPL
;
823 switch (ovl
->format
->fourcc
) {
824 case V4L2_PIX_FMT_RGB565
:
825 format
|= LDBBSIFR_AL_1
| LDBBSIFR_RY
| LDBBSIFR_RPKF_RGB16
;
827 case V4L2_PIX_FMT_BGR24
:
828 format
|= LDBBSIFR_AL_1
| LDBBSIFR_RY
| LDBBSIFR_RPKF_RGB24
;
830 case V4L2_PIX_FMT_BGR32
:
831 format
|= LDBBSIFR_AL_PK
| LDBBSIFR_RY
| LDDFR_PKF_ARGB32
;
833 case V4L2_PIX_FMT_NV12
:
834 case V4L2_PIX_FMT_NV21
:
835 format
|= LDBBSIFR_AL_1
| LDBBSIFR_CHRR_420
;
837 case V4L2_PIX_FMT_NV16
:
838 case V4L2_PIX_FMT_NV61
:
839 format
|= LDBBSIFR_AL_1
| LDBBSIFR_CHRR_422
;
841 case V4L2_PIX_FMT_NV24
:
842 case V4L2_PIX_FMT_NV42
:
843 format
|= LDBBSIFR_AL_1
| LDBBSIFR_CHRR_444
;
847 lcdc_write(ovl
->channel
->lcdc
, LDBCR
, LDBCR_UPC(ovl
->index
));
849 lcdc_write_overlay(ovl
, LDBnBSIFR(ovl
->index
), format
);
851 lcdc_write_overlay(ovl
, LDBnBSSZR(ovl
->index
),
852 (ovl
->yres
<< LDBBSSZR_BVSS_SHIFT
) |
853 (ovl
->xres
<< LDBBSSZR_BHSS_SHIFT
));
854 lcdc_write_overlay(ovl
, LDBnBLOCR(ovl
->index
),
855 (ovl
->pos_y
<< LDBBLOCR_CVLC_SHIFT
) |
856 (ovl
->pos_x
<< LDBBLOCR_CHLC_SHIFT
));
857 lcdc_write_overlay(ovl
, LDBnBSMWR(ovl
->index
),
858 ovl
->pitch
<< LDBBSMWR_BSMW_SHIFT
);
860 lcdc_write_overlay(ovl
, LDBnBSAYR(ovl
->index
), ovl
->base_addr_y
);
861 lcdc_write_overlay(ovl
, LDBnBSACR(ovl
->index
), ovl
->base_addr_c
);
863 lcdc_write(ovl
->channel
->lcdc
, LDBCR
,
864 LDBCR_UPF(ovl
->index
) | LDBCR_UPD(ovl
->index
));
868 * __sh_mobile_lcdc_start - Configure and start the LCDC
871 * Configure all enabled channels and start the LCDC device. All external
872 * devices (clocks, MERAM, panels, ...) are not touched by this function.
874 static void __sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv
*priv
)
876 struct sh_mobile_lcdc_chan
*ch
;
880 /* Enable LCDC channels. Read data from external memory, avoid using the
883 lcdc_write(priv
, _LDCNT2R
, priv
->ch
[0].enabled
| priv
->ch
[1].enabled
);
885 /* Stop the LCDC first and disable all interrupts. */
886 sh_mobile_lcdc_start_stop(priv
, 0);
887 lcdc_write(priv
, _LDINTR
, 0);
889 /* Configure power supply, dot clocks and start them. */
891 for (k
= 0; k
< ARRAY_SIZE(priv
->ch
); k
++) {
897 lcdc_write_chan(ch
, LDPMR
, 0);
899 m
= ch
->cfg
->clock_divider
;
903 /* FIXME: sh7724 can only use 42, 48, 54 and 60 for the divider
906 lcdc_write_chan(ch
, LDDCKPAT1R
, 0);
907 lcdc_write_chan(ch
, LDDCKPAT2R
, (1 << (m
/2)) - 1);
911 tmp
|= m
<< (lcdc_chan_is_sublcd(ch
) ? 8 : 0);
914 lcdc_write(priv
, _LDDCKR
, tmp
);
915 lcdc_write(priv
, _LDDCKSTPR
, 0);
916 lcdc_wait_bit(priv
, _LDDCKSTPR
, ~0, 0);
918 /* Setup geometry, format, frame buffer memory and operation mode. */
919 for (k
= 0; k
< ARRAY_SIZE(priv
->ch
); k
++) {
924 sh_mobile_lcdc_geometry(ch
);
926 tmp
= ch
->format
->lddfr
;
928 if (ch
->format
->yuv
) {
929 switch (ch
->colorspace
) {
930 case V4L2_COLORSPACE_REC709
:
933 case V4L2_COLORSPACE_JPEG
:
939 lcdc_write_chan(ch
, LDDFR
, tmp
);
940 lcdc_write_chan(ch
, LDMLSR
, ch
->line_size
);
941 lcdc_write_chan(ch
, LDSA1R
, ch
->base_addr_y
);
943 lcdc_write_chan(ch
, LDSA2R
, ch
->base_addr_c
);
945 /* When using deferred I/O mode, configure the LCDC for one-shot
946 * operation and enable the frame end interrupt. Otherwise use
947 * continuous read mode.
949 if (ch
->ldmt1r_value
& LDMT1R_IFM
&&
950 ch
->cfg
->sys_bus_cfg
.deferred_io_msec
) {
951 lcdc_write_chan(ch
, LDSM1R
, LDSM1R_OS
);
952 lcdc_write(priv
, _LDINTR
, LDINTR_FE
);
954 lcdc_write_chan(ch
, LDSM1R
, 0);
958 /* Word and long word swap. */
959 switch (priv
->ch
[0].format
->fourcc
) {
960 case V4L2_PIX_FMT_RGB565
:
961 case V4L2_PIX_FMT_NV21
:
962 case V4L2_PIX_FMT_NV61
:
963 case V4L2_PIX_FMT_NV42
:
964 tmp
= LDDDSR_LS
| LDDDSR_WS
;
966 case V4L2_PIX_FMT_BGR24
:
967 case V4L2_PIX_FMT_NV12
:
968 case V4L2_PIX_FMT_NV16
:
969 case V4L2_PIX_FMT_NV24
:
970 tmp
= LDDDSR_LS
| LDDDSR_WS
| LDDDSR_BS
;
972 case V4L2_PIX_FMT_BGR32
:
977 lcdc_write(priv
, _LDDDSR
, tmp
);
979 /* Enable the display output. */
980 lcdc_write(priv
, _LDCNT1R
, LDCNT1R_DE
);
981 sh_mobile_lcdc_start_stop(priv
, 1);
985 static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv
*priv
)
987 struct sh_mobile_lcdc_chan
*ch
;
992 /* enable clocks before accessing the hardware */
993 for (k
= 0; k
< ARRAY_SIZE(priv
->ch
); k
++) {
994 if (priv
->ch
[k
].enabled
)
995 sh_mobile_lcdc_clk_on(priv
);
999 lcdc_write(priv
, _LDCNT2R
, lcdc_read(priv
, _LDCNT2R
) | LDCNT2R_BR
);
1000 lcdc_wait_bit(priv
, _LDCNT2R
, LDCNT2R_BR
, 0);
1002 for (k
= 0; k
< ARRAY_SIZE(priv
->ch
); k
++) {
1003 const struct sh_mobile_lcdc_panel_cfg
*panel
;
1009 panel
= &ch
->cfg
->panel_cfg
;
1010 if (panel
->setup_sys
) {
1011 ret
= panel
->setup_sys(ch
, &sh_mobile_lcdc_sys_bus_ops
);
1017 /* Compute frame buffer base address and pitch for each channel. */
1018 for (k
= 0; k
< ARRAY_SIZE(priv
->ch
); k
++) {
1023 ch
->base_addr_y
= ch
->dma_handle
;
1024 ch
->base_addr_c
= ch
->dma_handle
1025 + ch
->xres_virtual
* ch
->yres_virtual
;
1026 ch
->line_size
= ch
->pitch
;
1029 for (k
= 0; k
< ARRAY_SIZE(priv
->overlays
); ++k
) {
1030 struct sh_mobile_lcdc_overlay
*ovl
= &priv
->overlays
[k
];
1031 sh_mobile_lcdc_overlay_setup(ovl
);
1034 /* Start the LCDC. */
1035 __sh_mobile_lcdc_start(priv
);
1037 /* Setup deferred I/O, tell the board code to enable the panels, and
1038 * turn backlight on.
1040 for (k
= 0; k
< ARRAY_SIZE(priv
->ch
); k
++) {
1045 tmp
= ch
->cfg
->sys_bus_cfg
.deferred_io_msec
;
1046 if (ch
->ldmt1r_value
& LDMT1R_IFM
&& tmp
) {
1047 ch
->defio
.deferred_io
= sh_mobile_lcdc_deferred_io
;
1048 ch
->defio
.delay
= msecs_to_jiffies(tmp
);
1049 ch
->info
->fbdefio
= &ch
->defio
;
1050 fb_deferred_io_init(ch
->info
);
1053 sh_mobile_lcdc_display_on(ch
);
1056 ch
->bl
->props
.power
= FB_BLANK_UNBLANK
;
1057 backlight_update_status(ch
->bl
);
1064 static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv
*priv
)
1066 struct sh_mobile_lcdc_chan
*ch
;
1069 /* clean up deferred io and ask board code to disable panel */
1070 for (k
= 0; k
< ARRAY_SIZE(priv
->ch
); k
++) {
1075 /* deferred io mode:
1076 * flush frame, and wait for frame end interrupt
1077 * clean up deferred io and enable clock
1079 if (ch
->info
&& ch
->info
->fbdefio
) {
1081 schedule_delayed_work(&ch
->info
->deferred_work
, 0);
1082 wait_event(ch
->frame_end_wait
, ch
->frame_end
);
1083 fb_deferred_io_cleanup(ch
->info
);
1084 ch
->info
->fbdefio
= NULL
;
1085 sh_mobile_lcdc_clk_on(priv
);
1089 ch
->bl
->props
.power
= FB_BLANK_POWERDOWN
;
1090 backlight_update_status(ch
->bl
);
1093 sh_mobile_lcdc_display_off(ch
);
1097 if (priv
->started
) {
1098 sh_mobile_lcdc_start_stop(priv
, 0);
1103 for (k
= 0; k
< ARRAY_SIZE(priv
->ch
); k
++)
1104 if (priv
->ch
[k
].enabled
)
1105 sh_mobile_lcdc_clk_off(priv
);
1108 static int __sh_mobile_lcdc_check_var(struct fb_var_screeninfo
*var
,
1109 struct fb_info
*info
)
1111 if (var
->xres
> MAX_XRES
|| var
->yres
> MAX_YRES
)
1114 /* Make sure the virtual resolution is at least as big as the visible
1117 if (var
->xres_virtual
< var
->xres
)
1118 var
->xres_virtual
= var
->xres
;
1119 if (var
->yres_virtual
< var
->yres
)
1120 var
->yres_virtual
= var
->yres
;
1122 if (sh_mobile_format_is_fourcc(var
)) {
1123 const struct sh_mobile_lcdc_format_info
*format
;
1125 format
= sh_mobile_format_info(var
->grayscale
);
1128 var
->bits_per_pixel
= format
->bpp
;
1130 /* Default to RGB and JPEG color-spaces for RGB and YUV formats
1134 var
->colorspace
= V4L2_COLORSPACE_SRGB
;
1135 else if (var
->colorspace
!= V4L2_COLORSPACE_REC709
)
1136 var
->colorspace
= V4L2_COLORSPACE_JPEG
;
1138 if (var
->bits_per_pixel
<= 16) { /* RGB 565 */
1139 var
->bits_per_pixel
= 16;
1140 var
->red
.offset
= 11;
1141 var
->red
.length
= 5;
1142 var
->green
.offset
= 5;
1143 var
->green
.length
= 6;
1144 var
->blue
.offset
= 0;
1145 var
->blue
.length
= 5;
1146 var
->transp
.offset
= 0;
1147 var
->transp
.length
= 0;
1148 } else if (var
->bits_per_pixel
<= 24) { /* RGB 888 */
1149 var
->bits_per_pixel
= 24;
1150 var
->red
.offset
= 16;
1151 var
->red
.length
= 8;
1152 var
->green
.offset
= 8;
1153 var
->green
.length
= 8;
1154 var
->blue
.offset
= 0;
1155 var
->blue
.length
= 8;
1156 var
->transp
.offset
= 0;
1157 var
->transp
.length
= 0;
1158 } else if (var
->bits_per_pixel
<= 32) { /* RGBA 888 */
1159 var
->bits_per_pixel
= 32;
1160 var
->red
.offset
= 16;
1161 var
->red
.length
= 8;
1162 var
->green
.offset
= 8;
1163 var
->green
.length
= 8;
1164 var
->blue
.offset
= 0;
1165 var
->blue
.length
= 8;
1166 var
->transp
.offset
= 24;
1167 var
->transp
.length
= 8;
1171 var
->red
.msb_right
= 0;
1172 var
->green
.msb_right
= 0;
1173 var
->blue
.msb_right
= 0;
1174 var
->transp
.msb_right
= 0;
1177 /* Make sure we don't exceed our allocated memory. */
1178 if (var
->xres_virtual
* var
->yres_virtual
* var
->bits_per_pixel
/ 8 >
1185 /* -----------------------------------------------------------------------------
1186 * Frame buffer operations - Overlays
1190 overlay_alpha_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1192 struct fb_info
*info
= dev_get_drvdata(dev
);
1193 struct sh_mobile_lcdc_overlay
*ovl
= info
->par
;
1195 return scnprintf(buf
, PAGE_SIZE
, "%u\n", ovl
->alpha
);
1199 overlay_alpha_store(struct device
*dev
, struct device_attribute
*attr
,
1200 const char *buf
, size_t count
)
1202 struct fb_info
*info
= dev_get_drvdata(dev
);
1203 struct sh_mobile_lcdc_overlay
*ovl
= info
->par
;
1207 alpha
= simple_strtoul(buf
, &endp
, 10);
1211 if (endp
- buf
!= count
)
1217 if (ovl
->alpha
!= alpha
) {
1220 if (ovl
->mode
== LCDC_OVERLAY_BLEND
&& ovl
->enabled
)
1221 sh_mobile_lcdc_overlay_setup(ovl
);
1228 overlay_mode_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1230 struct fb_info
*info
= dev_get_drvdata(dev
);
1231 struct sh_mobile_lcdc_overlay
*ovl
= info
->par
;
1233 return scnprintf(buf
, PAGE_SIZE
, "%u\n", ovl
->mode
);
1237 overlay_mode_store(struct device
*dev
, struct device_attribute
*attr
,
1238 const char *buf
, size_t count
)
1240 struct fb_info
*info
= dev_get_drvdata(dev
);
1241 struct sh_mobile_lcdc_overlay
*ovl
= info
->par
;
1245 mode
= simple_strtoul(buf
, &endp
, 10);
1249 if (endp
- buf
!= count
)
1252 if (mode
!= LCDC_OVERLAY_BLEND
&& mode
!= LCDC_OVERLAY_ROP3
)
1255 if (ovl
->mode
!= mode
) {
1259 sh_mobile_lcdc_overlay_setup(ovl
);
1266 overlay_position_show(struct device
*dev
, struct device_attribute
*attr
,
1269 struct fb_info
*info
= dev_get_drvdata(dev
);
1270 struct sh_mobile_lcdc_overlay
*ovl
= info
->par
;
1272 return scnprintf(buf
, PAGE_SIZE
, "%d,%d\n", ovl
->pos_x
, ovl
->pos_y
);
1276 overlay_position_store(struct device
*dev
, struct device_attribute
*attr
,
1277 const char *buf
, size_t count
)
1279 struct fb_info
*info
= dev_get_drvdata(dev
);
1280 struct sh_mobile_lcdc_overlay
*ovl
= info
->par
;
1285 pos_x
= simple_strtol(buf
, &endp
, 10);
1289 pos_y
= simple_strtol(endp
+ 1, &endp
, 10);
1293 if (endp
- buf
!= count
)
1296 if (ovl
->pos_x
!= pos_x
|| ovl
->pos_y
!= pos_y
) {
1301 sh_mobile_lcdc_overlay_setup(ovl
);
1308 overlay_rop3_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1310 struct fb_info
*info
= dev_get_drvdata(dev
);
1311 struct sh_mobile_lcdc_overlay
*ovl
= info
->par
;
1313 return scnprintf(buf
, PAGE_SIZE
, "%u\n", ovl
->rop3
);
1317 overlay_rop3_store(struct device
*dev
, struct device_attribute
*attr
,
1318 const char *buf
, size_t count
)
1320 struct fb_info
*info
= dev_get_drvdata(dev
);
1321 struct sh_mobile_lcdc_overlay
*ovl
= info
->par
;
1325 rop3
= simple_strtoul(buf
, &endp
, 10);
1329 if (endp
- buf
!= count
)
1335 if (ovl
->rop3
!= rop3
) {
1338 if (ovl
->mode
== LCDC_OVERLAY_ROP3
&& ovl
->enabled
)
1339 sh_mobile_lcdc_overlay_setup(ovl
);
1345 static const struct device_attribute overlay_sysfs_attrs
[] = {
1346 __ATTR(ovl_alpha
, S_IRUGO
|S_IWUSR
,
1347 overlay_alpha_show
, overlay_alpha_store
),
1348 __ATTR(ovl_mode
, S_IRUGO
|S_IWUSR
,
1349 overlay_mode_show
, overlay_mode_store
),
1350 __ATTR(ovl_position
, S_IRUGO
|S_IWUSR
,
1351 overlay_position_show
, overlay_position_store
),
1352 __ATTR(ovl_rop3
, S_IRUGO
|S_IWUSR
,
1353 overlay_rop3_show
, overlay_rop3_store
),
1356 static const struct fb_fix_screeninfo sh_mobile_lcdc_overlay_fix
= {
1357 .id
= "SH Mobile LCDC",
1358 .type
= FB_TYPE_PACKED_PIXELS
,
1359 .visual
= FB_VISUAL_TRUECOLOR
,
1360 .accel
= FB_ACCEL_NONE
,
1364 .capabilities
= FB_CAP_FOURCC
,
1367 static int sh_mobile_lcdc_overlay_pan(struct fb_var_screeninfo
*var
,
1368 struct fb_info
*info
)
1370 struct sh_mobile_lcdc_overlay
*ovl
= info
->par
;
1371 unsigned long base_addr_y
;
1372 unsigned long base_addr_c
;
1373 unsigned long y_offset
;
1374 unsigned long c_offset
;
1376 if (!ovl
->format
->yuv
) {
1377 y_offset
= (var
->yoffset
* ovl
->xres_virtual
+ var
->xoffset
)
1378 * ovl
->format
->bpp
/ 8;
1381 unsigned int xsub
= ovl
->format
->bpp
< 24 ? 2 : 1;
1382 unsigned int ysub
= ovl
->format
->bpp
< 16 ? 2 : 1;
1384 y_offset
= var
->yoffset
* ovl
->xres_virtual
+ var
->xoffset
;
1385 c_offset
= var
->yoffset
/ ysub
* ovl
->xres_virtual
* 2 / xsub
1386 + var
->xoffset
* 2 / xsub
;
1389 /* If the Y offset hasn't changed, the C offset hasn't either. There's
1390 * nothing to do in that case.
1392 if (y_offset
== ovl
->pan_y_offset
)
1395 /* Set the source address for the next refresh */
1396 base_addr_y
= ovl
->dma_handle
+ y_offset
;
1397 base_addr_c
= ovl
->dma_handle
+ ovl
->xres_virtual
* ovl
->yres_virtual
1400 ovl
->base_addr_y
= base_addr_y
;
1401 ovl
->base_addr_c
= base_addr_c
;
1402 ovl
->pan_y_offset
= y_offset
;
1404 lcdc_write(ovl
->channel
->lcdc
, LDBCR
, LDBCR_UPC(ovl
->index
));
1406 lcdc_write_overlay(ovl
, LDBnBSAYR(ovl
->index
), ovl
->base_addr_y
);
1407 lcdc_write_overlay(ovl
, LDBnBSACR(ovl
->index
), ovl
->base_addr_c
);
1409 lcdc_write(ovl
->channel
->lcdc
, LDBCR
,
1410 LDBCR_UPF(ovl
->index
) | LDBCR_UPD(ovl
->index
));
1415 static int sh_mobile_lcdc_overlay_ioctl(struct fb_info
*info
, unsigned int cmd
,
1418 struct sh_mobile_lcdc_overlay
*ovl
= info
->par
;
1421 case FBIO_WAITFORVSYNC
:
1422 return sh_mobile_lcdc_wait_for_vsync(ovl
->channel
);
1425 return -ENOIOCTLCMD
;
1429 static int sh_mobile_lcdc_overlay_check_var(struct fb_var_screeninfo
*var
,
1430 struct fb_info
*info
)
1432 return __sh_mobile_lcdc_check_var(var
, info
);
1435 static int sh_mobile_lcdc_overlay_set_par(struct fb_info
*info
)
1437 struct sh_mobile_lcdc_overlay
*ovl
= info
->par
;
1440 sh_mobile_format_info(sh_mobile_format_fourcc(&info
->var
));
1442 ovl
->xres
= info
->var
.xres
;
1443 ovl
->xres_virtual
= info
->var
.xres_virtual
;
1444 ovl
->yres
= info
->var
.yres
;
1445 ovl
->yres_virtual
= info
->var
.yres_virtual
;
1447 if (ovl
->format
->yuv
)
1448 ovl
->pitch
= info
->var
.xres_virtual
;
1450 ovl
->pitch
= info
->var
.xres_virtual
* ovl
->format
->bpp
/ 8;
1452 sh_mobile_lcdc_overlay_setup(ovl
);
1454 info
->fix
.line_length
= ovl
->pitch
;
1456 if (sh_mobile_format_is_fourcc(&info
->var
)) {
1457 info
->fix
.type
= FB_TYPE_FOURCC
;
1458 info
->fix
.visual
= FB_VISUAL_FOURCC
;
1460 info
->fix
.type
= FB_TYPE_PACKED_PIXELS
;
1461 info
->fix
.visual
= FB_VISUAL_TRUECOLOR
;
1467 /* Overlay blanking. Disable the overlay when blanked. */
1468 static int sh_mobile_lcdc_overlay_blank(int blank
, struct fb_info
*info
)
1470 struct sh_mobile_lcdc_overlay
*ovl
= info
->par
;
1472 ovl
->enabled
= !blank
;
1473 sh_mobile_lcdc_overlay_setup(ovl
);
1475 /* Prevent the backlight from receiving a blanking event by returning
1482 sh_mobile_lcdc_overlay_mmap(struct fb_info
*info
, struct vm_area_struct
*vma
)
1484 struct sh_mobile_lcdc_overlay
*ovl
= info
->par
;
1486 return dma_mmap_coherent(ovl
->channel
->lcdc
->dev
, vma
, ovl
->fb_mem
,
1487 ovl
->dma_handle
, ovl
->fb_size
);
1490 static const struct fb_ops sh_mobile_lcdc_overlay_ops
= {
1491 .owner
= THIS_MODULE
,
1492 .fb_read
= fb_sys_read
,
1493 .fb_write
= fb_sys_write
,
1494 .fb_fillrect
= sys_fillrect
,
1495 .fb_copyarea
= sys_copyarea
,
1496 .fb_imageblit
= sys_imageblit
,
1497 .fb_blank
= sh_mobile_lcdc_overlay_blank
,
1498 .fb_pan_display
= sh_mobile_lcdc_overlay_pan
,
1499 .fb_ioctl
= sh_mobile_lcdc_overlay_ioctl
,
1500 .fb_check_var
= sh_mobile_lcdc_overlay_check_var
,
1501 .fb_set_par
= sh_mobile_lcdc_overlay_set_par
,
1502 .fb_mmap
= sh_mobile_lcdc_overlay_mmap
,
1506 sh_mobile_lcdc_overlay_fb_unregister(struct sh_mobile_lcdc_overlay
*ovl
)
1508 struct fb_info
*info
= ovl
->info
;
1510 if (info
== NULL
|| info
->dev
== NULL
)
1513 unregister_framebuffer(ovl
->info
);
1517 sh_mobile_lcdc_overlay_fb_register(struct sh_mobile_lcdc_overlay
*ovl
)
1519 struct sh_mobile_lcdc_priv
*lcdc
= ovl
->channel
->lcdc
;
1520 struct fb_info
*info
= ovl
->info
;
1527 ret
= register_framebuffer(info
);
1531 dev_info(lcdc
->dev
, "registered %s/overlay %u as %dx%d %dbpp.\n",
1532 dev_name(lcdc
->dev
), ovl
->index
, info
->var
.xres
,
1533 info
->var
.yres
, info
->var
.bits_per_pixel
);
1535 for (i
= 0; i
< ARRAY_SIZE(overlay_sysfs_attrs
); ++i
) {
1536 ret
= device_create_file(info
->dev
, &overlay_sysfs_attrs
[i
]);
1545 sh_mobile_lcdc_overlay_fb_cleanup(struct sh_mobile_lcdc_overlay
*ovl
)
1547 struct fb_info
*info
= ovl
->info
;
1549 if (info
== NULL
|| info
->device
== NULL
)
1552 framebuffer_release(info
);
1556 sh_mobile_lcdc_overlay_fb_init(struct sh_mobile_lcdc_overlay
*ovl
)
1558 struct sh_mobile_lcdc_priv
*priv
= ovl
->channel
->lcdc
;
1559 struct fb_var_screeninfo
*var
;
1560 struct fb_info
*info
;
1562 /* Allocate and initialize the frame buffer device. */
1563 info
= framebuffer_alloc(0, priv
->dev
);
1569 info
->flags
= FBINFO_FLAG_DEFAULT
;
1570 info
->fbops
= &sh_mobile_lcdc_overlay_ops
;
1571 info
->device
= priv
->dev
;
1572 info
->screen_buffer
= ovl
->fb_mem
;
1575 /* Initialize fixed screen information. Restrict pan to 2 lines steps
1576 * for NV12 and NV21.
1578 info
->fix
= sh_mobile_lcdc_overlay_fix
;
1579 snprintf(info
->fix
.id
, sizeof(info
->fix
.id
),
1580 "SH Mobile LCDC Overlay %u", ovl
->index
);
1581 info
->fix
.smem_start
= ovl
->dma_handle
;
1582 info
->fix
.smem_len
= ovl
->fb_size
;
1583 info
->fix
.line_length
= ovl
->pitch
;
1585 if (ovl
->format
->yuv
)
1586 info
->fix
.visual
= FB_VISUAL_FOURCC
;
1588 info
->fix
.visual
= FB_VISUAL_TRUECOLOR
;
1590 switch (ovl
->format
->fourcc
) {
1591 case V4L2_PIX_FMT_NV12
:
1592 case V4L2_PIX_FMT_NV21
:
1593 info
->fix
.ypanstep
= 2;
1595 case V4L2_PIX_FMT_NV16
:
1596 case V4L2_PIX_FMT_NV61
:
1597 info
->fix
.xpanstep
= 2;
1600 /* Initialize variable screen information. */
1602 memset(var
, 0, sizeof(*var
));
1603 var
->xres
= ovl
->xres
;
1604 var
->yres
= ovl
->yres
;
1605 var
->xres_virtual
= ovl
->xres_virtual
;
1606 var
->yres_virtual
= ovl
->yres_virtual
;
1607 var
->activate
= FB_ACTIVATE_NOW
;
1609 /* Use the legacy API by default for RGB formats, and the FOURCC API
1612 if (!ovl
->format
->yuv
)
1613 var
->bits_per_pixel
= ovl
->format
->bpp
;
1615 var
->grayscale
= ovl
->format
->fourcc
;
1617 return sh_mobile_lcdc_overlay_check_var(var
, info
);
1620 /* -----------------------------------------------------------------------------
1621 * Frame buffer operations - main frame buffer
1624 static int sh_mobile_lcdc_setcolreg(u_int regno
,
1625 u_int red
, u_int green
, u_int blue
,
1626 u_int transp
, struct fb_info
*info
)
1628 u32
*palette
= info
->pseudo_palette
;
1630 if (regno
>= PALETTE_NR
)
1633 /* only FB_VISUAL_TRUECOLOR supported */
1635 red
>>= 16 - info
->var
.red
.length
;
1636 green
>>= 16 - info
->var
.green
.length
;
1637 blue
>>= 16 - info
->var
.blue
.length
;
1638 transp
>>= 16 - info
->var
.transp
.length
;
1640 palette
[regno
] = (red
<< info
->var
.red
.offset
) |
1641 (green
<< info
->var
.green
.offset
) |
1642 (blue
<< info
->var
.blue
.offset
) |
1643 (transp
<< info
->var
.transp
.offset
);
1648 static const struct fb_fix_screeninfo sh_mobile_lcdc_fix
= {
1649 .id
= "SH Mobile LCDC",
1650 .type
= FB_TYPE_PACKED_PIXELS
,
1651 .visual
= FB_VISUAL_TRUECOLOR
,
1652 .accel
= FB_ACCEL_NONE
,
1656 .capabilities
= FB_CAP_FOURCC
,
1659 static void sh_mobile_lcdc_fillrect(struct fb_info
*info
,
1660 const struct fb_fillrect
*rect
)
1662 sys_fillrect(info
, rect
);
1663 sh_mobile_lcdc_deferred_io_touch(info
);
1666 static void sh_mobile_lcdc_copyarea(struct fb_info
*info
,
1667 const struct fb_copyarea
*area
)
1669 sys_copyarea(info
, area
);
1670 sh_mobile_lcdc_deferred_io_touch(info
);
1673 static void sh_mobile_lcdc_imageblit(struct fb_info
*info
,
1674 const struct fb_image
*image
)
1676 sys_imageblit(info
, image
);
1677 sh_mobile_lcdc_deferred_io_touch(info
);
1680 static int sh_mobile_lcdc_pan(struct fb_var_screeninfo
*var
,
1681 struct fb_info
*info
)
1683 struct sh_mobile_lcdc_chan
*ch
= info
->par
;
1684 struct sh_mobile_lcdc_priv
*priv
= ch
->lcdc
;
1685 unsigned long ldrcntr
;
1686 unsigned long base_addr_y
, base_addr_c
;
1687 unsigned long y_offset
;
1688 unsigned long c_offset
;
1690 if (!ch
->format
->yuv
) {
1691 y_offset
= (var
->yoffset
* ch
->xres_virtual
+ var
->xoffset
)
1692 * ch
->format
->bpp
/ 8;
1695 unsigned int xsub
= ch
->format
->bpp
< 24 ? 2 : 1;
1696 unsigned int ysub
= ch
->format
->bpp
< 16 ? 2 : 1;
1698 y_offset
= var
->yoffset
* ch
->xres_virtual
+ var
->xoffset
;
1699 c_offset
= var
->yoffset
/ ysub
* ch
->xres_virtual
* 2 / xsub
1700 + var
->xoffset
* 2 / xsub
;
1703 /* If the Y offset hasn't changed, the C offset hasn't either. There's
1704 * nothing to do in that case.
1706 if (y_offset
== ch
->pan_y_offset
)
1709 /* Set the source address for the next refresh */
1710 base_addr_y
= ch
->dma_handle
+ y_offset
;
1711 base_addr_c
= ch
->dma_handle
+ ch
->xres_virtual
* ch
->yres_virtual
1714 ch
->base_addr_y
= base_addr_y
;
1715 ch
->base_addr_c
= base_addr_c
;
1716 ch
->pan_y_offset
= y_offset
;
1718 lcdc_write_chan_mirror(ch
, LDSA1R
, base_addr_y
);
1719 if (ch
->format
->yuv
)
1720 lcdc_write_chan_mirror(ch
, LDSA2R
, base_addr_c
);
1722 ldrcntr
= lcdc_read(priv
, _LDRCNTR
);
1723 if (lcdc_chan_is_sublcd(ch
))
1724 lcdc_write(ch
->lcdc
, _LDRCNTR
, ldrcntr
^ LDRCNTR_SRS
);
1726 lcdc_write(ch
->lcdc
, _LDRCNTR
, ldrcntr
^ LDRCNTR_MRS
);
1729 sh_mobile_lcdc_deferred_io_touch(info
);
1734 static int sh_mobile_lcdc_ioctl(struct fb_info
*info
, unsigned int cmd
,
1737 struct sh_mobile_lcdc_chan
*ch
= info
->par
;
1741 case FBIO_WAITFORVSYNC
:
1742 retval
= sh_mobile_lcdc_wait_for_vsync(ch
);
1746 retval
= -ENOIOCTLCMD
;
1752 static void sh_mobile_fb_reconfig(struct fb_info
*info
)
1754 struct sh_mobile_lcdc_chan
*ch
= info
->par
;
1755 struct fb_var_screeninfo var
;
1756 struct fb_videomode mode
;
1758 if (ch
->use_count
> 1 || (ch
->use_count
== 1 && !info
->fbcon_par
))
1759 /* More framebuffer users are active */
1762 fb_var_to_videomode(&mode
, &info
->var
);
1764 if (fb_mode_is_equal(&ch
->display
.mode
, &mode
))
1767 /* Display has been re-plugged, framebuffer is free now, reconfigure */
1769 fb_videomode_to_var(&var
, &ch
->display
.mode
);
1770 var
.width
= ch
->display
.width
;
1771 var
.height
= ch
->display
.height
;
1772 var
.activate
= FB_ACTIVATE_NOW
;
1774 if (fb_set_var(info
, &var
) < 0)
1775 /* Couldn't reconfigure, hopefully, can continue as before */
1778 fbcon_update_vcs(info
, true);
1782 * Locking: both .fb_release() and .fb_open() are called with info->lock held if
1783 * user == 1, or with console sem held, if user == 0.
1785 static int sh_mobile_lcdc_release(struct fb_info
*info
, int user
)
1787 struct sh_mobile_lcdc_chan
*ch
= info
->par
;
1789 mutex_lock(&ch
->open_lock
);
1790 dev_dbg(info
->dev
, "%s(): %d users\n", __func__
, ch
->use_count
);
1794 /* Nothing to reconfigure, when called from fbcon */
1797 sh_mobile_fb_reconfig(info
);
1801 mutex_unlock(&ch
->open_lock
);
1806 static int sh_mobile_lcdc_open(struct fb_info
*info
, int user
)
1808 struct sh_mobile_lcdc_chan
*ch
= info
->par
;
1810 mutex_lock(&ch
->open_lock
);
1813 dev_dbg(info
->dev
, "%s(): %d users\n", __func__
, ch
->use_count
);
1814 mutex_unlock(&ch
->open_lock
);
1819 static int sh_mobile_lcdc_check_var(struct fb_var_screeninfo
*var
,
1820 struct fb_info
*info
)
1822 struct sh_mobile_lcdc_chan
*ch
= info
->par
;
1823 struct sh_mobile_lcdc_priv
*p
= ch
->lcdc
;
1824 unsigned int best_dist
= (unsigned int)-1;
1825 unsigned int best_xres
= 0;
1826 unsigned int best_yres
= 0;
1830 /* If board code provides us with a list of available modes, make sure
1831 * we use one of them. Find the mode closest to the requested one. The
1832 * distance between two modes is defined as the size of the
1833 * non-overlapping parts of the two rectangles.
1835 for (i
= 0; i
< ch
->cfg
->num_modes
; ++i
) {
1836 const struct fb_videomode
*mode
= &ch
->cfg
->lcd_modes
[i
];
1839 /* We can only round up. */
1840 if (var
->xres
> mode
->xres
|| var
->yres
> mode
->yres
)
1843 dist
= var
->xres
* var
->yres
+ mode
->xres
* mode
->yres
1844 - 2 * min(var
->xres
, mode
->xres
)
1845 * min(var
->yres
, mode
->yres
);
1847 if (dist
< best_dist
) {
1848 best_xres
= mode
->xres
;
1849 best_yres
= mode
->yres
;
1854 /* If no available mode can be used, return an error. */
1855 if (ch
->cfg
->num_modes
!= 0) {
1856 if (best_dist
== (unsigned int)-1)
1859 var
->xres
= best_xres
;
1860 var
->yres
= best_yres
;
1863 ret
= __sh_mobile_lcdc_check_var(var
, info
);
1867 /* only accept the forced_fourcc for dual channel configurations */
1868 if (p
->forced_fourcc
&&
1869 p
->forced_fourcc
!= sh_mobile_format_fourcc(var
))
1875 static int sh_mobile_lcdc_set_par(struct fb_info
*info
)
1877 struct sh_mobile_lcdc_chan
*ch
= info
->par
;
1880 sh_mobile_lcdc_stop(ch
->lcdc
);
1882 ch
->format
= sh_mobile_format_info(sh_mobile_format_fourcc(&info
->var
));
1883 ch
->colorspace
= info
->var
.colorspace
;
1885 ch
->xres
= info
->var
.xres
;
1886 ch
->xres_virtual
= info
->var
.xres_virtual
;
1887 ch
->yres
= info
->var
.yres
;
1888 ch
->yres_virtual
= info
->var
.yres_virtual
;
1890 if (ch
->format
->yuv
)
1891 ch
->pitch
= info
->var
.xres_virtual
;
1893 ch
->pitch
= info
->var
.xres_virtual
* ch
->format
->bpp
/ 8;
1895 ret
= sh_mobile_lcdc_start(ch
->lcdc
);
1897 dev_err(info
->dev
, "%s: unable to restart LCDC\n", __func__
);
1899 info
->fix
.line_length
= ch
->pitch
;
1901 if (sh_mobile_format_is_fourcc(&info
->var
)) {
1902 info
->fix
.type
= FB_TYPE_FOURCC
;
1903 info
->fix
.visual
= FB_VISUAL_FOURCC
;
1905 info
->fix
.type
= FB_TYPE_PACKED_PIXELS
;
1906 info
->fix
.visual
= FB_VISUAL_TRUECOLOR
;
1913 * Screen blanking. Behavior is as follows:
1914 * FB_BLANK_UNBLANK: screen unblanked, clocks enabled
1915 * FB_BLANK_NORMAL: screen blanked, clocks enabled
1918 * FB_BLANK_POWEROFF: screen blanked, clocks disabled
1920 static int sh_mobile_lcdc_blank(int blank
, struct fb_info
*info
)
1922 struct sh_mobile_lcdc_chan
*ch
= info
->par
;
1923 struct sh_mobile_lcdc_priv
*p
= ch
->lcdc
;
1925 /* blank the screen? */
1926 if (blank
> FB_BLANK_UNBLANK
&& ch
->blank_status
== FB_BLANK_UNBLANK
) {
1927 struct fb_fillrect rect
= {
1931 sh_mobile_lcdc_fillrect(info
, &rect
);
1933 /* turn clocks on? */
1934 if (blank
<= FB_BLANK_NORMAL
&& ch
->blank_status
> FB_BLANK_NORMAL
) {
1935 sh_mobile_lcdc_clk_on(p
);
1937 /* turn clocks off? */
1938 if (blank
> FB_BLANK_NORMAL
&& ch
->blank_status
<= FB_BLANK_NORMAL
) {
1939 /* make sure the screen is updated with the black fill before
1940 * switching the clocks off. one vsync is not enough since
1941 * blanking may occur in the middle of a refresh. deferred io
1942 * mode will reenable the clocks and update the screen in time,
1943 * so it does not need this. */
1944 if (!info
->fbdefio
) {
1945 sh_mobile_lcdc_wait_for_vsync(ch
);
1946 sh_mobile_lcdc_wait_for_vsync(ch
);
1948 sh_mobile_lcdc_clk_off(p
);
1951 ch
->blank_status
= blank
;
1956 sh_mobile_lcdc_mmap(struct fb_info
*info
, struct vm_area_struct
*vma
)
1958 struct sh_mobile_lcdc_chan
*ch
= info
->par
;
1960 return dma_mmap_coherent(ch
->lcdc
->dev
, vma
, ch
->fb_mem
,
1961 ch
->dma_handle
, ch
->fb_size
);
1964 static const struct fb_ops sh_mobile_lcdc_ops
= {
1965 .owner
= THIS_MODULE
,
1966 .fb_setcolreg
= sh_mobile_lcdc_setcolreg
,
1967 .fb_read
= fb_sys_read
,
1968 .fb_write
= fb_sys_write
,
1969 .fb_fillrect
= sh_mobile_lcdc_fillrect
,
1970 .fb_copyarea
= sh_mobile_lcdc_copyarea
,
1971 .fb_imageblit
= sh_mobile_lcdc_imageblit
,
1972 .fb_blank
= sh_mobile_lcdc_blank
,
1973 .fb_pan_display
= sh_mobile_lcdc_pan
,
1974 .fb_ioctl
= sh_mobile_lcdc_ioctl
,
1975 .fb_open
= sh_mobile_lcdc_open
,
1976 .fb_release
= sh_mobile_lcdc_release
,
1977 .fb_check_var
= sh_mobile_lcdc_check_var
,
1978 .fb_set_par
= sh_mobile_lcdc_set_par
,
1979 .fb_mmap
= sh_mobile_lcdc_mmap
,
1983 sh_mobile_lcdc_channel_fb_unregister(struct sh_mobile_lcdc_chan
*ch
)
1985 if (ch
->info
&& ch
->info
->dev
)
1986 unregister_framebuffer(ch
->info
);
1990 sh_mobile_lcdc_channel_fb_register(struct sh_mobile_lcdc_chan
*ch
)
1992 struct fb_info
*info
= ch
->info
;
1995 if (info
->fbdefio
) {
1996 ch
->sglist
= vmalloc(sizeof(struct scatterlist
) *
1997 ch
->fb_size
>> PAGE_SHIFT
);
2002 info
->bl_dev
= ch
->bl
;
2004 ret
= register_framebuffer(info
);
2008 dev_info(ch
->lcdc
->dev
, "registered %s/%s as %dx%d %dbpp.\n",
2009 dev_name(ch
->lcdc
->dev
), (ch
->cfg
->chan
== LCDC_CHAN_MAINLCD
) ?
2010 "mainlcd" : "sublcd", info
->var
.xres
, info
->var
.yres
,
2011 info
->var
.bits_per_pixel
);
2013 /* deferred io mode: disable clock to save power */
2014 if (info
->fbdefio
|| info
->state
== FBINFO_STATE_SUSPENDED
)
2015 sh_mobile_lcdc_clk_off(ch
->lcdc
);
2021 sh_mobile_lcdc_channel_fb_cleanup(struct sh_mobile_lcdc_chan
*ch
)
2023 struct fb_info
*info
= ch
->info
;
2025 if (!info
|| !info
->device
)
2030 fb_dealloc_cmap(&info
->cmap
);
2031 framebuffer_release(info
);
2035 sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan
*ch
,
2036 const struct fb_videomode
*modes
,
2037 unsigned int num_modes
)
2039 struct sh_mobile_lcdc_priv
*priv
= ch
->lcdc
;
2040 struct fb_var_screeninfo
*var
;
2041 struct fb_info
*info
;
2044 /* Allocate and initialize the frame buffer device. Create the modes
2045 * list and allocate the color map.
2047 info
= framebuffer_alloc(0, priv
->dev
);
2053 info
->flags
= FBINFO_FLAG_DEFAULT
;
2054 info
->fbops
= &sh_mobile_lcdc_ops
;
2055 info
->device
= priv
->dev
;
2056 info
->screen_buffer
= ch
->fb_mem
;
2057 info
->pseudo_palette
= &ch
->pseudo_palette
;
2060 fb_videomode_to_modelist(modes
, num_modes
, &info
->modelist
);
2062 ret
= fb_alloc_cmap(&info
->cmap
, PALETTE_NR
, 0);
2064 dev_err(priv
->dev
, "unable to allocate cmap\n");
2068 /* Initialize fixed screen information. Restrict pan to 2 lines steps
2069 * for NV12 and NV21.
2071 info
->fix
= sh_mobile_lcdc_fix
;
2072 info
->fix
.smem_start
= ch
->dma_handle
;
2073 info
->fix
.smem_len
= ch
->fb_size
;
2074 info
->fix
.line_length
= ch
->pitch
;
2076 if (ch
->format
->yuv
)
2077 info
->fix
.visual
= FB_VISUAL_FOURCC
;
2079 info
->fix
.visual
= FB_VISUAL_TRUECOLOR
;
2081 switch (ch
->format
->fourcc
) {
2082 case V4L2_PIX_FMT_NV12
:
2083 case V4L2_PIX_FMT_NV21
:
2084 info
->fix
.ypanstep
= 2;
2086 case V4L2_PIX_FMT_NV16
:
2087 case V4L2_PIX_FMT_NV61
:
2088 info
->fix
.xpanstep
= 2;
2091 /* Initialize variable screen information using the first mode as
2095 fb_videomode_to_var(var
, modes
);
2096 var
->width
= ch
->display
.width
;
2097 var
->height
= ch
->display
.height
;
2098 var
->xres_virtual
= ch
->xres_virtual
;
2099 var
->yres_virtual
= ch
->yres_virtual
;
2100 var
->activate
= FB_ACTIVATE_NOW
;
2102 /* Use the legacy API by default for RGB formats, and the FOURCC API
2105 if (!ch
->format
->yuv
)
2106 var
->bits_per_pixel
= ch
->format
->bpp
;
2108 var
->grayscale
= ch
->format
->fourcc
;
2110 ret
= sh_mobile_lcdc_check_var(var
, info
);
2117 /* -----------------------------------------------------------------------------
2121 static int sh_mobile_lcdc_update_bl(struct backlight_device
*bdev
)
2123 struct sh_mobile_lcdc_chan
*ch
= bl_get_data(bdev
);
2124 int brightness
= bdev
->props
.brightness
;
2126 if (bdev
->props
.power
!= FB_BLANK_UNBLANK
||
2127 bdev
->props
.state
& (BL_CORE_SUSPENDED
| BL_CORE_FBBLANK
))
2130 ch
->bl_brightness
= brightness
;
2131 return ch
->cfg
->bl_info
.set_brightness(brightness
);
2134 static int sh_mobile_lcdc_get_brightness(struct backlight_device
*bdev
)
2136 struct sh_mobile_lcdc_chan
*ch
= bl_get_data(bdev
);
2138 return ch
->bl_brightness
;
2141 static int sh_mobile_lcdc_check_fb(struct backlight_device
*bdev
,
2142 struct fb_info
*info
)
2144 return (info
->bl_dev
== bdev
);
2147 static const struct backlight_ops sh_mobile_lcdc_bl_ops
= {
2148 .options
= BL_CORE_SUSPENDRESUME
,
2149 .update_status
= sh_mobile_lcdc_update_bl
,
2150 .get_brightness
= sh_mobile_lcdc_get_brightness
,
2151 .check_fb
= sh_mobile_lcdc_check_fb
,
2154 static struct backlight_device
*sh_mobile_lcdc_bl_probe(struct device
*parent
,
2155 struct sh_mobile_lcdc_chan
*ch
)
2157 struct backlight_device
*bl
;
2159 bl
= backlight_device_register(ch
->cfg
->bl_info
.name
, parent
, ch
,
2160 &sh_mobile_lcdc_bl_ops
, NULL
);
2162 dev_err(parent
, "unable to register backlight device: %ld\n",
2167 bl
->props
.max_brightness
= ch
->cfg
->bl_info
.max_brightness
;
2168 bl
->props
.brightness
= bl
->props
.max_brightness
;
2169 backlight_update_status(bl
);
2174 static void sh_mobile_lcdc_bl_remove(struct backlight_device
*bdev
)
2176 backlight_device_unregister(bdev
);
2179 /* -----------------------------------------------------------------------------
2183 static int sh_mobile_lcdc_suspend(struct device
*dev
)
2185 struct platform_device
*pdev
= to_platform_device(dev
);
2187 sh_mobile_lcdc_stop(platform_get_drvdata(pdev
));
2191 static int sh_mobile_lcdc_resume(struct device
*dev
)
2193 struct platform_device
*pdev
= to_platform_device(dev
);
2195 return sh_mobile_lcdc_start(platform_get_drvdata(pdev
));
2198 static int sh_mobile_lcdc_runtime_suspend(struct device
*dev
)
2200 struct sh_mobile_lcdc_priv
*priv
= dev_get_drvdata(dev
);
2202 /* turn off LCDC hardware */
2203 lcdc_write(priv
, _LDCNT1R
, 0);
2208 static int sh_mobile_lcdc_runtime_resume(struct device
*dev
)
2210 struct sh_mobile_lcdc_priv
*priv
= dev_get_drvdata(dev
);
2212 __sh_mobile_lcdc_start(priv
);
2217 static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops
= {
2218 .suspend
= sh_mobile_lcdc_suspend
,
2219 .resume
= sh_mobile_lcdc_resume
,
2220 .runtime_suspend
= sh_mobile_lcdc_runtime_suspend
,
2221 .runtime_resume
= sh_mobile_lcdc_runtime_resume
,
2224 /* -----------------------------------------------------------------------------
2225 * Framebuffer notifier
2228 /* -----------------------------------------------------------------------------
2229 * Probe/remove and driver init/exit
2232 static const struct fb_videomode default_720p
= {
2233 .name
= "HDMI 720p",
2238 .right_margin
= 110,
2247 .sync
= FB_SYNC_VERT_HIGH_ACT
| FB_SYNC_HOR_HIGH_ACT
,
2250 static int sh_mobile_lcdc_remove(struct platform_device
*pdev
)
2252 struct sh_mobile_lcdc_priv
*priv
= platform_get_drvdata(pdev
);
2255 for (i
= 0; i
< ARRAY_SIZE(priv
->overlays
); i
++)
2256 sh_mobile_lcdc_overlay_fb_unregister(&priv
->overlays
[i
]);
2257 for (i
= 0; i
< ARRAY_SIZE(priv
->ch
); i
++)
2258 sh_mobile_lcdc_channel_fb_unregister(&priv
->ch
[i
]);
2260 sh_mobile_lcdc_stop(priv
);
2262 for (i
= 0; i
< ARRAY_SIZE(priv
->overlays
); i
++) {
2263 struct sh_mobile_lcdc_overlay
*ovl
= &priv
->overlays
[i
];
2265 sh_mobile_lcdc_overlay_fb_cleanup(ovl
);
2268 dma_free_coherent(&pdev
->dev
, ovl
->fb_size
,
2269 ovl
->fb_mem
, ovl
->dma_handle
);
2272 for (i
= 0; i
< ARRAY_SIZE(priv
->ch
); i
++) {
2273 struct sh_mobile_lcdc_chan
*ch
= &priv
->ch
[i
];
2276 ch
->tx_dev
->lcdc
= NULL
;
2277 module_put(ch
->cfg
->tx_dev
->dev
.driver
->owner
);
2280 sh_mobile_lcdc_channel_fb_cleanup(ch
);
2283 dma_free_coherent(&pdev
->dev
, ch
->fb_size
,
2284 ch
->fb_mem
, ch
->dma_handle
);
2287 for (i
= 0; i
< ARRAY_SIZE(priv
->ch
); i
++) {
2288 struct sh_mobile_lcdc_chan
*ch
= &priv
->ch
[i
];
2291 sh_mobile_lcdc_bl_remove(ch
->bl
);
2292 mutex_destroy(&ch
->open_lock
);
2295 if (priv
->dot_clk
) {
2296 pm_runtime_disable(&pdev
->dev
);
2297 clk_put(priv
->dot_clk
);
2301 iounmap(priv
->base
);
2304 free_irq(priv
->irq
, priv
);
2309 static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan
*ch
)
2311 int interface_type
= ch
->cfg
->interface_type
;
2313 switch (interface_type
) {
2337 /* SUBLCD only supports SYS interface */
2338 if (lcdc_chan_is_sublcd(ch
)) {
2339 if (!(interface_type
& LDMT1R_IFM
))
2342 interface_type
&= ~LDMT1R_IFM
;
2345 ch
->ldmt1r_value
= interface_type
;
2350 sh_mobile_lcdc_overlay_init(struct sh_mobile_lcdc_overlay
*ovl
)
2352 const struct sh_mobile_lcdc_format_info
*format
;
2353 struct device
*dev
= ovl
->channel
->lcdc
->dev
;
2356 if (ovl
->cfg
->fourcc
== 0)
2359 /* Validate the format. */
2360 format
= sh_mobile_format_info(ovl
->cfg
->fourcc
);
2361 if (format
== NULL
) {
2362 dev_err(dev
, "Invalid FOURCC %08x\n", ovl
->cfg
->fourcc
);
2366 ovl
->enabled
= false;
2367 ovl
->mode
= LCDC_OVERLAY_BLEND
;
2373 /* The default Y virtual resolution is twice the panel size to allow for
2376 ovl
->format
= format
;
2377 ovl
->xres
= ovl
->cfg
->max_xres
;
2378 ovl
->xres_virtual
= ovl
->xres
;
2379 ovl
->yres
= ovl
->cfg
->max_yres
;
2380 ovl
->yres_virtual
= ovl
->yres
* 2;
2383 ovl
->pitch
= ovl
->xres_virtual
* format
->bpp
/ 8;
2385 ovl
->pitch
= ovl
->xres_virtual
;
2387 /* Allocate frame buffer memory. */
2388 ovl
->fb_size
= ovl
->cfg
->max_xres
* ovl
->cfg
->max_yres
2389 * format
->bpp
/ 8 * 2;
2390 ovl
->fb_mem
= dma_alloc_coherent(dev
, ovl
->fb_size
, &ovl
->dma_handle
,
2393 dev_err(dev
, "unable to allocate buffer\n");
2397 ret
= sh_mobile_lcdc_overlay_fb_init(ovl
);
2405 sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan
*ch
)
2407 const struct sh_mobile_lcdc_format_info
*format
;
2408 const struct sh_mobile_lcdc_chan_cfg
*cfg
= ch
->cfg
;
2409 struct device
*dev
= ch
->lcdc
->dev
;
2410 const struct fb_videomode
*max_mode
;
2411 const struct fb_videomode
*mode
;
2412 unsigned int num_modes
;
2413 unsigned int max_size
;
2416 /* Validate the format. */
2417 format
= sh_mobile_format_info(cfg
->fourcc
);
2418 if (format
== NULL
) {
2419 dev_err(dev
, "Invalid FOURCC %08x.\n", cfg
->fourcc
);
2423 /* Iterate through the modes to validate them and find the highest
2429 for (i
= 0, mode
= cfg
->lcd_modes
; i
< cfg
->num_modes
; i
++, mode
++) {
2430 unsigned int size
= mode
->yres
* mode
->xres
;
2432 /* NV12/NV21 buffers must have even number of lines */
2433 if ((cfg
->fourcc
== V4L2_PIX_FMT_NV12
||
2434 cfg
->fourcc
== V4L2_PIX_FMT_NV21
) && (mode
->yres
& 0x1)) {
2435 dev_err(dev
, "yres must be multiple of 2 for "
2436 "YCbCr420 mode.\n");
2440 if (size
> max_size
) {
2447 max_size
= MAX_XRES
* MAX_YRES
;
2449 dev_dbg(dev
, "Found largest videomode %ux%u\n",
2450 max_mode
->xres
, max_mode
->yres
);
2452 if (cfg
->lcd_modes
== NULL
) {
2453 mode
= &default_720p
;
2456 mode
= cfg
->lcd_modes
;
2457 num_modes
= cfg
->num_modes
;
2460 /* Use the first mode as default. The default Y virtual resolution is
2461 * twice the panel size to allow for double-buffering.
2463 ch
->format
= format
;
2464 ch
->xres
= mode
->xres
;
2465 ch
->xres_virtual
= mode
->xres
;
2466 ch
->yres
= mode
->yres
;
2467 ch
->yres_virtual
= mode
->yres
* 2;
2470 ch
->colorspace
= V4L2_COLORSPACE_SRGB
;
2471 ch
->pitch
= ch
->xres_virtual
* format
->bpp
/ 8;
2473 ch
->colorspace
= V4L2_COLORSPACE_REC709
;
2474 ch
->pitch
= ch
->xres_virtual
;
2477 ch
->display
.width
= cfg
->panel_cfg
.width
;
2478 ch
->display
.height
= cfg
->panel_cfg
.height
;
2479 ch
->display
.mode
= *mode
;
2481 /* Allocate frame buffer memory. */
2482 ch
->fb_size
= max_size
* format
->bpp
/ 8 * 2;
2483 ch
->fb_mem
= dma_alloc_coherent(dev
, ch
->fb_size
, &ch
->dma_handle
,
2485 if (ch
->fb_mem
== NULL
) {
2486 dev_err(dev
, "unable to allocate buffer\n");
2490 /* Initialize the transmitter device if present. */
2492 if (!cfg
->tx_dev
->dev
.driver
||
2493 !try_module_get(cfg
->tx_dev
->dev
.driver
->owner
)) {
2494 dev_warn(dev
, "unable to get transmitter device\n");
2497 ch
->tx_dev
= platform_get_drvdata(cfg
->tx_dev
);
2498 ch
->tx_dev
->lcdc
= ch
;
2499 ch
->tx_dev
->def_mode
= *mode
;
2502 return sh_mobile_lcdc_channel_fb_init(ch
, mode
, num_modes
);
2505 static int sh_mobile_lcdc_probe(struct platform_device
*pdev
)
2507 struct sh_mobile_lcdc_info
*pdata
= pdev
->dev
.platform_data
;
2508 struct sh_mobile_lcdc_priv
*priv
;
2509 struct resource
*res
;
2515 dev_err(&pdev
->dev
, "no platform data defined\n");
2519 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
2520 irq
= platform_get_irq(pdev
, 0);
2521 if (!res
|| irq
< 0) {
2522 dev_err(&pdev
->dev
, "cannot get platform resources\n");
2526 priv
= kzalloc(sizeof(*priv
), GFP_KERNEL
);
2530 priv
->dev
= &pdev
->dev
;
2532 for (i
= 0; i
< ARRAY_SIZE(priv
->ch
); i
++)
2533 mutex_init(&priv
->ch
[i
].open_lock
);
2534 platform_set_drvdata(pdev
, priv
);
2536 error
= request_irq(irq
, sh_mobile_lcdc_irq
, 0,
2537 dev_name(&pdev
->dev
), priv
);
2539 dev_err(&pdev
->dev
, "unable to request irq\n");
2544 atomic_set(&priv
->hw_usecnt
, -1);
2546 for (i
= 0, num_channels
= 0; i
< ARRAY_SIZE(pdata
->ch
); i
++) {
2547 struct sh_mobile_lcdc_chan
*ch
= priv
->ch
+ num_channels
;
2550 ch
->cfg
= &pdata
->ch
[i
];
2552 error
= sh_mobile_lcdc_check_interface(ch
);
2554 dev_err(&pdev
->dev
, "unsupported interface type\n");
2557 init_waitqueue_head(&ch
->frame_end_wait
);
2558 init_completion(&ch
->vsync_completion
);
2560 /* probe the backlight is there is one defined */
2561 if (ch
->cfg
->bl_info
.max_brightness
)
2562 ch
->bl
= sh_mobile_lcdc_bl_probe(&pdev
->dev
, ch
);
2564 switch (pdata
->ch
[i
].chan
) {
2565 case LCDC_CHAN_MAINLCD
:
2566 ch
->enabled
= LDCNT2R_ME
;
2567 ch
->reg_offs
= lcdc_offs_mainlcd
;
2570 case LCDC_CHAN_SUBLCD
:
2571 ch
->enabled
= LDCNT2R_SE
;
2572 ch
->reg_offs
= lcdc_offs_sublcd
;
2578 if (!num_channels
) {
2579 dev_err(&pdev
->dev
, "no channels defined\n");
2584 /* for dual channel LCDC (MAIN + SUB) force shared format setting */
2585 if (num_channels
== 2)
2586 priv
->forced_fourcc
= pdata
->ch
[0].fourcc
;
2588 priv
->base
= ioremap(res
->start
, resource_size(res
));
2594 error
= sh_mobile_lcdc_setup_clocks(priv
, pdata
->clock_source
);
2596 dev_err(&pdev
->dev
, "unable to setup clocks\n");
2600 /* Enable runtime PM. */
2601 pm_runtime_enable(&pdev
->dev
);
2603 for (i
= 0; i
< num_channels
; i
++) {
2604 struct sh_mobile_lcdc_chan
*ch
= &priv
->ch
[i
];
2606 error
= sh_mobile_lcdc_channel_init(ch
);
2611 for (i
= 0; i
< ARRAY_SIZE(pdata
->overlays
); i
++) {
2612 struct sh_mobile_lcdc_overlay
*ovl
= &priv
->overlays
[i
];
2614 ovl
->cfg
= &pdata
->overlays
[i
];
2615 ovl
->channel
= &priv
->ch
[0];
2617 error
= sh_mobile_lcdc_overlay_init(ovl
);
2622 error
= sh_mobile_lcdc_start(priv
);
2624 dev_err(&pdev
->dev
, "unable to start hardware\n");
2628 for (i
= 0; i
< num_channels
; i
++) {
2629 struct sh_mobile_lcdc_chan
*ch
= priv
->ch
+ i
;
2631 error
= sh_mobile_lcdc_channel_fb_register(ch
);
2636 for (i
= 0; i
< ARRAY_SIZE(pdata
->overlays
); i
++) {
2637 struct sh_mobile_lcdc_overlay
*ovl
= &priv
->overlays
[i
];
2639 error
= sh_mobile_lcdc_overlay_fb_register(ovl
);
2646 sh_mobile_lcdc_remove(pdev
);
2651 static struct platform_driver sh_mobile_lcdc_driver
= {
2653 .name
= "sh_mobile_lcdc_fb",
2654 .pm
= &sh_mobile_lcdc_dev_pm_ops
,
2656 .probe
= sh_mobile_lcdc_probe
,
2657 .remove
= sh_mobile_lcdc_remove
,
2660 module_platform_driver(sh_mobile_lcdc_driver
);
2662 MODULE_DESCRIPTION("SuperH Mobile LCDC Framebuffer driver");
2663 MODULE_AUTHOR("Magnus Damm <damm@opensource.se>");
2664 MODULE_LICENSE("GPL v2");