1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * vsp1_drm.c  --  R-Car VSP1 DRM/KMS Interface
4 *
5 * Copyright (C) 2015 Renesas Electronics Corporation
6 *
7 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
8 */
9
10#include <linux/device.h>
11#include <linux/dma-mapping.h>
12#include <linux/slab.h>
13
14#include <media/media-entity.h>
15#include <media/v4l2-subdev.h>
16#include <media/vsp1.h>
17
18#include "vsp1.h"
19#include "vsp1_brx.h"
20#include "vsp1_dl.h"
21#include "vsp1_drm.h"
22#include "vsp1_lif.h"
23#include "vsp1_pipe.h"
24#include "vsp1_rwpf.h"
25#include "vsp1_uif.h"
26
27#define BRX_NAME(e)	(e)->type == VSP1_ENTITY_BRU ? "BRU" : "BRS"
28
29/* -----------------------------------------------------------------------------
30 * Interrupt Handling
31 */
32
33static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
34				       unsigned int completion)
35{
36	struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
37
38	if (drm_pipe->du_complete) {
39		struct vsp1_entity *uif = drm_pipe->uif;
40		unsigned int status = completion
41				    & (VSP1_DU_STATUS_COMPLETE |
42				       VSP1_DU_STATUS_WRITEBACK);
43		u32 crc;
44
45		crc = uif ? vsp1_uif_get_crc(to_uif(&uif->subdev)) : 0;
46		drm_pipe->du_complete(drm_pipe->du_private, status, crc);
47	}
48
49	if (completion & VSP1_DL_FRAME_END_INTERNAL) {
50		drm_pipe->force_brx_release = false;
51		wake_up(&drm_pipe->wait_queue);
52	}
53}
54
55/* -----------------------------------------------------------------------------
56 * Pipeline Configuration
57 */
58
59/*
60 * Insert the UIF in the pipeline between the prev and next entities. If no UIF
61 * is available connect the two entities directly.
62 */
63static int vsp1_du_insert_uif(struct vsp1_device *vsp1,
64			      struct vsp1_pipeline *pipe,
65			      struct vsp1_entity *uif,
66			      struct vsp1_entity *prev, unsigned int prev_pad,
67			      struct vsp1_entity *next, unsigned int next_pad)
68{
69	struct v4l2_subdev_format format = {
70		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
71	};
72	int ret;
73
74	if (!uif) {
75		/*
76		 * If there's no UIF to be inserted, connect the previous and
77		 * next entities directly.
78		 */
79		prev->sink = next;
80		prev->sink_pad = next_pad;
81		return 0;
82	}
83
84	prev->sink = uif;
85	prev->sink_pad = UIF_PAD_SINK;
86
87	format.pad = prev_pad;
88
89	ret = v4l2_subdev_call(&prev->subdev, pad, get_fmt, NULL, &format);
90	if (ret < 0)
91		return ret;
92
93	format.pad = UIF_PAD_SINK;
94
95	ret = v4l2_subdev_call(&uif->subdev, pad, set_fmt, NULL, &format);
96	if (ret < 0)
97		return ret;
98
99	dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on UIF sink\n",
100		__func__, format.format.width, format.format.height,
101		format.format.code);
102
103	/*
104	 * The UIF doesn't mangle the format between its sink and source pads,
105	 * so there is no need to retrieve the format on its source pad.
106	 */
107
108	uif->sink = next;
109	uif->sink_pad = next_pad;
110
111	return 0;
112}
113
114/* Setup one RPF and the connected BRx sink pad. */
115static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
116				      struct vsp1_pipeline *pipe,
117				      struct vsp1_rwpf *rpf,
118				      struct vsp1_entity *uif,
119				      unsigned int brx_input)
120{
121	struct v4l2_subdev_selection sel = {
122		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
123	};
124	struct v4l2_subdev_format format = {
125		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
126	};
127	const struct v4l2_rect *crop;
128	int ret;
129
130	/*
131	 * Configure the format on the RPF sink pad and propagate it up to the
132	 * BRx sink pad.
133	 */
134	crop = &vsp1->drm->inputs[rpf->entity.index].crop;
135
136	format.pad = RWPF_PAD_SINK;
137	format.format.width = crop->width + crop->left;
138	format.format.height = crop->height + crop->top;
139	format.format.code = rpf->fmtinfo->mbus;
140	format.format.field = V4L2_FIELD_NONE;
141
142	ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_fmt, NULL,
143			       &format);
144	if (ret < 0)
145		return ret;
146
147	dev_dbg(vsp1->dev,
148		"%s: set format %ux%u (%x) on RPF%u sink\n",
149		__func__, format.format.width, format.format.height,
150		format.format.code, rpf->entity.index);
151
152	sel.pad = RWPF_PAD_SINK;
153	sel.target = V4L2_SEL_TGT_CROP;
154	sel.r = *crop;
155
156	ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_selection, NULL,
157			       &sel);
158	if (ret < 0)
159		return ret;
160
161	dev_dbg(vsp1->dev,
162		"%s: set selection (%u,%u)/%ux%u on RPF%u sink\n",
163		__func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height,
164		rpf->entity.index);
165
166	/*
167	 * RPF source, hardcode the format to ARGB8888 to turn on format
168	 * conversion if needed.
169	 */
170	format.pad = RWPF_PAD_SOURCE;
171
172	ret = v4l2_subdev_call(&rpf->entity.subdev, pad, get_fmt, NULL,
173			       &format);
174	if (ret < 0)
175		return ret;
176
177	dev_dbg(vsp1->dev,
178		"%s: got format %ux%u (%x) on RPF%u source\n",
179		__func__, format.format.width, format.format.height,
180		format.format.code, rpf->entity.index);
181
182	format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
183
184	ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_fmt, NULL,
185			       &format);
186	if (ret < 0)
187		return ret;
188
189	/* Insert and configure the UIF if available. */
190	ret = vsp1_du_insert_uif(vsp1, pipe, uif, &rpf->entity, RWPF_PAD_SOURCE,
191				 pipe->brx, brx_input);
192	if (ret < 0)
193		return ret;
194
195	/* BRx sink, propagate the format from the RPF source. */
196	format.pad = brx_input;
197
198	ret = v4l2_subdev_call(&pipe->brx->subdev, pad, set_fmt, NULL,
199			       &format);
200	if (ret < 0)
201		return ret;
202
203	dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n",
204		__func__, format.format.width, format.format.height,
205		format.format.code, BRX_NAME(pipe->brx), format.pad);
206
207	sel.pad = brx_input;
208	sel.target = V4L2_SEL_TGT_COMPOSE;
209	sel.r = vsp1->drm->inputs[rpf->entity.index].compose;
210
211	ret = v4l2_subdev_call(&pipe->brx->subdev, pad, set_selection, NULL,
212			       &sel);
213	if (ret < 0)
214		return ret;
215
216	dev_dbg(vsp1->dev, "%s: set selection (%u,%u)/%ux%u on %s pad %u\n",
217		__func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height,
218		BRX_NAME(pipe->brx), sel.pad);
219
220	return 0;
221}
222
223/* Setup the BRx source pad. */
224static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
225					 struct vsp1_pipeline *pipe);
226static void vsp1_du_pipeline_configure(struct vsp1_pipeline *pipe);
227
228static int vsp1_du_pipeline_setup_brx(struct vsp1_device *vsp1,
229				      struct vsp1_pipeline *pipe)
230{
231	struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
232	struct v4l2_subdev_format format = {
233		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
234	};
235	struct vsp1_entity *brx;
236	int ret;
237
238	/*
239	 * Pick a BRx:
240	 * - If we need more than two inputs, use the BRU.
241	 * - Otherwise, if we are not forced to release our BRx, keep it.
242	 * - Else, use any free BRx (randomly starting with the BRU).
243	 */
244	if (pipe->num_inputs > 2)
245		brx = &vsp1->bru->entity;
246	else if (pipe->brx && !drm_pipe->force_brx_release)
247		brx = pipe->brx;
248	else if (vsp1_feature(vsp1, VSP1_HAS_BRU) && !vsp1->bru->entity.pipe)
249		brx = &vsp1->bru->entity;
250	else
251		brx = &vsp1->brs->entity;
252
253	/* Switch BRx if needed. */
254	if (brx != pipe->brx) {
255		struct vsp1_entity *released_brx = NULL;
256
257		/* Release our BRx if we have one. */
258		if (pipe->brx) {
259			dev_dbg(vsp1->dev, "%s: pipe %u: releasing %s\n",
260				__func__, pipe->lif->index,
261				BRX_NAME(pipe->brx));
262
263			/*
264			 * The BRx might be acquired by the other pipeline in
265			 * the next step. We must thus remove it from the list
266			 * of entities for this pipeline. The other pipeline's
267			 * hardware configuration will reconfigure the BRx
268			 * routing.
269			 *
270			 * However, if the other pipeline doesn't acquire our
271			 * BRx, we need to keep it in the list, otherwise the
272			 * hardware configuration step won't disconnect it from
273			 * the pipeline. To solve this, store the released BRx
274			 * pointer to add it back to the list of entities later
275			 * if it isn't acquired by the other pipeline.
276			 */
277			released_brx = pipe->brx;
278
279			list_del(&pipe->brx->list_pipe);
280			pipe->brx->sink = NULL;
281			pipe->brx->pipe = NULL;
282			pipe->brx = NULL;
283		}
284
285		/*
286		 * If the BRx we need is in use, force the owner pipeline to
287		 * switch to the other BRx and wait until the switch completes.
288		 */
289		if (brx->pipe) {
290			struct vsp1_drm_pipeline *owner_pipe;
291
292			dev_dbg(vsp1->dev, "%s: pipe %u: waiting for %s\n",
293				__func__, pipe->lif->index, BRX_NAME(brx));
294
295			owner_pipe = to_vsp1_drm_pipeline(brx->pipe);
296			owner_pipe->force_brx_release = true;
297
298			vsp1_du_pipeline_setup_inputs(vsp1, &owner_pipe->pipe);
299			vsp1_du_pipeline_configure(&owner_pipe->pipe);
300
301			ret = wait_event_timeout(owner_pipe->wait_queue,
302						 !owner_pipe->force_brx_release,
303						 msecs_to_jiffies(500));
304			if (ret == 0)
305				dev_warn(vsp1->dev,
306					 "DRM pipeline %u reconfiguration timeout\n",
307					 owner_pipe->pipe.lif->index);
308		}
309
310		/*
311		 * If the BRx we have released previously hasn't been acquired
312		 * by the other pipeline, add it back to the entities list (with
313		 * the pipe pointer NULL) to let vsp1_du_pipeline_configure()
314		 * disconnect it from the hardware pipeline.
315		 */
316		if (released_brx && !released_brx->pipe)
317			list_add_tail(&released_brx->list_pipe,
318				      &pipe->entities);
319
320		/* Add the BRx to the pipeline. */
321		dev_dbg(vsp1->dev, "%s: pipe %u: acquired %s\n",
322			__func__, pipe->lif->index, BRX_NAME(brx));
323
324		pipe->brx = brx;
325		pipe->brx->pipe = pipe;
326		pipe->brx->sink = &pipe->output->entity;
327		pipe->brx->sink_pad = 0;
328
329		list_add_tail(&pipe->brx->list_pipe, &pipe->entities);
330	}
331
332	/*
333	 * Configure the format on the BRx source and verify that it matches the
334	 * requested format. We don't set the media bus code as it is configured
335	 * on the BRx sink pad 0 and propagated inside the entity, not on the
336	 * source pad.
337	 */
338	format.pad = brx->source_pad;
339	format.format.width = drm_pipe->width;
340	format.format.height = drm_pipe->height;
341	format.format.field = V4L2_FIELD_NONE;
342
343	ret = v4l2_subdev_call(&brx->subdev, pad, set_fmt, NULL,
344			       &format);
345	if (ret < 0)
346		return ret;
347
348	dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n",
349		__func__, format.format.width, format.format.height,
350		format.format.code, BRX_NAME(brx), brx->source_pad);
351
352	if (format.format.width != drm_pipe->width ||
353	    format.format.height != drm_pipe->height) {
354		dev_dbg(vsp1->dev, "%s: format mismatch\n", __func__);
355		return -EPIPE;
356	}
357
358	return 0;
359}
360
361static unsigned int rpf_zpos(struct vsp1_device *vsp1, struct vsp1_rwpf *rpf)
362{
363	return vsp1->drm->inputs[rpf->entity.index].zpos;
364}
365
366/* Setup the input side of the pipeline (RPFs and BRx). */
367static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
368					struct vsp1_pipeline *pipe)
369{
370	struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
371	struct vsp1_rwpf *inputs[VSP1_MAX_RPF] = { NULL, };
372	struct vsp1_entity *uif;
373	bool use_uif = false;
374	struct vsp1_brx *brx;
375	unsigned int i;
376	int ret;
377
378	/* Count the number of enabled inputs and sort them by Z-order. */
379	pipe->num_inputs = 0;
380
381	for (i = 0; i < vsp1->info->rpf_count; ++i) {
382		struct vsp1_rwpf *rpf = vsp1->rpf[i];
383		unsigned int j;
384
385		if (!pipe->inputs[i])
386			continue;
387
388		/* Insert the RPF in the sorted RPFs array. */
389		for (j = pipe->num_inputs++; j > 0; --j) {
390			if (rpf_zpos(vsp1, inputs[j-1]) <= rpf_zpos(vsp1, rpf))
391				break;
392			inputs[j] = inputs[j-1];
393		}
394
395		inputs[j] = rpf;
396	}
397
398	/*
399	 * Setup the BRx. This must be done before setting up the RPF input
400	 * pipelines as the BRx sink compose rectangles depend on the BRx source
401	 * format.
402	 */
403	ret = vsp1_du_pipeline_setup_brx(vsp1, pipe);
404	if (ret < 0) {
405		dev_err(vsp1->dev, "%s: failed to setup %s source\n", __func__,
406			BRX_NAME(pipe->brx));
407		return ret;
408	}
409
410	brx = to_brx(&pipe->brx->subdev);
411
412	/* Setup the RPF input pipeline for every enabled input. */
413	for (i = 0; i < pipe->brx->source_pad; ++i) {
414		struct vsp1_rwpf *rpf = inputs[i];
415
416		if (!rpf) {
417			brx->inputs[i].rpf = NULL;
418			continue;
419		}
420
421		if (!rpf->entity.pipe) {
422			rpf->entity.pipe = pipe;
423			list_add_tail(&rpf->entity.list_pipe, &pipe->entities);
424		}
425
426		brx->inputs[i].rpf = rpf;
427		rpf->brx_input = i;
428		rpf->entity.sink = pipe->brx;
429		rpf->entity.sink_pad = i;
430
431		dev_dbg(vsp1->dev, "%s: connecting RPF.%u to %s:%u\n",
432			__func__, rpf->entity.index, BRX_NAME(pipe->brx), i);
433
434		uif = drm_pipe->crc.source == VSP1_DU_CRC_PLANE &&
435		      drm_pipe->crc.index == i ? drm_pipe->uif : NULL;
436		if (uif)
437			use_uif = true;
438		ret = vsp1_du_pipeline_setup_rpf(vsp1, pipe, rpf, uif, i);
439		if (ret < 0) {
440			dev_err(vsp1->dev,
441				"%s: failed to setup RPF.%u\n",
442				__func__, rpf->entity.index);
443			return ret;
444		}
445	}
446
447	/* Insert and configure the UIF at the BRx output if available. */
448	uif = drm_pipe->crc.source == VSP1_DU_CRC_OUTPUT ? drm_pipe->uif : NULL;
449	if (uif)
450		use_uif = true;
451	ret = vsp1_du_insert_uif(vsp1, pipe, uif,
452				 pipe->brx, pipe->brx->source_pad,
453				 &pipe->output->entity, 0);
454	if (ret < 0)
455		dev_err(vsp1->dev, "%s: failed to setup UIF after %s\n",
456			__func__, BRX_NAME(pipe->brx));
457
458	/* If the DRM pipe does not have a UIF there is nothing we can update. */
459	if (!drm_pipe->uif)
460		return 0;
461
462	/*
463	 * If the UIF is not in use schedule it for removal by setting its pipe
464	 * pointer to NULL, vsp1_du_pipeline_configure() will remove it from the
465	 * hardware pipeline and from the pipeline's list of entities. Otherwise
466	 * make sure it is present in the pipeline's list of entities if it
467	 * wasn't already.
468	 */
469	if (!use_uif) {
470		drm_pipe->uif->pipe = NULL;
471	} else if (!drm_pipe->uif->pipe) {
472		drm_pipe->uif->pipe = pipe;
473		list_add_tail(&drm_pipe->uif->list_pipe, &pipe->entities);
474	}
475
476	return 0;
477}
478
479/* Setup the output side of the pipeline (WPF and LIF). */
480static int vsp1_du_pipeline_setup_output(struct vsp1_device *vsp1,
481					 struct vsp1_pipeline *pipe)
482{
483	struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
484	struct v4l2_subdev_format format = {
485		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
486	};
487	int ret;
488
489	format.pad = RWPF_PAD_SINK;
490	format.format.width = drm_pipe->width;
491	format.format.height = drm_pipe->height;
492	format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
493	format.format.field = V4L2_FIELD_NONE;
494
495	ret = v4l2_subdev_call(&pipe->output->entity.subdev, pad, set_fmt, NULL,
496			       &format);
497	if (ret < 0)
498		return ret;
499
500	dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on WPF%u sink\n",
501		__func__, format.format.width, format.format.height,
502		format.format.code, pipe->output->entity.index);
503
504	format.pad = RWPF_PAD_SOURCE;
505	ret = v4l2_subdev_call(&pipe->output->entity.subdev, pad, get_fmt, NULL,
506			       &format);
507	if (ret < 0)
508		return ret;
509
510	dev_dbg(vsp1->dev, "%s: got format %ux%u (%x) on WPF%u source\n",
511		__func__, format.format.width, format.format.height,
512		format.format.code, pipe->output->entity.index);
513
514	format.pad = LIF_PAD_SINK;
515	ret = v4l2_subdev_call(&pipe->lif->subdev, pad, set_fmt, NULL,
516			       &format);
517	if (ret < 0)
518		return ret;
519
520	dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on LIF%u sink\n",
521		__func__, format.format.width, format.format.height,
522		format.format.code, pipe->lif->index);
523
524	/*
525	 * Verify that the format at the output of the pipeline matches the
526	 * requested frame size and media bus code.
527	 */
528	if (format.format.width != drm_pipe->width ||
529	    format.format.height != drm_pipe->height ||
530	    format.format.code != MEDIA_BUS_FMT_ARGB8888_1X32) {
531		dev_dbg(vsp1->dev, "%s: format mismatch on LIF%u\n", __func__,
532			pipe->lif->index);
533		return -EPIPE;
534	}
535
536	return 0;
537}
538
539/* Configure all entities in the pipeline. */
540static void vsp1_du_pipeline_configure(struct vsp1_pipeline *pipe)
541{
542	struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
543	struct vsp1_entity *entity;
544	struct vsp1_entity *next;
545	struct vsp1_dl_list *dl;
546	struct vsp1_dl_body *dlb;
547	unsigned int dl_flags = 0;
548
549	if (drm_pipe->force_brx_release)
550		dl_flags |= VSP1_DL_FRAME_END_INTERNAL;
551	if (pipe->output->writeback)
552		dl_flags |= VSP1_DL_FRAME_END_WRITEBACK;
553
554	dl = vsp1_dl_list_get(pipe->output->dlm);
555	dlb = vsp1_dl_list_get_body0(dl);
556
557	list_for_each_entry_safe(entity, next, &pipe->entities, list_pipe) {
558		/* Disconnect unused entities from the pipeline. */
559		if (!entity->pipe) {
560			vsp1_dl_body_write(dlb, entity->route->reg,
561					   VI6_DPR_NODE_UNUSED);
562
563			entity->sink = NULL;
564			list_del(&entity->list_pipe);
565
566			continue;
567		}
568
569		vsp1_entity_route_setup(entity, pipe, dlb);
570		vsp1_entity_configure_stream(entity, pipe, dl, dlb);
571		vsp1_entity_configure_frame(entity, pipe, dl, dlb);
572		vsp1_entity_configure_partition(entity, pipe, dl, dlb);
573	}
574
575	vsp1_dl_list_commit(dl, dl_flags);
576}
577
578static int vsp1_du_pipeline_set_rwpf_format(struct vsp1_device *vsp1,
579					    struct vsp1_rwpf *rwpf,
580					    u32 pixelformat, unsigned int pitch)
581{
582	const struct vsp1_format_info *fmtinfo;
583	unsigned int chroma_hsub;
584
585	fmtinfo = vsp1_get_format_info(vsp1, pixelformat);
586	if (!fmtinfo) {
587		dev_dbg(vsp1->dev, "Unsupported pixel format %08x\n",
588			pixelformat);
589		return -EINVAL;
590	}
591
592	/*
593	 * Only formats with three planes can affect the chroma planes pitch.
594	 * All formats with two planes have a horizontal subsampling value of 2,
595	 * but combine U and V in a single chroma plane, which thus results in
596	 * the luma plane and chroma plane having the same pitch.
597	 */
598	chroma_hsub = (fmtinfo->planes == 3) ? fmtinfo->hsub : 1;
599
600	rwpf->fmtinfo = fmtinfo;
601	rwpf->format.num_planes = fmtinfo->planes;
602	rwpf->format.plane_fmt[0].bytesperline = pitch;
603	rwpf->format.plane_fmt[1].bytesperline = pitch / chroma_hsub;
604
605	return 0;
606}
607
608/* -----------------------------------------------------------------------------
609 * DU Driver API
610 */
611
612int vsp1_du_init(struct device *dev)
613{
614	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
615
616	if (!vsp1)
617		return -EPROBE_DEFER;
618
619	return 0;
620}
621EXPORT_SYMBOL_GPL(vsp1_du_init);
622
623/**
624 * vsp1_du_setup_lif - Setup the output part of the VSP pipeline
625 * @dev: the VSP device
626 * @pipe_index: the DRM pipeline index
627 * @cfg: the LIF configuration
628 *
629 * Configure the output part of VSP DRM pipeline for the given frame @cfg.width
630 * and @cfg.height. This sets up formats on the BRx source pad, the WPF sink and
631 * source pads, and the LIF sink pad.
632 *
633 * The @pipe_index argument selects which DRM pipeline to setup. The number of
634 * available pipelines depend on the VSP instance.
635 *
636 * As the media bus code on the blend unit source pad is conditioned by the
637 * configuration of its sink 0 pad, we also set up the formats on all blend unit
638 * sinks, even if the configuration will be overwritten later by
639 * vsp1_du_setup_rpf(). This ensures that the blend unit configuration is set to
640 * a well defined state.
641 *
642 * Return 0 on success or a negative error code on failure.
643 */
644int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index,
645		      const struct vsp1_du_lif_config *cfg)
646{
647	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
648	struct vsp1_drm_pipeline *drm_pipe;
649	struct vsp1_pipeline *pipe;
650	unsigned long flags;
651	unsigned int i;
652	int ret;
653
654	if (pipe_index >= vsp1->info->lif_count)
655		return -EINVAL;
656
657	drm_pipe = &vsp1->drm->pipe[pipe_index];
658	pipe = &drm_pipe->pipe;
659
660	if (!cfg) {
661		struct vsp1_brx *brx;
662
663		mutex_lock(&vsp1->drm->lock);
664
665		brx = to_brx(&pipe->brx->subdev);
666
667		/*
668		 * NULL configuration means the CRTC is being disabled, stop
669		 * the pipeline and turn the light off.
670		 */
671		ret = vsp1_pipeline_stop(pipe);
672		if (ret == -ETIMEDOUT)
673			dev_err(vsp1->dev, "DRM pipeline stop timeout\n");
674
675		for (i = 0; i < ARRAY_SIZE(pipe->inputs); ++i) {
676			struct vsp1_rwpf *rpf = pipe->inputs[i];
677
678			if (!rpf)
679				continue;
680
681			/*
682			 * Remove the RPF from the pipe and the list of BRx
683			 * inputs.
684			 */
685			WARN_ON(!rpf->entity.pipe);
686			rpf->entity.pipe = NULL;
687			list_del(&rpf->entity.list_pipe);
688			pipe->inputs[i] = NULL;
689
690			brx->inputs[rpf->brx_input].rpf = NULL;
691		}
692
693		drm_pipe->du_complete = NULL;
694		pipe->num_inputs = 0;
695
696		dev_dbg(vsp1->dev, "%s: pipe %u: releasing %s\n",
697			__func__, pipe->lif->index,
698			BRX_NAME(pipe->brx));
699
700		list_del(&pipe->brx->list_pipe);
701		pipe->brx->pipe = NULL;
702		pipe->brx = NULL;
703
704		mutex_unlock(&vsp1->drm->lock);
705
706		vsp1_dlm_reset(pipe->output->dlm);
707		vsp1_device_put(vsp1);
708
709		dev_dbg(vsp1->dev, "%s: pipeline disabled\n", __func__);
710
711		return 0;
712	}
713
714	/* Reset the underrun counter */
715	pipe->underrun_count = 0;
716
717	drm_pipe->width = cfg->width;
718	drm_pipe->height = cfg->height;
719	pipe->interlaced = cfg->interlaced;
720
721	dev_dbg(vsp1->dev, "%s: configuring LIF%u with format %ux%u%s\n",
722		__func__, pipe_index, cfg->width, cfg->height,
723		pipe->interlaced ? "i" : "");
724
725	mutex_lock(&vsp1->drm->lock);
726
727	/* Setup formats through the pipeline. */
728	ret = vsp1_du_pipeline_setup_inputs(vsp1, pipe);
729	if (ret < 0)
730		goto unlock;
731
732	ret = vsp1_du_pipeline_setup_output(vsp1, pipe);
733	if (ret < 0)
734		goto unlock;
735
736	/* Enable the VSP1. */
737	ret = vsp1_device_get(vsp1);
738	if (ret < 0)
739		goto unlock;
740
741	/*
742	 * Register a callback to allow us to notify the DRM driver of frame
743	 * completion events.
744	 */
745	drm_pipe->du_complete = cfg->callback;
746	drm_pipe->du_private = cfg->callback_data;
747
748	/* Disable the display interrupts. */
749	vsp1_write(vsp1, VI6_DISP_IRQ_STA(pipe_index), 0);
750	vsp1_write(vsp1, VI6_DISP_IRQ_ENB(pipe_index), 0);
751
752	/* Configure all entities in the pipeline. */
753	vsp1_du_pipeline_configure(pipe);
754
755unlock:
756	mutex_unlock(&vsp1->drm->lock);
757
758	if (ret < 0)
759		return ret;
760
761	/* Start the pipeline. */
762	spin_lock_irqsave(&pipe->irqlock, flags);
763	vsp1_pipeline_run(pipe);
764	spin_unlock_irqrestore(&pipe->irqlock, flags);
765
766	dev_dbg(vsp1->dev, "%s: pipeline enabled\n", __func__);
767
768	return 0;
769}
770EXPORT_SYMBOL_GPL(vsp1_du_setup_lif);
771
772/**
773 * vsp1_du_atomic_begin - Prepare for an atomic update
774 * @dev: the VSP device
775 * @pipe_index: the DRM pipeline index
776 */
777void vsp1_du_atomic_begin(struct device *dev, unsigned int pipe_index)
778{
779}
780EXPORT_SYMBOL_GPL(vsp1_du_atomic_begin);
781
782/**
783 * vsp1_du_atomic_update - Setup one RPF input of the VSP pipeline
784 * @dev: the VSP device
785 * @pipe_index: the DRM pipeline index
786 * @rpf_index: index of the RPF to setup (0-based)
787 * @cfg: the RPF configuration
788 *
789 * Configure the VSP to perform image composition through RPF @rpf_index as
790 * described by the @cfg configuration. The image to compose is referenced by
791 * @cfg.mem and composed using the @cfg.src crop rectangle and the @cfg.dst
792 * composition rectangle. The Z-order is configurable with higher @zpos values
793 * displayed on top.
794 *
795 * If the @cfg configuration is NULL, the RPF will be disabled. Calling the
796 * function on a disabled RPF is allowed.
797 *
798 * Image format as stored in memory is expressed as a V4L2 @cfg.pixelformat
799 * value. The memory pitch is configurable to allow for padding at end of lines,
800 * or simply for images that extend beyond the crop rectangle boundaries. The
801 * @cfg.pitch value is expressed in bytes and applies to all planes for
802 * multiplanar formats.
803 *
804 * The source memory buffer is referenced by the DMA address of its planes in
805 * the @cfg.mem array. Up to two planes are supported. The second plane DMA
806 * address is ignored for formats using a single plane.
807 *
808 * This function isn't reentrant, the caller needs to serialize calls.
809 *
810 * Return 0 on success or a negative error code on failure.
811 */
812int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
813			  unsigned int rpf_index,
814			  const struct vsp1_du_atomic_config *cfg)
815{
816	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
817	struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
818	struct vsp1_rwpf *rpf;
819	int ret;
820
821	if (rpf_index >= vsp1->info->rpf_count)
822		return -EINVAL;
823
824	rpf = vsp1->rpf[rpf_index];
825
826	if (!cfg) {
827		dev_dbg(vsp1->dev, "%s: RPF%u: disable requested\n", __func__,
828			rpf_index);
829
830		/*
831		 * Remove the RPF from the pipeline's inputs. Keep it in the
832		 * pipeline's entity list to let vsp1_du_pipeline_configure()
833		 * remove it from the hardware pipeline.
834		 */
835		rpf->entity.pipe = NULL;
836		drm_pipe->pipe.inputs[rpf_index] = NULL;
837		return 0;
838	}
839
840	dev_dbg(vsp1->dev,
841		"%s: RPF%u: (%u,%u)/%ux%u -> (%u,%u)/%ux%u (%08x), pitch %u dma { %pad, %pad, %pad } zpos %u\n",
842		__func__, rpf_index,
843		cfg->src.left, cfg->src.top, cfg->src.width, cfg->src.height,
844		cfg->dst.left, cfg->dst.top, cfg->dst.width, cfg->dst.height,
845		cfg->pixelformat, cfg->pitch, &cfg->mem[0], &cfg->mem[1],
846		&cfg->mem[2], cfg->zpos);
847
848	/*
849	 * Store the format, stride, memory buffer address, crop and compose
850	 * rectangles and Z-order position and for the input.
851	 */
852	ret = vsp1_du_pipeline_set_rwpf_format(vsp1, rpf, cfg->pixelformat,
853					       cfg->pitch);
854	if (ret < 0)
855		return ret;
856
857	rpf->alpha = cfg->alpha;
858
859	rpf->mem.addr[0] = cfg->mem[0];
860	rpf->mem.addr[1] = cfg->mem[1];
861	rpf->mem.addr[2] = cfg->mem[2];
862
863	rpf->format.flags = cfg->premult ? V4L2_PIX_FMT_FLAG_PREMUL_ALPHA : 0;
864
865	vsp1->drm->inputs[rpf_index].crop = cfg->src;
866	vsp1->drm->inputs[rpf_index].compose = cfg->dst;
867	vsp1->drm->inputs[rpf_index].zpos = cfg->zpos;
868
869	drm_pipe->pipe.inputs[rpf_index] = rpf;
870
871	return 0;
872}
873EXPORT_SYMBOL_GPL(vsp1_du_atomic_update);
874
875/**
876 * vsp1_du_atomic_flush - Commit an atomic update
877 * @dev: the VSP device
878 * @pipe_index: the DRM pipeline index
879 * @cfg: atomic pipe configuration
880 */
881void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
882			  const struct vsp1_du_atomic_pipe_config *cfg)
883{
884	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
885	struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
886	struct vsp1_pipeline *pipe = &drm_pipe->pipe;
887	int ret;
888
889	drm_pipe->crc = cfg->crc;
890
891	mutex_lock(&vsp1->drm->lock);
892
893	if (cfg->writeback.pixelformat) {
894		const struct vsp1_du_writeback_config *wb_cfg = &cfg->writeback;
895
896		ret = vsp1_du_pipeline_set_rwpf_format(vsp1, pipe->output,
897						       wb_cfg->pixelformat,
898						       wb_cfg->pitch);
899		if (WARN_ON(ret < 0))
900			goto done;
901
902		pipe->output->mem.addr[0] = wb_cfg->mem[0];
903		pipe->output->mem.addr[1] = wb_cfg->mem[1];
904		pipe->output->mem.addr[2] = wb_cfg->mem[2];
905		pipe->output->writeback = true;
906	}
907
908	vsp1_du_pipeline_setup_inputs(vsp1, pipe);
909	vsp1_du_pipeline_configure(pipe);
910
911done:
912	mutex_unlock(&vsp1->drm->lock);
913}
914EXPORT_SYMBOL_GPL(vsp1_du_atomic_flush);
915
916int vsp1_du_map_sg(struct device *dev, struct sg_table *sgt)
917{
918	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
919
920	/*
921	 * As all the buffers allocated by the DU driver are coherent, we can
922	 * skip cache sync. This will need to be revisited when support for
923	 * non-coherent buffers will be added to the DU driver.
924	 */
925	return dma_map_sgtable(vsp1->bus_master, sgt, DMA_TO_DEVICE,
926			       DMA_ATTR_SKIP_CPU_SYNC);
927}
928EXPORT_SYMBOL_GPL(vsp1_du_map_sg);
929
930void vsp1_du_unmap_sg(struct device *dev, struct sg_table *sgt)
931{
932	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
933
934	dma_unmap_sgtable(vsp1->bus_master, sgt, DMA_TO_DEVICE,
935			  DMA_ATTR_SKIP_CPU_SYNC);
936}
937EXPORT_SYMBOL_GPL(vsp1_du_unmap_sg);
938
939/* -----------------------------------------------------------------------------
940 * Initialization
941 */
942
943int vsp1_drm_init(struct vsp1_device *vsp1)
944{
945	unsigned int i;
946
947	vsp1->drm = devm_kzalloc(vsp1->dev, sizeof(*vsp1->drm), GFP_KERNEL);
948	if (!vsp1->drm)
949		return -ENOMEM;
950
951	mutex_init(&vsp1->drm->lock);
952
953	/* Create one DRM pipeline per LIF. */
954	for (i = 0; i < vsp1->info->lif_count; ++i) {
955		struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[i];
956		struct vsp1_pipeline *pipe = &drm_pipe->pipe;
957
958		init_waitqueue_head(&drm_pipe->wait_queue);
959
960		vsp1_pipeline_init(pipe);
961
962		pipe->frame_end = vsp1_du_pipeline_frame_end;
963
964		/*
965		 * The output side of the DRM pipeline is static, add the
966		 * corresponding entities manually.
967		 */
968		pipe->output = vsp1->wpf[i];
969		pipe->lif = &vsp1->lif[i]->entity;
970
971		pipe->output->entity.pipe = pipe;
972		pipe->output->entity.sink = pipe->lif;
973		pipe->output->entity.sink_pad = 0;
974		list_add_tail(&pipe->output->entity.list_pipe, &pipe->entities);
975
976		pipe->lif->pipe = pipe;
977		list_add_tail(&pipe->lif->list_pipe, &pipe->entities);
978
979		/*
980		 * CRC computation is initially disabled, don't add the UIF to
981		 * the pipeline.
982		 */
983		if (i < vsp1->info->uif_count)
984			drm_pipe->uif = &vsp1->uif[i]->entity;
985	}
986
987	/* Disable all RPFs initially. */
988	for (i = 0; i < vsp1->info->rpf_count; ++i) {
989		struct vsp1_rwpf *input = vsp1->rpf[i];
990
991		INIT_LIST_HEAD(&input->entity.list_pipe);
992	}
993
994	return 0;
995}
996
997void vsp1_drm_cleanup(struct vsp1_device *vsp1)
998{
999	mutex_destroy(&vsp1->drm->lock);
1000}
1001