xref: /OK3568_Linux_fs/kernel/drivers/media/platform/rockchip/ispp/params.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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/rk-isp1-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 	if (fecsize->buf_cnt > FEC_MESH_BUF_MAX)
126 		params->buf_cnt = FEC_MESH_BUF_MAX;
127 	else if (fecsize->buf_cnt > 0)
128 		params->buf_cnt = fecsize->buf_cnt;
129 	else
130 		params->buf_cnt = FEC_MESH_BUF_NUM;
131 
132 	params->buf_fec_idx = 0;
133 	for (i = 0; i < params->buf_cnt; i++) {
134 		params->buf_fec[i].is_need_vaddr = true;
135 		params->buf_fec[i].is_need_dbuf = true;
136 		params->buf_fec[i].is_need_dmafd = true;
137 		params->buf_fec[i].size = PAGE_ALIGN(buf_size);
138 		ret = rkispp_allow_buffer(params->dev, &params->buf_fec[i]);
139 		if (ret) {
140 			dev_err(pp_dev->dev, "can not alloc fec buffer\n");
141 			return ret;
142 		}
143 
144 		fec_data = (struct rkispp_fec_head *)params->buf_fec[i].vaddr;
145 		fec_data->stat = FEC_BUF_INIT;
146 		fec_data->meshxf_oft = ALIGN(sizeof(struct rkispp_fec_head), 16);
147 		fec_data->meshyf_oft = fec_data->meshxf_oft + ALIGN(mesh_size, 16);
148 		fec_data->meshxi_oft = fec_data->meshyf_oft + ALIGN(mesh_size, 16);
149 		fec_data->meshyi_oft = fec_data->meshxi_oft + ALIGN(mesh_size * 2, 16);
150 
151 		if (!i) {
152 			u32 val, dma_addr = params->buf_fec[i].dma_addr;
153 
154 			val = dma_addr + fec_data->meshxf_oft;
155 			rkispp_write(pp_dev, RKISPP_FEC_MESH_XFRA_BASE, val);
156 			val = dma_addr + fec_data->meshyf_oft;
157 			rkispp_write(pp_dev, RKISPP_FEC_MESH_YFRA_BASE, val);
158 			val = dma_addr + fec_data->meshxi_oft;
159 			rkispp_write(pp_dev, RKISPP_FEC_MESH_XINT_BASE, val);
160 			val = dma_addr + fec_data->meshyi_oft;
161 			rkispp_write(pp_dev, RKISPP_FEC_MESH_YINT_BASE, val);
162 		}
163 		v4l2_dbg(1, rkispp_debug, &pp_dev->v4l2_dev,
164 			 "%s idx:%d fd:%d dma:%pad offset xf:0x%x yf:0x%x xi:0x%x yi:0x%x\n",
165 			 __func__, i, params->buf_fec[i].dma_fd, &params->buf_fec[i].dma_addr,
166 			 fec_data->meshxf_oft, fec_data->meshyf_oft,
167 			 fec_data->meshxi_oft, fec_data->meshyi_oft);
168 	}
169 
170 	return 0;
171 }
172 
173 static void
rkispp_param_deinit_fecbuf(struct rkispp_params_vdev * params)174 rkispp_param_deinit_fecbuf(struct rkispp_params_vdev *params)
175 {
176 	int i;
177 
178 	params->buf_fec_idx = 0;
179 	for (i = 0; i < FEC_MESH_BUF_MAX; i++)
180 		rkispp_free_buffer(params->dev, &params->buf_fec[i]);
181 }
182 
rkispp_params_vb2_queue_setup(struct vb2_queue * vq,unsigned int * num_buffers,unsigned int * num_planes,unsigned int sizes[],struct device * alloc_ctxs[])183 static int rkispp_params_vb2_queue_setup(struct vb2_queue *vq,
184 					 unsigned int *num_buffers,
185 					 unsigned int *num_planes,
186 					 unsigned int sizes[],
187 					 struct device *alloc_ctxs[])
188 {
189 	struct rkispp_params_vdev *params_vdev = vq->drv_priv;
190 	struct rkispp_device *dev = params_vdev->dev;
191 
192 	*num_buffers = clamp_t(u32, *num_buffers,
193 			       RKISP1_ISP_PARAMS_REQ_BUFS_MIN,
194 			       RKISP1_ISP_PARAMS_REQ_BUFS_MAX);
195 
196 	*num_planes = 1;
197 	if (dev->ispp_ver == ISPP_V10) {
198 		switch (params_vdev->vdev_id) {
199 		case PARAM_VDEV_TNR:
200 			sizes[0] = sizeof(struct rkispp_params_tnrcfg);
201 			break;
202 		case PARAM_VDEV_NR:
203 			sizes[0] = sizeof(struct rkispp_params_nrcfg);
204 			break;
205 		case PARAM_VDEV_FEC:
206 		default:
207 			sizes[0] = sizeof(struct rkispp_params_feccfg);
208 			break;
209 		}
210 	} else if (dev->ispp_ver == ISPP_V20) {
211 		sizes[0] = sizeof(struct fec_params_cfg);
212 	}
213 
214 	INIT_LIST_HEAD(&params_vdev->params);
215 	params_vdev->first_params = true;
216 
217 	return 0;
218 }
219 
rkispp_params_vb2_buf_queue(struct vb2_buffer * vb)220 static void rkispp_params_vb2_buf_queue(struct vb2_buffer *vb)
221 {
222 	struct vb2_queue *vq = vb->vb2_queue;
223 	struct rkispp_params_vdev *params_vdev = vq->drv_priv;
224 
225 	params_vdev->params_ops->rkispp_params_vb2_buf_queue(vb);
226 }
227 
rkispp_params_vb2_stop_streaming(struct vb2_queue * vq)228 static void rkispp_params_vb2_stop_streaming(struct vb2_queue *vq)
229 {
230 	struct rkispp_params_vdev *params_vdev = vq->drv_priv;
231 	struct rkispp_buffer *buf;
232 	unsigned long flags;
233 	int i;
234 
235 	/* stop params input firstly */
236 	spin_lock_irqsave(&params_vdev->config_lock, flags);
237 	params_vdev->streamon = false;
238 	wake_up(&params_vdev->dev->sync_onoff);
239 	spin_unlock_irqrestore(&params_vdev->config_lock, flags);
240 
241 	for (i = 0; i < RKISP1_ISP_PARAMS_REQ_BUFS_MAX; i++) {
242 		spin_lock_irqsave(&params_vdev->config_lock, flags);
243 		if (!list_empty(&params_vdev->params)) {
244 			buf = list_first_entry(&params_vdev->params,
245 					       struct rkispp_buffer, queue);
246 			list_del(&buf->queue);
247 			spin_unlock_irqrestore(&params_vdev->config_lock,
248 					       flags);
249 		} else {
250 			spin_unlock_irqrestore(&params_vdev->config_lock,
251 					       flags);
252 			break;
253 		}
254 
255 		if (buf)
256 			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
257 		buf = NULL;
258 	}
259 
260 	if (params_vdev->cur_buf) {
261 		vb2_buffer_done(&params_vdev->cur_buf->vb.vb2_buf,
262 				VB2_BUF_STATE_ERROR);
263 		params_vdev->cur_buf = NULL;
264 	}
265 }
266 
267 static int
rkispp_params_vb2_start_streaming(struct vb2_queue * queue,unsigned int count)268 rkispp_params_vb2_start_streaming(struct vb2_queue *queue, unsigned int count)
269 {
270 	struct rkispp_params_vdev *params_vdev = queue->drv_priv;
271 	unsigned long flags;
272 
273 	spin_lock_irqsave(&params_vdev->config_lock, flags);
274 	params_vdev->streamon = true;
275 	spin_unlock_irqrestore(&params_vdev->config_lock, flags);
276 
277 	return 0;
278 }
279 
280 static int
rkispp_param_fh_open(struct file * filp)281 rkispp_param_fh_open(struct file *filp)
282 {
283 	struct rkispp_params_vdev *params = video_drvdata(filp);
284 	struct rkispp_device *isppdev = params->dev;
285 	int ret;
286 
287 	ret = v4l2_fh_open(filp);
288 	if (!ret) {
289 		ret = v4l2_pipeline_pm_get(&params->vnode.vdev.entity);
290 		if (ret < 0) {
291 			v4l2_err(&isppdev->v4l2_dev,
292 				 "pipeline power on failed %d\n", ret);
293 			goto ERR;
294 		}
295 	}
296 
297 	return 0;
298 
299 ERR:
300 	vb2_fop_release(filp);
301 	return ret;
302 }
303 
304 static int
rkispp_param_fh_release(struct file * filp)305 rkispp_param_fh_release(struct file *filp)
306 {
307 	struct rkispp_params_vdev *params = video_drvdata(filp);
308 	struct video_device *vdev = video_devdata(filp);
309 	int ret;
310 
311 	if (filp->private_data == vdev->queue->owner)
312 		rkispp_param_deinit_fecbuf(params);
313 
314 	ret = vb2_fop_release(filp);
315 	if (!ret)
316 		v4l2_pipeline_pm_put(&params->vnode.vdev.entity);
317 	return ret;
318 }
319 
320 static struct vb2_ops rkispp_params_vb2_ops = {
321 	.queue_setup = rkispp_params_vb2_queue_setup,
322 	.wait_prepare = vb2_ops_wait_prepare,
323 	.wait_finish = vb2_ops_wait_finish,
324 	.buf_queue = rkispp_params_vb2_buf_queue,
325 	.start_streaming = rkispp_params_vb2_start_streaming,
326 	.stop_streaming = rkispp_params_vb2_stop_streaming,
327 };
328 
329 struct v4l2_file_operations rkispp_params_fops = {
330 	.mmap = vb2_fop_mmap,
331 	.unlocked_ioctl = video_ioctl2,
332 	.poll = vb2_fop_poll,
333 	.open = rkispp_param_fh_open,
334 	.release = rkispp_param_fh_release,
335 };
336 
337 static int
rkispp_params_init_vb2_queue(struct vb2_queue * q,struct rkispp_params_vdev * params_vdev)338 rkispp_params_init_vb2_queue(struct vb2_queue *q,
339 			     struct rkispp_params_vdev *params_vdev)
340 {
341 	q->type = V4L2_BUF_TYPE_META_OUTPUT;
342 	q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_USERPTR;
343 	q->drv_priv = params_vdev;
344 	q->ops = &rkispp_params_vb2_ops;
345 	q->mem_ops = &vb2_vmalloc_memops;
346 	q->buf_struct_size = sizeof(struct rkispp_buffer);
347 	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
348 	q->lock = &params_vdev->dev->iqlock;
349 	q->dev = params_vdev->dev->hw_dev->dev;
350 
351 	return vb2_queue_init(q);
352 }
353 
rkispp_params_get_fecbuf_inf(struct rkispp_params_vdev * params_vdev,struct rkispp_fecbuf_info * fecbuf)354 void rkispp_params_get_fecbuf_inf(struct rkispp_params_vdev *params_vdev,
355 				  struct rkispp_fecbuf_info *fecbuf)
356 {
357 	int i;
358 
359 	if (params_vdev->vdev_id != PARAM_VDEV_FEC)
360 		return;
361 
362 	for (i = 0; i < FEC_MESH_BUF_MAX; i++) {
363 		fecbuf->buf_fd[i] = -1;
364 		fecbuf->buf_size[i] = 0;
365 	}
366 
367 	for (i = 0; i < params_vdev->buf_cnt; i++) {
368 		fecbuf->buf_fd[i] = params_vdev->buf_fec[i].dma_fd;
369 		fecbuf->buf_size[i] = params_vdev->buf_fec[i].size;
370 	}
371 }
372 
rkispp_params_set_fecbuf_size(struct rkispp_params_vdev * params_vdev,struct rkispp_fecbuf_size * fecsize)373 void rkispp_params_set_fecbuf_size(struct rkispp_params_vdev *params_vdev,
374 				   struct rkispp_fecbuf_size *fecsize)
375 {
376 	if (params_vdev->vdev_id != PARAM_VDEV_FEC)
377 		return;
378 
379 	rkispp_param_deinit_fecbuf(params_vdev);
380 	rkispp_param_init_fecbuf(params_vdev, fecsize);
381 }
382 
rkispp_register_params_vdev(struct rkispp_device * dev,enum rkispp_paramvdev_id vdev_id)383 static int rkispp_register_params_vdev(struct rkispp_device *dev,
384 				       enum rkispp_paramvdev_id vdev_id)
385 {
386 	struct rkispp_params_vdev *params_vdev = &dev->params_vdev[vdev_id];
387 	struct rkispp_vdev_node *node = &params_vdev->vnode;
388 	struct video_device *vdev = &node->vdev;
389 	int ret;
390 
391 	params_vdev->dev = dev;
392 	params_vdev->is_subs_evt = false;
393 	params_vdev->vdev_id = vdev_id;
394 
395 	if (dev->ispp_ver == ISPP_V10)
396 		rkispp_params_init_ops_v10(params_vdev);
397 	if (dev->ispp_ver == ISPP_V20)
398 		rkispp_params_init_ops_v20(params_vdev);
399 	spin_lock_init(&params_vdev->config_lock);
400 	switch (vdev_id) {
401 	case PARAM_VDEV_TNR:
402 		strncpy(vdev->name, "rkispp_tnr_params", sizeof(vdev->name) - 1);
403 		break;
404 	case PARAM_VDEV_NR:
405 		strncpy(vdev->name, "rkispp_nr_params", sizeof(vdev->name) - 1);
406 		break;
407 	case PARAM_VDEV_FEC:
408 	default:
409 		params_vdev->buf_cnt = FEC_MESH_BUF_NUM;
410 		strncpy(vdev->name, "rkispp_fec_params", sizeof(vdev->name) - 1);
411 		break;
412 	}
413 
414 	video_set_drvdata(vdev, params_vdev);
415 	vdev->ioctl_ops = &rkispp_params_ioctl;
416 	vdev->fops = &rkispp_params_fops;
417 	vdev->release = video_device_release_empty;
418 	/*
419 	 * Provide a mutex to v4l2 core. It will be used
420 	 * to protect all fops and v4l2 ioctls.
421 	 */
422 	vdev->lock = &dev->iqlock;
423 	vdev->v4l2_dev = &dev->v4l2_dev;
424 	vdev->queue = &node->buf_queue;
425 	vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_OUTPUT;
426 	vdev->vfl_dir = VFL_DIR_TX;
427 	rkispp_params_init_vb2_queue(vdev->queue, params_vdev);
428 	params_vdev->vdev_fmt.fmt.meta.dataformat =
429 		V4L2_META_FMT_RK_ISPP_PARAMS;
430 
431 	node->pad.flags = MEDIA_PAD_FL_SOURCE;
432 	ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);
433 	if (ret < 0)
434 		goto err_release_queue;
435 	ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
436 	if (ret < 0) {
437 		dev_err(&vdev->dev,
438 			"could not register Video for Linux device\n");
439 		goto err_cleanup_media_entity;
440 	}
441 	return 0;
442 
443 err_cleanup_media_entity:
444 	media_entity_cleanup(&vdev->entity);
445 err_release_queue:
446 	vb2_queue_release(vdev->queue);
447 
448 	return ret;
449 }
450 
rkispp_unregister_params_vdev(struct rkispp_device * dev,enum rkispp_paramvdev_id vdev_id)451 static void rkispp_unregister_params_vdev(struct rkispp_device *dev,
452 					  enum rkispp_paramvdev_id vdev_id)
453 {
454 	struct rkispp_params_vdev *params_vdev = &dev->params_vdev[vdev_id];
455 	struct rkispp_vdev_node *node = &params_vdev->vnode;
456 	struct video_device *vdev = &node->vdev;
457 
458 	video_unregister_device(vdev);
459 	media_entity_cleanup(&vdev->entity);
460 	vb2_queue_release(vdev->queue);
461 }
462 
rkispp_register_params_vdevs(struct rkispp_device * dev)463 int rkispp_register_params_vdevs(struct rkispp_device *dev)
464 {
465 	int ret = 0;
466 
467 	ret = rkispp_register_params_vdev(dev, PARAM_VDEV_FEC);
468 	if (ret)
469 		return ret;
470 
471 	if (dev->ispp_ver == ISPP_V10) {
472 		ret = rkispp_register_params_vdev(dev, PARAM_VDEV_TNR);
473 		if (ret) {
474 			rkispp_unregister_params_vdev(dev, PARAM_VDEV_FEC);
475 			return ret;
476 		}
477 
478 		ret = rkispp_register_params_vdev(dev, PARAM_VDEV_NR);
479 		if (ret) {
480 			rkispp_unregister_params_vdev(dev, PARAM_VDEV_FEC);
481 			rkispp_unregister_params_vdev(dev, PARAM_VDEV_TNR);
482 			return ret;
483 		}
484 	}
485 
486 	return ret;
487 }
488 
rkispp_unregister_params_vdevs(struct rkispp_device * dev)489 void rkispp_unregister_params_vdevs(struct rkispp_device *dev)
490 {
491 	rkispp_unregister_params_vdev(dev, PARAM_VDEV_FEC);
492 	if (dev->ispp_ver == ISPP_V10) {
493 		rkispp_unregister_params_vdev(dev, PARAM_VDEV_TNR);
494 		rkispp_unregister_params_vdev(dev, PARAM_VDEV_NR);
495 	}
496 }
497