treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / gpu / drm / mediatek / mtk_drm_ddp.c
blob13035c906035107b52c42e79fedf464efd163e12
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2015 MediaTek Inc.
4 */
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>
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 {
141 int id;
142 bool claimed;
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,
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;
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;
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,
251 unsigned int *addr)
253 unsigned int value;
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;
325 return value;
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)
332 unsigned int value;
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;
383 return value;
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);
410 if (value) {
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);
418 if (value) {
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);
431 if (value) {
432 reg = readl_relaxed(config_regs + addr) & ~value;
433 writel_relaxed(reg, config_regs + addr);
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);
443 struct mtk_disp_mutex *mtk_disp_mutex_get(struct device *dev, unsigned int id)
445 struct mtk_ddp *ddp = dev_get_drvdata(dev);
447 if (id >= 10)
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,
460 mutex[mutex->id]);
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,
470 mutex[mutex->id]);
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,
477 mutex[mutex->id]);
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,
485 mutex[mutex->id]);
486 unsigned int reg;
487 unsigned int sof_id;
488 unsigned int offset;
490 WARN_ON(&ddp->mutex[mutex->id] != mutex);
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);
524 return;
527 writel_relaxed(ddp->data->mutex_sof[sof_id],
528 ddp->regs +
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,
536 mutex[mutex->id]);
537 unsigned int reg;
538 unsigned int offset;
540 WARN_ON(&ddp->mutex[mutex->id] != mutex);
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);
567 break;
571 void mtk_disp_mutex_enable(struct mtk_disp_mutex *mutex)
573 struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
574 mutex[mutex->id]);
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,
584 mutex[mutex->id]);
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,
594 mutex[mutex->id]);
595 u32 tmp;
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,
607 mutex[mutex->id]);
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;
615 struct mtk_ddp *ddp;
616 struct resource *regs;
617 int i;
619 ddp = devm_kzalloc(dev, sizeof(*ddp), GFP_KERNEL);
620 if (!ddp)
621 return -ENOMEM;
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);
645 return 0;
648 static int mtk_ddp_remove(struct platform_device *pdev)
650 return 0;
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,
667 .driver = {
668 .name = "mediatek-ddp",
669 .owner = THIS_MODULE,
670 .of_match_table = ddp_driver_dt_match,