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