zynqmp_disp.c (46983B)
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_crtc.h> 16#include <drm/drm_device.h> 17#include <drm/drm_fb_cma_helper.h> 18#include <drm/drm_fourcc.h> 19#include <drm/drm_framebuffer.h> 20#include <drm/drm_managed.h> 21#include <drm/drm_plane.h> 22#include <drm/drm_plane_helper.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 */ 86struct 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 */ 99enum 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 */ 109enum 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 */ 120struct 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 */ 132struct 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 */ 149struct 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 */ 178struct 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 209static 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 215static 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 221static 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 227static 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 233static 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 */ 240static 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 */ 345static 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 409static u32 zynqmp_disp_avbuf_read(struct zynqmp_disp *disp, int reg) 410{ 411 return readl(disp->avbuf.base + reg); 412} 413 414static void zynqmp_disp_avbuf_write(struct zynqmp_disp *disp, int reg, u32 val) 415{ 416 writel(val, disp->avbuf.base + reg); 417} 418 419static bool zynqmp_disp_layer_is_gfx(const struct zynqmp_disp_layer *layer) 420{ 421 return layer->id == ZYNQMP_DISP_LAYER_GFX; 422} 423 424static 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 */ 437static 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 */ 471static void 472zynqmp_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 */ 494static 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 */ 522static 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 */ 537static 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 */ 554static 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 */ 573static 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 */ 604static 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 */ 626static 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 */ 637static 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 647static 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 */ 657static const u16 csc_zero_matrix[] = { 658 0x0, 0x0, 0x0, 659 0x0, 0x0, 0x0, 660 0x0, 0x0, 0x0 661}; 662 663static const u16 csc_identity_matrix[] = { 664 0x1000, 0x0, 0x0, 665 0x0, 0x1000, 0x0, 666 0x0, 0x0, 0x1000 667}; 668 669static const u32 csc_zero_offsets[] = { 670 0, 0, 0 671}; 672 673static const u16 csc_rgb_to_sdtv_matrix[] = { 674 0x4c9, 0x864, 0x1d3, 675 0x7d4d, 0x7ab3, 0x800, 676 0x800, 0x794d, 0x7eb3 677}; 678 679static const u32 csc_rgb_to_sdtv_offsets[] = { 680 0x0, 0x8000000, 0x8000000 681}; 682 683static const u16 csc_sdtv_to_rgb_matrix[] = { 684 0x1000, 0x166f, 0x0, 685 0x1000, 0x7483, 0x7a7f, 686 0x1000, 0x0, 0x1c5a 687}; 688 689static 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 */ 700static 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 */ 747static 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 */ 761static 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 */ 780static 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 */ 826static 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 */ 858static 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 873static 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 */ 885static 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 */ 899static 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 905static 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 */ 935void 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 */ 950bool 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 */ 961unsigned 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 */ 974uint32_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 */ 994static const struct zynqmp_disp_format * 995zynqmp_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 */ 1015static 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 */ 1031static 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 */ 1050static 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 */ 1090static 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 paddr; 1102 1103 paddr = drm_fb_cma_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 = paddr; 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 1131static 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 1136static int 1137zynqmp_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_HELPER_NO_SCALING, 1154 DRM_PLANE_HELPER_NO_SCALING, 1155 false, false); 1156} 1157 1158static void 1159zynqmp_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 1176static void 1177zynqmp_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 1212static 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 1218static 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 1227static 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 */ 1275static 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 */ 1299static 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 */ 1316static 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 */ 1347static 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 1379err: 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 */ 1392static 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 */ 1408static 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 1417static inline struct zynqmp_disp *crtc_to_disp(struct drm_crtc *crtc) 1418{ 1419 return container_of(crtc, struct zynqmp_disp, crtc); 1420} 1421 1422static 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 1451static void 1452zynqmp_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 1481static void 1482zynqmp_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 1512static 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 1518static void 1519zynqmp_disp_crtc_atomic_begin(struct drm_crtc *crtc, 1520 struct drm_atomic_state *state) 1521{ 1522 drm_crtc_vblank_on(crtc); 1523} 1524 1525static void 1526zynqmp_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 1546static 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 1554static 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 1563static 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 1570static 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 1581static 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 1599static 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 1612int 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 1630int 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 1692void zynqmp_disp_remove(struct zynqmp_dpsub *dpsub) 1693{ 1694 struct zynqmp_disp *disp = dpsub->disp; 1695 1696 zynqmp_disp_destroy_layers(disp); 1697}