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