File Index
Files and directories
Sign in
FILE

zynqmp_disp.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/xlnx/zynqmp_disp.c C
   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_fb_dma_helper.h>
  13#include <drm/drm_fourcc.h>
  14#include <drm/drm_framebuffer.h>
  15#include <drm/drm_plane.h>
  16
  17#include <linux/clk.h>
  18#include <linux/dma/xilinx_dpdma.h>
  19#include <linux/dma-mapping.h>
  20#include <linux/dmaengine.h>
  21#include <linux/media-bus-format.h>
  22#include <linux/module.h>
  23#include <linux/of.h>
  24#include <linux/platform_device.h>
  25#include <linux/slab.h>
  26
  27#include "zynqmp_disp.h"
  28#include "zynqmp_disp_regs.h"
  29#include "zynqmp_dp.h"
  30#include "zynqmp_dpsub.h"
  31
  32/*
  33 * Overview
  34 * --------
  35 *
  36 * The display controller part of ZynqMP DP subsystem, made of the Audio/Video
  37 * Buffer Manager, the Video Rendering Pipeline (blender) and the Audio Mixer.
  38 *
  39 *              +------------------------------------------------------------+
  40 * +--------+   | +----------------+     +-----------+                       |
  41 * | DPDMA  | --->|                | --> |   Video   | Video +-------------+ |
  42 * | 4x vid |   | |                |     | Rendering | -+--> |             | |   +------+
  43 * | 2x aud |   | |  Audio/Video   | --> | Pipeline  |  |    | DisplayPort |---> | PHY0 |
  44 * +--------+   | | Buffer Manager |     +-----------+  |    |   Source    | |   +------+
  45 *              | |    and STC     |     +-----------+  |    | Controller  | |   +------+
  46 * Live Video --->|                | --> |   Audio   | Audio |             |---> | PHY1 |
  47 *              | |                |     |   Mixer   | --+-> |             | |   +------+
  48 * Live Audio --->|                | --> |           |  ||   +-------------+ |
  49 *              | +----------------+     +-----------+  ||                   |
  50 *              +---------------------------------------||-------------------+
  51 *                                                      vv
  52 *                                                Blended Video and
  53 *                                                Mixed Audio to PL
  54 *
  55 * Only non-live input from the DPDMA and output to the DisplayPort Source
  56 * Controller are currently supported. Interface with the programmable logic
  57 * for live streams is not implemented.
  58 *
  59 * The display controller code creates planes for the DPDMA video and graphics
  60 * layers, and a CRTC for the Video Rendering Pipeline.
  61 */
  62
  63#define ZYNQMP_DISP_AV_BUF_NUM_VID_GFX_BUFFERS		4
  64#define ZYNQMP_DISP_AV_BUF_NUM_BUFFERS			6
  65
  66#define ZYNQMP_DISP_MAX_NUM_SUB_PLANES			3
  67
  68/**
  69 * enum zynqmp_dpsub_layer_mode - Layer mode
  70 * @ZYNQMP_DPSUB_LAYER_NONLIVE: non-live (memory) mode
  71 * @ZYNQMP_DPSUB_LAYER_LIVE: live (stream) mode
  72 */
  73enum zynqmp_dpsub_layer_mode {
  74	ZYNQMP_DPSUB_LAYER_NONLIVE,
  75	ZYNQMP_DPSUB_LAYER_LIVE,
  76};
  77
  78/**
  79 * struct zynqmp_disp_format - Display subsystem format information
  80 * @drm_fmt: DRM format (4CC)
  81 * @bus_fmt: Media bus format
  82 * @buf_fmt: AV buffer format
  83 * @swap: Flag to swap R & B for RGB formats, and U & V for YUV formats
  84 * @sf: Scaling factors for color components
  85 */
  86struct zynqmp_disp_format {
  87	u32 drm_fmt;
  88	u32 bus_fmt;
  89	u32 buf_fmt;
  90	bool swap;
  91	const u32 *sf;
  92};
  93
  94/**
  95 * struct zynqmp_disp_layer_dma - DMA channel for one data plane of a layer
  96 * @chan: DMA channel
  97 * @xt: Interleaved DMA descriptor template
  98 * @sgl: Data chunk for dma_interleaved_template
  99 */
 100struct zynqmp_disp_layer_dma {
 101	struct dma_chan *chan;
 102	struct dma_interleaved_template xt;
 103	struct data_chunk sgl;
 104};
 105
 106/**
 107 * struct zynqmp_disp_layer_info - Static layer information
 108 * @formats: Array of supported formats
 109 * @num_formats: Number of formats in @formats array
 110 * @num_channels: Number of DMA channels
 111 */
 112struct zynqmp_disp_layer_info {
 113	const struct zynqmp_disp_format *formats;
 114	unsigned int num_formats;
 115	unsigned int num_channels;
 116};
 117
 118/**
 119 * struct zynqmp_disp_layer - Display layer
 120 * @id: Layer ID
 121 * @disp: Back pointer to struct zynqmp_disp
 122 * @info: Static layer information
 123 * @dmas: DMA channels
 124 * @disp_fmt: Current format information
 125 * @drm_fmt: Current DRM format information
 126 * @mode: Current operation mode
 127 */
 128struct zynqmp_disp_layer {
 129	enum zynqmp_dpsub_layer_id id;
 130	struct zynqmp_disp *disp;
 131	const struct zynqmp_disp_layer_info *info;
 132
 133	struct zynqmp_disp_layer_dma dmas[ZYNQMP_DISP_MAX_NUM_SUB_PLANES];
 134
 135	const struct zynqmp_disp_format *disp_fmt;
 136	const struct drm_format_info *drm_fmt;
 137	enum zynqmp_dpsub_layer_mode mode;
 138};
 139
 140/**
 141 * struct zynqmp_disp - Display controller
 142 * @dev: Device structure
 143 * @dpsub: Display subsystem
 144 * @blend: Register I/O base address for the blender
 145 * @avbuf: Register I/O base address for the audio/video buffer manager
 146 * @layers: Layers (planes)
 147 */
 148struct zynqmp_disp {
 149	struct device *dev;
 150	struct zynqmp_dpsub *dpsub;
 151
 152	void __iomem *blend;
 153	void __iomem *avbuf;
 154
 155	struct zynqmp_disp_layer layers[ZYNQMP_DPSUB_NUM_LAYERS];
 156};
 157
 158/* -----------------------------------------------------------------------------
 159 * Audio/Video Buffer Manager
 160 */
 161
 162static const u32 scaling_factors_444[] = {
 163	ZYNQMP_DISP_AV_BUF_4BIT_SF,
 164	ZYNQMP_DISP_AV_BUF_4BIT_SF,
 165	ZYNQMP_DISP_AV_BUF_4BIT_SF,
 166};
 167
 168static const u32 scaling_factors_555[] = {
 169	ZYNQMP_DISP_AV_BUF_5BIT_SF,
 170	ZYNQMP_DISP_AV_BUF_5BIT_SF,
 171	ZYNQMP_DISP_AV_BUF_5BIT_SF,
 172};
 173
 174static const u32 scaling_factors_565[] = {
 175	ZYNQMP_DISP_AV_BUF_5BIT_SF,
 176	ZYNQMP_DISP_AV_BUF_6BIT_SF,
 177	ZYNQMP_DISP_AV_BUF_5BIT_SF,
 178};
 179
 180static const u32 scaling_factors_666[] = {
 181	ZYNQMP_DISP_AV_BUF_6BIT_SF,
 182	ZYNQMP_DISP_AV_BUF_6BIT_SF,
 183	ZYNQMP_DISP_AV_BUF_6BIT_SF,
 184};
 185
 186static const u32 scaling_factors_888[] = {
 187	ZYNQMP_DISP_AV_BUF_8BIT_SF,
 188	ZYNQMP_DISP_AV_BUF_8BIT_SF,
 189	ZYNQMP_DISP_AV_BUF_8BIT_SF,
 190};
 191
 192static const u32 scaling_factors_101010[] = {
 193	ZYNQMP_DISP_AV_BUF_10BIT_SF,
 194	ZYNQMP_DISP_AV_BUF_10BIT_SF,
 195	ZYNQMP_DISP_AV_BUF_10BIT_SF,
 196};
 197
 198/* List of video layer formats */
 199static const struct zynqmp_disp_format avbuf_vid_fmts[] = {
 200	{
 201		.drm_fmt	= DRM_FORMAT_VYUY,
 202		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_VYUY,
 203		.swap		= true,
 204		.sf		= scaling_factors_888,
 205	}, {
 206		.drm_fmt	= DRM_FORMAT_UYVY,
 207		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_VYUY,
 208		.swap		= false,
 209		.sf		= scaling_factors_888,
 210	}, {
 211		.drm_fmt	= DRM_FORMAT_YUYV,
 212		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YUYV,
 213		.swap		= false,
 214		.sf		= scaling_factors_888,
 215	}, {
 216		.drm_fmt	= DRM_FORMAT_YVYU,
 217		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YUYV,
 218		.swap		= true,
 219		.sf		= scaling_factors_888,
 220	}, {
 221		.drm_fmt	= DRM_FORMAT_YUV422,
 222		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16,
 223		.swap		= false,
 224		.sf		= scaling_factors_888,
 225	}, {
 226		.drm_fmt	= DRM_FORMAT_YVU422,
 227		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16,
 228		.swap		= true,
 229		.sf		= scaling_factors_888,
 230	}, {
 231		.drm_fmt	= DRM_FORMAT_YUV444,
 232		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV24,
 233		.swap		= false,
 234		.sf		= scaling_factors_888,
 235	}, {
 236		.drm_fmt	= DRM_FORMAT_YVU444,
 237		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV24,
 238		.swap		= true,
 239		.sf		= scaling_factors_888,
 240	}, {
 241		.drm_fmt	= DRM_FORMAT_NV16,
 242		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI,
 243		.swap		= false,
 244		.sf		= scaling_factors_888,
 245	}, {
 246		.drm_fmt	= DRM_FORMAT_NV61,
 247		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI,
 248		.swap		= true,
 249		.sf		= scaling_factors_888,
 250	}, {
 251		.drm_fmt	= DRM_FORMAT_BGR888,
 252		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGB888,
 253		.swap		= false,
 254		.sf		= scaling_factors_888,
 255	}, {
 256		.drm_fmt	= DRM_FORMAT_RGB888,
 257		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGB888,
 258		.swap		= true,
 259		.sf		= scaling_factors_888,
 260	}, {
 261		.drm_fmt	= DRM_FORMAT_XBGR8888,
 262		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGBA8880,
 263		.swap		= false,
 264		.sf		= scaling_factors_888,
 265	}, {
 266		.drm_fmt	= DRM_FORMAT_XRGB8888,
 267		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGBA8880,
 268		.swap		= true,
 269		.sf		= scaling_factors_888,
 270	}, {
 271		.drm_fmt	= DRM_FORMAT_XBGR2101010,
 272		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGB888_10,
 273		.swap		= false,
 274		.sf		= scaling_factors_101010,
 275	}, {
 276		.drm_fmt	= DRM_FORMAT_XRGB2101010,
 277		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGB888_10,
 278		.swap		= true,
 279		.sf		= scaling_factors_101010,
 280	}, {
 281		.drm_fmt	= DRM_FORMAT_YUV420,
 282		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16_420,
 283		.swap		= false,
 284		.sf		= scaling_factors_888,
 285	}, {
 286		.drm_fmt	= DRM_FORMAT_YVU420,
 287		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16_420,
 288		.swap		= true,
 289		.sf		= scaling_factors_888,
 290	}, {
 291		.drm_fmt	= DRM_FORMAT_NV12,
 292		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI_420,
 293		.swap		= false,
 294		.sf		= scaling_factors_888,
 295	}, {
 296		.drm_fmt	= DRM_FORMAT_NV21,
 297		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI_420,
 298		.swap		= true,
 299		.sf		= scaling_factors_888,
 300	},
 301};
 302
 303/* List of graphics layer formats */
 304static const struct zynqmp_disp_format avbuf_gfx_fmts[] = {
 305	{
 306		.drm_fmt	= DRM_FORMAT_ABGR8888,
 307		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA8888,
 308		.swap		= false,
 309		.sf		= scaling_factors_888,
 310	}, {
 311		.drm_fmt	= DRM_FORMAT_ARGB8888,
 312		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA8888,
 313		.swap		= true,
 314		.sf		= scaling_factors_888,
 315	}, {
 316		.drm_fmt	= DRM_FORMAT_RGBA8888,
 317		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_ABGR8888,
 318		.swap		= false,
 319		.sf		= scaling_factors_888,
 320	}, {
 321		.drm_fmt	= DRM_FORMAT_BGRA8888,
 322		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_ABGR8888,
 323		.swap		= true,
 324		.sf		= scaling_factors_888,
 325	}, {
 326		.drm_fmt	= DRM_FORMAT_BGR888,
 327		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGB888,
 328		.swap		= false,
 329		.sf		= scaling_factors_888,
 330	}, {
 331		.drm_fmt	= DRM_FORMAT_RGB888,
 332		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_BGR888,
 333		.swap		= false,
 334		.sf		= scaling_factors_888,
 335	}, {
 336		.drm_fmt	= DRM_FORMAT_RGBA5551,
 337		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA5551,
 338		.swap		= false,
 339		.sf		= scaling_factors_555,
 340	}, {
 341		.drm_fmt	= DRM_FORMAT_BGRA5551,
 342		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA5551,
 343		.swap		= true,
 344		.sf		= scaling_factors_555,
 345	}, {
 346		.drm_fmt	= DRM_FORMAT_RGBA4444,
 347		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA4444,
 348		.swap		= false,
 349		.sf		= scaling_factors_444,
 350	}, {
 351		.drm_fmt	= DRM_FORMAT_BGRA4444,
 352		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA4444,
 353		.swap		= true,
 354		.sf		= scaling_factors_444,
 355	}, {
 356		.drm_fmt	= DRM_FORMAT_RGB565,
 357		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGB565,
 358		.swap		= false,
 359		.sf		= scaling_factors_565,
 360	}, {
 361		.drm_fmt	= DRM_FORMAT_BGR565,
 362		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGB565,
 363		.swap		= true,
 364		.sf		= scaling_factors_565,
 365	},
 366};
 367
 368/* List of live video layer formats */
 369static const struct zynqmp_disp_format avbuf_live_fmts[] = {
 370	{
 371		.drm_fmt	= DRM_FORMAT_RGB565,
 372		.bus_fmt	= MEDIA_BUS_FMT_RGB666_1X18,
 373		.buf_fmt	= ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_6 |
 374				  ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_RGB,
 375		.sf		= scaling_factors_666,
 376	}, {
 377		.drm_fmt	= DRM_FORMAT_RGB888,
 378		.bus_fmt	= MEDIA_BUS_FMT_RGB888_1X24,
 379		.buf_fmt	= ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_8 |
 380				  ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_RGB,
 381		.sf		= scaling_factors_888,
 382	}, {
 383		.drm_fmt	= DRM_FORMAT_YUV422,
 384		.bus_fmt	= MEDIA_BUS_FMT_UYVY8_1X16,
 385		.buf_fmt	= ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_8 |
 386				  ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV422,
 387		.sf		= scaling_factors_888,
 388	}, {
 389		.drm_fmt	= DRM_FORMAT_YUV444,
 390		.bus_fmt	= MEDIA_BUS_FMT_VUY8_1X24,
 391		.buf_fmt	= ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_8 |
 392				  ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV444,
 393		.sf		= scaling_factors_888,
 394	}, {
 395		.drm_fmt	= DRM_FORMAT_P210,
 396		.bus_fmt	= MEDIA_BUS_FMT_UYVY10_1X20,
 397		.buf_fmt	= ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_10 |
 398				  ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV422,
 399		.sf		= scaling_factors_101010,
 400	},
 401};
 402
 403static u32 zynqmp_disp_avbuf_read(struct zynqmp_disp *disp, int reg)
 404{
 405	return readl(disp->avbuf + reg);
 406}
 407
 408static void zynqmp_disp_avbuf_write(struct zynqmp_disp *disp, int reg, u32 val)
 409{
 410	writel(val, disp->avbuf + reg);
 411}
 412
 413static bool zynqmp_disp_layer_is_video(const struct zynqmp_disp_layer *layer)
 414{
 415	return layer->id == ZYNQMP_DPSUB_LAYER_VID;
 416}
 417
 418/**
 419 * zynqmp_disp_avbuf_set_format - Set the input format for a layer
 420 * @disp: Display controller
 421 * @layer: The layer
 422 * @fmt: The format information
 423 *
 424 * Set the video buffer manager format for @layer to @fmt.
 425 */
 426static void zynqmp_disp_avbuf_set_format(struct zynqmp_disp *disp,
 427					 struct zynqmp_disp_layer *layer,
 428					 const struct zynqmp_disp_format *fmt)
 429{
 430	unsigned int i;
 431	u32 val, reg;
 432
 433	layer->disp_fmt = fmt;
 434	if (layer->mode == ZYNQMP_DPSUB_LAYER_NONLIVE) {
 435		reg = ZYNQMP_DISP_AV_BUF_FMT;
 436		val = zynqmp_disp_avbuf_read(disp, ZYNQMP_DISP_AV_BUF_FMT);
 437		val &= zynqmp_disp_layer_is_video(layer)
 438		    ? ~ZYNQMP_DISP_AV_BUF_FMT_NL_VID_MASK
 439		    : ~ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_MASK;
 440		val |= fmt->buf_fmt;
 441		zynqmp_disp_avbuf_write(disp, reg, val);
 442	} else {
 443		reg = zynqmp_disp_layer_is_video(layer)
 444		    ? ZYNQMP_DISP_AV_BUF_LIVE_VID_CONFIG
 445		    : ZYNQMP_DISP_AV_BUF_LIVE_GFX_CONFIG;
 446		val = fmt->buf_fmt;
 447		zynqmp_disp_avbuf_write(disp, reg, val);
 448	}
 449
 450	for (i = 0; i < ZYNQMP_DISP_AV_BUF_NUM_SF; i++) {
 451		reg = zynqmp_disp_layer_is_video(layer)
 452		    ? ZYNQMP_DISP_AV_BUF_VID_COMP_SF(i)
 453		    : ZYNQMP_DISP_AV_BUF_GFX_COMP_SF(i);
 454
 455		zynqmp_disp_avbuf_write(disp, reg, fmt->sf[i]);
 456	}
 457}
 458
 459/**
 460 * zynqmp_disp_avbuf_set_clocks_sources - Set the clocks sources
 461 * @disp: Display controller
 462 * @video_from_ps: True if the video clock originates from the PS
 463 * @audio_from_ps: True if the audio clock originates from the PS
 464 * @timings_internal: True if video timings are generated internally
 465 *
 466 * Set the source for the video and audio clocks, as well as for the video
 467 * timings. Clocks can originate from the PS or PL, and timings can be
 468 * generated internally or externally.
 469 */
 470static void
 471zynqmp_disp_avbuf_set_clocks_sources(struct zynqmp_disp *disp,
 472				     bool video_from_ps, bool audio_from_ps,
 473				     bool timings_internal)
 474{
 475	u32 val = 0;
 476
 477	if (video_from_ps)
 478		val |= ZYNQMP_DISP_AV_BUF_CLK_SRC_VID_FROM_PS;
 479	if (audio_from_ps)
 480		val |= ZYNQMP_DISP_AV_BUF_CLK_SRC_AUD_FROM_PS;
 481	if (timings_internal)
 482		val |= ZYNQMP_DISP_AV_BUF_CLK_SRC_VID_INTERNAL_TIMING;
 483
 484	zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_CLK_SRC, val);
 485}
 486
 487/**
 488 * zynqmp_disp_avbuf_enable_channels - Enable buffer channels
 489 * @disp: Display controller
 490 *
 491 * Enable all (video and audio) buffer channels.
 492 */
 493static void zynqmp_disp_avbuf_enable_channels(struct zynqmp_disp *disp)
 494{
 495	unsigned int i;
 496	u32 val;
 497
 498	val = ZYNQMP_DISP_AV_BUF_CHBUF_EN |
 499	      (ZYNQMP_DISP_AV_BUF_CHBUF_BURST_LEN_MAX <<
 500	       ZYNQMP_DISP_AV_BUF_CHBUF_BURST_LEN_SHIFT);
 501
 502	for (i = 0; i < ZYNQMP_DISP_AV_BUF_NUM_VID_GFX_BUFFERS; i++)
 503		zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_CHBUF(i),
 504					val);
 505
 506	val = ZYNQMP_DISP_AV_BUF_CHBUF_EN |
 507	      (ZYNQMP_DISP_AV_BUF_CHBUF_BURST_LEN_AUD_MAX <<
 508	       ZYNQMP_DISP_AV_BUF_CHBUF_BURST_LEN_SHIFT);
 509
 510	for (; i < ZYNQMP_DISP_AV_BUF_NUM_BUFFERS; i++)
 511		zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_CHBUF(i),
 512					val);
 513}
 514
 515/**
 516 * zynqmp_disp_avbuf_disable_channels - Disable buffer channels
 517 * @disp: Display controller
 518 *
 519 * Disable all (video and audio) buffer channels.
 520 */
 521static void zynqmp_disp_avbuf_disable_channels(struct zynqmp_disp *disp)
 522{
 523	unsigned int i;
 524
 525	for (i = 0; i < ZYNQMP_DISP_AV_BUF_NUM_BUFFERS; i++)
 526		zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_CHBUF(i),
 527					ZYNQMP_DISP_AV_BUF_CHBUF_FLUSH);
 528}
 529
 530/**
 531 * zynqmp_disp_avbuf_enable_audio - Enable audio
 532 * @disp: Display controller
 533 *
 534 * Enable all audio buffers with a non-live (memory) source.
 535 */
 536static void zynqmp_disp_avbuf_enable_audio(struct zynqmp_disp *disp)
 537{
 538	u32 val;
 539
 540	val = zynqmp_disp_avbuf_read(disp, ZYNQMP_DISP_AV_BUF_OUTPUT);
 541	val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_AUD1_MASK;
 542	val |= ZYNQMP_DISP_AV_BUF_OUTPUT_AUD1_MEM;
 543	val |= ZYNQMP_DISP_AV_BUF_OUTPUT_AUD2_EN;
 544	zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_OUTPUT, val);
 545}
 546
 547/**
 548 * zynqmp_disp_avbuf_disable_audio - Disable audio
 549 * @disp: Display controller
 550 *
 551 * Disable all audio buffers.
 552 */
 553static void zynqmp_disp_avbuf_disable_audio(struct zynqmp_disp *disp)
 554{
 555	u32 val;
 556
 557	val = zynqmp_disp_avbuf_read(disp, ZYNQMP_DISP_AV_BUF_OUTPUT);
 558	val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_AUD1_MASK;
 559	val |= ZYNQMP_DISP_AV_BUF_OUTPUT_AUD1_DISABLE;
 560	val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_AUD2_EN;
 561	zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_OUTPUT, val);
 562}
 563
 564/**
 565 * zynqmp_disp_avbuf_enable_video - Enable a video layer
 566 * @disp: Display controller
 567 * @layer: The layer
 568 *
 569 * Enable the video/graphics buffer for @layer.
 570 */
 571static void zynqmp_disp_avbuf_enable_video(struct zynqmp_disp *disp,
 572					   struct zynqmp_disp_layer *layer)
 573{
 574	u32 val;
 575
 576	val = zynqmp_disp_avbuf_read(disp, ZYNQMP_DISP_AV_BUF_OUTPUT);
 577	if (zynqmp_disp_layer_is_video(layer)) {
 578		val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_MASK;
 579		if (layer->mode == ZYNQMP_DPSUB_LAYER_NONLIVE)
 580			val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_MEM;
 581		else
 582			val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_LIVE;
 583	} else {
 584		val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_MASK;
 585		val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_MEM;
 586		if (layer->mode == ZYNQMP_DPSUB_LAYER_NONLIVE)
 587			val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_MEM;
 588		else
 589			val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_LIVE;
 590	}
 591	zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_OUTPUT, val);
 592}
 593
 594/**
 595 * zynqmp_disp_avbuf_disable_video - Disable a video layer
 596 * @disp: Display controller
 597 * @layer: The layer
 598 *
 599 * Disable the video/graphics buffer for @layer.
 600 */
 601static void zynqmp_disp_avbuf_disable_video(struct zynqmp_disp *disp,
 602					    struct zynqmp_disp_layer *layer)
 603{
 604	u32 val;
 605
 606	val = zynqmp_disp_avbuf_read(disp, ZYNQMP_DISP_AV_BUF_OUTPUT);
 607	if (zynqmp_disp_layer_is_video(layer)) {
 608		val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_MASK;
 609		val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_NONE;
 610	} else {
 611		val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_MASK;
 612		val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_DISABLE;
 613	}
 614	zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_OUTPUT, val);
 615}
 616
 617/**
 618 * zynqmp_disp_avbuf_enable - Enable the video pipe
 619 * @disp: Display controller
 620 *
 621 * De-assert the video pipe reset.
 622 */
 623static void zynqmp_disp_avbuf_enable(struct zynqmp_disp *disp)
 624{
 625	zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_SRST_REG, 0);
 626}
 627
 628/**
 629 * zynqmp_disp_avbuf_disable - Disable the video pipe
 630 * @disp: Display controller
 631 *
 632 * Assert the video pipe reset.
 633 */
 634static void zynqmp_disp_avbuf_disable(struct zynqmp_disp *disp)
 635{
 636	zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_SRST_REG,
 637				ZYNQMP_DISP_AV_BUF_SRST_REG_VID_RST);
 638}
 639
 640/* -----------------------------------------------------------------------------
 641 * Blender (Video Pipeline)
 642 */
 643
 644static void zynqmp_disp_blend_write(struct zynqmp_disp *disp, int reg, u32 val)
 645{
 646	writel(val, disp->blend + reg);
 647}
 648
 649/*
 650 * Colorspace conversion matrices.
 651 *
 652 * Hardcode RGB <-> YUV conversion to full-range SDTV for now.
 653 */
 654static const u16 csc_zero_matrix[] = {
 655	0x0,    0x0,    0x0,
 656	0x0,    0x0,    0x0,
 657	0x0,    0x0,    0x0
 658};
 659
 660static const u16 csc_identity_matrix[] = {
 661	0x1000, 0x0,    0x0,
 662	0x0,    0x1000, 0x0,
 663	0x0,    0x0,    0x1000
 664};
 665
 666static const u32 csc_zero_offsets[] = {
 667	0, 0, 0
 668};
 669
 670static const u16 csc_rgb_to_sdtv_matrix[] = {
 671	0x4c9,  0x864,  0x1d3,
 672	0x7d4d, 0x7ab3, 0x800,
 673	0x800,  0x794d, 0x7eb3
 674};
 675
 676static const u32 csc_rgb_to_sdtv_offsets[] = {
 677	0x0, 0x8000000, 0x8000000
 678};
 679
 680static const u16 csc_sdtv_to_rgb_matrix[] = {
 681	0x1000, 0x166f, 0x0,
 682	0x1000, 0x7483, 0x7a7f,
 683	0x1000, 0x0,    0x1c5a
 684};
 685
 686static const u32 csc_sdtv_to_rgb_offsets[] = {
 687	0x0, 0x1800, 0x1800
 688};
 689
 690/**
 691 * zynqmp_disp_blend_set_output_format - Set the output format of the blender
 692 * @disp: Display controller
 693 * @format: Output format
 694 *
 695 * Set the output format of the blender to @format.
 696 */
 697static void zynqmp_disp_blend_set_output_format(struct zynqmp_disp *disp,
 698						enum zynqmp_dpsub_format format)
 699{
 700	static const unsigned int blend_output_fmts[] = {
 701		[ZYNQMP_DPSUB_FORMAT_RGB] = ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_RGB,
 702		[ZYNQMP_DPSUB_FORMAT_YCRCB444] = ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_YCBCR444,
 703		[ZYNQMP_DPSUB_FORMAT_YCRCB422] = ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_YCBCR422
 704					       | ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_EN_DOWNSAMPLE,
 705		[ZYNQMP_DPSUB_FORMAT_YONLY] = ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_YONLY,
 706	};
 707
 708	u32 fmt = blend_output_fmts[format];
 709	const u16 *coeffs;
 710	const u32 *offsets;
 711	unsigned int i;
 712
 713	zynqmp_disp_blend_write(disp, ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT, fmt);
 714	if (fmt == ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_RGB) {
 715		coeffs = csc_identity_matrix;
 716		offsets = csc_zero_offsets;
 717	} else {
 718		coeffs = csc_rgb_to_sdtv_matrix;
 719		offsets = csc_rgb_to_sdtv_offsets;
 720	}
 721
 722	for (i = 0; i < ZYNQMP_DISP_V_BLEND_NUM_COEFF; i++)
 723		zynqmp_disp_blend_write(disp,
 724					ZYNQMP_DISP_V_BLEND_RGB2YCBCR_COEFF(i),
 725					coeffs[i]);
 726
 727	for (i = 0; i < ZYNQMP_DISP_V_BLEND_NUM_OFFSET; i++)
 728		zynqmp_disp_blend_write(disp,
 729					ZYNQMP_DISP_V_BLEND_OUTCSC_OFFSET(i),
 730					offsets[i]);
 731}
 732
 733/**
 734 * zynqmp_disp_blend_set_bg_color - Set the background color
 735 * @disp: Display controller
 736 * @rcr: Red/Cr color component
 737 * @gy: Green/Y color component
 738 * @bcb: Blue/Cb color component
 739 *
 740 * Set the background color to (@rcr, @gy, @bcb), corresponding to the R, G and
 741 * B or Cr, Y and Cb components respectively depending on the selected output
 742 * format.
 743 */
 744static void zynqmp_disp_blend_set_bg_color(struct zynqmp_disp *disp,
 745					   u32 rcr, u32 gy, u32 bcb)
 746{
 747	zynqmp_disp_blend_write(disp, ZYNQMP_DISP_V_BLEND_BG_CLR_0, rcr);
 748	zynqmp_disp_blend_write(disp, ZYNQMP_DISP_V_BLEND_BG_CLR_1, gy);
 749	zynqmp_disp_blend_write(disp, ZYNQMP_DISP_V_BLEND_BG_CLR_2, bcb);
 750}
 751
 752/**
 753 * zynqmp_disp_blend_set_global_alpha - Configure global alpha blending
 754 * @disp: Display controller
 755 * @enable: True to enable global alpha blending
 756 * @alpha: Global alpha value (ignored if @enabled is false)
 757 */
 758void zynqmp_disp_blend_set_global_alpha(struct zynqmp_disp *disp,
 759					bool enable, u32 alpha)
 760{
 761	zynqmp_disp_blend_write(disp, ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA,
 762				ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA_VALUE(alpha) |
 763				(enable ? ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA_EN : 0));
 764}
 765
 766/**
 767 * zynqmp_disp_blend_layer_set_csc - Configure colorspace conversion for layer
 768 * @disp: Display controller
 769 * @layer: The layer
 770 * @coeffs: Colorspace conversion matrix
 771 * @offsets: Colorspace conversion offsets
 772 *
 773 * Configure the input colorspace conversion matrix and offsets for the @layer.
 774 * Columns of the matrix are automatically swapped based on the input format to
 775 * handle RGB and YCrCb components permutations.
 776 */
 777static void zynqmp_disp_blend_layer_set_csc(struct zynqmp_disp *disp,
 778					    struct zynqmp_disp_layer *layer,
 779					    const u16 *coeffs,
 780					    const u32 *offsets)
 781{
 782	unsigned int swap[3] = { 0, 1, 2 };
 783	unsigned int reg;
 784	unsigned int i;
 785
 786	if (layer->disp_fmt->swap) {
 787		if (layer->drm_fmt->is_yuv) {
 788			/* Swap U and V. */
 789			swap[1] = 2;
 790			swap[2] = 1;
 791		} else {
 792			/* Swap R and B. */
 793			swap[0] = 2;
 794			swap[2] = 0;
 795		}
 796	}
 797
 798	if (zynqmp_disp_layer_is_video(layer))
 799		reg = ZYNQMP_DISP_V_BLEND_IN1CSC_COEFF(0);
 800	else
 801		reg = ZYNQMP_DISP_V_BLEND_IN2CSC_COEFF(0);
 802
 803	for (i = 0; i < ZYNQMP_DISP_V_BLEND_NUM_COEFF; i += 3, reg += 12) {
 804		zynqmp_disp_blend_write(disp, reg + 0, coeffs[i + swap[0]]);
 805		zynqmp_disp_blend_write(disp, reg + 4, coeffs[i + swap[1]]);
 806		zynqmp_disp_blend_write(disp, reg + 8, coeffs[i + swap[2]]);
 807	}
 808
 809	if (zynqmp_disp_layer_is_video(layer))
 810		reg = ZYNQMP_DISP_V_BLEND_IN1CSC_OFFSET(0);
 811	else
 812		reg = ZYNQMP_DISP_V_BLEND_IN2CSC_OFFSET(0);
 813
 814	for (i = 0; i < ZYNQMP_DISP_V_BLEND_NUM_OFFSET; i++)
 815		zynqmp_disp_blend_write(disp, reg + i * 4, offsets[i]);
 816}
 817
 818/**
 819 * zynqmp_disp_blend_layer_enable - Enable a layer
 820 * @disp: Display controller
 821 * @layer: The layer
 822 */
 823static void zynqmp_disp_blend_layer_enable(struct zynqmp_disp *disp,
 824					   struct zynqmp_disp_layer *layer)
 825{
 826	const u16 *coeffs;
 827	const u32 *offsets;
 828	u32 val;
 829
 830	val = (layer->drm_fmt->is_yuv ?
 831	       0 : ZYNQMP_DISP_V_BLEND_LAYER_CONTROL_RGB) |
 832	      (layer->drm_fmt->hsub > 1 ?
 833	       ZYNQMP_DISP_V_BLEND_LAYER_CONTROL_EN_US : 0);
 834
 835	zynqmp_disp_blend_write(disp,
 836				ZYNQMP_DISP_V_BLEND_LAYER_CONTROL(layer->id),
 837				val);
 838
 839	if (layer->drm_fmt->is_yuv) {
 840		coeffs = csc_sdtv_to_rgb_matrix;
 841		offsets = csc_sdtv_to_rgb_offsets;
 842	} else {
 843		coeffs = csc_identity_matrix;
 844		offsets = csc_zero_offsets;
 845	}
 846
 847	zynqmp_disp_blend_layer_set_csc(disp, layer, coeffs, offsets);
 848}
 849
 850/**
 851 * zynqmp_disp_blend_layer_disable - Disable a layer
 852 * @disp: Display controller
 853 * @layer: The layer
 854 */
 855static void zynqmp_disp_blend_layer_disable(struct zynqmp_disp *disp,
 856					    struct zynqmp_disp_layer *layer)
 857{
 858	zynqmp_disp_blend_write(disp,
 859				ZYNQMP_DISP_V_BLEND_LAYER_CONTROL(layer->id),
 860				0);
 861
 862	zynqmp_disp_blend_layer_set_csc(disp, layer, csc_zero_matrix,
 863					csc_zero_offsets);
 864}
 865
 866/* -----------------------------------------------------------------------------
 867 * ZynqMP Display Layer & DRM Plane
 868 */
 869
 870/**
 871 * zynqmp_disp_layer_find_format - Find format information for a DRM format
 872 * @layer: The layer
 873 * @drm_fmt: DRM format to search
 874 *
 875 * Search display subsystem format information corresponding to the given DRM
 876 * format @drm_fmt for the @layer, and return a pointer to the format
 877 * descriptor.
 878 *
 879 * Return: A pointer to the format descriptor if found, NULL otherwise
 880 */
 881static const struct zynqmp_disp_format *
 882zynqmp_disp_layer_find_format(struct zynqmp_disp_layer *layer,
 883			      u32 drm_fmt)
 884{
 885	unsigned int i;
 886
 887	for (i = 0; i < layer->info->num_formats; i++) {
 888		if (layer->info->formats[i].drm_fmt == drm_fmt)
 889			return &layer->info->formats[i];
 890	}
 891
 892	return NULL;
 893}
 894
 895/**
 896 * zynqmp_disp_layer_find_live_format - Find format information for given
 897 * media bus format
 898 * @layer: The layer
 899 * @media_bus_format: Media bus format to search
 900 *
 901 * Search display subsystem format information corresponding to the given media
 902 * bus format @media_bus_format for the @layer, and return a pointer to the
 903 * format descriptor.
 904 *
 905 * Return: A pointer to the format descriptor if found, NULL otherwise
 906 */
 907static const struct zynqmp_disp_format *
 908zynqmp_disp_layer_find_live_format(struct zynqmp_disp_layer *layer,
 909				   u32 media_bus_format)
 910{
 911	unsigned int i;
 912
 913	for (i = 0; i < layer->info->num_formats; i++)
 914		if (layer->info->formats[i].bus_fmt == media_bus_format)
 915			return &layer->info->formats[i];
 916
 917	return NULL;
 918}
 919
 920/**
 921 * zynqmp_disp_layer_drm_formats - Return the DRM formats supported by the layer
 922 * @layer: The layer
 923 * @num_formats: Pointer to the returned number of formats
 924 *
 925 * NOTE: This function doesn't make sense for live video layers and will
 926 * always return an empty list in such cases. zynqmp_disp_live_layer_formats()
 927 * should be used to query a list of media bus formats supported by the live
 928 * video input layer.
 929 *
 930 * Return: A newly allocated u32 array that stores all the DRM formats
 931 * supported by the layer. The number of formats in the array is returned
 932 * through the num_formats argument.
 933 */
 934u32 *zynqmp_disp_layer_drm_formats(struct zynqmp_disp_layer *layer,
 935				   unsigned int *num_formats)
 936{
 937	unsigned int i;
 938	u32 *formats;
 939
 940	if (WARN_ON(layer->mode != ZYNQMP_DPSUB_LAYER_NONLIVE)) {
 941		*num_formats = 0;
 942		return NULL;
 943	}
 944
 945	formats = kcalloc(layer->info->num_formats, sizeof(*formats),
 946			  GFP_KERNEL);
 947	if (!formats) {
 948		*num_formats = 0;
 949		return NULL;
 950	}
 951
 952	for (i = 0; i < layer->info->num_formats; ++i)
 953		formats[i] = layer->info->formats[i].drm_fmt;
 954
 955	*num_formats = layer->info->num_formats;
 956	return formats;
 957}
 958
 959/**
 960 * zynqmp_disp_live_layer_formats - Return the media bus formats supported by
 961 * the live video layer
 962 * @layer: The layer
 963 * @num_formats: Pointer to the returned number of formats
 964 *
 965 * NOTE: This function should be used only for live video input layers.
 966 *
 967 * Return: A newly allocated u32 array of media bus formats supported by the
 968 * layer. The number of formats in the array is returned through the
 969 * @num_formats argument.
 970 */
 971u32 *zynqmp_disp_live_layer_formats(struct zynqmp_disp_layer *layer,
 972				    unsigned int *num_formats)
 973{
 974	unsigned int i;
 975	u32 *formats;
 976
 977	if (WARN_ON(layer->mode != ZYNQMP_DPSUB_LAYER_LIVE)) {
 978		*num_formats = 0;
 979		return NULL;
 980	}
 981
 982	formats = kcalloc(layer->info->num_formats, sizeof(*formats),
 983			  GFP_KERNEL);
 984	if (!formats) {
 985		*num_formats = 0;
 986		return NULL;
 987	}
 988
 989	for (i = 0; i < layer->info->num_formats; ++i)
 990		formats[i] = layer->info->formats[i].bus_fmt;
 991
 992	*num_formats = layer->info->num_formats;
 993	return formats;
 994}
 995
 996/**
 997 * zynqmp_disp_layer_enable - Enable a layer
 998 * @layer: The layer
 999 *
1000 * Enable the @layer in the audio/video buffer manager and the blender. DMA
1001 * channels are started separately by zynqmp_disp_layer_update().
1002 */
1003void zynqmp_disp_layer_enable(struct zynqmp_disp_layer *layer)
1004{
1005	zynqmp_disp_avbuf_enable_video(layer->disp, layer);
1006	zynqmp_disp_blend_layer_enable(layer->disp, layer);
1007}
1008
1009/**
1010 * zynqmp_disp_layer_disable - Disable the layer
1011 * @layer: The layer
1012 *
1013 * Disable the layer by stopping its DMA channels and disabling it in the
1014 * audio/video buffer manager and the blender.
1015 */
1016void zynqmp_disp_layer_disable(struct zynqmp_disp_layer *layer)
1017{
1018	unsigned int i;
1019
1020	if (layer->mode == ZYNQMP_DPSUB_LAYER_NONLIVE) {
1021		for (i = 0; i < layer->drm_fmt->num_planes; i++)
1022			dmaengine_terminate_sync(layer->dmas[i].chan);
1023	}
1024
1025	zynqmp_disp_avbuf_disable_video(layer->disp, layer);
1026	zynqmp_disp_blend_layer_disable(layer->disp, layer);
1027}
1028
1029/**
1030 * zynqmp_disp_layer_set_format - Set the layer format
1031 * @layer: The layer
1032 * @info: The format info
1033 *
1034 * NOTE: Use zynqmp_disp_layer_set_live_format() to set media bus format for
1035 * live video layers.
1036 *
1037 * Set the format for @layer to @info. The layer must be disabled.
1038 */
1039void zynqmp_disp_layer_set_format(struct zynqmp_disp_layer *layer,
1040				  const struct drm_format_info *info)
1041{
1042	unsigned int i;
1043
1044	if (WARN_ON(layer->mode != ZYNQMP_DPSUB_LAYER_NONLIVE))
1045		return;
1046
1047	layer->disp_fmt = zynqmp_disp_layer_find_format(layer, info->format);
1048	if (WARN_ON(!layer->disp_fmt))
1049		return;
1050	layer->drm_fmt = info;
1051
1052	zynqmp_disp_avbuf_set_format(layer->disp, layer, layer->disp_fmt);
1053
1054	/*
1055	 * Set pconfig for each DMA channel to indicate they're part of a
1056	 * video group.
1057	 */
1058	for (i = 0; i < info->num_planes; i++) {
1059		struct zynqmp_disp_layer_dma *dma = &layer->dmas[i];
1060		struct xilinx_dpdma_peripheral_config pconfig = {
1061			.video_group = true,
1062		};
1063		struct dma_slave_config config = {
1064			.direction = DMA_MEM_TO_DEV,
1065			.peripheral_config = &pconfig,
1066			.peripheral_size = sizeof(pconfig),
1067		};
1068
1069		dmaengine_slave_config(dma->chan, &config);
1070	}
1071}
1072
1073/**
1074 * zynqmp_disp_layer_set_live_format - Set the live video layer format
1075 * @layer: The layer
1076 * @media_bus_format: Media bus format to set
1077 *
1078 * NOTE: This function should not be used to set format for non-live video
1079 * layer. Use zynqmp_disp_layer_set_format() instead.
1080 *
1081 * Set the display format for the live @layer. The layer must be disabled.
1082 */
1083void zynqmp_disp_layer_set_live_format(struct zynqmp_disp_layer *layer,
1084				       u32 media_bus_format)
1085{
1086	if (WARN_ON(layer->mode != ZYNQMP_DPSUB_LAYER_LIVE))
1087		return;
1088
1089	layer->disp_fmt = zynqmp_disp_layer_find_live_format(layer,
1090							     media_bus_format);
1091	if (WARN_ON(!layer->disp_fmt))
1092		return;
1093
1094	zynqmp_disp_avbuf_set_format(layer->disp, layer, layer->disp_fmt);
1095
1096	layer->drm_fmt = drm_format_info(layer->disp_fmt->drm_fmt);
1097}
1098
1099/**
1100 * zynqmp_disp_layer_update - Update the layer framebuffer
1101 * @layer: The layer
1102 * @state: The plane state
1103 *
1104 * Update the framebuffer for the layer by issuing a new DMA engine transaction
1105 * for the new framebuffer.
1106 *
1107 * Return: 0 on success, or the DMA descriptor failure error otherwise
1108 */
1109int zynqmp_disp_layer_update(struct zynqmp_disp_layer *layer,
1110			     struct drm_plane_state *state)
1111{
1112	const struct drm_format_info *info = layer->drm_fmt;
1113	unsigned int i;
1114
1115	if (layer->mode == ZYNQMP_DPSUB_LAYER_LIVE)
1116		return 0;
1117
1118	for (i = 0; i < info->num_planes; i++) {
1119		unsigned int width = state->crtc_w / (i ? info->hsub : 1);
1120		unsigned int height = state->crtc_h / (i ? info->vsub : 1);
1121		struct zynqmp_disp_layer_dma *dma = &layer->dmas[i];
1122		struct dma_async_tx_descriptor *desc;
1123		dma_addr_t dma_addr;
1124
1125		dma_addr = drm_fb_dma_get_gem_addr(state->fb, state, i);
1126
1127		dma->xt.numf = height;
1128		dma->sgl.size = width * info->cpp[i];
1129		dma->sgl.icg = state->fb->pitches[i] - dma->sgl.size;
1130		dma->xt.src_start = dma_addr;
1131		dma->xt.frame_size = 1;
1132		dma->xt.dir = DMA_MEM_TO_DEV;
1133		dma->xt.src_sgl = true;
1134		dma->xt.dst_sgl = false;
1135
1136		desc = dmaengine_prep_interleaved_dma(dma->chan, &dma->xt,
1137						      DMA_CTRL_ACK |
1138						      DMA_PREP_REPEAT |
1139						      DMA_PREP_LOAD_EOT);
1140		if (!desc) {
1141			dev_err(layer->disp->dev,
1142				"failed to prepare DMA descriptor\n");
1143			return -ENOMEM;
1144		}
1145
1146		dmaengine_submit(desc);
1147		dma_async_issue_pending(dma->chan);
1148	}
1149
1150	return 0;
1151}
1152
1153/**
1154 * zynqmp_disp_layer_release_dma - Release DMA channels for a layer
1155 * @disp: Display controller
1156 * @layer: The layer
1157 *
1158 * Release the DMA channels associated with @layer.
1159 */
1160static void zynqmp_disp_layer_release_dma(struct zynqmp_disp *disp,
1161					  struct zynqmp_disp_layer *layer)
1162{
1163	unsigned int i;
1164
1165	if (!layer->info)
1166		return;
1167
1168	for (i = 0; i < layer->info->num_channels; i++) {
1169		struct zynqmp_disp_layer_dma *dma = &layer->dmas[i];
1170
1171		if (!dma->chan)
1172			continue;
1173
1174		/* Make sure the channel is terminated before release. */
1175		dmaengine_terminate_sync(dma->chan);
1176		dma_release_channel(dma->chan);
1177	}
1178}
1179
1180/**
1181 * zynqmp_disp_destroy_layers - Destroy all layers
1182 * @disp: Display controller
1183 */
1184static void zynqmp_disp_destroy_layers(struct zynqmp_disp *disp)
1185{
1186	unsigned int i;
1187
1188	for (i = 0; i < ARRAY_SIZE(disp->layers); i++)
1189		zynqmp_disp_layer_release_dma(disp, &disp->layers[i]);
1190}
1191
1192/**
1193 * zynqmp_disp_layer_request_dma - Request DMA channels for a layer
1194 * @disp: Display controller
1195 * @layer: The layer
1196 *
1197 * Request all DMA engine channels needed by @layer.
1198 *
1199 * Return: 0 on success, or the DMA channel request error otherwise
1200 */
1201static int zynqmp_disp_layer_request_dma(struct zynqmp_disp *disp,
1202					 struct zynqmp_disp_layer *layer)
1203{
1204	static const char * const dma_names[] = { "vid", "gfx" };
1205	unsigned int i;
1206	int ret;
1207
1208	for (i = 0; i < layer->info->num_channels; i++) {
1209		struct zynqmp_disp_layer_dma *dma = &layer->dmas[i];
1210		char dma_channel_name[16];
1211
1212		snprintf(dma_channel_name, sizeof(dma_channel_name),
1213			 "%s%u", dma_names[layer->id], i);
1214		dma->chan = dma_request_chan(disp->dev, dma_channel_name);
1215		if (IS_ERR(dma->chan)) {
1216			ret = dev_err_probe(disp->dev, PTR_ERR(dma->chan),
1217					    "failed to request dma channel\n");
1218			dma->chan = NULL;
1219			return ret;
1220		}
1221	}
1222
1223	return 0;
1224}
1225
1226/**
1227 * zynqmp_disp_create_layers - Create and initialize all layers
1228 * @disp: Display controller
1229 *
1230 * Return: 0 on success, or the DMA channel request error otherwise
1231 */
1232static int zynqmp_disp_create_layers(struct zynqmp_disp *disp)
1233{
1234	static const struct zynqmp_disp_layer_info layer_info[] = {
1235		[ZYNQMP_DPSUB_LAYER_VID] = {
1236			.formats = avbuf_vid_fmts,
1237			.num_formats = ARRAY_SIZE(avbuf_vid_fmts),
1238			.num_channels = 3,
1239		},
1240		[ZYNQMP_DPSUB_LAYER_GFX] = {
1241			.formats = avbuf_gfx_fmts,
1242			.num_formats = ARRAY_SIZE(avbuf_gfx_fmts),
1243			.num_channels = 1,
1244		},
1245	};
1246	static const struct zynqmp_disp_layer_info live_layer_info = {
1247		.formats = avbuf_live_fmts,
1248		.num_formats = ARRAY_SIZE(avbuf_live_fmts),
1249		.num_channels = 0,
1250	};
1251
1252	unsigned int i;
1253	int ret;
1254
1255	for (i = 0; i < ARRAY_SIZE(disp->layers); i++) {
1256		struct zynqmp_disp_layer *layer = &disp->layers[i];
1257
1258		layer->id = i;
1259		layer->disp = disp;
1260		/*
1261		 * For now assume dpsub works in either live or non-live mode for both layers.
1262		 * Hybrid mode is not supported yet.
1263		 */
1264		if (disp->dpsub->dma_enabled) {
1265			layer->mode = ZYNQMP_DPSUB_LAYER_NONLIVE;
1266			layer->info = &layer_info[i];
1267		} else {
1268			layer->mode = ZYNQMP_DPSUB_LAYER_LIVE;
1269			layer->info = &live_layer_info;
1270		}
1271
1272		ret = zynqmp_disp_layer_request_dma(disp, layer);
1273		if (ret)
1274			goto err;
1275
1276		disp->dpsub->layers[i] = layer;
1277	}
1278
1279	return 0;
1280
1281err:
1282	zynqmp_disp_destroy_layers(disp);
1283	return ret;
1284}
1285
1286/* -----------------------------------------------------------------------------
1287 * ZynqMP Display
1288 */
1289
1290/**
1291 * zynqmp_disp_enable - Enable the display controller
1292 * @disp: Display controller
1293 */
1294void zynqmp_disp_enable(struct zynqmp_disp *disp)
1295{
1296	zynqmp_disp_blend_set_output_format(disp, ZYNQMP_DPSUB_FORMAT_RGB);
1297	zynqmp_disp_blend_set_bg_color(disp, 0, 0, 0);
1298
1299	zynqmp_disp_avbuf_enable(disp);
1300	/* Choose clock source based on the DT clock handle. */
1301	zynqmp_disp_avbuf_set_clocks_sources(disp, disp->dpsub->vid_clk_from_ps,
1302					     disp->dpsub->aud_clk_from_ps,
1303					     disp->dpsub->vid_clk_from_ps);
1304	zynqmp_disp_avbuf_enable_channels(disp);
1305	zynqmp_disp_avbuf_enable_audio(disp);
1306}
1307
1308/**
1309 * zynqmp_disp_disable - Disable the display controller
1310 * @disp: Display controller
1311 */
1312void zynqmp_disp_disable(struct zynqmp_disp *disp)
1313{
1314	zynqmp_disp_avbuf_disable_audio(disp);
1315	zynqmp_disp_avbuf_disable_channels(disp);
1316	zynqmp_disp_avbuf_disable(disp);
1317}
1318
1319/**
1320 * zynqmp_disp_setup_clock - Configure the display controller pixel clock rate
1321 * @disp: Display controller
1322 * @mode_clock: The pixel clock rate, in Hz
1323 *
1324 * Return: 0 on success, or a negative error clock otherwise
1325 */
1326int zynqmp_disp_setup_clock(struct zynqmp_disp *disp,
1327			    unsigned long mode_clock)
1328{
1329	unsigned long rate;
1330	long diff;
1331	int ret;
1332
1333	ret = clk_set_rate(disp->dpsub->vid_clk, mode_clock);
1334	if (ret) {
1335		dev_err(disp->dev, "failed to set the video clock\n");
1336		return ret;
1337	}
1338
1339	rate = clk_get_rate(disp->dpsub->vid_clk);
1340	diff = rate - mode_clock;
1341	if (abs(diff) > mode_clock / 20)
1342		dev_info(disp->dev,
1343			 "requested pixel rate: %lu actual rate: %lu\n",
1344			 mode_clock, rate);
1345	else
1346		dev_dbg(disp->dev,
1347			"requested pixel rate: %lu actual rate: %lu\n",
1348			mode_clock, rate);
1349
1350	return 0;
1351}
1352
1353/* -----------------------------------------------------------------------------
1354 * Initialization & Cleanup
1355 */
1356
1357int zynqmp_disp_probe(struct zynqmp_dpsub *dpsub)
1358{
1359	struct platform_device *pdev = to_platform_device(dpsub->dev);
1360	struct zynqmp_disp *disp;
1361	int ret;
1362
1363	disp = kzalloc(sizeof(*disp), GFP_KERNEL);
1364	if (!disp)
1365		return -ENOMEM;
1366
1367	disp->dev = &pdev->dev;
1368	disp->dpsub = dpsub;
1369
1370	disp->blend = devm_platform_ioremap_resource_byname(pdev, "blend");
1371	if (IS_ERR(disp->blend)) {
1372		ret = PTR_ERR(disp->blend);
1373		goto error;
1374	}
1375
1376	disp->avbuf = devm_platform_ioremap_resource_byname(pdev, "av_buf");
1377	if (IS_ERR(disp->avbuf)) {
1378		ret = PTR_ERR(disp->avbuf);
1379		goto error;
1380	}
1381
1382	ret = zynqmp_disp_create_layers(disp);
1383	if (ret)
1384		goto error;
1385
1386	if (disp->dpsub->dma_enabled) {
1387		struct zynqmp_disp_layer *layer;
1388
1389		layer = &disp->layers[ZYNQMP_DPSUB_LAYER_VID];
1390		dpsub->dma_align = 1 << layer->dmas[0].chan->device->copy_align;
1391	}
1392
1393	dpsub->disp = disp;
1394
1395	return 0;
1396
1397error:
1398	kfree(disp);
1399	return ret;
1400}
1401
1402void zynqmp_disp_remove(struct zynqmp_dpsub *dpsub)
1403{
1404	struct zynqmp_disp *disp = dpsub->disp;
1405
1406	zynqmp_disp_destroy_layers(disp);
1407}
~/ Read-only file preview.