xref: /openbmc/linux/drivers/soc/mediatek/mtk-mutex.c (revision d47a97bd)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2015 MediaTek Inc.
4  */
5 
6 #include <linux/clk.h>
7 #include <linux/iopoll.h>
8 #include <linux/module.h>
9 #include <linux/of_device.h>
10 #include <linux/of_address.h>
11 #include <linux/platform_device.h>
12 #include <linux/regmap.h>
13 #include <linux/soc/mediatek/mtk-mmsys.h>
14 #include <linux/soc/mediatek/mtk-mutex.h>
15 #include <linux/soc/mediatek/mtk-cmdq.h>
16 
17 #define MT2701_MUTEX0_MOD0			0x2c
18 #define MT2701_MUTEX0_SOF0			0x30
19 #define MT8183_MUTEX0_MOD0			0x30
20 #define MT8183_MUTEX0_SOF0			0x2c
21 
22 #define DISP_REG_MUTEX_EN(n)			(0x20 + 0x20 * (n))
23 #define DISP_REG_MUTEX(n)			(0x24 + 0x20 * (n))
24 #define DISP_REG_MUTEX_RST(n)			(0x28 + 0x20 * (n))
25 #define DISP_REG_MUTEX_MOD(mutex_mod_reg, n)	(mutex_mod_reg + 0x20 * (n))
26 #define DISP_REG_MUTEX_SOF(mutex_sof_reg, n)	(mutex_sof_reg + 0x20 * (n))
27 #define DISP_REG_MUTEX_MOD2(n)			(0x34 + 0x20 * (n))
28 
29 #define INT_MUTEX				BIT(1)
30 
31 #define MT8186_MUTEX_MOD_DISP_OVL0		0
32 #define MT8186_MUTEX_MOD_DISP_OVL0_2L		1
33 #define MT8186_MUTEX_MOD_DISP_RDMA0		2
34 #define MT8186_MUTEX_MOD_DISP_COLOR0		4
35 #define MT8186_MUTEX_MOD_DISP_CCORR0		5
36 #define MT8186_MUTEX_MOD_DISP_AAL0		7
37 #define MT8186_MUTEX_MOD_DISP_GAMMA0		8
38 #define MT8186_MUTEX_MOD_DISP_POSTMASK0		9
39 #define MT8186_MUTEX_MOD_DISP_DITHER0		10
40 #define MT8186_MUTEX_MOD_DISP_RDMA1		17
41 
42 #define MT8186_MUTEX_SOF_SINGLE_MODE		0
43 #define MT8186_MUTEX_SOF_DSI0			1
44 #define MT8186_MUTEX_SOF_DPI0			2
45 #define MT8186_MUTEX_EOF_DSI0			(MT8186_MUTEX_SOF_DSI0 << 6)
46 #define MT8186_MUTEX_EOF_DPI0			(MT8186_MUTEX_SOF_DPI0 << 6)
47 
48 #define MT8167_MUTEX_MOD_DISP_PWM		1
49 #define MT8167_MUTEX_MOD_DISP_OVL0		6
50 #define MT8167_MUTEX_MOD_DISP_OVL1		7
51 #define MT8167_MUTEX_MOD_DISP_RDMA0		8
52 #define MT8167_MUTEX_MOD_DISP_RDMA1		9
53 #define MT8167_MUTEX_MOD_DISP_WDMA0		10
54 #define MT8167_MUTEX_MOD_DISP_CCORR		11
55 #define MT8167_MUTEX_MOD_DISP_COLOR		12
56 #define MT8167_MUTEX_MOD_DISP_AAL		13
57 #define MT8167_MUTEX_MOD_DISP_GAMMA		14
58 #define MT8167_MUTEX_MOD_DISP_DITHER		15
59 #define MT8167_MUTEX_MOD_DISP_UFOE		16
60 
61 #define MT8192_MUTEX_MOD_DISP_OVL0		0
62 #define MT8192_MUTEX_MOD_DISP_OVL0_2L		1
63 #define MT8192_MUTEX_MOD_DISP_RDMA0		2
64 #define MT8192_MUTEX_MOD_DISP_COLOR0		4
65 #define MT8192_MUTEX_MOD_DISP_CCORR0		5
66 #define MT8192_MUTEX_MOD_DISP_AAL0		6
67 #define MT8192_MUTEX_MOD_DISP_GAMMA0		7
68 #define MT8192_MUTEX_MOD_DISP_POSTMASK0		8
69 #define MT8192_MUTEX_MOD_DISP_DITHER0		9
70 #define MT8192_MUTEX_MOD_DISP_OVL2_2L		16
71 #define MT8192_MUTEX_MOD_DISP_RDMA4		17
72 
73 #define MT8183_MUTEX_MOD_DISP_RDMA0		0
74 #define MT8183_MUTEX_MOD_DISP_RDMA1		1
75 #define MT8183_MUTEX_MOD_DISP_OVL0		9
76 #define MT8183_MUTEX_MOD_DISP_OVL0_2L		10
77 #define MT8183_MUTEX_MOD_DISP_OVL1_2L		11
78 #define MT8183_MUTEX_MOD_DISP_WDMA0		12
79 #define MT8183_MUTEX_MOD_DISP_COLOR0		13
80 #define MT8183_MUTEX_MOD_DISP_CCORR0		14
81 #define MT8183_MUTEX_MOD_DISP_AAL0		15
82 #define MT8183_MUTEX_MOD_DISP_GAMMA0		16
83 #define MT8183_MUTEX_MOD_DISP_DITHER0		17
84 
85 #define MT8183_MUTEX_MOD_MDP_RDMA0		2
86 #define MT8183_MUTEX_MOD_MDP_RSZ0		4
87 #define MT8183_MUTEX_MOD_MDP_RSZ1		5
88 #define MT8183_MUTEX_MOD_MDP_TDSHP0		6
89 #define MT8183_MUTEX_MOD_MDP_WROT0		7
90 #define MT8183_MUTEX_MOD_MDP_WDMA		8
91 #define MT8183_MUTEX_MOD_MDP_AAL0		23
92 #define MT8183_MUTEX_MOD_MDP_CCORR0		24
93 
94 #define MT8186_MUTEX_MOD_MDP_RDMA0		0
95 #define MT8186_MUTEX_MOD_MDP_AAL0		2
96 #define MT8186_MUTEX_MOD_MDP_HDR0		4
97 #define MT8186_MUTEX_MOD_MDP_RSZ0		5
98 #define MT8186_MUTEX_MOD_MDP_RSZ1		6
99 #define MT8186_MUTEX_MOD_MDP_WROT0		7
100 #define MT8186_MUTEX_MOD_MDP_TDSHP0		9
101 #define MT8186_MUTEX_MOD_MDP_COLOR0		14
102 
103 #define MT8173_MUTEX_MOD_DISP_OVL0		11
104 #define MT8173_MUTEX_MOD_DISP_OVL1		12
105 #define MT8173_MUTEX_MOD_DISP_RDMA0		13
106 #define MT8173_MUTEX_MOD_DISP_RDMA1		14
107 #define MT8173_MUTEX_MOD_DISP_RDMA2		15
108 #define MT8173_MUTEX_MOD_DISP_WDMA0		16
109 #define MT8173_MUTEX_MOD_DISP_WDMA1		17
110 #define MT8173_MUTEX_MOD_DISP_COLOR0		18
111 #define MT8173_MUTEX_MOD_DISP_COLOR1		19
112 #define MT8173_MUTEX_MOD_DISP_AAL		20
113 #define MT8173_MUTEX_MOD_DISP_GAMMA		21
114 #define MT8173_MUTEX_MOD_DISP_UFOE		22
115 #define MT8173_MUTEX_MOD_DISP_PWM0		23
116 #define MT8173_MUTEX_MOD_DISP_PWM1		24
117 #define MT8173_MUTEX_MOD_DISP_OD		25
118 
119 #define MT8188_MUTEX_MOD_DISP_OVL0		0
120 #define MT8188_MUTEX_MOD_DISP_WDMA0		1
121 #define MT8188_MUTEX_MOD_DISP_RDMA0		2
122 #define MT8188_MUTEX_MOD_DISP_COLOR0		3
123 #define MT8188_MUTEX_MOD_DISP_CCORR0		4
124 #define MT8188_MUTEX_MOD_DISP_AAL0		5
125 #define MT8188_MUTEX_MOD_DISP_GAMMA0		6
126 #define MT8188_MUTEX_MOD_DISP_DITHER0		7
127 #define MT8188_MUTEX_MOD_DISP_DSI0		8
128 #define MT8188_MUTEX_MOD_DISP_DSC_WRAP0_CORE0	9
129 #define MT8188_MUTEX_MOD_DISP_VPP_MERGE		20
130 #define MT8188_MUTEX_MOD_DISP_DP_INTF0		21
131 #define MT8188_MUTEX_MOD_DISP_POSTMASK0		24
132 #define MT8188_MUTEX_MOD2_DISP_PWM0		33
133 
134 #define MT8195_MUTEX_MOD_DISP_OVL0		0
135 #define MT8195_MUTEX_MOD_DISP_WDMA0		1
136 #define MT8195_MUTEX_MOD_DISP_RDMA0		2
137 #define MT8195_MUTEX_MOD_DISP_COLOR0		3
138 #define MT8195_MUTEX_MOD_DISP_CCORR0		4
139 #define MT8195_MUTEX_MOD_DISP_AAL0		5
140 #define MT8195_MUTEX_MOD_DISP_GAMMA0		6
141 #define MT8195_MUTEX_MOD_DISP_DITHER0		7
142 #define MT8195_MUTEX_MOD_DISP_DSI0		8
143 #define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0	9
144 #define MT8195_MUTEX_MOD_DISP_VPP_MERGE		20
145 #define MT8195_MUTEX_MOD_DISP_DP_INTF0		21
146 #define MT8195_MUTEX_MOD_DISP_PWM0		27
147 
148 #define MT8195_MUTEX_MOD_DISP1_MDP_RDMA0	0
149 #define MT8195_MUTEX_MOD_DISP1_MDP_RDMA1	1
150 #define MT8195_MUTEX_MOD_DISP1_MDP_RDMA2	2
151 #define MT8195_MUTEX_MOD_DISP1_MDP_RDMA3	3
152 #define MT8195_MUTEX_MOD_DISP1_MDP_RDMA4	4
153 #define MT8195_MUTEX_MOD_DISP1_MDP_RDMA5	5
154 #define MT8195_MUTEX_MOD_DISP1_MDP_RDMA6	6
155 #define MT8195_MUTEX_MOD_DISP1_MDP_RDMA7	7
156 #define MT8195_MUTEX_MOD_DISP1_VPP_MERGE0	8
157 #define MT8195_MUTEX_MOD_DISP1_VPP_MERGE1	9
158 #define MT8195_MUTEX_MOD_DISP1_VPP_MERGE2	10
159 #define MT8195_MUTEX_MOD_DISP1_VPP_MERGE3	11
160 #define MT8195_MUTEX_MOD_DISP1_VPP_MERGE4	12
161 #define MT8195_MUTEX_MOD_DISP1_DISP_MIXER	18
162 #define MT8195_MUTEX_MOD_DISP1_DPI0		25
163 #define MT8195_MUTEX_MOD_DISP1_DPI1		26
164 #define MT8195_MUTEX_MOD_DISP1_DP_INTF0		27
165 
166 #define MT8365_MUTEX_MOD_DISP_OVL0		7
167 #define MT8365_MUTEX_MOD_DISP_OVL0_2L		8
168 #define MT8365_MUTEX_MOD_DISP_RDMA0		9
169 #define MT8365_MUTEX_MOD_DISP_RDMA1		10
170 #define MT8365_MUTEX_MOD_DISP_WDMA0		11
171 #define MT8365_MUTEX_MOD_DISP_COLOR0		12
172 #define MT8365_MUTEX_MOD_DISP_CCORR		13
173 #define MT8365_MUTEX_MOD_DISP_AAL		14
174 #define MT8365_MUTEX_MOD_DISP_GAMMA		15
175 #define MT8365_MUTEX_MOD_DISP_DITHER		16
176 #define MT8365_MUTEX_MOD_DISP_DSI0		17
177 #define MT8365_MUTEX_MOD_DISP_PWM0		20
178 #define MT8365_MUTEX_MOD_DISP_DPI0		22
179 
180 #define MT2712_MUTEX_MOD_DISP_PWM2		10
181 #define MT2712_MUTEX_MOD_DISP_OVL0		11
182 #define MT2712_MUTEX_MOD_DISP_OVL1		12
183 #define MT2712_MUTEX_MOD_DISP_RDMA0		13
184 #define MT2712_MUTEX_MOD_DISP_RDMA1		14
185 #define MT2712_MUTEX_MOD_DISP_RDMA2		15
186 #define MT2712_MUTEX_MOD_DISP_WDMA0		16
187 #define MT2712_MUTEX_MOD_DISP_WDMA1		17
188 #define MT2712_MUTEX_MOD_DISP_COLOR0		18
189 #define MT2712_MUTEX_MOD_DISP_COLOR1		19
190 #define MT2712_MUTEX_MOD_DISP_AAL0		20
191 #define MT2712_MUTEX_MOD_DISP_UFOE		22
192 #define MT2712_MUTEX_MOD_DISP_PWM0		23
193 #define MT2712_MUTEX_MOD_DISP_PWM1		24
194 #define MT2712_MUTEX_MOD_DISP_OD0		25
195 #define MT2712_MUTEX_MOD2_DISP_AAL1		33
196 #define MT2712_MUTEX_MOD2_DISP_OD1		34
197 
198 #define MT2701_MUTEX_MOD_DISP_OVL		3
199 #define MT2701_MUTEX_MOD_DISP_WDMA		6
200 #define MT2701_MUTEX_MOD_DISP_COLOR		7
201 #define MT2701_MUTEX_MOD_DISP_BLS		9
202 #define MT2701_MUTEX_MOD_DISP_RDMA0		10
203 #define MT2701_MUTEX_MOD_DISP_RDMA1		12
204 
205 #define MT2712_MUTEX_SOF_SINGLE_MODE		0
206 #define MT2712_MUTEX_SOF_DSI0			1
207 #define MT2712_MUTEX_SOF_DSI1			2
208 #define MT2712_MUTEX_SOF_DPI0			3
209 #define MT2712_MUTEX_SOF_DPI1			4
210 #define MT2712_MUTEX_SOF_DSI2			5
211 #define MT2712_MUTEX_SOF_DSI3			6
212 #define MT8167_MUTEX_SOF_DPI0			2
213 #define MT8167_MUTEX_SOF_DPI1			3
214 #define MT8183_MUTEX_SOF_DSI0			1
215 #define MT8183_MUTEX_SOF_DPI0			2
216 #define MT8188_MUTEX_SOF_DSI0			1
217 #define MT8188_MUTEX_SOF_DP_INTF0		3
218 #define MT8195_MUTEX_SOF_DSI0			1
219 #define MT8195_MUTEX_SOF_DSI1			2
220 #define MT8195_MUTEX_SOF_DP_INTF0		3
221 #define MT8195_MUTEX_SOF_DP_INTF1		4
222 #define MT8195_MUTEX_SOF_DPI0			6 /* for HDMI_TX */
223 #define MT8195_MUTEX_SOF_DPI1			5 /* for digital video out */
224 
225 #define MT8183_MUTEX_EOF_DSI0			(MT8183_MUTEX_SOF_DSI0 << 6)
226 #define MT8183_MUTEX_EOF_DPI0			(MT8183_MUTEX_SOF_DPI0 << 6)
227 #define MT8188_MUTEX_EOF_DSI0			(MT8188_MUTEX_SOF_DSI0 << 7)
228 #define MT8188_MUTEX_EOF_DP_INTF0		(MT8188_MUTEX_SOF_DP_INTF0 << 7)
229 #define MT8195_MUTEX_EOF_DSI0			(MT8195_MUTEX_SOF_DSI0 << 7)
230 #define MT8195_MUTEX_EOF_DSI1			(MT8195_MUTEX_SOF_DSI1 << 7)
231 #define MT8195_MUTEX_EOF_DP_INTF0		(MT8195_MUTEX_SOF_DP_INTF0 << 7)
232 #define MT8195_MUTEX_EOF_DP_INTF1		(MT8195_MUTEX_SOF_DP_INTF1 << 7)
233 #define MT8195_MUTEX_EOF_DPI0			(MT8195_MUTEX_SOF_DPI0 << 7)
234 #define MT8195_MUTEX_EOF_DPI1			(MT8195_MUTEX_SOF_DPI1 << 7)
235 
236 struct mtk_mutex {
237 	int id;
238 	bool claimed;
239 };
240 
241 enum mtk_mutex_sof_id {
242 	MUTEX_SOF_SINGLE_MODE,
243 	MUTEX_SOF_DSI0,
244 	MUTEX_SOF_DSI1,
245 	MUTEX_SOF_DPI0,
246 	MUTEX_SOF_DPI1,
247 	MUTEX_SOF_DSI2,
248 	MUTEX_SOF_DSI3,
249 	MUTEX_SOF_DP_INTF0,
250 	MUTEX_SOF_DP_INTF1,
251 	DDP_MUTEX_SOF_MAX,
252 };
253 
254 struct mtk_mutex_data {
255 	const unsigned int *mutex_mod;
256 	const unsigned int *mutex_sof;
257 	const unsigned int mutex_mod_reg;
258 	const unsigned int mutex_sof_reg;
259 	const unsigned int *mutex_table_mod;
260 	const bool no_clk;
261 };
262 
263 struct mtk_mutex_ctx {
264 	struct device			*dev;
265 	struct clk			*clk;
266 	void __iomem			*regs;
267 	struct mtk_mutex		mutex[10];
268 	const struct mtk_mutex_data	*data;
269 	phys_addr_t			addr;
270 	struct cmdq_client_reg		cmdq_reg;
271 };
272 
273 static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
274 	[DDP_COMPONENT_BLS] = MT2701_MUTEX_MOD_DISP_BLS,
275 	[DDP_COMPONENT_COLOR0] = MT2701_MUTEX_MOD_DISP_COLOR,
276 	[DDP_COMPONENT_OVL0] = MT2701_MUTEX_MOD_DISP_OVL,
277 	[DDP_COMPONENT_RDMA0] = MT2701_MUTEX_MOD_DISP_RDMA0,
278 	[DDP_COMPONENT_RDMA1] = MT2701_MUTEX_MOD_DISP_RDMA1,
279 	[DDP_COMPONENT_WDMA0] = MT2701_MUTEX_MOD_DISP_WDMA,
280 };
281 
282 static const unsigned int mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = {
283 	[DDP_COMPONENT_AAL0] = MT2712_MUTEX_MOD_DISP_AAL0,
284 	[DDP_COMPONENT_AAL1] = MT2712_MUTEX_MOD2_DISP_AAL1,
285 	[DDP_COMPONENT_COLOR0] = MT2712_MUTEX_MOD_DISP_COLOR0,
286 	[DDP_COMPONENT_COLOR1] = MT2712_MUTEX_MOD_DISP_COLOR1,
287 	[DDP_COMPONENT_OD0] = MT2712_MUTEX_MOD_DISP_OD0,
288 	[DDP_COMPONENT_OD1] = MT2712_MUTEX_MOD2_DISP_OD1,
289 	[DDP_COMPONENT_OVL0] = MT2712_MUTEX_MOD_DISP_OVL0,
290 	[DDP_COMPONENT_OVL1] = MT2712_MUTEX_MOD_DISP_OVL1,
291 	[DDP_COMPONENT_PWM0] = MT2712_MUTEX_MOD_DISP_PWM0,
292 	[DDP_COMPONENT_PWM1] = MT2712_MUTEX_MOD_DISP_PWM1,
293 	[DDP_COMPONENT_PWM2] = MT2712_MUTEX_MOD_DISP_PWM2,
294 	[DDP_COMPONENT_RDMA0] = MT2712_MUTEX_MOD_DISP_RDMA0,
295 	[DDP_COMPONENT_RDMA1] = MT2712_MUTEX_MOD_DISP_RDMA1,
296 	[DDP_COMPONENT_RDMA2] = MT2712_MUTEX_MOD_DISP_RDMA2,
297 	[DDP_COMPONENT_UFOE] = MT2712_MUTEX_MOD_DISP_UFOE,
298 	[DDP_COMPONENT_WDMA0] = MT2712_MUTEX_MOD_DISP_WDMA0,
299 	[DDP_COMPONENT_WDMA1] = MT2712_MUTEX_MOD_DISP_WDMA1,
300 };
301 
302 static const unsigned int mt8167_mutex_mod[DDP_COMPONENT_ID_MAX] = {
303 	[DDP_COMPONENT_AAL0] = MT8167_MUTEX_MOD_DISP_AAL,
304 	[DDP_COMPONENT_CCORR] = MT8167_MUTEX_MOD_DISP_CCORR,
305 	[DDP_COMPONENT_COLOR0] = MT8167_MUTEX_MOD_DISP_COLOR,
306 	[DDP_COMPONENT_DITHER0] = MT8167_MUTEX_MOD_DISP_DITHER,
307 	[DDP_COMPONENT_GAMMA] = MT8167_MUTEX_MOD_DISP_GAMMA,
308 	[DDP_COMPONENT_OVL0] = MT8167_MUTEX_MOD_DISP_OVL0,
309 	[DDP_COMPONENT_OVL1] = MT8167_MUTEX_MOD_DISP_OVL1,
310 	[DDP_COMPONENT_PWM0] = MT8167_MUTEX_MOD_DISP_PWM,
311 	[DDP_COMPONENT_RDMA0] = MT8167_MUTEX_MOD_DISP_RDMA0,
312 	[DDP_COMPONENT_RDMA1] = MT8167_MUTEX_MOD_DISP_RDMA1,
313 	[DDP_COMPONENT_UFOE] = MT8167_MUTEX_MOD_DISP_UFOE,
314 	[DDP_COMPONENT_WDMA0] = MT8167_MUTEX_MOD_DISP_WDMA0,
315 };
316 
317 static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
318 	[DDP_COMPONENT_AAL0] = MT8173_MUTEX_MOD_DISP_AAL,
319 	[DDP_COMPONENT_COLOR0] = MT8173_MUTEX_MOD_DISP_COLOR0,
320 	[DDP_COMPONENT_COLOR1] = MT8173_MUTEX_MOD_DISP_COLOR1,
321 	[DDP_COMPONENT_GAMMA] = MT8173_MUTEX_MOD_DISP_GAMMA,
322 	[DDP_COMPONENT_OD0] = MT8173_MUTEX_MOD_DISP_OD,
323 	[DDP_COMPONENT_OVL0] = MT8173_MUTEX_MOD_DISP_OVL0,
324 	[DDP_COMPONENT_OVL1] = MT8173_MUTEX_MOD_DISP_OVL1,
325 	[DDP_COMPONENT_PWM0] = MT8173_MUTEX_MOD_DISP_PWM0,
326 	[DDP_COMPONENT_PWM1] = MT8173_MUTEX_MOD_DISP_PWM1,
327 	[DDP_COMPONENT_RDMA0] = MT8173_MUTEX_MOD_DISP_RDMA0,
328 	[DDP_COMPONENT_RDMA1] = MT8173_MUTEX_MOD_DISP_RDMA1,
329 	[DDP_COMPONENT_RDMA2] = MT8173_MUTEX_MOD_DISP_RDMA2,
330 	[DDP_COMPONENT_UFOE] = MT8173_MUTEX_MOD_DISP_UFOE,
331 	[DDP_COMPONENT_WDMA0] = MT8173_MUTEX_MOD_DISP_WDMA0,
332 	[DDP_COMPONENT_WDMA1] = MT8173_MUTEX_MOD_DISP_WDMA1,
333 };
334 
335 static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
336 	[DDP_COMPONENT_AAL0] = MT8183_MUTEX_MOD_DISP_AAL0,
337 	[DDP_COMPONENT_CCORR] = MT8183_MUTEX_MOD_DISP_CCORR0,
338 	[DDP_COMPONENT_COLOR0] = MT8183_MUTEX_MOD_DISP_COLOR0,
339 	[DDP_COMPONENT_DITHER0] = MT8183_MUTEX_MOD_DISP_DITHER0,
340 	[DDP_COMPONENT_GAMMA] = MT8183_MUTEX_MOD_DISP_GAMMA0,
341 	[DDP_COMPONENT_OVL0] = MT8183_MUTEX_MOD_DISP_OVL0,
342 	[DDP_COMPONENT_OVL_2L0] = MT8183_MUTEX_MOD_DISP_OVL0_2L,
343 	[DDP_COMPONENT_OVL_2L1] = MT8183_MUTEX_MOD_DISP_OVL1_2L,
344 	[DDP_COMPONENT_RDMA0] = MT8183_MUTEX_MOD_DISP_RDMA0,
345 	[DDP_COMPONENT_RDMA1] = MT8183_MUTEX_MOD_DISP_RDMA1,
346 	[DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0,
347 };
348 
349 static const unsigned int mt8183_mutex_table_mod[MUTEX_MOD_IDX_MAX] = {
350 	[MUTEX_MOD_IDX_MDP_RDMA0] = MT8183_MUTEX_MOD_MDP_RDMA0,
351 	[MUTEX_MOD_IDX_MDP_RSZ0] = MT8183_MUTEX_MOD_MDP_RSZ0,
352 	[MUTEX_MOD_IDX_MDP_RSZ1] = MT8183_MUTEX_MOD_MDP_RSZ1,
353 	[MUTEX_MOD_IDX_MDP_TDSHP0] = MT8183_MUTEX_MOD_MDP_TDSHP0,
354 	[MUTEX_MOD_IDX_MDP_WROT0] = MT8183_MUTEX_MOD_MDP_WROT0,
355 	[MUTEX_MOD_IDX_MDP_WDMA] = MT8183_MUTEX_MOD_MDP_WDMA,
356 	[MUTEX_MOD_IDX_MDP_AAL0] = MT8183_MUTEX_MOD_MDP_AAL0,
357 	[MUTEX_MOD_IDX_MDP_CCORR0] = MT8183_MUTEX_MOD_MDP_CCORR0,
358 };
359 
360 static const unsigned int mt8186_mutex_mod[DDP_COMPONENT_ID_MAX] = {
361 	[DDP_COMPONENT_AAL0] = MT8186_MUTEX_MOD_DISP_AAL0,
362 	[DDP_COMPONENT_CCORR] = MT8186_MUTEX_MOD_DISP_CCORR0,
363 	[DDP_COMPONENT_COLOR0] = MT8186_MUTEX_MOD_DISP_COLOR0,
364 	[DDP_COMPONENT_DITHER0] = MT8186_MUTEX_MOD_DISP_DITHER0,
365 	[DDP_COMPONENT_GAMMA] = MT8186_MUTEX_MOD_DISP_GAMMA0,
366 	[DDP_COMPONENT_OVL0] = MT8186_MUTEX_MOD_DISP_OVL0,
367 	[DDP_COMPONENT_OVL_2L0] = MT8186_MUTEX_MOD_DISP_OVL0_2L,
368 	[DDP_COMPONENT_POSTMASK0] = MT8186_MUTEX_MOD_DISP_POSTMASK0,
369 	[DDP_COMPONENT_RDMA0] = MT8186_MUTEX_MOD_DISP_RDMA0,
370 	[DDP_COMPONENT_RDMA1] = MT8186_MUTEX_MOD_DISP_RDMA1,
371 };
372 
373 static const unsigned int mt8186_mdp_mutex_table_mod[MUTEX_MOD_IDX_MAX] = {
374 	[MUTEX_MOD_IDX_MDP_RDMA0] = MT8186_MUTEX_MOD_MDP_RDMA0,
375 	[MUTEX_MOD_IDX_MDP_RSZ0] = MT8186_MUTEX_MOD_MDP_RSZ0,
376 	[MUTEX_MOD_IDX_MDP_RSZ1] = MT8186_MUTEX_MOD_MDP_RSZ1,
377 	[MUTEX_MOD_IDX_MDP_TDSHP0] = MT8186_MUTEX_MOD_MDP_TDSHP0,
378 	[MUTEX_MOD_IDX_MDP_WROT0] = MT8186_MUTEX_MOD_MDP_WROT0,
379 	[MUTEX_MOD_IDX_MDP_HDR0] = MT8186_MUTEX_MOD_MDP_HDR0,
380 	[MUTEX_MOD_IDX_MDP_AAL0] = MT8186_MUTEX_MOD_MDP_AAL0,
381 	[MUTEX_MOD_IDX_MDP_COLOR0] = MT8186_MUTEX_MOD_MDP_COLOR0,
382 };
383 
384 static const unsigned int mt8188_mutex_mod[DDP_COMPONENT_ID_MAX] = {
385 	[DDP_COMPONENT_OVL0] = MT8188_MUTEX_MOD_DISP_OVL0,
386 	[DDP_COMPONENT_WDMA0] = MT8188_MUTEX_MOD_DISP_WDMA0,
387 	[DDP_COMPONENT_RDMA0] = MT8188_MUTEX_MOD_DISP_RDMA0,
388 	[DDP_COMPONENT_COLOR0] = MT8188_MUTEX_MOD_DISP_COLOR0,
389 	[DDP_COMPONENT_CCORR] = MT8188_MUTEX_MOD_DISP_CCORR0,
390 	[DDP_COMPONENT_AAL0] = MT8188_MUTEX_MOD_DISP_AAL0,
391 	[DDP_COMPONENT_GAMMA] = MT8188_MUTEX_MOD_DISP_GAMMA0,
392 	[DDP_COMPONENT_POSTMASK0] = MT8188_MUTEX_MOD_DISP_POSTMASK0,
393 	[DDP_COMPONENT_DITHER0] = MT8188_MUTEX_MOD_DISP_DITHER0,
394 	[DDP_COMPONENT_MERGE0] = MT8188_MUTEX_MOD_DISP_VPP_MERGE,
395 	[DDP_COMPONENT_DSC0] = MT8188_MUTEX_MOD_DISP_DSC_WRAP0_CORE0,
396 	[DDP_COMPONENT_DSI0] = MT8188_MUTEX_MOD_DISP_DSI0,
397 	[DDP_COMPONENT_PWM0] = MT8188_MUTEX_MOD2_DISP_PWM0,
398 	[DDP_COMPONENT_DP_INTF0] = MT8188_MUTEX_MOD_DISP_DP_INTF0,
399 };
400 
401 static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = {
402 	[DDP_COMPONENT_AAL0] = MT8192_MUTEX_MOD_DISP_AAL0,
403 	[DDP_COMPONENT_CCORR] = MT8192_MUTEX_MOD_DISP_CCORR0,
404 	[DDP_COMPONENT_COLOR0] = MT8192_MUTEX_MOD_DISP_COLOR0,
405 	[DDP_COMPONENT_DITHER0] = MT8192_MUTEX_MOD_DISP_DITHER0,
406 	[DDP_COMPONENT_GAMMA] = MT8192_MUTEX_MOD_DISP_GAMMA0,
407 	[DDP_COMPONENT_POSTMASK0] = MT8192_MUTEX_MOD_DISP_POSTMASK0,
408 	[DDP_COMPONENT_OVL0] = MT8192_MUTEX_MOD_DISP_OVL0,
409 	[DDP_COMPONENT_OVL_2L0] = MT8192_MUTEX_MOD_DISP_OVL0_2L,
410 	[DDP_COMPONENT_OVL_2L2] = MT8192_MUTEX_MOD_DISP_OVL2_2L,
411 	[DDP_COMPONENT_RDMA0] = MT8192_MUTEX_MOD_DISP_RDMA0,
412 	[DDP_COMPONENT_RDMA4] = MT8192_MUTEX_MOD_DISP_RDMA4,
413 };
414 
415 static const unsigned int mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
416 	[DDP_COMPONENT_OVL0] = MT8195_MUTEX_MOD_DISP_OVL0,
417 	[DDP_COMPONENT_WDMA0] = MT8195_MUTEX_MOD_DISP_WDMA0,
418 	[DDP_COMPONENT_RDMA0] = MT8195_MUTEX_MOD_DISP_RDMA0,
419 	[DDP_COMPONENT_COLOR0] = MT8195_MUTEX_MOD_DISP_COLOR0,
420 	[DDP_COMPONENT_CCORR] = MT8195_MUTEX_MOD_DISP_CCORR0,
421 	[DDP_COMPONENT_AAL0] = MT8195_MUTEX_MOD_DISP_AAL0,
422 	[DDP_COMPONENT_GAMMA] = MT8195_MUTEX_MOD_DISP_GAMMA0,
423 	[DDP_COMPONENT_DITHER0] = MT8195_MUTEX_MOD_DISP_DITHER0,
424 	[DDP_COMPONENT_MERGE0] = MT8195_MUTEX_MOD_DISP_VPP_MERGE,
425 	[DDP_COMPONENT_DSC0] = MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0,
426 	[DDP_COMPONENT_DSI0] = MT8195_MUTEX_MOD_DISP_DSI0,
427 	[DDP_COMPONENT_PWM0] = MT8195_MUTEX_MOD_DISP_PWM0,
428 	[DDP_COMPONENT_DP_INTF0] = MT8195_MUTEX_MOD_DISP_DP_INTF0,
429 	[DDP_COMPONENT_MDP_RDMA0] = MT8195_MUTEX_MOD_DISP1_MDP_RDMA0,
430 	[DDP_COMPONENT_MDP_RDMA1] = MT8195_MUTEX_MOD_DISP1_MDP_RDMA1,
431 	[DDP_COMPONENT_MDP_RDMA2] = MT8195_MUTEX_MOD_DISP1_MDP_RDMA2,
432 	[DDP_COMPONENT_MDP_RDMA3] = MT8195_MUTEX_MOD_DISP1_MDP_RDMA3,
433 	[DDP_COMPONENT_MDP_RDMA4] = MT8195_MUTEX_MOD_DISP1_MDP_RDMA4,
434 	[DDP_COMPONENT_MDP_RDMA5] = MT8195_MUTEX_MOD_DISP1_MDP_RDMA5,
435 	[DDP_COMPONENT_MDP_RDMA6] = MT8195_MUTEX_MOD_DISP1_MDP_RDMA6,
436 	[DDP_COMPONENT_MDP_RDMA7] = MT8195_MUTEX_MOD_DISP1_MDP_RDMA7,
437 	[DDP_COMPONENT_MERGE1] = MT8195_MUTEX_MOD_DISP1_VPP_MERGE0,
438 	[DDP_COMPONENT_MERGE2] = MT8195_MUTEX_MOD_DISP1_VPP_MERGE1,
439 	[DDP_COMPONENT_MERGE3] = MT8195_MUTEX_MOD_DISP1_VPP_MERGE2,
440 	[DDP_COMPONENT_MERGE4] = MT8195_MUTEX_MOD_DISP1_VPP_MERGE3,
441 	[DDP_COMPONENT_ETHDR_MIXER] = MT8195_MUTEX_MOD_DISP1_DISP_MIXER,
442 	[DDP_COMPONENT_MERGE5] = MT8195_MUTEX_MOD_DISP1_VPP_MERGE4,
443 	[DDP_COMPONENT_DP_INTF1] = MT8195_MUTEX_MOD_DISP1_DP_INTF0,
444 };
445 
446 static const unsigned int mt8365_mutex_mod[DDP_COMPONENT_ID_MAX] = {
447 	[DDP_COMPONENT_AAL0] = MT8365_MUTEX_MOD_DISP_AAL,
448 	[DDP_COMPONENT_CCORR] = MT8365_MUTEX_MOD_DISP_CCORR,
449 	[DDP_COMPONENT_COLOR0] = MT8365_MUTEX_MOD_DISP_COLOR0,
450 	[DDP_COMPONENT_DITHER0] = MT8365_MUTEX_MOD_DISP_DITHER,
451 	[DDP_COMPONENT_DPI0] = MT8365_MUTEX_MOD_DISP_DPI0,
452 	[DDP_COMPONENT_DSI0] = MT8365_MUTEX_MOD_DISP_DSI0,
453 	[DDP_COMPONENT_GAMMA] = MT8365_MUTEX_MOD_DISP_GAMMA,
454 	[DDP_COMPONENT_OVL0] = MT8365_MUTEX_MOD_DISP_OVL0,
455 	[DDP_COMPONENT_OVL_2L0] = MT8365_MUTEX_MOD_DISP_OVL0_2L,
456 	[DDP_COMPONENT_PWM0] = MT8365_MUTEX_MOD_DISP_PWM0,
457 	[DDP_COMPONENT_RDMA0] = MT8365_MUTEX_MOD_DISP_RDMA0,
458 	[DDP_COMPONENT_RDMA1] = MT8365_MUTEX_MOD_DISP_RDMA1,
459 	[DDP_COMPONENT_WDMA0] = MT8365_MUTEX_MOD_DISP_WDMA0,
460 };
461 
462 static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = {
463 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
464 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
465 	[MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1,
466 	[MUTEX_SOF_DPI0] = MUTEX_SOF_DPI0,
467 	[MUTEX_SOF_DPI1] = MUTEX_SOF_DPI1,
468 	[MUTEX_SOF_DSI2] = MUTEX_SOF_DSI2,
469 	[MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3,
470 };
471 
472 static const unsigned int mt6795_mutex_sof[DDP_MUTEX_SOF_MAX] = {
473 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
474 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
475 	[MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1,
476 	[MUTEX_SOF_DPI0] = MUTEX_SOF_DPI0,
477 };
478 
479 static const unsigned int mt8167_mutex_sof[DDP_MUTEX_SOF_MAX] = {
480 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
481 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
482 	[MUTEX_SOF_DPI0] = MT8167_MUTEX_SOF_DPI0,
483 	[MUTEX_SOF_DPI1] = MT8167_MUTEX_SOF_DPI1,
484 };
485 
486 /* Add EOF setting so overlay hardware can receive frame done irq */
487 static const unsigned int mt8183_mutex_sof[DDP_MUTEX_SOF_MAX] = {
488 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
489 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0 | MT8183_MUTEX_EOF_DSI0,
490 	[MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0,
491 };
492 
493 static const unsigned int mt8186_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
494 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
495 	[MUTEX_SOF_DSI0] = MT8186_MUTEX_SOF_DSI0 | MT8186_MUTEX_EOF_DSI0,
496 	[MUTEX_SOF_DPI0] = MT8186_MUTEX_SOF_DPI0 | MT8186_MUTEX_EOF_DPI0,
497 };
498 
499 /*
500  * To support refresh mode(video mode), DISP_REG_MUTEX_SOF should
501  * select the EOF source and configure the EOF plus timing from the
502  * module that provides the timing signal.
503  * So that MUTEX can not only send a STREAM_DONE event to GCE
504  * but also detect the error at end of frame(EAEOF) when EOF signal
505  * arrives.
506  */
507 static const unsigned int mt8188_mutex_sof[DDP_MUTEX_SOF_MAX] = {
508 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
509 	[MUTEX_SOF_DSI0] =
510 		MT8188_MUTEX_SOF_DSI0 | MT8188_MUTEX_EOF_DSI0,
511 	[MUTEX_SOF_DP_INTF0] =
512 		MT8188_MUTEX_SOF_DP_INTF0 | MT8188_MUTEX_EOF_DP_INTF0,
513 };
514 
515 static const unsigned int mt8195_mutex_sof[DDP_MUTEX_SOF_MAX] = {
516 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
517 	[MUTEX_SOF_DSI0] = MT8195_MUTEX_SOF_DSI0 | MT8195_MUTEX_EOF_DSI0,
518 	[MUTEX_SOF_DSI1] = MT8195_MUTEX_SOF_DSI1 | MT8195_MUTEX_EOF_DSI1,
519 	[MUTEX_SOF_DPI0] = MT8195_MUTEX_SOF_DPI0 | MT8195_MUTEX_EOF_DPI0,
520 	[MUTEX_SOF_DPI1] = MT8195_MUTEX_SOF_DPI1 | MT8195_MUTEX_EOF_DPI1,
521 	[MUTEX_SOF_DP_INTF0] =
522 		MT8195_MUTEX_SOF_DP_INTF0 | MT8195_MUTEX_EOF_DP_INTF0,
523 	[MUTEX_SOF_DP_INTF1] =
524 		MT8195_MUTEX_SOF_DP_INTF1 | MT8195_MUTEX_EOF_DP_INTF1,
525 };
526 
527 static const struct mtk_mutex_data mt2701_mutex_driver_data = {
528 	.mutex_mod = mt2701_mutex_mod,
529 	.mutex_sof = mt2712_mutex_sof,
530 	.mutex_mod_reg = MT2701_MUTEX0_MOD0,
531 	.mutex_sof_reg = MT2701_MUTEX0_SOF0,
532 };
533 
534 static const struct mtk_mutex_data mt2712_mutex_driver_data = {
535 	.mutex_mod = mt2712_mutex_mod,
536 	.mutex_sof = mt2712_mutex_sof,
537 	.mutex_mod_reg = MT2701_MUTEX0_MOD0,
538 	.mutex_sof_reg = MT2701_MUTEX0_SOF0,
539 };
540 
541 static const struct mtk_mutex_data mt6795_mutex_driver_data = {
542 	.mutex_mod = mt8173_mutex_mod,
543 	.mutex_sof = mt6795_mutex_sof,
544 	.mutex_mod_reg = MT2701_MUTEX0_MOD0,
545 	.mutex_sof_reg = MT2701_MUTEX0_SOF0,
546 };
547 
548 static const struct mtk_mutex_data mt8167_mutex_driver_data = {
549 	.mutex_mod = mt8167_mutex_mod,
550 	.mutex_sof = mt8167_mutex_sof,
551 	.mutex_mod_reg = MT2701_MUTEX0_MOD0,
552 	.mutex_sof_reg = MT2701_MUTEX0_SOF0,
553 	.no_clk = true,
554 };
555 
556 static const struct mtk_mutex_data mt8173_mutex_driver_data = {
557 	.mutex_mod = mt8173_mutex_mod,
558 	.mutex_sof = mt2712_mutex_sof,
559 	.mutex_mod_reg = MT2701_MUTEX0_MOD0,
560 	.mutex_sof_reg = MT2701_MUTEX0_SOF0,
561 };
562 
563 static const struct mtk_mutex_data mt8183_mutex_driver_data = {
564 	.mutex_mod = mt8183_mutex_mod,
565 	.mutex_sof = mt8183_mutex_sof,
566 	.mutex_mod_reg = MT8183_MUTEX0_MOD0,
567 	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
568 	.mutex_table_mod = mt8183_mutex_table_mod,
569 	.no_clk = true,
570 };
571 
572 static const struct mtk_mutex_data mt8186_mdp_mutex_driver_data = {
573 	.mutex_mod_reg = MT8183_MUTEX0_MOD0,
574 	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
575 	.mutex_table_mod = mt8186_mdp_mutex_table_mod,
576 };
577 
578 static const struct mtk_mutex_data mt8186_mutex_driver_data = {
579 	.mutex_mod = mt8186_mutex_mod,
580 	.mutex_sof = mt8186_mutex_sof,
581 	.mutex_mod_reg = MT8183_MUTEX0_MOD0,
582 	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
583 };
584 
585 static const struct mtk_mutex_data mt8188_mutex_driver_data = {
586 	.mutex_mod = mt8188_mutex_mod,
587 	.mutex_sof = mt8188_mutex_sof,
588 	.mutex_mod_reg = MT8183_MUTEX0_MOD0,
589 	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
590 };
591 
592 static const struct mtk_mutex_data mt8192_mutex_driver_data = {
593 	.mutex_mod = mt8192_mutex_mod,
594 	.mutex_sof = mt8183_mutex_sof,
595 	.mutex_mod_reg = MT8183_MUTEX0_MOD0,
596 	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
597 };
598 
599 static const struct mtk_mutex_data mt8195_mutex_driver_data = {
600 	.mutex_mod = mt8195_mutex_mod,
601 	.mutex_sof = mt8195_mutex_sof,
602 	.mutex_mod_reg = MT8183_MUTEX0_MOD0,
603 	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
604 };
605 
606 static const struct mtk_mutex_data mt8365_mutex_driver_data = {
607 	.mutex_mod = mt8365_mutex_mod,
608 	.mutex_sof = mt8183_mutex_sof,
609 	.mutex_mod_reg = MT8183_MUTEX0_MOD0,
610 	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
611 	.no_clk = true,
612 };
613 
614 struct mtk_mutex *mtk_mutex_get(struct device *dev)
615 {
616 	struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev);
617 	int i;
618 
619 	for (i = 0; i < 10; i++)
620 		if (!mtx->mutex[i].claimed) {
621 			mtx->mutex[i].claimed = true;
622 			return &mtx->mutex[i];
623 		}
624 
625 	return ERR_PTR(-EBUSY);
626 }
627 EXPORT_SYMBOL_GPL(mtk_mutex_get);
628 
629 void mtk_mutex_put(struct mtk_mutex *mutex)
630 {
631 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
632 						 mutex[mutex->id]);
633 
634 	WARN_ON(&mtx->mutex[mutex->id] != mutex);
635 
636 	mutex->claimed = false;
637 }
638 EXPORT_SYMBOL_GPL(mtk_mutex_put);
639 
640 int mtk_mutex_prepare(struct mtk_mutex *mutex)
641 {
642 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
643 						 mutex[mutex->id]);
644 	return clk_prepare_enable(mtx->clk);
645 }
646 EXPORT_SYMBOL_GPL(mtk_mutex_prepare);
647 
648 void mtk_mutex_unprepare(struct mtk_mutex *mutex)
649 {
650 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
651 						 mutex[mutex->id]);
652 	clk_disable_unprepare(mtx->clk);
653 }
654 EXPORT_SYMBOL_GPL(mtk_mutex_unprepare);
655 
656 void mtk_mutex_add_comp(struct mtk_mutex *mutex,
657 			enum mtk_ddp_comp_id id)
658 {
659 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
660 						 mutex[mutex->id]);
661 	unsigned int reg;
662 	unsigned int sof_id;
663 	unsigned int offset;
664 
665 	WARN_ON(&mtx->mutex[mutex->id] != mutex);
666 
667 	switch (id) {
668 	case DDP_COMPONENT_DSI0:
669 		sof_id = MUTEX_SOF_DSI0;
670 		break;
671 	case DDP_COMPONENT_DSI1:
672 		sof_id = MUTEX_SOF_DSI0;
673 		break;
674 	case DDP_COMPONENT_DSI2:
675 		sof_id = MUTEX_SOF_DSI2;
676 		break;
677 	case DDP_COMPONENT_DSI3:
678 		sof_id = MUTEX_SOF_DSI3;
679 		break;
680 	case DDP_COMPONENT_DPI0:
681 		sof_id = MUTEX_SOF_DPI0;
682 		break;
683 	case DDP_COMPONENT_DPI1:
684 		sof_id = MUTEX_SOF_DPI1;
685 		break;
686 	case DDP_COMPONENT_DP_INTF0:
687 		sof_id = MUTEX_SOF_DP_INTF0;
688 		break;
689 	case DDP_COMPONENT_DP_INTF1:
690 		sof_id = MUTEX_SOF_DP_INTF1;
691 		break;
692 	default:
693 		if (mtx->data->mutex_mod[id] < 32) {
694 			offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
695 						    mutex->id);
696 			reg = readl_relaxed(mtx->regs + offset);
697 			reg |= 1 << mtx->data->mutex_mod[id];
698 			writel_relaxed(reg, mtx->regs + offset);
699 		} else {
700 			offset = DISP_REG_MUTEX_MOD2(mutex->id);
701 			reg = readl_relaxed(mtx->regs + offset);
702 			reg |= 1 << (mtx->data->mutex_mod[id] - 32);
703 			writel_relaxed(reg, mtx->regs + offset);
704 		}
705 		return;
706 	}
707 
708 	writel_relaxed(mtx->data->mutex_sof[sof_id],
709 		       mtx->regs +
710 		       DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg, mutex->id));
711 }
712 EXPORT_SYMBOL_GPL(mtk_mutex_add_comp);
713 
714 void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
715 			   enum mtk_ddp_comp_id id)
716 {
717 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
718 						 mutex[mutex->id]);
719 	unsigned int reg;
720 	unsigned int offset;
721 
722 	WARN_ON(&mtx->mutex[mutex->id] != mutex);
723 
724 	switch (id) {
725 	case DDP_COMPONENT_DSI0:
726 	case DDP_COMPONENT_DSI1:
727 	case DDP_COMPONENT_DSI2:
728 	case DDP_COMPONENT_DSI3:
729 	case DDP_COMPONENT_DPI0:
730 	case DDP_COMPONENT_DPI1:
731 	case DDP_COMPONENT_DP_INTF0:
732 	case DDP_COMPONENT_DP_INTF1:
733 		writel_relaxed(MUTEX_SOF_SINGLE_MODE,
734 			       mtx->regs +
735 			       DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg,
736 						  mutex->id));
737 		break;
738 	default:
739 		if (mtx->data->mutex_mod[id] < 32) {
740 			offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
741 						    mutex->id);
742 			reg = readl_relaxed(mtx->regs + offset);
743 			reg &= ~(1 << mtx->data->mutex_mod[id]);
744 			writel_relaxed(reg, mtx->regs + offset);
745 		} else {
746 			offset = DISP_REG_MUTEX_MOD2(mutex->id);
747 			reg = readl_relaxed(mtx->regs + offset);
748 			reg &= ~(1 << (mtx->data->mutex_mod[id] - 32));
749 			writel_relaxed(reg, mtx->regs + offset);
750 		}
751 		break;
752 	}
753 }
754 EXPORT_SYMBOL_GPL(mtk_mutex_remove_comp);
755 
756 void mtk_mutex_enable(struct mtk_mutex *mutex)
757 {
758 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
759 						 mutex[mutex->id]);
760 
761 	WARN_ON(&mtx->mutex[mutex->id] != mutex);
762 
763 	writel(1, mtx->regs + DISP_REG_MUTEX_EN(mutex->id));
764 }
765 EXPORT_SYMBOL_GPL(mtk_mutex_enable);
766 
767 int mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex, void *pkt)
768 {
769 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
770 						 mutex[mutex->id]);
771 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
772 	struct cmdq_pkt *cmdq_pkt = (struct cmdq_pkt *)pkt;
773 
774 	WARN_ON(&mtx->mutex[mutex->id] != mutex);
775 
776 	if (!mtx->cmdq_reg.size) {
777 		dev_err(mtx->dev, "mediatek,gce-client-reg hasn't been set");
778 		return -EINVAL;
779 	}
780 
781 	cmdq_pkt_write(cmdq_pkt, mtx->cmdq_reg.subsys,
782 		       mtx->addr + DISP_REG_MUTEX_EN(mutex->id), 1);
783 	return 0;
784 #else
785 	dev_err(mtx->dev, "Not support for enable MUTEX by CMDQ");
786 	return -ENODEV;
787 #endif
788 }
789 EXPORT_SYMBOL_GPL(mtk_mutex_enable_by_cmdq);
790 
791 void mtk_mutex_disable(struct mtk_mutex *mutex)
792 {
793 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
794 						 mutex[mutex->id]);
795 
796 	WARN_ON(&mtx->mutex[mutex->id] != mutex);
797 
798 	writel(0, mtx->regs + DISP_REG_MUTEX_EN(mutex->id));
799 }
800 EXPORT_SYMBOL_GPL(mtk_mutex_disable);
801 
802 void mtk_mutex_acquire(struct mtk_mutex *mutex)
803 {
804 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
805 						 mutex[mutex->id]);
806 	u32 tmp;
807 
808 	writel(1, mtx->regs + DISP_REG_MUTEX_EN(mutex->id));
809 	writel(1, mtx->regs + DISP_REG_MUTEX(mutex->id));
810 	if (readl_poll_timeout_atomic(mtx->regs + DISP_REG_MUTEX(mutex->id),
811 				      tmp, tmp & INT_MUTEX, 1, 10000))
812 		pr_err("could not acquire mutex %d\n", mutex->id);
813 }
814 EXPORT_SYMBOL_GPL(mtk_mutex_acquire);
815 
816 void mtk_mutex_release(struct mtk_mutex *mutex)
817 {
818 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
819 						 mutex[mutex->id]);
820 
821 	writel(0, mtx->regs + DISP_REG_MUTEX(mutex->id));
822 }
823 EXPORT_SYMBOL_GPL(mtk_mutex_release);
824 
825 int mtk_mutex_write_mod(struct mtk_mutex *mutex,
826 			enum mtk_mutex_mod_index idx, bool clear)
827 {
828 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
829 						 mutex[mutex->id]);
830 	unsigned int reg;
831 	unsigned int offset;
832 
833 	WARN_ON(&mtx->mutex[mutex->id] != mutex);
834 
835 	if (idx < MUTEX_MOD_IDX_MDP_RDMA0 ||
836 	    idx >= MUTEX_MOD_IDX_MAX) {
837 		dev_err(mtx->dev, "Not supported MOD table index : %d", idx);
838 		return -EINVAL;
839 	}
840 
841 	offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
842 				    mutex->id);
843 	reg = readl_relaxed(mtx->regs + offset);
844 
845 	if (clear)
846 		reg &= ~BIT(mtx->data->mutex_table_mod[idx]);
847 	else
848 		reg |= BIT(mtx->data->mutex_table_mod[idx]);
849 
850 	writel_relaxed(reg, mtx->regs + offset);
851 
852 	return 0;
853 }
854 EXPORT_SYMBOL_GPL(mtk_mutex_write_mod);
855 
856 int mtk_mutex_write_sof(struct mtk_mutex *mutex,
857 			enum mtk_mutex_sof_index idx)
858 {
859 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
860 						 mutex[mutex->id]);
861 
862 	WARN_ON(&mtx->mutex[mutex->id] != mutex);
863 
864 	if (idx < MUTEX_SOF_IDX_SINGLE_MODE ||
865 	    idx >= MUTEX_SOF_IDX_MAX) {
866 		dev_err(mtx->dev, "Not supported SOF index : %d", idx);
867 		return -EINVAL;
868 	}
869 
870 	writel_relaxed(idx, mtx->regs +
871 		       DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg, mutex->id));
872 
873 	return 0;
874 }
875 EXPORT_SYMBOL_GPL(mtk_mutex_write_sof);
876 
877 static int mtk_mutex_probe(struct platform_device *pdev)
878 {
879 	struct device *dev = &pdev->dev;
880 	struct mtk_mutex_ctx *mtx;
881 	struct resource *regs;
882 	int i;
883 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
884 	int ret;
885 #endif
886 
887 	mtx = devm_kzalloc(dev, sizeof(*mtx), GFP_KERNEL);
888 	if (!mtx)
889 		return -ENOMEM;
890 
891 	for (i = 0; i < 10; i++)
892 		mtx->mutex[i].id = i;
893 
894 	mtx->data = of_device_get_match_data(dev);
895 
896 	if (!mtx->data->no_clk) {
897 		mtx->clk = devm_clk_get(dev, NULL);
898 		if (IS_ERR(mtx->clk)) {
899 			if (PTR_ERR(mtx->clk) != -EPROBE_DEFER)
900 				dev_err(dev, "Failed to get clock\n");
901 			return PTR_ERR(mtx->clk);
902 		}
903 	}
904 
905 	mtx->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &regs);
906 	if (IS_ERR(mtx->regs)) {
907 		dev_err(dev, "Failed to map mutex registers\n");
908 		return PTR_ERR(mtx->regs);
909 	}
910 	mtx->addr = regs->start;
911 
912 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
913 	ret = cmdq_dev_get_client_reg(dev, &mtx->cmdq_reg, 0);
914 	if (ret)
915 		dev_dbg(dev, "No mediatek,gce-client-reg!\n");
916 #endif
917 
918 	platform_set_drvdata(pdev, mtx);
919 
920 	return 0;
921 }
922 
923 static const struct of_device_id mutex_driver_dt_match[] = {
924 	{ .compatible = "mediatek,mt2701-disp-mutex",
925 	  .data = &mt2701_mutex_driver_data},
926 	{ .compatible = "mediatek,mt2712-disp-mutex",
927 	  .data = &mt2712_mutex_driver_data},
928 	{ .compatible = "mediatek,mt6795-disp-mutex",
929 	  .data = &mt6795_mutex_driver_data},
930 	{ .compatible = "mediatek,mt8167-disp-mutex",
931 	  .data = &mt8167_mutex_driver_data},
932 	{ .compatible = "mediatek,mt8173-disp-mutex",
933 	  .data = &mt8173_mutex_driver_data},
934 	{ .compatible = "mediatek,mt8183-disp-mutex",
935 	  .data = &mt8183_mutex_driver_data},
936 	{ .compatible = "mediatek,mt8186-disp-mutex",
937 	  .data = &mt8186_mutex_driver_data},
938 	{ .compatible = "mediatek,mt8186-mdp3-mutex",
939 	  .data = &mt8186_mdp_mutex_driver_data},
940 	{ .compatible = "mediatek,mt8188-disp-mutex",
941 	  .data = &mt8188_mutex_driver_data},
942 	{ .compatible = "mediatek,mt8192-disp-mutex",
943 	  .data = &mt8192_mutex_driver_data},
944 	{ .compatible = "mediatek,mt8195-disp-mutex",
945 	  .data = &mt8195_mutex_driver_data},
946 	{ .compatible = "mediatek,mt8365-disp-mutex",
947 	  .data = &mt8365_mutex_driver_data},
948 	{},
949 };
950 MODULE_DEVICE_TABLE(of, mutex_driver_dt_match);
951 
952 static struct platform_driver mtk_mutex_driver = {
953 	.probe		= mtk_mutex_probe,
954 	.driver		= {
955 		.name	= "mediatek-mutex",
956 		.owner	= THIS_MODULE,
957 		.of_match_table = mutex_driver_dt_match,
958 	},
959 };
960 
961 static int __init mtk_mutex_init(void)
962 {
963 	return platform_driver_register(&mtk_mutex_driver);
964 }
965 
966 static void __exit mtk_mutex_exit(void)
967 {
968 	platform_driver_unregister(&mtk_mutex_driver);
969 }
970 
971 module_init(mtk_mutex_init);
972 module_exit(mtk_mutex_exit);
973 
974 MODULE_AUTHOR("Yongqiang Niu <yongqiang.niu@mediatek.com>");
975 MODULE_DESCRIPTION("MediaTek SoC MUTEX driver");
976 MODULE_LICENSE("GPL");
977