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