MAINTAINERS: mmc: Move the mmc tree to kernel.org
[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 } 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->zpos);
285
286         /* Store the format, stride, memory buffer address, crop and compose
287          * rectangles and Z-order position and for the input.
288          */
289         fmtinfo = vsp1_get_format_info(cfg->pixelformat);
290         if (!fmtinfo) {
291                 dev_dbg(vsp1->dev, "Unsupport pixel format %08x for RPF\n",
292                         cfg->pixelformat);
293                 return -EINVAL;
294         }
295
296         rpf->fmtinfo = fmtinfo;
297         rpf->format.num_planes = fmtinfo->planes;
298         rpf->format.plane_fmt[0].bytesperline = cfg->pitch;
299         rpf->format.plane_fmt[1].bytesperline = cfg->pitch;
300         rpf->alpha = cfg->alpha;
301
302         rpf->mem.addr[0] = cfg->mem[0];
303         rpf->mem.addr[1] = cfg->mem[1];
304         rpf->mem.addr[2] = 0;
305
306         vsp1->drm->inputs[rpf_index].crop = cfg->src;
307         vsp1->drm->inputs[rpf_index].compose = cfg->dst;
308         vsp1->drm->inputs[rpf_index].zpos = cfg->zpos;
309         vsp1->drm->inputs[rpf_index].enabled = true;
310
311         return 0;
312 }
313 EXPORT_SYMBOL_GPL(vsp1_du_atomic_update);
314
315 static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1,
316                                   struct vsp1_rwpf *rpf, unsigned int bru_input)
317 {
318         struct v4l2_subdev_selection sel;
319         struct v4l2_subdev_format format;
320         const struct v4l2_rect *crop;
321         int ret;
322
323         /* Configure the format on the RPF sink pad and propagate it up to the
324          * BRU sink pad.
325          */
326         crop = &vsp1->drm->inputs[rpf->entity.index].crop;
327
328         memset(&format, 0, sizeof(format));
329         format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
330         format.pad = RWPF_PAD_SINK;
331         format.format.width = crop->width + crop->left;
332         format.format.height = crop->height + crop->top;
333         format.format.code = rpf->fmtinfo->mbus;
334         format.format.field = V4L2_FIELD_NONE;
335
336         ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_fmt, NULL,
337                                &format);
338         if (ret < 0)
339                 return ret;
340
341         dev_dbg(vsp1->dev,
342                 "%s: set format %ux%u (%x) on RPF%u sink\n",
343                 __func__, format.format.width, format.format.height,
344                 format.format.code, rpf->entity.index);
345
346         memset(&sel, 0, sizeof(sel));
347         sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
348         sel.pad = RWPF_PAD_SINK;
349         sel.target = V4L2_SEL_TGT_CROP;
350         sel.r = *crop;
351
352         ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_selection, NULL,
353                                &sel);
354         if (ret < 0)
355                 return ret;
356
357         dev_dbg(vsp1->dev,
358                 "%s: set selection (%u,%u)/%ux%u on RPF%u sink\n",
359                 __func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height,
360                 rpf->entity.index);
361
362         /* RPF source, hardcode the format to ARGB8888 to turn on format
363          * conversion if needed.
364          */
365         format.pad = RWPF_PAD_SOURCE;
366
367         ret = v4l2_subdev_call(&rpf->entity.subdev, pad, get_fmt, NULL,
368                                &format);
369         if (ret < 0)
370                 return ret;
371
372         dev_dbg(vsp1->dev,
373                 "%s: got format %ux%u (%x) on RPF%u source\n",
374                 __func__, format.format.width, format.format.height,
375                 format.format.code, rpf->entity.index);
376
377         format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
378
379         ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_fmt, NULL,
380                                &format);
381         if (ret < 0)
382                 return ret;
383
384         /* BRU sink, propagate the format from the RPF source. */
385         format.pad = bru_input;
386
387         ret = v4l2_subdev_call(&vsp1->bru->entity.subdev, pad, set_fmt, NULL,
388                                &format);
389         if (ret < 0)
390                 return ret;
391
392         dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on BRU pad %u\n",
393                 __func__, format.format.width, format.format.height,
394                 format.format.code, format.pad);
395
396         sel.pad = bru_input;
397         sel.target = V4L2_SEL_TGT_COMPOSE;
398         sel.r = vsp1->drm->inputs[rpf->entity.index].compose;
399
400         ret = v4l2_subdev_call(&vsp1->bru->entity.subdev, pad, set_selection,
401                                NULL, &sel);
402         if (ret < 0)
403                 return ret;
404
405         dev_dbg(vsp1->dev,
406                 "%s: set selection (%u,%u)/%ux%u on BRU pad %u\n",
407                 __func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height,
408                 sel.pad);
409
410         return 0;
411 }
412
413 static unsigned int rpf_zpos(struct vsp1_device *vsp1, struct vsp1_rwpf *rpf)
414 {
415         return vsp1->drm->inputs[rpf->entity.index].zpos;
416 }
417
418 /**
419  * vsp1_du_atomic_flush - Commit an atomic update
420  * @dev: the VSP device
421  */
422 void vsp1_du_atomic_flush(struct device *dev)
423 {
424         struct vsp1_device *vsp1 = dev_get_drvdata(dev);
425         struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
426         struct vsp1_rwpf *inputs[VSP1_MAX_RPF] = { NULL, };
427         struct vsp1_entity *entity;
428         unsigned long flags;
429         unsigned int i;
430         int ret;
431
432         /* Count the number of enabled inputs and sort them by Z-order. */
433         pipe->num_inputs = 0;
434
435         for (i = 0; i < vsp1->info->rpf_count; ++i) {
436                 struct vsp1_rwpf *rpf = vsp1->rpf[i];
437                 unsigned int j;
438
439                 if (!vsp1->drm->inputs[i].enabled) {
440                         pipe->inputs[i] = NULL;
441                         continue;
442                 }
443
444                 pipe->inputs[i] = rpf;
445
446                 /* Insert the RPF in the sorted RPFs array. */
447                 for (j = pipe->num_inputs++; j > 0; --j) {
448                         if (rpf_zpos(vsp1, inputs[j-1]) <= rpf_zpos(vsp1, rpf))
449                                 break;
450                         inputs[j] = inputs[j-1];
451                 }
452
453                 inputs[j] = rpf;
454         }
455
456         /* Setup the RPF input pipeline for every enabled input. */
457         for (i = 0; i < vsp1->info->num_bru_inputs; ++i) {
458                 struct vsp1_rwpf *rpf = inputs[i];
459
460                 if (!rpf) {
461                         vsp1->bru->inputs[i].rpf = NULL;
462                         continue;
463                 }
464
465                 vsp1->bru->inputs[i].rpf = rpf;
466                 rpf->bru_input = i;
467                 rpf->entity.sink_pad = i;
468
469                 dev_dbg(vsp1->dev, "%s: connecting RPF.%u to BRU:%u\n",
470                         __func__, rpf->entity.index, i);
471
472                 ret = vsp1_du_setup_rpf_pipe(vsp1, rpf, i);
473                 if (ret < 0)
474                         dev_err(vsp1->dev,
475                                 "%s: failed to setup RPF.%u\n",
476                                 __func__, rpf->entity.index);
477         }
478
479         /* Configure all entities in the pipeline. */
480         list_for_each_entry(entity, &pipe->entities, list_pipe) {
481                 /* Disconnect unused RPFs from the pipeline. */
482                 if (entity->type == VSP1_ENTITY_RPF) {
483                         struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev);
484
485                         if (!pipe->inputs[rpf->entity.index]) {
486                                 vsp1_dl_list_write(pipe->dl, entity->route->reg,
487                                                    VI6_DPR_NODE_UNUSED);
488                                 continue;
489                         }
490                 }
491
492                 vsp1_entity_route_setup(entity, pipe->dl);
493
494                 if (entity->ops->configure) {
495                         entity->ops->configure(entity, pipe, pipe->dl, true);
496                         entity->ops->configure(entity, pipe, pipe->dl, false);
497                 }
498
499                 /* The memory buffer address must be applied after configuring
500                  * the RPF to make sure the crop offset are computed.
501                  */
502                 if (entity->type == VSP1_ENTITY_RPF)
503                         vsp1_rwpf_set_memory(to_rwpf(&entity->subdev),
504                                              pipe->dl);
505         }
506
507         vsp1_dl_list_commit(pipe->dl);
508         pipe->dl = NULL;
509
510         /* Start or stop the pipeline if needed. */
511         if (!vsp1->drm->num_inputs && pipe->num_inputs) {
512                 vsp1_write(vsp1, VI6_DISP_IRQ_STA, 0);
513                 vsp1_write(vsp1, VI6_DISP_IRQ_ENB, VI6_DISP_IRQ_ENB_DSTE);
514                 spin_lock_irqsave(&pipe->irqlock, flags);
515                 vsp1_pipeline_run(pipe);
516                 spin_unlock_irqrestore(&pipe->irqlock, flags);
517         } else if (vsp1->drm->num_inputs && !pipe->num_inputs) {
518                 vsp1_write(vsp1, VI6_DISP_IRQ_ENB, 0);
519                 vsp1_pipeline_stop(pipe);
520         }
521 }
522 EXPORT_SYMBOL_GPL(vsp1_du_atomic_flush);
523
524 /* -----------------------------------------------------------------------------
525  * Initialization
526  */
527
528 int vsp1_drm_create_links(struct vsp1_device *vsp1)
529 {
530         const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;
531         unsigned int i;
532         int ret;
533
534         /* VSPD instances require a BRU to perform composition and a LIF to
535          * output to the DU.
536          */
537         if (!vsp1->bru || !vsp1->lif)
538                 return -ENXIO;
539
540         for (i = 0; i < vsp1->info->rpf_count; ++i) {
541                 struct vsp1_rwpf *rpf = vsp1->rpf[i];
542
543                 ret = media_create_pad_link(&rpf->entity.subdev.entity,
544                                             RWPF_PAD_SOURCE,
545                                             &vsp1->bru->entity.subdev.entity,
546                                             i, flags);
547                 if (ret < 0)
548                         return ret;
549
550                 rpf->entity.sink = &vsp1->bru->entity.subdev.entity;
551                 rpf->entity.sink_pad = i;
552         }
553
554         ret = media_create_pad_link(&vsp1->bru->entity.subdev.entity,
555                                     vsp1->bru->entity.source_pad,
556                                     &vsp1->wpf[0]->entity.subdev.entity,
557                                     RWPF_PAD_SINK, flags);
558         if (ret < 0)
559                 return ret;
560
561         vsp1->bru->entity.sink = &vsp1->wpf[0]->entity.subdev.entity;
562         vsp1->bru->entity.sink_pad = RWPF_PAD_SINK;
563
564         ret = media_create_pad_link(&vsp1->wpf[0]->entity.subdev.entity,
565                                     RWPF_PAD_SOURCE,
566                                     &vsp1->lif->entity.subdev.entity,
567                                     LIF_PAD_SINK, flags);
568         if (ret < 0)
569                 return ret;
570
571         return 0;
572 }
573
574 int vsp1_drm_init(struct vsp1_device *vsp1)
575 {
576         struct vsp1_pipeline *pipe;
577         unsigned int i;
578
579         vsp1->drm = devm_kzalloc(vsp1->dev, sizeof(*vsp1->drm), GFP_KERNEL);
580         if (!vsp1->drm)
581                 return -ENOMEM;
582
583         pipe = &vsp1->drm->pipe;
584
585         vsp1_pipeline_init(pipe);
586
587         /* The DRM pipeline is static, add entities manually. */
588         for (i = 0; i < vsp1->info->rpf_count; ++i) {
589                 struct vsp1_rwpf *input = vsp1->rpf[i];
590
591                 list_add_tail(&input->entity.list_pipe, &pipe->entities);
592         }
593
594         list_add_tail(&vsp1->bru->entity.list_pipe, &pipe->entities);
595         list_add_tail(&vsp1->wpf[0]->entity.list_pipe, &pipe->entities);
596         list_add_tail(&vsp1->lif->entity.list_pipe, &pipe->entities);
597
598         pipe->bru = &vsp1->bru->entity;
599         pipe->lif = &vsp1->lif->entity;
600         pipe->output = vsp1->wpf[0];
601
602         return 0;
603 }
604
605 void vsp1_drm_cleanup(struct vsp1_device *vsp1)
606 {
607 }