Merge tag 'gcc-plugins-v4.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git...
[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  * @cfg: the RPF configuration
234  *
235  * Configure the VSP to perform image composition through RPF @rpf_index as
236  * described by the @cfg configuration. The image to compose is referenced by
237  * @cfg.mem and composed using the @cfg.src crop rectangle and the @cfg.dst
238  * composition rectangle. The Z-order is configurable with higher @zpos values
239  * displayed on top.
240  *
241  * If the @cfg configuration is NULL, the RPF will be disabled. Calling the
242  * function on a disabled RPF is allowed.
243  *
244  * Image format as stored in memory is expressed as a V4L2 @cfg.pixelformat
245  * value. The memory pitch is configurable to allow for padding at end of lines,
246  * or simply for images that extend beyond the crop rectangle boundaries. The
247  * @cfg.pitch value is expressed in bytes and applies to all planes for
248  * multiplanar formats.
249  *
250  * The source memory buffer is referenced by the DMA address of its planes in
251  * the @cfg.mem array. Up to two planes are supported. The second plane DMA
252  * address is ignored for formats using a single plane.
253  *
254  * This function isn't reentrant, the caller needs to serialize calls.
255  *
256  * Return 0 on success or a negative error code on failure.
257  */
258 int vsp1_du_atomic_update(struct device *dev, unsigned int rpf_index,
259                           const struct vsp1_du_atomic_config *cfg)
260 {
261         struct vsp1_device *vsp1 = dev_get_drvdata(dev);
262         const struct vsp1_format_info *fmtinfo;
263         struct vsp1_rwpf *rpf;
264
265         if (rpf_index >= vsp1->info->rpf_count)
266                 return -EINVAL;
267
268         rpf = vsp1->rpf[rpf_index];
269
270         if (!cfg) {
271                 dev_dbg(vsp1->dev, "%s: RPF%u: disable requested\n", __func__,
272                         rpf_index);
273
274                 vsp1->drm->inputs[rpf_index].enabled = false;
275                 return 0;
276         }
277
278         dev_dbg(vsp1->dev,
279                 "%s: RPF%u: (%u,%u)/%ux%u -> (%u,%u)/%ux%u (%08x), pitch %u dma { %pad, %pad, %pad } zpos %u\n",
280                 __func__, rpf_index,
281                 cfg->src.left, cfg->src.top, cfg->src.width, cfg->src.height,
282                 cfg->dst.left, cfg->dst.top, cfg->dst.width, cfg->dst.height,
283                 cfg->pixelformat, cfg->pitch, &cfg->mem[0], &cfg->mem[1],
284                 &cfg->mem[2], cfg->zpos);
285
286         /*
287          * Store the format, stride, memory buffer address, crop and compose
288          * rectangles and Z-order position and for the input.
289          */
290         fmtinfo = vsp1_get_format_info(vsp1, cfg->pixelformat);
291         if (!fmtinfo) {
292                 dev_dbg(vsp1->dev, "Unsupport pixel format %08x for RPF\n",
293                         cfg->pixelformat);
294                 return -EINVAL;
295         }
296
297         rpf->fmtinfo = fmtinfo;
298         rpf->format.num_planes = fmtinfo->planes;
299         rpf->format.plane_fmt[0].bytesperline = cfg->pitch;
300         rpf->format.plane_fmt[1].bytesperline = cfg->pitch;
301         rpf->alpha = cfg->alpha;
302
303         rpf->mem.addr[0] = cfg->mem[0];
304         rpf->mem.addr[1] = cfg->mem[1];
305         rpf->mem.addr[2] = cfg->mem[2];
306
307         vsp1->drm->inputs[rpf_index].crop = cfg->src;
308         vsp1->drm->inputs[rpf_index].compose = cfg->dst;
309         vsp1->drm->inputs[rpf_index].zpos = cfg->zpos;
310         vsp1->drm->inputs[rpf_index].enabled = true;
311
312         return 0;
313 }
314 EXPORT_SYMBOL_GPL(vsp1_du_atomic_update);
315
316 static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1,
317                                   struct vsp1_rwpf *rpf, unsigned int bru_input)
318 {
319         struct v4l2_subdev_selection sel;
320         struct v4l2_subdev_format format;
321         const struct v4l2_rect *crop;
322         int ret;
323
324         /* Configure the format on the RPF sink pad and propagate it up to the
325          * BRU sink pad.
326          */
327         crop = &vsp1->drm->inputs[rpf->entity.index].crop;
328
329         memset(&format, 0, sizeof(format));
330         format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
331         format.pad = RWPF_PAD_SINK;
332         format.format.width = crop->width + crop->left;
333         format.format.height = crop->height + crop->top;
334         format.format.code = rpf->fmtinfo->mbus;
335         format.format.field = V4L2_FIELD_NONE;
336
337         ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_fmt, NULL,
338                                &format);
339         if (ret < 0)
340                 return ret;
341
342         dev_dbg(vsp1->dev,
343                 "%s: set format %ux%u (%x) on RPF%u sink\n",
344                 __func__, format.format.width, format.format.height,
345                 format.format.code, rpf->entity.index);
346
347         memset(&sel, 0, sizeof(sel));
348         sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
349         sel.pad = RWPF_PAD_SINK;
350         sel.target = V4L2_SEL_TGT_CROP;
351         sel.r = *crop;
352
353         ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_selection, NULL,
354                                &sel);
355         if (ret < 0)
356                 return ret;
357
358         dev_dbg(vsp1->dev,
359                 "%s: set selection (%u,%u)/%ux%u on RPF%u sink\n",
360                 __func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height,
361                 rpf->entity.index);
362
363         /* RPF source, hardcode the format to ARGB8888 to turn on format
364          * conversion if needed.
365          */
366         format.pad = RWPF_PAD_SOURCE;
367
368         ret = v4l2_subdev_call(&rpf->entity.subdev, pad, get_fmt, NULL,
369                                &format);
370         if (ret < 0)
371                 return ret;
372
373         dev_dbg(vsp1->dev,
374                 "%s: got format %ux%u (%x) on RPF%u source\n",
375                 __func__, format.format.width, format.format.height,
376                 format.format.code, rpf->entity.index);
377
378         format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
379
380         ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_fmt, NULL,
381                                &format);
382         if (ret < 0)
383                 return ret;
384
385         /* BRU sink, propagate the format from the RPF source. */
386         format.pad = bru_input;
387
388         ret = v4l2_subdev_call(&vsp1->bru->entity.subdev, pad, set_fmt, NULL,
389                                &format);
390         if (ret < 0)
391                 return ret;
392
393         dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on BRU pad %u\n",
394                 __func__, format.format.width, format.format.height,
395                 format.format.code, format.pad);
396
397         sel.pad = bru_input;
398         sel.target = V4L2_SEL_TGT_COMPOSE;
399         sel.r = vsp1->drm->inputs[rpf->entity.index].compose;
400
401         ret = v4l2_subdev_call(&vsp1->bru->entity.subdev, pad, set_selection,
402                                NULL, &sel);
403         if (ret < 0)
404                 return ret;
405
406         dev_dbg(vsp1->dev,
407                 "%s: set selection (%u,%u)/%ux%u on BRU pad %u\n",
408                 __func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height,
409                 sel.pad);
410
411         return 0;
412 }
413
414 static unsigned int rpf_zpos(struct vsp1_device *vsp1, struct vsp1_rwpf *rpf)
415 {
416         return vsp1->drm->inputs[rpf->entity.index].zpos;
417 }
418
419 /**
420  * vsp1_du_atomic_flush - Commit an atomic update
421  * @dev: the VSP device
422  */
423 void vsp1_du_atomic_flush(struct device *dev)
424 {
425         struct vsp1_device *vsp1 = dev_get_drvdata(dev);
426         struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
427         struct vsp1_rwpf *inputs[VSP1_MAX_RPF] = { NULL, };
428         struct vsp1_entity *entity;
429         unsigned long flags;
430         unsigned int i;
431         int ret;
432
433         /* Count the number of enabled inputs and sort them by Z-order. */
434         pipe->num_inputs = 0;
435
436         for (i = 0; i < vsp1->info->rpf_count; ++i) {
437                 struct vsp1_rwpf *rpf = vsp1->rpf[i];
438                 unsigned int j;
439
440                 if (!vsp1->drm->inputs[i].enabled) {
441                         pipe->inputs[i] = NULL;
442                         continue;
443                 }
444
445                 pipe->inputs[i] = rpf;
446
447                 /* Insert the RPF in the sorted RPFs array. */
448                 for (j = pipe->num_inputs++; j > 0; --j) {
449                         if (rpf_zpos(vsp1, inputs[j-1]) <= rpf_zpos(vsp1, rpf))
450                                 break;
451                         inputs[j] = inputs[j-1];
452                 }
453
454                 inputs[j] = rpf;
455         }
456
457         /* Setup the RPF input pipeline for every enabled input. */
458         for (i = 0; i < vsp1->info->num_bru_inputs; ++i) {
459                 struct vsp1_rwpf *rpf = inputs[i];
460
461                 if (!rpf) {
462                         vsp1->bru->inputs[i].rpf = NULL;
463                         continue;
464                 }
465
466                 vsp1->bru->inputs[i].rpf = rpf;
467                 rpf->bru_input = i;
468                 rpf->entity.sink_pad = i;
469
470                 dev_dbg(vsp1->dev, "%s: connecting RPF.%u to BRU:%u\n",
471                         __func__, rpf->entity.index, i);
472
473                 ret = vsp1_du_setup_rpf_pipe(vsp1, rpf, i);
474                 if (ret < 0)
475                         dev_err(vsp1->dev,
476                                 "%s: failed to setup RPF.%u\n",
477                                 __func__, rpf->entity.index);
478         }
479
480         /* Configure all entities in the pipeline. */
481         list_for_each_entry(entity, &pipe->entities, list_pipe) {
482                 /* Disconnect unused RPFs from the pipeline. */
483                 if (entity->type == VSP1_ENTITY_RPF) {
484                         struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev);
485
486                         if (!pipe->inputs[rpf->entity.index]) {
487                                 vsp1_dl_list_write(pipe->dl, entity->route->reg,
488                                                    VI6_DPR_NODE_UNUSED);
489                                 continue;
490                         }
491                 }
492
493                 vsp1_entity_route_setup(entity, pipe->dl);
494
495                 if (entity->ops->configure) {
496                         entity->ops->configure(entity, pipe, pipe->dl,
497                                                VSP1_ENTITY_PARAMS_INIT);
498                         entity->ops->configure(entity, pipe, pipe->dl,
499                                                VSP1_ENTITY_PARAMS_RUNTIME);
500                         entity->ops->configure(entity, pipe, pipe->dl,
501                                                VSP1_ENTITY_PARAMS_PARTITION);
502                 }
503         }
504
505         vsp1_dl_list_commit(pipe->dl);
506         pipe->dl = NULL;
507
508         /* Start or stop the pipeline if needed. */
509         if (!vsp1->drm->num_inputs && pipe->num_inputs) {
510                 vsp1_write(vsp1, VI6_DISP_IRQ_STA, 0);
511                 vsp1_write(vsp1, VI6_DISP_IRQ_ENB, VI6_DISP_IRQ_ENB_DSTE);
512                 spin_lock_irqsave(&pipe->irqlock, flags);
513                 vsp1_pipeline_run(pipe);
514                 spin_unlock_irqrestore(&pipe->irqlock, flags);
515         } else if (vsp1->drm->num_inputs && !pipe->num_inputs) {
516                 vsp1_write(vsp1, VI6_DISP_IRQ_ENB, 0);
517                 vsp1_pipeline_stop(pipe);
518         }
519 }
520 EXPORT_SYMBOL_GPL(vsp1_du_atomic_flush);
521
522 /* -----------------------------------------------------------------------------
523  * Initialization
524  */
525
526 int vsp1_drm_create_links(struct vsp1_device *vsp1)
527 {
528         const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;
529         unsigned int i;
530         int ret;
531
532         /* VSPD instances require a BRU to perform composition and a LIF to
533          * output to the DU.
534          */
535         if (!vsp1->bru || !vsp1->lif)
536                 return -ENXIO;
537
538         for (i = 0; i < vsp1->info->rpf_count; ++i) {
539                 struct vsp1_rwpf *rpf = vsp1->rpf[i];
540
541                 ret = media_create_pad_link(&rpf->entity.subdev.entity,
542                                             RWPF_PAD_SOURCE,
543                                             &vsp1->bru->entity.subdev.entity,
544                                             i, flags);
545                 if (ret < 0)
546                         return ret;
547
548                 rpf->entity.sink = &vsp1->bru->entity.subdev.entity;
549                 rpf->entity.sink_pad = i;
550         }
551
552         ret = media_create_pad_link(&vsp1->bru->entity.subdev.entity,
553                                     vsp1->bru->entity.source_pad,
554                                     &vsp1->wpf[0]->entity.subdev.entity,
555                                     RWPF_PAD_SINK, flags);
556         if (ret < 0)
557                 return ret;
558
559         vsp1->bru->entity.sink = &vsp1->wpf[0]->entity.subdev.entity;
560         vsp1->bru->entity.sink_pad = RWPF_PAD_SINK;
561
562         ret = media_create_pad_link(&vsp1->wpf[0]->entity.subdev.entity,
563                                     RWPF_PAD_SOURCE,
564                                     &vsp1->lif->entity.subdev.entity,
565                                     LIF_PAD_SINK, flags);
566         if (ret < 0)
567                 return ret;
568
569         return 0;
570 }
571
572 int vsp1_drm_init(struct vsp1_device *vsp1)
573 {
574         struct vsp1_pipeline *pipe;
575         unsigned int i;
576
577         vsp1->drm = devm_kzalloc(vsp1->dev, sizeof(*vsp1->drm), GFP_KERNEL);
578         if (!vsp1->drm)
579                 return -ENOMEM;
580
581         pipe = &vsp1->drm->pipe;
582
583         vsp1_pipeline_init(pipe);
584
585         /* The DRM pipeline is static, add entities manually. */
586         for (i = 0; i < vsp1->info->rpf_count; ++i) {
587                 struct vsp1_rwpf *input = vsp1->rpf[i];
588
589                 list_add_tail(&input->entity.list_pipe, &pipe->entities);
590         }
591
592         list_add_tail(&vsp1->bru->entity.list_pipe, &pipe->entities);
593         list_add_tail(&vsp1->wpf[0]->entity.list_pipe, &pipe->entities);
594         list_add_tail(&vsp1->lif->entity.list_pipe, &pipe->entities);
595
596         pipe->bru = &vsp1->bru->entity;
597         pipe->lif = &vsp1->lif->entity;
598         pipe->output = vsp1->wpf[0];
599
600         return 0;
601 }
602
603 void vsp1_drm_cleanup(struct vsp1_device *vsp1)
604 {
605 }