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