xref: /openbmc/linux/drivers/soc/mediatek/mtk-mutex.c (revision 47010c04)
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 MT2712_MUTEX_MOD_DISP_PWM2		10
100 #define MT2712_MUTEX_MOD_DISP_OVL0		11
101 #define MT2712_MUTEX_MOD_DISP_OVL1		12
102 #define MT2712_MUTEX_MOD_DISP_RDMA0		13
103 #define MT2712_MUTEX_MOD_DISP_RDMA1		14
104 #define MT2712_MUTEX_MOD_DISP_RDMA2		15
105 #define MT2712_MUTEX_MOD_DISP_WDMA0		16
106 #define MT2712_MUTEX_MOD_DISP_WDMA1		17
107 #define MT2712_MUTEX_MOD_DISP_COLOR0		18
108 #define MT2712_MUTEX_MOD_DISP_COLOR1		19
109 #define MT2712_MUTEX_MOD_DISP_AAL0		20
110 #define MT2712_MUTEX_MOD_DISP_UFOE		22
111 #define MT2712_MUTEX_MOD_DISP_PWM0		23
112 #define MT2712_MUTEX_MOD_DISP_PWM1		24
113 #define MT2712_MUTEX_MOD_DISP_OD0		25
114 #define MT2712_MUTEX_MOD2_DISP_AAL1		33
115 #define MT2712_MUTEX_MOD2_DISP_OD1		34
116 
117 #define MT2701_MUTEX_MOD_DISP_OVL		3
118 #define MT2701_MUTEX_MOD_DISP_WDMA		6
119 #define MT2701_MUTEX_MOD_DISP_COLOR		7
120 #define MT2701_MUTEX_MOD_DISP_BLS		9
121 #define MT2701_MUTEX_MOD_DISP_RDMA0		10
122 #define MT2701_MUTEX_MOD_DISP_RDMA1		12
123 
124 #define MT2712_MUTEX_SOF_SINGLE_MODE		0
125 #define MT2712_MUTEX_SOF_DSI0			1
126 #define MT2712_MUTEX_SOF_DSI1			2
127 #define MT2712_MUTEX_SOF_DPI0			3
128 #define MT2712_MUTEX_SOF_DPI1			4
129 #define MT2712_MUTEX_SOF_DSI2			5
130 #define MT2712_MUTEX_SOF_DSI3			6
131 #define MT8167_MUTEX_SOF_DPI0			2
132 #define MT8167_MUTEX_SOF_DPI1			3
133 #define MT8183_MUTEX_SOF_DSI0			1
134 #define MT8183_MUTEX_SOF_DPI0			2
135 
136 #define MT8183_MUTEX_EOF_DSI0			(MT8183_MUTEX_SOF_DSI0 << 6)
137 #define MT8183_MUTEX_EOF_DPI0			(MT8183_MUTEX_SOF_DPI0 << 6)
138 
139 struct mtk_mutex {
140 	int id;
141 	bool claimed;
142 };
143 
144 enum mtk_mutex_sof_id {
145 	MUTEX_SOF_SINGLE_MODE,
146 	MUTEX_SOF_DSI0,
147 	MUTEX_SOF_DSI1,
148 	MUTEX_SOF_DPI0,
149 	MUTEX_SOF_DPI1,
150 	MUTEX_SOF_DSI2,
151 	MUTEX_SOF_DSI3,
152 };
153 
154 struct mtk_mutex_data {
155 	const unsigned int *mutex_mod;
156 	const unsigned int *mutex_sof;
157 	const unsigned int mutex_mod_reg;
158 	const unsigned int mutex_sof_reg;
159 	const bool no_clk;
160 };
161 
162 struct mtk_mutex_ctx {
163 	struct device			*dev;
164 	struct clk			*clk;
165 	void __iomem			*regs;
166 	struct mtk_mutex		mutex[10];
167 	const struct mtk_mutex_data	*data;
168 };
169 
170 static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
171 	[DDP_COMPONENT_BLS] = MT2701_MUTEX_MOD_DISP_BLS,
172 	[DDP_COMPONENT_COLOR0] = MT2701_MUTEX_MOD_DISP_COLOR,
173 	[DDP_COMPONENT_OVL0] = MT2701_MUTEX_MOD_DISP_OVL,
174 	[DDP_COMPONENT_RDMA0] = MT2701_MUTEX_MOD_DISP_RDMA0,
175 	[DDP_COMPONENT_RDMA1] = MT2701_MUTEX_MOD_DISP_RDMA1,
176 	[DDP_COMPONENT_WDMA0] = MT2701_MUTEX_MOD_DISP_WDMA,
177 };
178 
179 static const unsigned int mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = {
180 	[DDP_COMPONENT_AAL0] = MT2712_MUTEX_MOD_DISP_AAL0,
181 	[DDP_COMPONENT_AAL1] = MT2712_MUTEX_MOD2_DISP_AAL1,
182 	[DDP_COMPONENT_COLOR0] = MT2712_MUTEX_MOD_DISP_COLOR0,
183 	[DDP_COMPONENT_COLOR1] = MT2712_MUTEX_MOD_DISP_COLOR1,
184 	[DDP_COMPONENT_OD0] = MT2712_MUTEX_MOD_DISP_OD0,
185 	[DDP_COMPONENT_OD1] = MT2712_MUTEX_MOD2_DISP_OD1,
186 	[DDP_COMPONENT_OVL0] = MT2712_MUTEX_MOD_DISP_OVL0,
187 	[DDP_COMPONENT_OVL1] = MT2712_MUTEX_MOD_DISP_OVL1,
188 	[DDP_COMPONENT_PWM0] = MT2712_MUTEX_MOD_DISP_PWM0,
189 	[DDP_COMPONENT_PWM1] = MT2712_MUTEX_MOD_DISP_PWM1,
190 	[DDP_COMPONENT_PWM2] = MT2712_MUTEX_MOD_DISP_PWM2,
191 	[DDP_COMPONENT_RDMA0] = MT2712_MUTEX_MOD_DISP_RDMA0,
192 	[DDP_COMPONENT_RDMA1] = MT2712_MUTEX_MOD_DISP_RDMA1,
193 	[DDP_COMPONENT_RDMA2] = MT2712_MUTEX_MOD_DISP_RDMA2,
194 	[DDP_COMPONENT_UFOE] = MT2712_MUTEX_MOD_DISP_UFOE,
195 	[DDP_COMPONENT_WDMA0] = MT2712_MUTEX_MOD_DISP_WDMA0,
196 	[DDP_COMPONENT_WDMA1] = MT2712_MUTEX_MOD_DISP_WDMA1,
197 };
198 
199 static const unsigned int mt8167_mutex_mod[DDP_COMPONENT_ID_MAX] = {
200 	[DDP_COMPONENT_AAL0] = MT8167_MUTEX_MOD_DISP_AAL,
201 	[DDP_COMPONENT_CCORR] = MT8167_MUTEX_MOD_DISP_CCORR,
202 	[DDP_COMPONENT_COLOR0] = MT8167_MUTEX_MOD_DISP_COLOR,
203 	[DDP_COMPONENT_DITHER] = MT8167_MUTEX_MOD_DISP_DITHER,
204 	[DDP_COMPONENT_GAMMA] = MT8167_MUTEX_MOD_DISP_GAMMA,
205 	[DDP_COMPONENT_OVL0] = MT8167_MUTEX_MOD_DISP_OVL0,
206 	[DDP_COMPONENT_OVL1] = MT8167_MUTEX_MOD_DISP_OVL1,
207 	[DDP_COMPONENT_PWM0] = MT8167_MUTEX_MOD_DISP_PWM,
208 	[DDP_COMPONENT_RDMA0] = MT8167_MUTEX_MOD_DISP_RDMA0,
209 	[DDP_COMPONENT_RDMA1] = MT8167_MUTEX_MOD_DISP_RDMA1,
210 	[DDP_COMPONENT_UFOE] = MT8167_MUTEX_MOD_DISP_UFOE,
211 	[DDP_COMPONENT_WDMA0] = MT8167_MUTEX_MOD_DISP_WDMA0,
212 };
213 
214 static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
215 	[DDP_COMPONENT_AAL0] = MT8173_MUTEX_MOD_DISP_AAL,
216 	[DDP_COMPONENT_COLOR0] = MT8173_MUTEX_MOD_DISP_COLOR0,
217 	[DDP_COMPONENT_COLOR1] = MT8173_MUTEX_MOD_DISP_COLOR1,
218 	[DDP_COMPONENT_GAMMA] = MT8173_MUTEX_MOD_DISP_GAMMA,
219 	[DDP_COMPONENT_OD0] = MT8173_MUTEX_MOD_DISP_OD,
220 	[DDP_COMPONENT_OVL0] = MT8173_MUTEX_MOD_DISP_OVL0,
221 	[DDP_COMPONENT_OVL1] = MT8173_MUTEX_MOD_DISP_OVL1,
222 	[DDP_COMPONENT_PWM0] = MT8173_MUTEX_MOD_DISP_PWM0,
223 	[DDP_COMPONENT_PWM1] = MT8173_MUTEX_MOD_DISP_PWM1,
224 	[DDP_COMPONENT_RDMA0] = MT8173_MUTEX_MOD_DISP_RDMA0,
225 	[DDP_COMPONENT_RDMA1] = MT8173_MUTEX_MOD_DISP_RDMA1,
226 	[DDP_COMPONENT_RDMA2] = MT8173_MUTEX_MOD_DISP_RDMA2,
227 	[DDP_COMPONENT_UFOE] = MT8173_MUTEX_MOD_DISP_UFOE,
228 	[DDP_COMPONENT_WDMA0] = MT8173_MUTEX_MOD_DISP_WDMA0,
229 	[DDP_COMPONENT_WDMA1] = MT8173_MUTEX_MOD_DISP_WDMA1,
230 };
231 
232 static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
233 	[DDP_COMPONENT_AAL0] = MT8183_MUTEX_MOD_DISP_AAL0,
234 	[DDP_COMPONENT_CCORR] = MT8183_MUTEX_MOD_DISP_CCORR0,
235 	[DDP_COMPONENT_COLOR0] = MT8183_MUTEX_MOD_DISP_COLOR0,
236 	[DDP_COMPONENT_DITHER] = MT8183_MUTEX_MOD_DISP_DITHER0,
237 	[DDP_COMPONENT_GAMMA] = MT8183_MUTEX_MOD_DISP_GAMMA0,
238 	[DDP_COMPONENT_OVL0] = MT8183_MUTEX_MOD_DISP_OVL0,
239 	[DDP_COMPONENT_OVL_2L0] = MT8183_MUTEX_MOD_DISP_OVL0_2L,
240 	[DDP_COMPONENT_OVL_2L1] = MT8183_MUTEX_MOD_DISP_OVL1_2L,
241 	[DDP_COMPONENT_RDMA0] = MT8183_MUTEX_MOD_DISP_RDMA0,
242 	[DDP_COMPONENT_RDMA1] = MT8183_MUTEX_MOD_DISP_RDMA1,
243 	[DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0,
244 };
245 
246 static const unsigned int mt8186_mutex_mod[DDP_COMPONENT_ID_MAX] = {
247 	[DDP_COMPONENT_AAL0] = MT8186_MUTEX_MOD_DISP_AAL0,
248 	[DDP_COMPONENT_CCORR] = MT8186_MUTEX_MOD_DISP_CCORR0,
249 	[DDP_COMPONENT_COLOR0] = MT8186_MUTEX_MOD_DISP_COLOR0,
250 	[DDP_COMPONENT_DITHER] = MT8186_MUTEX_MOD_DISP_DITHER0,
251 	[DDP_COMPONENT_GAMMA] = MT8186_MUTEX_MOD_DISP_GAMMA0,
252 	[DDP_COMPONENT_OVL0] = MT8186_MUTEX_MOD_DISP_OVL0,
253 	[DDP_COMPONENT_OVL_2L0] = MT8186_MUTEX_MOD_DISP_OVL0_2L,
254 	[DDP_COMPONENT_POSTMASK0] = MT8186_MUTEX_MOD_DISP_POSTMASK0,
255 	[DDP_COMPONENT_RDMA0] = MT8186_MUTEX_MOD_DISP_RDMA0,
256 	[DDP_COMPONENT_RDMA1] = MT8186_MUTEX_MOD_DISP_RDMA1,
257 };
258 
259 static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = {
260 	[DDP_COMPONENT_AAL0] = MT8192_MUTEX_MOD_DISP_AAL0,
261 	[DDP_COMPONENT_CCORR] = MT8192_MUTEX_MOD_DISP_CCORR0,
262 	[DDP_COMPONENT_COLOR0] = MT8192_MUTEX_MOD_DISP_COLOR0,
263 	[DDP_COMPONENT_DITHER] = MT8192_MUTEX_MOD_DISP_DITHER0,
264 	[DDP_COMPONENT_GAMMA] = MT8192_MUTEX_MOD_DISP_GAMMA0,
265 	[DDP_COMPONENT_POSTMASK0] = MT8192_MUTEX_MOD_DISP_POSTMASK0,
266 	[DDP_COMPONENT_OVL0] = MT8192_MUTEX_MOD_DISP_OVL0,
267 	[DDP_COMPONENT_OVL_2L0] = MT8192_MUTEX_MOD_DISP_OVL0_2L,
268 	[DDP_COMPONENT_OVL_2L2] = MT8192_MUTEX_MOD_DISP_OVL2_2L,
269 	[DDP_COMPONENT_RDMA0] = MT8192_MUTEX_MOD_DISP_RDMA0,
270 	[DDP_COMPONENT_RDMA4] = MT8192_MUTEX_MOD_DISP_RDMA4,
271 };
272 
273 static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
274 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
275 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
276 	[MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1,
277 	[MUTEX_SOF_DPI0] = MUTEX_SOF_DPI0,
278 	[MUTEX_SOF_DPI1] = MUTEX_SOF_DPI1,
279 	[MUTEX_SOF_DSI2] = MUTEX_SOF_DSI2,
280 	[MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3,
281 };
282 
283 static const unsigned int mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
284 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
285 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
286 	[MUTEX_SOF_DPI0] = MT8167_MUTEX_SOF_DPI0,
287 	[MUTEX_SOF_DPI1] = MT8167_MUTEX_SOF_DPI1,
288 };
289 
290 /* Add EOF setting so overlay hardware can receive frame done irq */
291 static const unsigned int mt8183_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
292 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
293 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0 | MT8183_MUTEX_EOF_DSI0,
294 	[MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0,
295 };
296 
297 static const unsigned int mt8186_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
298 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
299 	[MUTEX_SOF_DSI0] = MT8186_MUTEX_SOF_DSI0 | MT8186_MUTEX_EOF_DSI0,
300 	[MUTEX_SOF_DPI0] = MT8186_MUTEX_SOF_DPI0 | MT8186_MUTEX_EOF_DPI0,
301 };
302 
303 static const struct mtk_mutex_data mt2701_mutex_driver_data = {
304 	.mutex_mod = mt2701_mutex_mod,
305 	.mutex_sof = mt2712_mutex_sof,
306 	.mutex_mod_reg = MT2701_MUTEX0_MOD0,
307 	.mutex_sof_reg = MT2701_MUTEX0_SOF0,
308 };
309 
310 static const struct mtk_mutex_data mt2712_mutex_driver_data = {
311 	.mutex_mod = mt2712_mutex_mod,
312 	.mutex_sof = mt2712_mutex_sof,
313 	.mutex_mod_reg = MT2701_MUTEX0_MOD0,
314 	.mutex_sof_reg = MT2701_MUTEX0_SOF0,
315 };
316 
317 static const struct mtk_mutex_data mt8167_mutex_driver_data = {
318 	.mutex_mod = mt8167_mutex_mod,
319 	.mutex_sof = mt8167_mutex_sof,
320 	.mutex_mod_reg = MT2701_MUTEX0_MOD0,
321 	.mutex_sof_reg = MT2701_MUTEX0_SOF0,
322 	.no_clk = true,
323 };
324 
325 static const struct mtk_mutex_data mt8173_mutex_driver_data = {
326 	.mutex_mod = mt8173_mutex_mod,
327 	.mutex_sof = mt2712_mutex_sof,
328 	.mutex_mod_reg = MT2701_MUTEX0_MOD0,
329 	.mutex_sof_reg = MT2701_MUTEX0_SOF0,
330 };
331 
332 static const struct mtk_mutex_data mt8183_mutex_driver_data = {
333 	.mutex_mod = mt8183_mutex_mod,
334 	.mutex_sof = mt8183_mutex_sof,
335 	.mutex_mod_reg = MT8183_MUTEX0_MOD0,
336 	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
337 	.no_clk = true,
338 };
339 
340 static const struct mtk_mutex_data mt8186_mutex_driver_data = {
341 	.mutex_mod = mt8186_mutex_mod,
342 	.mutex_sof = mt8186_mutex_sof,
343 	.mutex_mod_reg = MT8183_MUTEX0_MOD0,
344 	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
345 };
346 
347 static const struct mtk_mutex_data mt8192_mutex_driver_data = {
348 	.mutex_mod = mt8192_mutex_mod,
349 	.mutex_sof = mt8183_mutex_sof,
350 	.mutex_mod_reg = MT8183_MUTEX0_MOD0,
351 	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
352 };
353 
354 struct mtk_mutex *mtk_mutex_get(struct device *dev)
355 {
356 	struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev);
357 	int i;
358 
359 	for (i = 0; i < 10; i++)
360 		if (!mtx->mutex[i].claimed) {
361 			mtx->mutex[i].claimed = true;
362 			return &mtx->mutex[i];
363 		}
364 
365 	return ERR_PTR(-EBUSY);
366 }
367 EXPORT_SYMBOL_GPL(mtk_mutex_get);
368 
369 void mtk_mutex_put(struct mtk_mutex *mutex)
370 {
371 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
372 						 mutex[mutex->id]);
373 
374 	WARN_ON(&mtx->mutex[mutex->id] != mutex);
375 
376 	mutex->claimed = false;
377 }
378 EXPORT_SYMBOL_GPL(mtk_mutex_put);
379 
380 int mtk_mutex_prepare(struct mtk_mutex *mutex)
381 {
382 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
383 						 mutex[mutex->id]);
384 	return clk_prepare_enable(mtx->clk);
385 }
386 EXPORT_SYMBOL_GPL(mtk_mutex_prepare);
387 
388 void mtk_mutex_unprepare(struct mtk_mutex *mutex)
389 {
390 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
391 						 mutex[mutex->id]);
392 	clk_disable_unprepare(mtx->clk);
393 }
394 EXPORT_SYMBOL_GPL(mtk_mutex_unprepare);
395 
396 void mtk_mutex_add_comp(struct mtk_mutex *mutex,
397 			enum mtk_ddp_comp_id id)
398 {
399 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
400 						 mutex[mutex->id]);
401 	unsigned int reg;
402 	unsigned int sof_id;
403 	unsigned int offset;
404 
405 	WARN_ON(&mtx->mutex[mutex->id] != mutex);
406 
407 	switch (id) {
408 	case DDP_COMPONENT_DSI0:
409 		sof_id = MUTEX_SOF_DSI0;
410 		break;
411 	case DDP_COMPONENT_DSI1:
412 		sof_id = MUTEX_SOF_DSI0;
413 		break;
414 	case DDP_COMPONENT_DSI2:
415 		sof_id = MUTEX_SOF_DSI2;
416 		break;
417 	case DDP_COMPONENT_DSI3:
418 		sof_id = MUTEX_SOF_DSI3;
419 		break;
420 	case DDP_COMPONENT_DPI0:
421 		sof_id = MUTEX_SOF_DPI0;
422 		break;
423 	case DDP_COMPONENT_DPI1:
424 		sof_id = MUTEX_SOF_DPI1;
425 		break;
426 	default:
427 		if (mtx->data->mutex_mod[id] < 32) {
428 			offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
429 						    mutex->id);
430 			reg = readl_relaxed(mtx->regs + offset);
431 			reg |= 1 << mtx->data->mutex_mod[id];
432 			writel_relaxed(reg, mtx->regs + offset);
433 		} else {
434 			offset = DISP_REG_MUTEX_MOD2(mutex->id);
435 			reg = readl_relaxed(mtx->regs + offset);
436 			reg |= 1 << (mtx->data->mutex_mod[id] - 32);
437 			writel_relaxed(reg, mtx->regs + offset);
438 		}
439 		return;
440 	}
441 
442 	writel_relaxed(mtx->data->mutex_sof[sof_id],
443 		       mtx->regs +
444 		       DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg, mutex->id));
445 }
446 EXPORT_SYMBOL_GPL(mtk_mutex_add_comp);
447 
448 void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
449 			   enum mtk_ddp_comp_id id)
450 {
451 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
452 						 mutex[mutex->id]);
453 	unsigned int reg;
454 	unsigned int offset;
455 
456 	WARN_ON(&mtx->mutex[mutex->id] != mutex);
457 
458 	switch (id) {
459 	case DDP_COMPONENT_DSI0:
460 	case DDP_COMPONENT_DSI1:
461 	case DDP_COMPONENT_DSI2:
462 	case DDP_COMPONENT_DSI3:
463 	case DDP_COMPONENT_DPI0:
464 	case DDP_COMPONENT_DPI1:
465 		writel_relaxed(MUTEX_SOF_SINGLE_MODE,
466 			       mtx->regs +
467 			       DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg,
468 						  mutex->id));
469 		break;
470 	default:
471 		if (mtx->data->mutex_mod[id] < 32) {
472 			offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
473 						    mutex->id);
474 			reg = readl_relaxed(mtx->regs + offset);
475 			reg &= ~(1 << mtx->data->mutex_mod[id]);
476 			writel_relaxed(reg, mtx->regs + offset);
477 		} else {
478 			offset = DISP_REG_MUTEX_MOD2(mutex->id);
479 			reg = readl_relaxed(mtx->regs + offset);
480 			reg &= ~(1 << (mtx->data->mutex_mod[id] - 32));
481 			writel_relaxed(reg, mtx->regs + offset);
482 		}
483 		break;
484 	}
485 }
486 EXPORT_SYMBOL_GPL(mtk_mutex_remove_comp);
487 
488 void mtk_mutex_enable(struct mtk_mutex *mutex)
489 {
490 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
491 						 mutex[mutex->id]);
492 
493 	WARN_ON(&mtx->mutex[mutex->id] != mutex);
494 
495 	writel(1, mtx->regs + DISP_REG_MUTEX_EN(mutex->id));
496 }
497 EXPORT_SYMBOL_GPL(mtk_mutex_enable);
498 
499 void mtk_mutex_disable(struct mtk_mutex *mutex)
500 {
501 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
502 						 mutex[mutex->id]);
503 
504 	WARN_ON(&mtx->mutex[mutex->id] != mutex);
505 
506 	writel(0, mtx->regs + DISP_REG_MUTEX_EN(mutex->id));
507 }
508 EXPORT_SYMBOL_GPL(mtk_mutex_disable);
509 
510 void mtk_mutex_acquire(struct mtk_mutex *mutex)
511 {
512 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
513 						 mutex[mutex->id]);
514 	u32 tmp;
515 
516 	writel(1, mtx->regs + DISP_REG_MUTEX_EN(mutex->id));
517 	writel(1, mtx->regs + DISP_REG_MUTEX(mutex->id));
518 	if (readl_poll_timeout_atomic(mtx->regs + DISP_REG_MUTEX(mutex->id),
519 				      tmp, tmp & INT_MUTEX, 1, 10000))
520 		pr_err("could not acquire mutex %d\n", mutex->id);
521 }
522 EXPORT_SYMBOL_GPL(mtk_mutex_acquire);
523 
524 void mtk_mutex_release(struct mtk_mutex *mutex)
525 {
526 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
527 						 mutex[mutex->id]);
528 
529 	writel(0, mtx->regs + DISP_REG_MUTEX(mutex->id));
530 }
531 EXPORT_SYMBOL_GPL(mtk_mutex_release);
532 
533 static int mtk_mutex_probe(struct platform_device *pdev)
534 {
535 	struct device *dev = &pdev->dev;
536 	struct mtk_mutex_ctx *mtx;
537 	struct resource *regs;
538 	int i;
539 
540 	mtx = devm_kzalloc(dev, sizeof(*mtx), GFP_KERNEL);
541 	if (!mtx)
542 		return -ENOMEM;
543 
544 	for (i = 0; i < 10; i++)
545 		mtx->mutex[i].id = i;
546 
547 	mtx->data = of_device_get_match_data(dev);
548 
549 	if (!mtx->data->no_clk) {
550 		mtx->clk = devm_clk_get(dev, NULL);
551 		if (IS_ERR(mtx->clk)) {
552 			if (PTR_ERR(mtx->clk) != -EPROBE_DEFER)
553 				dev_err(dev, "Failed to get clock\n");
554 			return PTR_ERR(mtx->clk);
555 		}
556 	}
557 
558 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
559 	mtx->regs = devm_ioremap_resource(dev, regs);
560 	if (IS_ERR(mtx->regs)) {
561 		dev_err(dev, "Failed to map mutex registers\n");
562 		return PTR_ERR(mtx->regs);
563 	}
564 
565 	platform_set_drvdata(pdev, mtx);
566 
567 	return 0;
568 }
569 
570 static int mtk_mutex_remove(struct platform_device *pdev)
571 {
572 	return 0;
573 }
574 
575 static const struct of_device_id mutex_driver_dt_match[] = {
576 	{ .compatible = "mediatek,mt2701-disp-mutex",
577 	  .data = &mt2701_mutex_driver_data},
578 	{ .compatible = "mediatek,mt2712-disp-mutex",
579 	  .data = &mt2712_mutex_driver_data},
580 	{ .compatible = "mediatek,mt8167-disp-mutex",
581 	  .data = &mt8167_mutex_driver_data},
582 	{ .compatible = "mediatek,mt8173-disp-mutex",
583 	  .data = &mt8173_mutex_driver_data},
584 	{ .compatible = "mediatek,mt8183-disp-mutex",
585 	  .data = &mt8183_mutex_driver_data},
586 	{ .compatible = "mediatek,mt8186-disp-mutex",
587 	  .data = &mt8186_mutex_driver_data},
588 	{ .compatible = "mediatek,mt8192-disp-mutex",
589 	  .data = &mt8192_mutex_driver_data},
590 	{},
591 };
592 MODULE_DEVICE_TABLE(of, mutex_driver_dt_match);
593 
594 static struct platform_driver mtk_mutex_driver = {
595 	.probe		= mtk_mutex_probe,
596 	.remove		= mtk_mutex_remove,
597 	.driver		= {
598 		.name	= "mediatek-mutex",
599 		.owner	= THIS_MODULE,
600 		.of_match_table = mutex_driver_dt_match,
601 	},
602 };
603 
604 builtin_platform_driver(mtk_mutex_driver);
605