1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com/
4 */
5#include <linux/kernel.h>
6#include <linux/init.h>
7#include <linux/module.h>
8#include <linux/errno.h>
9#include <linux/interrupt.h>
10#include <linux/string.h>
11#include <linux/wait.h>
12#include <linux/time.h>
13#include <linux/platform_device.h>
14#include <linux/irq.h>
15#include <linux/mm.h>
16#include <linux/mutex.h>
17#include <linux/videodev2.h>
18#include <linux/slab.h>
19
20
21#include <media/v4l2-dev.h>
22#include <media/v4l2-common.h>
23#include <media/v4l2-ioctl.h>
24#include <media/v4l2-device.h>
25#include <media/davinci/vpbe_display.h>
26#include <media/davinci/vpbe_types.h>
27#include <media/davinci/vpbe.h>
28#include <media/davinci/vpbe_venc.h>
29#include <media/davinci/vpbe_osd.h>
30#include "vpbe_venc_regs.h"
31
32#define VPBE_DISPLAY_DRIVER "vpbe-v4l2"
33
34static int debug;
35
36#define VPBE_DEFAULT_NUM_BUFS 3
37
38module_param(debug, int, 0644);
39
40static int vpbe_set_osd_display_params(struct vpbe_display *disp_dev,
41			struct vpbe_layer *layer);
42
43static int venc_is_second_field(struct vpbe_display *disp_dev)
44{
45	struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
46	int ret, val;
47
48	ret = v4l2_subdev_call(vpbe_dev->venc,
49			       core,
50			       command,
51			       VENC_GET_FLD,
52			       &val);
53	if (ret < 0) {
54		v4l2_err(&vpbe_dev->v4l2_dev,
55			 "Error in getting Field ID 0\n");
56		return 1;
57	}
58	return val;
59}
60
61static void vpbe_isr_even_field(struct vpbe_display *disp_obj,
62				struct vpbe_layer *layer)
63{
64	if (layer->cur_frm == layer->next_frm)
65		return;
66
67	layer->cur_frm->vb.vb2_buf.timestamp = ktime_get_ns();
68	vb2_buffer_done(&layer->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
69	/* Make cur_frm pointing to next_frm */
70	layer->cur_frm = layer->next_frm;
71}
72
73static void vpbe_isr_odd_field(struct vpbe_display *disp_obj,
74				struct vpbe_layer *layer)
75{
76	struct osd_state *osd_device = disp_obj->osd_device;
77	unsigned long addr;
78
79	spin_lock(&disp_obj->dma_queue_lock);
80	if (list_empty(&layer->dma_queue) ||
81		(layer->cur_frm != layer->next_frm)) {
82		spin_unlock(&disp_obj->dma_queue_lock);
83		return;
84	}
85	/*
86	 * one field is displayed configure
87	 * the next frame if it is available
88	 * otherwise hold on current frame
89	 * Get next from the buffer queue
90	 */
91	layer->next_frm = list_entry(layer->dma_queue.next,
92			  struct  vpbe_disp_buffer, list);
93	/* Remove that from the buffer queue */
94	list_del(&layer->next_frm->list);
95	spin_unlock(&disp_obj->dma_queue_lock);
96	/* Mark state of the frame to active */
97	layer->next_frm->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
98	addr = vb2_dma_contig_plane_dma_addr(&layer->next_frm->vb.vb2_buf, 0);
99	osd_device->ops.start_layer(osd_device,
100			layer->layer_info.id,
101			addr,
102			disp_obj->cbcr_ofst);
103}
104
105/* interrupt service routine */
106static irqreturn_t venc_isr(int irq, void *arg)
107{
108	struct vpbe_display *disp_dev = (struct vpbe_display *)arg;
109	struct vpbe_layer *layer;
110	static unsigned last_event;
111	unsigned event = 0;
112	int fid;
113	int i;
114
115	if (!arg || !disp_dev->dev[0])
116		return IRQ_HANDLED;
117
118	if (venc_is_second_field(disp_dev))
119		event |= VENC_SECOND_FIELD;
120	else
121		event |= VENC_FIRST_FIELD;
122
123	if (event == (last_event & ~VENC_END_OF_FRAME)) {
124		/*
125		* If the display is non-interlaced, then we need to flag the
126		* end-of-frame event at every interrupt regardless of the
127		* value of the FIDST bit.  We can conclude that the display is
128		* non-interlaced if the value of the FIDST bit is unchanged
129		* from the previous interrupt.
130		*/
131		event |= VENC_END_OF_FRAME;
132	} else if (event == VENC_SECOND_FIELD) {
133		/* end-of-frame for interlaced display */
134		event |= VENC_END_OF_FRAME;
135	}
136	last_event = event;
137
138	for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
139		layer = disp_dev->dev[i];
140
141		if (!vb2_start_streaming_called(&layer->buffer_queue))
142			continue;
143
144		if (layer->layer_first_int) {
145			layer->layer_first_int = 0;
146			continue;
147		}
148		/* Check the field format */
149		if ((V4L2_FIELD_NONE == layer->pix_fmt.field) &&
150			(event & VENC_END_OF_FRAME)) {
151			/* Progressive mode */
152
153			vpbe_isr_even_field(disp_dev, layer);
154			vpbe_isr_odd_field(disp_dev, layer);
155		} else {
156		/* Interlaced mode */
157
158			layer->field_id ^= 1;
159			if (event & VENC_FIRST_FIELD)
160				fid = 0;
161			else
162				fid = 1;
163
164			/*
165			* If field id does not match with store
166			* field id
167			*/
168			if (fid != layer->field_id) {
169				/* Make them in sync */
170				layer->field_id = fid;
171				continue;
172			}
173			/*
174			* device field id and local field id are
175			* in sync. If this is even field
176			*/
177			if (0 == fid)
178				vpbe_isr_even_field(disp_dev, layer);
179			else  /* odd field */
180				vpbe_isr_odd_field(disp_dev, layer);
181		}
182	}
183
184	return IRQ_HANDLED;
185}
186
187/*
188 * vpbe_buffer_prepare()
189 * This is the callback function called from vb2_qbuf() function
190 * the buffer is prepared and user space virtual address is converted into
191 * physical address
192 */
193static int vpbe_buffer_prepare(struct vb2_buffer *vb)
194{
195	struct vb2_queue *q = vb->vb2_queue;
196	struct vpbe_layer *layer = vb2_get_drv_priv(q);
197	struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
198	unsigned long addr;
199
200	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
201				"vpbe_buffer_prepare\n");
202
203	vb2_set_plane_payload(vb, 0, layer->pix_fmt.sizeimage);
204	if (vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
205		return -EINVAL;
206
207	addr = vb2_dma_contig_plane_dma_addr(vb, 0);
208	if (!IS_ALIGNED(addr, 8)) {
209		v4l2_err(&vpbe_dev->v4l2_dev,
210			 "buffer_prepare:offset is not aligned to 32 bytes\n");
211		return -EINVAL;
212	}
213	return 0;
214}
215
216/*
217 * vpbe_buffer_setup()
218 * This function allocates memory for the buffers
219 */
220static int
221vpbe_buffer_queue_setup(struct vb2_queue *vq,
222			unsigned int *nbuffers, unsigned int *nplanes,
223			unsigned int sizes[], struct device *alloc_devs[])
224
225{
226	/* Get the file handle object and layer object */
227	struct vpbe_layer *layer = vb2_get_drv_priv(vq);
228	struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
229
230	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_buffer_setup\n");
231
232	/* Store number of buffers allocated in numbuffer member */
233	if (vq->num_buffers + *nbuffers < VPBE_DEFAULT_NUM_BUFS)
234		*nbuffers = VPBE_DEFAULT_NUM_BUFS - vq->num_buffers;
235
236	if (*nplanes)
237		return sizes[0] < layer->pix_fmt.sizeimage ? -EINVAL : 0;
238
239	*nplanes = 1;
240	sizes[0] = layer->pix_fmt.sizeimage;
241
242	return 0;
243}
244
245/*
246 * vpbe_buffer_queue()
247 * This function adds the buffer to DMA queue
248 */
249static void vpbe_buffer_queue(struct vb2_buffer *vb)
250{
251	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
252	/* Get the file handle object and layer object */
253	struct vpbe_disp_buffer *buf = container_of(vbuf,
254				struct vpbe_disp_buffer, vb);
255	struct vpbe_layer *layer = vb2_get_drv_priv(vb->vb2_queue);
256	struct vpbe_display *disp = layer->disp_dev;
257	struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
258	unsigned long flags;
259
260	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
261			"vpbe_buffer_queue\n");
262
263	/* add the buffer to the DMA queue */
264	spin_lock_irqsave(&disp->dma_queue_lock, flags);
265	list_add_tail(&buf->list, &layer->dma_queue);
266	spin_unlock_irqrestore(&disp->dma_queue_lock, flags);
267}
268
269static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
270{
271	struct vpbe_layer *layer = vb2_get_drv_priv(vq);
272	struct osd_state *osd_device = layer->disp_dev->osd_device;
273	int ret;
274
275	osd_device->ops.disable_layer(osd_device, layer->layer_info.id);
276
277	/* Get the next frame from the buffer queue */
278	layer->next_frm = layer->cur_frm = list_entry(layer->dma_queue.next,
279				struct vpbe_disp_buffer, list);
280	/* Remove buffer from the buffer queue */
281	list_del(&layer->cur_frm->list);
282	/* Mark state of the current frame to active */
283	layer->cur_frm->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
284	/* Initialize field_id and started member */
285	layer->field_id = 0;
286
287	/* Set parameters in OSD and VENC */
288	ret = vpbe_set_osd_display_params(layer->disp_dev, layer);
289	if (ret < 0) {
290		struct vpbe_disp_buffer *buf, *tmp;
291
292		vb2_buffer_done(&layer->cur_frm->vb.vb2_buf,
293				VB2_BUF_STATE_QUEUED);
294		list_for_each_entry_safe(buf, tmp, &layer->dma_queue, list) {
295			list_del(&buf->list);
296			vb2_buffer_done(&buf->vb.vb2_buf,
297					VB2_BUF_STATE_QUEUED);
298		}
299
300		return ret;
301	}
302
303	/*
304	 * if request format is yuv420 semiplanar, need to
305	 * enable both video windows
306	 */
307	layer->layer_first_int = 1;
308
309	return ret;
310}
311
312static void vpbe_stop_streaming(struct vb2_queue *vq)
313{
314	struct vpbe_layer *layer = vb2_get_drv_priv(vq);
315	struct osd_state *osd_device = layer->disp_dev->osd_device;
316	struct vpbe_display *disp = layer->disp_dev;
317	unsigned long flags;
318
319	if (!vb2_is_streaming(vq))
320		return;
321
322	osd_device->ops.disable_layer(osd_device, layer->layer_info.id);
323
324	/* release all active buffers */
325	spin_lock_irqsave(&disp->dma_queue_lock, flags);
326	if (layer->cur_frm == layer->next_frm) {
327		vb2_buffer_done(&layer->cur_frm->vb.vb2_buf,
328				VB2_BUF_STATE_ERROR);
329	} else {
330		if (layer->cur_frm)
331			vb2_buffer_done(&layer->cur_frm->vb.vb2_buf,
332					VB2_BUF_STATE_ERROR);
333		if (layer->next_frm)
334			vb2_buffer_done(&layer->next_frm->vb.vb2_buf,
335					VB2_BUF_STATE_ERROR);
336	}
337
338	while (!list_empty(&layer->dma_queue)) {
339		layer->next_frm = list_entry(layer->dma_queue.next,
340						struct vpbe_disp_buffer, list);
341		list_del(&layer->next_frm->list);
342		vb2_buffer_done(&layer->next_frm->vb.vb2_buf,
343				VB2_BUF_STATE_ERROR);
344	}
345	spin_unlock_irqrestore(&disp->dma_queue_lock, flags);
346}
347
348static const struct vb2_ops video_qops = {
349	.queue_setup = vpbe_buffer_queue_setup,
350	.wait_prepare = vb2_ops_wait_prepare,
351	.wait_finish = vb2_ops_wait_finish,
352	.buf_prepare = vpbe_buffer_prepare,
353	.start_streaming = vpbe_start_streaming,
354	.stop_streaming = vpbe_stop_streaming,
355	.buf_queue = vpbe_buffer_queue,
356};
357
358static
359struct vpbe_layer*
360_vpbe_display_get_other_win_layer(struct vpbe_display *disp_dev,
361			struct vpbe_layer *layer)
362{
363	enum vpbe_display_device_id thiswin, otherwin;
364	thiswin = layer->device_id;
365
366	otherwin = (thiswin == VPBE_DISPLAY_DEVICE_0) ?
367	VPBE_DISPLAY_DEVICE_1 : VPBE_DISPLAY_DEVICE_0;
368	return disp_dev->dev[otherwin];
369}
370
371static int vpbe_set_osd_display_params(struct vpbe_display *disp_dev,
372			struct vpbe_layer *layer)
373{
374	struct osd_layer_config *cfg  = &layer->layer_info.config;
375	struct osd_state *osd_device = disp_dev->osd_device;
376	struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
377	unsigned long addr;
378	int ret;
379
380	addr = vb2_dma_contig_plane_dma_addr(&layer->cur_frm->vb.vb2_buf, 0);
381	/* Set address in the display registers */
382	osd_device->ops.start_layer(osd_device,
383				    layer->layer_info.id,
384				    addr,
385				    disp_dev->cbcr_ofst);
386
387	ret = osd_device->ops.enable_layer(osd_device,
388				layer->layer_info.id, 0);
389	if (ret < 0) {
390		v4l2_err(&vpbe_dev->v4l2_dev,
391			"Error in enabling osd window layer 0\n");
392		return -1;
393	}
394
395	/* Enable the window */
396	layer->layer_info.enable = 1;
397	if (cfg->pixfmt == PIXFMT_NV12) {
398		struct vpbe_layer *otherlayer =
399			_vpbe_display_get_other_win_layer(disp_dev, layer);
400
401		ret = osd_device->ops.enable_layer(osd_device,
402				otherlayer->layer_info.id, 1);
403		if (ret < 0) {
404			v4l2_err(&vpbe_dev->v4l2_dev,
405				"Error in enabling osd window layer 1\n");
406			return -1;
407		}
408		otherlayer->layer_info.enable = 1;
409	}
410	return 0;
411}
412
413static void
414vpbe_disp_calculate_scale_factor(struct vpbe_display *disp_dev,
415			struct vpbe_layer *layer,
416			int expected_xsize, int expected_ysize)
417{
418	struct display_layer_info *layer_info = &layer->layer_info;
419	struct v4l2_pix_format *pixfmt = &layer->pix_fmt;
420	struct osd_layer_config *cfg  = &layer->layer_info.config;
421	struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
422	int calculated_xsize;
423	int h_exp = 0;
424	int v_exp = 0;
425	int h_scale;
426	int v_scale;
427
428	v4l2_std_id standard_id = vpbe_dev->current_timings.std_id;
429
430	/*
431	 * Application initially set the image format. Current display
432	 * size is obtained from the vpbe display controller. expected_xsize
433	 * and expected_ysize are set through S_SELECTION ioctl. Based on this,
434	 * driver will calculate the scale factors for vertical and
435	 * horizontal direction so that the image is displayed scaled
436	 * and expanded. Application uses expansion to display the image
437	 * in a square pixel. Otherwise it is displayed using displays
438	 * pixel aspect ratio.It is expected that application chooses
439	 * the crop coordinates for cropped or scaled display. if crop
440	 * size is less than the image size, it is displayed cropped or
441	 * it is displayed scaled and/or expanded.
442	 *
443	 * to begin with, set the crop window same as expected. Later we
444	 * will override with scaled window size
445	 */
446
447	cfg->xsize = pixfmt->width;
448	cfg->ysize = pixfmt->height;
449	layer_info->h_zoom = ZOOM_X1;	/* no horizontal zoom */
450	layer_info->v_zoom = ZOOM_X1;	/* no horizontal zoom */
451	layer_info->h_exp = H_EXP_OFF;	/* no horizontal zoom */
452	layer_info->v_exp = V_EXP_OFF;	/* no horizontal zoom */
453
454	if (pixfmt->width < expected_xsize) {
455		h_scale = vpbe_dev->current_timings.xres / pixfmt->width;
456		if (h_scale < 2)
457			h_scale = 1;
458		else if (h_scale >= 4)
459			h_scale = 4;
460		else
461			h_scale = 2;
462		cfg->xsize *= h_scale;
463		if (cfg->xsize < expected_xsize) {
464			if ((standard_id & V4L2_STD_525_60) ||
465			(standard_id & V4L2_STD_625_50)) {
466				calculated_xsize = (cfg->xsize *
467					VPBE_DISPLAY_H_EXP_RATIO_N) /
468					VPBE_DISPLAY_H_EXP_RATIO_D;
469				if (calculated_xsize <= expected_xsize) {
470					h_exp = 1;
471					cfg->xsize = calculated_xsize;
472				}
473			}
474		}
475		if (h_scale == 2)
476			layer_info->h_zoom = ZOOM_X2;
477		else if (h_scale == 4)
478			layer_info->h_zoom = ZOOM_X4;
479		if (h_exp)
480			layer_info->h_exp = H_EXP_9_OVER_8;
481	} else {
482		/* no scaling, only cropping. Set display area to crop area */
483		cfg->xsize = expected_xsize;
484	}
485
486	if (pixfmt->height < expected_ysize) {
487		v_scale = expected_ysize / pixfmt->height;
488		if (v_scale < 2)
489			v_scale = 1;
490		else if (v_scale >= 4)
491			v_scale = 4;
492		else
493			v_scale = 2;
494		cfg->ysize *= v_scale;
495		if (cfg->ysize < expected_ysize) {
496			if ((standard_id & V4L2_STD_625_50)) {
497				calculated_xsize = (cfg->ysize *
498					VPBE_DISPLAY_V_EXP_RATIO_N) /
499					VPBE_DISPLAY_V_EXP_RATIO_D;
500				if (calculated_xsize <= expected_ysize) {
501					v_exp = 1;
502					cfg->ysize = calculated_xsize;
503				}
504			}
505		}
506		if (v_scale == 2)
507			layer_info->v_zoom = ZOOM_X2;
508		else if (v_scale == 4)
509			layer_info->v_zoom = ZOOM_X4;
510		if (v_exp)
511			layer_info->v_exp = V_EXP_6_OVER_5;
512	} else {
513		/* no scaling, only cropping. Set display area to crop area */
514		cfg->ysize = expected_ysize;
515	}
516	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
517		"crop display xsize = %d, ysize = %d\n",
518		cfg->xsize, cfg->ysize);
519}
520
521static void vpbe_disp_adj_position(struct vpbe_display *disp_dev,
522			struct vpbe_layer *layer,
523			int top, int left)
524{
525	struct osd_layer_config *cfg = &layer->layer_info.config;
526	struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
527
528	cfg->xpos = min((unsigned int)left,
529			vpbe_dev->current_timings.xres - cfg->xsize);
530	cfg->ypos = min((unsigned int)top,
531			vpbe_dev->current_timings.yres - cfg->ysize);
532
533	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
534		"new xpos = %d, ypos = %d\n",
535		cfg->xpos, cfg->ypos);
536}
537
538static void vpbe_disp_check_window_params(struct vpbe_display *disp_dev,
539			struct v4l2_rect *c)
540{
541	struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
542
543	if ((c->width == 0) ||
544	  ((c->width + c->left) > vpbe_dev->current_timings.xres))
545		c->width = vpbe_dev->current_timings.xres - c->left;
546
547	if ((c->height == 0) || ((c->height + c->top) >
548	  vpbe_dev->current_timings.yres))
549		c->height = vpbe_dev->current_timings.yres - c->top;
550
551	/* window height must be even for interlaced display */
552	if (vpbe_dev->current_timings.interlaced)
553		c->height &= (~0x01);
554
555}
556
557/*
558 * vpbe_try_format()
559 * If user application provides width and height, and have bytesperline set
560 * to zero, driver calculates bytesperline and sizeimage based on hardware
561 * limits.
562 */
563static int vpbe_try_format(struct vpbe_display *disp_dev,
564			struct v4l2_pix_format *pixfmt, int check)
565{
566	struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
567	int min_height = 1;
568	int min_width = 32;
569	int max_height;
570	int max_width;
571	int bpp;
572
573	if ((pixfmt->pixelformat != V4L2_PIX_FMT_UYVY) &&
574	    (pixfmt->pixelformat != V4L2_PIX_FMT_NV12))
575		/* choose default as V4L2_PIX_FMT_UYVY */
576		pixfmt->pixelformat = V4L2_PIX_FMT_UYVY;
577
578	/* Check the field format */
579	if ((pixfmt->field != V4L2_FIELD_INTERLACED) &&
580		(pixfmt->field != V4L2_FIELD_NONE)) {
581		if (vpbe_dev->current_timings.interlaced)
582			pixfmt->field = V4L2_FIELD_INTERLACED;
583		else
584			pixfmt->field = V4L2_FIELD_NONE;
585	}
586
587	if (pixfmt->field == V4L2_FIELD_INTERLACED)
588		min_height = 2;
589
590	if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
591		bpp = 1;
592	else
593		bpp = 2;
594
595	max_width = vpbe_dev->current_timings.xres;
596	max_height = vpbe_dev->current_timings.yres;
597
598	min_width /= bpp;
599
600	if (!pixfmt->width || (pixfmt->width < min_width) ||
601		(pixfmt->width > max_width)) {
602		pixfmt->width = vpbe_dev->current_timings.xres;
603	}
604
605	if (!pixfmt->height || (pixfmt->height  < min_height) ||
606		(pixfmt->height  > max_height)) {
607		pixfmt->height = vpbe_dev->current_timings.yres;
608	}
609
610	if (pixfmt->bytesperline < (pixfmt->width * bpp))
611		pixfmt->bytesperline = pixfmt->width * bpp;
612
613	/* Make the bytesperline 32 byte aligned */
614	pixfmt->bytesperline = ((pixfmt->width * bpp + 31) & ~31);
615
616	if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
617		pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height +
618				(pixfmt->bytesperline * pixfmt->height >> 1);
619	else
620		pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
621
622	return 0;
623}
624
625static int vpbe_display_querycap(struct file *file, void  *priv,
626			       struct v4l2_capability *cap)
627{
628	struct vpbe_layer *layer = video_drvdata(file);
629	struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
630
631	snprintf(cap->driver, sizeof(cap->driver), "%s",
632		dev_name(vpbe_dev->pdev));
633	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
634		 dev_name(vpbe_dev->pdev));
635	strscpy(cap->card, vpbe_dev->cfg->module_name, sizeof(cap->card));
636
637	return 0;
638}
639
640static int vpbe_display_s_selection(struct file *file, void *priv,
641			     struct v4l2_selection *sel)
642{
643	struct vpbe_layer *layer = video_drvdata(file);
644	struct vpbe_display *disp_dev = layer->disp_dev;
645	struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
646	struct osd_layer_config *cfg = &layer->layer_info.config;
647	struct osd_state *osd_device = disp_dev->osd_device;
648	struct v4l2_rect rect = sel->r;
649	int ret;
650
651	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
652		"VIDIOC_S_SELECTION, layer id = %d\n", layer->device_id);
653
654	if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
655	    sel->target != V4L2_SEL_TGT_CROP)
656		return -EINVAL;
657
658	if (rect.top < 0)
659		rect.top = 0;
660	if (rect.left < 0)
661		rect.left = 0;
662
663	vpbe_disp_check_window_params(disp_dev, &rect);
664
665	osd_device->ops.get_layer_config(osd_device,
666			layer->layer_info.id, cfg);
667
668	vpbe_disp_calculate_scale_factor(disp_dev, layer,
669					rect.width,
670					rect.height);
671	vpbe_disp_adj_position(disp_dev, layer, rect.top,
672					rect.left);
673	ret = osd_device->ops.set_layer_config(osd_device,
674				layer->layer_info.id, cfg);
675	if (ret < 0) {
676		v4l2_err(&vpbe_dev->v4l2_dev,
677			"Error in set layer config:\n");
678		return -EINVAL;
679	}
680
681	/* apply zooming and h or v expansion */
682	osd_device->ops.set_zoom(osd_device,
683			layer->layer_info.id,
684			layer->layer_info.h_zoom,
685			layer->layer_info.v_zoom);
686	ret = osd_device->ops.set_vid_expansion(osd_device,
687			layer->layer_info.h_exp,
688			layer->layer_info.v_exp);
689	if (ret < 0) {
690		v4l2_err(&vpbe_dev->v4l2_dev,
691		"Error in set vid expansion:\n");
692		return -EINVAL;
693	}
694
695	if ((layer->layer_info.h_zoom != ZOOM_X1) ||
696		(layer->layer_info.v_zoom != ZOOM_X1) ||
697		(layer->layer_info.h_exp != H_EXP_OFF) ||
698		(layer->layer_info.v_exp != V_EXP_OFF))
699		/* Enable expansion filter */
700		osd_device->ops.set_interpolation_filter(osd_device, 1);
701	else
702		osd_device->ops.set_interpolation_filter(osd_device, 0);
703
704	sel->r = rect;
705	return 0;
706}
707
708static int vpbe_display_g_selection(struct file *file, void *priv,
709				    struct v4l2_selection *sel)
710{
711	struct vpbe_layer *layer = video_drvdata(file);
712	struct osd_layer_config *cfg = &layer->layer_info.config;
713	struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
714	struct osd_state *osd_device = layer->disp_dev->osd_device;
715	struct v4l2_rect *rect = &sel->r;
716
717	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
718			"VIDIOC_G_SELECTION, layer id = %d\n",
719			layer->device_id);
720
721	if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
722		return -EINVAL;
723
724	switch (sel->target) {
725	case V4L2_SEL_TGT_CROP:
726		osd_device->ops.get_layer_config(osd_device,
727						 layer->layer_info.id, cfg);
728		rect->top = cfg->ypos;
729		rect->left = cfg->xpos;
730		rect->width = cfg->xsize;
731		rect->height = cfg->ysize;
732		break;
733	case V4L2_SEL_TGT_CROP_DEFAULT:
734	case V4L2_SEL_TGT_CROP_BOUNDS:
735		rect->left = 0;
736		rect->top = 0;
737		rect->width = vpbe_dev->current_timings.xres;
738		rect->height = vpbe_dev->current_timings.yres;
739		break;
740	default:
741		return -EINVAL;
742	}
743
744	return 0;
745}
746
747static int vpbe_display_g_pixelaspect(struct file *file, void *priv,
748				      int type, struct v4l2_fract *f)
749{
750	struct vpbe_layer *layer = video_drvdata(file);
751	struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
752
753	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_CROPCAP ioctl\n");
754
755	if (type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
756		return -EINVAL;
757
758	*f = vpbe_dev->current_timings.aspect;
759	return 0;
760}
761
762static int vpbe_display_g_fmt(struct file *file, void *priv,
763				struct v4l2_format *fmt)
764{
765	struct vpbe_layer *layer = video_drvdata(file);
766	struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
767
768	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
769			"VIDIOC_G_FMT, layer id = %d\n",
770			layer->device_id);
771
772	/* If buffer type is video output */
773	if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
774		v4l2_err(&vpbe_dev->v4l2_dev, "invalid type\n");
775		return -EINVAL;
776	}
777	/* Fill in the information about format */
778	fmt->fmt.pix = layer->pix_fmt;
779
780	return 0;
781}
782
783static int vpbe_display_enum_fmt(struct file *file, void  *priv,
784				   struct v4l2_fmtdesc *fmt)
785{
786	struct vpbe_layer *layer = video_drvdata(file);
787	struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
788
789	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
790				"VIDIOC_ENUM_FMT, layer id = %d\n",
791				layer->device_id);
792	if (fmt->index > 1) {
793		v4l2_err(&vpbe_dev->v4l2_dev, "Invalid format index\n");
794		return -EINVAL;
795	}
796
797	/* Fill in the information about format */
798	if (fmt->index == 0)
799		fmt->pixelformat = V4L2_PIX_FMT_UYVY;
800	else
801		fmt->pixelformat = V4L2_PIX_FMT_NV12;
802
803	return 0;
804}
805
806static int vpbe_display_s_fmt(struct file *file, void *priv,
807				struct v4l2_format *fmt)
808{
809	struct vpbe_layer *layer = video_drvdata(file);
810	struct vpbe_display *disp_dev = layer->disp_dev;
811	struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
812	struct osd_layer_config *cfg  = &layer->layer_info.config;
813	struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
814	struct osd_state *osd_device = disp_dev->osd_device;
815	int ret;
816
817	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
818			"VIDIOC_S_FMT, layer id = %d\n",
819			layer->device_id);
820
821	if (vb2_is_busy(&layer->buffer_queue))
822		return -EBUSY;
823
824	if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
825		v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "invalid type\n");
826		return -EINVAL;
827	}
828	/* Check for valid pixel format */
829	ret = vpbe_try_format(disp_dev, pixfmt, 1);
830	if (ret)
831		return ret;
832
833	/* YUV420 is requested, check availability of the
834	other video window */
835
836	layer->pix_fmt = *pixfmt;
837	if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12) {
838		struct vpbe_layer *otherlayer;
839
840		otherlayer = _vpbe_display_get_other_win_layer(disp_dev, layer);
841		/* if other layer is available, only
842		 * claim it, do not configure it
843		 */
844		ret = osd_device->ops.request_layer(osd_device,
845						    otherlayer->layer_info.id);
846		if (ret < 0) {
847			v4l2_err(&vpbe_dev->v4l2_dev,
848				 "Display Manager failed to allocate layer\n");
849			return -EBUSY;
850		}
851	}
852
853	/* Get osd layer config */
854	osd_device->ops.get_layer_config(osd_device,
855			layer->layer_info.id, cfg);
856	/* Store the pixel format in the layer object */
857	cfg->xsize = pixfmt->width;
858	cfg->ysize = pixfmt->height;
859	cfg->line_length = pixfmt->bytesperline;
860	cfg->ypos = 0;
861	cfg->xpos = 0;
862	cfg->interlaced = vpbe_dev->current_timings.interlaced;
863
864	if (V4L2_PIX_FMT_UYVY == pixfmt->pixelformat)
865		cfg->pixfmt = PIXFMT_YCBCRI;
866
867	/* Change of the default pixel format for both video windows */
868	if (V4L2_PIX_FMT_NV12 == pixfmt->pixelformat) {
869		struct vpbe_layer *otherlayer;
870		cfg->pixfmt = PIXFMT_NV12;
871		otherlayer = _vpbe_display_get_other_win_layer(disp_dev,
872								layer);
873		otherlayer->layer_info.config.pixfmt = PIXFMT_NV12;
874	}
875
876	/* Set the layer config in the osd window */
877	ret = osd_device->ops.set_layer_config(osd_device,
878				layer->layer_info.id, cfg);
879	if (ret < 0) {
880		v4l2_err(&vpbe_dev->v4l2_dev,
881				"Error in S_FMT params:\n");
882		return -EINVAL;
883	}
884
885	/* Readback and fill the local copy of current pix format */
886	osd_device->ops.get_layer_config(osd_device,
887			layer->layer_info.id, cfg);
888
889	return 0;
890}
891
892static int vpbe_display_try_fmt(struct file *file, void *priv,
893				  struct v4l2_format *fmt)
894{
895	struct vpbe_layer *layer = video_drvdata(file);
896	struct vpbe_display *disp_dev = layer->disp_dev;
897	struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
898	struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
899
900	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_TRY_FMT\n");
901
902	if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
903		v4l2_err(&vpbe_dev->v4l2_dev, "invalid type\n");
904		return -EINVAL;
905	}
906
907	/* Check for valid field format */
908	return  vpbe_try_format(disp_dev, pixfmt, 0);
909
910}
911
912/*
913 * vpbe_display_s_std - Set the given standard in the encoder
914 *
915 * Sets the standard if supported by the current encoder. Return the status.
916 * 0 - success & -EINVAL on error
917 */
918static int vpbe_display_s_std(struct file *file, void *priv,
919				v4l2_std_id std_id)
920{
921	struct vpbe_layer *layer = video_drvdata(file);
922	struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
923	int ret;
924
925	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_STD\n");
926
927	if (vb2_is_busy(&layer->buffer_queue))
928		return -EBUSY;
929
930	if (vpbe_dev->ops.s_std) {
931		ret = vpbe_dev->ops.s_std(vpbe_dev, std_id);
932		if (ret) {
933			v4l2_err(&vpbe_dev->v4l2_dev,
934			"Failed to set standard for sub devices\n");
935			return -EINVAL;
936		}
937	} else {
938		return -EINVAL;
939	}
940
941	return 0;
942}
943
944/*
945 * vpbe_display_g_std - Get the standard in the current encoder
946 *
947 * Get the standard in the current encoder. Return the status. 0 - success
948 * -EINVAL on error
949 */
950static int vpbe_display_g_std(struct file *file, void *priv,
951				v4l2_std_id *std_id)
952{
953	struct vpbe_layer *layer = video_drvdata(file);
954	struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
955
956	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,	"VIDIOC_G_STD\n");
957
958	/* Get the standard from the current encoder */
959	if (vpbe_dev->current_timings.timings_type & VPBE_ENC_STD) {
960		*std_id = vpbe_dev->current_timings.std_id;
961		return 0;
962	}
963
964	return -EINVAL;
965}
966
967/*
968 * vpbe_display_enum_output - enumerate outputs
969 *
970 * Enumerates the outputs available at the vpbe display
971 * returns the status, -EINVAL if end of output list
972 */
973static int vpbe_display_enum_output(struct file *file, void *priv,
974				    struct v4l2_output *output)
975{
976	struct vpbe_layer *layer = video_drvdata(file);
977	struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
978	int ret;
979
980	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,	"VIDIOC_ENUM_OUTPUT\n");
981
982	/* Enumerate outputs */
983	if (!vpbe_dev->ops.enum_outputs)
984		return -EINVAL;
985
986	ret = vpbe_dev->ops.enum_outputs(vpbe_dev, output);
987	if (ret) {
988		v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
989			"Failed to enumerate outputs\n");
990		return -EINVAL;
991	}
992
993	return 0;
994}
995
996/*
997 * vpbe_display_s_output - Set output to
998 * the output specified by the index
999 */
1000static int vpbe_display_s_output(struct file *file, void *priv,
1001				unsigned int i)
1002{
1003	struct vpbe_layer *layer = video_drvdata(file);
1004	struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
1005	int ret;
1006
1007	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,	"VIDIOC_S_OUTPUT\n");
1008
1009	if (vb2_is_busy(&layer->buffer_queue))
1010		return -EBUSY;
1011
1012	if (!vpbe_dev->ops.set_output)
1013		return -EINVAL;
1014
1015	ret = vpbe_dev->ops.set_output(vpbe_dev, i);
1016	if (ret) {
1017		v4l2_err(&vpbe_dev->v4l2_dev,
1018			"Failed to set output for sub devices\n");
1019		return -EINVAL;
1020	}
1021
1022	return 0;
1023}
1024
1025/*
1026 * vpbe_display_g_output - Get output from subdevice
1027 * for a given by the index
1028 */
1029static int vpbe_display_g_output(struct file *file, void *priv,
1030				unsigned int *i)
1031{
1032	struct vpbe_layer *layer = video_drvdata(file);
1033	struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
1034
1035	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_OUTPUT\n");
1036	/* Get the standard from the current encoder */
1037	*i = vpbe_dev->current_out_index;
1038
1039	return 0;
1040}
1041
1042/*
1043 * vpbe_display_enum_dv_timings - Enumerate the dv timings
1044 *
1045 * enum the timings in the current encoder. Return the status. 0 - success
1046 * -EINVAL on error
1047 */
1048static int
1049vpbe_display_enum_dv_timings(struct file *file, void *priv,
1050			struct v4l2_enum_dv_timings *timings)
1051{
1052	struct vpbe_layer *layer = video_drvdata(file);
1053	struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
1054	int ret;
1055
1056	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_DV_TIMINGS\n");
1057
1058	/* Enumerate outputs */
1059	if (!vpbe_dev->ops.enum_dv_timings)
1060		return -EINVAL;
1061
1062	ret = vpbe_dev->ops.enum_dv_timings(vpbe_dev, timings);
1063	if (ret) {
1064		v4l2_err(&vpbe_dev->v4l2_dev,
1065			"Failed to enumerate dv timings info\n");
1066		return -EINVAL;
1067	}
1068
1069	return 0;
1070}
1071
1072/*
1073 * vpbe_display_s_dv_timings - Set the dv timings
1074 *
1075 * Set the timings in the current encoder. Return the status. 0 - success
1076 * -EINVAL on error
1077 */
1078static int
1079vpbe_display_s_dv_timings(struct file *file, void *priv,
1080				struct v4l2_dv_timings *timings)
1081{
1082	struct vpbe_layer *layer = video_drvdata(file);
1083	struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
1084	int ret;
1085
1086	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_DV_TIMINGS\n");
1087
1088	if (vb2_is_busy(&layer->buffer_queue))
1089		return -EBUSY;
1090
1091	/* Set the given standard in the encoder */
1092	if (!vpbe_dev->ops.s_dv_timings)
1093		return -EINVAL;
1094
1095	ret = vpbe_dev->ops.s_dv_timings(vpbe_dev, timings);
1096	if (ret) {
1097		v4l2_err(&vpbe_dev->v4l2_dev,
1098			"Failed to set the dv timings info\n");
1099		return -EINVAL;
1100	}
1101
1102	return 0;
1103}
1104
1105/*
1106 * vpbe_display_g_dv_timings - Set the dv timings
1107 *
1108 * Get the timings in the current encoder. Return the status. 0 - success
1109 * -EINVAL on error
1110 */
1111static int
1112vpbe_display_g_dv_timings(struct file *file, void *priv,
1113				struct v4l2_dv_timings *dv_timings)
1114{
1115	struct vpbe_layer *layer = video_drvdata(file);
1116	struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
1117
1118	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_DV_TIMINGS\n");
1119
1120	/* Get the given standard in the encoder */
1121
1122	if (vpbe_dev->current_timings.timings_type &
1123				VPBE_ENC_DV_TIMINGS) {
1124		*dv_timings = vpbe_dev->current_timings.dv_timings;
1125	} else {
1126		return -EINVAL;
1127	}
1128
1129	return 0;
1130}
1131
1132/*
1133 * vpbe_display_open()
1134 * It creates object of file handle structure and stores it in private_data
1135 * member of filepointer
1136 */
1137static int vpbe_display_open(struct file *file)
1138{
1139	struct vpbe_layer *layer = video_drvdata(file);
1140	struct vpbe_display *disp_dev = layer->disp_dev;
1141	struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
1142	struct osd_state *osd_device = disp_dev->osd_device;
1143	int err;
1144
1145	/* creating context for file descriptor */
1146	err = v4l2_fh_open(file);
1147	if (err) {
1148		v4l2_err(&vpbe_dev->v4l2_dev, "v4l2_fh_open failed\n");
1149		return err;
1150	}
1151
1152	/* leaving if layer is already initialized */
1153	if (!v4l2_fh_is_singular_file(file))
1154		return err;
1155
1156	if (!layer->usrs) {
1157		if (mutex_lock_interruptible(&layer->opslock))
1158			return -ERESTARTSYS;
1159		/* First claim the layer for this device */
1160		err = osd_device->ops.request_layer(osd_device,
1161						layer->layer_info.id);
1162		mutex_unlock(&layer->opslock);
1163		if (err < 0) {
1164			/* Couldn't get layer */
1165			v4l2_err(&vpbe_dev->v4l2_dev,
1166				"Display Manager failed to allocate layer\n");
1167			v4l2_fh_release(file);
1168			return -EINVAL;
1169		}
1170	}
1171	/* Increment layer usrs counter */
1172	layer->usrs++;
1173	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
1174			"vpbe display device opened successfully\n");
1175	return 0;
1176}
1177
1178/*
1179 * vpbe_display_release()
1180 * This function deletes buffer queue, frees the buffers and the davinci
1181 * display file * handle
1182 */
1183static int vpbe_display_release(struct file *file)
1184{
1185	struct vpbe_layer *layer = video_drvdata(file);
1186	struct osd_layer_config *cfg  = &layer->layer_info.config;
1187	struct vpbe_display *disp_dev = layer->disp_dev;
1188	struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
1189	struct osd_state *osd_device = disp_dev->osd_device;
1190
1191	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_release\n");
1192
1193	mutex_lock(&layer->opslock);
1194
1195	osd_device->ops.disable_layer(osd_device,
1196			layer->layer_info.id);
1197	/* Decrement layer usrs counter */
1198	layer->usrs--;
1199	/* If this file handle has initialize encoder device, reset it */
1200	if (!layer->usrs) {
1201		if (cfg->pixfmt == PIXFMT_NV12) {
1202			struct vpbe_layer *otherlayer;
1203			otherlayer =
1204			_vpbe_display_get_other_win_layer(disp_dev, layer);
1205			osd_device->ops.disable_layer(osd_device,
1206					otherlayer->layer_info.id);
1207			osd_device->ops.release_layer(osd_device,
1208					otherlayer->layer_info.id);
1209		}
1210		osd_device->ops.disable_layer(osd_device,
1211				layer->layer_info.id);
1212		osd_device->ops.release_layer(osd_device,
1213				layer->layer_info.id);
1214	}
1215
1216	_vb2_fop_release(file, NULL);
1217	mutex_unlock(&layer->opslock);
1218
1219	disp_dev->cbcr_ofst = 0;
1220
1221	return 0;
1222}
1223
1224/* vpbe capture ioctl operations */
1225static const struct v4l2_ioctl_ops vpbe_ioctl_ops = {
1226	.vidioc_querycap	 = vpbe_display_querycap,
1227	.vidioc_g_fmt_vid_out    = vpbe_display_g_fmt,
1228	.vidioc_enum_fmt_vid_out = vpbe_display_enum_fmt,
1229	.vidioc_s_fmt_vid_out    = vpbe_display_s_fmt,
1230	.vidioc_try_fmt_vid_out  = vpbe_display_try_fmt,
1231
1232	.vidioc_reqbufs		 = vb2_ioctl_reqbufs,
1233	.vidioc_create_bufs	 = vb2_ioctl_create_bufs,
1234	.vidioc_querybuf	 = vb2_ioctl_querybuf,
1235	.vidioc_qbuf		 = vb2_ioctl_qbuf,
1236	.vidioc_dqbuf		 = vb2_ioctl_dqbuf,
1237	.vidioc_streamon	 = vb2_ioctl_streamon,
1238	.vidioc_streamoff	 = vb2_ioctl_streamoff,
1239	.vidioc_expbuf		 = vb2_ioctl_expbuf,
1240
1241	.vidioc_g_pixelaspect	 = vpbe_display_g_pixelaspect,
1242	.vidioc_g_selection	 = vpbe_display_g_selection,
1243	.vidioc_s_selection	 = vpbe_display_s_selection,
1244
1245	.vidioc_s_std		 = vpbe_display_s_std,
1246	.vidioc_g_std		 = vpbe_display_g_std,
1247
1248	.vidioc_enum_output	 = vpbe_display_enum_output,
1249	.vidioc_s_output	 = vpbe_display_s_output,
1250	.vidioc_g_output	 = vpbe_display_g_output,
1251
1252	.vidioc_s_dv_timings	 = vpbe_display_s_dv_timings,
1253	.vidioc_g_dv_timings	 = vpbe_display_g_dv_timings,
1254	.vidioc_enum_dv_timings	 = vpbe_display_enum_dv_timings,
1255};
1256
1257static const struct v4l2_file_operations vpbe_fops = {
1258	.owner = THIS_MODULE,
1259	.open = vpbe_display_open,
1260	.release = vpbe_display_release,
1261	.unlocked_ioctl = video_ioctl2,
1262	.mmap = vb2_fop_mmap,
1263	.poll =  vb2_fop_poll,
1264};
1265
1266static int vpbe_device_get(struct device *dev, void *data)
1267{
1268	struct platform_device *pdev = to_platform_device(dev);
1269	struct vpbe_display *vpbe_disp  = data;
1270
1271	if (strcmp("vpbe_controller", pdev->name) == 0)
1272		vpbe_disp->vpbe_dev = platform_get_drvdata(pdev);
1273
1274	if (strstr(pdev->name, "vpbe-osd"))
1275		vpbe_disp->osd_device = platform_get_drvdata(pdev);
1276
1277	return 0;
1278}
1279
1280static int init_vpbe_layer(int i, struct vpbe_display *disp_dev,
1281			   struct platform_device *pdev)
1282{
1283	struct vpbe_layer *vpbe_display_layer = NULL;
1284	struct video_device *vbd = NULL;
1285
1286	/* Allocate memory for four plane display objects */
1287	disp_dev->dev[i] = kzalloc(sizeof(*disp_dev->dev[i]), GFP_KERNEL);
1288	if (!disp_dev->dev[i])
1289		return  -ENOMEM;
1290
1291	spin_lock_init(&disp_dev->dev[i]->irqlock);
1292	mutex_init(&disp_dev->dev[i]->opslock);
1293
1294	/* Get the pointer to the layer object */
1295	vpbe_display_layer = disp_dev->dev[i];
1296	vbd = &vpbe_display_layer->video_dev;
1297	/* Initialize field of video device */
1298	vbd->release	= video_device_release_empty;
1299	vbd->fops	= &vpbe_fops;
1300	vbd->ioctl_ops	= &vpbe_ioctl_ops;
1301	vbd->minor	= -1;
1302	vbd->v4l2_dev   = &disp_dev->vpbe_dev->v4l2_dev;
1303	vbd->lock	= &vpbe_display_layer->opslock;
1304	vbd->vfl_dir	= VFL_DIR_TX;
1305	vbd->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
1306
1307	if (disp_dev->vpbe_dev->current_timings.timings_type &
1308			VPBE_ENC_STD)
1309		vbd->tvnorms = (V4L2_STD_525_60 | V4L2_STD_625_50);
1310
1311	snprintf(vbd->name, sizeof(vbd->name),
1312			"DaVinci_VPBE Display_DRIVER_V%d.%d.%d",
1313			(VPBE_DISPLAY_VERSION_CODE >> 16) & 0xff,
1314			(VPBE_DISPLAY_VERSION_CODE >> 8) & 0xff,
1315			(VPBE_DISPLAY_VERSION_CODE) & 0xff);
1316
1317	vpbe_display_layer->device_id = i;
1318
1319	vpbe_display_layer->layer_info.id =
1320		((i == VPBE_DISPLAY_DEVICE_0) ? WIN_VID0 : WIN_VID1);
1321
1322
1323	return 0;
1324}
1325
1326static int register_device(struct vpbe_layer *vpbe_display_layer,
1327			   struct vpbe_display *disp_dev,
1328			   struct platform_device *pdev)
1329{
1330	int err;
1331
1332	v4l2_info(&disp_dev->vpbe_dev->v4l2_dev,
1333		  "Trying to register VPBE display device.\n");
1334	v4l2_info(&disp_dev->vpbe_dev->v4l2_dev,
1335		  "layer=%p,layer->video_dev=%p\n",
1336		  vpbe_display_layer,
1337		  &vpbe_display_layer->video_dev);
1338
1339	vpbe_display_layer->video_dev.queue = &vpbe_display_layer->buffer_queue;
1340	err = video_register_device(&vpbe_display_layer->video_dev,
1341				    VFL_TYPE_VIDEO,
1342				    -1);
1343	if (err)
1344		return -ENODEV;
1345
1346	vpbe_display_layer->disp_dev = disp_dev;
1347	/* set the driver data in platform device */
1348	platform_set_drvdata(pdev, disp_dev);
1349	video_set_drvdata(&vpbe_display_layer->video_dev,
1350			  vpbe_display_layer);
1351
1352	return 0;
1353}
1354
1355
1356
1357/*
1358 * vpbe_display_probe()
1359 * This function creates device entries by register itself to the V4L2 driver
1360 * and initializes fields of each layer objects
1361 */
1362static int vpbe_display_probe(struct platform_device *pdev)
1363{
1364	struct vpbe_display *disp_dev;
1365	struct v4l2_device *v4l2_dev;
1366	struct resource *res = NULL;
1367	struct vb2_queue *q;
1368	int k;
1369	int i;
1370	int err;
1371	int irq;
1372
1373	printk(KERN_DEBUG "vpbe_display_probe\n");
1374	/* Allocate memory for vpbe_display */
1375	disp_dev = devm_kzalloc(&pdev->dev, sizeof(*disp_dev), GFP_KERNEL);
1376	if (!disp_dev)
1377		return -ENOMEM;
1378
1379	spin_lock_init(&disp_dev->dma_queue_lock);
1380	/*
1381	 * Scan all the platform devices to find the vpbe
1382	 * controller device and get the vpbe_dev object
1383	 */
1384	err = bus_for_each_dev(&platform_bus_type, NULL, disp_dev,
1385			vpbe_device_get);
1386	if (err < 0)
1387		return err;
1388
1389	v4l2_dev = &disp_dev->vpbe_dev->v4l2_dev;
1390	/* Initialize the vpbe display controller */
1391	if (disp_dev->vpbe_dev->ops.initialize) {
1392		err = disp_dev->vpbe_dev->ops.initialize(&pdev->dev,
1393							 disp_dev->vpbe_dev);
1394		if (err) {
1395			v4l2_err(v4l2_dev, "Error initing vpbe\n");
1396			err = -ENOMEM;
1397			goto probe_out;
1398		}
1399	}
1400
1401	for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
1402		if (init_vpbe_layer(i, disp_dev, pdev)) {
1403			err = -ENODEV;
1404			goto probe_out;
1405		}
1406	}
1407
1408	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1409	if (!res) {
1410		v4l2_err(v4l2_dev, "Unable to get VENC interrupt resource\n");
1411		err = -ENODEV;
1412		goto probe_out;
1413	}
1414
1415	irq = res->start;
1416	err = devm_request_irq(&pdev->dev, irq, venc_isr, 0,
1417			       VPBE_DISPLAY_DRIVER, disp_dev);
1418	if (err) {
1419		v4l2_err(v4l2_dev, "VPBE IRQ request failed\n");
1420		goto probe_out;
1421	}
1422
1423	for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
1424		/* initialize vb2 queue */
1425		q = &disp_dev->dev[i]->buffer_queue;
1426		memset(q, 0, sizeof(*q));
1427		q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1428		q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
1429		q->drv_priv = disp_dev->dev[i];
1430		q->ops = &video_qops;
1431		q->mem_ops = &vb2_dma_contig_memops;
1432		q->buf_struct_size = sizeof(struct vpbe_disp_buffer);
1433		q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1434		q->min_buffers_needed = 1;
1435		q->lock = &disp_dev->dev[i]->opslock;
1436		q->dev = disp_dev->vpbe_dev->pdev;
1437		err = vb2_queue_init(q);
1438		if (err) {
1439			v4l2_err(v4l2_dev, "vb2_queue_init() failed\n");
1440			goto probe_out;
1441		}
1442
1443		INIT_LIST_HEAD(&disp_dev->dev[i]->dma_queue);
1444
1445		if (register_device(disp_dev->dev[i], disp_dev, pdev)) {
1446			err = -ENODEV;
1447			goto probe_out;
1448		}
1449	}
1450
1451	v4l2_dbg(1, debug, v4l2_dev,
1452		 "Successfully completed the probing of vpbe v4l2 device\n");
1453
1454	return 0;
1455
1456probe_out:
1457	for (k = 0; k < VPBE_DISPLAY_MAX_DEVICES; k++) {
1458		/* Unregister video device */
1459		if (disp_dev->dev[k]) {
1460			video_unregister_device(&disp_dev->dev[k]->video_dev);
1461			kfree(disp_dev->dev[k]);
1462		}
1463	}
1464	return err;
1465}
1466
1467/*
1468 * vpbe_display_remove()
1469 * It un-register hardware layer from V4L2 driver
1470 */
1471static int vpbe_display_remove(struct platform_device *pdev)
1472{
1473	struct vpbe_layer *vpbe_display_layer;
1474	struct vpbe_display *disp_dev = platform_get_drvdata(pdev);
1475	struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
1476	int i;
1477
1478	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_remove\n");
1479
1480	/* deinitialize the vpbe display controller */
1481	if (vpbe_dev->ops.deinitialize)
1482		vpbe_dev->ops.deinitialize(&pdev->dev, vpbe_dev);
1483	/* un-register device */
1484	for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
1485		/* Get the pointer to the layer object */
1486		vpbe_display_layer = disp_dev->dev[i];
1487		/* Unregister video device */
1488		video_unregister_device(&vpbe_display_layer->video_dev);
1489
1490	}
1491	for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
1492		kfree(disp_dev->dev[i]);
1493		disp_dev->dev[i] = NULL;
1494	}
1495
1496	return 0;
1497}
1498
1499static struct platform_driver vpbe_display_driver = {
1500	.driver = {
1501		.name = VPBE_DISPLAY_DRIVER,
1502		.bus = &platform_bus_type,
1503	},
1504	.probe = vpbe_display_probe,
1505	.remove = vpbe_display_remove,
1506};
1507
1508module_platform_driver(vpbe_display_driver);
1509
1510MODULE_DESCRIPTION("TI DM644x/DM355/DM365 VPBE Display controller");
1511MODULE_LICENSE("GPL");
1512MODULE_AUTHOR("Texas Instruments");
1513