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