]> Git Repo - linux.git/blob - drivers/soc/mediatek/mtk-mmsys.c
drm/nouveau/kms: Don't change EDID when it hasn't actually changed
[linux.git] / drivers / soc / mediatek / mtk-mmsys.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2014 MediaTek Inc.
4  * Author: James Liao <[email protected]>
5  */
6
7 #include <linux/device.h>
8 #include <linux/of_device.h>
9 #include <linux/platform_device.h>
10 #include <linux/soc/mediatek/mtk-mmsys.h>
11
12 #include "../../gpu/drm/mediatek/mtk_drm_ddp.h"
13 #include "../../gpu/drm/mediatek/mtk_drm_ddp_comp.h"
14
15 #define DISP_REG_CONFIG_DISP_OVL0_MOUT_EN       0x040
16 #define DISP_REG_CONFIG_DISP_OVL1_MOUT_EN       0x044
17 #define DISP_REG_CONFIG_DISP_OD_MOUT_EN         0x048
18 #define DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN      0x04c
19 #define DISP_REG_CONFIG_DISP_UFOE_MOUT_EN       0x050
20 #define DISP_REG_CONFIG_DISP_COLOR0_SEL_IN      0x084
21 #define DISP_REG_CONFIG_DISP_COLOR1_SEL_IN      0x088
22 #define DISP_REG_CONFIG_DSIE_SEL_IN             0x0a4
23 #define DISP_REG_CONFIG_DSIO_SEL_IN             0x0a8
24 #define DISP_REG_CONFIG_DPI_SEL_IN              0x0ac
25 #define DISP_REG_CONFIG_DISP_RDMA2_SOUT         0x0b8
26 #define DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN      0x0c4
27 #define DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN      0x0c8
28 #define DISP_REG_CONFIG_MMSYS_CG_CON0           0x100
29
30 #define DISP_REG_CONFIG_DISP_OVL_MOUT_EN        0x030
31 #define DISP_REG_CONFIG_OUT_SEL                 0x04c
32 #define DISP_REG_CONFIG_DSI_SEL                 0x050
33 #define DISP_REG_CONFIG_DPI_SEL                 0x064
34
35 #define OVL0_MOUT_EN_COLOR0                     0x1
36 #define OD_MOUT_EN_RDMA0                        0x1
37 #define OD1_MOUT_EN_RDMA1                       BIT(16)
38 #define UFOE_MOUT_EN_DSI0                       0x1
39 #define COLOR0_SEL_IN_OVL0                      0x1
40 #define OVL1_MOUT_EN_COLOR1                     0x1
41 #define GAMMA_MOUT_EN_RDMA1                     0x1
42 #define RDMA0_SOUT_DPI0                         0x2
43 #define RDMA0_SOUT_DPI1                         0x3
44 #define RDMA0_SOUT_DSI1                         0x1
45 #define RDMA0_SOUT_DSI2                         0x4
46 #define RDMA0_SOUT_DSI3                         0x5
47 #define RDMA1_SOUT_DPI0                         0x2
48 #define RDMA1_SOUT_DPI1                         0x3
49 #define RDMA1_SOUT_DSI1                         0x1
50 #define RDMA1_SOUT_DSI2                         0x4
51 #define RDMA1_SOUT_DSI3                         0x5
52 #define RDMA2_SOUT_DPI0                         0x2
53 #define RDMA2_SOUT_DPI1                         0x3
54 #define RDMA2_SOUT_DSI1                         0x1
55 #define RDMA2_SOUT_DSI2                         0x4
56 #define RDMA2_SOUT_DSI3                         0x5
57 #define DPI0_SEL_IN_RDMA1                       0x1
58 #define DPI0_SEL_IN_RDMA2                       0x3
59 #define DPI1_SEL_IN_RDMA1                       (0x1 << 8)
60 #define DPI1_SEL_IN_RDMA2                       (0x3 << 8)
61 #define DSI0_SEL_IN_RDMA1                       0x1
62 #define DSI0_SEL_IN_RDMA2                       0x4
63 #define DSI1_SEL_IN_RDMA1                       0x1
64 #define DSI1_SEL_IN_RDMA2                       0x4
65 #define DSI2_SEL_IN_RDMA1                       (0x1 << 16)
66 #define DSI2_SEL_IN_RDMA2                       (0x4 << 16)
67 #define DSI3_SEL_IN_RDMA1                       (0x1 << 16)
68 #define DSI3_SEL_IN_RDMA2                       (0x4 << 16)
69 #define COLOR1_SEL_IN_OVL1                      0x1
70
71 #define OVL_MOUT_EN_RDMA                        0x1
72 #define BLS_TO_DSI_RDMA1_TO_DPI1                0x8
73 #define BLS_TO_DPI_RDMA1_TO_DSI                 0x2
74 #define DSI_SEL_IN_BLS                          0x0
75 #define DPI_SEL_IN_BLS                          0x0
76 #define DSI_SEL_IN_RDMA                         0x1
77
78 struct mtk_mmsys_driver_data {
79         const char *clk_driver;
80 };
81
82 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
83         .clk_driver = "clk-mt2701-mm",
84 };
85
86 static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
87         .clk_driver = "clk-mt2712-mm",
88 };
89
90 static const struct mtk_mmsys_driver_data mt6779_mmsys_driver_data = {
91         .clk_driver = "clk-mt6779-mm",
92 };
93
94 static const struct mtk_mmsys_driver_data mt6797_mmsys_driver_data = {
95         .clk_driver = "clk-mt6797-mm",
96 };
97
98 static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
99         .clk_driver = "clk-mt8173-mm",
100 };
101
102 static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
103         .clk_driver = "clk-mt8183-mm",
104 };
105
106 static unsigned int mtk_mmsys_ddp_mout_en(enum mtk_ddp_comp_id cur,
107                                           enum mtk_ddp_comp_id next,
108                                           unsigned int *addr)
109 {
110         unsigned int value;
111
112         if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) {
113                 *addr = DISP_REG_CONFIG_DISP_OVL0_MOUT_EN;
114                 value = OVL0_MOUT_EN_COLOR0;
115         } else if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_RDMA0) {
116                 *addr = DISP_REG_CONFIG_DISP_OVL_MOUT_EN;
117                 value = OVL_MOUT_EN_RDMA;
118         } else if (cur == DDP_COMPONENT_OD0 && next == DDP_COMPONENT_RDMA0) {
119                 *addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN;
120                 value = OD_MOUT_EN_RDMA0;
121         } else if (cur == DDP_COMPONENT_UFOE && next == DDP_COMPONENT_DSI0) {
122                 *addr = DISP_REG_CONFIG_DISP_UFOE_MOUT_EN;
123                 value = UFOE_MOUT_EN_DSI0;
124         } else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) {
125                 *addr = DISP_REG_CONFIG_DISP_OVL1_MOUT_EN;
126                 value = OVL1_MOUT_EN_COLOR1;
127         } else if (cur == DDP_COMPONENT_GAMMA && next == DDP_COMPONENT_RDMA1) {
128                 *addr = DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN;
129                 value = GAMMA_MOUT_EN_RDMA1;
130         } else if (cur == DDP_COMPONENT_OD1 && next == DDP_COMPONENT_RDMA1) {
131                 *addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN;
132                 value = OD1_MOUT_EN_RDMA1;
133         } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI0) {
134                 *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
135                 value = RDMA0_SOUT_DPI0;
136         } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI1) {
137                 *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
138                 value = RDMA0_SOUT_DPI1;
139         } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI1) {
140                 *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
141                 value = RDMA0_SOUT_DSI1;
142         } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI2) {
143                 *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
144                 value = RDMA0_SOUT_DSI2;
145         } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI3) {
146                 *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
147                 value = RDMA0_SOUT_DSI3;
148         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI1) {
149                 *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
150                 value = RDMA1_SOUT_DSI1;
151         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI2) {
152                 *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
153                 value = RDMA1_SOUT_DSI2;
154         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI3) {
155                 *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
156                 value = RDMA1_SOUT_DSI3;
157         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI0) {
158                 *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
159                 value = RDMA1_SOUT_DPI0;
160         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI1) {
161                 *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
162                 value = RDMA1_SOUT_DPI1;
163         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI0) {
164                 *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
165                 value = RDMA2_SOUT_DPI0;
166         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI1) {
167                 *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
168                 value = RDMA2_SOUT_DPI1;
169         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI1) {
170                 *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
171                 value = RDMA2_SOUT_DSI1;
172         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI2) {
173                 *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
174                 value = RDMA2_SOUT_DSI2;
175         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI3) {
176                 *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
177                 value = RDMA2_SOUT_DSI3;
178         } else {
179                 value = 0;
180         }
181
182         return value;
183 }
184
185 static unsigned int mtk_mmsys_ddp_sel_in(enum mtk_ddp_comp_id cur,
186                                          enum mtk_ddp_comp_id next,
187                                          unsigned int *addr)
188 {
189         unsigned int value;
190
191         if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) {
192                 *addr = DISP_REG_CONFIG_DISP_COLOR0_SEL_IN;
193                 value = COLOR0_SEL_IN_OVL0;
194         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI0) {
195                 *addr = DISP_REG_CONFIG_DPI_SEL_IN;
196                 value = DPI0_SEL_IN_RDMA1;
197         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI1) {
198                 *addr = DISP_REG_CONFIG_DPI_SEL_IN;
199                 value = DPI1_SEL_IN_RDMA1;
200         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI0) {
201                 *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
202                 value = DSI0_SEL_IN_RDMA1;
203         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI1) {
204                 *addr = DISP_REG_CONFIG_DSIO_SEL_IN;
205                 value = DSI1_SEL_IN_RDMA1;
206         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI2) {
207                 *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
208                 value = DSI2_SEL_IN_RDMA1;
209         } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI3) {
210                 *addr = DISP_REG_CONFIG_DSIO_SEL_IN;
211                 value = DSI3_SEL_IN_RDMA1;
212         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI0) {
213                 *addr = DISP_REG_CONFIG_DPI_SEL_IN;
214                 value = DPI0_SEL_IN_RDMA2;
215         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI1) {
216                 *addr = DISP_REG_CONFIG_DPI_SEL_IN;
217                 value = DPI1_SEL_IN_RDMA2;
218         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI0) {
219                 *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
220                 value = DSI0_SEL_IN_RDMA2;
221         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI1) {
222                 *addr = DISP_REG_CONFIG_DSIO_SEL_IN;
223                 value = DSI1_SEL_IN_RDMA2;
224         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI2) {
225                 *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
226                 value = DSI2_SEL_IN_RDMA2;
227         } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI3) {
228                 *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
229                 value = DSI3_SEL_IN_RDMA2;
230         } else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) {
231                 *addr = DISP_REG_CONFIG_DISP_COLOR1_SEL_IN;
232                 value = COLOR1_SEL_IN_OVL1;
233         } else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) {
234                 *addr = DISP_REG_CONFIG_DSI_SEL;
235                 value = DSI_SEL_IN_BLS;
236         } else {
237                 value = 0;
238         }
239
240         return value;
241 }
242
243 static void mtk_mmsys_ddp_sout_sel(void __iomem *config_regs,
244                                    enum mtk_ddp_comp_id cur,
245                                    enum mtk_ddp_comp_id next)
246 {
247         if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) {
248                 writel_relaxed(BLS_TO_DSI_RDMA1_TO_DPI1,
249                                config_regs + DISP_REG_CONFIG_OUT_SEL);
250         } else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DPI0) {
251                 writel_relaxed(BLS_TO_DPI_RDMA1_TO_DSI,
252                                config_regs + DISP_REG_CONFIG_OUT_SEL);
253                 writel_relaxed(DSI_SEL_IN_RDMA,
254                                config_regs + DISP_REG_CONFIG_DSI_SEL);
255                 writel_relaxed(DPI_SEL_IN_BLS,
256                                config_regs + DISP_REG_CONFIG_DPI_SEL);
257         }
258 }
259
260 void mtk_mmsys_ddp_connect(struct device *dev,
261                            enum mtk_ddp_comp_id cur,
262                            enum mtk_ddp_comp_id next)
263 {
264         void __iomem *config_regs = dev_get_drvdata(dev);
265         unsigned int addr, value, reg;
266
267         value = mtk_mmsys_ddp_mout_en(cur, next, &addr);
268         if (value) {
269                 reg = readl_relaxed(config_regs + addr) | value;
270                 writel_relaxed(reg, config_regs + addr);
271         }
272
273         mtk_mmsys_ddp_sout_sel(config_regs, cur, next);
274
275         value = mtk_mmsys_ddp_sel_in(cur, next, &addr);
276         if (value) {
277                 reg = readl_relaxed(config_regs + addr) | value;
278                 writel_relaxed(reg, config_regs + addr);
279         }
280 }
281 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_connect);
282
283 void mtk_mmsys_ddp_disconnect(struct device *dev,
284                               enum mtk_ddp_comp_id cur,
285                               enum mtk_ddp_comp_id next)
286 {
287         void __iomem *config_regs = dev_get_drvdata(dev);
288         unsigned int addr, value, reg;
289
290         value = mtk_mmsys_ddp_mout_en(cur, next, &addr);
291         if (value) {
292                 reg = readl_relaxed(config_regs + addr) & ~value;
293                 writel_relaxed(reg, config_regs + addr);
294         }
295
296         value = mtk_mmsys_ddp_sel_in(cur, next, &addr);
297         if (value) {
298                 reg = readl_relaxed(config_regs + addr) & ~value;
299                 writel_relaxed(reg, config_regs + addr);
300         }
301 }
302 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect);
303
304 static int mtk_mmsys_probe(struct platform_device *pdev)
305 {
306         const struct mtk_mmsys_driver_data *data;
307         struct device *dev = &pdev->dev;
308         struct platform_device *clks;
309         struct platform_device *drm;
310         void __iomem *config_regs;
311         struct resource *mem;
312         int ret;
313
314         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
315         config_regs = devm_ioremap_resource(dev, mem);
316         if (IS_ERR(config_regs)) {
317                 ret = PTR_ERR(config_regs);
318                 dev_err(dev, "Failed to ioremap mmsys-config resource: %d\n",
319                         ret);
320                 return ret;
321         }
322
323         platform_set_drvdata(pdev, config_regs);
324
325         data = of_device_get_match_data(&pdev->dev);
326
327         clks = platform_device_register_data(&pdev->dev, data->clk_driver,
328                                              PLATFORM_DEVID_AUTO, NULL, 0);
329         if (IS_ERR(clks))
330                 return PTR_ERR(clks);
331
332         drm = platform_device_register_data(&pdev->dev, "mediatek-drm",
333                                             PLATFORM_DEVID_AUTO, NULL, 0);
334         if (IS_ERR(drm)) {
335                 platform_device_unregister(clks);
336                 return PTR_ERR(drm);
337         }
338
339         return 0;
340 }
341
342 static const struct of_device_id of_match_mtk_mmsys[] = {
343         {
344                 .compatible = "mediatek,mt2701-mmsys",
345                 .data = &mt2701_mmsys_driver_data,
346         },
347         {
348                 .compatible = "mediatek,mt2712-mmsys",
349                 .data = &mt2712_mmsys_driver_data,
350         },
351         {
352                 .compatible = "mediatek,mt6779-mmsys",
353                 .data = &mt6779_mmsys_driver_data,
354         },
355         {
356                 .compatible = "mediatek,mt6797-mmsys",
357                 .data = &mt6797_mmsys_driver_data,
358         },
359         {
360                 .compatible = "mediatek,mt8173-mmsys",
361                 .data = &mt8173_mmsys_driver_data,
362         },
363         {
364                 .compatible = "mediatek,mt8183-mmsys",
365                 .data = &mt8183_mmsys_driver_data,
366         },
367         { }
368 };
369
370 static struct platform_driver mtk_mmsys_drv = {
371         .driver = {
372                 .name = "mtk-mmsys",
373                 .of_match_table = of_match_mtk_mmsys,
374         },
375         .probe = mtk_mmsys_probe,
376 };
377
378 builtin_platform_driver(mtk_mmsys_drv);
This page took 0.053209 seconds and 4 git commands to generate.