Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph...
[cascardo/linux.git] / drivers / media / platform / vsp1 / vsp1_drm.c
1 /*
2  * vsp1_drm.c  --  R-Car VSP1 DRM API
3  *
4  * Copyright (C) 2015 Renesas Electronics Corporation
5  *
6  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  */
13
14 #include <linux/device.h>
15 #include <linux/slab.h>
16
17 #include <media/media-entity.h>
18 #include <media/v4l2-subdev.h>
19 #include <media/vsp1.h>
20
21 #include "vsp1.h"
22 #include "vsp1_bru.h"
23 #include "vsp1_dl.h"
24 #include "vsp1_drm.h"
25 #include "vsp1_lif.h"
26 #include "vsp1_pipe.h"
27 #include "vsp1_rwpf.h"
28
29
30 /* -----------------------------------------------------------------------------
31  * Interrupt Handling
32  */
33
34 void vsp1_drm_display_start(struct vsp1_device *vsp1)
35 {
36         vsp1_dlm_irq_display_start(vsp1->drm->pipe.output->dlm);
37 }
38
39 /* -----------------------------------------------------------------------------
40  * DU Driver API
41  */
42
43 int vsp1_du_init(struct device *dev)
44 {
45         struct vsp1_device *vsp1 = dev_get_drvdata(dev);
46
47         if (!vsp1)
48                 return -EPROBE_DEFER;
49
50         return 0;
51 }
52 EXPORT_SYMBOL_GPL(vsp1_du_init);
53
54 /**
55  * vsp1_du_setup_lif - Setup the output part of the VSP pipeline
56  * @dev: the VSP device
57  * @width: output frame width in pixels
58  * @height: output frame height in pixels
59  *
60  * Configure the output part of VSP DRM pipeline for the given frame @width and
61  * @height. This sets up formats on the BRU source pad, the WPF0 sink and source
62  * pads, and the LIF sink pad.
63  *
64  * As the media bus code on the BRU source pad is conditioned by the
65  * configuration of the BRU sink 0 pad, we also set up the formats on all BRU
66  * sinks, even if the configuration will be overwritten later by
67  * vsp1_du_setup_rpf(). This ensures that the BRU configuration is set to a well
68  * defined state.
69  *
70  * Return 0 on success or a negative error code on failure.
71  */
72 int vsp1_du_setup_lif(struct device *dev, unsigned int width,
73                       unsigned int height)
74 {
75         struct vsp1_device *vsp1 = dev_get_drvdata(dev);
76         struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
77         struct vsp1_bru *bru = vsp1->bru;
78         struct v4l2_subdev_format format;
79         unsigned int i;
80         int ret;
81
82         dev_dbg(vsp1->dev, "%s: configuring LIF with format %ux%u\n",
83                 __func__, width, height);
84
85         if (width == 0 || height == 0) {
86                 /* Zero width or height means the CRTC is being disabled, stop
87                  * the pipeline and turn the light off.
88                  */
89                 ret = vsp1_pipeline_stop(pipe);
90                 if (ret == -ETIMEDOUT)
91                         dev_err(vsp1->dev, "DRM pipeline stop timeout\n");
92
93                 media_entity_pipeline_stop(&pipe->output->entity.subdev.entity);
94
95                 for (i = 0; i < bru->entity.source_pad; ++i) {
96                         vsp1->drm->inputs[i].enabled = false;
97                         bru->inputs[i].rpf = NULL;
98                         pipe->inputs[i] = NULL;
99                 }
100
101                 pipe->num_inputs = 0;
102
103                 vsp1_dlm_reset(pipe->output->dlm);
104                 vsp1_device_put(vsp1);
105
106                 dev_dbg(vsp1->dev, "%s: pipeline disabled\n", __func__);
107
108                 return 0;
109         }
110
111         /* Configure the format at the BRU sinks and propagate it through the
112          * pipeline.
113          */
114         memset(&format, 0, sizeof(format));
115         format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
116
117         for (i = 0; i < bru->entity.source_pad; ++i) {
118                 format.pad = i;
119
120                 format.format.width = width;
121                 format.format.height = height;
122                 format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
123                 format.format.field = V4L2_FIELD_NONE;
124
125                 ret = v4l2_subdev_call(&bru->entity.subdev, pad,
126                                        set_fmt, NULL, &format);
127                 if (ret < 0)
128                         return ret;
129
130                 dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on BRU pad %u\n",
131                         __func__, format.format.width, format.format.height,
132                         format.format.code, i);
133         }
134
135         format.pad = bru->entity.source_pad;
136         format.format.width = width;
137         format.format.height = height;
138         format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
139         format.format.field = V4L2_FIELD_NONE;
140
141         ret = v4l2_subdev_call(&bru->entity.subdev, pad, set_fmt, NULL,
142                                &format);
143         if (ret < 0)
144                 return ret;
145
146         dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on BRU pad %u\n",
147                 __func__, format.format.width, format.format.height,
148                 format.format.code, i);
149
150         format.pad = RWPF_PAD_SINK;
151         ret = v4l2_subdev_call(&vsp1->wpf[0]->entity.subdev, pad, set_fmt, NULL,
152                                &format);
153         if (ret < 0)
154                 return ret;
155
156         dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on WPF0 sink\n",
157                 __func__, format.format.width, format.format.height,
158                 format.format.code);
159
160         format.pad = RWPF_PAD_SOURCE;
161         ret = v4l2_subdev_call(&vsp1->wpf[0]->entity.subdev, pad, get_fmt, NULL,
162                                &format);
163         if (ret < 0)
164                 return ret;
165
166         dev_dbg(vsp1->dev, "%s: got format %ux%u (%x) on WPF0 source\n",
167                 __func__, format.format.width, format.format.height,
168                 format.format.code);
169
170         format.pad = LIF_PAD_SINK;
171         ret = v4l2_subdev_call(&vsp1->lif->entity.subdev, pad, set_fmt, NULL,
172                                &format);
173         if (ret < 0)
174                 return ret;
175
176         dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on LIF sink\n",
177                 __func__, format.format.width, format.format.height,
178                 format.format.code);
179
180         /* Verify that the format at the output of the pipeline matches the
181          * requested frame size and media bus code.
182          */
183         if (format.format.width != width || format.format.height != height ||
184             format.format.code != MEDIA_BUS_FMT_ARGB8888_1X32) {
185                 dev_dbg(vsp1->dev, "%s: format mismatch\n", __func__);
186                 return -EPIPE;
187         }
188
189         /* Mark the pipeline as streaming and enable the VSP1. This will store
190          * the pipeline pointer in all entities, which the s_stream handlers
191          * will need. We don't start the entities themselves right at this point
192          * as there's no plane configured yet, so we can't start processing
193          * buffers.
194          */
195         ret = vsp1_device_get(vsp1);
196         if (ret < 0)
197                 return ret;
198
199         ret = media_entity_pipeline_start(&pipe->output->entity.subdev.entity,
200                                           &pipe->pipe);
201         if (ret < 0) {
202                 dev_dbg(vsp1->dev, "%s: pipeline start failed\n", __func__);
203                 vsp1_device_put(vsp1);
204                 return ret;
205         }
206
207         dev_dbg(vsp1->dev, "%s: pipeline enabled\n", __func__);
208
209         return 0;
210 }
211 EXPORT_SYMBOL_GPL(vsp1_du_setup_lif);
212
213 /**
214  * vsp1_du_atomic_begin - Prepare for an atomic update
215  * @dev: the VSP device
216  */
217 void vsp1_du_atomic_begin(struct device *dev)
218 {
219         struct vsp1_device *vsp1 = dev_get_drvdata(dev);
220         struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
221
222         vsp1->drm->num_inputs = pipe->num_inputs;
223
224         /* Prepare the display list. */
225         pipe->dl = vsp1_dl_list_get(pipe->output->dlm);
226 }
227 EXPORT_SYMBOL_GPL(vsp1_du_atomic_begin);
228
229 /**
230  * vsp1_du_atomic_update - Setup one RPF input of the VSP pipeline
231  * @dev: the VSP device
232  * @rpf_index: index of the RPF to setup (0-based)
233  * @pixelformat: V4L2 pixel format for the RPF memory input
234  * @pitch: number of bytes per line in the image stored in memory
235  * @mem: DMA addresses of the memory buffers (one per plane)
236  * @src: the source crop rectangle for the RPF
237  * @dst: the destination compose rectangle for the BRU input
238  * @alpha: global alpha value for the input
239  * @zpos: the Z-order position of the input
240  *
241  * Configure the VSP to perform composition of the image referenced by @mem
242  * through RPF @rpf_index, using the @src crop rectangle and the @dst
243  * composition rectangle. The Z-order is configurable with higher @zpos values
244  * displayed on top.
245  *
246  * Image format as stored in memory is expressed as a V4L2 @pixelformat value.
247  * As a special case, setting the pixel format to 0 will disable the RPF. The
248  * @pitch, @mem, @src and @dst parameters are ignored in that case. Calling the
249  * function on a disabled RPF is allowed.
250  *
251  * The memory pitch is configurable to allow for padding at end of lines, or
252  * simple for images that extend beyond the crop rectangle boundaries. The
253  * @pitch value is expressed in bytes and applies to all planes for multiplanar
254  * formats.
255  *
256  * The source memory buffer is referenced by the DMA address of its planes in
257  * the @mem array. Up to two planes are supported. The second plane DMA address
258  * is ignored for formats using a single plane.
259  *
260  * This function isn't reentrant, the caller needs to serialize calls.
261  *
262  * Return 0 on success or a negative error code on failure.
263  */
264 int vsp1_du_atomic_update_ext(struct device *dev, unsigned int rpf_index,
265                               u32 pixelformat, unsigned int pitch,
266                               dma_addr_t mem[2], const struct v4l2_rect *src,
267                               const struct v4l2_rect *dst, unsigned int alpha,
268                               unsigned int zpos)
269 {
270         struct vsp1_device *vsp1 = dev_get_drvdata(dev);
271         const struct vsp1_format_info *fmtinfo;
272         struct vsp1_rwpf *rpf;
273
274         if (rpf_index >= vsp1->info->rpf_count)
275                 return -EINVAL;
276
277         rpf = vsp1->rpf[rpf_index];
278
279         if (pixelformat == 0) {
280                 dev_dbg(vsp1->dev, "%s: RPF%u: disable requested\n", __func__,
281                         rpf_index);
282
283                 vsp1->drm->inputs[rpf_index].enabled = false;
284                 return 0;
285         }
286
287         dev_dbg(vsp1->dev,
288                 "%s: RPF%u: (%u,%u)/%ux%u -> (%u,%u)/%ux%u (%08x), pitch %u dma { %pad, %pad } zpos %u\n",
289                 __func__, rpf_index,
290                 src->left, src->top, src->width, src->height,
291                 dst->left, dst->top, dst->width, dst->height,
292                 pixelformat, pitch, &mem[0], &mem[1], zpos);
293
294         /* Store the format, stride, memory buffer address, crop and compose
295          * rectangles and Z-order position and for the input.
296          */
297         fmtinfo = vsp1_get_format_info(pixelformat);
298         if (!fmtinfo) {
299                 dev_dbg(vsp1->dev, "Unsupport pixel format %08x for RPF\n",
300                         pixelformat);
301                 return -EINVAL;
302         }
303
304         rpf->fmtinfo = fmtinfo;
305         rpf->format.num_planes = fmtinfo->planes;
306         rpf->format.plane_fmt[0].bytesperline = pitch;
307         rpf->format.plane_fmt[1].bytesperline = pitch;
308         rpf->alpha = alpha;
309
310         rpf->mem.addr[0] = mem[0];
311         rpf->mem.addr[1] = mem[1];
312         rpf->mem.addr[2] = 0;
313
314         vsp1->drm->inputs[rpf_index].crop = *src;
315         vsp1->drm->inputs[rpf_index].compose = *dst;
316         vsp1->drm->inputs[rpf_index].zpos = zpos;
317         vsp1->drm->inputs[rpf_index].enabled = true;
318
319         return 0;
320 }
321 EXPORT_SYMBOL_GPL(vsp1_du_atomic_update_ext);
322
323 static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1,
324                                   struct vsp1_rwpf *rpf, unsigned int bru_input)
325 {
326         struct v4l2_subdev_selection sel;
327         struct v4l2_subdev_format format;
328         const struct v4l2_rect *crop;
329         int ret;
330
331         /* Configure the format on the RPF sink pad and propagate it up to the
332          * BRU sink pad.
333          */
334         crop = &vsp1->drm->inputs[rpf->entity.index].crop;
335
336         memset(&format, 0, sizeof(format));
337         format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
338         format.pad = RWPF_PAD_SINK;
339         format.format.width = crop->width + crop->left;
340         format.format.height = crop->height + crop->top;
341         format.format.code = rpf->fmtinfo->mbus;
342         format.format.field = V4L2_FIELD_NONE;
343
344         ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_fmt, NULL,
345                                &format);
346         if (ret < 0)
347                 return ret;
348
349         dev_dbg(vsp1->dev,
350                 "%s: set format %ux%u (%x) on RPF%u sink\n",
351                 __func__, format.format.width, format.format.height,
352                 format.format.code, rpf->entity.index);
353
354         memset(&sel, 0, sizeof(sel));
355         sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
356         sel.pad = RWPF_PAD_SINK;
357         sel.target = V4L2_SEL_TGT_CROP;
358         sel.r = *crop;
359
360         ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_selection, NULL,
361                                &sel);
362         if (ret < 0)
363                 return ret;
364
365         dev_dbg(vsp1->dev,
366                 "%s: set selection (%u,%u)/%ux%u on RPF%u sink\n",
367                 __func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height,
368                 rpf->entity.index);
369
370         /* RPF source, hardcode the format to ARGB8888 to turn on format
371          * conversion if needed.
372          */
373         format.pad = RWPF_PAD_SOURCE;
374
375         ret = v4l2_subdev_call(&rpf->entity.subdev, pad, get_fmt, NULL,
376                                &format);
377         if (ret < 0)
378                 return ret;
379
380         dev_dbg(vsp1->dev,
381                 "%s: got format %ux%u (%x) on RPF%u source\n",
382                 __func__, format.format.width, format.format.height,
383                 format.format.code, rpf->entity.index);
384
385         format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
386
387         ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_fmt, NULL,
388                                &format);
389         if (ret < 0)
390                 return ret;
391
392         /* BRU sink, propagate the format from the RPF source. */
393         format.pad = bru_input;
394
395         ret = v4l2_subdev_call(&vsp1->bru->entity.subdev, pad, set_fmt, NULL,
396                                &format);
397         if (ret < 0)
398                 return ret;
399
400         dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on BRU pad %u\n",
401                 __func__, format.format.width, format.format.height,
402                 format.format.code, format.pad);
403
404         sel.pad = bru_input;
405         sel.target = V4L2_SEL_TGT_COMPOSE;
406         sel.r = vsp1->drm->inputs[rpf->entity.index].compose;
407
408         ret = v4l2_subdev_call(&vsp1->bru->entity.subdev, pad, set_selection,
409                                NULL, &sel);
410         if (ret < 0)
411                 return ret;
412
413         dev_dbg(vsp1->dev,
414                 "%s: set selection (%u,%u)/%ux%u on BRU pad %u\n",
415                 __func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height,
416                 sel.pad);
417
418         return 0;
419 }
420
421 static unsigned int rpf_zpos(struct vsp1_device *vsp1, struct vsp1_rwpf *rpf)
422 {
423         return vsp1->drm->inputs[rpf->entity.index].zpos;
424 }
425
426 /**
427  * vsp1_du_atomic_flush - Commit an atomic update
428  * @dev: the VSP device
429  */
430 void vsp1_du_atomic_flush(struct device *dev)
431 {
432         struct vsp1_device *vsp1 = dev_get_drvdata(dev);
433         struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
434         struct vsp1_rwpf *inputs[VSP1_MAX_RPF] = { NULL, };
435         struct vsp1_entity *entity;
436         unsigned long flags;
437         unsigned int i;
438         int ret;
439
440         /* Count the number of enabled inputs and sort them by Z-order. */
441         pipe->num_inputs = 0;
442
443         for (i = 0; i < vsp1->info->rpf_count; ++i) {
444                 struct vsp1_rwpf *rpf = vsp1->rpf[i];
445                 unsigned int j;
446
447                 if (!vsp1->drm->inputs[i].enabled) {
448                         pipe->inputs[i] = NULL;
449                         continue;
450                 }
451
452                 pipe->inputs[i] = rpf;
453
454                 /* Insert the RPF in the sorted RPFs array. */
455                 for (j = pipe->num_inputs++; j > 0; --j) {
456                         if (rpf_zpos(vsp1, inputs[j-1]) <= rpf_zpos(vsp1, rpf))
457                                 break;
458                         inputs[j] = inputs[j-1];
459                 }
460
461                 inputs[j] = rpf;
462         }
463
464         /* Setup the RPF input pipeline for every enabled input. */
465         for (i = 0; i < vsp1->info->num_bru_inputs; ++i) {
466                 struct vsp1_rwpf *rpf = inputs[i];
467
468                 if (!rpf) {
469                         vsp1->bru->inputs[i].rpf = NULL;
470                         continue;
471                 }
472
473                 vsp1->bru->inputs[i].rpf = rpf;
474                 rpf->bru_input = i;
475                 rpf->entity.sink_pad = i;
476
477                 dev_dbg(vsp1->dev, "%s: connecting RPF.%u to BRU:%u\n",
478                         __func__, rpf->entity.index, i);
479
480                 ret = vsp1_du_setup_rpf_pipe(vsp1, rpf, i);
481                 if (ret < 0)
482                         dev_err(vsp1->dev,
483                                 "%s: failed to setup RPF.%u\n",
484                                 __func__, rpf->entity.index);
485         }
486
487         /* Configure all entities in the pipeline. */
488         list_for_each_entry(entity, &pipe->entities, list_pipe) {
489                 /* Disconnect unused RPFs from the pipeline. */
490                 if (entity->type == VSP1_ENTITY_RPF) {
491                         struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev);
492
493                         if (!pipe->inputs[rpf->entity.index]) {
494                                 vsp1_dl_list_write(pipe->dl, entity->route->reg,
495                                                    VI6_DPR_NODE_UNUSED);
496                                 continue;
497                         }
498                 }
499
500                 vsp1_entity_route_setup(entity, pipe->dl);
501
502                 if (entity->ops->configure)
503                         entity->ops->configure(entity, pipe, pipe->dl);
504
505                 /* The memory buffer address must be applied after configuring
506                  * the RPF to make sure the crop offset are computed.
507                  */
508                 if (entity->type == VSP1_ENTITY_RPF)
509                         vsp1_rwpf_set_memory(to_rwpf(&entity->subdev),
510                                              pipe->dl);
511         }
512
513         vsp1_dl_list_commit(pipe->dl);
514         pipe->dl = NULL;
515
516         /* Start or stop the pipeline if needed. */
517         if (!vsp1->drm->num_inputs && pipe->num_inputs) {
518                 vsp1_write(vsp1, VI6_DISP_IRQ_STA, 0);
519                 vsp1_write(vsp1, VI6_DISP_IRQ_ENB, VI6_DISP_IRQ_ENB_DSTE);
520                 spin_lock_irqsave(&pipe->irqlock, flags);
521                 vsp1_pipeline_run(pipe);
522                 spin_unlock_irqrestore(&pipe->irqlock, flags);
523         } else if (vsp1->drm->num_inputs && !pipe->num_inputs) {
524                 vsp1_write(vsp1, VI6_DISP_IRQ_ENB, 0);
525                 vsp1_pipeline_stop(pipe);
526         }
527 }
528 EXPORT_SYMBOL_GPL(vsp1_du_atomic_flush);
529
530 /* -----------------------------------------------------------------------------
531  * Initialization
532  */
533
534 int vsp1_drm_create_links(struct vsp1_device *vsp1)
535 {
536         const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;
537         unsigned int i;
538         int ret;
539
540         /* VSPD instances require a BRU to perform composition and a LIF to
541          * output to the DU.
542          */
543         if (!vsp1->bru || !vsp1->lif)
544                 return -ENXIO;
545
546         for (i = 0; i < vsp1->info->rpf_count; ++i) {
547                 struct vsp1_rwpf *rpf = vsp1->rpf[i];
548
549                 ret = media_create_pad_link(&rpf->entity.subdev.entity,
550                                             RWPF_PAD_SOURCE,
551                                             &vsp1->bru->entity.subdev.entity,
552                                             i, flags);
553                 if (ret < 0)
554                         return ret;
555
556                 rpf->entity.sink = &vsp1->bru->entity.subdev.entity;
557                 rpf->entity.sink_pad = i;
558         }
559
560         ret = media_create_pad_link(&vsp1->bru->entity.subdev.entity,
561                                     vsp1->bru->entity.source_pad,
562                                     &vsp1->wpf[0]->entity.subdev.entity,
563                                     RWPF_PAD_SINK, flags);
564         if (ret < 0)
565                 return ret;
566
567         vsp1->bru->entity.sink = &vsp1->wpf[0]->entity.subdev.entity;
568         vsp1->bru->entity.sink_pad = RWPF_PAD_SINK;
569
570         ret = media_create_pad_link(&vsp1->wpf[0]->entity.subdev.entity,
571                                     RWPF_PAD_SOURCE,
572                                     &vsp1->lif->entity.subdev.entity,
573                                     LIF_PAD_SINK, flags);
574         if (ret < 0)
575                 return ret;
576
577         return 0;
578 }
579
580 int vsp1_drm_init(struct vsp1_device *vsp1)
581 {
582         struct vsp1_pipeline *pipe;
583         unsigned int i;
584
585         vsp1->drm = devm_kzalloc(vsp1->dev, sizeof(*vsp1->drm), GFP_KERNEL);
586         if (!vsp1->drm)
587                 return -ENOMEM;
588
589         pipe = &vsp1->drm->pipe;
590
591         vsp1_pipeline_init(pipe);
592
593         /* The DRM pipeline is static, add entities manually. */
594         for (i = 0; i < vsp1->info->rpf_count; ++i) {
595                 struct vsp1_rwpf *input = vsp1->rpf[i];
596
597                 list_add_tail(&input->entity.list_pipe, &pipe->entities);
598         }
599
600         list_add_tail(&vsp1->bru->entity.list_pipe, &pipe->entities);
601         list_add_tail(&vsp1->wpf[0]->entity.list_pipe, &pipe->entities);
602         list_add_tail(&vsp1->lif->entity.list_pipe, &pipe->entities);
603
604         pipe->bru = &vsp1->bru->entity;
605         pipe->lif = &vsp1->lif->entity;
606         pipe->output = vsp1->wpf[0];
607
608         return 0;
609 }
610
611 void vsp1_drm_cleanup(struct vsp1_device *vsp1)
612 {
613 }