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, ¶ms->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, ¶ms->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, ¶ms->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(¶ms_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(¶ms_vdev->config_lock, flags);
218 params_vdev->streamon = false;
219 wake_up(¶ms_vdev->dev->sync_onoff);
220 spin_unlock_irqrestore(¶ms_vdev->config_lock, flags);
221
222 for (i = 0; i < RKISP1_ISP_PARAMS_REQ_BUFS_MAX; i++) {
223 spin_lock_irqsave(¶ms_vdev->config_lock, flags);
224 if (!list_empty(¶ms_vdev->params)) {
225 buf = list_first_entry(¶ms_vdev->params,
226 struct rkispp_buffer, queue);
227 list_del(&buf->queue);
228 spin_unlock_irqrestore(¶ms_vdev->config_lock,
229 flags);
230 } else {
231 spin_unlock_irqrestore(¶ms_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(¶ms_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(¶ms_vdev->config_lock, flags);
259 params_vdev->streamon = true;
260 spin_unlock_irqrestore(¶ms_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(¶ms->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(¶ms->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 = ¶ms_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 = ¶ms_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(¶ms_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 = ¶ms_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