• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * ZynqMP Display Controller Driver
4  *
5  * Copyright (C) 2017 - 2020 Xilinx, Inc.
6  *
7  * Authors:
8  * - Hyun Woo Kwon <hyun.kwon@xilinx.com>
9  * - Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10  */
11 
12 #include <drm/drm_atomic.h>
13 #include <drm/drm_atomic_helper.h>
14 #include <drm/drm_atomic_uapi.h>
15 #include <drm/drm_blend.h>
16 #include <drm/drm_crtc.h>
17 #include <drm/drm_device.h>
18 #include <drm/drm_fb_dma_helper.h>
19 #include <drm/drm_fourcc.h>
20 #include <drm/drm_framebuffer.h>
21 #include <drm/drm_managed.h>
22 #include <drm/drm_plane.h>
23 #include <drm/drm_vblank.h>
24 
25 #include <linux/clk.h>
26 #include <linux/delay.h>
27 #include <linux/dma/xilinx_dpdma.h>
28 #include <linux/dma-mapping.h>
29 #include <linux/dmaengine.h>
30 #include <linux/module.h>
31 #include <linux/of.h>
32 #include <linux/platform_device.h>
33 #include <linux/pm_runtime.h>
34 #include <linux/spinlock.h>
35 
36 #include "zynqmp_disp.h"
37 #include "zynqmp_disp_regs.h"
38 #include "zynqmp_dp.h"
39 #include "zynqmp_dpsub.h"
40 
41 /*
42  * Overview
43  * --------
44  *
45  * The display controller part of ZynqMP DP subsystem, made of the Audio/Video
46  * Buffer Manager, the Video Rendering Pipeline (blender) and the Audio Mixer.
47  *
48  *              +------------------------------------------------------------+
49  * +--------+   | +----------------+     +-----------+                       |
50  * | DPDMA  | --->|                | --> |   Video   | Video +-------------+ |
51  * | 4x vid |   | |                |     | Rendering | -+--> |             | |   +------+
52  * | 2x aud |   | |  Audio/Video   | --> | Pipeline  |  |    | DisplayPort |---> | PHY0 |
53  * +--------+   | | Buffer Manager |     +-----------+  |    |   Source    | |   +------+
54  *              | |    and STC     |     +-----------+  |    | Controller  | |   +------+
55  * Live Video --->|                | --> |   Audio   | Audio |             |---> | PHY1 |
56  *              | |                |     |   Mixer   | --+-> |             | |   +------+
57  * Live Audio --->|                | --> |           |  ||   +-------------+ |
58  *              | +----------------+     +-----------+  ||                   |
59  *              +---------------------------------------||-------------------+
60  *                                                      vv
61  *                                                Blended Video and
62  *                                                Mixed Audio to PL
63  *
64  * Only non-live input from the DPDMA and output to the DisplayPort Source
65  * Controller are currently supported. Interface with the programmable logic
66  * for live streams is not implemented.
67  *
68  * The display controller code creates planes for the DPDMA video and graphics
69  * layers, and a CRTC for the Video Rendering Pipeline.
70  */
71 
72 #define ZYNQMP_DISP_AV_BUF_NUM_VID_GFX_BUFFERS		4
73 #define ZYNQMP_DISP_AV_BUF_NUM_BUFFERS			6
74 
75 #define ZYNQMP_DISP_NUM_LAYERS				2
76 #define ZYNQMP_DISP_MAX_NUM_SUB_PLANES			3
77 
78 /**
79  * struct zynqmp_disp_format - Display subsystem format information
80  * @drm_fmt: DRM format (4CC)
81  * @buf_fmt: AV buffer format
82  * @bus_fmt: Media bus formats (live formats)
83  * @swap: Flag to swap R & B for RGB formats, and U & V for YUV formats
84  * @sf: Scaling factors for color components
85  */
86 struct zynqmp_disp_format {
87 	u32 drm_fmt;
88 	u32 buf_fmt;
89 	u32 bus_fmt;
90 	bool swap;
91 	const u32 *sf;
92 };
93 
94 /**
95  * enum zynqmp_disp_layer_id - Layer identifier
96  * @ZYNQMP_DISP_LAYER_VID: Video layer
97  * @ZYNQMP_DISP_LAYER_GFX: Graphics layer
98  */
99 enum zynqmp_disp_layer_id {
100 	ZYNQMP_DISP_LAYER_VID,
101 	ZYNQMP_DISP_LAYER_GFX
102 };
103 
104 /**
105  * enum zynqmp_disp_layer_mode - Layer mode
106  * @ZYNQMP_DISP_LAYER_NONLIVE: non-live (memory) mode
107  * @ZYNQMP_DISP_LAYER_LIVE: live (stream) mode
108  */
109 enum zynqmp_disp_layer_mode {
110 	ZYNQMP_DISP_LAYER_NONLIVE,
111 	ZYNQMP_DISP_LAYER_LIVE
112 };
113 
114 /**
115  * struct zynqmp_disp_layer_dma - DMA channel for one data plane of a layer
116  * @chan: DMA channel
117  * @xt: Interleaved DMA descriptor template
118  * @sgl: Data chunk for dma_interleaved_template
119  */
120 struct zynqmp_disp_layer_dma {
121 	struct dma_chan *chan;
122 	struct dma_interleaved_template xt;
123 	struct data_chunk sgl;
124 };
125 
126 /**
127  * struct zynqmp_disp_layer_info - Static layer information
128  * @formats: Array of supported formats
129  * @num_formats: Number of formats in @formats array
130  * @num_channels: Number of DMA channels
131  */
132 struct zynqmp_disp_layer_info {
133 	const struct zynqmp_disp_format *formats;
134 	unsigned int num_formats;
135 	unsigned int num_channels;
136 };
137 
138 /**
139  * struct zynqmp_disp_layer - Display layer (DRM plane)
140  * @plane: DRM plane
141  * @id: Layer ID
142  * @disp: Back pointer to struct zynqmp_disp
143  * @info: Static layer information
144  * @dmas: DMA channels
145  * @disp_fmt: Current format information
146  * @drm_fmt: Current DRM format information
147  * @mode: Current operation mode
148  */
149 struct zynqmp_disp_layer {
150 	struct drm_plane plane;
151 	enum zynqmp_disp_layer_id id;
152 	struct zynqmp_disp *disp;
153 	const struct zynqmp_disp_layer_info *info;
154 
155 	struct zynqmp_disp_layer_dma dmas[ZYNQMP_DISP_MAX_NUM_SUB_PLANES];
156 
157 	const struct zynqmp_disp_format *disp_fmt;
158 	const struct drm_format_info *drm_fmt;
159 	enum zynqmp_disp_layer_mode mode;
160 };
161 
162 /**
163  * struct zynqmp_disp - Display controller
164  * @dev: Device structure
165  * @drm: DRM core
166  * @dpsub: Display subsystem
167  * @crtc: DRM CRTC
168  * @blend.base: Register I/O base address for the blender
169  * @avbuf.base: Register I/O base address for the audio/video buffer manager
170  * @audio.base: Registers I/O base address for the audio mixer
171  * @audio.clk: Audio clock
172  * @audio.clk_from_ps: True of the audio clock comes from PS, false from PL
173  * @layers: Layers (planes)
174  * @event: Pending vblank event request
175  * @pclk: Pixel clock
176  * @pclk_from_ps: True of the video clock comes from PS, false from PL
177  */
178 struct zynqmp_disp {
179 	struct device *dev;
180 	struct drm_device *drm;
181 	struct zynqmp_dpsub *dpsub;
182 
183 	struct drm_crtc crtc;
184 
185 	struct {
186 		void __iomem *base;
187 	} blend;
188 	struct {
189 		void __iomem *base;
190 	} avbuf;
191 	struct {
192 		void __iomem *base;
193 		struct clk *clk;
194 		bool clk_from_ps;
195 	} audio;
196 
197 	struct zynqmp_disp_layer layers[ZYNQMP_DISP_NUM_LAYERS];
198 
199 	struct drm_pending_vblank_event *event;
200 
201 	struct clk *pclk;
202 	bool pclk_from_ps;
203 };
204 
205 /* -----------------------------------------------------------------------------
206  * Audio/Video Buffer Manager
207  */
208 
209 static const u32 scaling_factors_444[] = {
210 	ZYNQMP_DISP_AV_BUF_4BIT_SF,
211 	ZYNQMP_DISP_AV_BUF_4BIT_SF,
212 	ZYNQMP_DISP_AV_BUF_4BIT_SF,
213 };
214 
215 static const u32 scaling_factors_555[] = {
216 	ZYNQMP_DISP_AV_BUF_5BIT_SF,
217 	ZYNQMP_DISP_AV_BUF_5BIT_SF,
218 	ZYNQMP_DISP_AV_BUF_5BIT_SF,
219 };
220 
221 static const u32 scaling_factors_565[] = {
222 	ZYNQMP_DISP_AV_BUF_5BIT_SF,
223 	ZYNQMP_DISP_AV_BUF_6BIT_SF,
224 	ZYNQMP_DISP_AV_BUF_5BIT_SF,
225 };
226 
227 static const u32 scaling_factors_888[] = {
228 	ZYNQMP_DISP_AV_BUF_8BIT_SF,
229 	ZYNQMP_DISP_AV_BUF_8BIT_SF,
230 	ZYNQMP_DISP_AV_BUF_8BIT_SF,
231 };
232 
233 static const u32 scaling_factors_101010[] = {
234 	ZYNQMP_DISP_AV_BUF_10BIT_SF,
235 	ZYNQMP_DISP_AV_BUF_10BIT_SF,
236 	ZYNQMP_DISP_AV_BUF_10BIT_SF,
237 };
238 
239 /* List of video layer formats */
240 static const struct zynqmp_disp_format avbuf_vid_fmts[] = {
241 	{
242 		.drm_fmt	= DRM_FORMAT_VYUY,
243 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_VYUY,
244 		.swap		= true,
245 		.sf		= scaling_factors_888,
246 	}, {
247 		.drm_fmt	= DRM_FORMAT_UYVY,
248 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_VYUY,
249 		.swap		= false,
250 		.sf		= scaling_factors_888,
251 	}, {
252 		.drm_fmt	= DRM_FORMAT_YUYV,
253 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YUYV,
254 		.swap		= false,
255 		.sf		= scaling_factors_888,
256 	}, {
257 		.drm_fmt	= DRM_FORMAT_YVYU,
258 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YUYV,
259 		.swap		= true,
260 		.sf		= scaling_factors_888,
261 	}, {
262 		.drm_fmt	= DRM_FORMAT_YUV422,
263 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16,
264 		.swap		= false,
265 		.sf		= scaling_factors_888,
266 	}, {
267 		.drm_fmt	= DRM_FORMAT_YVU422,
268 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16,
269 		.swap		= true,
270 		.sf		= scaling_factors_888,
271 	}, {
272 		.drm_fmt	= DRM_FORMAT_YUV444,
273 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV24,
274 		.swap		= false,
275 		.sf		= scaling_factors_888,
276 	}, {
277 		.drm_fmt	= DRM_FORMAT_YVU444,
278 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV24,
279 		.swap		= true,
280 		.sf		= scaling_factors_888,
281 	}, {
282 		.drm_fmt	= DRM_FORMAT_NV16,
283 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI,
284 		.swap		= false,
285 		.sf		= scaling_factors_888,
286 	}, {
287 		.drm_fmt	= DRM_FORMAT_NV61,
288 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI,
289 		.swap		= true,
290 		.sf		= scaling_factors_888,
291 	}, {
292 		.drm_fmt	= DRM_FORMAT_BGR888,
293 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGB888,
294 		.swap		= false,
295 		.sf		= scaling_factors_888,
296 	}, {
297 		.drm_fmt	= DRM_FORMAT_RGB888,
298 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGB888,
299 		.swap		= true,
300 		.sf		= scaling_factors_888,
301 	}, {
302 		.drm_fmt	= DRM_FORMAT_XBGR8888,
303 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGBA8880,
304 		.swap		= false,
305 		.sf		= scaling_factors_888,
306 	}, {
307 		.drm_fmt	= DRM_FORMAT_XRGB8888,
308 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGBA8880,
309 		.swap		= true,
310 		.sf		= scaling_factors_888,
311 	}, {
312 		.drm_fmt	= DRM_FORMAT_XBGR2101010,
313 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGB888_10,
314 		.swap		= false,
315 		.sf		= scaling_factors_101010,
316 	}, {
317 		.drm_fmt	= DRM_FORMAT_XRGB2101010,
318 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGB888_10,
319 		.swap		= true,
320 		.sf		= scaling_factors_101010,
321 	}, {
322 		.drm_fmt	= DRM_FORMAT_YUV420,
323 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16_420,
324 		.swap		= false,
325 		.sf		= scaling_factors_888,
326 	}, {
327 		.drm_fmt	= DRM_FORMAT_YVU420,
328 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16_420,
329 		.swap		= true,
330 		.sf		= scaling_factors_888,
331 	}, {
332 		.drm_fmt	= DRM_FORMAT_NV12,
333 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI_420,
334 		.swap		= false,
335 		.sf		= scaling_factors_888,
336 	}, {
337 		.drm_fmt	= DRM_FORMAT_NV21,
338 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI_420,
339 		.swap		= true,
340 		.sf		= scaling_factors_888,
341 	},
342 };
343 
344 /* List of graphics layer formats */
345 static const struct zynqmp_disp_format avbuf_gfx_fmts[] = {
346 	{
347 		.drm_fmt	= DRM_FORMAT_ABGR8888,
348 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA8888,
349 		.swap		= false,
350 		.sf		= scaling_factors_888,
351 	}, {
352 		.drm_fmt	= DRM_FORMAT_ARGB8888,
353 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA8888,
354 		.swap		= true,
355 		.sf		= scaling_factors_888,
356 	}, {
357 		.drm_fmt	= DRM_FORMAT_RGBA8888,
358 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_ABGR8888,
359 		.swap		= false,
360 		.sf		= scaling_factors_888,
361 	}, {
362 		.drm_fmt	= DRM_FORMAT_BGRA8888,
363 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_ABGR8888,
364 		.swap		= true,
365 		.sf		= scaling_factors_888,
366 	}, {
367 		.drm_fmt	= DRM_FORMAT_BGR888,
368 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGB888,
369 		.swap		= false,
370 		.sf		= scaling_factors_888,
371 	}, {
372 		.drm_fmt	= DRM_FORMAT_RGB888,
373 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_BGR888,
374 		.swap		= false,
375 		.sf		= scaling_factors_888,
376 	}, {
377 		.drm_fmt	= DRM_FORMAT_RGBA5551,
378 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA5551,
379 		.swap		= false,
380 		.sf		= scaling_factors_555,
381 	}, {
382 		.drm_fmt	= DRM_FORMAT_BGRA5551,
383 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA5551,
384 		.swap		= true,
385 		.sf		= scaling_factors_555,
386 	}, {
387 		.drm_fmt	= DRM_FORMAT_RGBA4444,
388 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA4444,
389 		.swap		= false,
390 		.sf		= scaling_factors_444,
391 	}, {
392 		.drm_fmt	= DRM_FORMAT_BGRA4444,
393 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA4444,
394 		.swap		= true,
395 		.sf		= scaling_factors_444,
396 	}, {
397 		.drm_fmt	= DRM_FORMAT_RGB565,
398 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGB565,
399 		.swap		= false,
400 		.sf		= scaling_factors_565,
401 	}, {
402 		.drm_fmt	= DRM_FORMAT_BGR565,
403 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGB565,
404 		.swap		= true,
405 		.sf		= scaling_factors_565,
406 	},
407 };
408 
zynqmp_disp_avbuf_read(struct zynqmp_disp * disp,int reg)409 static u32 zynqmp_disp_avbuf_read(struct zynqmp_disp *disp, int reg)
410 {
411 	return readl(disp->avbuf.base + reg);
412 }
413 
zynqmp_disp_avbuf_write(struct zynqmp_disp * disp,int reg,u32 val)414 static void zynqmp_disp_avbuf_write(struct zynqmp_disp *disp, int reg, u32 val)
415 {
416 	writel(val, disp->avbuf.base + reg);
417 }
418 
zynqmp_disp_layer_is_gfx(const struct zynqmp_disp_layer * layer)419 static bool zynqmp_disp_layer_is_gfx(const struct zynqmp_disp_layer *layer)
420 {
421 	return layer->id == ZYNQMP_DISP_LAYER_GFX;
422 }
423 
zynqmp_disp_layer_is_video(const struct zynqmp_disp_layer * layer)424 static bool zynqmp_disp_layer_is_video(const struct zynqmp_disp_layer *layer)
425 {
426 	return layer->id == ZYNQMP_DISP_LAYER_VID;
427 }
428 
429 /**
430  * zynqmp_disp_avbuf_set_format - Set the input format for a layer
431  * @disp: Display controller
432  * @layer: The layer
433  * @fmt: The format information
434  *
435  * Set the video buffer manager format for @layer to @fmt.
436  */
zynqmp_disp_avbuf_set_format(struct zynqmp_disp * disp,struct zynqmp_disp_layer * layer,const struct zynqmp_disp_format * fmt)437 static void zynqmp_disp_avbuf_set_format(struct zynqmp_disp *disp,
438 					 struct zynqmp_disp_layer *layer,
439 					 const struct zynqmp_disp_format *fmt)
440 {
441 	unsigned int i;
442 	u32 val;
443 
444 	val = zynqmp_disp_avbuf_read(disp, ZYNQMP_DISP_AV_BUF_FMT);
445 	val &= zynqmp_disp_layer_is_video(layer)
446 	    ? ~ZYNQMP_DISP_AV_BUF_FMT_NL_VID_MASK
447 	    : ~ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_MASK;
448 	val |= fmt->buf_fmt;
449 	zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_FMT, val);
450 
451 	for (i = 0; i < ZYNQMP_DISP_AV_BUF_NUM_SF; i++) {
452 		unsigned int reg = zynqmp_disp_layer_is_video(layer)
453 				 ? ZYNQMP_DISP_AV_BUF_VID_COMP_SF(i)
454 				 : ZYNQMP_DISP_AV_BUF_GFX_COMP_SF(i);
455 
456 		zynqmp_disp_avbuf_write(disp, reg, fmt->sf[i]);
457 	}
458 }
459 
460 /**
461  * zynqmp_disp_avbuf_set_clocks_sources - Set the clocks sources
462  * @disp: Display controller
463  * @video_from_ps: True if the video clock originates from the PS
464  * @audio_from_ps: True if the audio clock originates from the PS
465  * @timings_internal: True if video timings are generated internally
466  *
467  * Set the source for the video and audio clocks, as well as for the video
468  * timings. Clocks can originate from the PS or PL, and timings can be
469  * generated internally or externally.
470  */
471 static void
zynqmp_disp_avbuf_set_clocks_sources(struct zynqmp_disp * disp,bool video_from_ps,bool audio_from_ps,bool timings_internal)472 zynqmp_disp_avbuf_set_clocks_sources(struct zynqmp_disp *disp,
473 				     bool video_from_ps, bool audio_from_ps,
474 				     bool timings_internal)
475 {
476 	u32 val = 0;
477 
478 	if (video_from_ps)
479 		val |= ZYNQMP_DISP_AV_BUF_CLK_SRC_VID_FROM_PS;
480 	if (audio_from_ps)
481 		val |= ZYNQMP_DISP_AV_BUF_CLK_SRC_AUD_FROM_PS;
482 	if (timings_internal)
483 		val |= ZYNQMP_DISP_AV_BUF_CLK_SRC_VID_INTERNAL_TIMING;
484 
485 	zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_CLK_SRC, val);
486 }
487 
488 /**
489  * zynqmp_disp_avbuf_enable_channels - Enable buffer channels
490  * @disp: Display controller
491  *
492  * Enable all (video and audio) buffer channels.
493  */
zynqmp_disp_avbuf_enable_channels(struct zynqmp_disp * disp)494 static void zynqmp_disp_avbuf_enable_channels(struct zynqmp_disp *disp)
495 {
496 	unsigned int i;
497 	u32 val;
498 
499 	val = ZYNQMP_DISP_AV_BUF_CHBUF_EN |
500 	      (ZYNQMP_DISP_AV_BUF_CHBUF_BURST_LEN_MAX <<
501 	       ZYNQMP_DISP_AV_BUF_CHBUF_BURST_LEN_SHIFT);
502 
503 	for (i = 0; i < ZYNQMP_DISP_AV_BUF_NUM_VID_GFX_BUFFERS; i++)
504 		zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_CHBUF(i),
505 					val);
506 
507 	val = ZYNQMP_DISP_AV_BUF_CHBUF_EN |
508 	      (ZYNQMP_DISP_AV_BUF_CHBUF_BURST_LEN_AUD_MAX <<
509 	       ZYNQMP_DISP_AV_BUF_CHBUF_BURST_LEN_SHIFT);
510 
511 	for (; i < ZYNQMP_DISP_AV_BUF_NUM_BUFFERS; i++)
512 		zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_CHBUF(i),
513 					val);
514 }
515 
516 /**
517  * zynqmp_disp_avbuf_disable_channels - Disable buffer channels
518  * @disp: Display controller
519  *
520  * Disable all (video and audio) buffer channels.
521  */
zynqmp_disp_avbuf_disable_channels(struct zynqmp_disp * disp)522 static void zynqmp_disp_avbuf_disable_channels(struct zynqmp_disp *disp)
523 {
524 	unsigned int i;
525 
526 	for (i = 0; i < ZYNQMP_DISP_AV_BUF_NUM_BUFFERS; i++)
527 		zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_CHBUF(i),
528 					ZYNQMP_DISP_AV_BUF_CHBUF_FLUSH);
529 }
530 
531 /**
532  * zynqmp_disp_avbuf_enable_audio - Enable audio
533  * @disp: Display controller
534  *
535  * Enable all audio buffers with a non-live (memory) source.
536  */
zynqmp_disp_avbuf_enable_audio(struct zynqmp_disp * disp)537 static void zynqmp_disp_avbuf_enable_audio(struct zynqmp_disp *disp)
538 {
539 	u32 val;
540 
541 	val = zynqmp_disp_avbuf_read(disp, ZYNQMP_DISP_AV_BUF_OUTPUT);
542 	val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_AUD1_MASK;
543 	val |= ZYNQMP_DISP_AV_BUF_OUTPUT_AUD1_MEM;
544 	val |= ZYNQMP_DISP_AV_BUF_OUTPUT_AUD2_EN;
545 	zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_OUTPUT, val);
546 }
547 
548 /**
549  * zynqmp_disp_avbuf_disable_audio - Disable audio
550  * @disp: Display controller
551  *
552  * Disable all audio buffers.
553  */
zynqmp_disp_avbuf_disable_audio(struct zynqmp_disp * disp)554 static void zynqmp_disp_avbuf_disable_audio(struct zynqmp_disp *disp)
555 {
556 	u32 val;
557 
558 	val = zynqmp_disp_avbuf_read(disp, ZYNQMP_DISP_AV_BUF_OUTPUT);
559 	val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_AUD1_MASK;
560 	val |= ZYNQMP_DISP_AV_BUF_OUTPUT_AUD1_DISABLE;
561 	val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_AUD2_EN;
562 	zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_OUTPUT, val);
563 }
564 
565 /**
566  * zynqmp_disp_avbuf_enable_video - Enable a video layer
567  * @disp: Display controller
568  * @layer: The layer
569  * @mode: Operating mode of layer
570  *
571  * Enable the video/graphics buffer for @layer.
572  */
zynqmp_disp_avbuf_enable_video(struct zynqmp_disp * disp,struct zynqmp_disp_layer * layer,enum zynqmp_disp_layer_mode mode)573 static void zynqmp_disp_avbuf_enable_video(struct zynqmp_disp *disp,
574 					   struct zynqmp_disp_layer *layer,
575 					   enum zynqmp_disp_layer_mode mode)
576 {
577 	u32 val;
578 
579 	val = zynqmp_disp_avbuf_read(disp, ZYNQMP_DISP_AV_BUF_OUTPUT);
580 	if (zynqmp_disp_layer_is_video(layer)) {
581 		val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_MASK;
582 		if (mode == ZYNQMP_DISP_LAYER_NONLIVE)
583 			val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_MEM;
584 		else
585 			val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_LIVE;
586 	} else {
587 		val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_MASK;
588 		val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_MEM;
589 		if (mode == ZYNQMP_DISP_LAYER_NONLIVE)
590 			val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_MEM;
591 		else
592 			val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_LIVE;
593 	}
594 	zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_OUTPUT, val);
595 }
596 
597 /**
598  * zynqmp_disp_avbuf_disable_video - Disable a video layer
599  * @disp: Display controller
600  * @layer: The layer
601  *
602  * Disable the video/graphics buffer for @layer.
603  */
zynqmp_disp_avbuf_disable_video(struct zynqmp_disp * disp,struct zynqmp_disp_layer * layer)604 static void zynqmp_disp_avbuf_disable_video(struct zynqmp_disp *disp,
605 					    struct zynqmp_disp_layer *layer)
606 {
607 	u32 val;
608 
609 	val = zynqmp_disp_avbuf_read(disp, ZYNQMP_DISP_AV_BUF_OUTPUT);
610 	if (zynqmp_disp_layer_is_video(layer)) {
611 		val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_MASK;
612 		val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_NONE;
613 	} else {
614 		val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_MASK;
615 		val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_DISABLE;
616 	}
617 	zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_OUTPUT, val);
618 }
619 
620 /**
621  * zynqmp_disp_avbuf_enable - Enable the video pipe
622  * @disp: Display controller
623  *
624  * De-assert the video pipe reset.
625  */
zynqmp_disp_avbuf_enable(struct zynqmp_disp * disp)626 static void zynqmp_disp_avbuf_enable(struct zynqmp_disp *disp)
627 {
628 	zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_SRST_REG, 0);
629 }
630 
631 /**
632  * zynqmp_disp_avbuf_disable - Disable the video pipe
633  * @disp: Display controller
634  *
635  * Assert the video pipe reset.
636  */
zynqmp_disp_avbuf_disable(struct zynqmp_disp * disp)637 static void zynqmp_disp_avbuf_disable(struct zynqmp_disp *disp)
638 {
639 	zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_SRST_REG,
640 				ZYNQMP_DISP_AV_BUF_SRST_REG_VID_RST);
641 }
642 
643 /* -----------------------------------------------------------------------------
644  * Blender (Video Pipeline)
645  */
646 
zynqmp_disp_blend_write(struct zynqmp_disp * disp,int reg,u32 val)647 static void zynqmp_disp_blend_write(struct zynqmp_disp *disp, int reg, u32 val)
648 {
649 	writel(val, disp->blend.base + reg);
650 }
651 
652 /*
653  * Colorspace conversion matrices.
654  *
655  * Hardcode RGB <-> YUV conversion to full-range SDTV for now.
656  */
657 static const u16 csc_zero_matrix[] = {
658 	0x0,    0x0,    0x0,
659 	0x0,    0x0,    0x0,
660 	0x0,    0x0,    0x0
661 };
662 
663 static const u16 csc_identity_matrix[] = {
664 	0x1000, 0x0,    0x0,
665 	0x0,    0x1000, 0x0,
666 	0x0,    0x0,    0x1000
667 };
668 
669 static const u32 csc_zero_offsets[] = {
670 	0, 0, 0
671 };
672 
673 static const u16 csc_rgb_to_sdtv_matrix[] = {
674 	0x4c9,  0x864,  0x1d3,
675 	0x7d4d, 0x7ab3, 0x800,
676 	0x800,  0x794d, 0x7eb3
677 };
678 
679 static const u32 csc_rgb_to_sdtv_offsets[] = {
680 	0x0, 0x8000000, 0x8000000
681 };
682 
683 static const u16 csc_sdtv_to_rgb_matrix[] = {
684 	0x1000, 0x166f, 0x0,
685 	0x1000, 0x7483, 0x7a7f,
686 	0x1000, 0x0,    0x1c5a
687 };
688 
689 static const u32 csc_sdtv_to_rgb_offsets[] = {
690 	0x0, 0x1800, 0x1800
691 };
692 
693 /**
694  * zynqmp_disp_blend_set_output_format - Set the output format of the blender
695  * @disp: Display controller
696  * @format: Output format
697  *
698  * Set the output format of the blender to @format.
699  */
zynqmp_disp_blend_set_output_format(struct zynqmp_disp * disp,enum zynqmp_dpsub_format format)700 static void zynqmp_disp_blend_set_output_format(struct zynqmp_disp *disp,
701 						enum zynqmp_dpsub_format format)
702 {
703 	static const unsigned int blend_output_fmts[] = {
704 		[ZYNQMP_DPSUB_FORMAT_RGB] = ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_RGB,
705 		[ZYNQMP_DPSUB_FORMAT_YCRCB444] = ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_YCBCR444,
706 		[ZYNQMP_DPSUB_FORMAT_YCRCB422] = ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_YCBCR422
707 					       | ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_EN_DOWNSAMPLE,
708 		[ZYNQMP_DPSUB_FORMAT_YONLY] = ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_YONLY,
709 	};
710 
711 	u32 fmt = blend_output_fmts[format];
712 	const u16 *coeffs;
713 	const u32 *offsets;
714 	unsigned int i;
715 
716 	zynqmp_disp_blend_write(disp, ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT, fmt);
717 	if (fmt == ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_RGB) {
718 		coeffs = csc_identity_matrix;
719 		offsets = csc_zero_offsets;
720 	} else {
721 		coeffs = csc_rgb_to_sdtv_matrix;
722 		offsets = csc_rgb_to_sdtv_offsets;
723 	}
724 
725 	for (i = 0; i < ZYNQMP_DISP_V_BLEND_NUM_COEFF; i++)
726 		zynqmp_disp_blend_write(disp,
727 					ZYNQMP_DISP_V_BLEND_RGB2YCBCR_COEFF(i),
728 					coeffs[i]);
729 
730 	for (i = 0; i < ZYNQMP_DISP_V_BLEND_NUM_OFFSET; i++)
731 		zynqmp_disp_blend_write(disp,
732 					ZYNQMP_DISP_V_BLEND_OUTCSC_OFFSET(i),
733 					offsets[i]);
734 }
735 
736 /**
737  * zynqmp_disp_blend_set_bg_color - Set the background color
738  * @disp: Display controller
739  * @rcr: Red/Cr color component
740  * @gy: Green/Y color component
741  * @bcb: Blue/Cb color component
742  *
743  * Set the background color to (@rcr, @gy, @bcb), corresponding to the R, G and
744  * B or Cr, Y and Cb components respectively depending on the selected output
745  * format.
746  */
zynqmp_disp_blend_set_bg_color(struct zynqmp_disp * disp,u32 rcr,u32 gy,u32 bcb)747 static void zynqmp_disp_blend_set_bg_color(struct zynqmp_disp *disp,
748 					   u32 rcr, u32 gy, u32 bcb)
749 {
750 	zynqmp_disp_blend_write(disp, ZYNQMP_DISP_V_BLEND_BG_CLR_0, rcr);
751 	zynqmp_disp_blend_write(disp, ZYNQMP_DISP_V_BLEND_BG_CLR_1, gy);
752 	zynqmp_disp_blend_write(disp, ZYNQMP_DISP_V_BLEND_BG_CLR_2, bcb);
753 }
754 
755 /**
756  * zynqmp_disp_blend_set_global_alpha - Configure global alpha blending
757  * @disp: Display controller
758  * @enable: True to enable global alpha blending
759  * @alpha: Global alpha value (ignored if @enabled is false)
760  */
zynqmp_disp_blend_set_global_alpha(struct zynqmp_disp * disp,bool enable,u32 alpha)761 static void zynqmp_disp_blend_set_global_alpha(struct zynqmp_disp *disp,
762 					       bool enable, u32 alpha)
763 {
764 	zynqmp_disp_blend_write(disp, ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA,
765 				ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA_VALUE(alpha) |
766 				(enable ? ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA_EN : 0));
767 }
768 
769 /**
770  * zynqmp_disp_blend_layer_set_csc - Configure colorspace conversion for layer
771  * @disp: Display controller
772  * @layer: The layer
773  * @coeffs: Colorspace conversion matrix
774  * @offsets: Colorspace conversion offsets
775  *
776  * Configure the input colorspace conversion matrix and offsets for the @layer.
777  * Columns of the matrix are automatically swapped based on the input format to
778  * handle RGB and YCrCb components permutations.
779  */
zynqmp_disp_blend_layer_set_csc(struct zynqmp_disp * disp,struct zynqmp_disp_layer * layer,const u16 * coeffs,const u32 * offsets)780 static void zynqmp_disp_blend_layer_set_csc(struct zynqmp_disp *disp,
781 					    struct zynqmp_disp_layer *layer,
782 					    const u16 *coeffs,
783 					    const u32 *offsets)
784 {
785 	unsigned int swap[3] = { 0, 1, 2 };
786 	unsigned int reg;
787 	unsigned int i;
788 
789 	if (layer->disp_fmt->swap) {
790 		if (layer->drm_fmt->is_yuv) {
791 			/* Swap U and V. */
792 			swap[1] = 2;
793 			swap[2] = 1;
794 		} else {
795 			/* Swap R and B. */
796 			swap[0] = 2;
797 			swap[2] = 0;
798 		}
799 	}
800 
801 	if (zynqmp_disp_layer_is_video(layer))
802 		reg = ZYNQMP_DISP_V_BLEND_IN1CSC_COEFF(0);
803 	else
804 		reg = ZYNQMP_DISP_V_BLEND_IN2CSC_COEFF(0);
805 
806 	for (i = 0; i < ZYNQMP_DISP_V_BLEND_NUM_COEFF; i += 3, reg += 12) {
807 		zynqmp_disp_blend_write(disp, reg + 0, coeffs[i + swap[0]]);
808 		zynqmp_disp_blend_write(disp, reg + 4, coeffs[i + swap[1]]);
809 		zynqmp_disp_blend_write(disp, reg + 8, coeffs[i + swap[2]]);
810 	}
811 
812 	if (zynqmp_disp_layer_is_video(layer))
813 		reg = ZYNQMP_DISP_V_BLEND_IN1CSC_OFFSET(0);
814 	else
815 		reg = ZYNQMP_DISP_V_BLEND_IN2CSC_OFFSET(0);
816 
817 	for (i = 0; i < ZYNQMP_DISP_V_BLEND_NUM_OFFSET; i++)
818 		zynqmp_disp_blend_write(disp, reg + i * 4, offsets[i]);
819 }
820 
821 /**
822  * zynqmp_disp_blend_layer_enable - Enable a layer
823  * @disp: Display controller
824  * @layer: The layer
825  */
zynqmp_disp_blend_layer_enable(struct zynqmp_disp * disp,struct zynqmp_disp_layer * layer)826 static void zynqmp_disp_blend_layer_enable(struct zynqmp_disp *disp,
827 					   struct zynqmp_disp_layer *layer)
828 {
829 	const u16 *coeffs;
830 	const u32 *offsets;
831 	u32 val;
832 
833 	val = (layer->drm_fmt->is_yuv ?
834 	       0 : ZYNQMP_DISP_V_BLEND_LAYER_CONTROL_RGB) |
835 	      (layer->drm_fmt->hsub > 1 ?
836 	       ZYNQMP_DISP_V_BLEND_LAYER_CONTROL_EN_US : 0);
837 
838 	zynqmp_disp_blend_write(disp,
839 				ZYNQMP_DISP_V_BLEND_LAYER_CONTROL(layer->id),
840 				val);
841 
842 	if (layer->drm_fmt->is_yuv) {
843 		coeffs = csc_sdtv_to_rgb_matrix;
844 		offsets = csc_sdtv_to_rgb_offsets;
845 	} else {
846 		coeffs = csc_identity_matrix;
847 		offsets = csc_zero_offsets;
848 	}
849 
850 	zynqmp_disp_blend_layer_set_csc(disp, layer, coeffs, offsets);
851 }
852 
853 /**
854  * zynqmp_disp_blend_layer_disable - Disable a layer
855  * @disp: Display controller
856  * @layer: The layer
857  */
zynqmp_disp_blend_layer_disable(struct zynqmp_disp * disp,struct zynqmp_disp_layer * layer)858 static void zynqmp_disp_blend_layer_disable(struct zynqmp_disp *disp,
859 					    struct zynqmp_disp_layer *layer)
860 {
861 	zynqmp_disp_blend_write(disp,
862 				ZYNQMP_DISP_V_BLEND_LAYER_CONTROL(layer->id),
863 				0);
864 
865 	zynqmp_disp_blend_layer_set_csc(disp, layer, csc_zero_matrix,
866 					csc_zero_offsets);
867 }
868 
869 /* -----------------------------------------------------------------------------
870  * Audio Mixer
871  */
872 
zynqmp_disp_audio_write(struct zynqmp_disp * disp,int reg,u32 val)873 static void zynqmp_disp_audio_write(struct zynqmp_disp *disp, int reg, u32 val)
874 {
875 	writel(val, disp->audio.base + reg);
876 }
877 
878 /**
879  * zynqmp_disp_audio_enable - Enable the audio mixer
880  * @disp: Display controller
881  *
882  * Enable the audio mixer by de-asserting the soft reset. The audio state is set to
883  * default values by the reset, set the default mixer volume explicitly.
884  */
zynqmp_disp_audio_enable(struct zynqmp_disp * disp)885 static void zynqmp_disp_audio_enable(struct zynqmp_disp *disp)
886 {
887 	/* Clear the audio soft reset register as it's an non-reset flop. */
888 	zynqmp_disp_audio_write(disp, ZYNQMP_DISP_AUD_SOFT_RESET, 0);
889 	zynqmp_disp_audio_write(disp, ZYNQMP_DISP_AUD_MIXER_VOLUME,
890 				ZYNQMP_DISP_AUD_MIXER_VOLUME_NO_SCALE);
891 }
892 
893 /**
894  * zynqmp_disp_audio_disable - Disable the audio mixer
895  * @disp: Display controller
896  *
897  * Disable the audio mixer by asserting its soft reset.
898  */
zynqmp_disp_audio_disable(struct zynqmp_disp * disp)899 static void zynqmp_disp_audio_disable(struct zynqmp_disp *disp)
900 {
901 	zynqmp_disp_audio_write(disp, ZYNQMP_DISP_AUD_SOFT_RESET,
902 				ZYNQMP_DISP_AUD_SOFT_RESET_AUD_SRST);
903 }
904 
zynqmp_disp_audio_init(struct zynqmp_disp * disp)905 static void zynqmp_disp_audio_init(struct zynqmp_disp *disp)
906 {
907 	/* Try the live PL audio clock. */
908 	disp->audio.clk = devm_clk_get(disp->dev, "dp_live_audio_aclk");
909 	if (!IS_ERR(disp->audio.clk)) {
910 		disp->audio.clk_from_ps = false;
911 		return;
912 	}
913 
914 	/* If the live PL audio clock is not valid, fall back to PS clock. */
915 	disp->audio.clk = devm_clk_get(disp->dev, "dp_aud_clk");
916 	if (!IS_ERR(disp->audio.clk)) {
917 		disp->audio.clk_from_ps = true;
918 		return;
919 	}
920 
921 	dev_err(disp->dev, "audio disabled due to missing clock\n");
922 }
923 
924 /* -----------------------------------------------------------------------------
925  * ZynqMP Display external functions for zynqmp_dp
926  */
927 
928 /**
929  * zynqmp_disp_handle_vblank - Handle the vblank event
930  * @disp: Display controller
931  *
932  * This function handles the vblank interrupt, and sends an event to
933  * CRTC object. This will be called by the DP vblank interrupt handler.
934  */
zynqmp_disp_handle_vblank(struct zynqmp_disp * disp)935 void zynqmp_disp_handle_vblank(struct zynqmp_disp *disp)
936 {
937 	struct drm_crtc *crtc = &disp->crtc;
938 
939 	drm_crtc_handle_vblank(crtc);
940 }
941 
942 /**
943  * zynqmp_disp_audio_enabled - If the audio is enabled
944  * @disp: Display controller
945  *
946  * Return if the audio is enabled depending on the audio clock.
947  *
948  * Return: true if audio is enabled, or false.
949  */
zynqmp_disp_audio_enabled(struct zynqmp_disp * disp)950 bool zynqmp_disp_audio_enabled(struct zynqmp_disp *disp)
951 {
952 	return !!disp->audio.clk;
953 }
954 
955 /**
956  * zynqmp_disp_get_audio_clk_rate - Get the current audio clock rate
957  * @disp: Display controller
958  *
959  * Return: the current audio clock rate.
960  */
zynqmp_disp_get_audio_clk_rate(struct zynqmp_disp * disp)961 unsigned int zynqmp_disp_get_audio_clk_rate(struct zynqmp_disp *disp)
962 {
963 	if (zynqmp_disp_audio_enabled(disp))
964 		return 0;
965 	return clk_get_rate(disp->audio.clk);
966 }
967 
968 /**
969  * zynqmp_disp_get_crtc_mask - Return the CRTC bit mask
970  * @disp: Display controller
971  *
972  * Return: the crtc mask of the zyqnmp_disp CRTC.
973  */
zynqmp_disp_get_crtc_mask(struct zynqmp_disp * disp)974 uint32_t zynqmp_disp_get_crtc_mask(struct zynqmp_disp *disp)
975 {
976 	return drm_crtc_mask(&disp->crtc);
977 }
978 
979 /* -----------------------------------------------------------------------------
980  * ZynqMP Display Layer & DRM Plane
981  */
982 
983 /**
984  * zynqmp_disp_layer_find_format - Find format information for a DRM format
985  * @layer: The layer
986  * @drm_fmt: DRM format to search
987  *
988  * Search display subsystem format information corresponding to the given DRM
989  * format @drm_fmt for the @layer, and return a pointer to the format
990  * descriptor.
991  *
992  * Return: A pointer to the format descriptor if found, NULL otherwise
993  */
994 static const struct zynqmp_disp_format *
zynqmp_disp_layer_find_format(struct zynqmp_disp_layer * layer,u32 drm_fmt)995 zynqmp_disp_layer_find_format(struct zynqmp_disp_layer *layer,
996 			      u32 drm_fmt)
997 {
998 	unsigned int i;
999 
1000 	for (i = 0; i < layer->info->num_formats; i++) {
1001 		if (layer->info->formats[i].drm_fmt == drm_fmt)
1002 			return &layer->info->formats[i];
1003 	}
1004 
1005 	return NULL;
1006 }
1007 
1008 /**
1009  * zynqmp_disp_layer_enable - Enable a layer
1010  * @layer: The layer
1011  *
1012  * Enable the @layer in the audio/video buffer manager and the blender. DMA
1013  * channels are started separately by zynqmp_disp_layer_update().
1014  */
zynqmp_disp_layer_enable(struct zynqmp_disp_layer * layer)1015 static void zynqmp_disp_layer_enable(struct zynqmp_disp_layer *layer)
1016 {
1017 	zynqmp_disp_avbuf_enable_video(layer->disp, layer,
1018 				       ZYNQMP_DISP_LAYER_NONLIVE);
1019 	zynqmp_disp_blend_layer_enable(layer->disp, layer);
1020 
1021 	layer->mode = ZYNQMP_DISP_LAYER_NONLIVE;
1022 }
1023 
1024 /**
1025  * zynqmp_disp_layer_disable - Disable the layer
1026  * @layer: The layer
1027  *
1028  * Disable the layer by stopping its DMA channels and disabling it in the
1029  * audio/video buffer manager and the blender.
1030  */
zynqmp_disp_layer_disable(struct zynqmp_disp_layer * layer)1031 static void zynqmp_disp_layer_disable(struct zynqmp_disp_layer *layer)
1032 {
1033 	unsigned int i;
1034 
1035 	for (i = 0; i < layer->drm_fmt->num_planes; i++)
1036 		dmaengine_terminate_sync(layer->dmas[i].chan);
1037 
1038 	zynqmp_disp_avbuf_disable_video(layer->disp, layer);
1039 	zynqmp_disp_blend_layer_disable(layer->disp, layer);
1040 }
1041 
1042 /**
1043  * zynqmp_disp_layer_set_format - Set the layer format
1044  * @layer: The layer
1045  * @state: The plane state
1046  *
1047  * Set the format for @layer based on @state->fb->format. The layer must be
1048  * disabled.
1049  */
zynqmp_disp_layer_set_format(struct zynqmp_disp_layer * layer,struct drm_plane_state * state)1050 static void zynqmp_disp_layer_set_format(struct zynqmp_disp_layer *layer,
1051 					 struct drm_plane_state *state)
1052 {
1053 	const struct drm_format_info *info = state->fb->format;
1054 	unsigned int i;
1055 
1056 	layer->disp_fmt = zynqmp_disp_layer_find_format(layer, info->format);
1057 	layer->drm_fmt = info;
1058 
1059 	zynqmp_disp_avbuf_set_format(layer->disp, layer, layer->disp_fmt);
1060 
1061 	/*
1062 	 * Set pconfig for each DMA channel to indicate they're part of a
1063 	 * video group.
1064 	 */
1065 	for (i = 0; i < info->num_planes; i++) {
1066 		struct zynqmp_disp_layer_dma *dma = &layer->dmas[i];
1067 		struct xilinx_dpdma_peripheral_config pconfig = {
1068 			.video_group = true,
1069 		};
1070 		struct dma_slave_config config = {
1071 			.direction = DMA_MEM_TO_DEV,
1072 			.peripheral_config = &pconfig,
1073 			.peripheral_size = sizeof(pconfig),
1074 		};
1075 
1076 		dmaengine_slave_config(dma->chan, &config);
1077 	}
1078 }
1079 
1080 /**
1081  * zynqmp_disp_layer_update - Update the layer framebuffer
1082  * @layer: The layer
1083  * @state: The plane state
1084  *
1085  * Update the framebuffer for the layer by issuing a new DMA engine transaction
1086  * for the new framebuffer.
1087  *
1088  * Return: 0 on success, or the DMA descriptor failure error otherwise
1089  */
zynqmp_disp_layer_update(struct zynqmp_disp_layer * layer,struct drm_plane_state * state)1090 static int zynqmp_disp_layer_update(struct zynqmp_disp_layer *layer,
1091 				    struct drm_plane_state *state)
1092 {
1093 	const struct drm_format_info *info = layer->drm_fmt;
1094 	unsigned int i;
1095 
1096 	for (i = 0; i < layer->drm_fmt->num_planes; i++) {
1097 		unsigned int width = state->crtc_w / (i ? info->hsub : 1);
1098 		unsigned int height = state->crtc_h / (i ? info->vsub : 1);
1099 		struct zynqmp_disp_layer_dma *dma = &layer->dmas[i];
1100 		struct dma_async_tx_descriptor *desc;
1101 		dma_addr_t dma_addr;
1102 
1103 		dma_addr = drm_fb_dma_get_gem_addr(state->fb, state, i);
1104 
1105 		dma->xt.numf = height;
1106 		dma->sgl.size = width * info->cpp[i];
1107 		dma->sgl.icg = state->fb->pitches[i] - dma->sgl.size;
1108 		dma->xt.src_start = dma_addr;
1109 		dma->xt.frame_size = 1;
1110 		dma->xt.dir = DMA_MEM_TO_DEV;
1111 		dma->xt.src_sgl = true;
1112 		dma->xt.dst_sgl = false;
1113 
1114 		desc = dmaengine_prep_interleaved_dma(dma->chan, &dma->xt,
1115 						      DMA_CTRL_ACK |
1116 						      DMA_PREP_REPEAT |
1117 						      DMA_PREP_LOAD_EOT);
1118 		if (!desc) {
1119 			dev_err(layer->disp->dev,
1120 				"failed to prepare DMA descriptor\n");
1121 			return -ENOMEM;
1122 		}
1123 
1124 		dmaengine_submit(desc);
1125 		dma_async_issue_pending(dma->chan);
1126 	}
1127 
1128 	return 0;
1129 }
1130 
plane_to_layer(struct drm_plane * plane)1131 static inline struct zynqmp_disp_layer *plane_to_layer(struct drm_plane *plane)
1132 {
1133 	return container_of(plane, struct zynqmp_disp_layer, plane);
1134 }
1135 
1136 static int
zynqmp_disp_plane_atomic_check(struct drm_plane * plane,struct drm_atomic_state * state)1137 zynqmp_disp_plane_atomic_check(struct drm_plane *plane,
1138 			       struct drm_atomic_state *state)
1139 {
1140 	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
1141 										 plane);
1142 	struct drm_crtc_state *crtc_state;
1143 
1144 	if (!new_plane_state->crtc)
1145 		return 0;
1146 
1147 	crtc_state = drm_atomic_get_crtc_state(state, new_plane_state->crtc);
1148 	if (IS_ERR(crtc_state))
1149 		return PTR_ERR(crtc_state);
1150 
1151 	return drm_atomic_helper_check_plane_state(new_plane_state,
1152 						   crtc_state,
1153 						   DRM_PLANE_NO_SCALING,
1154 						   DRM_PLANE_NO_SCALING,
1155 						   false, false);
1156 }
1157 
1158 static void
zynqmp_disp_plane_atomic_disable(struct drm_plane * plane,struct drm_atomic_state * state)1159 zynqmp_disp_plane_atomic_disable(struct drm_plane *plane,
1160 				 struct drm_atomic_state *state)
1161 {
1162 	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
1163 									   plane);
1164 	struct zynqmp_disp_layer *layer = plane_to_layer(plane);
1165 
1166 	if (!old_state->fb)
1167 		return;
1168 
1169 	zynqmp_disp_layer_disable(layer);
1170 
1171 	if (zynqmp_disp_layer_is_gfx(layer))
1172 		zynqmp_disp_blend_set_global_alpha(layer->disp, false,
1173 						   plane->state->alpha >> 8);
1174 }
1175 
1176 static void
zynqmp_disp_plane_atomic_update(struct drm_plane * plane,struct drm_atomic_state * state)1177 zynqmp_disp_plane_atomic_update(struct drm_plane *plane,
1178 				struct drm_atomic_state *state)
1179 {
1180 	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, plane);
1181 	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane);
1182 	struct zynqmp_disp_layer *layer = plane_to_layer(plane);
1183 	bool format_changed = false;
1184 
1185 	if (!old_state->fb ||
1186 	    old_state->fb->format->format != new_state->fb->format->format)
1187 		format_changed = true;
1188 
1189 	/*
1190 	 * If the format has changed (including going from a previously
1191 	 * disabled state to any format), reconfigure the format. Disable the
1192 	 * plane first if needed.
1193 	 */
1194 	if (format_changed) {
1195 		if (old_state->fb)
1196 			zynqmp_disp_layer_disable(layer);
1197 
1198 		zynqmp_disp_layer_set_format(layer, new_state);
1199 	}
1200 
1201 	zynqmp_disp_layer_update(layer, new_state);
1202 
1203 	if (zynqmp_disp_layer_is_gfx(layer))
1204 		zynqmp_disp_blend_set_global_alpha(layer->disp, true,
1205 						   plane->state->alpha >> 8);
1206 
1207 	/* Enable or re-enable the plane is the format has changed. */
1208 	if (format_changed)
1209 		zynqmp_disp_layer_enable(layer);
1210 }
1211 
1212 static const struct drm_plane_helper_funcs zynqmp_disp_plane_helper_funcs = {
1213 	.atomic_check		= zynqmp_disp_plane_atomic_check,
1214 	.atomic_update		= zynqmp_disp_plane_atomic_update,
1215 	.atomic_disable		= zynqmp_disp_plane_atomic_disable,
1216 };
1217 
1218 static const struct drm_plane_funcs zynqmp_disp_plane_funcs = {
1219 	.update_plane		= drm_atomic_helper_update_plane,
1220 	.disable_plane		= drm_atomic_helper_disable_plane,
1221 	.destroy		= drm_plane_cleanup,
1222 	.reset			= drm_atomic_helper_plane_reset,
1223 	.atomic_duplicate_state	= drm_atomic_helper_plane_duplicate_state,
1224 	.atomic_destroy_state	= drm_atomic_helper_plane_destroy_state,
1225 };
1226 
zynqmp_disp_create_planes(struct zynqmp_disp * disp)1227 static int zynqmp_disp_create_planes(struct zynqmp_disp *disp)
1228 {
1229 	unsigned int i, j;
1230 	int ret;
1231 
1232 	for (i = 0; i < ZYNQMP_DISP_NUM_LAYERS; i++) {
1233 		struct zynqmp_disp_layer *layer = &disp->layers[i];
1234 		enum drm_plane_type type;
1235 		u32 *drm_formats;
1236 
1237 		drm_formats = drmm_kcalloc(disp->drm, sizeof(*drm_formats),
1238 					   layer->info->num_formats,
1239 					   GFP_KERNEL);
1240 		if (!drm_formats)
1241 			return -ENOMEM;
1242 
1243 		for (j = 0; j < layer->info->num_formats; ++j)
1244 			drm_formats[j] = layer->info->formats[j].drm_fmt;
1245 
1246 		/* Graphics layer is primary, and video layer is overlay. */
1247 		type = zynqmp_disp_layer_is_video(layer)
1248 		     ? DRM_PLANE_TYPE_OVERLAY : DRM_PLANE_TYPE_PRIMARY;
1249 		ret = drm_universal_plane_init(disp->drm, &layer->plane, 0,
1250 					       &zynqmp_disp_plane_funcs,
1251 					       drm_formats,
1252 					       layer->info->num_formats,
1253 					       NULL, type, NULL);
1254 		if (ret)
1255 			return ret;
1256 
1257 		drm_plane_helper_add(&layer->plane,
1258 				     &zynqmp_disp_plane_helper_funcs);
1259 
1260 		drm_plane_create_zpos_immutable_property(&layer->plane, i);
1261 		if (zynqmp_disp_layer_is_gfx(layer))
1262 			drm_plane_create_alpha_property(&layer->plane);
1263 	}
1264 
1265 	return 0;
1266 }
1267 
1268 /**
1269  * zynqmp_disp_layer_release_dma - Release DMA channels for a layer
1270  * @disp: Display controller
1271  * @layer: The layer
1272  *
1273  * Release the DMA channels associated with @layer.
1274  */
zynqmp_disp_layer_release_dma(struct zynqmp_disp * disp,struct zynqmp_disp_layer * layer)1275 static void zynqmp_disp_layer_release_dma(struct zynqmp_disp *disp,
1276 					  struct zynqmp_disp_layer *layer)
1277 {
1278 	unsigned int i;
1279 
1280 	if (!layer->info)
1281 		return;
1282 
1283 	for (i = 0; i < layer->info->num_channels; i++) {
1284 		struct zynqmp_disp_layer_dma *dma = &layer->dmas[i];
1285 
1286 		if (!dma->chan)
1287 			continue;
1288 
1289 		/* Make sure the channel is terminated before release. */
1290 		dmaengine_terminate_sync(dma->chan);
1291 		dma_release_channel(dma->chan);
1292 	}
1293 }
1294 
1295 /**
1296  * zynqmp_disp_destroy_layers - Destroy all layers
1297  * @disp: Display controller
1298  */
zynqmp_disp_destroy_layers(struct zynqmp_disp * disp)1299 static void zynqmp_disp_destroy_layers(struct zynqmp_disp *disp)
1300 {
1301 	unsigned int i;
1302 
1303 	for (i = 0; i < ZYNQMP_DISP_NUM_LAYERS; i++)
1304 		zynqmp_disp_layer_release_dma(disp, &disp->layers[i]);
1305 }
1306 
1307 /**
1308  * zynqmp_disp_layer_request_dma - Request DMA channels for a layer
1309  * @disp: Display controller
1310  * @layer: The layer
1311  *
1312  * Request all DMA engine channels needed by @layer.
1313  *
1314  * Return: 0 on success, or the DMA channel request error otherwise
1315  */
zynqmp_disp_layer_request_dma(struct zynqmp_disp * disp,struct zynqmp_disp_layer * layer)1316 static int zynqmp_disp_layer_request_dma(struct zynqmp_disp *disp,
1317 					 struct zynqmp_disp_layer *layer)
1318 {
1319 	static const char * const dma_names[] = { "vid", "gfx" };
1320 	unsigned int i;
1321 	int ret;
1322 
1323 	for (i = 0; i < layer->info->num_channels; i++) {
1324 		struct zynqmp_disp_layer_dma *dma = &layer->dmas[i];
1325 		char dma_channel_name[16];
1326 
1327 		snprintf(dma_channel_name, sizeof(dma_channel_name),
1328 			 "%s%u", dma_names[layer->id], i);
1329 		dma->chan = dma_request_chan(disp->dev, dma_channel_name);
1330 		if (IS_ERR(dma->chan)) {
1331 			dev_err(disp->dev, "failed to request dma channel\n");
1332 			ret = PTR_ERR(dma->chan);
1333 			dma->chan = NULL;
1334 			return ret;
1335 		}
1336 	}
1337 
1338 	return 0;
1339 }
1340 
1341 /**
1342  * zynqmp_disp_create_layers - Create and initialize all layers
1343  * @disp: Display controller
1344  *
1345  * Return: 0 on success, or the DMA channel request error otherwise
1346  */
zynqmp_disp_create_layers(struct zynqmp_disp * disp)1347 static int zynqmp_disp_create_layers(struct zynqmp_disp *disp)
1348 {
1349 	static const struct zynqmp_disp_layer_info layer_info[] = {
1350 		[ZYNQMP_DISP_LAYER_VID] = {
1351 			.formats = avbuf_vid_fmts,
1352 			.num_formats = ARRAY_SIZE(avbuf_vid_fmts),
1353 			.num_channels = 3,
1354 		},
1355 		[ZYNQMP_DISP_LAYER_GFX] = {
1356 			.formats = avbuf_gfx_fmts,
1357 			.num_formats = ARRAY_SIZE(avbuf_gfx_fmts),
1358 			.num_channels = 1,
1359 		},
1360 	};
1361 
1362 	unsigned int i;
1363 	int ret;
1364 
1365 	for (i = 0; i < ZYNQMP_DISP_NUM_LAYERS; i++) {
1366 		struct zynqmp_disp_layer *layer = &disp->layers[i];
1367 
1368 		layer->id = i;
1369 		layer->disp = disp;
1370 		layer->info = &layer_info[i];
1371 
1372 		ret = zynqmp_disp_layer_request_dma(disp, layer);
1373 		if (ret)
1374 			goto err;
1375 	}
1376 
1377 	return 0;
1378 
1379 err:
1380 	zynqmp_disp_destroy_layers(disp);
1381 	return ret;
1382 }
1383 
1384 /* -----------------------------------------------------------------------------
1385  * ZynqMP Display & DRM CRTC
1386  */
1387 
1388 /**
1389  * zynqmp_disp_enable - Enable the display controller
1390  * @disp: Display controller
1391  */
zynqmp_disp_enable(struct zynqmp_disp * disp)1392 static void zynqmp_disp_enable(struct zynqmp_disp *disp)
1393 {
1394 	zynqmp_disp_avbuf_enable(disp);
1395 	/* Choose clock source based on the DT clock handle. */
1396 	zynqmp_disp_avbuf_set_clocks_sources(disp, disp->pclk_from_ps,
1397 					     disp->audio.clk_from_ps, true);
1398 	zynqmp_disp_avbuf_enable_channels(disp);
1399 	zynqmp_disp_avbuf_enable_audio(disp);
1400 
1401 	zynqmp_disp_audio_enable(disp);
1402 }
1403 
1404 /**
1405  * zynqmp_disp_disable - Disable the display controller
1406  * @disp: Display controller
1407  */
zynqmp_disp_disable(struct zynqmp_disp * disp)1408 static void zynqmp_disp_disable(struct zynqmp_disp *disp)
1409 {
1410 	zynqmp_disp_audio_disable(disp);
1411 
1412 	zynqmp_disp_avbuf_disable_audio(disp);
1413 	zynqmp_disp_avbuf_disable_channels(disp);
1414 	zynqmp_disp_avbuf_disable(disp);
1415 }
1416 
crtc_to_disp(struct drm_crtc * crtc)1417 static inline struct zynqmp_disp *crtc_to_disp(struct drm_crtc *crtc)
1418 {
1419 	return container_of(crtc, struct zynqmp_disp, crtc);
1420 }
1421 
zynqmp_disp_crtc_setup_clock(struct drm_crtc * crtc,struct drm_display_mode * adjusted_mode)1422 static int zynqmp_disp_crtc_setup_clock(struct drm_crtc *crtc,
1423 					struct drm_display_mode *adjusted_mode)
1424 {
1425 	struct zynqmp_disp *disp = crtc_to_disp(crtc);
1426 	unsigned long mode_clock = adjusted_mode->clock * 1000;
1427 	unsigned long rate;
1428 	long diff;
1429 	int ret;
1430 
1431 	ret = clk_set_rate(disp->pclk, mode_clock);
1432 	if (ret) {
1433 		dev_err(disp->dev, "failed to set a pixel clock\n");
1434 		return ret;
1435 	}
1436 
1437 	rate = clk_get_rate(disp->pclk);
1438 	diff = rate - mode_clock;
1439 	if (abs(diff) > mode_clock / 20)
1440 		dev_info(disp->dev,
1441 			 "requested pixel rate: %lu actual rate: %lu\n",
1442 			 mode_clock, rate);
1443 	else
1444 		dev_dbg(disp->dev,
1445 			"requested pixel rate: %lu actual rate: %lu\n",
1446 			mode_clock, rate);
1447 
1448 	return 0;
1449 }
1450 
1451 static void
zynqmp_disp_crtc_atomic_enable(struct drm_crtc * crtc,struct drm_atomic_state * state)1452 zynqmp_disp_crtc_atomic_enable(struct drm_crtc *crtc,
1453 			       struct drm_atomic_state *state)
1454 {
1455 	struct zynqmp_disp *disp = crtc_to_disp(crtc);
1456 	struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
1457 	int ret, vrefresh;
1458 
1459 	pm_runtime_get_sync(disp->dev);
1460 
1461 	zynqmp_disp_crtc_setup_clock(crtc, adjusted_mode);
1462 
1463 	ret = clk_prepare_enable(disp->pclk);
1464 	if (ret) {
1465 		dev_err(disp->dev, "failed to enable a pixel clock\n");
1466 		pm_runtime_put_sync(disp->dev);
1467 		return;
1468 	}
1469 
1470 	zynqmp_disp_blend_set_output_format(disp, ZYNQMP_DPSUB_FORMAT_RGB);
1471 	zynqmp_disp_blend_set_bg_color(disp, 0, 0, 0);
1472 
1473 	zynqmp_disp_enable(disp);
1474 
1475 	/* Delay of 3 vblank intervals for timing gen to be stable */
1476 	vrefresh = (adjusted_mode->clock * 1000) /
1477 		   (adjusted_mode->vtotal * adjusted_mode->htotal);
1478 	msleep(3 * 1000 / vrefresh);
1479 }
1480 
1481 static void
zynqmp_disp_crtc_atomic_disable(struct drm_crtc * crtc,struct drm_atomic_state * state)1482 zynqmp_disp_crtc_atomic_disable(struct drm_crtc *crtc,
1483 				struct drm_atomic_state *state)
1484 {
1485 	struct zynqmp_disp *disp = crtc_to_disp(crtc);
1486 	struct drm_plane_state *old_plane_state;
1487 
1488 	/*
1489 	 * Disable the plane if active. The old plane state can be NULL in the
1490 	 * .shutdown() path if the plane is already disabled, skip
1491 	 * zynqmp_disp_plane_atomic_disable() in that case.
1492 	 */
1493 	old_plane_state = drm_atomic_get_old_plane_state(state, crtc->primary);
1494 	if (old_plane_state)
1495 		zynqmp_disp_plane_atomic_disable(crtc->primary, state);
1496 
1497 	zynqmp_disp_disable(disp);
1498 
1499 	drm_crtc_vblank_off(&disp->crtc);
1500 
1501 	spin_lock_irq(&crtc->dev->event_lock);
1502 	if (crtc->state->event) {
1503 		drm_crtc_send_vblank_event(crtc, crtc->state->event);
1504 		crtc->state->event = NULL;
1505 	}
1506 	spin_unlock_irq(&crtc->dev->event_lock);
1507 
1508 	clk_disable_unprepare(disp->pclk);
1509 	pm_runtime_put_sync(disp->dev);
1510 }
1511 
zynqmp_disp_crtc_atomic_check(struct drm_crtc * crtc,struct drm_atomic_state * state)1512 static int zynqmp_disp_crtc_atomic_check(struct drm_crtc *crtc,
1513 					 struct drm_atomic_state *state)
1514 {
1515 	return drm_atomic_add_affected_planes(state, crtc);
1516 }
1517 
1518 static void
zynqmp_disp_crtc_atomic_begin(struct drm_crtc * crtc,struct drm_atomic_state * state)1519 zynqmp_disp_crtc_atomic_begin(struct drm_crtc *crtc,
1520 			      struct drm_atomic_state *state)
1521 {
1522 	drm_crtc_vblank_on(crtc);
1523 }
1524 
1525 static void
zynqmp_disp_crtc_atomic_flush(struct drm_crtc * crtc,struct drm_atomic_state * state)1526 zynqmp_disp_crtc_atomic_flush(struct drm_crtc *crtc,
1527 			      struct drm_atomic_state *state)
1528 {
1529 	if (crtc->state->event) {
1530 		struct drm_pending_vblank_event *event;
1531 
1532 		/* Consume the flip_done event from atomic helper. */
1533 		event = crtc->state->event;
1534 		crtc->state->event = NULL;
1535 
1536 		event->pipe = drm_crtc_index(crtc);
1537 
1538 		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
1539 
1540 		spin_lock_irq(&crtc->dev->event_lock);
1541 		drm_crtc_arm_vblank_event(crtc, event);
1542 		spin_unlock_irq(&crtc->dev->event_lock);
1543 	}
1544 }
1545 
1546 static const struct drm_crtc_helper_funcs zynqmp_disp_crtc_helper_funcs = {
1547 	.atomic_enable	= zynqmp_disp_crtc_atomic_enable,
1548 	.atomic_disable	= zynqmp_disp_crtc_atomic_disable,
1549 	.atomic_check	= zynqmp_disp_crtc_atomic_check,
1550 	.atomic_begin	= zynqmp_disp_crtc_atomic_begin,
1551 	.atomic_flush	= zynqmp_disp_crtc_atomic_flush,
1552 };
1553 
zynqmp_disp_crtc_enable_vblank(struct drm_crtc * crtc)1554 static int zynqmp_disp_crtc_enable_vblank(struct drm_crtc *crtc)
1555 {
1556 	struct zynqmp_disp *disp = crtc_to_disp(crtc);
1557 
1558 	zynqmp_dp_enable_vblank(disp->dpsub->dp);
1559 
1560 	return 0;
1561 }
1562 
zynqmp_disp_crtc_disable_vblank(struct drm_crtc * crtc)1563 static void zynqmp_disp_crtc_disable_vblank(struct drm_crtc *crtc)
1564 {
1565 	struct zynqmp_disp *disp = crtc_to_disp(crtc);
1566 
1567 	zynqmp_dp_disable_vblank(disp->dpsub->dp);
1568 }
1569 
1570 static const struct drm_crtc_funcs zynqmp_disp_crtc_funcs = {
1571 	.destroy		= drm_crtc_cleanup,
1572 	.set_config		= drm_atomic_helper_set_config,
1573 	.page_flip		= drm_atomic_helper_page_flip,
1574 	.reset			= drm_atomic_helper_crtc_reset,
1575 	.atomic_duplicate_state	= drm_atomic_helper_crtc_duplicate_state,
1576 	.atomic_destroy_state	= drm_atomic_helper_crtc_destroy_state,
1577 	.enable_vblank		= zynqmp_disp_crtc_enable_vblank,
1578 	.disable_vblank		= zynqmp_disp_crtc_disable_vblank,
1579 };
1580 
zynqmp_disp_create_crtc(struct zynqmp_disp * disp)1581 static int zynqmp_disp_create_crtc(struct zynqmp_disp *disp)
1582 {
1583 	struct drm_plane *plane = &disp->layers[ZYNQMP_DISP_LAYER_GFX].plane;
1584 	int ret;
1585 
1586 	ret = drm_crtc_init_with_planes(disp->drm, &disp->crtc, plane,
1587 					NULL, &zynqmp_disp_crtc_funcs, NULL);
1588 	if (ret < 0)
1589 		return ret;
1590 
1591 	drm_crtc_helper_add(&disp->crtc, &zynqmp_disp_crtc_helper_funcs);
1592 
1593 	/* Start with vertical blanking interrupt reporting disabled. */
1594 	drm_crtc_vblank_off(&disp->crtc);
1595 
1596 	return 0;
1597 }
1598 
zynqmp_disp_map_crtc_to_plane(struct zynqmp_disp * disp)1599 static void zynqmp_disp_map_crtc_to_plane(struct zynqmp_disp *disp)
1600 {
1601 	u32 possible_crtcs = drm_crtc_mask(&disp->crtc);
1602 	unsigned int i;
1603 
1604 	for (i = 0; i < ZYNQMP_DISP_NUM_LAYERS; i++)
1605 		disp->layers[i].plane.possible_crtcs = possible_crtcs;
1606 }
1607 
1608 /* -----------------------------------------------------------------------------
1609  * Initialization & Cleanup
1610  */
1611 
zynqmp_disp_drm_init(struct zynqmp_dpsub * dpsub)1612 int zynqmp_disp_drm_init(struct zynqmp_dpsub *dpsub)
1613 {
1614 	struct zynqmp_disp *disp = dpsub->disp;
1615 	int ret;
1616 
1617 	ret = zynqmp_disp_create_planes(disp);
1618 	if (ret)
1619 		return ret;
1620 
1621 	ret = zynqmp_disp_create_crtc(disp);
1622 	if (ret < 0)
1623 		return ret;
1624 
1625 	zynqmp_disp_map_crtc_to_plane(disp);
1626 
1627 	return 0;
1628 }
1629 
zynqmp_disp_probe(struct zynqmp_dpsub * dpsub,struct drm_device * drm)1630 int zynqmp_disp_probe(struct zynqmp_dpsub *dpsub, struct drm_device *drm)
1631 {
1632 	struct platform_device *pdev = to_platform_device(dpsub->dev);
1633 	struct zynqmp_disp *disp;
1634 	struct zynqmp_disp_layer *layer;
1635 	struct resource *res;
1636 	int ret;
1637 
1638 	disp = drmm_kzalloc(drm, sizeof(*disp), GFP_KERNEL);
1639 	if (!disp)
1640 		return -ENOMEM;
1641 
1642 	disp->dev = &pdev->dev;
1643 	disp->dpsub = dpsub;
1644 	disp->drm = drm;
1645 
1646 	dpsub->disp = disp;
1647 
1648 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "blend");
1649 	disp->blend.base = devm_ioremap_resource(disp->dev, res);
1650 	if (IS_ERR(disp->blend.base))
1651 		return PTR_ERR(disp->blend.base);
1652 
1653 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "av_buf");
1654 	disp->avbuf.base = devm_ioremap_resource(disp->dev, res);
1655 	if (IS_ERR(disp->avbuf.base))
1656 		return PTR_ERR(disp->avbuf.base);
1657 
1658 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "aud");
1659 	disp->audio.base = devm_ioremap_resource(disp->dev, res);
1660 	if (IS_ERR(disp->audio.base))
1661 		return PTR_ERR(disp->audio.base);
1662 
1663 	/* Try the live PL video clock */
1664 	disp->pclk = devm_clk_get(disp->dev, "dp_live_video_in_clk");
1665 	if (!IS_ERR(disp->pclk))
1666 		disp->pclk_from_ps = false;
1667 	else if (PTR_ERR(disp->pclk) == -EPROBE_DEFER)
1668 		return PTR_ERR(disp->pclk);
1669 
1670 	/* If the live PL video clock is not valid, fall back to PS clock */
1671 	if (IS_ERR_OR_NULL(disp->pclk)) {
1672 		disp->pclk = devm_clk_get(disp->dev, "dp_vtc_pixel_clk_in");
1673 		if (IS_ERR(disp->pclk)) {
1674 			dev_err(disp->dev, "failed to init any video clock\n");
1675 			return PTR_ERR(disp->pclk);
1676 		}
1677 		disp->pclk_from_ps = true;
1678 	}
1679 
1680 	zynqmp_disp_audio_init(disp);
1681 
1682 	ret = zynqmp_disp_create_layers(disp);
1683 	if (ret)
1684 		return ret;
1685 
1686 	layer = &disp->layers[ZYNQMP_DISP_LAYER_VID];
1687 	dpsub->dma_align = 1 << layer->dmas[0].chan->device->copy_align;
1688 
1689 	return 0;
1690 }
1691 
zynqmp_disp_remove(struct zynqmp_dpsub * dpsub)1692 void zynqmp_disp_remove(struct zynqmp_dpsub *dpsub)
1693 {
1694 	struct zynqmp_disp *disp = dpsub->disp;
1695 
1696 	zynqmp_disp_destroy_layers(disp);
1697 }
1698