linux/drivers/gpu/drm/xlnx/zynqmp_disp.c
<<
>>
Prefs
   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_crtc_helper.h>
  17#include <drm/drm_fb_cma_helper.h>
  18#include <drm/drm_fourcc.h>
  19#include <drm/drm_plane_helper.h>
  20#include <drm/drm_vblank.h>
  21
  22#include <linux/clk.h>
  23#include <linux/delay.h>
  24#include <linux/device.h>
  25#include <linux/dma-mapping.h>
  26#include <linux/dmaengine.h>
  27#include <linux/interrupt.h>
  28#include <linux/irqreturn.h>
  29#include <linux/list.h>
  30#include <linux/module.h>
  31#include <linux/mutex.h>
  32#include <linux/of.h>
  33#include <linux/of_dma.h>
  34#include <linux/platform_device.h>
  35#include <linux/pm_runtime.h>
  36#include <linux/spinlock.h>
  37#include <linux/uaccess.h>
  38#include <video/videomode.h>
  39#include <linux/mfd/syscon.h>
  40#include <linux/regmap.h>
  41
  42#include "xlnx_bridge.h"
  43#include "xlnx_crtc.h"
  44#include "xlnx_fb.h"
  45#include "zynqmp_disp.h"
  46#include "zynqmp_disp_regs.h"
  47#include "zynqmp_dp.h"
  48#include "zynqmp_dpsub.h"
  49
  50/*
  51 * Overview
  52 * --------
  53 *
  54 * The display part of ZynqMP DP subsystem. Internally, the device
  55 * is partitioned into 3 blocks: AV buffer manager, Blender, Audio.
  56 * The driver creates the DRM crtc and plane objectes and maps the DRM
  57 * interface into those 3 blocks. In high level, the driver is layered
  58 * in the following way:
  59 *
  60 * zynqmp_disp_crtc & zynqmp_disp_plane
  61 * |->zynqmp_disp
  62 *      |->zynqmp_disp_aud
  63 *      |->zynqmp_disp_blend
  64 *      |->zynqmp_disp_av_buf
  65 *
  66 * The driver APIs are used externally by
  67 * - zynqmp_dpsub: Top level ZynqMP DP subsystem driver
  68 * - zynqmp_dp: ZynqMP DP driver
  69 * - xlnx_crtc: Xilinx DRM specific crtc functions
  70 */
  71
  72/* The default value is ZYNQMP_DISP_AV_BUF_GFX_FMT_RGB565 */
  73static uint zynqmp_disp_gfx_init_fmt;
  74module_param_named(gfx_init_fmt, zynqmp_disp_gfx_init_fmt, uint, 0444);
  75MODULE_PARM_DESC(gfx_init_fmt, "The initial format of the graphics layer\n"
  76                               "\t\t0 = rgb565 (default)\n"
  77                               "\t\t1 = rgb888\n"
  78                               "\t\t2 = argb8888\n");
  79/* These value should be mapped to index of av_buf_gfx_fmts[] */
  80#define ZYNQMP_DISP_AV_BUF_GFX_FMT_RGB565               10
  81#define ZYNQMP_DISP_AV_BUF_GFX_FMT_RGB888               5
  82#define ZYNQMP_DISP_AV_BUF_GFX_FMT_ARGB8888             1
  83static const u32 zynqmp_disp_gfx_init_fmts[] = {
  84        ZYNQMP_DISP_AV_BUF_GFX_FMT_RGB565,
  85        ZYNQMP_DISP_AV_BUF_GFX_FMT_RGB888,
  86        ZYNQMP_DISP_AV_BUF_GFX_FMT_ARGB8888,
  87};
  88
  89#define ZYNQMP_DISP_AV_BUF_NUM_VID_GFX_BUFFERS          4
  90#define ZYNQMP_DISP_AV_BUF_NUM_BUFFERS                  6
  91
  92#define ZYNQMP_DISP_NUM_LAYERS                          2
  93#define ZYNQMP_DISP_MAX_NUM_SUB_PLANES                  3
  94/*
  95 * 3840x2160 is advertised max resolution, but almost any resolutions under
  96 * 300Mhz pixel rate would work. Thus put 4096 as maximum width and height.
  97 */
  98#define ZYNQMP_DISP_MAX_WIDTH                           4096
  99#define ZYNQMP_DISP_MAX_HEIGHT                          4096
 100/* 44 bit addressing. This is actually DPDMA limitation */
 101#define ZYNQMP_DISP_MAX_DMA_BIT                         44
 102
 103static struct regmap_config dpaud_regmap_config = {
 104        .name = "regmap",
 105        .reg_bits = 32,
 106        .val_bits = 32,
 107        .reg_stride = 4,
 108        .max_register = 0xfff,
 109        .cache_type = REGCACHE_NONE,
 110};
 111
 112/**
 113 * enum zynqmp_disp_layer_type - Layer type (can be used for hw ID)
 114 * @ZYNQMP_DISP_LAYER_VID: Video layer
 115 * @ZYNQMP_DISP_LAYER_GFX: Graphics layer
 116 */
 117enum zynqmp_disp_layer_type {
 118        ZYNQMP_DISP_LAYER_VID,
 119        ZYNQMP_DISP_LAYER_GFX
 120};
 121
 122/**
 123 * enum zynqmp_disp_layer_mode - Layer mode
 124 * @ZYNQMP_DISP_LAYER_NONLIVE: non-live (memory) mode
 125 * @ZYNQMP_DISP_LAYER_LIVE: live (stream) mode
 126 */
 127enum zynqmp_disp_layer_mode {
 128        ZYNQMP_DISP_LAYER_NONLIVE,
 129        ZYNQMP_DISP_LAYER_LIVE
 130};
 131
 132/**
 133 * struct zynqmp_disp_layer_dma - struct for DMA engine
 134 * @chan: DMA channel
 135 * @is_active: flag if the DMA is active
 136 * @xt: Interleaved desc config container
 137 * @sgl: Data chunk for dma_interleaved_template
 138 */
 139struct zynqmp_disp_layer_dma {
 140        struct dma_chan *chan;
 141        bool is_active;
 142        struct dma_interleaved_template xt;
 143        struct data_chunk sgl[1];
 144};
 145
 146/**
 147 * struct zynqmp_disp_layer - Display subsystem layer
 148 * @plane: DRM plane
 149 * @bridge: Xlnx bridge
 150 * @dma: struct for DMA engine
 151 * @num_chan: Number of DMA channel
 152 * @id: Layer ID
 153 * @offset: Layer offset in the register space
 154 * @enabled: flag if enabled
 155 * @fmt: Current format descriptor
 156 * @drm_fmts: Array of supported DRM formats
 157 * @num_fmts: Number of supported DRM formats
 158 * @bus_fmts: Array of supported bus formats
 159 * @num_bus_fmts: Number of supported bus formats
 160 * @w: Width
 161 * @h: Height
 162 * @mode: the operation mode
 163 * @other: other layer
 164 * @disp: back pointer to struct zynqmp_disp
 165 */
 166struct zynqmp_disp_layer {
 167        struct drm_plane plane;
 168        struct xlnx_bridge bridge;
 169        struct zynqmp_disp_layer_dma dma[ZYNQMP_DISP_MAX_NUM_SUB_PLANES];
 170        unsigned int num_chan;
 171        enum zynqmp_disp_layer_type id;
 172        u32 offset;
 173        u8 enabled;
 174        const struct zynqmp_disp_fmt *fmt;
 175        u32 *drm_fmts;
 176        unsigned int num_fmts;
 177        u32 *bus_fmts;
 178        unsigned int num_bus_fmts;
 179        u32 w;
 180        u32 h;
 181        enum zynqmp_disp_layer_mode mode;
 182        struct zynqmp_disp_layer *other;
 183        struct zynqmp_disp *disp;
 184};
 185
 186/**
 187 * struct zynqmp_disp_blend - Blender
 188 * @base: Base address offset
 189 */
 190struct zynqmp_disp_blend {
 191        void __iomem *base;
 192};
 193
 194/**
 195 * struct zynqmp_disp_av_buf - AV buffer manager
 196 * @base: Base address offset
 197 */
 198struct zynqmp_disp_av_buf {
 199        void __iomem *base;
 200};
 201
 202/**
 203 * struct zynqmp_disp_aud - Audio
 204 * @base: Base address offset
 205 */
 206struct zynqmp_disp_aud {
 207        struct regmap *base;
 208};
 209
 210/**
 211 * struct zynqmp_disp - Display subsystem
 212 * @xlnx_crtc: Xilinx DRM crtc
 213 * @dev: device structure
 214 * @dpsub: Display subsystem
 215 * @drm: DRM core
 216 * @enabled: flag if enabled
 217 * @blend: Blender block
 218 * @av_buf: AV buffer manager block
 219 * @aud:Audio block
 220 * @layers: layers
 221 * @g_alpha_prop: global alpha property
 222 * @alpha: current global alpha value
 223 * @g_alpha_en_prop: the global alpha enable property
 224 * @alpha_en: flag if the global alpha is enabled
 225 * @color_prop: output color format property
 226 * @color: current output color value
 227 * @bg_c0_prop: 1st component of background color property
 228 * @bg_c0: current value of 1st background color component
 229 * @bg_c1_prop: 2nd component of background color property
 230 * @bg_c1: current value of 2nd background color component
 231 * @bg_c2_prop: 3rd component of background color property
 232 * @bg_c2: current value of 3rd background color component
 233 * @tpg_prop: Test Pattern Generation mode property
 234 * @tpg_on: current TPG mode state
 235 * @event: pending vblank event request
 236 * @_ps_pclk: Pixel clock from PS
 237 * @_pl_pclk: Pixel clock from PL
 238 * @pclk: Pixel clock
 239 * @pclk_en: Flag if the pixel clock is enabled
 240 * @_ps_audclk: Audio clock from PS
 241 * @_pl_audclk: Audio clock from PL
 242 * @audclk: Audio clock
 243 * @audclk_en: Flag if the audio clock is enabled
 244 * @aclk: APB clock
 245 * @aclk_en: Flag if the APB clock is enabled
 246 * @vtc_bridge: vtc_bridge structure
 247 */
 248struct zynqmp_disp {
 249        struct xlnx_crtc xlnx_crtc;
 250        struct device *dev;
 251        struct zynqmp_dpsub *dpsub;
 252        struct drm_device *drm;
 253        bool enabled;
 254        struct zynqmp_disp_blend blend;
 255        struct zynqmp_disp_av_buf av_buf;
 256        struct zynqmp_disp_aud aud;
 257        struct zynqmp_disp_layer layers[ZYNQMP_DISP_NUM_LAYERS];
 258        struct drm_property *g_alpha_prop;
 259        u32 alpha;
 260        struct drm_property *g_alpha_en_prop;
 261        bool alpha_en;
 262        struct drm_property *color_prop;
 263        unsigned int color;
 264        struct drm_property *bg_c0_prop;
 265        u32 bg_c0;
 266        struct drm_property *bg_c1_prop;
 267        u32 bg_c1;
 268        struct drm_property *bg_c2_prop;
 269        u32 bg_c2;
 270        struct drm_property *tpg_prop;
 271        bool tpg_on;
 272        struct drm_pending_vblank_event *event;
 273        /* Don't operate directly on _ps_ */
 274        struct clk *_ps_pclk;
 275        struct clk *_pl_pclk;
 276        struct clk *pclk;
 277        bool pclk_en;
 278        struct clk *_ps_audclk;
 279        struct clk *_pl_audclk;
 280        struct clk *audclk;
 281        bool audclk_en;
 282        struct clk *aclk;
 283        bool aclk_en;
 284        struct xlnx_bridge *vtc_bridge;
 285};
 286
 287/**
 288 * struct zynqmp_disp_fmt - Display subsystem format mapping
 289 * @drm_fmt: drm format
 290 * @disp_fmt: Display subsystem format
 291 * @bus_fmt: Bus formats (live formats)
 292 * @rgb: flag for RGB formats
 293 * @swap: flag to swap r & b for rgb formats, and u & v for yuv formats
 294 * @chroma_sub: flag for chroma subsampled formats
 295 * @sf: scaling factors for up to 3 color components
 296 */
 297struct zynqmp_disp_fmt {
 298        u32 drm_fmt;
 299        u32 disp_fmt;
 300        u32 bus_fmt;
 301        bool rgb;
 302        bool swap;
 303        bool chroma_sub;
 304        u32 sf[3];
 305};
 306
 307static void zynqmp_disp_write(void __iomem *base, int offset, u32 val)
 308{
 309        writel(val, base + offset);
 310}
 311
 312static u32 zynqmp_disp_read(void __iomem *base, int offset)
 313{
 314        return readl(base + offset);
 315}
 316
 317static void zynqmp_disp_clr(void __iomem *base, int offset, u32 clr)
 318{
 319        zynqmp_disp_write(base, offset, zynqmp_disp_read(base, offset) & ~clr);
 320}
 321
 322static void zynqmp_disp_set(void __iomem *base, int offset, u32 set)
 323{
 324        zynqmp_disp_write(base, offset, zynqmp_disp_read(base, offset) | set);
 325}
 326
 327/*
 328 * Clock functions
 329 */
 330
 331/**
 332 * zynqmp_disp_clk_enable - Enable the clock if needed
 333 * @clk: clk device
 334 * @flag: flag if the clock is enabled
 335 *
 336 * Enable the clock only if it's not enabled @flag.
 337 *
 338 * Return: value from clk_prepare_enable().
 339 */
 340static int zynqmp_disp_clk_enable(struct clk *clk, bool *flag)
 341{
 342        int ret = 0;
 343
 344        if (!*flag) {
 345                ret = clk_prepare_enable(clk);
 346                if (!ret)
 347                        *flag = true;
 348        }
 349
 350        return ret;
 351}
 352
 353/**
 354 * zynqmp_disp_clk_disable - Disable the clock if needed
 355 * @clk: clk device
 356 * @flag: flag if the clock is enabled
 357 *
 358 * Disable the clock only if it's enabled @flag.
 359 */
 360static void zynqmp_disp_clk_disable(struct clk *clk, bool *flag)
 361{
 362        if (*flag) {
 363                clk_disable_unprepare(clk);
 364                *flag = false;
 365        }
 366}
 367
 368/**
 369 * zynqmp_disp_clk_enable_disable - Enable and disable the clock
 370 * @clk: clk device
 371 * @flag: flag if the clock is enabled
 372 *
 373 * This is to ensure the clock is disabled. The initial hardware state is
 374 * unknown, and this makes sure that the clock is disabled.
 375 *
 376 * Return: value from clk_prepare_enable().
 377 */
 378static int zynqmp_disp_clk_enable_disable(struct clk *clk, bool *flag)
 379{
 380        int ret = 0;
 381
 382        if (!*flag) {
 383                ret = clk_prepare_enable(clk);
 384                clk_disable_unprepare(clk);
 385        }
 386
 387        return ret;
 388}
 389
 390/*
 391 * Blender functions
 392 */
 393
 394/**
 395 * zynqmp_disp_blend_set_output_fmt - Set the output format of the blend
 396 * @blend: blend object
 397 * @fmt: output format
 398 *
 399 * Set the output format to @fmt.
 400 */
 401static void
 402zynqmp_disp_blend_set_output_fmt(struct zynqmp_disp_blend *blend, u32 fmt)
 403{
 404        u16 reset_coeffs[] = { 0x1000, 0x0, 0x0,
 405                               0x0, 0x1000, 0x0,
 406                               0x0, 0x0, 0x1000 };
 407        u32 reset_offsets[] = { 0x0, 0x0, 0x0 };
 408        u16 sdtv_coeffs[] = { 0x4c9, 0x864, 0x1d3,
 409                              0x7d4d, 0x7ab3, 0x800,
 410                              0x800, 0x794d, 0x7eb3 };
 411        u32 full_range_offsets[] = { 0x0, 0x8000000, 0x8000000 };
 412        u16 *coeffs;
 413        u32 *offsets;
 414        u32 offset, i;
 415
 416        zynqmp_disp_write(blend->base, ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT, fmt);
 417        if (fmt == ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_RGB) {
 418                coeffs = reset_coeffs;
 419                offsets = reset_offsets;
 420        } else {
 421                /* Hardcode Full-range SDTV values. Can be runtime config */
 422                coeffs = sdtv_coeffs;
 423                offsets = full_range_offsets;
 424        }
 425
 426        offset = ZYNQMP_DISP_V_BLEND_RGB2YCBCR_COEFF0;
 427        for (i = 0; i < ZYNQMP_DISP_V_BLEND_NUM_COEFF; i++)
 428                zynqmp_disp_write(blend->base, offset + i * 4, coeffs[i]);
 429
 430        offset = ZYNQMP_DISP_V_BLEND_LUMA_OUTCSC_OFFSET;
 431        for (i = 0; i < ZYNQMP_DISP_V_BLEND_NUM_OFFSET; i++)
 432                zynqmp_disp_write(blend->base, offset + i * 4, offsets[i]);
 433}
 434
 435/**
 436 * zynqmp_disp_blend_layer_coeff - Set the coefficients for @layer
 437 * @blend: blend object
 438 * @layer: layer to set the coefficients for
 439 * @on: if layer is on / off
 440 *
 441 * Depending on the format (rgb / yuv and swap), and the status (on / off),
 442 * this function sets the coefficients for the given layer @layer accordingly.
 443 */
 444static void zynqmp_disp_blend_layer_coeff(struct zynqmp_disp_blend *blend,
 445                                          struct zynqmp_disp_layer *layer,
 446                                          bool on)
 447{
 448        u32 offset, i, s0, s1;
 449        u16 sdtv_coeffs[] = { 0x1000, 0x166f, 0x0,
 450                              0x1000, 0x7483, 0x7a7f,
 451                              0x1000, 0x0, 0x1c5a };
 452        u16 sdtv_coeffs_yonly[] = { 0x0, 0x0, 0x1000,
 453                                    0x0, 0x0, 0x1000,
 454                                    0x0, 0x0, 0x1000 };
 455        u16 swap_coeffs[] = { 0x1000, 0x0, 0x0,
 456                              0x0, 0x1000, 0x0,
 457                              0x0, 0x0, 0x1000 };
 458        u16 null_coeffs[] = { 0x0, 0x0, 0x0,
 459                              0x0, 0x0, 0x0,
 460                              0x0, 0x0, 0x0 };
 461        u16 *coeffs;
 462        u32 sdtv_offsets[] = { 0x0, 0x1800, 0x1800 };
 463        u32 sdtv_offsets_yonly[] = { 0x1800, 0x1800, 0x0 };
 464        u32 null_offsets[] = { 0x0, 0x0, 0x0 };
 465        u32 *offsets;
 466        struct zynqmp_disp *display = layer->disp;
 467
 468        if (layer->id == ZYNQMP_DISP_LAYER_VID)
 469                offset = ZYNQMP_DISP_V_BLEND_IN1CSC_COEFF0;
 470        else
 471                offset = ZYNQMP_DISP_V_BLEND_IN2CSC_COEFF0;
 472
 473        if (!on) {
 474                coeffs = null_coeffs;
 475                offsets = null_offsets;
 476        } else {
 477                if ((!layer->fmt->rgb) && (!display->tpg_on)) {
 478                        /*
 479                         * In case of Y_ONLY formats, pixels are unpacked
 480                         * differently compared to YCbCr
 481                         */
 482                        if (layer->fmt->drm_fmt == DRM_FORMAT_Y8 ||
 483                            layer->fmt->drm_fmt == DRM_FORMAT_Y10) {
 484                                coeffs = sdtv_coeffs_yonly;
 485                                offsets = sdtv_offsets_yonly;
 486                        } else {
 487                                coeffs = sdtv_coeffs;
 488                                offsets = sdtv_offsets;
 489                        }
 490
 491                        s0 = 1;
 492                        s1 = 2;
 493                } else {
 494                        coeffs = swap_coeffs;
 495                        s0 = 0;
 496                        s1 = 2;
 497
 498                        /* No offset for RGB formats */
 499                        offsets = null_offsets;
 500                }
 501
 502                if (layer->fmt->swap) {
 503                        for (i = 0; i < 3; i++) {
 504                                coeffs[i * 3 + s0] ^= coeffs[i * 3 + s1];
 505                                coeffs[i * 3 + s1] ^= coeffs[i * 3 + s0];
 506                                coeffs[i * 3 + s0] ^= coeffs[i * 3 + s1];
 507                        }
 508                }
 509        }
 510
 511        /* Program coefficients. Can be runtime configurable */
 512        for (i = 0; i < ZYNQMP_DISP_V_BLEND_NUM_COEFF; i++)
 513                zynqmp_disp_write(blend->base, offset + i * 4, coeffs[i]);
 514
 515        if (layer->id == ZYNQMP_DISP_LAYER_VID)
 516                offset = ZYNQMP_DISP_V_BLEND_LUMA_IN1CSC_OFFSET;
 517        else
 518                offset = ZYNQMP_DISP_V_BLEND_LUMA_IN2CSC_OFFSET;
 519
 520        /* Program offsets. Can be runtime configurable */
 521        for (i = 0; i < ZYNQMP_DISP_V_BLEND_NUM_OFFSET; i++)
 522                zynqmp_disp_write(blend->base, offset + i * 4, offsets[i]);
 523}
 524
 525/**
 526 * zynqmp_disp_blend_layer_enable - Enable a layer
 527 * @blend: blend object
 528 * @layer: layer to enable
 529 *
 530 * Enable a layer @layer.
 531 */
 532static void zynqmp_disp_blend_layer_enable(struct zynqmp_disp_blend *blend,
 533                                           struct zynqmp_disp_layer *layer)
 534{
 535        u32 reg;
 536
 537        reg = layer->fmt->rgb ? ZYNQMP_DISP_V_BLEND_LAYER_CONTROL_RGB : 0;
 538        reg |= layer->fmt->chroma_sub ?
 539               ZYNQMP_DISP_V_BLEND_LAYER_CONTROL_EN_US : 0;
 540
 541        zynqmp_disp_write(blend->base,
 542                          ZYNQMP_DISP_V_BLEND_LAYER_CONTROL + layer->offset,
 543                          reg);
 544
 545        zynqmp_disp_blend_layer_coeff(blend, layer, true);
 546}
 547
 548/**
 549 * zynqmp_disp_blend_layer_disable - Disable a layer
 550 * @blend: blend object
 551 * @layer: layer to disable
 552 *
 553 * Disable a layer @layer.
 554 */
 555static void zynqmp_disp_blend_layer_disable(struct zynqmp_disp_blend *blend,
 556                                            struct zynqmp_disp_layer *layer)
 557{
 558        zynqmp_disp_write(blend->base,
 559                          ZYNQMP_DISP_V_BLEND_LAYER_CONTROL + layer->offset, 0);
 560
 561        zynqmp_disp_blend_layer_coeff(blend, layer, false);
 562}
 563
 564/**
 565 * zynqmp_disp_blend_set_bg_color - Set the background color
 566 * @blend: blend object
 567 * @c0: color component 0
 568 * @c1: color component 1
 569 * @c2: color component 2
 570 *
 571 * Set the background color.
 572 */
 573static void zynqmp_disp_blend_set_bg_color(struct zynqmp_disp_blend *blend,
 574                                           u32 c0, u32 c1, u32 c2)
 575{
 576        zynqmp_disp_write(blend->base, ZYNQMP_DISP_V_BLEND_BG_CLR_0, c0);
 577        zynqmp_disp_write(blend->base, ZYNQMP_DISP_V_BLEND_BG_CLR_1, c1);
 578        zynqmp_disp_write(blend->base, ZYNQMP_DISP_V_BLEND_BG_CLR_2, c2);
 579}
 580
 581/**
 582 * zynqmp_disp_blend_set_alpha - Set the alpha for blending
 583 * @blend: blend object
 584 * @alpha: alpha value to be used
 585 *
 586 * Set the alpha for blending.
 587 */
 588static void
 589zynqmp_disp_blend_set_alpha(struct zynqmp_disp_blend *blend, u32 alpha)
 590{
 591        u32 reg;
 592
 593        reg = zynqmp_disp_read(blend->base,
 594                               ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA);
 595        reg &= ~ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA_MASK;
 596        reg |= alpha << 1;
 597        zynqmp_disp_write(blend->base, ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA,
 598                          reg);
 599}
 600
 601/**
 602 * zynqmp_disp_blend_enable_alpha - Enable/disable the global alpha
 603 * @blend: blend object
 604 * @enable: flag to enable or disable alpha blending
 605 *
 606 * Enable/disable the global alpha blending based on @enable.
 607 */
 608static void
 609zynqmp_disp_blend_enable_alpha(struct zynqmp_disp_blend *blend, bool enable)
 610{
 611        if (enable)
 612                zynqmp_disp_set(blend->base,
 613                                ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA, BIT(0));
 614        else
 615                zynqmp_disp_clr(blend->base,
 616                                ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA, BIT(0));
 617}
 618
 619/* List of blend output formats */
 620/* The id / order should be aligned with zynqmp_disp_color_enum */
 621static const struct zynqmp_disp_fmt blend_output_fmts[] = {
 622        {
 623                .disp_fmt       = ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_RGB,
 624        }, {
 625                .disp_fmt       = ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_YCBCR444,
 626        }, {
 627                .disp_fmt       = ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_YCBCR422,
 628        }, {
 629                .disp_fmt       = ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_YONLY,
 630        }
 631};
 632
 633/*
 634 * AV buffer manager functions
 635 */
 636
 637/* List of video layer formats */
 638#define ZYNQMP_DISP_AV_BUF_VID_FMT_YUYV 2
 639static const struct zynqmp_disp_fmt av_buf_vid_fmts[] = {
 640        {
 641                .drm_fmt        = DRM_FORMAT_VYUY,
 642                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_VYUY,
 643                .rgb            = false,
 644                .swap           = true,
 645                .chroma_sub     = true,
 646                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 647                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 648                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 649        }, {
 650                .drm_fmt        = DRM_FORMAT_UYVY,
 651                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_VYUY,
 652                .rgb            = false,
 653                .swap           = false,
 654                .chroma_sub     = true,
 655                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 656                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 657                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 658        }, {
 659                .drm_fmt        = DRM_FORMAT_YUYV,
 660                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YUYV,
 661                .rgb            = false,
 662                .swap           = false,
 663                .chroma_sub     = true,
 664                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 665                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 666                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 667        }, {
 668                .drm_fmt        = DRM_FORMAT_YVYU,
 669                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YUYV,
 670                .rgb            = false,
 671                .swap           = true,
 672                .chroma_sub     = true,
 673                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 674                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 675                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 676        }, {
 677                .drm_fmt        = DRM_FORMAT_YUV422,
 678                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16,
 679                .rgb            = false,
 680                .swap           = false,
 681                .chroma_sub     = true,
 682                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 683                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 684                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 685        }, {
 686                .drm_fmt        = DRM_FORMAT_YVU422,
 687                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16,
 688                .rgb            = false,
 689                .swap           = true,
 690                .chroma_sub     = true,
 691                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 692                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 693                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 694        }, {
 695                .drm_fmt        = DRM_FORMAT_YUV444,
 696                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV24,
 697                .rgb            = false,
 698                .swap           = false,
 699                .chroma_sub     = false,
 700                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 701                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 702                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 703        }, {
 704                .drm_fmt        = DRM_FORMAT_YVU444,
 705                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV24,
 706                .rgb            = false,
 707                .swap           = true,
 708                .chroma_sub     = false,
 709                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 710                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 711                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 712        }, {
 713                .drm_fmt        = DRM_FORMAT_NV16,
 714                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI,
 715                .rgb            = false,
 716                .swap           = false,
 717                .chroma_sub     = true,
 718                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 719                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 720                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 721        }, {
 722                .drm_fmt        = DRM_FORMAT_NV61,
 723                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI,
 724                .rgb            = false,
 725                .swap           = true,
 726                .chroma_sub     = true,
 727                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 728                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 729                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 730        }, {
 731                .drm_fmt        = DRM_FORMAT_Y8,
 732                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_MONO,
 733                .rgb            = false,
 734                .swap           = false,
 735                .chroma_sub     = false,
 736                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 737                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 738                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 739        }, {
 740                .drm_fmt        = DRM_FORMAT_Y10,
 741                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YONLY_10,
 742                .rgb            = false,
 743                .swap           = false,
 744                .chroma_sub     = false,
 745                .sf[0]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
 746                .sf[1]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
 747                .sf[2]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
 748        }, {
 749                .drm_fmt        = DRM_FORMAT_BGR888,
 750                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGB888,
 751                .rgb            = true,
 752                .swap           = false,
 753                .chroma_sub     = false,
 754                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 755                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 756                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 757        }, {
 758                .drm_fmt        = DRM_FORMAT_RGB888,
 759                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGB888,
 760                .rgb            = true,
 761                .swap           = true,
 762                .chroma_sub     = false,
 763                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 764                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 765                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 766        }, {
 767                .drm_fmt        = DRM_FORMAT_XBGR8888,
 768                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGBA8880,
 769                .rgb            = true,
 770                .swap           = false,
 771                .chroma_sub     = false,
 772                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 773                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 774                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 775        }, {
 776                .drm_fmt        = DRM_FORMAT_XRGB8888,
 777                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGBA8880,
 778                .rgb            = true,
 779                .swap           = true,
 780                .chroma_sub     = false,
 781                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 782                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 783                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 784        }, {
 785                .drm_fmt        = DRM_FORMAT_XBGR2101010,
 786                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGB888_10,
 787                .rgb            = true,
 788                .swap           = false,
 789                .chroma_sub     = false,
 790                .sf[0]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
 791                .sf[1]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
 792                .sf[2]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
 793        }, {
 794                .drm_fmt        = DRM_FORMAT_XRGB2101010,
 795                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGB888_10,
 796                .rgb            = true,
 797                .swap           = true,
 798                .chroma_sub     = false,
 799                .sf[0]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
 800                .sf[1]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
 801                .sf[2]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
 802        }, {
 803                .drm_fmt        = DRM_FORMAT_YUV420,
 804                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16_420,
 805                .rgb            = false,
 806                .swap           = false,
 807                .chroma_sub     = true,
 808                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 809                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 810                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 811        }, {
 812                .drm_fmt        = DRM_FORMAT_YVU420,
 813                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16_420,
 814                .rgb            = false,
 815                .swap           = true,
 816                .chroma_sub     = true,
 817                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 818                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 819                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 820        }, {
 821                .drm_fmt        = DRM_FORMAT_NV12,
 822                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI_420,
 823                .rgb            = false,
 824                .swap           = false,
 825                .chroma_sub     = true,
 826                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 827                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 828                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 829        }, {
 830                .drm_fmt        = DRM_FORMAT_NV21,
 831                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI_420,
 832                .rgb            = false,
 833                .swap           = true,
 834                .chroma_sub     = true,
 835                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 836                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 837                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 838        }, {
 839                .drm_fmt        = DRM_FORMAT_XV15,
 840                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI_420_10,
 841                .rgb            = false,
 842                .swap           = false,
 843                .chroma_sub     = true,
 844                .sf[0]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
 845                .sf[1]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
 846                .sf[2]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
 847        }, {
 848                .drm_fmt        = DRM_FORMAT_XV20,
 849                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI_10,
 850                .rgb            = false,
 851                .swap           = false,
 852                .chroma_sub     = true,
 853                .sf[0]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
 854                .sf[1]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
 855                .sf[2]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
 856        }, {
 857                .drm_fmt        = DRM_FORMAT_X403,
 858                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV24_10,
 859                .rgb            = false,
 860                .swap           = false,
 861                .chroma_sub     = false,
 862                .sf[0]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
 863                .sf[1]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
 864                .sf[2]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
 865        }
 866};
 867
 868/* List of graphics layer formats */
 869static const struct zynqmp_disp_fmt av_buf_gfx_fmts[] = {
 870        {
 871                .drm_fmt        = DRM_FORMAT_ABGR8888,
 872                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA8888,
 873                .rgb            = true,
 874                .swap           = false,
 875                .chroma_sub     = false,
 876                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 877                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 878                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 879        }, {
 880                .drm_fmt        = DRM_FORMAT_ARGB8888,
 881                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA8888,
 882                .rgb            = true,
 883                .swap           = true,
 884                .chroma_sub     = false,
 885                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 886                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 887                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 888        }, {
 889                .drm_fmt        = DRM_FORMAT_RGBA8888,
 890                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_ABGR8888,
 891                .rgb            = true,
 892                .swap           = false,
 893                .chroma_sub     = false,
 894                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 895                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 896                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 897        }, {
 898                .drm_fmt        = DRM_FORMAT_BGRA8888,
 899                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_ABGR8888,
 900                .rgb            = true,
 901                .swap           = true,
 902                .chroma_sub     = false,
 903                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 904                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 905                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 906        }, {
 907                .drm_fmt        = DRM_FORMAT_BGR888,
 908                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGB888,
 909                .rgb            = true,
 910                .swap           = false,
 911                .chroma_sub     = false,
 912                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 913                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 914                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 915        }, {
 916                .drm_fmt        = DRM_FORMAT_RGB888,
 917                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_BGR888,
 918                .rgb            = true,
 919                .swap           = false,
 920                .chroma_sub     = false,
 921                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 922                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 923                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
 924        }, {
 925                .drm_fmt        = DRM_FORMAT_RGBA5551,
 926                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA5551,
 927                .rgb            = true,
 928                .swap           = false,
 929                .chroma_sub     = false,
 930                .sf[0]          = ZYNQMP_DISP_AV_BUF_5BIT_SF,
 931                .sf[1]          = ZYNQMP_DISP_AV_BUF_5BIT_SF,
 932                .sf[2]          = ZYNQMP_DISP_AV_BUF_5BIT_SF,
 933        }, {
 934                .drm_fmt        = DRM_FORMAT_BGRA5551,
 935                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA5551,
 936                .rgb            = true,
 937                .swap           = true,
 938                .chroma_sub     = false,
 939                .sf[0]          = ZYNQMP_DISP_AV_BUF_5BIT_SF,
 940                .sf[1]          = ZYNQMP_DISP_AV_BUF_5BIT_SF,
 941                .sf[2]          = ZYNQMP_DISP_AV_BUF_5BIT_SF,
 942        }, {
 943                .drm_fmt        = DRM_FORMAT_RGBA4444,
 944                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA4444,
 945                .rgb            = true,
 946                .swap           = false,
 947                .chroma_sub     = false,
 948                .sf[0]          = ZYNQMP_DISP_AV_BUF_4BIT_SF,
 949                .sf[1]          = ZYNQMP_DISP_AV_BUF_4BIT_SF,
 950                .sf[2]          = ZYNQMP_DISP_AV_BUF_4BIT_SF,
 951        }, {
 952                .drm_fmt        = DRM_FORMAT_BGRA4444,
 953                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA4444,
 954                .rgb            = true,
 955                .swap           = true,
 956                .chroma_sub     = false,
 957                .sf[0]          = ZYNQMP_DISP_AV_BUF_4BIT_SF,
 958                .sf[1]          = ZYNQMP_DISP_AV_BUF_4BIT_SF,
 959                .sf[2]          = ZYNQMP_DISP_AV_BUF_4BIT_SF,
 960        }, {
 961                .drm_fmt        = DRM_FORMAT_RGB565,
 962                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGB565,
 963                .rgb            = true,
 964                .swap           = false,
 965                .chroma_sub     = false,
 966                .sf[0]          = ZYNQMP_DISP_AV_BUF_5BIT_SF,
 967                .sf[1]          = ZYNQMP_DISP_AV_BUF_6BIT_SF,
 968                .sf[2]          = ZYNQMP_DISP_AV_BUF_5BIT_SF,
 969        }, {
 970                .drm_fmt        = DRM_FORMAT_BGR565,
 971                .disp_fmt       = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGB565,
 972                .rgb            = true,
 973                .swap           = true,
 974                .chroma_sub     = false,
 975                .sf[0]          = ZYNQMP_DISP_AV_BUF_5BIT_SF,
 976                .sf[1]          = ZYNQMP_DISP_AV_BUF_6BIT_SF,
 977                .sf[2]          = ZYNQMP_DISP_AV_BUF_5BIT_SF,
 978        }
 979};
 980
 981/* List of live formats */
 982/* Format can be combination of color, bpc, and cb-cr order.
 983 * - Color: RGB / YUV444 / YUV422 / Y only
 984 * - BPC: 6, 8, 10, 12
 985 * - Swap: Cb and Cr swap
 986 * which can be 32 bus formats. Only list the subset of those for now.
 987 */
 988static const struct zynqmp_disp_fmt av_buf_live_fmts[] = {
 989        {
 990                .bus_fmt        = MEDIA_BUS_FMT_RGB666_1X18,
 991                .disp_fmt       = ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_6 |
 992                                  ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_RGB,
 993                .rgb            = true,
 994                .swap           = false,
 995                .chroma_sub     = false,
 996                .sf[0]          = ZYNQMP_DISP_AV_BUF_6BIT_SF,
 997                .sf[1]          = ZYNQMP_DISP_AV_BUF_6BIT_SF,
 998                .sf[2]          = ZYNQMP_DISP_AV_BUF_6BIT_SF,
 999        }, {
1000                .bus_fmt        = MEDIA_BUS_FMT_RBG888_1X24,
1001                .disp_fmt       = ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_8 |
1002                                  ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_RGB,
1003                .rgb            = true,
1004                .swap           = false,
1005                .chroma_sub     = false,
1006                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
1007                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
1008                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
1009        }, {
1010                .bus_fmt        = MEDIA_BUS_FMT_UYVY8_1X16,
1011                .disp_fmt       = ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_8 |
1012                                  ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV422,
1013                .rgb            = false,
1014                .swap           = false,
1015                .chroma_sub     = true,
1016                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
1017                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
1018                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
1019        }, {
1020                .bus_fmt        = MEDIA_BUS_FMT_VUY8_1X24,
1021                .disp_fmt       = ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_8 |
1022                                  ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV444,
1023                .rgb            = false,
1024                .swap           = false,
1025                .chroma_sub     = false,
1026                .sf[0]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
1027                .sf[1]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
1028                .sf[2]          = ZYNQMP_DISP_AV_BUF_8BIT_SF,
1029        }, {
1030                .bus_fmt        = MEDIA_BUS_FMT_UYVY10_1X20,
1031                .disp_fmt       = ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_10 |
1032                                  ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV422,
1033                .rgb            = false,
1034                .swap           = false,
1035                .chroma_sub     = true,
1036                .sf[0]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
1037                .sf[1]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
1038                .sf[2]          = ZYNQMP_DISP_AV_BUF_10BIT_SF,
1039        }
1040};
1041
1042/**
1043 * zynqmp_disp_av_buf_set_fmt - Set the input formats
1044 * @av_buf: av buffer manager
1045 * @fmt: formats
1046 *
1047 * Set the av buffer manager format to @fmt. @fmt should have valid values
1048 * for both video and graphics layer.
1049 */
1050static void
1051zynqmp_disp_av_buf_set_fmt(struct zynqmp_disp_av_buf *av_buf, u32 fmt)
1052{
1053        zynqmp_disp_write(av_buf->base, ZYNQMP_DISP_AV_BUF_FMT, fmt);
1054}
1055
1056/**
1057 * zynqmp_disp_av_buf_get_fmt - Get the input formats
1058 * @av_buf: av buffer manager
1059 *
1060 * Get the input formats (which include video and graphics) of
1061 * av buffer manager.
1062 *
1063 * Return: value of ZYNQMP_DISP_AV_BUF_FMT register.
1064 */
1065static u32
1066zynqmp_disp_av_buf_get_fmt(struct zynqmp_disp_av_buf *av_buf)
1067{
1068        return zynqmp_disp_read(av_buf->base, ZYNQMP_DISP_AV_BUF_FMT);
1069}
1070
1071/**
1072 * zynqmp_disp_av_buf_set_live_fmt - Set the live_input format
1073 * @av_buf: av buffer manager
1074 * @fmt: format
1075 * @is_vid: if it's for video layer
1076 *
1077 * Set the live input format to @fmt. @fmt should have valid values.
1078 * @vid will determine if it's for video layer or graphics layer
1079 * @fmt should be a valid hardware value.
1080 */
1081static void zynqmp_disp_av_buf_set_live_fmt(struct zynqmp_disp_av_buf *av_buf,
1082                                            u32 fmt, bool is_vid)
1083{
1084        u32 offset;
1085
1086        if (is_vid)
1087                offset = ZYNQMP_DISP_AV_BUF_LIVE_VID_CONFIG;
1088        else
1089                offset = ZYNQMP_DISP_AV_BUF_LIVE_GFX_CONFIG;
1090
1091        zynqmp_disp_write(av_buf->base, offset, fmt);
1092}
1093
1094/**
1095 * zynqmp_disp_av_buf_set_vid_clock_src - Set the video clock source
1096 * @av_buf: av buffer manager
1097 * @from_ps: flag if the video clock is from ps
1098 *
1099 * Set the video clock source based on @from_ps. It can come from either PS or
1100 * PL.
1101 */
1102static void
1103zynqmp_disp_av_buf_set_vid_clock_src(struct zynqmp_disp_av_buf *av_buf,
1104                                     bool from_ps)
1105{
1106        u32 reg = zynqmp_disp_read(av_buf->base, ZYNQMP_DISP_AV_BUF_CLK_SRC);
1107
1108        if (from_ps)
1109                reg |= ZYNQMP_DISP_AV_BUF_CLK_SRC_VID_FROM_PS;
1110        else
1111                reg &= ~ZYNQMP_DISP_AV_BUF_CLK_SRC_VID_FROM_PS;
1112        zynqmp_disp_write(av_buf->base, ZYNQMP_DISP_AV_BUF_CLK_SRC, reg);
1113}
1114
1115/**
1116 * zynqmp_disp_av_buf_vid_clock_src_is_ps - if ps clock is used
1117 * @av_buf: av buffer manager
1118 *
1119 * Return: if ps clock is used
1120 */
1121static bool
1122zynqmp_disp_av_buf_vid_clock_src_is_ps(struct zynqmp_disp_av_buf *av_buf)
1123{
1124        u32 reg = zynqmp_disp_read(av_buf->base, ZYNQMP_DISP_AV_BUF_CLK_SRC);
1125
1126        return !!(reg & ZYNQMP_DISP_AV_BUF_CLK_SRC_VID_FROM_PS);
1127}
1128
1129/**
1130 * zynqmp_disp_av_buf_set_vid_timing_src - Set the video timing source
1131 * @av_buf: av buffer manager
1132 * @internal: flag if the video timing is generated internally
1133 *
1134 * Set the video timing source based on @internal. It can come externally or
1135 * be generated internally.
1136 */
1137static void
1138zynqmp_disp_av_buf_set_vid_timing_src(struct zynqmp_disp_av_buf *av_buf,
1139                                      bool internal)
1140{
1141        u32 reg = zynqmp_disp_read(av_buf->base, ZYNQMP_DISP_AV_BUF_CLK_SRC);
1142
1143        if (internal)
1144                reg |= ZYNQMP_DISP_AV_BUF_CLK_SRC_VID_INTERNAL_TIMING;
1145        else
1146                reg &= ~ZYNQMP_DISP_AV_BUF_CLK_SRC_VID_INTERNAL_TIMING;
1147        zynqmp_disp_write(av_buf->base, ZYNQMP_DISP_AV_BUF_CLK_SRC, reg);
1148}
1149
1150/**
1151 * zynqmp_disp_av_buf_vid_timing_src_is_int - if internal timing is used
1152 * @av_buf: av buffer manager
1153 *
1154 * Return: if the internal timing is used
1155 */
1156static bool
1157zynqmp_disp_av_buf_vid_timing_src_is_int(struct zynqmp_disp_av_buf *av_buf)
1158{
1159        u32 reg = zynqmp_disp_read(av_buf->base, ZYNQMP_DISP_AV_BUF_CLK_SRC);
1160
1161        return !!(reg & ZYNQMP_DISP_AV_BUF_CLK_SRC_VID_INTERNAL_TIMING);
1162}
1163
1164/**
1165 * zynqmp_disp_av_buf_set_aud_clock_src - Set the audio clock source
1166 * @av_buf: av buffer manager
1167 * @from_ps: flag if the video clock is from ps
1168 *
1169 * Set the audio clock source based on @from_ps. It can come from either PS or
1170 * PL.
1171 */
1172static void
1173zynqmp_disp_av_buf_set_aud_clock_src(struct zynqmp_disp_av_buf *av_buf,
1174                                     bool from_ps)
1175{
1176        u32 reg = zynqmp_disp_read(av_buf->base, ZYNQMP_DISP_AV_BUF_CLK_SRC);
1177
1178        if (from_ps)
1179                reg |= ZYNQMP_DISP_AV_BUF_CLK_SRC_AUD_FROM_PS;
1180        else
1181                reg &= ~ZYNQMP_DISP_AV_BUF_CLK_SRC_AUD_FROM_PS;
1182        zynqmp_disp_write(av_buf->base, ZYNQMP_DISP_AV_BUF_CLK_SRC, reg);
1183}
1184
1185/**
1186 * zynqmp_disp_av_buf_enable_buf - Enable buffers
1187 * @av_buf: av buffer manager
1188 *
1189 * Enable all (video and audio) buffers.
1190 */
1191static void
1192zynqmp_disp_av_buf_enable_buf(struct zynqmp_disp_av_buf *av_buf)
1193{
1194        u32 reg, i;
1195
1196        reg = ZYNQMP_DISP_AV_BUF_CHBUF_EN;
1197        reg |= ZYNQMP_DISP_AV_BUF_CHBUF_BURST_LEN_MAX <<
1198               ZYNQMP_DISP_AV_BUF_CHBUF_BURST_LEN_SHIFT;
1199
1200        for (i = 0; i < ZYNQMP_DISP_AV_BUF_NUM_VID_GFX_BUFFERS; i++)
1201                zynqmp_disp_write(av_buf->base,
1202                                  ZYNQMP_DISP_AV_BUF_CHBUF + i * 4, reg);
1203
1204        reg = ZYNQMP_DISP_AV_BUF_CHBUF_EN;
1205        reg |= ZYNQMP_DISP_AV_BUF_CHBUF_BURST_LEN_AUD_MAX <<
1206               ZYNQMP_DISP_AV_BUF_CHBUF_BURST_LEN_SHIFT;
1207
1208        for (; i < ZYNQMP_DISP_AV_BUF_NUM_BUFFERS; i++)
1209                zynqmp_disp_write(av_buf->base,
1210                                  ZYNQMP_DISP_AV_BUF_CHBUF + i * 4, reg);
1211}
1212
1213/**
1214 * zynqmp_disp_av_buf_disable_buf - Disable buffers
1215 * @av_buf: av buffer manager
1216 *
1217 * Disable all (video and audio) buffers.
1218 */
1219static void
1220zynqmp_disp_av_buf_disable_buf(struct zynqmp_disp_av_buf *av_buf)
1221{
1222        u32 reg, i;
1223
1224        reg = ZYNQMP_DISP_AV_BUF_CHBUF_FLUSH & ~ZYNQMP_DISP_AV_BUF_CHBUF_EN;
1225        for (i = 0; i < ZYNQMP_DISP_AV_BUF_NUM_BUFFERS; i++)
1226                zynqmp_disp_write(av_buf->base,
1227                                  ZYNQMP_DISP_AV_BUF_CHBUF + i * 4, reg);
1228}
1229
1230/**
1231 * zynqmp_disp_av_buf_enable_aud - Enable audio
1232 * @av_buf: av buffer manager
1233 *
1234 * Enable all audio buffers.
1235 */
1236static void
1237zynqmp_disp_av_buf_enable_aud(struct zynqmp_disp_av_buf *av_buf)
1238{
1239        u32 reg;
1240
1241        reg = zynqmp_disp_read(av_buf->base, ZYNQMP_DISP_AV_BUF_OUTPUT);
1242        reg &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_AUD1_MASK;
1243        reg |= ZYNQMP_DISP_AV_BUF_OUTPUT_AUD1_MEM;
1244        reg |= ZYNQMP_DISP_AV_BUF_OUTPUT_AUD2_EN;
1245        zynqmp_disp_write(av_buf->base, ZYNQMP_DISP_AV_BUF_OUTPUT, reg);
1246}
1247
1248/**
1249 * zynqmp_disp_av_buf_enable - Enable the video pipe
1250 * @av_buf: av buffer manager
1251 *
1252 * De-assert the video pipe reset
1253 */
1254static void
1255zynqmp_disp_av_buf_enable(struct zynqmp_disp_av_buf *av_buf)
1256{
1257        zynqmp_disp_write(av_buf->base, ZYNQMP_DISP_AV_BUF_SRST_REG, 0);
1258}
1259
1260/**
1261 * zynqmp_disp_av_buf_disable - Disable the video pipe
1262 * @av_buf: av buffer manager
1263 *
1264 * Assert the video pipe reset
1265 */
1266static void
1267zynqmp_disp_av_buf_disable(struct zynqmp_disp_av_buf *av_buf)
1268{
1269        zynqmp_disp_write(av_buf->base, ZYNQMP_DISP_AV_BUF_SRST_REG,
1270                          ZYNQMP_DISP_AV_BUF_SRST_REG_VID_RST);
1271}
1272
1273/**
1274 * zynqmp_disp_av_buf_disable_aud - Disable audio
1275 * @av_buf: av buffer manager
1276 *
1277 * Disable all audio buffers.
1278 */
1279static void
1280zynqmp_disp_av_buf_disable_aud(struct zynqmp_disp_av_buf *av_buf)
1281{
1282        u32 reg;
1283
1284        reg = zynqmp_disp_read(av_buf->base, ZYNQMP_DISP_AV_BUF_OUTPUT);
1285        reg &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_AUD1_MASK;
1286        reg |= ZYNQMP_DISP_AV_BUF_OUTPUT_AUD1_DISABLE;
1287        reg &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_AUD2_EN;
1288        zynqmp_disp_write(av_buf->base, ZYNQMP_DISP_AV_BUF_OUTPUT, reg);
1289}
1290
1291/**
1292 * zynqmp_disp_av_buf_set_tpg - Set TPG mode
1293 * @av_buf: av buffer manager
1294 * @tpg_on: if TPG should be on
1295 *
1296 * Set the TPG mode based on @tpg_on.
1297 */
1298static void zynqmp_disp_av_buf_set_tpg(struct zynqmp_disp_av_buf *av_buf,
1299                                       bool tpg_on)
1300{
1301        u32 reg;
1302
1303        reg = zynqmp_disp_read(av_buf->base, ZYNQMP_DISP_AV_BUF_OUTPUT);
1304        reg &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_MASK;
1305        if (tpg_on)
1306                reg |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_PATTERN;
1307        else
1308                reg &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_PATTERN;
1309        zynqmp_disp_write(av_buf->base, ZYNQMP_DISP_AV_BUF_OUTPUT, reg);
1310}
1311
1312/**
1313 * zynqmp_disp_av_buf_enable_vid - Enable the video layer buffer
1314 * @av_buf: av buffer manager
1315 * @layer: layer to enable
1316 * @mode: operation mode of layer
1317 *
1318 * Enable the video/graphics buffer for @layer.
1319 */
1320static void zynqmp_disp_av_buf_enable_vid(struct zynqmp_disp_av_buf *av_buf,
1321                                          struct zynqmp_disp_layer *layer,
1322                                          enum zynqmp_disp_layer_mode mode)
1323{
1324        u32 reg;
1325
1326        reg = zynqmp_disp_read(av_buf->base, ZYNQMP_DISP_AV_BUF_OUTPUT);
1327        if (layer->id == ZYNQMP_DISP_LAYER_VID) {
1328                reg &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_MASK;
1329                if (mode == ZYNQMP_DISP_LAYER_NONLIVE)
1330                        reg |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_MEM;
1331                else
1332                        reg |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_LIVE;
1333        } else {
1334                reg &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_MASK;
1335                reg |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_MEM;
1336                if (mode == ZYNQMP_DISP_LAYER_NONLIVE)
1337                        reg |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_MEM;
1338                else
1339                        reg |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_LIVE;
1340        }
1341        zynqmp_disp_write(av_buf->base, ZYNQMP_DISP_AV_BUF_OUTPUT, reg);
1342}
1343
1344/**
1345 * zynqmp_disp_av_buf_disable_vid - Disable the video layer buffer
1346 * @av_buf: av buffer manager
1347 * @layer: layer to disable
1348 *
1349 * Disable the video/graphics buffer for @layer.
1350 */
1351static void
1352zynqmp_disp_av_buf_disable_vid(struct zynqmp_disp_av_buf *av_buf,
1353                               struct zynqmp_disp_layer *layer)
1354{
1355        u32 reg;
1356
1357        reg = zynqmp_disp_read(av_buf->base, ZYNQMP_DISP_AV_BUF_OUTPUT);
1358        if (layer->id == ZYNQMP_DISP_LAYER_VID) {
1359                reg &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_MASK;
1360                reg |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_NONE;
1361        } else {
1362                reg &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_MASK;
1363                reg |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_DISABLE;
1364        }
1365        zynqmp_disp_write(av_buf->base, ZYNQMP_DISP_AV_BUF_OUTPUT, reg);
1366}
1367
1368/**
1369 * zynqmp_disp_av_buf_init_sf - Initialize scaling factors
1370 * @av_buf: av buffer manager
1371 * @vid_fmt: video format descriptor
1372 * @gfx_fmt: graphics format descriptor
1373 *
1374 * Initialize scaling factors for both video and graphics layers.
1375 * If the format descriptor is NULL, the function skips the programming.
1376 */
1377static void zynqmp_disp_av_buf_init_sf(struct zynqmp_disp_av_buf *av_buf,
1378                                       const struct zynqmp_disp_fmt *vid_fmt,
1379                                       const struct zynqmp_disp_fmt *gfx_fmt)
1380{
1381        unsigned int i;
1382        u32 offset;
1383
1384        if (gfx_fmt) {
1385                offset = ZYNQMP_DISP_AV_BUF_GFX_COMP0_SF;
1386                for (i = 0; i < ZYNQMP_DISP_AV_BUF_NUM_SF; i++)
1387                        zynqmp_disp_write(av_buf->base, offset + i * 4,
1388                                          gfx_fmt->sf[i]);
1389        }
1390
1391        if (vid_fmt) {
1392                offset = ZYNQMP_DISP_AV_BUF_VID_COMP0_SF;
1393                for (i = 0; i < ZYNQMP_DISP_AV_BUF_NUM_SF; i++)
1394                        zynqmp_disp_write(av_buf->base, offset + i * 4,
1395                                          vid_fmt->sf[i]);
1396        }
1397}
1398
1399/**
1400 * zynqmp_disp_av_buf_init_live_sf - Initialize scaling factors for live source
1401 * @av_buf: av buffer manager
1402 * @fmt: format descriptor
1403 * @is_vid: flag if this is for video layer
1404 *
1405 * Initialize scaling factors for live source.
1406 */
1407static void zynqmp_disp_av_buf_init_live_sf(struct zynqmp_disp_av_buf *av_buf,
1408                                            const struct zynqmp_disp_fmt *fmt,
1409                                            bool is_vid)
1410{
1411        unsigned int i;
1412        u32 offset;
1413
1414        if (is_vid)
1415                offset = ZYNQMP_DISP_AV_BUF_LIVE_VID_COMP0_SF;
1416        else
1417                offset = ZYNQMP_DISP_AV_BUF_LIVE_GFX_COMP0_SF;
1418
1419        for (i = 0; i < ZYNQMP_DISP_AV_BUF_NUM_SF; i++)
1420                zynqmp_disp_write(av_buf->base, offset + i * 4,
1421                                  fmt->sf[i]);
1422}
1423
1424/*
1425 * Audio functions
1426 */
1427
1428/**
1429 * zynqmp_disp_aud_init - Initialize the audio
1430 * @aud: audio
1431 *
1432 * Initialize the audio with default mixer volume. The de-assertion will
1433 * initialize the audio states.
1434 */
1435static void zynqmp_disp_aud_init(struct zynqmp_disp_aud *aud)
1436{
1437        /* Clear the audio soft reset register as it's an non-reset flop */
1438        regmap_write(aud->base, ZYNQMP_DISP_AUD_SOFT_RESET, 0);
1439        regmap_write(aud->base, ZYNQMP_DISP_AUD_MIXER_VOLUME,
1440                     ZYNQMP_DISP_AUD_MIXER_VOLUME_NO_SCALE);
1441}
1442
1443/**
1444 * zynqmp_disp_aud_deinit - De-initialize the audio
1445 * @aud: audio
1446 *
1447 * Put the audio in reset.
1448 */
1449static void zynqmp_disp_aud_deinit(struct zynqmp_disp_aud *aud)
1450{
1451        regmap_write_bits(aud->base, ZYNQMP_DISP_AUD_SOFT_RESET,
1452                          ZYNQMP_DISP_AUD_SOFT_RESET_AUD_SRST,
1453                          ZYNQMP_DISP_AUD_SOFT_RESET_AUD_SRST);
1454}
1455
1456/*
1457 * ZynqMP Display layer functions
1458 */
1459
1460/**
1461 * zynqmp_disp_layer_check_size - Verify width and height for the layer
1462 * @disp: Display subsystem
1463 * @layer: layer
1464 * @width: width
1465 * @height: height
1466 *
1467 * The Display subsystem has the limitation that both layers should have
1468 * identical size. This function stores width and height of @layer, and verifies
1469 * if the size (width and height) is valid.
1470 *
1471 * Return: 0 on success, or -EINVAL if width or/and height is invalid.
1472 */
1473static int zynqmp_disp_layer_check_size(struct zynqmp_disp *disp,
1474                                        struct zynqmp_disp_layer *layer,
1475                                        u32 width, u32 height)
1476{
1477        struct zynqmp_disp_layer *other = layer->other;
1478
1479        if (other->enabled && (other->w != width || other->h != height)) {
1480                dev_err(disp->dev, "Layer width:height must be %d:%d\n",
1481                        other->w, other->h);
1482                return -EINVAL;
1483        }
1484
1485        layer->w = width;
1486        layer->h = height;
1487
1488        return 0;
1489}
1490
1491/**
1492 * zynqmp_disp_map_fmt - Find the Display subsystem format for given drm format
1493 * @fmts: format table to look up
1494 * @size: size of the table @fmts
1495 * @drm_fmt: DRM format to search
1496 *
1497 * Search a Display subsystem format corresponding to the given DRM format
1498 * @drm_fmt, and return the format descriptor which contains the Display
1499 * subsystem format value.
1500 *
1501 * Return: a Display subsystem format descriptor on success, or NULL.
1502 */
1503static const struct zynqmp_disp_fmt *
1504zynqmp_disp_map_fmt(const struct zynqmp_disp_fmt fmts[],
1505                    unsigned int size, uint32_t drm_fmt)
1506{
1507        unsigned int i;
1508
1509        for (i = 0; i < size; i++)
1510                if (fmts[i].drm_fmt == drm_fmt)
1511                        return &fmts[i];
1512
1513        return NULL;
1514}
1515
1516/**
1517 * zynqmp_disp_layer_set_fmt - Set the format of the layer
1518 * @disp: Display subsystem
1519 * @layer: layer to set the format
1520 * @drm_fmt: DRM format to set
1521 *
1522 * Set the format of the given layer to @drm_fmt.
1523 *
1524 * Return: 0 on success. -EINVAL if @drm_fmt is not supported by the layer.
1525 */
1526static int zynqmp_disp_layer_set_fmt(struct zynqmp_disp *disp,
1527                                     struct zynqmp_disp_layer *layer,
1528                                     uint32_t drm_fmt)
1529{
1530        const struct zynqmp_disp_fmt *fmt;
1531        const struct zynqmp_disp_fmt *vid_fmt = NULL, *gfx_fmt = NULL;
1532        u32 size, fmts, mask;
1533
1534        if (layer->id == ZYNQMP_DISP_LAYER_VID) {
1535                size = ARRAY_SIZE(av_buf_vid_fmts);
1536                mask = ~ZYNQMP_DISP_AV_BUF_FMT_NL_VID_MASK;
1537                fmt = zynqmp_disp_map_fmt(av_buf_vid_fmts, size, drm_fmt);
1538                vid_fmt = fmt;
1539        } else {
1540                size = ARRAY_SIZE(av_buf_gfx_fmts);
1541                mask = ~ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_MASK;
1542                fmt = zynqmp_disp_map_fmt(av_buf_gfx_fmts, size, drm_fmt);
1543                gfx_fmt = fmt;
1544        }
1545
1546        if (!fmt)
1547                return -EINVAL;
1548
1549        fmts = zynqmp_disp_av_buf_get_fmt(&disp->av_buf);
1550        fmts &= mask;
1551        fmts |= fmt->disp_fmt;
1552        zynqmp_disp_av_buf_set_fmt(&disp->av_buf, fmts);
1553        zynqmp_disp_av_buf_init_sf(&disp->av_buf, vid_fmt, gfx_fmt);
1554        layer->fmt = fmt;
1555
1556        return 0;
1557}
1558
1559/**
1560 * zynqmp_disp_map_live_fmt - Find the hardware format for given bus format
1561 * @fmts: format table to look up
1562 * @size: size of the table @fmts
1563 * @bus_fmt: bus format to search
1564 *
1565 * Search a Display subsystem format corresponding to the given bus format
1566 * @bus_fmt, and return the format descriptor which contains the Display
1567 * subsystem format value.
1568 *
1569 * Return: a Display subsystem format descriptor on success, or NULL.
1570 */
1571static const struct zynqmp_disp_fmt *
1572zynqmp_disp_map_live_fmt(const struct zynqmp_disp_fmt fmts[],
1573                         unsigned int size, uint32_t bus_fmt)
1574{
1575        unsigned int i;
1576
1577        for (i = 0; i < size; i++)
1578                if (fmts[i].bus_fmt == bus_fmt)
1579                        return &fmts[i];
1580
1581        return NULL;
1582}
1583
1584/**
1585 * zynqmp_disp_layer_set_live_fmt - Set the live format of the layer
1586 * @disp: Display subsystem
1587 * @layer: layer to set the format
1588 * @bus_fmt: bus format to set
1589 *
1590 * Set the live format of the given layer to @live_fmt.
1591 *
1592 * Return: 0 on success. -EINVAL if @bus_fmt is not supported by the layer.
1593 */
1594static int zynqmp_disp_layer_set_live_fmt(struct zynqmp_disp *disp,
1595                                          struct zynqmp_disp_layer *layer,
1596                                          uint32_t bus_fmt)
1597{
1598        const struct zynqmp_disp_fmt *fmt;
1599        u32 size;
1600        bool is_vid = layer->id == ZYNQMP_DISP_LAYER_VID;
1601
1602        size = ARRAY_SIZE(av_buf_live_fmts);
1603        fmt = zynqmp_disp_map_live_fmt(av_buf_live_fmts, size, bus_fmt);
1604        if (!fmt)
1605                return -EINVAL;
1606
1607        zynqmp_disp_av_buf_set_live_fmt(&disp->av_buf, fmt->disp_fmt, is_vid);
1608        zynqmp_disp_av_buf_init_live_sf(&disp->av_buf, fmt, is_vid);
1609        layer->fmt = fmt;
1610
1611        return 0;
1612}
1613
1614/**
1615 * zynqmp_disp_layer_set_tpg - Enable or disable TPG
1616 * @disp: Display subsystem
1617 * @layer: Video layer
1618 * @tpg_on: flag if TPG needs to be enabled or disabled
1619 *
1620 * Enable / disable the TPG mode on the video layer @layer depending on
1621 * @tpg_on. The video layer should be disabled prior to enable request.
1622 *
1623 * Return: 0 on success. -ENODEV if it's not video layer. -EIO if
1624 * the video layer is enabled.
1625 */
1626static int zynqmp_disp_layer_set_tpg(struct zynqmp_disp *disp,
1627                                     struct zynqmp_disp_layer *layer,
1628                                     bool tpg_on)
1629{
1630        if (layer->id != ZYNQMP_DISP_LAYER_VID) {
1631                dev_err(disp->dev,
1632                        "only the video layer has the tpg mode\n");
1633                return -ENODEV;
1634        }
1635
1636        if (layer->enabled) {
1637                dev_err(disp->dev,
1638                        "the video layer should be disabled for tpg mode\n");
1639                return -EIO;
1640        }
1641
1642        disp->tpg_on = tpg_on;
1643        zynqmp_disp_av_buf_set_tpg(&disp->av_buf, tpg_on);
1644
1645        return 0;
1646}
1647
1648/**
1649 * zynqmp_disp_layer_get_tpg - Get the TPG mode status
1650 * @disp: Display subsystem
1651 * @layer: Video layer
1652 *
1653 * Return if the TPG is enabled or not.
1654 *
1655 * Return: true if TPG is on, otherwise false
1656 */
1657static bool zynqmp_disp_layer_get_tpg(struct zynqmp_disp *disp,
1658                                      struct zynqmp_disp_layer *layer)
1659{
1660        return disp->tpg_on;
1661}
1662
1663/**
1664 * zynqmp_disp_layer_get_fmts - Get the supported DRM formats of the layer
1665 * @disp: Display subsystem
1666 * @layer: layer to get the formats
1667 * @drm_fmts: pointer to array of DRM format strings
1668 * @num_fmts: pointer to number of returned DRM formats
1669 *
1670 * Get the supported DRM formats of the given layer.
1671 */
1672static void zynqmp_disp_layer_get_fmts(struct zynqmp_disp *disp,
1673                                       struct zynqmp_disp_layer *layer,
1674                                       u32 **drm_fmts, unsigned int *num_fmts)
1675{
1676        *drm_fmts = layer->drm_fmts;
1677        *num_fmts = layer->num_fmts;
1678}
1679
1680/**
1681 * zynqmp_disp_layer_enable - Enable the layer
1682 * @disp: Display subsystem
1683 * @layer: layer to esable
1684 * @mode: operation mode
1685 *
1686 * Enable the layer @layer.
1687 *
1688 * Return: 0 on success, otherwise error code.
1689 */
1690static int zynqmp_disp_layer_enable(struct zynqmp_disp *disp,
1691                                    struct zynqmp_disp_layer *layer,
1692                                    enum zynqmp_disp_layer_mode mode)
1693{
1694        struct device *dev = disp->dev;
1695        struct dma_async_tx_descriptor *desc;
1696        unsigned long flags;
1697        unsigned int i;
1698
1699        if (layer->enabled && layer->mode != mode) {
1700                dev_err(dev, "layer is already enabled in different mode\n");
1701                return -EBUSY;
1702        }
1703
1704        zynqmp_disp_av_buf_enable_vid(&disp->av_buf, layer, mode);
1705        zynqmp_disp_blend_layer_enable(&disp->blend, layer);
1706
1707        layer->enabled = true;
1708        layer->mode = mode;
1709
1710        if (mode == ZYNQMP_DISP_LAYER_LIVE)
1711                return 0;
1712
1713        for (i = 0; i < ZYNQMP_DISP_MAX_NUM_SUB_PLANES; i++) {
1714                struct zynqmp_disp_layer_dma *dma = &layer->dma[i];
1715
1716                if (dma->chan && dma->is_active) {
1717                        flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT | DMA_PREP_REPEAT |
1718                                DMA_PREP_LOAD_EOT;
1719                        desc = dmaengine_prep_interleaved_dma(dma->chan,
1720                                                              &dma->xt, flags);
1721                        if (!desc) {
1722                                dev_err(dev, "failed to prep DMA descriptor\n");
1723                                return -ENOMEM;
1724                        }
1725
1726                        dmaengine_submit(desc);
1727                        dma_async_issue_pending(dma->chan);
1728                }
1729        }
1730
1731        return 0;
1732}
1733
1734/**
1735 * zynqmp_disp_layer_disable - Disable the layer
1736 * @disp: Display subsystem
1737 * @layer: layer to disable
1738 * @mode: operation mode
1739 *
1740 * Disable the layer @layer.
1741 *
1742 * Return: 0 on success, or -EBUSY if the layer is in different mode.
1743 */
1744static int zynqmp_disp_layer_disable(struct zynqmp_disp *disp,
1745                                     struct zynqmp_disp_layer *layer,
1746                                     enum zynqmp_disp_layer_mode mode)
1747{
1748        struct device *dev = disp->dev;
1749        unsigned int i;
1750
1751        if (layer->mode != mode) {
1752                dev_err(dev, "the layer is operating in different mode\n");
1753                return -EBUSY;
1754        }
1755
1756        for (i = 0; i < ZYNQMP_DISP_MAX_NUM_SUB_PLANES; i++)
1757                if (layer->dma[i].chan && layer->dma[i].is_active)
1758                        dmaengine_terminate_sync(layer->dma[i].chan);
1759
1760        zynqmp_disp_av_buf_disable_vid(&disp->av_buf, layer);
1761        zynqmp_disp_blend_layer_disable(&disp->blend, layer);
1762        layer->enabled = false;
1763
1764        return 0;
1765}
1766
1767/**
1768 * zynqmp_disp_layer_request_dma - Request DMA channels for a layer
1769 * @disp: Display subsystem
1770 * @layer: layer to request DMA channels
1771 * @name: identifier string for layer type
1772 *
1773 * Request DMA engine channels for corresponding layer.
1774 *
1775 * Return: 0 on success, or err value from of_dma_request_slave_channel().
1776 */
1777static int
1778zynqmp_disp_layer_request_dma(struct zynqmp_disp *disp,
1779                              struct zynqmp_disp_layer *layer, const char *name)
1780{
1781        struct zynqmp_disp_layer_dma *dma;
1782        unsigned int i;
1783        int ret;
1784
1785        for (i = 0; i < layer->num_chan; i++) {
1786                char temp[16];
1787
1788                dma = &layer->dma[i];
1789                snprintf(temp, sizeof(temp), "%s%d", name, i);
1790                dma->chan = of_dma_request_slave_channel(disp->dev->of_node,
1791                                                         temp);
1792                if (IS_ERR(dma->chan)) {
1793                        dev_err(disp->dev, "failed to request dma channel\n");
1794                        ret = PTR_ERR(dma->chan);
1795                        dma->chan = NULL;
1796                        return ret;
1797                }
1798        }
1799
1800        return 0;
1801}
1802
1803/**
1804 * zynqmp_disp_layer_release_dma - Release DMA channels for a layer
1805 * @disp: Display subsystem
1806 * @layer: layer to release DMA channels
1807 *
1808 * Release the dma channels associated with @layer.
1809 */
1810static void zynqmp_disp_layer_release_dma(struct zynqmp_disp *disp,
1811                                          struct zynqmp_disp_layer *layer)
1812{
1813        unsigned int i;
1814
1815        for (i = 0; i < layer->num_chan; i++) {
1816                if (layer->dma[i].chan) {
1817                        /* Make sure the channel is terminated before release */
1818                        dmaengine_terminate_all(layer->dma[i].chan);
1819                        dma_release_channel(layer->dma[i].chan);
1820                }
1821        }
1822}
1823
1824/**
1825 * zynqmp_disp_layer_is_live - if any layer is live
1826 * @disp: Display subsystem
1827 *
1828 * Return: true if any layer is live
1829 */
1830static bool zynqmp_disp_layer_is_live(struct zynqmp_disp *disp)
1831{
1832        unsigned int i;
1833
1834        for (i = 0; i < ZYNQMP_DISP_NUM_LAYERS; i++) {
1835                if (disp->layers[i].enabled &&
1836                    disp->layers[i].mode == ZYNQMP_DISP_LAYER_LIVE)
1837                        return true;
1838        }
1839
1840        return false;
1841}
1842
1843/**
1844 * zynqmp_disp_layer_is_enabled - if any layer is enabled
1845 * @disp: Display subsystem
1846 *
1847 * Return: true if any layer is enabled
1848 */
1849static bool zynqmp_disp_layer_is_enabled(struct zynqmp_disp *disp)
1850{
1851        unsigned int i;
1852
1853        for (i = 0; i < ZYNQMP_DISP_NUM_LAYERS; i++)
1854                if (disp->layers[i].enabled)
1855                        return true;
1856
1857        return false;
1858}
1859
1860/**
1861 * zynqmp_disp_layer_destroy - Destroy all layers
1862 * @disp: Display subsystem
1863 *
1864 * Destroy all layers.
1865 */
1866static void zynqmp_disp_layer_destroy(struct zynqmp_disp *disp)
1867{
1868        unsigned int i;
1869
1870        for (i = 0; i < ZYNQMP_DISP_NUM_LAYERS; i++)
1871                zynqmp_disp_layer_release_dma(disp, &disp->layers[i]);
1872}
1873
1874/**
1875 * zynqmp_disp_layer_create - Create all layers
1876 * @disp: Display subsystem
1877 *
1878 * Create all layers.
1879 *
1880 * Return: 0 on success, otherwise error code from failed function
1881 */
1882static int zynqmp_disp_layer_create(struct zynqmp_disp *disp)
1883{
1884        struct zynqmp_disp_layer *layer;
1885        unsigned int i;
1886        int num_chans[ZYNQMP_DISP_NUM_LAYERS] = { 3, 1 };
1887        const char * const dma_name[] = { "vid", "gfx" };
1888        int ret = -EINVAL;
1889
1890        for (i = 0; i < ZYNQMP_DISP_NUM_LAYERS; i++) {
1891                layer = &disp->layers[i];
1892                layer->id = (enum zynqmp_disp_layer_type)i;
1893                layer->offset = i * 4;
1894                layer->other = &disp->layers[!i];
1895                layer->num_chan = num_chans[i];
1896                ret = zynqmp_disp_layer_request_dma(disp, layer, dma_name[i]);
1897                if (ret)
1898                        goto err;
1899                layer->disp = disp;
1900        }
1901
1902        return 0;
1903
1904err:
1905        zynqmp_disp_layer_destroy(disp);
1906        return ret;
1907}
1908
1909/*
1910 * ZynqMP Display internal functions
1911 */
1912
1913/*
1914 * Output format enumeration.
1915 * The ID should be aligned with blend_output_fmts.
1916 * The string should be aligned with how zynqmp_dp_set_color() decodes.
1917 */
1918static struct drm_prop_enum_list zynqmp_disp_color_enum[] = {
1919        { 0, "rgb" },
1920        { 1, "ycrcb444" },
1921        { 2, "ycrcb422" },
1922        { 3, "yonly" },
1923};
1924
1925/**
1926 * zynqmp_disp_set_output_fmt - Set the output format
1927 * @disp: Display subsystem
1928 * @id: the format ID. Refer to zynqmp_disp_color_enum[].
1929 *
1930 * This function sets the output format of the display / blender as well as
1931 * the format of DP controller. The @id should be aligned with
1932 * zynqmp_disp_color_enum.
1933 */
1934static void
1935zynqmp_disp_set_output_fmt(struct zynqmp_disp *disp, unsigned int id)
1936{
1937        const struct zynqmp_disp_fmt *fmt = &blend_output_fmts[id];
1938
1939        zynqmp_dp_set_color(disp->dpsub->dp, zynqmp_disp_color_enum[id].name);
1940        zynqmp_disp_blend_set_output_fmt(&disp->blend, fmt->disp_fmt);
1941}
1942
1943/**
1944 * zynqmp_disp_set_bg_color - Set the background color
1945 * @disp: Display subsystem
1946 * @c0: color component 0
1947 * @c1: color component 1
1948 * @c2: color component 2
1949 *
1950 * Set the background color with given color components (@c0, @c1, @c2).
1951 */
1952static void zynqmp_disp_set_bg_color(struct zynqmp_disp *disp,
1953                                     u32 c0, u32 c1, u32 c2)
1954{
1955        zynqmp_disp_blend_set_bg_color(&disp->blend, c0, c1, c2);
1956}
1957
1958/**
1959 * zynqmp_disp_set_alpha - Set the alpha value
1960 * @disp: Display subsystem
1961 * @alpha: alpha value to set
1962 *
1963 * Set the alpha value for blending.
1964 */
1965static void zynqmp_disp_set_alpha(struct zynqmp_disp *disp, u32 alpha)
1966{
1967        disp->alpha = alpha;
1968        zynqmp_disp_blend_set_alpha(&disp->blend, alpha);
1969}
1970
1971/**
1972 * zynqmp_disp_get_alpha - Get the alpha value
1973 * @disp: Display subsystem
1974 *
1975 * Get the alpha value for blending.
1976 *
1977 * Return: current alpha value.
1978 */
1979static u32 zynqmp_disp_get_alpha(struct zynqmp_disp *disp)
1980{
1981        return disp->alpha;
1982}
1983
1984/**
1985 * zynqmp_disp_set_g_alpha - Enable/disable the global alpha blending
1986 * @disp: Display subsystem
1987 * @enable: flag to enable or disable alpha blending
1988 *
1989 * Set the alpha value for blending.
1990 */
1991static void zynqmp_disp_set_g_alpha(struct zynqmp_disp *disp, bool enable)
1992{
1993        disp->alpha_en = enable;
1994        zynqmp_disp_blend_enable_alpha(&disp->blend, enable);
1995}
1996
1997/**
1998 * zynqmp_disp_get_g_alpha - Get the global alpha status
1999 * @disp: Display subsystem
2000 *
2001 * Get the global alpha statue.
2002 *
2003 * Return: true if global alpha is enabled, or false.
2004 */
2005static bool zynqmp_disp_get_g_alpha(struct zynqmp_disp *disp)
2006{
2007        return disp->alpha_en;
2008}
2009
2010/**
2011 * zynqmp_disp_enable - Enable the Display subsystem
2012 * @disp: Display subsystem
2013 *
2014 * Enable the Display subsystem.
2015 */
2016static void zynqmp_disp_enable(struct zynqmp_disp *disp)
2017{
2018        bool live;
2019
2020        if (disp->enabled)
2021                return;
2022
2023        zynqmp_disp_av_buf_enable(&disp->av_buf);
2024        /* Choose clock source based on the DT clock handle */
2025        zynqmp_disp_av_buf_set_vid_clock_src(&disp->av_buf, !!disp->_ps_pclk);
2026        zynqmp_disp_av_buf_set_aud_clock_src(&disp->av_buf, !!disp->_ps_audclk);
2027        live = zynqmp_disp_layer_is_live(disp);
2028        zynqmp_disp_av_buf_set_vid_timing_src(&disp->av_buf, !live);
2029        zynqmp_disp_av_buf_enable_buf(&disp->av_buf);
2030        zynqmp_disp_av_buf_enable_aud(&disp->av_buf);
2031        zynqmp_disp_aud_init(&disp->aud);
2032        disp->enabled = true;
2033}
2034
2035/**
2036 * zynqmp_disp_disable - Disable the Display subsystem
2037 * @disp: Display subsystem
2038 * @force: flag to disable forcefully
2039 *
2040 * Disable the Display subsystem.
2041 */
2042static void zynqmp_disp_disable(struct zynqmp_disp *disp, bool force)
2043{
2044        struct drm_crtc *crtc = &disp->xlnx_crtc.crtc;
2045
2046        if (!force && (!disp->enabled || zynqmp_disp_layer_is_enabled(disp)))
2047                return;
2048
2049        zynqmp_disp_aud_deinit(&disp->aud);
2050        zynqmp_disp_av_buf_disable_aud(&disp->av_buf);
2051        zynqmp_disp_av_buf_disable_buf(&disp->av_buf);
2052        zynqmp_disp_av_buf_disable(&disp->av_buf);
2053
2054        /* Mark the flip is done as crtc is disabled anyway */
2055        if (crtc->state->event) {
2056                complete_all(crtc->state->event->base.completion);
2057                crtc->state->event = NULL;
2058        }
2059
2060        disp->enabled = false;
2061}
2062
2063/**
2064 * zynqmp_disp_init - Initialize the Display subsystem states
2065 * @disp: Display subsystem
2066 *
2067 * Some states are not initialized as desired. For example, the output select
2068 * register resets to the live source. This function is to initialize
2069 * some register states as desired.
2070 */
2071static void zynqmp_disp_init(struct zynqmp_disp *disp)
2072{
2073        struct zynqmp_disp_layer *layer;
2074        unsigned int i;
2075
2076        for (i = 0; i < ZYNQMP_DISP_NUM_LAYERS; i++) {
2077                layer = &disp->layers[i];
2078                zynqmp_disp_av_buf_disable_vid(&disp->av_buf, layer);
2079        }
2080}
2081
2082/*
2083 * ZynqMP Display external functions for zynqmp_dp
2084 */
2085
2086/**
2087 * zynqmp_disp_handle_vblank - Handle the vblank event
2088 * @disp: Display subsystem
2089 *
2090 * This function handles the vblank interrupt, and sends an event to
2091 * CRTC object. This will be called by the DP vblank interrupt handler.
2092 */
2093void zynqmp_disp_handle_vblank(struct zynqmp_disp *disp)
2094{
2095        struct drm_crtc *crtc = &disp->xlnx_crtc.crtc;
2096
2097        drm_crtc_handle_vblank(crtc);
2098}
2099
2100/**
2101 * zynqmp_disp_get_apb_clk_rate - Get the current APB clock rate
2102 * @disp: Display subsystem
2103 *
2104 * Return: the current APB clock rate.
2105 */
2106unsigned int zynqmp_disp_get_apb_clk_rate(struct zynqmp_disp *disp)
2107{
2108        return clk_get_rate(disp->aclk);
2109}
2110
2111/**
2112 * zynqmp_disp_aud_enabled - If the audio is enabled
2113 * @disp: Display subsystem
2114 *
2115 * Return if the audio is enabled depending on the audio clock.
2116 *
2117 * Return: true if audio is enabled, or false.
2118 */
2119bool zynqmp_disp_aud_enabled(struct zynqmp_disp *disp)
2120{
2121        return !!disp->audclk;
2122}
2123
2124/**
2125 * zynqmp_disp_get_aud_clk_rate - Get the current audio clock rate
2126 * @disp: Display subsystem
2127 *
2128 * Return: the current audio clock rate.
2129 */
2130unsigned int zynqmp_disp_get_aud_clk_rate(struct zynqmp_disp *disp)
2131{
2132        if (zynqmp_disp_aud_enabled(disp))
2133                return 0;
2134        return clk_get_rate(disp->aclk);
2135}
2136
2137/**
2138 * zynqmp_disp_get_crtc_mask - Return the CRTC bit mask
2139 * @disp: Display subsystem
2140 *
2141 * Return: the crtc mask of the zyqnmp_disp CRTC.
2142 */
2143uint32_t zynqmp_disp_get_crtc_mask(struct zynqmp_disp *disp)
2144{
2145        return drm_crtc_mask(&disp->xlnx_crtc.crtc);
2146}
2147
2148/*
2149 * DRM plane functions
2150 */
2151
2152static inline struct zynqmp_disp_layer *plane_to_layer(struct drm_plane *plane)
2153{
2154        return container_of(plane, struct zynqmp_disp_layer, plane);
2155}
2156
2157static int zynqmp_disp_plane_enable(struct drm_plane *plane)
2158{
2159        struct zynqmp_disp_layer *layer = plane_to_layer(plane);
2160        struct zynqmp_disp *disp = layer->disp;
2161        int ret;
2162
2163        zynqmp_disp_set_g_alpha(disp, disp->alpha_en);
2164        zynqmp_disp_set_alpha(disp, disp->alpha);
2165        ret = zynqmp_disp_layer_enable(layer->disp, layer,
2166                                       ZYNQMP_DISP_LAYER_NONLIVE);
2167        if (ret)
2168                return ret;
2169
2170        if (layer->id == ZYNQMP_DISP_LAYER_GFX && disp->tpg_on) {
2171                layer = &disp->layers[ZYNQMP_DISP_LAYER_VID];
2172                zynqmp_disp_layer_set_tpg(disp, layer, disp->tpg_on);
2173        }
2174
2175        return 0;
2176}
2177
2178static int zynqmp_disp_plane_disable(struct drm_plane *plane)
2179{
2180        struct zynqmp_disp_layer *layer = plane_to_layer(plane);
2181        struct zynqmp_disp *disp = layer->disp;
2182
2183        zynqmp_disp_layer_disable(disp, layer, ZYNQMP_DISP_LAYER_NONLIVE);
2184        if (layer->id == ZYNQMP_DISP_LAYER_VID && disp->tpg_on)
2185                zynqmp_disp_layer_set_tpg(disp, layer, disp->tpg_on);
2186
2187        return 0;
2188}
2189
2190static int zynqmp_disp_plane_mode_set(struct drm_plane *plane,
2191                                      struct drm_framebuffer *fb,
2192                                      int crtc_x, int crtc_y,
2193                                      unsigned int crtc_w, unsigned int crtc_h,
2194                                      u32 src_x, u32 src_y,
2195                                      u32 src_w, u32 src_h)
2196{
2197        struct zynqmp_disp_layer *layer = plane_to_layer(plane);
2198        const struct drm_format_info *info = fb->format;
2199        struct device *dev = layer->disp->dev;
2200        dma_addr_t paddr;
2201        unsigned int i;
2202        int ret;
2203
2204        if (!info) {
2205                dev_err(dev, "No format info found\n");
2206                return -EINVAL;
2207        }
2208
2209        ret = zynqmp_disp_layer_check_size(layer->disp, layer, src_w, src_h);
2210        if (ret)
2211                return ret;
2212
2213        for (i = 0; i < info->num_planes; i++) {
2214                unsigned int width = src_w / (i ? info->hsub : 1);
2215                unsigned int height = src_h / (i ? info->vsub : 1);
2216                int width_bytes;
2217
2218                paddr = drm_fb_cma_get_gem_addr(fb, plane->state, i);
2219                if (!paddr) {
2220                        dev_err(dev, "failed to get a paddr\n");
2221                        return -EINVAL;
2222                }
2223
2224                layer->dma[i].xt.numf = height;
2225                width_bytes = drm_format_plane_width_bytes(info, i, width);
2226                layer->dma[i].sgl[0].size = width_bytes;
2227                layer->dma[i].sgl[0].icg = fb->pitches[i] -
2228                                           layer->dma[i].sgl[0].size;
2229                layer->dma[i].xt.src_start = paddr;
2230                layer->dma[i].xt.frame_size = 1;
2231                layer->dma[i].xt.dir = DMA_MEM_TO_DEV;
2232                layer->dma[i].xt.src_sgl = true;
2233                layer->dma[i].xt.dst_sgl = false;
2234                layer->dma[i].is_active = true;
2235        }
2236
2237        for (; i < ZYNQMP_DISP_MAX_NUM_SUB_PLANES; i++)
2238                layer->dma[i].is_active = false;
2239
2240        ret = zynqmp_disp_layer_set_fmt(layer->disp,  layer, info->format);
2241        if (ret)
2242                dev_err(dev, "failed to set dp_sub layer fmt\n");
2243
2244        return ret;
2245}
2246
2247static void zynqmp_disp_plane_destroy(struct drm_plane *plane)
2248{
2249        struct zynqmp_disp_layer *layer = plane_to_layer(plane);
2250
2251        xlnx_bridge_unregister(&layer->bridge);
2252        drm_plane_cleanup(plane);
2253}
2254
2255static int
2256zynqmp_disp_plane_atomic_set_property(struct drm_plane *plane,
2257                                      struct drm_plane_state *state,
2258                                      struct drm_property *property, u64 val)
2259{
2260        struct zynqmp_disp_layer *layer = plane_to_layer(plane);
2261        struct zynqmp_disp *disp = layer->disp;
2262        int ret = 0;
2263
2264        if (property == disp->g_alpha_prop)
2265                zynqmp_disp_set_alpha(disp, val);
2266        else if (property == disp->g_alpha_en_prop)
2267                zynqmp_disp_set_g_alpha(disp, val);
2268        else if (property == disp->tpg_prop)
2269                ret = zynqmp_disp_layer_set_tpg(disp, layer, val);
2270        else
2271                return -EINVAL;
2272
2273        return ret;
2274}
2275
2276static int
2277zynqmp_disp_plane_atomic_get_property(struct drm_plane *plane,
2278                                      const struct drm_plane_state *state,
2279                                      struct drm_property *property,
2280                                      uint64_t *val)
2281{
2282        struct zynqmp_disp_layer *layer = plane_to_layer(plane);
2283        struct zynqmp_disp *disp = layer->disp;
2284        int ret = 0;
2285
2286        if (property == disp->g_alpha_prop)
2287                *val = zynqmp_disp_get_alpha(disp);
2288        else if (property == disp->g_alpha_en_prop)
2289                *val = zynqmp_disp_get_g_alpha(disp);
2290        else if (property == disp->tpg_prop)
2291                *val = zynqmp_disp_layer_get_tpg(disp, layer);
2292        else
2293                return -EINVAL;
2294
2295        return ret;
2296}
2297
2298static int
2299zynqmp_disp_plane_atomic_update_plane(struct drm_plane *plane,
2300                                      struct drm_crtc *crtc,
2301                                      struct drm_framebuffer *fb,
2302                                      int crtc_x, int crtc_y,
2303                                      unsigned int crtc_w, unsigned int crtc_h,
2304                                      u32 src_x, u32 src_y,
2305                                      u32 src_w, u32 src_h,
2306                                      struct drm_modeset_acquire_ctx *ctx)
2307{
2308        struct drm_atomic_state *state;
2309        struct drm_plane_state *plane_state;
2310        int ret;
2311
2312        state = drm_atomic_state_alloc(plane->dev);
2313        if (!state)
2314                return -ENOMEM;
2315
2316        state->acquire_ctx = ctx;
2317        plane_state = drm_atomic_get_plane_state(state, plane);
2318        if (IS_ERR(plane_state)) {
2319                ret = PTR_ERR(plane_state);
2320                goto fail;
2321        }
2322
2323        ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
2324        if (ret)
2325                goto fail;
2326        drm_atomic_set_fb_for_plane(plane_state, fb);
2327        plane_state->crtc_x = crtc_x;
2328        plane_state->crtc_y = crtc_y;
2329        plane_state->crtc_w = crtc_w;
2330        plane_state->crtc_h = crtc_h;
2331        plane_state->src_x = src_x;
2332        plane_state->src_y = src_y;
2333        plane_state->src_w = src_w;
2334        plane_state->src_h = src_h;
2335
2336        if (plane == crtc->cursor)
2337                state->legacy_cursor_update = true;
2338
2339        /* Do async-update if possible */
2340        state->async_update = !drm_atomic_helper_async_check(plane->dev, state);
2341        ret = drm_atomic_commit(state);
2342fail:
2343        drm_atomic_state_put(state);
2344        return ret;
2345}
2346
2347static struct drm_plane_funcs zynqmp_disp_plane_funcs = {
2348        .update_plane           = zynqmp_disp_plane_atomic_update_plane,
2349        .disable_plane          = drm_atomic_helper_disable_plane,
2350        .atomic_set_property    = zynqmp_disp_plane_atomic_set_property,
2351        .atomic_get_property    = zynqmp_disp_plane_atomic_get_property,
2352        .destroy                = zynqmp_disp_plane_destroy,
2353        .reset                  = drm_atomic_helper_plane_reset,
2354        .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
2355        .atomic_destroy_state   = drm_atomic_helper_plane_destroy_state,
2356};
2357
2358static void
2359zynqmp_disp_plane_atomic_update(struct drm_plane *plane,
2360                                struct drm_atomic_state *state)
2361{
2362        int ret;
2363        struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, plane);
2364
2365        if (!plane->state->crtc || !plane->state->fb)
2366                return;
2367
2368        if (plane->state->fb == old_state->fb &&
2369            plane->state->crtc_x == old_state->crtc_x &&
2370            plane->state->crtc_y == old_state->crtc_y &&
2371            plane->state->crtc_w == old_state->crtc_w &&
2372            plane->state->crtc_h == old_state->crtc_h &&
2373            plane->state->src_x == old_state->src_x &&
2374            plane->state->src_y == old_state->src_y &&
2375            plane->state->src_w == old_state->src_w &&
2376            plane->state->src_h == old_state->src_h)
2377                return;
2378
2379        if (old_state->fb &&
2380            old_state->fb->format->format != plane->state->fb->format->format)
2381                zynqmp_disp_plane_disable(plane);
2382
2383        ret = zynqmp_disp_plane_mode_set(plane, plane->state->fb,
2384                                         plane->state->crtc_x,
2385                                         plane->state->crtc_y,
2386                                         plane->state->crtc_w,
2387                                         plane->state->crtc_h,
2388                                         plane->state->src_x >> 16,
2389                                         plane->state->src_y >> 16,
2390                                         plane->state->src_w >> 16,
2391                                         plane->state->src_h >> 16);
2392        if (ret)
2393                return;
2394
2395        zynqmp_disp_plane_enable(plane);
2396}
2397
2398static void
2399zynqmp_disp_plane_atomic_disable(struct drm_plane *plane,
2400                                 struct drm_atomic_state *state)
2401{
2402        zynqmp_disp_plane_disable(plane);
2403}
2404
2405static int zynqmp_disp_plane_atomic_async_check(struct drm_plane *plane,
2406                                                struct drm_atomic_state *state)
2407{
2408        return 0;
2409}
2410
2411static void
2412zynqmp_disp_plane_atomic_async_update(struct drm_plane *plane,
2413                                      struct drm_atomic_state *state)
2414{
2415        int ret;
2416        struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane);
2417
2418        if (plane->state->fb == new_state->fb)
2419                return;
2420
2421        if (plane->state->fb &&
2422            plane->state->fb->format->format != new_state->fb->format->format)
2423                zynqmp_disp_plane_disable(plane);
2424
2425         /* Update the current state with new configurations */
2426        swap(plane->state->fb, new_state->fb);
2427        plane->state->crtc = new_state->crtc;
2428        plane->state->crtc_x = new_state->crtc_x;
2429        plane->state->crtc_y = new_state->crtc_y;
2430        plane->state->crtc_w = new_state->crtc_w;
2431        plane->state->crtc_h = new_state->crtc_h;
2432        plane->state->src_x = new_state->src_x;
2433        plane->state->src_y = new_state->src_y;
2434        plane->state->src_w = new_state->src_w;
2435        plane->state->src_h = new_state->src_h;
2436        plane->state->state = new_state->state;
2437
2438        ret = zynqmp_disp_plane_mode_set(plane, plane->state->fb,
2439                                         plane->state->crtc_x,
2440                                         plane->state->crtc_y,
2441                                         plane->state->crtc_w,
2442                                         plane->state->crtc_h,
2443                                         plane->state->src_x >> 16,
2444                                         plane->state->src_y >> 16,
2445                                         plane->state->src_w >> 16,
2446                                         plane->state->src_h >> 16);
2447        if (ret)
2448                return;
2449
2450        zynqmp_disp_plane_enable(plane);
2451}
2452
2453static const struct drm_plane_helper_funcs zynqmp_disp_plane_helper_funcs = {
2454        .atomic_update          = zynqmp_disp_plane_atomic_update,
2455        .atomic_disable         = zynqmp_disp_plane_atomic_disable,
2456        .atomic_async_check     = zynqmp_disp_plane_atomic_async_check,
2457        .atomic_async_update    = zynqmp_disp_plane_atomic_async_update,
2458};
2459
2460static int zynqmp_disp_create_plane(struct zynqmp_disp *disp)
2461{
2462        struct zynqmp_disp_layer *layer;
2463        unsigned int i;
2464        u32 *fmts = NULL;
2465        unsigned int num_fmts = 0;
2466        enum drm_plane_type type;
2467        int ret;
2468
2469        /* graphics layer is primary, and video layer is overaly */
2470        type = DRM_PLANE_TYPE_OVERLAY;
2471        for (i = 0; i < ZYNQMP_DISP_NUM_LAYERS; i++) {
2472                layer = &disp->layers[i];
2473                zynqmp_disp_layer_get_fmts(disp, layer, &fmts, &num_fmts);
2474                ret = drm_universal_plane_init(disp->drm, &layer->plane, 0,
2475                                               &zynqmp_disp_plane_funcs, fmts,
2476                                               num_fmts, NULL, type, NULL);
2477                if (ret)
2478                        goto err_plane;
2479                drm_plane_helper_add(&layer->plane,
2480                                     &zynqmp_disp_plane_helper_funcs);
2481                type = DRM_PLANE_TYPE_PRIMARY;
2482        }
2483
2484        /* Attach properties to each layers */
2485        drm_object_attach_property(&layer->plane.base, disp->g_alpha_prop,
2486                                   ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA_MAX);
2487        disp->alpha = ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA_MAX;
2488        /* Enable the global alpha as default */
2489        drm_object_attach_property(&layer->plane.base, disp->g_alpha_en_prop,
2490                                   true);
2491        disp->alpha_en = true;
2492
2493        layer = &disp->layers[ZYNQMP_DISP_LAYER_VID];
2494        drm_object_attach_property(&layer->plane.base, disp->tpg_prop, false);
2495
2496        return ret;
2497
2498err_plane:
2499        if (i)
2500                drm_plane_cleanup(&disp->layers[0].plane);
2501        return ret;
2502}
2503
2504static void zynqmp_disp_destroy_plane(struct zynqmp_disp *disp)
2505{
2506        unsigned int i;
2507
2508        for (i = 0; i < ZYNQMP_DISP_NUM_LAYERS; i++)
2509                zynqmp_disp_plane_destroy(&disp->layers[i].plane);
2510}
2511
2512/*
2513 * Xlnx crtc functions
2514 */
2515
2516static inline struct zynqmp_disp *xlnx_crtc_to_disp(struct xlnx_crtc *xlnx_crtc)
2517{
2518        return container_of(xlnx_crtc, struct zynqmp_disp, xlnx_crtc);
2519}
2520
2521static int zynqmp_disp_get_max_width(struct xlnx_crtc *xlnx_crtc)
2522{
2523        return ZYNQMP_DISP_MAX_WIDTH;
2524}
2525
2526static int zynqmp_disp_get_max_height(struct xlnx_crtc *xlnx_crtc)
2527{
2528        return ZYNQMP_DISP_MAX_HEIGHT;
2529}
2530
2531static uint32_t zynqmp_disp_get_format(struct xlnx_crtc *xlnx_crtc)
2532{
2533        struct zynqmp_disp *disp = xlnx_crtc_to_disp(xlnx_crtc);
2534
2535        return disp->layers[ZYNQMP_DISP_LAYER_GFX].fmt->drm_fmt;
2536}
2537
2538static unsigned int zynqmp_disp_get_align(struct xlnx_crtc *xlnx_crtc)
2539{
2540        struct zynqmp_disp *disp = xlnx_crtc_to_disp(xlnx_crtc);
2541        struct zynqmp_disp_layer *layer = &disp->layers[ZYNQMP_DISP_LAYER_VID];
2542
2543        return 1 << layer->dma->chan->device->copy_align;
2544}
2545
2546static u64 zynqmp_disp_get_dma_mask(struct xlnx_crtc *xlnx_crtc)
2547{
2548        return DMA_BIT_MASK(ZYNQMP_DISP_MAX_DMA_BIT);
2549}
2550
2551/*
2552 * DRM crtc functions
2553 */
2554
2555static inline struct zynqmp_disp *crtc_to_disp(struct drm_crtc *crtc)
2556{
2557        struct xlnx_crtc *xlnx_crtc = to_xlnx_crtc(crtc);
2558
2559        return xlnx_crtc_to_disp(xlnx_crtc);
2560}
2561
2562static int zynqmp_disp_crtc_mode_set(struct drm_crtc *crtc,
2563                                     struct drm_display_mode *mode,
2564                                     struct drm_display_mode *adjusted_mode,
2565                                     int x, int y,
2566                                     struct drm_framebuffer *old_fb)
2567{
2568        struct zynqmp_disp *disp = crtc_to_disp(crtc);
2569        unsigned long rate;
2570        long diff;
2571        int ret;
2572
2573        zynqmp_disp_clk_disable(disp->pclk, &disp->pclk_en);
2574        ret = clk_set_rate(disp->pclk,
2575                           (unsigned long)adjusted_mode->clock * 1000);
2576        if (ret) {
2577                dev_err(disp->dev, "failed to set a pixel clock\n");
2578                return ret;
2579        }
2580
2581        rate = clk_get_rate(disp->pclk);
2582        diff = rate - (unsigned long)adjusted_mode->clock * 1000;
2583        if (abs(diff) > ((long)adjusted_mode->clock * 1000) / 20) {
2584                dev_info(disp->dev, "request pixel rate: %d actual rate: %lu\n",
2585                         adjusted_mode->clock, rate);
2586        } else {
2587                dev_dbg(disp->dev, "request pixel rate: %d actual rate: %lu\n",
2588                        adjusted_mode->clock, rate);
2589        }
2590
2591        /* The timing register should be programmed always */
2592        zynqmp_dp_encoder_mode_set_stream(disp->dpsub->dp, adjusted_mode);
2593
2594        return 0;
2595}
2596
2597static void
2598zynqmp_disp_crtc_atomic_enable(struct drm_crtc *crtc,
2599                               struct drm_atomic_state *state)
2600{
2601        struct zynqmp_disp *disp = crtc_to_disp(crtc);
2602        struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
2603        int ret, vrefresh;
2604
2605        zynqmp_disp_crtc_mode_set(crtc, &crtc->state->mode,
2606                                  adjusted_mode, crtc->x, crtc->y, NULL);
2607
2608        ret = pm_runtime_get_sync(disp->dev);
2609        if (ret < 0) {
2610                dev_err(disp->dev, "IRQ sync failed to resume: %d\n", ret);
2611                return;
2612        }
2613
2614        ret = zynqmp_disp_clk_enable(disp->pclk, &disp->pclk_en);
2615        if (ret) {
2616                dev_err(disp->dev, "failed to enable a pixel clock\n");
2617                return;
2618        }
2619        zynqmp_disp_set_output_fmt(disp, disp->color);
2620        zynqmp_disp_set_bg_color(disp, disp->bg_c0, disp->bg_c1, disp->bg_c2);
2621        zynqmp_disp_enable(disp);
2622        /* Delay of 3 vblank intervals for timing gen to be stable */
2623        vrefresh = (adjusted_mode->clock * 1000) /
2624                   (adjusted_mode->vtotal * adjusted_mode->htotal);
2625        msleep(3 * 1000 / vrefresh);
2626}
2627
2628static void
2629zynqmp_disp_crtc_atomic_disable(struct drm_crtc *crtc,
2630                                struct drm_atomic_state *state)
2631{
2632        struct zynqmp_disp *disp = crtc_to_disp(crtc);
2633
2634        zynqmp_disp_clk_disable(disp->pclk, &disp->pclk_en);
2635        zynqmp_disp_plane_disable(crtc->primary);
2636        zynqmp_disp_disable(disp, true);
2637        if (!disp->dpsub->external_crtc_attached)
2638                drm_crtc_vblank_off(crtc);
2639        pm_runtime_put_sync(disp->dev);
2640}
2641
2642static int zynqmp_disp_crtc_atomic_check(struct drm_crtc *crtc,
2643                                         struct drm_atomic_state *state)
2644{
2645        return drm_atomic_add_affected_planes(state, crtc);
2646}
2647
2648static void
2649zynqmp_disp_crtc_atomic_begin(struct drm_crtc *crtc,
2650                              struct drm_atomic_state *state)
2651{
2652        drm_crtc_vblank_on(crtc);
2653        /* Don't rely on vblank when disabling crtc */
2654        spin_lock_irq(&crtc->dev->event_lock);
2655        if (crtc->state->event) {
2656                /* Consume the flip_done event from atomic helper */
2657                crtc->state->event->pipe = drm_crtc_index(crtc);
2658                WARN_ON(drm_crtc_vblank_get(crtc) != 0);
2659                drm_crtc_arm_vblank_event(crtc, crtc->state->event);
2660                crtc->state->event = NULL;
2661        }
2662        spin_unlock_irq(&crtc->dev->event_lock);
2663}
2664
2665static struct drm_crtc_helper_funcs zynqmp_disp_crtc_helper_funcs = {
2666        .atomic_enable  = zynqmp_disp_crtc_atomic_enable,
2667        .atomic_disable = zynqmp_disp_crtc_atomic_disable,
2668        .atomic_check   = zynqmp_disp_crtc_atomic_check,
2669        .atomic_begin   = zynqmp_disp_crtc_atomic_begin,
2670};
2671
2672static void zynqmp_disp_crtc_destroy(struct drm_crtc *crtc)
2673{
2674        zynqmp_disp_crtc_atomic_disable(crtc, NULL);
2675        drm_crtc_cleanup(crtc);
2676}
2677
2678static int zynqmp_disp_crtc_enable_vblank(struct drm_crtc *crtc)
2679{
2680        struct zynqmp_disp *disp = crtc_to_disp(crtc);
2681
2682        zynqmp_dp_enable_vblank(disp->dpsub->dp);
2683
2684        return 0;
2685}
2686
2687static void zynqmp_disp_crtc_disable_vblank(struct drm_crtc *crtc)
2688{
2689        struct zynqmp_disp *disp = crtc_to_disp(crtc);
2690
2691        zynqmp_dp_disable_vblank(disp->dpsub->dp);
2692}
2693
2694static int
2695zynqmp_disp_crtc_atomic_set_property(struct drm_crtc *crtc,
2696                                     struct drm_crtc_state *state,
2697                                     struct drm_property *property,
2698                                     uint64_t val)
2699{
2700        struct zynqmp_disp *disp = crtc_to_disp(crtc);
2701
2702        /*
2703         * CRTC prop values are just stored here and applied when CRTC gets
2704         * enabled
2705         */
2706        if (property == disp->color_prop)
2707                disp->color = val;
2708        else if (property == disp->bg_c0_prop)
2709                disp->bg_c0 = val;
2710        else if (property == disp->bg_c1_prop)
2711                disp->bg_c1 = val;
2712        else if (property == disp->bg_c2_prop)
2713                disp->bg_c2 = val;
2714        else
2715                return -EINVAL;
2716
2717        return 0;
2718}
2719
2720static int
2721zynqmp_disp_crtc_atomic_get_property(struct drm_crtc *crtc,
2722                                     const struct drm_crtc_state *state,
2723                                     struct drm_property *property,
2724                                     uint64_t *val)
2725{
2726        struct zynqmp_disp *disp = crtc_to_disp(crtc);
2727
2728        if (property == disp->color_prop)
2729                *val = disp->color;
2730        else if (property == disp->bg_c0_prop)
2731                *val = disp->bg_c0;
2732        else if (property == disp->bg_c1_prop)
2733                *val = disp->bg_c1;
2734        else if (property == disp->bg_c2_prop)
2735                *val = disp->bg_c2;
2736        else
2737                return -EINVAL;
2738
2739        return 0;
2740}
2741
2742static struct drm_crtc_funcs zynqmp_disp_crtc_funcs = {
2743        .destroy                = zynqmp_disp_crtc_destroy,
2744        .set_config             = drm_atomic_helper_set_config,
2745        .page_flip              = drm_atomic_helper_page_flip,
2746        .atomic_set_property    = zynqmp_disp_crtc_atomic_set_property,
2747        .atomic_get_property    = zynqmp_disp_crtc_atomic_get_property,
2748        .reset                  = drm_atomic_helper_crtc_reset,
2749        .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
2750        .atomic_destroy_state   = drm_atomic_helper_crtc_destroy_state,
2751        .enable_vblank          = zynqmp_disp_crtc_enable_vblank,
2752        .disable_vblank         = zynqmp_disp_crtc_disable_vblank,
2753};
2754
2755static int zynqmp_disp_create_crtc(struct zynqmp_disp *disp)
2756{
2757        struct drm_plane *plane = &disp->layers[ZYNQMP_DISP_LAYER_GFX].plane;
2758        struct drm_mode_object *obj = &disp->xlnx_crtc.crtc.base;
2759        int ret;
2760
2761        ret = drm_crtc_init_with_planes(disp->drm, &disp->xlnx_crtc.crtc,
2762                                        plane, NULL, &zynqmp_disp_crtc_funcs,
2763                                        NULL);
2764        if (ret < 0) {
2765                dev_err(disp->dev, "failed to initialize disp CRTC: %d\n",
2766                        ret);
2767                return ret;
2768        }
2769
2770        drm_crtc_helper_add(&disp->xlnx_crtc.crtc,
2771                            &zynqmp_disp_crtc_helper_funcs);
2772        drm_object_attach_property(obj, disp->color_prop, 0);
2773        zynqmp_dp_set_color(disp->dpsub->dp, zynqmp_disp_color_enum[0].name);
2774        drm_object_attach_property(obj, disp->bg_c0_prop, 0);
2775        drm_object_attach_property(obj, disp->bg_c1_prop, 0);
2776        drm_object_attach_property(obj, disp->bg_c2_prop, 0);
2777
2778        disp->xlnx_crtc.get_max_width = &zynqmp_disp_get_max_width;
2779        disp->xlnx_crtc.get_max_height = &zynqmp_disp_get_max_height;
2780        disp->xlnx_crtc.get_format = &zynqmp_disp_get_format;
2781        disp->xlnx_crtc.get_align = &zynqmp_disp_get_align;
2782        disp->xlnx_crtc.get_dma_mask = &zynqmp_disp_get_dma_mask;
2783        /* Only register the PS DP CRTC if there is no external port/CRTC */
2784        if (!disp->dpsub->external_crtc_attached)
2785                xlnx_crtc_register(disp->drm, &disp->xlnx_crtc);
2786
2787        return 0;
2788}
2789
2790static void zynqmp_disp_destroy_crtc(struct zynqmp_disp *disp)
2791{
2792        if (!disp->dpsub->external_crtc_attached)
2793                xlnx_crtc_unregister(disp->drm, &disp->xlnx_crtc);
2794        zynqmp_disp_crtc_destroy(&disp->xlnx_crtc.crtc);
2795}
2796
2797static void zynqmp_disp_map_crtc_to_plane(struct zynqmp_disp *disp)
2798{
2799        u32 possible_crtcs = drm_crtc_mask(&disp->xlnx_crtc.crtc);
2800        unsigned int i;
2801
2802        for (i = 0; i < ZYNQMP_DISP_NUM_LAYERS; i++)
2803                disp->layers[i].plane.possible_crtcs = possible_crtcs;
2804}
2805
2806/*
2807 * Xlnx bridge functions
2808 */
2809
2810static inline struct zynqmp_disp_layer
2811*bridge_to_layer(struct xlnx_bridge *bridge)
2812{
2813        return container_of(bridge, struct zynqmp_disp_layer, bridge);
2814}
2815
2816static int zynqmp_disp_bridge_enable(struct xlnx_bridge *bridge)
2817{
2818        struct zynqmp_disp_layer *layer = bridge_to_layer(bridge);
2819        struct zynqmp_disp *disp = layer->disp;
2820        struct drm_crtc *crtc = &disp->xlnx_crtc.crtc;
2821        struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
2822        struct videomode vm;
2823        int ret;
2824
2825        if (!disp->_pl_pclk) {
2826                dev_err(disp->dev, "PL clock is required for live\n");
2827                return -ENODEV;
2828        }
2829
2830        ret = zynqmp_disp_layer_check_size(disp, layer, layer->w, layer->h);
2831        if (ret)
2832                return ret;
2833
2834        /* Enable DP encoder if external CRTC attached */
2835        if (disp->dpsub->external_crtc_attached)
2836                zynqmp_disp_crtc_atomic_enable(crtc, NULL);
2837
2838        if (disp->vtc_bridge) {
2839                drm_display_mode_to_videomode(adjusted_mode, &vm);
2840                xlnx_bridge_set_timing(disp->vtc_bridge, &vm);
2841                xlnx_bridge_enable(disp->vtc_bridge);
2842        }
2843
2844        /* If external CRTC is connected through video layer, set alpha to 0 */
2845        if (disp->dpsub->external_crtc_attached && layer->id == ZYNQMP_DISP_LAYER_VID)
2846                disp->alpha = 0;
2847
2848        zynqmp_disp_set_g_alpha(disp, disp->alpha_en);
2849        zynqmp_disp_set_alpha(disp, disp->alpha);
2850        ret = zynqmp_disp_layer_enable(layer->disp, layer,
2851                                       ZYNQMP_DISP_LAYER_LIVE);
2852        if (ret)
2853                return ret;
2854
2855        if (layer->id == ZYNQMP_DISP_LAYER_GFX && disp->tpg_on) {
2856                layer = &disp->layers[ZYNQMP_DISP_LAYER_VID];
2857                zynqmp_disp_layer_set_tpg(disp, layer, disp->tpg_on);
2858        }
2859
2860        if (zynqmp_disp_av_buf_vid_timing_src_is_int(&disp->av_buf) ||
2861            zynqmp_disp_av_buf_vid_clock_src_is_ps(&disp->av_buf)) {
2862                dev_info(disp->dev,
2863                         "Disabling the pipeline to change the clk/timing src");
2864                zynqmp_disp_disable(disp, true);
2865                zynqmp_disp_av_buf_set_vid_clock_src(&disp->av_buf, false);
2866                zynqmp_disp_av_buf_set_vid_timing_src(&disp->av_buf, false);
2867        }
2868
2869        zynqmp_disp_enable(disp);
2870
2871        return 0;
2872}
2873
2874static void zynqmp_disp_bridge_disable(struct xlnx_bridge *bridge)
2875{
2876        struct zynqmp_disp_layer *layer = bridge_to_layer(bridge);
2877        struct zynqmp_disp *disp = layer->disp;
2878
2879        zynqmp_disp_disable(disp, false);
2880
2881        zynqmp_disp_layer_disable(disp, layer, ZYNQMP_DISP_LAYER_LIVE);
2882        if (layer->id == ZYNQMP_DISP_LAYER_VID && disp->tpg_on)
2883                zynqmp_disp_layer_set_tpg(disp, layer, disp->tpg_on);
2884
2885        if (!zynqmp_disp_layer_is_live(disp)) {
2886                dev_info(disp->dev,
2887                         "Disabling the pipeline to change the clk/timing src");
2888                zynqmp_disp_disable(disp, true);
2889                zynqmp_disp_av_buf_set_vid_clock_src(&disp->av_buf, true);
2890                zynqmp_disp_av_buf_set_vid_timing_src(&disp->av_buf, true);
2891                if (zynqmp_disp_layer_is_enabled(disp))
2892                        zynqmp_disp_enable(disp);
2893        }
2894}
2895
2896static int zynqmp_disp_bridge_set_input(struct xlnx_bridge *bridge,
2897                                        u32 width, u32 height, u32 bus_fmt)
2898{
2899        struct zynqmp_disp_layer *layer = bridge_to_layer(bridge);
2900        int ret;
2901
2902        ret = zynqmp_disp_layer_check_size(layer->disp, layer, width, height);
2903        if (ret)
2904                return ret;
2905
2906        ret = zynqmp_disp_layer_set_live_fmt(layer->disp,  layer, bus_fmt);
2907        if (ret)
2908                dev_err(layer->disp->dev, "failed to set live fmt\n");
2909
2910        return ret;
2911}
2912
2913static int zynqmp_disp_bridge_get_input_fmts(struct xlnx_bridge *bridge,
2914                                             const u32 **fmts, u32 *count)
2915{
2916        struct zynqmp_disp_layer *layer = bridge_to_layer(bridge);
2917
2918        *fmts = layer->bus_fmts;
2919        *count = layer->num_bus_fmts;
2920
2921        return 0;
2922}
2923
2924static int zynqmp_disp_bridge_set_timing(struct xlnx_bridge *bridge,
2925                                         struct videomode *vm)
2926{
2927        struct zynqmp_disp_layer *layer = bridge_to_layer(bridge);
2928        struct zynqmp_disp *disp = layer->disp;
2929        struct drm_crtc *crtc = &disp->xlnx_crtc.crtc;
2930        struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
2931
2932        drm_display_mode_from_videomode(vm, adjusted_mode);
2933
2934        return 0;
2935}
2936
2937/*
2938 * Component functions
2939 */
2940
2941int zynqmp_disp_bind(struct device *dev, struct device *master, void *data)
2942{
2943        struct zynqmp_dpsub *dpsub = dev_get_drvdata(dev);
2944        struct zynqmp_disp *disp = dpsub->disp;
2945        struct drm_device *drm = data;
2946        int num;
2947        u64 max;
2948        int ret;
2949
2950        disp->drm = drm;
2951
2952        max = ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA_MAX;
2953        disp->g_alpha_prop = drm_property_create_range(drm, 0, "alpha", 0, max);
2954        disp->g_alpha_en_prop = drm_property_create_bool(drm, 0,
2955                                                         "g_alpha_en");
2956        num = ARRAY_SIZE(zynqmp_disp_color_enum);
2957        disp->color_prop = drm_property_create_enum(drm, 0,
2958                                                    "output_color",
2959                                                    zynqmp_disp_color_enum,
2960                                                    num);
2961        max = ZYNQMP_DISP_V_BLEND_BG_MAX;
2962        disp->bg_c0_prop = drm_property_create_range(drm, 0, "bg_c0", 0, max);
2963        disp->bg_c1_prop = drm_property_create_range(drm, 0, "bg_c1", 0, max);
2964        disp->bg_c2_prop = drm_property_create_range(drm, 0, "bg_c2", 0, max);
2965        disp->tpg_prop = drm_property_create_bool(drm, 0, "tpg");
2966
2967        ret = zynqmp_disp_create_plane(disp);
2968        if (ret)
2969                return ret;
2970        ret = zynqmp_disp_create_crtc(disp);
2971        if (ret)
2972                return ret;
2973        zynqmp_disp_map_crtc_to_plane(disp);
2974
2975        return 0;
2976}
2977
2978void zynqmp_disp_unbind(struct device *dev, struct device *master, void *data)
2979{
2980        struct zynqmp_dpsub *dpsub = dev_get_drvdata(dev);
2981        struct zynqmp_disp *disp = dpsub->disp;
2982
2983        zynqmp_disp_destroy_crtc(disp);
2984        zynqmp_disp_destroy_plane(disp);
2985        drm_property_destroy(disp->drm, disp->bg_c2_prop);
2986        drm_property_destroy(disp->drm, disp->bg_c1_prop);
2987        drm_property_destroy(disp->drm, disp->bg_c0_prop);
2988        drm_property_destroy(disp->drm, disp->color_prop);
2989        drm_property_destroy(disp->drm, disp->g_alpha_en_prop);
2990        drm_property_destroy(disp->drm, disp->g_alpha_prop);
2991}
2992
2993/*
2994 * Platform initialization functions
2995 */
2996
2997static int zynqmp_disp_enumerate_fmts(struct zynqmp_disp *disp)
2998{
2999        struct zynqmp_disp_layer *layer;
3000        u32 *bus_fmts;
3001        u32 i, size, num_bus_fmts;
3002        u32 gfx_fmt = ZYNQMP_DISP_AV_BUF_GFX_FMT_RGB565;
3003
3004        num_bus_fmts = ARRAY_SIZE(av_buf_live_fmts);
3005        bus_fmts = devm_kzalloc(disp->dev, sizeof(*bus_fmts) * num_bus_fmts,
3006                                GFP_KERNEL);
3007        if (!bus_fmts)
3008                return -ENOMEM;
3009        for (i = 0; i < num_bus_fmts; i++)
3010                bus_fmts[i] = av_buf_live_fmts[i].bus_fmt;
3011
3012        layer = &disp->layers[ZYNQMP_DISP_LAYER_VID];
3013        layer->num_bus_fmts = num_bus_fmts;
3014        layer->bus_fmts = bus_fmts;
3015        size = ARRAY_SIZE(av_buf_vid_fmts);
3016        layer->num_fmts = size;
3017        layer->drm_fmts = devm_kzalloc(disp->dev,
3018                                       sizeof(*layer->drm_fmts) * size,
3019                                       GFP_KERNEL);
3020        if (!layer->drm_fmts)
3021                return -ENOMEM;
3022        for (i = 0; i < layer->num_fmts; i++)
3023                layer->drm_fmts[i] = av_buf_vid_fmts[i].drm_fmt;
3024        layer->fmt = &av_buf_vid_fmts[ZYNQMP_DISP_AV_BUF_VID_FMT_YUYV];
3025
3026        layer = &disp->layers[ZYNQMP_DISP_LAYER_GFX];
3027        layer->num_bus_fmts = num_bus_fmts;
3028        layer->bus_fmts = bus_fmts;
3029        size = ARRAY_SIZE(av_buf_gfx_fmts);
3030        layer->num_fmts = size;
3031        layer->drm_fmts = devm_kzalloc(disp->dev,
3032                                       sizeof(*layer->drm_fmts) * size,
3033                                       GFP_KERNEL);
3034        if (!layer->drm_fmts)
3035                return -ENOMEM;
3036
3037        for (i = 0; i < layer->num_fmts; i++)
3038                layer->drm_fmts[i] = av_buf_gfx_fmts[i].drm_fmt;
3039        if (zynqmp_disp_gfx_init_fmt < ARRAY_SIZE(zynqmp_disp_gfx_init_fmts))
3040                gfx_fmt = zynqmp_disp_gfx_init_fmts[zynqmp_disp_gfx_init_fmt];
3041        layer->fmt = &av_buf_gfx_fmts[gfx_fmt];
3042
3043        return 0;
3044}
3045
3046int zynqmp_disp_probe(struct platform_device *pdev)
3047{
3048        struct zynqmp_dpsub *dpsub;
3049        struct zynqmp_disp *disp;
3050        struct resource *res;
3051        void __iomem *regs;
3052        int ret;
3053        struct zynqmp_disp_layer *layer;
3054        unsigned int i, j;
3055        struct device_node *vtc_node;
3056
3057        disp = devm_kzalloc(&pdev->dev, sizeof(*disp), GFP_KERNEL);
3058        if (!disp)
3059                return -ENOMEM;
3060        disp->dev = &pdev->dev;
3061
3062        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "blend");
3063        disp->blend.base = devm_ioremap_resource(&pdev->dev, res);
3064        if (IS_ERR(disp->blend.base))
3065                return PTR_ERR(disp->blend.base);
3066
3067        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "av_buf");
3068        disp->av_buf.base = devm_ioremap_resource(&pdev->dev, res);
3069        if (IS_ERR(disp->av_buf.base))
3070                return PTR_ERR(disp->av_buf.base);
3071
3072        disp->aud.base = syscon_regmap_lookup_by_phandle(disp->dev->of_node,
3073                                                         "xlnx,dpaud-reg");
3074        if (IS_ERR(disp->aud.base)) {
3075                dev_info(&pdev->dev, "could not find xlnx,dpaud-reg, trying direct register access. DisplayPort audio will not work\n");
3076
3077                regs = devm_platform_ioremap_resource_byname(pdev, "aud");
3078                if (IS_ERR(regs)) {
3079                        dev_err(&pdev->dev, "get aud memory resource failed.\n");
3080                        return PTR_ERR(regs);
3081                }
3082                disp->aud.base =
3083                        devm_regmap_init_mmio(&pdev->dev, regs,
3084                                              &dpaud_regmap_config);
3085                if (IS_ERR(disp->aud.base)) {
3086                        dev_err(&pdev->dev, "failed to init regmap\n");
3087                        return PTR_ERR(disp->aud.base);
3088                }
3089        }
3090
3091        dpsub = platform_get_drvdata(pdev);
3092        dpsub->disp = disp;
3093        disp->dpsub = dpsub;
3094
3095        ret = zynqmp_disp_enumerate_fmts(disp);
3096        if (ret)
3097                return ret;
3098
3099        /* Try the live PL video clock */
3100        disp->_pl_pclk = devm_clk_get(disp->dev, "dp_live_video_in_clk");
3101        if (!IS_ERR(disp->_pl_pclk)) {
3102                disp->pclk = disp->_pl_pclk;
3103                ret = zynqmp_disp_clk_enable_disable(disp->pclk,
3104                                                     &disp->pclk_en);
3105                if (ret)
3106                        disp->pclk = NULL;
3107        } else if (PTR_ERR(disp->_pl_pclk) == -EPROBE_DEFER) {
3108                return PTR_ERR(disp->_pl_pclk);
3109        }
3110
3111        /* If the live PL video clock is not valid, fall back to PS clock */
3112        if (!disp->pclk) {
3113                disp->_ps_pclk = devm_clk_get(disp->dev, "dp_vtc_pixel_clk_in");
3114                if (IS_ERR(disp->_ps_pclk)) {
3115                        dev_err(disp->dev, "failed to init any video clock\n");
3116                        return PTR_ERR(disp->_ps_pclk);
3117                }
3118                disp->pclk = disp->_ps_pclk;
3119                ret = zynqmp_disp_clk_enable_disable(disp->pclk,
3120                                                     &disp->pclk_en);
3121                if (ret) {
3122                        dev_err(disp->dev, "failed to init any video clock\n");
3123                        return ret;
3124                }
3125        }
3126
3127        disp->aclk = devm_clk_get(disp->dev, "dp_apb_clk");
3128        if (IS_ERR(disp->aclk))
3129                return PTR_ERR(disp->aclk);
3130        ret = zynqmp_disp_clk_enable(disp->aclk, &disp->aclk_en);
3131        if (ret) {
3132                dev_err(disp->dev, "failed to enable the APB clk\n");
3133                return ret;
3134        }
3135
3136        /* Try the live PL audio clock */
3137        disp->_pl_audclk = devm_clk_get(disp->dev, "dp_live_audio_aclk");
3138        if (!IS_ERR(disp->_pl_audclk)) {
3139                disp->audclk = disp->_pl_audclk;
3140                ret = zynqmp_disp_clk_enable_disable(disp->audclk,
3141                                                     &disp->audclk_en);
3142                if (ret)
3143                        disp->audclk = NULL;
3144        }
3145
3146        /* If the live PL audio clock is not valid, fall back to PS clock */
3147        if (!disp->audclk) {
3148                disp->_ps_audclk = devm_clk_get(disp->dev, "dp_aud_clk");
3149                if (!IS_ERR(disp->_ps_audclk)) {
3150                        disp->audclk = disp->_ps_audclk;
3151                        ret = zynqmp_disp_clk_enable_disable(disp->audclk,
3152                                                             &disp->audclk_en);
3153                        if (ret)
3154                                disp->audclk = NULL;
3155                }
3156
3157                if (!disp->audclk) {
3158                        dev_err(disp->dev,
3159                                "audio is disabled due to clock failure\n");
3160                }
3161        }
3162
3163        /* VTC Bridge support */
3164        vtc_node = of_parse_phandle(disp->dev->of_node, "xlnx,bridge", 0);
3165        if (vtc_node) {
3166                disp->vtc_bridge = of_xlnx_bridge_get(vtc_node);
3167                if (!disp->vtc_bridge) {
3168                        dev_info(disp->dev, "Didn't get vtc bridge instance\n");
3169                        return -EPROBE_DEFER;
3170                }
3171        } else {
3172                dev_info(disp->dev, "vtc bridge property not present\n");
3173        }
3174
3175        ret = zynqmp_disp_layer_create(disp);
3176        if (ret)
3177                goto error_aclk;
3178
3179        zynqmp_disp_init(disp);
3180
3181        /*
3182         * Register live bridges so external CRTCs will be able probe
3183         * successfully
3184         */
3185        for (i = 0; i < ZYNQMP_DISP_NUM_LAYERS; i++) {
3186                layer = &disp->layers[i];
3187                layer->bridge.enable = &zynqmp_disp_bridge_enable;
3188                layer->bridge.disable = &zynqmp_disp_bridge_disable;
3189                layer->bridge.set_input = &zynqmp_disp_bridge_set_input;
3190                layer->bridge.get_input_fmts =
3191                        &zynqmp_disp_bridge_get_input_fmts;
3192                layer->bridge.set_timing = &zynqmp_disp_bridge_set_timing;
3193                layer->bridge.of_node = disp->dev->of_node;
3194                layer->bridge.extra_name = ((i == 0) ? ".vid" : ".gfx");
3195                ret = xlnx_bridge_register(&layer->bridge);
3196                if (ret) {
3197                        dev_info(disp->dev, "Bridge registration failed\n");
3198                        for (j = 0; j < i; j++)
3199                                xlnx_bridge_unregister(&disp->layers[j].bridge);
3200                        goto error_aclk;
3201                }
3202        }
3203
3204        return 0;
3205
3206error_aclk:
3207        zynqmp_disp_clk_disable(disp->aclk, &disp->aclk_en);
3208        return ret;
3209}
3210
3211int zynqmp_disp_remove(struct platform_device *pdev)
3212{
3213        struct zynqmp_dpsub *dpsub = platform_get_drvdata(pdev);
3214        struct zynqmp_disp *disp = dpsub->disp;
3215
3216        zynqmp_disp_layer_destroy(disp);
3217        if (disp->audclk)
3218                zynqmp_disp_clk_disable(disp->audclk, &disp->audclk_en);
3219        if (disp->vtc_bridge)
3220                of_xlnx_bridge_put(disp->vtc_bridge);
3221        zynqmp_disp_clk_disable(disp->aclk, &disp->aclk_en);
3222        zynqmp_disp_clk_disable(disp->pclk, &disp->pclk_en);
3223        dpsub->disp = NULL;
3224
3225        return 0;
3226}
3227