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