cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sh_mobile_lcdcfb.c (67535B)


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