• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd. */
3 
4 #include <media/v4l2-common.h>
5 #include <media/v4l2-ioctl.h>
6 #include <media/videobuf2-core.h>
7 #include <media/videobuf2-vmalloc.h>
8 #include <media/v4l2-event.h>
9 #include <media/v4l2-mc.h>
10 #include <linux/rkisp1-config.h>
11 #include <uapi/linux/rk-video-format.h>
12 #include "dev.h"
13 #include "regs.h"
14 
15 #define RKISP1_ISP_PARAMS_REQ_BUFS_MIN	2
16 #define RKISP1_ISP_PARAMS_REQ_BUFS_MAX	8
17 
rkispp_params_enum_fmt_meta_out(struct file * file,void * priv,struct v4l2_fmtdesc * f)18 static int rkispp_params_enum_fmt_meta_out(struct file *file, void *priv,
19 					   struct v4l2_fmtdesc *f)
20 {
21 	struct video_device *video = video_devdata(file);
22 	struct rkispp_params_vdev *params_vdev = video_get_drvdata(video);
23 
24 	if (f->index > 0 || f->type != video->queue->type)
25 		return -EINVAL;
26 
27 	f->pixelformat = params_vdev->vdev_fmt.fmt.meta.dataformat;
28 
29 	return 0;
30 }
31 
rkispp_params_g_fmt_meta_out(struct file * file,void * fh,struct v4l2_format * f)32 static int rkispp_params_g_fmt_meta_out(struct file *file, void *fh,
33 					struct v4l2_format *f)
34 {
35 	struct video_device *video = video_devdata(file);
36 	struct rkispp_params_vdev *params_vdev = video_get_drvdata(video);
37 	struct v4l2_meta_format *meta = &f->fmt.meta;
38 
39 	if (f->type != video->queue->type)
40 		return -EINVAL;
41 
42 	memset(meta, 0, sizeof(*meta));
43 	meta->dataformat = params_vdev->vdev_fmt.fmt.meta.dataformat;
44 	meta->buffersize = params_vdev->vdev_fmt.fmt.meta.buffersize;
45 
46 	return 0;
47 }
48 
rkispp_params_querycap(struct file * file,void * priv,struct v4l2_capability * cap)49 static int rkispp_params_querycap(struct file *file,
50 				  void *priv, struct v4l2_capability *cap)
51 {
52 	struct video_device *vdev = video_devdata(file);
53 	struct rkispp_params_vdev *params_vdev = video_get_drvdata(vdev);
54 
55 	snprintf(cap->driver, sizeof(cap->driver),
56 		 "%s_v%d", DRIVER_NAME,
57 		 params_vdev->dev->ispp_ver >> 4);
58 	strlcpy(cap->card, vdev->name, sizeof(cap->card));
59 	strlcpy(cap->bus_info, "platform: " DRIVER_NAME, sizeof(cap->bus_info));
60 
61 	return 0;
62 }
63 
rkispp_params_subs_evt(struct v4l2_fh * fh,const struct v4l2_event_subscription * sub)64 static int rkispp_params_subs_evt(struct v4l2_fh *fh,
65 				  const struct v4l2_event_subscription *sub)
66 {
67 	struct rkispp_params_vdev *params_vdev = video_get_drvdata(fh->vdev);
68 
69 	if (sub->id != 0)
70 		return -EINVAL;
71 
72 	switch (sub->type) {
73 	case CIFISP_V4L2_EVENT_STREAM_START:
74 	case CIFISP_V4L2_EVENT_STREAM_STOP:
75 		params_vdev->is_subs_evt = true;
76 		return v4l2_event_subscribe(fh, sub, 0, NULL);
77 	default:
78 		return -EINVAL;
79 	}
80 }
81 
rkispp_params_unsubs_evt(struct v4l2_fh * fh,const struct v4l2_event_subscription * sub)82 static int rkispp_params_unsubs_evt(struct v4l2_fh *fh,
83 				    const struct v4l2_event_subscription *sub)
84 {
85 	struct rkispp_params_vdev *params_vdev = video_get_drvdata(fh->vdev);
86 
87 	params_vdev->is_subs_evt = false;
88 	return v4l2_event_unsubscribe(fh, sub);
89 }
90 
91 static const struct v4l2_ioctl_ops rkispp_params_ioctl = {
92 	.vidioc_reqbufs = vb2_ioctl_reqbufs,
93 	.vidioc_querybuf = vb2_ioctl_querybuf,
94 	.vidioc_create_bufs = vb2_ioctl_create_bufs,
95 	.vidioc_qbuf = vb2_ioctl_qbuf,
96 	.vidioc_dqbuf = vb2_ioctl_dqbuf,
97 	.vidioc_prepare_buf = vb2_ioctl_prepare_buf,
98 	.vidioc_expbuf = vb2_ioctl_expbuf,
99 	.vidioc_streamon = vb2_ioctl_streamon,
100 	.vidioc_streamoff = vb2_ioctl_streamoff,
101 	.vidioc_enum_fmt_meta_out = rkispp_params_enum_fmt_meta_out,
102 	.vidioc_g_fmt_meta_out = rkispp_params_g_fmt_meta_out,
103 	.vidioc_s_fmt_meta_out = rkispp_params_g_fmt_meta_out,
104 	.vidioc_try_fmt_meta_out = rkispp_params_g_fmt_meta_out,
105 	.vidioc_querycap = rkispp_params_querycap,
106 	.vidioc_subscribe_event = rkispp_params_subs_evt,
107 	.vidioc_unsubscribe_event = rkispp_params_unsubs_evt,
108 };
109 
110 static int
rkispp_param_init_fecbuf(struct rkispp_params_vdev * params,struct rkispp_fecbuf_size * fecsize)111 rkispp_param_init_fecbuf(struct rkispp_params_vdev *params,
112 			 struct rkispp_fecbuf_size *fecsize)
113 {
114 	struct rkispp_device *pp_dev = params->dev;
115 	struct rkispp_fec_head *fec_data;
116 	u32 width, height, mesh_size, buf_size;
117 	int i, ret;
118 
119 	width = fecsize->meas_width;
120 	height = fecsize->meas_height;
121 	mesh_size = cal_fec_mesh(width, height, fecsize->meas_mode);
122 	buf_size = ALIGN(sizeof(struct rkispp_fec_head), 16);
123 	buf_size += 2 * (ALIGN(mesh_size * 2, 16) + ALIGN(mesh_size, 16));
124 
125 	params->buf_fec_idx = 0;
126 	for (i = 0; i < FEC_MESH_BUF_NUM; i++) {
127 		params->buf_fec[i].is_need_vaddr = true;
128 		params->buf_fec[i].is_need_dbuf = true;
129 		params->buf_fec[i].is_need_dmafd = true;
130 		params->buf_fec[i].size = PAGE_ALIGN(buf_size);
131 		ret = rkispp_allow_buffer(params->dev, &params->buf_fec[i]);
132 		if (ret) {
133 			dev_err(pp_dev->dev, "can not alloc fec buffer\n");
134 			return ret;
135 		}
136 
137 		fec_data = (struct rkispp_fec_head *)params->buf_fec[i].vaddr;
138 		fec_data->stat = FEC_BUF_INIT;
139 		fec_data->meshxf_oft = ALIGN(sizeof(struct rkispp_fec_head), 16);
140 		fec_data->meshyf_oft = fec_data->meshxf_oft + ALIGN(mesh_size, 16);
141 		fec_data->meshxi_oft = fec_data->meshyf_oft + ALIGN(mesh_size, 16);
142 		fec_data->meshyi_oft = fec_data->meshxi_oft + ALIGN(mesh_size * 2, 16);
143 
144 		if (!i) {
145 			u32 val, dma_addr = params->buf_fec[i].dma_addr;
146 
147 			val = dma_addr + fec_data->meshxf_oft;
148 			rkispp_write(pp_dev, RKISPP_FEC_MESH_XFRA_BASE, val);
149 			val = dma_addr + fec_data->meshyf_oft;
150 			rkispp_write(pp_dev, RKISPP_FEC_MESH_YFRA_BASE, val);
151 			val = dma_addr + fec_data->meshxi_oft;
152 			rkispp_write(pp_dev, RKISPP_FEC_MESH_XINT_BASE, val);
153 			val = dma_addr + fec_data->meshyi_oft;
154 			rkispp_write(pp_dev, RKISPP_FEC_MESH_YINT_BASE, val);
155 		}
156 		v4l2_dbg(1, rkispp_debug, &pp_dev->v4l2_dev,
157 			 "%s idx:%d fd:%d dma:%pad offset xf:0x%x yf:0x%x xi:0x%x yi:0x%x\n",
158 			 __func__, i, params->buf_fec[i].dma_fd, &params->buf_fec[i].dma_addr,
159 			 fec_data->meshxf_oft, fec_data->meshyf_oft,
160 			 fec_data->meshxi_oft, fec_data->meshyi_oft);
161 	}
162 
163 	return 0;
164 }
165 
166 static void
rkispp_param_deinit_fecbuf(struct rkispp_params_vdev * params)167 rkispp_param_deinit_fecbuf(struct rkispp_params_vdev *params)
168 {
169 	int i;
170 
171 	params->buf_fec_idx = 0;
172 	for (i = 0; i < FEC_MESH_BUF_NUM; i++)
173 		rkispp_free_buffer(params->dev, &params->buf_fec[i]);
174 }
175 
rkispp_params_vb2_queue_setup(struct vb2_queue * vq,unsigned int * num_buffers,unsigned int * num_planes,unsigned int sizes[],struct device * alloc_ctxs[])176 static int rkispp_params_vb2_queue_setup(struct vb2_queue *vq,
177 					 unsigned int *num_buffers,
178 					 unsigned int *num_planes,
179 					 unsigned int sizes[],
180 					 struct device *alloc_ctxs[])
181 {
182 	struct rkispp_params_vdev *params_vdev = vq->drv_priv;
183 	struct rkispp_device *dev = params_vdev->dev;
184 
185 	*num_buffers = clamp_t(u32, *num_buffers,
186 			       RKISP1_ISP_PARAMS_REQ_BUFS_MIN,
187 			       RKISP1_ISP_PARAMS_REQ_BUFS_MAX);
188 
189 	*num_planes = 1;
190 	if (dev->ispp_ver == ISPP_V10)
191 		sizes[0] = sizeof(struct rkispp_params_cfg);
192 	else if (dev->ispp_ver == ISPP_V20)
193 		sizes[0] = sizeof(struct fec_params_cfg);
194 
195 	INIT_LIST_HEAD(&params_vdev->params);
196 	params_vdev->first_params = true;
197 
198 	return 0;
199 }
200 
rkispp_params_vb2_buf_queue(struct vb2_buffer * vb)201 static void rkispp_params_vb2_buf_queue(struct vb2_buffer *vb)
202 {
203 	struct vb2_queue *vq = vb->vb2_queue;
204 	struct rkispp_params_vdev *params_vdev = vq->drv_priv;
205 
206 	params_vdev->params_ops->rkispp_params_vb2_buf_queue(vb);
207 }
208 
rkispp_params_vb2_stop_streaming(struct vb2_queue * vq)209 static void rkispp_params_vb2_stop_streaming(struct vb2_queue *vq)
210 {
211 	struct rkispp_params_vdev *params_vdev = vq->drv_priv;
212 	struct rkispp_buffer *buf;
213 	unsigned long flags;
214 	int i;
215 
216 	/* stop params input firstly */
217 	spin_lock_irqsave(&params_vdev->config_lock, flags);
218 	params_vdev->streamon = false;
219 	wake_up(&params_vdev->dev->sync_onoff);
220 	spin_unlock_irqrestore(&params_vdev->config_lock, flags);
221 
222 	for (i = 0; i < RKISP1_ISP_PARAMS_REQ_BUFS_MAX; i++) {
223 		spin_lock_irqsave(&params_vdev->config_lock, flags);
224 		if (!list_empty(&params_vdev->params)) {
225 			buf = list_first_entry(&params_vdev->params,
226 					       struct rkispp_buffer, queue);
227 			list_del(&buf->queue);
228 			spin_unlock_irqrestore(&params_vdev->config_lock,
229 					       flags);
230 		} else {
231 			spin_unlock_irqrestore(&params_vdev->config_lock,
232 					       flags);
233 			break;
234 		}
235 
236 		if (buf)
237 			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
238 		buf = NULL;
239 	}
240 
241 	if (params_vdev->cur_buf) {
242 		vb2_buffer_done(&params_vdev->cur_buf->vb.vb2_buf,
243 				VB2_BUF_STATE_ERROR);
244 		params_vdev->cur_buf = NULL;
245 	}
246 
247 	/* clean module params */
248 	params_vdev->cur_params->module_cfg_update = 0;
249 	params_vdev->cur_params->module_en_update = 0;
250 }
251 
252 static int
rkispp_params_vb2_start_streaming(struct vb2_queue * queue,unsigned int count)253 rkispp_params_vb2_start_streaming(struct vb2_queue *queue, unsigned int count)
254 {
255 	struct rkispp_params_vdev *params_vdev = queue->drv_priv;
256 	unsigned long flags;
257 
258 	spin_lock_irqsave(&params_vdev->config_lock, flags);
259 	params_vdev->streamon = true;
260 	spin_unlock_irqrestore(&params_vdev->config_lock, flags);
261 
262 	return 0;
263 }
264 
265 static int
rkispp_param_fh_open(struct file * filp)266 rkispp_param_fh_open(struct file *filp)
267 {
268 	struct rkispp_params_vdev *params = video_drvdata(filp);
269 	struct rkispp_device *isppdev = params->dev;
270 	int ret;
271 
272 	ret = v4l2_fh_open(filp);
273 	if (!ret) {
274 		ret = v4l2_pipeline_pm_get(&params->vnode.vdev.entity);
275 		if (ret < 0) {
276 			v4l2_err(&isppdev->v4l2_dev,
277 				 "pipeline power on failed %d\n", ret);
278 			goto ERR;
279 		}
280 	}
281 
282 	return 0;
283 
284 ERR:
285 	vb2_fop_release(filp);
286 	return ret;
287 }
288 
289 static int
rkispp_param_fh_release(struct file * filp)290 rkispp_param_fh_release(struct file *filp)
291 {
292 	struct rkispp_params_vdev *params = video_drvdata(filp);
293 	struct video_device *vdev = video_devdata(filp);
294 	int ret;
295 
296 	if (filp->private_data == vdev->queue->owner)
297 		rkispp_param_deinit_fecbuf(params);
298 
299 	ret = vb2_fop_release(filp);
300 	if (!ret)
301 		v4l2_pipeline_pm_put(&params->vnode.vdev.entity);
302 	return ret;
303 }
304 
305 static struct vb2_ops rkispp_params_vb2_ops = {
306 	.queue_setup = rkispp_params_vb2_queue_setup,
307 	.wait_prepare = vb2_ops_wait_prepare,
308 	.wait_finish = vb2_ops_wait_finish,
309 	.buf_queue = rkispp_params_vb2_buf_queue,
310 	.start_streaming = rkispp_params_vb2_start_streaming,
311 	.stop_streaming = rkispp_params_vb2_stop_streaming,
312 
313 };
314 
315 struct v4l2_file_operations rkispp_params_fops = {
316 	.mmap = vb2_fop_mmap,
317 	.unlocked_ioctl = video_ioctl2,
318 	.poll = vb2_fop_poll,
319 	.open = rkispp_param_fh_open,
320 	.release = rkispp_param_fh_release,
321 };
322 
323 static int
rkispp_params_init_vb2_queue(struct vb2_queue * q,struct rkispp_params_vdev * params_vdev)324 rkispp_params_init_vb2_queue(struct vb2_queue *q,
325 			     struct rkispp_params_vdev *params_vdev)
326 {
327 	q->type = V4L2_BUF_TYPE_META_OUTPUT;
328 	q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_USERPTR;
329 	q->drv_priv = params_vdev;
330 	q->ops = &rkispp_params_vb2_ops;
331 	q->mem_ops = &vb2_vmalloc_memops;
332 	q->buf_struct_size = sizeof(struct rkispp_buffer);
333 	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
334 	q->lock = &params_vdev->dev->iqlock;
335 	q->dev = params_vdev->dev->hw_dev->dev;
336 
337 	return vb2_queue_init(q);
338 }
339 
rkispp_params_get_fecbuf_inf(struct rkispp_params_vdev * params_vdev,struct rkispp_fecbuf_info * fecbuf)340 void rkispp_params_get_fecbuf_inf(struct rkispp_params_vdev *params_vdev,
341 				  struct rkispp_fecbuf_info *fecbuf)
342 {
343 	int i;
344 
345 	for (i = 0; i < FEC_MESH_BUF_NUM; i++) {
346 		fecbuf->buf_fd[i] = params_vdev->buf_fec[i].dma_fd;
347 		fecbuf->buf_size[i] = params_vdev->buf_fec[i].size;
348 	}
349 }
350 
rkispp_params_set_fecbuf_size(struct rkispp_params_vdev * params_vdev,struct rkispp_fecbuf_size * fecsize)351 void rkispp_params_set_fecbuf_size(struct rkispp_params_vdev *params_vdev,
352 				   struct rkispp_fecbuf_size *fecsize)
353 {
354 	rkispp_param_deinit_fecbuf(params_vdev);
355 	rkispp_param_init_fecbuf(params_vdev, fecsize);
356 }
357 
rkispp_register_params_vdev(struct rkispp_device * dev)358 int rkispp_register_params_vdev(struct rkispp_device *dev)
359 {
360 	struct rkispp_params_vdev *params_vdev = &dev->params_vdev;
361 	struct rkispp_vdev_node *node = &params_vdev->vnode;
362 	struct video_device *vdev = &node->vdev;
363 	int ret;
364 
365 	params_vdev->dev = dev;
366 	params_vdev->is_subs_evt = false;
367 	params_vdev->cur_params = vmalloc(sizeof(*params_vdev->cur_params));
368 	if (!params_vdev->cur_params)
369 		return -ENOMEM;
370 
371 	params_vdev->cur_params->module_cfg_update = 0;
372 	params_vdev->cur_params->module_en_update = 0;
373 	if (dev->ispp_ver == ISPP_V10)
374 		rkispp_params_init_ops_v10(params_vdev);
375 	if (dev->ispp_ver == ISPP_V20)
376 		rkispp_params_init_ops_v20(params_vdev);
377 	spin_lock_init(&params_vdev->config_lock);
378 	strlcpy(vdev->name, "rkispp_input_params", sizeof(vdev->name));
379 
380 	video_set_drvdata(vdev, params_vdev);
381 	vdev->ioctl_ops = &rkispp_params_ioctl;
382 	vdev->fops = &rkispp_params_fops;
383 	vdev->release = video_device_release_empty;
384 	/*
385 	 * Provide a mutex to v4l2 core. It will be used
386 	 * to protect all fops and v4l2 ioctls.
387 	 */
388 	vdev->lock = &dev->iqlock;
389 	vdev->v4l2_dev = &dev->v4l2_dev;
390 	vdev->queue = &node->buf_queue;
391 	vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_OUTPUT;
392 	vdev->vfl_dir = VFL_DIR_TX;
393 	rkispp_params_init_vb2_queue(vdev->queue, params_vdev);
394 	params_vdev->vdev_fmt.fmt.meta.dataformat =
395 		V4L2_META_FMT_RK_ISPP_PARAMS;
396 
397 	node->pad.flags = MEDIA_PAD_FL_SOURCE;
398 	ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);
399 	if (ret < 0)
400 		goto err_release_queue;
401 	ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
402 	if (ret < 0) {
403 		dev_err(&vdev->dev,
404 			"could not register Video for Linux device\n");
405 		goto err_cleanup_media_entity;
406 	}
407 	return 0;
408 
409 err_cleanup_media_entity:
410 	media_entity_cleanup(&vdev->entity);
411 err_release_queue:
412 	vb2_queue_release(vdev->queue);
413 
414 	return ret;
415 }
416 
rkispp_unregister_params_vdev(struct rkispp_device * dev)417 void rkispp_unregister_params_vdev(struct rkispp_device *dev)
418 {
419 	struct rkispp_params_vdev *params_vdev = &dev->params_vdev;
420 	struct rkispp_vdev_node *node = &params_vdev->vnode;
421 	struct video_device *vdev = &node->vdev;
422 
423 	video_unregister_device(vdev);
424 	media_entity_cleanup(&vdev->entity);
425 	vb2_queue_release(vdev->queue);
426 	vfree(params_vdev->cur_params);
427 }
428