xref: /openbmc/linux/drivers/soc/mediatek/mtk-mutex.c (revision acf50233)
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/platform_device.h>
11 #include <linux/regmap.h>
12 #include <linux/soc/mediatek/mtk-mmsys.h>
13 #include <linux/soc/mediatek/mtk-mutex.h>
14 
15 #define MT2701_MUTEX0_MOD0			0x2c
16 #define MT2701_MUTEX0_SOF0			0x30
17 #define MT8183_MUTEX0_MOD0			0x30
18 #define MT8183_MUTEX0_SOF0			0x2c
19 
20 #define DISP_REG_MUTEX_EN(n)			(0x20 + 0x20 * (n))
21 #define DISP_REG_MUTEX(n)			(0x24 + 0x20 * (n))
22 #define DISP_REG_MUTEX_RST(n)			(0x28 + 0x20 * (n))
23 #define DISP_REG_MUTEX_MOD(mutex_mod_reg, n)	(mutex_mod_reg + 0x20 * (n))
24 #define DISP_REG_MUTEX_SOF(mutex_sof_reg, n)	(mutex_sof_reg + 0x20 * (n))
25 #define DISP_REG_MUTEX_MOD2(n)			(0x34 + 0x20 * (n))
26 
27 #define INT_MUTEX				BIT(1)
28 
29 #define MT8186_MUTEX_MOD_DISP_OVL0		0
30 #define MT8186_MUTEX_MOD_DISP_OVL0_2L		1
31 #define MT8186_MUTEX_MOD_DISP_RDMA0		2
32 #define MT8186_MUTEX_MOD_DISP_COLOR0		4
33 #define MT8186_MUTEX_MOD_DISP_CCORR0		5
34 #define MT8186_MUTEX_MOD_DISP_AAL0		7
35 #define MT8186_MUTEX_MOD_DISP_GAMMA0		8
36 #define MT8186_MUTEX_MOD_DISP_POSTMASK0		9
37 #define MT8186_MUTEX_MOD_DISP_DITHER0		10
38 #define MT8186_MUTEX_MOD_DISP_RDMA1		17
39 
40 #define MT8186_MUTEX_SOF_SINGLE_MODE		0
41 #define MT8186_MUTEX_SOF_DSI0			1
42 #define MT8186_MUTEX_SOF_DPI0			2
43 #define MT8186_MUTEX_EOF_DSI0			(MT8186_MUTEX_SOF_DSI0 << 6)
44 #define MT8186_MUTEX_EOF_DPI0			(MT8186_MUTEX_SOF_DPI0 << 6)
45 
46 #define MT8167_MUTEX_MOD_DISP_PWM		1
47 #define MT8167_MUTEX_MOD_DISP_OVL0		6
48 #define MT8167_MUTEX_MOD_DISP_OVL1		7
49 #define MT8167_MUTEX_MOD_DISP_RDMA0		8
50 #define MT8167_MUTEX_MOD_DISP_RDMA1		9
51 #define MT8167_MUTEX_MOD_DISP_WDMA0		10
52 #define MT8167_MUTEX_MOD_DISP_CCORR		11
53 #define MT8167_MUTEX_MOD_DISP_COLOR		12
54 #define MT8167_MUTEX_MOD_DISP_AAL		13
55 #define MT8167_MUTEX_MOD_DISP_GAMMA		14
56 #define MT8167_MUTEX_MOD_DISP_DITHER		15
57 #define MT8167_MUTEX_MOD_DISP_UFOE		16
58 
59 #define MT8192_MUTEX_MOD_DISP_OVL0		0
60 #define MT8192_MUTEX_MOD_DISP_OVL0_2L		1
61 #define MT8192_MUTEX_MOD_DISP_RDMA0		2
62 #define MT8192_MUTEX_MOD_DISP_COLOR0		4
63 #define MT8192_MUTEX_MOD_DISP_CCORR0		5
64 #define MT8192_MUTEX_MOD_DISP_AAL0		6
65 #define MT8192_MUTEX_MOD_DISP_GAMMA0		7
66 #define MT8192_MUTEX_MOD_DISP_POSTMASK0		8
67 #define MT8192_MUTEX_MOD_DISP_DITHER0		9
68 #define MT8192_MUTEX_MOD_DISP_OVL2_2L		16
69 #define MT8192_MUTEX_MOD_DISP_RDMA4		17
70 
71 #define MT8183_MUTEX_MOD_DISP_RDMA0		0
72 #define MT8183_MUTEX_MOD_DISP_RDMA1		1
73 #define MT8183_MUTEX_MOD_DISP_OVL0		9
74 #define MT8183_MUTEX_MOD_DISP_OVL0_2L		10
75 #define MT8183_MUTEX_MOD_DISP_OVL1_2L		11
76 #define MT8183_MUTEX_MOD_DISP_WDMA0		12
77 #define MT8183_MUTEX_MOD_DISP_COLOR0		13
78 #define MT8183_MUTEX_MOD_DISP_CCORR0		14
79 #define MT8183_MUTEX_MOD_DISP_AAL0		15
80 #define MT8183_MUTEX_MOD_DISP_GAMMA0		16
81 #define MT8183_MUTEX_MOD_DISP_DITHER0		17
82 
83 #define MT8173_MUTEX_MOD_DISP_OVL0		11
84 #define MT8173_MUTEX_MOD_DISP_OVL1		12
85 #define MT8173_MUTEX_MOD_DISP_RDMA0		13
86 #define MT8173_MUTEX_MOD_DISP_RDMA1		14
87 #define MT8173_MUTEX_MOD_DISP_RDMA2		15
88 #define MT8173_MUTEX_MOD_DISP_WDMA0		16
89 #define MT8173_MUTEX_MOD_DISP_WDMA1		17
90 #define MT8173_MUTEX_MOD_DISP_COLOR0		18
91 #define MT8173_MUTEX_MOD_DISP_COLOR1		19
92 #define MT8173_MUTEX_MOD_DISP_AAL		20
93 #define MT8173_MUTEX_MOD_DISP_GAMMA		21
94 #define MT8173_MUTEX_MOD_DISP_UFOE		22
95 #define MT8173_MUTEX_MOD_DISP_PWM0		23
96 #define MT8173_MUTEX_MOD_DISP_PWM1		24
97 #define MT8173_MUTEX_MOD_DISP_OD		25
98 
99 #define MT8195_MUTEX_MOD_DISP_OVL0		0
100 #define MT8195_MUTEX_MOD_DISP_WDMA0		1
101 #define MT8195_MUTEX_MOD_DISP_RDMA0		2
102 #define MT8195_MUTEX_MOD_DISP_COLOR0		3
103 #define MT8195_MUTEX_MOD_DISP_CCORR0		4
104 #define MT8195_MUTEX_MOD_DISP_AAL0		5
105 #define MT8195_MUTEX_MOD_DISP_GAMMA0		6
106 #define MT8195_MUTEX_MOD_DISP_DITHER0		7
107 #define MT8195_MUTEX_MOD_DISP_DSI0		8
108 #define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0	9
109 #define MT8195_MUTEX_MOD_DISP_VPP_MERGE		20
110 #define MT8195_MUTEX_MOD_DISP_DP_INTF0		21
111 #define MT8195_MUTEX_MOD_DISP_PWM0		27
112 
113 #define MT2712_MUTEX_MOD_DISP_PWM2		10
114 #define MT2712_MUTEX_MOD_DISP_OVL0		11
115 #define MT2712_MUTEX_MOD_DISP_OVL1		12
116 #define MT2712_MUTEX_MOD_DISP_RDMA0		13
117 #define MT2712_MUTEX_MOD_DISP_RDMA1		14
118 #define MT2712_MUTEX_MOD_DISP_RDMA2		15
119 #define MT2712_MUTEX_MOD_DISP_WDMA0		16
120 #define MT2712_MUTEX_MOD_DISP_WDMA1		17
121 #define MT2712_MUTEX_MOD_DISP_COLOR0		18
122 #define MT2712_MUTEX_MOD_DISP_COLOR1		19
123 #define MT2712_MUTEX_MOD_DISP_AAL0		20
124 #define MT2712_MUTEX_MOD_DISP_UFOE		22
125 #define MT2712_MUTEX_MOD_DISP_PWM0		23
126 #define MT2712_MUTEX_MOD_DISP_PWM1		24
127 #define MT2712_MUTEX_MOD_DISP_OD0		25
128 #define MT2712_MUTEX_MOD2_DISP_AAL1		33
129 #define MT2712_MUTEX_MOD2_DISP_OD1		34
130 
131 #define MT2701_MUTEX_MOD_DISP_OVL		3
132 #define MT2701_MUTEX_MOD_DISP_WDMA		6
133 #define MT2701_MUTEX_MOD_DISP_COLOR		7
134 #define MT2701_MUTEX_MOD_DISP_BLS		9
135 #define MT2701_MUTEX_MOD_DISP_RDMA0		10
136 #define MT2701_MUTEX_MOD_DISP_RDMA1		12
137 
138 #define MT2712_MUTEX_SOF_SINGLE_MODE		0
139 #define MT2712_MUTEX_SOF_DSI0			1
140 #define MT2712_MUTEX_SOF_DSI1			2
141 #define MT2712_MUTEX_SOF_DPI0			3
142 #define MT2712_MUTEX_SOF_DPI1			4
143 #define MT2712_MUTEX_SOF_DSI2			5
144 #define MT2712_MUTEX_SOF_DSI3			6
145 #define MT8167_MUTEX_SOF_DPI0			2
146 #define MT8167_MUTEX_SOF_DPI1			3
147 #define MT8183_MUTEX_SOF_DSI0			1
148 #define MT8183_MUTEX_SOF_DPI0			2
149 #define MT8195_MUTEX_SOF_DSI0			1
150 #define MT8195_MUTEX_SOF_DSI1			2
151 #define MT8195_MUTEX_SOF_DP_INTF0		3
152 #define MT8195_MUTEX_SOF_DP_INTF1		4
153 #define MT8195_MUTEX_SOF_DPI0			6 /* for HDMI_TX */
154 #define MT8195_MUTEX_SOF_DPI1			5 /* for digital video out */
155 
156 #define MT8183_MUTEX_EOF_DSI0			(MT8183_MUTEX_SOF_DSI0 << 6)
157 #define MT8183_MUTEX_EOF_DPI0			(MT8183_MUTEX_SOF_DPI0 << 6)
158 #define MT8195_MUTEX_EOF_DSI0			(MT8195_MUTEX_SOF_DSI0 << 7)
159 #define MT8195_MUTEX_EOF_DSI1			(MT8195_MUTEX_SOF_DSI1 << 7)
160 #define MT8195_MUTEX_EOF_DP_INTF0		(MT8195_MUTEX_SOF_DP_INTF0 << 7)
161 #define MT8195_MUTEX_EOF_DP_INTF1		(MT8195_MUTEX_SOF_DP_INTF1 << 7)
162 #define MT8195_MUTEX_EOF_DPI0			(MT8195_MUTEX_SOF_DPI0 << 7)
163 #define MT8195_MUTEX_EOF_DPI1			(MT8195_MUTEX_SOF_DPI1 << 7)
164 
165 struct mtk_mutex {
166 	int id;
167 	bool claimed;
168 };
169 
170 enum mtk_mutex_sof_id {
171 	MUTEX_SOF_SINGLE_MODE,
172 	MUTEX_SOF_DSI0,
173 	MUTEX_SOF_DSI1,
174 	MUTEX_SOF_DPI0,
175 	MUTEX_SOF_DPI1,
176 	MUTEX_SOF_DSI2,
177 	MUTEX_SOF_DSI3,
178 	MUTEX_SOF_DP_INTF0,
179 	MUTEX_SOF_DP_INTF1,
180 	DDP_MUTEX_SOF_MAX,
181 };
182 
183 struct mtk_mutex_data {
184 	const unsigned int *mutex_mod;
185 	const unsigned int *mutex_sof;
186 	const unsigned int mutex_mod_reg;
187 	const unsigned int mutex_sof_reg;
188 	const bool no_clk;
189 };
190 
191 struct mtk_mutex_ctx {
192 	struct device			*dev;
193 	struct clk			*clk;
194 	void __iomem			*regs;
195 	struct mtk_mutex		mutex[10];
196 	const struct mtk_mutex_data	*data;
197 };
198 
199 static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
200 	[DDP_COMPONENT_BLS] = MT2701_MUTEX_MOD_DISP_BLS,
201 	[DDP_COMPONENT_COLOR0] = MT2701_MUTEX_MOD_DISP_COLOR,
202 	[DDP_COMPONENT_OVL0] = MT2701_MUTEX_MOD_DISP_OVL,
203 	[DDP_COMPONENT_RDMA0] = MT2701_MUTEX_MOD_DISP_RDMA0,
204 	[DDP_COMPONENT_RDMA1] = MT2701_MUTEX_MOD_DISP_RDMA1,
205 	[DDP_COMPONENT_WDMA0] = MT2701_MUTEX_MOD_DISP_WDMA,
206 };
207 
208 static const unsigned int mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = {
209 	[DDP_COMPONENT_AAL0] = MT2712_MUTEX_MOD_DISP_AAL0,
210 	[DDP_COMPONENT_AAL1] = MT2712_MUTEX_MOD2_DISP_AAL1,
211 	[DDP_COMPONENT_COLOR0] = MT2712_MUTEX_MOD_DISP_COLOR0,
212 	[DDP_COMPONENT_COLOR1] = MT2712_MUTEX_MOD_DISP_COLOR1,
213 	[DDP_COMPONENT_OD0] = MT2712_MUTEX_MOD_DISP_OD0,
214 	[DDP_COMPONENT_OD1] = MT2712_MUTEX_MOD2_DISP_OD1,
215 	[DDP_COMPONENT_OVL0] = MT2712_MUTEX_MOD_DISP_OVL0,
216 	[DDP_COMPONENT_OVL1] = MT2712_MUTEX_MOD_DISP_OVL1,
217 	[DDP_COMPONENT_PWM0] = MT2712_MUTEX_MOD_DISP_PWM0,
218 	[DDP_COMPONENT_PWM1] = MT2712_MUTEX_MOD_DISP_PWM1,
219 	[DDP_COMPONENT_PWM2] = MT2712_MUTEX_MOD_DISP_PWM2,
220 	[DDP_COMPONENT_RDMA0] = MT2712_MUTEX_MOD_DISP_RDMA0,
221 	[DDP_COMPONENT_RDMA1] = MT2712_MUTEX_MOD_DISP_RDMA1,
222 	[DDP_COMPONENT_RDMA2] = MT2712_MUTEX_MOD_DISP_RDMA2,
223 	[DDP_COMPONENT_UFOE] = MT2712_MUTEX_MOD_DISP_UFOE,
224 	[DDP_COMPONENT_WDMA0] = MT2712_MUTEX_MOD_DISP_WDMA0,
225 	[DDP_COMPONENT_WDMA1] = MT2712_MUTEX_MOD_DISP_WDMA1,
226 };
227 
228 static const unsigned int mt8167_mutex_mod[DDP_COMPONENT_ID_MAX] = {
229 	[DDP_COMPONENT_AAL0] = MT8167_MUTEX_MOD_DISP_AAL,
230 	[DDP_COMPONENT_CCORR] = MT8167_MUTEX_MOD_DISP_CCORR,
231 	[DDP_COMPONENT_COLOR0] = MT8167_MUTEX_MOD_DISP_COLOR,
232 	[DDP_COMPONENT_DITHER0] = MT8167_MUTEX_MOD_DISP_DITHER,
233 	[DDP_COMPONENT_GAMMA] = MT8167_MUTEX_MOD_DISP_GAMMA,
234 	[DDP_COMPONENT_OVL0] = MT8167_MUTEX_MOD_DISP_OVL0,
235 	[DDP_COMPONENT_OVL1] = MT8167_MUTEX_MOD_DISP_OVL1,
236 	[DDP_COMPONENT_PWM0] = MT8167_MUTEX_MOD_DISP_PWM,
237 	[DDP_COMPONENT_RDMA0] = MT8167_MUTEX_MOD_DISP_RDMA0,
238 	[DDP_COMPONENT_RDMA1] = MT8167_MUTEX_MOD_DISP_RDMA1,
239 	[DDP_COMPONENT_UFOE] = MT8167_MUTEX_MOD_DISP_UFOE,
240 	[DDP_COMPONENT_WDMA0] = MT8167_MUTEX_MOD_DISP_WDMA0,
241 };
242 
243 static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
244 	[DDP_COMPONENT_AAL0] = MT8173_MUTEX_MOD_DISP_AAL,
245 	[DDP_COMPONENT_COLOR0] = MT8173_MUTEX_MOD_DISP_COLOR0,
246 	[DDP_COMPONENT_COLOR1] = MT8173_MUTEX_MOD_DISP_COLOR1,
247 	[DDP_COMPONENT_GAMMA] = MT8173_MUTEX_MOD_DISP_GAMMA,
248 	[DDP_COMPONENT_OD0] = MT8173_MUTEX_MOD_DISP_OD,
249 	[DDP_COMPONENT_OVL0] = MT8173_MUTEX_MOD_DISP_OVL0,
250 	[DDP_COMPONENT_OVL1] = MT8173_MUTEX_MOD_DISP_OVL1,
251 	[DDP_COMPONENT_PWM0] = MT8173_MUTEX_MOD_DISP_PWM0,
252 	[DDP_COMPONENT_PWM1] = MT8173_MUTEX_MOD_DISP_PWM1,
253 	[DDP_COMPONENT_RDMA0] = MT8173_MUTEX_MOD_DISP_RDMA0,
254 	[DDP_COMPONENT_RDMA1] = MT8173_MUTEX_MOD_DISP_RDMA1,
255 	[DDP_COMPONENT_RDMA2] = MT8173_MUTEX_MOD_DISP_RDMA2,
256 	[DDP_COMPONENT_UFOE] = MT8173_MUTEX_MOD_DISP_UFOE,
257 	[DDP_COMPONENT_WDMA0] = MT8173_MUTEX_MOD_DISP_WDMA0,
258 	[DDP_COMPONENT_WDMA1] = MT8173_MUTEX_MOD_DISP_WDMA1,
259 };
260 
261 static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
262 	[DDP_COMPONENT_AAL0] = MT8183_MUTEX_MOD_DISP_AAL0,
263 	[DDP_COMPONENT_CCORR] = MT8183_MUTEX_MOD_DISP_CCORR0,
264 	[DDP_COMPONENT_COLOR0] = MT8183_MUTEX_MOD_DISP_COLOR0,
265 	[DDP_COMPONENT_DITHER0] = MT8183_MUTEX_MOD_DISP_DITHER0,
266 	[DDP_COMPONENT_GAMMA] = MT8183_MUTEX_MOD_DISP_GAMMA0,
267 	[DDP_COMPONENT_OVL0] = MT8183_MUTEX_MOD_DISP_OVL0,
268 	[DDP_COMPONENT_OVL_2L0] = MT8183_MUTEX_MOD_DISP_OVL0_2L,
269 	[DDP_COMPONENT_OVL_2L1] = MT8183_MUTEX_MOD_DISP_OVL1_2L,
270 	[DDP_COMPONENT_RDMA0] = MT8183_MUTEX_MOD_DISP_RDMA0,
271 	[DDP_COMPONENT_RDMA1] = MT8183_MUTEX_MOD_DISP_RDMA1,
272 	[DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0,
273 };
274 
275 static const unsigned int mt8186_mutex_mod[DDP_COMPONENT_ID_MAX] = {
276 	[DDP_COMPONENT_AAL0] = MT8186_MUTEX_MOD_DISP_AAL0,
277 	[DDP_COMPONENT_CCORR] = MT8186_MUTEX_MOD_DISP_CCORR0,
278 	[DDP_COMPONENT_COLOR0] = MT8186_MUTEX_MOD_DISP_COLOR0,
279 	[DDP_COMPONENT_DITHER0] = MT8186_MUTEX_MOD_DISP_DITHER0,
280 	[DDP_COMPONENT_GAMMA] = MT8186_MUTEX_MOD_DISP_GAMMA0,
281 	[DDP_COMPONENT_OVL0] = MT8186_MUTEX_MOD_DISP_OVL0,
282 	[DDP_COMPONENT_OVL_2L0] = MT8186_MUTEX_MOD_DISP_OVL0_2L,
283 	[DDP_COMPONENT_POSTMASK0] = MT8186_MUTEX_MOD_DISP_POSTMASK0,
284 	[DDP_COMPONENT_RDMA0] = MT8186_MUTEX_MOD_DISP_RDMA0,
285 	[DDP_COMPONENT_RDMA1] = MT8186_MUTEX_MOD_DISP_RDMA1,
286 };
287 
288 static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = {
289 	[DDP_COMPONENT_AAL0] = MT8192_MUTEX_MOD_DISP_AAL0,
290 	[DDP_COMPONENT_CCORR] = MT8192_MUTEX_MOD_DISP_CCORR0,
291 	[DDP_COMPONENT_COLOR0] = MT8192_MUTEX_MOD_DISP_COLOR0,
292 	[DDP_COMPONENT_DITHER0] = MT8192_MUTEX_MOD_DISP_DITHER0,
293 	[DDP_COMPONENT_GAMMA] = MT8192_MUTEX_MOD_DISP_GAMMA0,
294 	[DDP_COMPONENT_POSTMASK0] = MT8192_MUTEX_MOD_DISP_POSTMASK0,
295 	[DDP_COMPONENT_OVL0] = MT8192_MUTEX_MOD_DISP_OVL0,
296 	[DDP_COMPONENT_OVL_2L0] = MT8192_MUTEX_MOD_DISP_OVL0_2L,
297 	[DDP_COMPONENT_OVL_2L2] = MT8192_MUTEX_MOD_DISP_OVL2_2L,
298 	[DDP_COMPONENT_RDMA0] = MT8192_MUTEX_MOD_DISP_RDMA0,
299 	[DDP_COMPONENT_RDMA4] = MT8192_MUTEX_MOD_DISP_RDMA4,
300 };
301 
302 static const unsigned int mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
303 	[DDP_COMPONENT_OVL0] = MT8195_MUTEX_MOD_DISP_OVL0,
304 	[DDP_COMPONENT_WDMA0] = MT8195_MUTEX_MOD_DISP_WDMA0,
305 	[DDP_COMPONENT_RDMA0] = MT8195_MUTEX_MOD_DISP_RDMA0,
306 	[DDP_COMPONENT_COLOR0] = MT8195_MUTEX_MOD_DISP_COLOR0,
307 	[DDP_COMPONENT_CCORR] = MT8195_MUTEX_MOD_DISP_CCORR0,
308 	[DDP_COMPONENT_AAL0] = MT8195_MUTEX_MOD_DISP_AAL0,
309 	[DDP_COMPONENT_GAMMA] = MT8195_MUTEX_MOD_DISP_GAMMA0,
310 	[DDP_COMPONENT_DITHER0] = MT8195_MUTEX_MOD_DISP_DITHER0,
311 	[DDP_COMPONENT_MERGE0] = MT8195_MUTEX_MOD_DISP_VPP_MERGE,
312 	[DDP_COMPONENT_DSC0] = MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0,
313 	[DDP_COMPONENT_DSI0] = MT8195_MUTEX_MOD_DISP_DSI0,
314 	[DDP_COMPONENT_PWM0] = MT8195_MUTEX_MOD_DISP_PWM0,
315 	[DDP_COMPONENT_DP_INTF0] = MT8195_MUTEX_MOD_DISP_DP_INTF0,
316 };
317 
318 static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = {
319 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
320 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
321 	[MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1,
322 	[MUTEX_SOF_DPI0] = MUTEX_SOF_DPI0,
323 	[MUTEX_SOF_DPI1] = MUTEX_SOF_DPI1,
324 	[MUTEX_SOF_DSI2] = MUTEX_SOF_DSI2,
325 	[MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3,
326 };
327 
328 static const unsigned int mt8167_mutex_sof[DDP_MUTEX_SOF_MAX] = {
329 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
330 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
331 	[MUTEX_SOF_DPI0] = MT8167_MUTEX_SOF_DPI0,
332 	[MUTEX_SOF_DPI1] = MT8167_MUTEX_SOF_DPI1,
333 };
334 
335 /* Add EOF setting so overlay hardware can receive frame done irq */
336 static const unsigned int mt8183_mutex_sof[DDP_MUTEX_SOF_MAX] = {
337 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
338 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0 | MT8183_MUTEX_EOF_DSI0,
339 	[MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0,
340 };
341 
342 static const unsigned int mt8186_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
343 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
344 	[MUTEX_SOF_DSI0] = MT8186_MUTEX_SOF_DSI0 | MT8186_MUTEX_EOF_DSI0,
345 	[MUTEX_SOF_DPI0] = MT8186_MUTEX_SOF_DPI0 | MT8186_MUTEX_EOF_DPI0,
346 };
347 
348 /*
349  * To support refresh mode(video mode), DISP_REG_MUTEX_SOF should
350  * select the EOF source and configure the EOF plus timing from the
351  * module that provides the timing signal.
352  * So that MUTEX can not only send a STREAM_DONE event to GCE
353  * but also detect the error at end of frame(EAEOF) when EOF signal
354  * arrives.
355  */
356 static const unsigned int mt8195_mutex_sof[DDP_MUTEX_SOF_MAX] = {
357 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
358 	[MUTEX_SOF_DSI0] = MT8195_MUTEX_SOF_DSI0 | MT8195_MUTEX_EOF_DSI0,
359 	[MUTEX_SOF_DSI1] = MT8195_MUTEX_SOF_DSI1 | MT8195_MUTEX_EOF_DSI1,
360 	[MUTEX_SOF_DPI0] = MT8195_MUTEX_SOF_DPI0 | MT8195_MUTEX_EOF_DPI0,
361 	[MUTEX_SOF_DPI1] = MT8195_MUTEX_SOF_DPI1 | MT8195_MUTEX_EOF_DPI1,
362 	[MUTEX_SOF_DP_INTF0] =
363 		MT8195_MUTEX_SOF_DP_INTF0 | MT8195_MUTEX_EOF_DP_INTF0,
364 	[MUTEX_SOF_DP_INTF1] =
365 		MT8195_MUTEX_SOF_DP_INTF1 | MT8195_MUTEX_EOF_DP_INTF1,
366 };
367 
368 static const struct mtk_mutex_data mt2701_mutex_driver_data = {
369 	.mutex_mod = mt2701_mutex_mod,
370 	.mutex_sof = mt2712_mutex_sof,
371 	.mutex_mod_reg = MT2701_MUTEX0_MOD0,
372 	.mutex_sof_reg = MT2701_MUTEX0_SOF0,
373 };
374 
375 static const struct mtk_mutex_data mt2712_mutex_driver_data = {
376 	.mutex_mod = mt2712_mutex_mod,
377 	.mutex_sof = mt2712_mutex_sof,
378 	.mutex_mod_reg = MT2701_MUTEX0_MOD0,
379 	.mutex_sof_reg = MT2701_MUTEX0_SOF0,
380 };
381 
382 static const struct mtk_mutex_data mt8167_mutex_driver_data = {
383 	.mutex_mod = mt8167_mutex_mod,
384 	.mutex_sof = mt8167_mutex_sof,
385 	.mutex_mod_reg = MT2701_MUTEX0_MOD0,
386 	.mutex_sof_reg = MT2701_MUTEX0_SOF0,
387 	.no_clk = true,
388 };
389 
390 static const struct mtk_mutex_data mt8173_mutex_driver_data = {
391 	.mutex_mod = mt8173_mutex_mod,
392 	.mutex_sof = mt2712_mutex_sof,
393 	.mutex_mod_reg = MT2701_MUTEX0_MOD0,
394 	.mutex_sof_reg = MT2701_MUTEX0_SOF0,
395 };
396 
397 static const struct mtk_mutex_data mt8183_mutex_driver_data = {
398 	.mutex_mod = mt8183_mutex_mod,
399 	.mutex_sof = mt8183_mutex_sof,
400 	.mutex_mod_reg = MT8183_MUTEX0_MOD0,
401 	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
402 	.no_clk = true,
403 };
404 
405 static const struct mtk_mutex_data mt8186_mutex_driver_data = {
406 	.mutex_mod = mt8186_mutex_mod,
407 	.mutex_sof = mt8186_mutex_sof,
408 	.mutex_mod_reg = MT8183_MUTEX0_MOD0,
409 	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
410 };
411 
412 static const struct mtk_mutex_data mt8192_mutex_driver_data = {
413 	.mutex_mod = mt8192_mutex_mod,
414 	.mutex_sof = mt8183_mutex_sof,
415 	.mutex_mod_reg = MT8183_MUTEX0_MOD0,
416 	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
417 };
418 
419 static const struct mtk_mutex_data mt8195_mutex_driver_data = {
420 	.mutex_mod = mt8195_mutex_mod,
421 	.mutex_sof = mt8195_mutex_sof,
422 	.mutex_mod_reg = MT8183_MUTEX0_MOD0,
423 	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
424 };
425 
426 struct mtk_mutex *mtk_mutex_get(struct device *dev)
427 {
428 	struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev);
429 	int i;
430 
431 	for (i = 0; i < 10; i++)
432 		if (!mtx->mutex[i].claimed) {
433 			mtx->mutex[i].claimed = true;
434 			return &mtx->mutex[i];
435 		}
436 
437 	return ERR_PTR(-EBUSY);
438 }
439 EXPORT_SYMBOL_GPL(mtk_mutex_get);
440 
441 void mtk_mutex_put(struct mtk_mutex *mutex)
442 {
443 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
444 						 mutex[mutex->id]);
445 
446 	WARN_ON(&mtx->mutex[mutex->id] != mutex);
447 
448 	mutex->claimed = false;
449 }
450 EXPORT_SYMBOL_GPL(mtk_mutex_put);
451 
452 int mtk_mutex_prepare(struct mtk_mutex *mutex)
453 {
454 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
455 						 mutex[mutex->id]);
456 	return clk_prepare_enable(mtx->clk);
457 }
458 EXPORT_SYMBOL_GPL(mtk_mutex_prepare);
459 
460 void mtk_mutex_unprepare(struct mtk_mutex *mutex)
461 {
462 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
463 						 mutex[mutex->id]);
464 	clk_disable_unprepare(mtx->clk);
465 }
466 EXPORT_SYMBOL_GPL(mtk_mutex_unprepare);
467 
468 void mtk_mutex_add_comp(struct mtk_mutex *mutex,
469 			enum mtk_ddp_comp_id id)
470 {
471 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
472 						 mutex[mutex->id]);
473 	unsigned int reg;
474 	unsigned int sof_id;
475 	unsigned int offset;
476 
477 	WARN_ON(&mtx->mutex[mutex->id] != mutex);
478 
479 	switch (id) {
480 	case DDP_COMPONENT_DSI0:
481 		sof_id = MUTEX_SOF_DSI0;
482 		break;
483 	case DDP_COMPONENT_DSI1:
484 		sof_id = MUTEX_SOF_DSI0;
485 		break;
486 	case DDP_COMPONENT_DSI2:
487 		sof_id = MUTEX_SOF_DSI2;
488 		break;
489 	case DDP_COMPONENT_DSI3:
490 		sof_id = MUTEX_SOF_DSI3;
491 		break;
492 	case DDP_COMPONENT_DPI0:
493 		sof_id = MUTEX_SOF_DPI0;
494 		break;
495 	case DDP_COMPONENT_DPI1:
496 		sof_id = MUTEX_SOF_DPI1;
497 		break;
498 	case DDP_COMPONENT_DP_INTF0:
499 		sof_id = MUTEX_SOF_DP_INTF0;
500 		break;
501 	default:
502 		if (mtx->data->mutex_mod[id] < 32) {
503 			offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
504 						    mutex->id);
505 			reg = readl_relaxed(mtx->regs + offset);
506 			reg |= 1 << mtx->data->mutex_mod[id];
507 			writel_relaxed(reg, mtx->regs + offset);
508 		} else {
509 			offset = DISP_REG_MUTEX_MOD2(mutex->id);
510 			reg = readl_relaxed(mtx->regs + offset);
511 			reg |= 1 << (mtx->data->mutex_mod[id] - 32);
512 			writel_relaxed(reg, mtx->regs + offset);
513 		}
514 		return;
515 	}
516 
517 	writel_relaxed(mtx->data->mutex_sof[sof_id],
518 		       mtx->regs +
519 		       DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg, mutex->id));
520 }
521 EXPORT_SYMBOL_GPL(mtk_mutex_add_comp);
522 
523 void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
524 			   enum mtk_ddp_comp_id id)
525 {
526 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
527 						 mutex[mutex->id]);
528 	unsigned int reg;
529 	unsigned int offset;
530 
531 	WARN_ON(&mtx->mutex[mutex->id] != mutex);
532 
533 	switch (id) {
534 	case DDP_COMPONENT_DSI0:
535 	case DDP_COMPONENT_DSI1:
536 	case DDP_COMPONENT_DSI2:
537 	case DDP_COMPONENT_DSI3:
538 	case DDP_COMPONENT_DPI0:
539 	case DDP_COMPONENT_DPI1:
540 	case DDP_COMPONENT_DP_INTF0:
541 		writel_relaxed(MUTEX_SOF_SINGLE_MODE,
542 			       mtx->regs +
543 			       DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg,
544 						  mutex->id));
545 		break;
546 	default:
547 		if (mtx->data->mutex_mod[id] < 32) {
548 			offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
549 						    mutex->id);
550 			reg = readl_relaxed(mtx->regs + offset);
551 			reg &= ~(1 << mtx->data->mutex_mod[id]);
552 			writel_relaxed(reg, mtx->regs + offset);
553 		} else {
554 			offset = DISP_REG_MUTEX_MOD2(mutex->id);
555 			reg = readl_relaxed(mtx->regs + offset);
556 			reg &= ~(1 << (mtx->data->mutex_mod[id] - 32));
557 			writel_relaxed(reg, mtx->regs + offset);
558 		}
559 		break;
560 	}
561 }
562 EXPORT_SYMBOL_GPL(mtk_mutex_remove_comp);
563 
564 void mtk_mutex_enable(struct mtk_mutex *mutex)
565 {
566 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
567 						 mutex[mutex->id]);
568 
569 	WARN_ON(&mtx->mutex[mutex->id] != mutex);
570 
571 	writel(1, mtx->regs + DISP_REG_MUTEX_EN(mutex->id));
572 }
573 EXPORT_SYMBOL_GPL(mtk_mutex_enable);
574 
575 void mtk_mutex_disable(struct mtk_mutex *mutex)
576 {
577 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
578 						 mutex[mutex->id]);
579 
580 	WARN_ON(&mtx->mutex[mutex->id] != mutex);
581 
582 	writel(0, mtx->regs + DISP_REG_MUTEX_EN(mutex->id));
583 }
584 EXPORT_SYMBOL_GPL(mtk_mutex_disable);
585 
586 void mtk_mutex_acquire(struct mtk_mutex *mutex)
587 {
588 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
589 						 mutex[mutex->id]);
590 	u32 tmp;
591 
592 	writel(1, mtx->regs + DISP_REG_MUTEX_EN(mutex->id));
593 	writel(1, mtx->regs + DISP_REG_MUTEX(mutex->id));
594 	if (readl_poll_timeout_atomic(mtx->regs + DISP_REG_MUTEX(mutex->id),
595 				      tmp, tmp & INT_MUTEX, 1, 10000))
596 		pr_err("could not acquire mutex %d\n", mutex->id);
597 }
598 EXPORT_SYMBOL_GPL(mtk_mutex_acquire);
599 
600 void mtk_mutex_release(struct mtk_mutex *mutex)
601 {
602 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
603 						 mutex[mutex->id]);
604 
605 	writel(0, mtx->regs + DISP_REG_MUTEX(mutex->id));
606 }
607 EXPORT_SYMBOL_GPL(mtk_mutex_release);
608 
609 static int mtk_mutex_probe(struct platform_device *pdev)
610 {
611 	struct device *dev = &pdev->dev;
612 	struct mtk_mutex_ctx *mtx;
613 	struct resource *regs;
614 	int i;
615 
616 	mtx = devm_kzalloc(dev, sizeof(*mtx), GFP_KERNEL);
617 	if (!mtx)
618 		return -ENOMEM;
619 
620 	for (i = 0; i < 10; i++)
621 		mtx->mutex[i].id = i;
622 
623 	mtx->data = of_device_get_match_data(dev);
624 
625 	if (!mtx->data->no_clk) {
626 		mtx->clk = devm_clk_get(dev, NULL);
627 		if (IS_ERR(mtx->clk)) {
628 			if (PTR_ERR(mtx->clk) != -EPROBE_DEFER)
629 				dev_err(dev, "Failed to get clock\n");
630 			return PTR_ERR(mtx->clk);
631 		}
632 	}
633 
634 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
635 	mtx->regs = devm_ioremap_resource(dev, regs);
636 	if (IS_ERR(mtx->regs)) {
637 		dev_err(dev, "Failed to map mutex registers\n");
638 		return PTR_ERR(mtx->regs);
639 	}
640 
641 	platform_set_drvdata(pdev, mtx);
642 
643 	return 0;
644 }
645 
646 static int mtk_mutex_remove(struct platform_device *pdev)
647 {
648 	return 0;
649 }
650 
651 static const struct of_device_id mutex_driver_dt_match[] = {
652 	{ .compatible = "mediatek,mt2701-disp-mutex",
653 	  .data = &mt2701_mutex_driver_data},
654 	{ .compatible = "mediatek,mt2712-disp-mutex",
655 	  .data = &mt2712_mutex_driver_data},
656 	{ .compatible = "mediatek,mt8167-disp-mutex",
657 	  .data = &mt8167_mutex_driver_data},
658 	{ .compatible = "mediatek,mt8173-disp-mutex",
659 	  .data = &mt8173_mutex_driver_data},
660 	{ .compatible = "mediatek,mt8183-disp-mutex",
661 	  .data = &mt8183_mutex_driver_data},
662 	{ .compatible = "mediatek,mt8186-disp-mutex",
663 	  .data = &mt8186_mutex_driver_data},
664 	{ .compatible = "mediatek,mt8192-disp-mutex",
665 	  .data = &mt8192_mutex_driver_data},
666 	{ .compatible = "mediatek,mt8195-disp-mutex",
667 	  .data = &mt8195_mutex_driver_data},
668 	{},
669 };
670 MODULE_DEVICE_TABLE(of, mutex_driver_dt_match);
671 
672 static struct platform_driver mtk_mutex_driver = {
673 	.probe		= mtk_mutex_probe,
674 	.remove		= mtk_mutex_remove,
675 	.driver		= {
676 		.name	= "mediatek-mutex",
677 		.owner	= THIS_MODULE,
678 		.of_match_table = mutex_driver_dt_match,
679 	},
680 };
681 
682 builtin_platform_driver(mtk_mutex_driver);
683