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