Merge tag 'powerpc-5.7-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[linux-2.6-microblaze.git] / drivers / gpu / drm / mediatek / mtk_drm_ddp.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
13 #include "mtk_drm_ddp.h"
14 #include "mtk_drm_ddp_comp.h"
15
16 #define DISP_REG_CONFIG_DISP_OVL0_MOUT_EN       0x040
17 #define DISP_REG_CONFIG_DISP_OVL1_MOUT_EN       0x044
18 #define DISP_REG_CONFIG_DISP_OD_MOUT_EN         0x048
19 #define DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN      0x04c
20 #define DISP_REG_CONFIG_DISP_UFOE_MOUT_EN       0x050
21 #define DISP_REG_CONFIG_DISP_COLOR0_SEL_IN      0x084
22 #define DISP_REG_CONFIG_DISP_COLOR1_SEL_IN      0x088
23 #define DISP_REG_CONFIG_DSIE_SEL_IN             0x0a4
24 #define DISP_REG_CONFIG_DSIO_SEL_IN             0x0a8
25 #define DISP_REG_CONFIG_DPI_SEL_IN              0x0ac
26 #define DISP_REG_CONFIG_DISP_RDMA2_SOUT         0x0b8
27 #define DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN      0x0c4
28 #define DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN      0x0c8
29 #define DISP_REG_CONFIG_MMSYS_CG_CON0           0x100
30
31 #define DISP_REG_CONFIG_DISP_OVL_MOUT_EN        0x030
32 #define DISP_REG_CONFIG_OUT_SEL                 0x04c
33 #define DISP_REG_CONFIG_DSI_SEL                 0x050
34 #define DISP_REG_CONFIG_DPI_SEL                 0x064
35
36 #define MT2701_DISP_MUTEX0_MOD0                 0x2c
37 #define MT2701_DISP_MUTEX0_SOF0                 0x30
38
39 #define DISP_REG_MUTEX_EN(n)                    (0x20 + 0x20 * (n))
40 #define DISP_REG_MUTEX(n)                       (0x24 + 0x20 * (n))
41 #define DISP_REG_MUTEX_RST(n)                   (0x28 + 0x20 * (n))
42 #define DISP_REG_MUTEX_MOD(mutex_mod_reg, n)    (mutex_mod_reg + 0x20 * (n))
43 #define DISP_REG_MUTEX_SOF(mutex_sof_reg, n)    (mutex_sof_reg + 0x20 * (n))
44 #define DISP_REG_MUTEX_MOD2(n)                  (0x34 + 0x20 * (n))
45
46 #define INT_MUTEX                               BIT(1)
47
48 #define MT8173_MUTEX_MOD_DISP_OVL0              11
49 #define MT8173_MUTEX_MOD_DISP_OVL1              12
50 #define MT8173_MUTEX_MOD_DISP_RDMA0             13
51 #define MT8173_MUTEX_MOD_DISP_RDMA1             14
52 #define MT8173_MUTEX_MOD_DISP_RDMA2             15
53 #define MT8173_MUTEX_MOD_DISP_WDMA0             16
54 #define MT8173_MUTEX_MOD_DISP_WDMA1             17
55 #define MT8173_MUTEX_MOD_DISP_COLOR0            18
56 #define MT8173_MUTEX_MOD_DISP_COLOR1            19
57 #define MT8173_MUTEX_MOD_DISP_AAL               20
58 #define MT8173_MUTEX_MOD_DISP_GAMMA             21
59 #define MT8173_MUTEX_MOD_DISP_UFOE              22
60 #define MT8173_MUTEX_MOD_DISP_PWM0              23
61 #define MT8173_MUTEX_MOD_DISP_PWM1              24
62 #define MT8173_MUTEX_MOD_DISP_OD                25
63
64 #define MT2712_MUTEX_MOD_DISP_PWM2              10
65 #define MT2712_MUTEX_MOD_DISP_OVL0              11
66 #define MT2712_MUTEX_MOD_DISP_OVL1              12
67 #define MT2712_MUTEX_MOD_DISP_RDMA0             13
68 #define MT2712_MUTEX_MOD_DISP_RDMA1             14
69 #define MT2712_MUTEX_MOD_DISP_RDMA2             15
70 #define MT2712_MUTEX_MOD_DISP_WDMA0             16
71 #define MT2712_MUTEX_MOD_DISP_WDMA1             17
72 #define MT2712_MUTEX_MOD_DISP_COLOR0            18
73 #define MT2712_MUTEX_MOD_DISP_COLOR1            19
74 #define MT2712_MUTEX_MOD_DISP_AAL0              20
75 #define MT2712_MUTEX_MOD_DISP_UFOE              22
76 #define MT2712_MUTEX_MOD_DISP_PWM0              23
77 #define MT2712_MUTEX_MOD_DISP_PWM1              24
78 #define MT2712_MUTEX_MOD_DISP_OD0               25
79 #define MT2712_MUTEX_MOD2_DISP_AAL1             33
80 #define MT2712_MUTEX_MOD2_DISP_OD1              34
81
82 #define MT2701_MUTEX_MOD_DISP_OVL               3
83 #define MT2701_MUTEX_MOD_DISP_WDMA              6
84 #define MT2701_MUTEX_MOD_DISP_COLOR             7
85 #define MT2701_MUTEX_MOD_DISP_BLS               9
86 #define MT2701_MUTEX_MOD_DISP_RDMA0             10
87 #define MT2701_MUTEX_MOD_DISP_RDMA1             12
88
89 #define MUTEX_SOF_SINGLE_MODE           0
90 #define MUTEX_SOF_DSI0                  1
91 #define MUTEX_SOF_DSI1                  2
92 #define MUTEX_SOF_DPI0                  3
93 #define MUTEX_SOF_DPI1                  4
94 #define MUTEX_SOF_DSI2                  5
95 #define MUTEX_SOF_DSI3                  6
96
97 #define OVL0_MOUT_EN_COLOR0             0x1
98 #define OD_MOUT_EN_RDMA0                0x1
99 #define OD1_MOUT_EN_RDMA1               BIT(16)
100 #define UFOE_MOUT_EN_DSI0               0x1
101 #define COLOR0_SEL_IN_OVL0              0x1
102 #define OVL1_MOUT_EN_COLOR1             0x1
103 #define GAMMA_MOUT_EN_RDMA1             0x1
104 #define RDMA0_SOUT_DPI0                 0x2
105 #define RDMA0_SOUT_DPI1                 0x3
106 #define RDMA0_SOUT_DSI1                 0x1
107 #define RDMA0_SOUT_DSI2                 0x4
108 #define RDMA0_SOUT_DSI3                 0x5
109 #define RDMA1_SOUT_DPI0                 0x2
110 #define RDMA1_SOUT_DPI1                 0x3
111 #define RDMA1_SOUT_DSI1                 0x1
112 #define RDMA1_SOUT_DSI2                 0x4
113 #define RDMA1_SOUT_DSI3                 0x5
114 #define RDMA2_SOUT_DPI0                 0x2
115 #define RDMA2_SOUT_DPI1                 0x3
116 #define RDMA2_SOUT_DSI1                 0x1
117 #define RDMA2_SOUT_DSI2                 0x4
118 #define RDMA2_SOUT_DSI3                 0x5
119 #define DPI0_SEL_IN_RDMA1               0x1
120 #define DPI0_SEL_IN_RDMA2               0x3
121 #define DPI1_SEL_IN_RDMA1               (0x1 << 8)
122 #define DPI1_SEL_IN_RDMA2               (0x3 << 8)
123 #define DSI0_SEL_IN_RDMA1               0x1
124 #define DSI0_SEL_IN_RDMA2               0x4
125 #define DSI1_SEL_IN_RDMA1               0x1
126 #define DSI1_SEL_IN_RDMA2               0x4
127 #define DSI2_SEL_IN_RDMA1               (0x1 << 16)
128 #define DSI2_SEL_IN_RDMA2               (0x4 << 16)
129 #define DSI3_SEL_IN_RDMA1               (0x1 << 16)
130 #define DSI3_SEL_IN_RDMA2               (0x4 << 16)
131 #define COLOR1_SEL_IN_OVL1              0x1
132
133 #define OVL_MOUT_EN_RDMA                0x1
134 #define BLS_TO_DSI_RDMA1_TO_DPI1        0x8
135 #define BLS_TO_DPI_RDMA1_TO_DSI         0x2
136 #define DSI_SEL_IN_BLS                  0x0
137 #define DPI_SEL_IN_BLS                  0x0
138 #define DSI_SEL_IN_RDMA                 0x1
139
140 struct mtk_disp_mutex {
141         int id;
142         bool claimed;
143 };
144
145 enum mtk_ddp_mutex_sof_id {
146         DDP_MUTEX_SOF_SINGLE_MODE,
147         DDP_MUTEX_SOF_DSI0,
148         DDP_MUTEX_SOF_DSI1,
149         DDP_MUTEX_SOF_DPI0,
150         DDP_MUTEX_SOF_DPI1,
151         DDP_MUTEX_SOF_DSI2,
152         DDP_MUTEX_SOF_DSI3,
153 };
154
155 struct mtk_ddp_data {
156         const unsigned int *mutex_mod;
157         const unsigned int *mutex_sof;
158         const unsigned int mutex_mod_reg;
159         const unsigned int mutex_sof_reg;
160         const bool no_clk;
161 };
162
163 struct mtk_ddp {
164         struct device                   *dev;
165         struct clk                      *clk;
166         void __iomem                    *regs;
167         struct mtk_disp_mutex           mutex[10];
168         const struct mtk_ddp_data       *data;
169 };
170
171 static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
172         [DDP_COMPONENT_BLS] = MT2701_MUTEX_MOD_DISP_BLS,
173         [DDP_COMPONENT_COLOR0] = MT2701_MUTEX_MOD_DISP_COLOR,
174         [DDP_COMPONENT_OVL0] = MT2701_MUTEX_MOD_DISP_OVL,
175         [DDP_COMPONENT_RDMA0] = MT2701_MUTEX_MOD_DISP_RDMA0,
176         [DDP_COMPONENT_RDMA1] = MT2701_MUTEX_MOD_DISP_RDMA1,
177         [DDP_COMPONENT_WDMA0] = MT2701_MUTEX_MOD_DISP_WDMA,
178 };
179
180 static const unsigned int mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = {
181         [DDP_COMPONENT_AAL0] = MT2712_MUTEX_MOD_DISP_AAL0,
182         [DDP_COMPONENT_AAL1] = MT2712_MUTEX_MOD2_DISP_AAL1,
183         [DDP_COMPONENT_COLOR0] = MT2712_MUTEX_MOD_DISP_COLOR0,
184         [DDP_COMPONENT_COLOR1] = MT2712_MUTEX_MOD_DISP_COLOR1,
185         [DDP_COMPONENT_OD0] = MT2712_MUTEX_MOD_DISP_OD0,
186         [DDP_COMPONENT_OD1] = MT2712_MUTEX_MOD2_DISP_OD1,
187         [DDP_COMPONENT_OVL0] = MT2712_MUTEX_MOD_DISP_OVL0,
188         [DDP_COMPONENT_OVL1] = MT2712_MUTEX_MOD_DISP_OVL1,
189         [DDP_COMPONENT_PWM0] = MT2712_MUTEX_MOD_DISP_PWM0,
190         [DDP_COMPONENT_PWM1] = MT2712_MUTEX_MOD_DISP_PWM1,
191         [DDP_COMPONENT_PWM2] = MT2712_MUTEX_MOD_DISP_PWM2,
192         [DDP_COMPONENT_RDMA0] = MT2712_MUTEX_MOD_DISP_RDMA0,
193         [DDP_COMPONENT_RDMA1] = MT2712_MUTEX_MOD_DISP_RDMA1,
194         [DDP_COMPONENT_RDMA2] = MT2712_MUTEX_MOD_DISP_RDMA2,
195         [DDP_COMPONENT_UFOE] = MT2712_MUTEX_MOD_DISP_UFOE,
196         [DDP_COMPONENT_WDMA0] = MT2712_MUTEX_MOD_DISP_WDMA0,
197         [DDP_COMPONENT_WDMA1] = MT2712_MUTEX_MOD_DISP_WDMA1,
198 };
199
200 static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
201         [DDP_COMPONENT_AAL0] = MT8173_MUTEX_MOD_DISP_AAL,
202         [DDP_COMPONENT_COLOR0] = MT8173_MUTEX_MOD_DISP_COLOR0,
203         [DDP_COMPONENT_COLOR1] = MT8173_MUTEX_MOD_DISP_COLOR1,
204         [DDP_COMPONENT_GAMMA] = MT8173_MUTEX_MOD_DISP_GAMMA,
205         [DDP_COMPONENT_OD0] = MT8173_MUTEX_MOD_DISP_OD,
206         [DDP_COMPONENT_OVL0] = MT8173_MUTEX_MOD_DISP_OVL0,
207         [DDP_COMPONENT_OVL1] = MT8173_MUTEX_MOD_DISP_OVL1,
208         [DDP_COMPONENT_PWM0] = MT8173_MUTEX_MOD_DISP_PWM0,
209         [DDP_COMPONENT_PWM1] = MT8173_MUTEX_MOD_DISP_PWM1,
210         [DDP_COMPONENT_RDMA0] = MT8173_MUTEX_MOD_DISP_RDMA0,
211         [DDP_COMPONENT_RDMA1] = MT8173_MUTEX_MOD_DISP_RDMA1,
212         [DDP_COMPONENT_RDMA2] = MT8173_MUTEX_MOD_DISP_RDMA2,
213         [DDP_COMPONENT_UFOE] = MT8173_MUTEX_MOD_DISP_UFOE,
214         [DDP_COMPONENT_WDMA0] = MT8173_MUTEX_MOD_DISP_WDMA0,
215         [DDP_COMPONENT_WDMA1] = MT8173_MUTEX_MOD_DISP_WDMA1,
216 };
217
218 static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_DSI3 + 1] = {
219         [DDP_MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
220         [DDP_MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
221         [DDP_MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1,
222         [DDP_MUTEX_SOF_DPI0] = MUTEX_SOF_DPI0,
223         [DDP_MUTEX_SOF_DPI1] = MUTEX_SOF_DPI1,
224         [DDP_MUTEX_SOF_DSI2] = MUTEX_SOF_DSI2,
225         [DDP_MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3,
226 };
227
228 static const struct mtk_ddp_data mt2701_ddp_driver_data = {
229         .mutex_mod = mt2701_mutex_mod,
230         .mutex_sof = mt2712_mutex_sof,
231         .mutex_mod_reg = MT2701_DISP_MUTEX0_MOD0,
232         .mutex_sof_reg = MT2701_DISP_MUTEX0_SOF0,
233 };
234
235 static const struct mtk_ddp_data mt2712_ddp_driver_data = {
236         .mutex_mod = mt2712_mutex_mod,
237         .mutex_sof = mt2712_mutex_sof,
238         .mutex_mod_reg = MT2701_DISP_MUTEX0_MOD0,
239         .mutex_sof_reg = MT2701_DISP_MUTEX0_SOF0,
240 };
241
242 static const struct mtk_ddp_data mt8173_ddp_driver_data = {
243         .mutex_mod = mt8173_mutex_mod,
244         .mutex_sof = mt2712_mutex_sof,
245         .mutex_mod_reg = MT2701_DISP_MUTEX0_MOD0,
246         .mutex_sof_reg = MT2701_DISP_MUTEX0_SOF0,
247 };
248
249 static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id cur,
250                                     enum mtk_ddp_comp_id next,
251                                     unsigned int *addr)
252 {
253         unsigned int value;
254
255         if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) {
256                 *addr = DISP_REG_CONFIG_DISP_OVL0_MOUT_EN;
257                 value = OVL0_MOUT_EN_COLOR0;
258         } else if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_RDMA0) {
259                 *addr = DISP_REG_CONFIG_DISP_OVL_MOUT_EN;
260                 value = OVL_MOUT_EN_RDMA;
261         } else if (cur == DDP_COMPONENT_OD0 && next == DDP_COMPONENT_RDMA0) {
262                 *addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN;
263                 value = OD_MOUT_EN_RDMA0;
264         } else if (cur == DDP_COMPONENT_UFOE && next == DDP_COMPONENT_DSI0) {
265                 *addr = DISP_REG_CONFIG_DISP_UFOE_MOUT_EN;
266                 value = UFOE_MOUT_EN_DSI0;
267         } else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) {
268                 *addr = DISP_REG_CONFIG_DISP_OVL1_MOUT_EN;
269                 value = OVL1_MOUT_EN_COLOR1;
270         } else if (cur == DDP_COMPONENT_GAMMA && next == DDP_COMPONENT_RDMA1) {
271                 *addr = DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN;
272                 value = GAMMA_MOUT_EN_RDMA1;
273         } else if (cur == DDP_COMPONENT_OD1 && next == DDP_COMPONENT_RDMA1) {
274                 *addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN;
275                 value = OD1_MOUT_EN_RDMA1;
276         } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI0) {
277                 *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
278                 value = RDMA0_SOUT_DPI0;
279         } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI1) {
280                 *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
281                 value = RDMA0_SOUT_DPI1;
282         } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI1) {
283                 *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
284                 value = RDMA0_SOUT_DSI1;
285         } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI2) {
286                 *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
287                 value = RDMA0_SOUT_DSI2;
288         } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI3) {
289                 *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
290                 value = RDMA0_SOUT_DSI3;
291         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI1) {
292                 *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
293                 value = RDMA1_SOUT_DSI1;
294         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI2) {
295                 *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
296                 value = RDMA1_SOUT_DSI2;
297         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI3) {
298                 *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
299                 value = RDMA1_SOUT_DSI3;
300         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI0) {
301                 *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
302                 value = RDMA1_SOUT_DPI0;
303         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI1) {
304                 *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
305                 value = RDMA1_SOUT_DPI1;
306         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI0) {
307                 *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
308                 value = RDMA2_SOUT_DPI0;
309         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI1) {
310                 *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
311                 value = RDMA2_SOUT_DPI1;
312         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI1) {
313                 *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
314                 value = RDMA2_SOUT_DSI1;
315         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI2) {
316                 *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
317                 value = RDMA2_SOUT_DSI2;
318         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI3) {
319                 *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
320                 value = RDMA2_SOUT_DSI3;
321         } else {
322                 value = 0;
323         }
324
325         return value;
326 }
327
328 static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id cur,
329                                    enum mtk_ddp_comp_id next,
330                                    unsigned int *addr)
331 {
332         unsigned int value;
333
334         if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) {
335                 *addr = DISP_REG_CONFIG_DISP_COLOR0_SEL_IN;
336                 value = COLOR0_SEL_IN_OVL0;
337         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI0) {
338                 *addr = DISP_REG_CONFIG_DPI_SEL_IN;
339                 value = DPI0_SEL_IN_RDMA1;
340         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI1) {
341                 *addr = DISP_REG_CONFIG_DPI_SEL_IN;
342                 value = DPI1_SEL_IN_RDMA1;
343         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI0) {
344                 *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
345                 value = DSI0_SEL_IN_RDMA1;
346         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI1) {
347                 *addr = DISP_REG_CONFIG_DSIO_SEL_IN;
348                 value = DSI1_SEL_IN_RDMA1;
349         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI2) {
350                 *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
351                 value = DSI2_SEL_IN_RDMA1;
352         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI3) {
353                 *addr = DISP_REG_CONFIG_DSIO_SEL_IN;
354                 value = DSI3_SEL_IN_RDMA1;
355         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI0) {
356                 *addr = DISP_REG_CONFIG_DPI_SEL_IN;
357                 value = DPI0_SEL_IN_RDMA2;
358         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI1) {
359                 *addr = DISP_REG_CONFIG_DPI_SEL_IN;
360                 value = DPI1_SEL_IN_RDMA2;
361         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI0) {
362                 *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
363                 value = DSI0_SEL_IN_RDMA2;
364         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI1) {
365                 *addr = DISP_REG_CONFIG_DSIO_SEL_IN;
366                 value = DSI1_SEL_IN_RDMA2;
367         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI2) {
368                 *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
369                 value = DSI2_SEL_IN_RDMA2;
370         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI3) {
371                 *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
372                 value = DSI3_SEL_IN_RDMA2;
373         } else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) {
374                 *addr = DISP_REG_CONFIG_DISP_COLOR1_SEL_IN;
375                 value = COLOR1_SEL_IN_OVL1;
376         } else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) {
377                 *addr = DISP_REG_CONFIG_DSI_SEL;
378                 value = DSI_SEL_IN_BLS;
379         } else {
380                 value = 0;
381         }
382
383         return value;
384 }
385
386 static void mtk_ddp_sout_sel(void __iomem *config_regs,
387                              enum mtk_ddp_comp_id cur,
388                              enum mtk_ddp_comp_id next)
389 {
390         if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) {
391                 writel_relaxed(BLS_TO_DSI_RDMA1_TO_DPI1,
392                                config_regs + DISP_REG_CONFIG_OUT_SEL);
393         } else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DPI0) {
394                 writel_relaxed(BLS_TO_DPI_RDMA1_TO_DSI,
395                                config_regs + DISP_REG_CONFIG_OUT_SEL);
396                 writel_relaxed(DSI_SEL_IN_RDMA,
397                                config_regs + DISP_REG_CONFIG_DSI_SEL);
398                 writel_relaxed(DPI_SEL_IN_BLS,
399                                config_regs + DISP_REG_CONFIG_DPI_SEL);
400         }
401 }
402
403 void mtk_ddp_add_comp_to_path(void __iomem *config_regs,
404                               enum mtk_ddp_comp_id cur,
405                               enum mtk_ddp_comp_id next)
406 {
407         unsigned int addr, value, reg;
408
409         value = mtk_ddp_mout_en(cur, next, &addr);
410         if (value) {
411                 reg = readl_relaxed(config_regs + addr) | value;
412                 writel_relaxed(reg, config_regs + addr);
413         }
414
415         mtk_ddp_sout_sel(config_regs, cur, next);
416
417         value = mtk_ddp_sel_in(cur, next, &addr);
418         if (value) {
419                 reg = readl_relaxed(config_regs + addr) | value;
420                 writel_relaxed(reg, config_regs + addr);
421         }
422 }
423
424 void mtk_ddp_remove_comp_from_path(void __iomem *config_regs,
425                                    enum mtk_ddp_comp_id cur,
426                                    enum mtk_ddp_comp_id next)
427 {
428         unsigned int addr, value, reg;
429
430         value = mtk_ddp_mout_en(cur, next, &addr);
431         if (value) {
432                 reg = readl_relaxed(config_regs + addr) & ~value;
433                 writel_relaxed(reg, config_regs + addr);
434         }
435
436         value = mtk_ddp_sel_in(cur, next, &addr);
437         if (value) {
438                 reg = readl_relaxed(config_regs + addr) & ~value;
439                 writel_relaxed(reg, config_regs + addr);
440         }
441 }
442
443 struct mtk_disp_mutex *mtk_disp_mutex_get(struct device *dev, unsigned int id)
444 {
445         struct mtk_ddp *ddp = dev_get_drvdata(dev);
446
447         if (id >= 10)
448                 return ERR_PTR(-EINVAL);
449         if (ddp->mutex[id].claimed)
450                 return ERR_PTR(-EBUSY);
451
452         ddp->mutex[id].claimed = true;
453
454         return &ddp->mutex[id];
455 }
456
457 void mtk_disp_mutex_put(struct mtk_disp_mutex *mutex)
458 {
459         struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
460                                            mutex[mutex->id]);
461
462         WARN_ON(&ddp->mutex[mutex->id] != mutex);
463
464         mutex->claimed = false;
465 }
466
467 int mtk_disp_mutex_prepare(struct mtk_disp_mutex *mutex)
468 {
469         struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
470                                            mutex[mutex->id]);
471         return clk_prepare_enable(ddp->clk);
472 }
473
474 void mtk_disp_mutex_unprepare(struct mtk_disp_mutex *mutex)
475 {
476         struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
477                                            mutex[mutex->id]);
478         clk_disable_unprepare(ddp->clk);
479 }
480
481 void mtk_disp_mutex_add_comp(struct mtk_disp_mutex *mutex,
482                              enum mtk_ddp_comp_id id)
483 {
484         struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
485                                            mutex[mutex->id]);
486         unsigned int reg;
487         unsigned int sof_id;
488         unsigned int offset;
489
490         WARN_ON(&ddp->mutex[mutex->id] != mutex);
491
492         switch (id) {
493         case DDP_COMPONENT_DSI0:
494                 sof_id = DDP_MUTEX_SOF_DSI0;
495                 break;
496         case DDP_COMPONENT_DSI1:
497                 sof_id = DDP_MUTEX_SOF_DSI0;
498                 break;
499         case DDP_COMPONENT_DSI2:
500                 sof_id = DDP_MUTEX_SOF_DSI2;
501                 break;
502         case DDP_COMPONENT_DSI3:
503                 sof_id = DDP_MUTEX_SOF_DSI3;
504                 break;
505         case DDP_COMPONENT_DPI0:
506                 sof_id = DDP_MUTEX_SOF_DPI0;
507                 break;
508         case DDP_COMPONENT_DPI1:
509                 sof_id = DDP_MUTEX_SOF_DPI1;
510                 break;
511         default:
512                 if (ddp->data->mutex_mod[id] < 32) {
513                         offset = DISP_REG_MUTEX_MOD(ddp->data->mutex_mod_reg,
514                                                     mutex->id);
515                         reg = readl_relaxed(ddp->regs + offset);
516                         reg |= 1 << ddp->data->mutex_mod[id];
517                         writel_relaxed(reg, ddp->regs + offset);
518                 } else {
519                         offset = DISP_REG_MUTEX_MOD2(mutex->id);
520                         reg = readl_relaxed(ddp->regs + offset);
521                         reg |= 1 << (ddp->data->mutex_mod[id] - 32);
522                         writel_relaxed(reg, ddp->regs + offset);
523                 }
524                 return;
525         }
526
527         writel_relaxed(ddp->data->mutex_sof[sof_id],
528                        ddp->regs +
529                        DISP_REG_MUTEX_SOF(ddp->data->mutex_sof_reg, mutex->id));
530 }
531
532 void mtk_disp_mutex_remove_comp(struct mtk_disp_mutex *mutex,
533                                 enum mtk_ddp_comp_id id)
534 {
535         struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
536                                            mutex[mutex->id]);
537         unsigned int reg;
538         unsigned int offset;
539
540         WARN_ON(&ddp->mutex[mutex->id] != mutex);
541
542         switch (id) {
543         case DDP_COMPONENT_DSI0:
544         case DDP_COMPONENT_DSI1:
545         case DDP_COMPONENT_DSI2:
546         case DDP_COMPONENT_DSI3:
547         case DDP_COMPONENT_DPI0:
548         case DDP_COMPONENT_DPI1:
549                 writel_relaxed(MUTEX_SOF_SINGLE_MODE,
550                                ddp->regs +
551                                DISP_REG_MUTEX_SOF(ddp->data->mutex_sof_reg,
552                                                   mutex->id));
553                 break;
554         default:
555                 if (ddp->data->mutex_mod[id] < 32) {
556                         offset = DISP_REG_MUTEX_MOD(ddp->data->mutex_mod_reg,
557                                                     mutex->id);
558                         reg = readl_relaxed(ddp->regs + offset);
559                         reg &= ~(1 << ddp->data->mutex_mod[id]);
560                         writel_relaxed(reg, ddp->regs + offset);
561                 } else {
562                         offset = DISP_REG_MUTEX_MOD2(mutex->id);
563                         reg = readl_relaxed(ddp->regs + offset);
564                         reg &= ~(1 << (ddp->data->mutex_mod[id] - 32));
565                         writel_relaxed(reg, ddp->regs + offset);
566                 }
567                 break;
568         }
569 }
570
571 void mtk_disp_mutex_enable(struct mtk_disp_mutex *mutex)
572 {
573         struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
574                                            mutex[mutex->id]);
575
576         WARN_ON(&ddp->mutex[mutex->id] != mutex);
577
578         writel(1, ddp->regs + DISP_REG_MUTEX_EN(mutex->id));
579 }
580
581 void mtk_disp_mutex_disable(struct mtk_disp_mutex *mutex)
582 {
583         struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
584                                            mutex[mutex->id]);
585
586         WARN_ON(&ddp->mutex[mutex->id] != mutex);
587
588         writel(0, ddp->regs + DISP_REG_MUTEX_EN(mutex->id));
589 }
590
591 void mtk_disp_mutex_acquire(struct mtk_disp_mutex *mutex)
592 {
593         struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
594                                            mutex[mutex->id]);
595         u32 tmp;
596
597         writel(1, ddp->regs + DISP_REG_MUTEX_EN(mutex->id));
598         writel(1, ddp->regs + DISP_REG_MUTEX(mutex->id));
599         if (readl_poll_timeout_atomic(ddp->regs + DISP_REG_MUTEX(mutex->id),
600                                       tmp, tmp & INT_MUTEX, 1, 10000))
601                 pr_err("could not acquire mutex %d\n", mutex->id);
602 }
603
604 void mtk_disp_mutex_release(struct mtk_disp_mutex *mutex)
605 {
606         struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
607                                            mutex[mutex->id]);
608
609         writel(0, ddp->regs + DISP_REG_MUTEX(mutex->id));
610 }
611
612 static int mtk_ddp_probe(struct platform_device *pdev)
613 {
614         struct device *dev = &pdev->dev;
615         struct mtk_ddp *ddp;
616         struct resource *regs;
617         int i;
618
619         ddp = devm_kzalloc(dev, sizeof(*ddp), GFP_KERNEL);
620         if (!ddp)
621                 return -ENOMEM;
622
623         for (i = 0; i < 10; i++)
624                 ddp->mutex[i].id = i;
625
626         ddp->data = of_device_get_match_data(dev);
627
628         if (!ddp->data->no_clk) {
629                 ddp->clk = devm_clk_get(dev, NULL);
630                 if (IS_ERR(ddp->clk)) {
631                         dev_err(dev, "Failed to get clock\n");
632                         return PTR_ERR(ddp->clk);
633                 }
634         }
635
636         regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
637         ddp->regs = devm_ioremap_resource(dev, regs);
638         if (IS_ERR(ddp->regs)) {
639                 dev_err(dev, "Failed to map mutex registers\n");
640                 return PTR_ERR(ddp->regs);
641         }
642
643         platform_set_drvdata(pdev, ddp);
644
645         return 0;
646 }
647
648 static int mtk_ddp_remove(struct platform_device *pdev)
649 {
650         return 0;
651 }
652
653 static const struct of_device_id ddp_driver_dt_match[] = {
654         { .compatible = "mediatek,mt2701-disp-mutex",
655           .data = &mt2701_ddp_driver_data},
656         { .compatible = "mediatek,mt2712-disp-mutex",
657           .data = &mt2712_ddp_driver_data},
658         { .compatible = "mediatek,mt8173-disp-mutex",
659           .data = &mt8173_ddp_driver_data},
660         {},
661 };
662 MODULE_DEVICE_TABLE(of, ddp_driver_dt_match);
663
664 struct platform_driver mtk_ddp_driver = {
665         .probe          = mtk_ddp_probe,
666         .remove         = mtk_ddp_remove,
667         .driver         = {
668                 .name   = "mediatek-ddp",
669                 .owner  = THIS_MODULE,
670                 .of_match_table = ddp_driver_dt_match,
671         },
672 };