GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / soc / mediatek / mtk-mutex.c
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);