Merge remote-tracking branches 'asoc/topic/max9878', 'asoc/topic/max98927', 'asoc...
[sfrench/cifs-2.6.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  * @cfg: the LIF configuration
58  *
59  * Configure the output part of VSP DRM pipeline for the given frame @cfg.width
60  * and @cfg.height. This sets up formats on the BRU source pad, the WPF0 sink
61  * and source pads, and the LIF sink pad.
62  *
63  * As the media bus code on the BRU source pad is conditioned by the
64  * configuration of the BRU sink 0 pad, we also set up the formats on all BRU
65  * sinks, even if the configuration will be overwritten later by
66  * vsp1_du_setup_rpf(). This ensures that the BRU configuration is set to a well
67  * defined state.
68  *
69  * Return 0 on success or a negative error code on failure.
70  */
71 int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
72 {
73         struct vsp1_device *vsp1 = dev_get_drvdata(dev);
74         struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
75         struct vsp1_bru *bru = vsp1->bru;
76         struct v4l2_subdev_format format;
77         unsigned int i;
78         int ret;
79
80         if (!cfg) {
81                 /* NULL configuration means the CRTC is being disabled, stop
82                  * the pipeline and turn the light off.
83                  */
84                 ret = vsp1_pipeline_stop(pipe);
85                 if (ret == -ETIMEDOUT)
86                         dev_err(vsp1->dev, "DRM pipeline stop timeout\n");
87
88                 media_pipeline_stop(&pipe->output->entity.subdev.entity);
89
90                 for (i = 0; i < bru->entity.source_pad; ++i) {
91                         vsp1->drm->inputs[i].enabled = false;
92                         bru->inputs[i].rpf = NULL;
93                         pipe->inputs[i] = NULL;
94                 }
95
96                 pipe->num_inputs = 0;
97
98                 vsp1_dlm_reset(pipe->output->dlm);
99                 vsp1_device_put(vsp1);
100
101                 dev_dbg(vsp1->dev, "%s: pipeline disabled\n", __func__);
102
103                 return 0;
104         }
105
106         dev_dbg(vsp1->dev, "%s: configuring LIF with format %ux%u\n",
107                 __func__, cfg->width, cfg->height);
108
109         /* Configure the format at the BRU sinks and propagate it through the
110          * pipeline.
111          */
112         memset(&format, 0, sizeof(format));
113         format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
114
115         for (i = 0; i < bru->entity.source_pad; ++i) {
116                 format.pad = i;
117
118                 format.format.width = cfg->width;
119                 format.format.height = cfg->height;
120                 format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
121                 format.format.field = V4L2_FIELD_NONE;
122
123                 ret = v4l2_subdev_call(&bru->entity.subdev, pad,
124                                        set_fmt, NULL, &format);
125                 if (ret < 0)
126                         return ret;
127
128                 dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on BRU pad %u\n",
129                         __func__, format.format.width, format.format.height,
130                         format.format.code, i);
131         }
132
133         format.pad = bru->entity.source_pad;
134         format.format.width = cfg->width;
135         format.format.height = cfg->height;
136         format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
137         format.format.field = V4L2_FIELD_NONE;
138
139         ret = v4l2_subdev_call(&bru->entity.subdev, pad, set_fmt, NULL,
140                                &format);
141         if (ret < 0)
142                 return ret;
143
144         dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on BRU pad %u\n",
145                 __func__, format.format.width, format.format.height,
146                 format.format.code, i);
147
148         format.pad = RWPF_PAD_SINK;
149         ret = v4l2_subdev_call(&vsp1->wpf[0]->entity.subdev, pad, set_fmt, NULL,
150                                &format);
151         if (ret < 0)
152                 return ret;
153
154         dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on WPF0 sink\n",
155                 __func__, format.format.width, format.format.height,
156                 format.format.code);
157
158         format.pad = RWPF_PAD_SOURCE;
159         ret = v4l2_subdev_call(&vsp1->wpf[0]->entity.subdev, pad, get_fmt, NULL,
160                                &format);
161         if (ret < 0)
162                 return ret;
163
164         dev_dbg(vsp1->dev, "%s: got format %ux%u (%x) on WPF0 source\n",
165                 __func__, format.format.width, format.format.height,
166                 format.format.code);
167
168         format.pad = LIF_PAD_SINK;
169         ret = v4l2_subdev_call(&vsp1->lif->entity.subdev, pad, set_fmt, NULL,
170                                &format);
171         if (ret < 0)
172                 return ret;
173
174         dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on LIF sink\n",
175                 __func__, format.format.width, format.format.height,
176                 format.format.code);
177
178         /* Verify that the format at the output of the pipeline matches the
179          * requested frame size and media bus code.
180          */
181         if (format.format.width != cfg->width ||
182             format.format.height != cfg->height ||
183             format.format.code != MEDIA_BUS_FMT_ARGB8888_1X32) {
184                 dev_dbg(vsp1->dev, "%s: format mismatch\n", __func__);
185                 return -EPIPE;
186         }
187
188         /* Mark the pipeline as streaming and enable the VSP1. This will store
189          * the pipeline pointer in all entities, which the s_stream handlers
190          * will need. We don't start the entities themselves right at this point
191          * as there's no plane configured yet, so we can't start processing
192          * buffers.
193          */
194         ret = vsp1_device_get(vsp1);
195         if (ret < 0)
196                 return ret;
197
198         ret = media_pipeline_start(&pipe->output->entity.subdev.entity,
199                                           &pipe->pipe);
200         if (ret < 0) {
201                 dev_dbg(vsp1->dev, "%s: pipeline start failed\n", __func__);
202                 vsp1_device_put(vsp1);
203                 return ret;
204         }
205
206         dev_dbg(vsp1->dev, "%s: pipeline enabled\n", __func__);
207
208         return 0;
209 }
210 EXPORT_SYMBOL_GPL(vsp1_du_setup_lif);
211
212 /**
213  * vsp1_du_atomic_begin - Prepare for an atomic update
214  * @dev: the VSP device
215  */
216 void vsp1_du_atomic_begin(struct device *dev)
217 {
218         struct vsp1_device *vsp1 = dev_get_drvdata(dev);
219         struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
220
221         vsp1->drm->num_inputs = pipe->num_inputs;
222
223         /* Prepare the display list. */
224         pipe->dl = vsp1_dl_list_get(pipe->output->dlm);
225 }
226 EXPORT_SYMBOL_GPL(vsp1_du_atomic_begin);
227
228 /**
229  * vsp1_du_atomic_update - Setup one RPF input of the VSP pipeline
230  * @dev: the VSP device
231  * @rpf_index: index of the RPF to setup (0-based)
232  * @cfg: the RPF configuration
233  *
234  * Configure the VSP to perform image composition through RPF @rpf_index as
235  * described by the @cfg configuration. The image to compose is referenced by
236  * @cfg.mem and composed using the @cfg.src crop rectangle and the @cfg.dst
237  * composition rectangle. The Z-order is configurable with higher @zpos values
238  * displayed on top.
239  *
240  * If the @cfg configuration is NULL, the RPF will be disabled. Calling the
241  * function on a disabled RPF is allowed.
242  *
243  * Image format as stored in memory is expressed as a V4L2 @cfg.pixelformat
244  * value. The memory pitch is configurable to allow for padding at end of lines,
245  * or simply for images that extend beyond the crop rectangle boundaries. The
246  * @cfg.pitch value is expressed in bytes and applies to all planes for
247  * multiplanar formats.
248  *
249  * The source memory buffer is referenced by the DMA address of its planes in
250  * the @cfg.mem array. Up to two planes are supported. The second plane DMA
251  * address is ignored for formats using a single plane.
252  *
253  * This function isn't reentrant, the caller needs to serialize calls.
254  *
255  * Return 0 on success or a negative error code on failure.
256  */
257 int vsp1_du_atomic_update(struct device *dev, unsigned int rpf_index,
258                           const struct vsp1_du_atomic_config *cfg)
259 {
260         struct vsp1_device *vsp1 = dev_get_drvdata(dev);
261         const struct vsp1_format_info *fmtinfo;
262         struct vsp1_rwpf *rpf;
263
264         if (rpf_index >= vsp1->info->rpf_count)
265                 return -EINVAL;
266
267         rpf = vsp1->rpf[rpf_index];
268
269         if (!cfg) {
270                 dev_dbg(vsp1->dev, "%s: RPF%u: disable requested\n", __func__,
271                         rpf_index);
272
273                 vsp1->drm->inputs[rpf_index].enabled = false;
274                 return 0;
275         }
276
277         dev_dbg(vsp1->dev,
278                 "%s: RPF%u: (%u,%u)/%ux%u -> (%u,%u)/%ux%u (%08x), pitch %u dma { %pad, %pad, %pad } zpos %u\n",
279                 __func__, rpf_index,
280                 cfg->src.left, cfg->src.top, cfg->src.width, cfg->src.height,
281                 cfg->dst.left, cfg->dst.top, cfg->dst.width, cfg->dst.height,
282                 cfg->pixelformat, cfg->pitch, &cfg->mem[0], &cfg->mem[1],
283                 &cfg->mem[2], cfg->zpos);
284
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(vsp1, 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] = cfg->mem[2];
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,
496                                                VSP1_ENTITY_PARAMS_INIT);
497                         entity->ops->configure(entity, pipe, pipe->dl,
498                                                VSP1_ENTITY_PARAMS_RUNTIME);
499                         entity->ops->configure(entity, pipe, pipe->dl,
500                                                VSP1_ENTITY_PARAMS_PARTITION);
501                 }
502         }
503
504         vsp1_dl_list_commit(pipe->dl);
505         pipe->dl = NULL;
506
507         /* Start or stop the pipeline if needed. */
508         if (!vsp1->drm->num_inputs && pipe->num_inputs) {
509                 vsp1_write(vsp1, VI6_DISP_IRQ_STA, 0);
510                 vsp1_write(vsp1, VI6_DISP_IRQ_ENB, VI6_DISP_IRQ_ENB_DSTE);
511                 spin_lock_irqsave(&pipe->irqlock, flags);
512                 vsp1_pipeline_run(pipe);
513                 spin_unlock_irqrestore(&pipe->irqlock, flags);
514         } else if (vsp1->drm->num_inputs && !pipe->num_inputs) {
515                 vsp1_write(vsp1, VI6_DISP_IRQ_ENB, 0);
516                 vsp1_pipeline_stop(pipe);
517         }
518 }
519 EXPORT_SYMBOL_GPL(vsp1_du_atomic_flush);
520
521 /* -----------------------------------------------------------------------------
522  * Initialization
523  */
524
525 int vsp1_drm_create_links(struct vsp1_device *vsp1)
526 {
527         const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;
528         unsigned int i;
529         int ret;
530
531         /* VSPD instances require a BRU to perform composition and a LIF to
532          * output to the DU.
533          */
534         if (!vsp1->bru || !vsp1->lif)
535                 return -ENXIO;
536
537         for (i = 0; i < vsp1->info->rpf_count; ++i) {
538                 struct vsp1_rwpf *rpf = vsp1->rpf[i];
539
540                 ret = media_create_pad_link(&rpf->entity.subdev.entity,
541                                             RWPF_PAD_SOURCE,
542                                             &vsp1->bru->entity.subdev.entity,
543                                             i, flags);
544                 if (ret < 0)
545                         return ret;
546
547                 rpf->entity.sink = &vsp1->bru->entity.subdev.entity;
548                 rpf->entity.sink_pad = i;
549         }
550
551         ret = media_create_pad_link(&vsp1->bru->entity.subdev.entity,
552                                     vsp1->bru->entity.source_pad,
553                                     &vsp1->wpf[0]->entity.subdev.entity,
554                                     RWPF_PAD_SINK, flags);
555         if (ret < 0)
556                 return ret;
557
558         vsp1->bru->entity.sink = &vsp1->wpf[0]->entity.subdev.entity;
559         vsp1->bru->entity.sink_pad = RWPF_PAD_SINK;
560
561         ret = media_create_pad_link(&vsp1->wpf[0]->entity.subdev.entity,
562                                     RWPF_PAD_SOURCE,
563                                     &vsp1->lif->entity.subdev.entity,
564                                     LIF_PAD_SINK, flags);
565         if (ret < 0)
566                 return ret;
567
568         return 0;
569 }
570
571 int vsp1_drm_init(struct vsp1_device *vsp1)
572 {
573         struct vsp1_pipeline *pipe;
574         unsigned int i;
575
576         vsp1->drm = devm_kzalloc(vsp1->dev, sizeof(*vsp1->drm), GFP_KERNEL);
577         if (!vsp1->drm)
578                 return -ENOMEM;
579
580         pipe = &vsp1->drm->pipe;
581
582         vsp1_pipeline_init(pipe);
583
584         /* The DRM pipeline is static, add entities manually. */
585         for (i = 0; i < vsp1->info->rpf_count; ++i) {
586                 struct vsp1_rwpf *input = vsp1->rpf[i];
587
588                 list_add_tail(&input->entity.list_pipe, &pipe->entities);
589         }
590
591         list_add_tail(&vsp1->bru->entity.list_pipe, &pipe->entities);
592         list_add_tail(&vsp1->wpf[0]->entity.list_pipe, &pipe->entities);
593         list_add_tail(&vsp1->lif->entity.list_pipe, &pipe->entities);
594
595         pipe->bru = &vsp1->bru->entity;
596         pipe->lif = &vsp1->lif->entity;
597         pipe->output = vsp1->wpf[0];
598
599         return 0;
600 }
601
602 void vsp1_drm_cleanup(struct vsp1_device *vsp1)
603 {
604 }