1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2015 MediaTek Inc.
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>
13 #include "mtk_drm_ddp.h"
14 #include "mtk_drm_ddp_comp.h"
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
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
36 #define MT2701_DISP_MUTEX0_MOD0 0x2c
37 #define MT2701_DISP_MUTEX0_SOF0 0x30
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))
46 #define INT_MUTEX BIT(1)
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
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
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
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
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
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
140 struct mtk_disp_mutex
{
145 enum mtk_ddp_mutex_sof_id
{
146 DDP_MUTEX_SOF_SINGLE_MODE
,
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
;
167 struct mtk_disp_mutex mutex
[10];
168 const struct mtk_ddp_data
*data
;
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
,
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
,
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
,
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
,
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
,
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
,
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
,
249 static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id cur
,
250 enum mtk_ddp_comp_id next
,
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
;
328 static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id cur
,
329 enum mtk_ddp_comp_id next
,
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
;
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
)
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
);
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
)
407 unsigned int addr
, value
, reg
;
409 value
= mtk_ddp_mout_en(cur
, next
, &addr
);
411 reg
= readl_relaxed(config_regs
+ addr
) | value
;
412 writel_relaxed(reg
, config_regs
+ addr
);
415 mtk_ddp_sout_sel(config_regs
, cur
, next
);
417 value
= mtk_ddp_sel_in(cur
, next
, &addr
);
419 reg
= readl_relaxed(config_regs
+ addr
) | value
;
420 writel_relaxed(reg
, config_regs
+ addr
);
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
)
428 unsigned int addr
, value
, reg
;
430 value
= mtk_ddp_mout_en(cur
, next
, &addr
);
432 reg
= readl_relaxed(config_regs
+ addr
) & ~value
;
433 writel_relaxed(reg
, config_regs
+ addr
);
436 value
= mtk_ddp_sel_in(cur
, next
, &addr
);
438 reg
= readl_relaxed(config_regs
+ addr
) & ~value
;
439 writel_relaxed(reg
, config_regs
+ addr
);
443 struct mtk_disp_mutex
*mtk_disp_mutex_get(struct device
*dev
, unsigned int id
)
445 struct mtk_ddp
*ddp
= dev_get_drvdata(dev
);
448 return ERR_PTR(-EINVAL
);
449 if (ddp
->mutex
[id
].claimed
)
450 return ERR_PTR(-EBUSY
);
452 ddp
->mutex
[id
].claimed
= true;
454 return &ddp
->mutex
[id
];
457 void mtk_disp_mutex_put(struct mtk_disp_mutex
*mutex
)
459 struct mtk_ddp
*ddp
= container_of(mutex
, struct mtk_ddp
,
462 WARN_ON(&ddp
->mutex
[mutex
->id
] != mutex
);
464 mutex
->claimed
= false;
467 int mtk_disp_mutex_prepare(struct mtk_disp_mutex
*mutex
)
469 struct mtk_ddp
*ddp
= container_of(mutex
, struct mtk_ddp
,
471 return clk_prepare_enable(ddp
->clk
);
474 void mtk_disp_mutex_unprepare(struct mtk_disp_mutex
*mutex
)
476 struct mtk_ddp
*ddp
= container_of(mutex
, struct mtk_ddp
,
478 clk_disable_unprepare(ddp
->clk
);
481 void mtk_disp_mutex_add_comp(struct mtk_disp_mutex
*mutex
,
482 enum mtk_ddp_comp_id id
)
484 struct mtk_ddp
*ddp
= container_of(mutex
, struct mtk_ddp
,
490 WARN_ON(&ddp
->mutex
[mutex
->id
] != mutex
);
493 case DDP_COMPONENT_DSI0
:
494 sof_id
= DDP_MUTEX_SOF_DSI0
;
496 case DDP_COMPONENT_DSI1
:
497 sof_id
= DDP_MUTEX_SOF_DSI0
;
499 case DDP_COMPONENT_DSI2
:
500 sof_id
= DDP_MUTEX_SOF_DSI2
;
502 case DDP_COMPONENT_DSI3
:
503 sof_id
= DDP_MUTEX_SOF_DSI3
;
505 case DDP_COMPONENT_DPI0
:
506 sof_id
= DDP_MUTEX_SOF_DPI0
;
508 case DDP_COMPONENT_DPI1
:
509 sof_id
= DDP_MUTEX_SOF_DPI1
;
512 if (ddp
->data
->mutex_mod
[id
] < 32) {
513 offset
= DISP_REG_MUTEX_MOD(ddp
->data
->mutex_mod_reg
,
515 reg
= readl_relaxed(ddp
->regs
+ offset
);
516 reg
|= 1 << ddp
->data
->mutex_mod
[id
];
517 writel_relaxed(reg
, ddp
->regs
+ offset
);
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
);
527 writel_relaxed(ddp
->data
->mutex_sof
[sof_id
],
529 DISP_REG_MUTEX_SOF(ddp
->data
->mutex_sof_reg
, mutex
->id
));
532 void mtk_disp_mutex_remove_comp(struct mtk_disp_mutex
*mutex
,
533 enum mtk_ddp_comp_id id
)
535 struct mtk_ddp
*ddp
= container_of(mutex
, struct mtk_ddp
,
540 WARN_ON(&ddp
->mutex
[mutex
->id
] != mutex
);
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
,
551 DISP_REG_MUTEX_SOF(ddp
->data
->mutex_sof_reg
,
555 if (ddp
->data
->mutex_mod
[id
] < 32) {
556 offset
= DISP_REG_MUTEX_MOD(ddp
->data
->mutex_mod_reg
,
558 reg
= readl_relaxed(ddp
->regs
+ offset
);
559 reg
&= ~(1 << ddp
->data
->mutex_mod
[id
]);
560 writel_relaxed(reg
, ddp
->regs
+ offset
);
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
);
571 void mtk_disp_mutex_enable(struct mtk_disp_mutex
*mutex
)
573 struct mtk_ddp
*ddp
= container_of(mutex
, struct mtk_ddp
,
576 WARN_ON(&ddp
->mutex
[mutex
->id
] != mutex
);
578 writel(1, ddp
->regs
+ DISP_REG_MUTEX_EN(mutex
->id
));
581 void mtk_disp_mutex_disable(struct mtk_disp_mutex
*mutex
)
583 struct mtk_ddp
*ddp
= container_of(mutex
, struct mtk_ddp
,
586 WARN_ON(&ddp
->mutex
[mutex
->id
] != mutex
);
588 writel(0, ddp
->regs
+ DISP_REG_MUTEX_EN(mutex
->id
));
591 void mtk_disp_mutex_acquire(struct mtk_disp_mutex
*mutex
)
593 struct mtk_ddp
*ddp
= container_of(mutex
, struct mtk_ddp
,
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
);
604 void mtk_disp_mutex_release(struct mtk_disp_mutex
*mutex
)
606 struct mtk_ddp
*ddp
= container_of(mutex
, struct mtk_ddp
,
609 writel(0, ddp
->regs
+ DISP_REG_MUTEX(mutex
->id
));
612 static int mtk_ddp_probe(struct platform_device
*pdev
)
614 struct device
*dev
= &pdev
->dev
;
616 struct resource
*regs
;
619 ddp
= devm_kzalloc(dev
, sizeof(*ddp
), GFP_KERNEL
);
623 for (i
= 0; i
< 10; i
++)
624 ddp
->mutex
[i
].id
= i
;
626 ddp
->data
= of_device_get_match_data(dev
);
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
);
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
);
643 platform_set_drvdata(pdev
, ddp
);
648 static int mtk_ddp_remove(struct platform_device
*pdev
)
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
},
662 MODULE_DEVICE_TABLE(of
, ddp_driver_dt_match
);
664 struct platform_driver mtk_ddp_driver
= {
665 .probe
= mtk_ddp_probe
,
666 .remove
= mtk_ddp_remove
,
668 .name
= "mediatek-ddp",
669 .owner
= THIS_MODULE
,
670 .of_match_table
= ddp_driver_dt_match
,