diff options
author | weiyi.lu@mediatek.com <weiyi.lu@mediatek.com> | 2017-10-23 00:10:34 -0400 |
---|---|---|
committer | Stephen Boyd <sboyd@codeaurora.org> | 2017-11-02 04:02:53 -0400 |
commit | e2f744a82d725ab55091cccfb8e527b4220471f0 (patch) | |
tree | 7e8776522ae45675ad1d48c52f25092facd97a0b | |
parent | b7f1a721bb3e493627d9db0a00edfb53c70ba823 (diff) |
clk: mediatek: Add MT2712 clock support
Add MT2712 clock support, include topckgen, apmixedsys,
infracfg, pericfg, mcucfg and subsystem clocks.
Signed-off-by: Weiyi Lu <weiyi.lu@mediatek.com>
[sboyd@codeaurora.org: Static on top_clk_data]
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-rw-r--r-- | drivers/clk/mediatek/Kconfig | 50 | ||||
-rw-r--r-- | drivers/clk/mediatek/Makefile | 8 | ||||
-rw-r--r-- | drivers/clk/mediatek/clk-mt2712-bdp.c | 102 | ||||
-rw-r--r-- | drivers/clk/mediatek/clk-mt2712-img.c | 80 | ||||
-rw-r--r-- | drivers/clk/mediatek/clk-mt2712-jpgdec.c | 76 | ||||
-rw-r--r-- | drivers/clk/mediatek/clk-mt2712-mfg.c | 75 | ||||
-rw-r--r-- | drivers/clk/mediatek/clk-mt2712-mm.c | 170 | ||||
-rw-r--r-- | drivers/clk/mediatek/clk-mt2712-vdec.c | 94 | ||||
-rw-r--r-- | drivers/clk/mediatek/clk-mt2712-venc.c | 77 | ||||
-rw-r--r-- | drivers/clk/mediatek/clk-mt2712.c | 1435 | ||||
-rw-r--r-- | drivers/clk/mediatek/clk-mtk.h | 2 | ||||
-rw-r--r-- | drivers/clk/mediatek/clk-pll.c | 13 |
12 files changed, 2180 insertions, 2 deletions
diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 28739a9a6e37..300dbb551bf7 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig | |||
@@ -50,6 +50,56 @@ config COMMON_CLK_MT2701_BDPSYS | |||
50 | ---help--- | 50 | ---help--- |
51 | This driver supports Mediatek MT2701 bdpsys clocks. | 51 | This driver supports Mediatek MT2701 bdpsys clocks. |
52 | 52 | ||
53 | config COMMON_CLK_MT2712 | ||
54 | bool "Clock driver for Mediatek MT2712" | ||
55 | depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST | ||
56 | select COMMON_CLK_MEDIATEK | ||
57 | default ARCH_MEDIATEK && ARM64 | ||
58 | ---help--- | ||
59 | This driver supports Mediatek MT2712 basic clocks. | ||
60 | |||
61 | config COMMON_CLK_MT2712_BDPSYS | ||
62 | bool "Clock driver for Mediatek MT2712 bdpsys" | ||
63 | depends on COMMON_CLK_MT2712 | ||
64 | ---help--- | ||
65 | This driver supports Mediatek MT2712 bdpsys clocks. | ||
66 | |||
67 | config COMMON_CLK_MT2712_IMGSYS | ||
68 | bool "Clock driver for Mediatek MT2712 imgsys" | ||
69 | depends on COMMON_CLK_MT2712 | ||
70 | ---help--- | ||
71 | This driver supports Mediatek MT2712 imgsys clocks. | ||
72 | |||
73 | config COMMON_CLK_MT2712_JPGDECSYS | ||
74 | bool "Clock driver for Mediatek MT2712 jpgdecsys" | ||
75 | depends on COMMON_CLK_MT2712 | ||
76 | ---help--- | ||
77 | This driver supports Mediatek MT2712 jpgdecsys clocks. | ||
78 | |||
79 | config COMMON_CLK_MT2712_MFGCFG | ||
80 | bool "Clock driver for Mediatek MT2712 mfgcfg" | ||
81 | depends on COMMON_CLK_MT2712 | ||
82 | ---help--- | ||
83 | This driver supports Mediatek MT2712 mfgcfg clocks. | ||
84 | |||
85 | config COMMON_CLK_MT2712_MMSYS | ||
86 | bool "Clock driver for Mediatek MT2712 mmsys" | ||
87 | depends on COMMON_CLK_MT2712 | ||
88 | ---help--- | ||
89 | This driver supports Mediatek MT2712 mmsys clocks. | ||
90 | |||
91 | config COMMON_CLK_MT2712_VDECSYS | ||
92 | bool "Clock driver for Mediatek MT2712 vdecsys" | ||
93 | depends on COMMON_CLK_MT2712 | ||
94 | ---help--- | ||
95 | This driver supports Mediatek MT2712 vdecsys clocks. | ||
96 | |||
97 | config COMMON_CLK_MT2712_VENCSYS | ||
98 | bool "Clock driver for Mediatek MT2712 vencsys" | ||
99 | depends on COMMON_CLK_MT2712 | ||
100 | ---help--- | ||
101 | This driver supports Mediatek MT2712 vencsys clocks. | ||
102 | |||
53 | config COMMON_CLK_MT6797 | 103 | config COMMON_CLK_MT6797 |
54 | bool "Clock driver for Mediatek MT6797" | 104 | bool "Clock driver for Mediatek MT6797" |
55 | depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST | 105 | depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST |
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 2a755b5fb51b..a4e5c47c73a4 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile | |||
@@ -12,5 +12,13 @@ obj-$(CONFIG_COMMON_CLK_MT2701_HIFSYS) += clk-mt2701-hif.o | |||
12 | obj-$(CONFIG_COMMON_CLK_MT2701_IMGSYS) += clk-mt2701-img.o | 12 | obj-$(CONFIG_COMMON_CLK_MT2701_IMGSYS) += clk-mt2701-img.o |
13 | obj-$(CONFIG_COMMON_CLK_MT2701_MMSYS) += clk-mt2701-mm.o | 13 | obj-$(CONFIG_COMMON_CLK_MT2701_MMSYS) += clk-mt2701-mm.o |
14 | obj-$(CONFIG_COMMON_CLK_MT2701_VDECSYS) += clk-mt2701-vdec.o | 14 | obj-$(CONFIG_COMMON_CLK_MT2701_VDECSYS) += clk-mt2701-vdec.o |
15 | obj-$(CONFIG_COMMON_CLK_MT2712) += clk-mt2712.o | ||
16 | obj-$(CONFIG_COMMON_CLK_MT2712_BDPSYS) += clk-mt2712-bdp.o | ||
17 | obj-$(CONFIG_COMMON_CLK_MT2712_IMGSYS) += clk-mt2712-img.o | ||
18 | obj-$(CONFIG_COMMON_CLK_MT2712_JPGDECSYS) += clk-mt2712-jpgdec.o | ||
19 | obj-$(CONFIG_COMMON_CLK_MT2712_MFGCFG) += clk-mt2712-mfg.o | ||
20 | obj-$(CONFIG_COMMON_CLK_MT2712_MMSYS) += clk-mt2712-mm.o | ||
21 | obj-$(CONFIG_COMMON_CLK_MT2712_VDECSYS) += clk-mt2712-vdec.o | ||
22 | obj-$(CONFIG_COMMON_CLK_MT2712_VENCSYS) += clk-mt2712-venc.o | ||
15 | obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o | 23 | obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o |
16 | obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o | 24 | obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o |
diff --git a/drivers/clk/mediatek/clk-mt2712-bdp.c b/drivers/clk/mediatek/clk-mt2712-bdp.c new file mode 100644 index 000000000000..5fe4728c076e --- /dev/null +++ b/drivers/clk/mediatek/clk-mt2712-bdp.c | |||
@@ -0,0 +1,102 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2017 MediaTek Inc. | ||
3 | * Author: Weiyi Lu <weiyi.lu@mediatek.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/clk-provider.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #include "clk-mtk.h" | ||
19 | #include "clk-gate.h" | ||
20 | |||
21 | #include <dt-bindings/clock/mt2712-clk.h> | ||
22 | |||
23 | static const struct mtk_gate_regs bdp_cg_regs = { | ||
24 | .set_ofs = 0x100, | ||
25 | .clr_ofs = 0x100, | ||
26 | .sta_ofs = 0x100, | ||
27 | }; | ||
28 | |||
29 | #define GATE_BDP(_id, _name, _parent, _shift) { \ | ||
30 | .id = _id, \ | ||
31 | .name = _name, \ | ||
32 | .parent_name = _parent, \ | ||
33 | .regs = &bdp_cg_regs, \ | ||
34 | .shift = _shift, \ | ||
35 | .ops = &mtk_clk_gate_ops_no_setclr, \ | ||
36 | } | ||
37 | |||
38 | static const struct mtk_gate bdp_clks[] = { | ||
39 | GATE_BDP(CLK_BDP_BRIDGE_B, "bdp_bridge_b", "mm_sel", 0), | ||
40 | GATE_BDP(CLK_BDP_BRIDGE_DRAM, "bdp_bridge_d", "mm_sel", 1), | ||
41 | GATE_BDP(CLK_BDP_LARB_DRAM, "bdp_larb_d", "mm_sel", 2), | ||
42 | GATE_BDP(CLK_BDP_WR_CHANNEL_VDI_PXL, "bdp_vdi_pxl", "tvd_sel", 3), | ||
43 | GATE_BDP(CLK_BDP_WR_CHANNEL_VDI_DRAM, "bdp_vdi_d", "mm_sel", 4), | ||
44 | GATE_BDP(CLK_BDP_WR_CHANNEL_VDI_B, "bdp_vdi_b", "mm_sel", 5), | ||
45 | GATE_BDP(CLK_BDP_MT_B, "bdp_fmt_b", "mm_sel", 9), | ||
46 | GATE_BDP(CLK_BDP_DISPFMT_27M, "bdp_27m", "di_sel", 10), | ||
47 | GATE_BDP(CLK_BDP_DISPFMT_27M_VDOUT, "bdp_27m_vdout", "di_sel", 11), | ||
48 | GATE_BDP(CLK_BDP_DISPFMT_27_74_74, "bdp_27_74_74", "di_sel", 12), | ||
49 | GATE_BDP(CLK_BDP_DISPFMT_2FS, "bdp_2fs", "di_sel", 13), | ||
50 | GATE_BDP(CLK_BDP_DISPFMT_2FS_2FS74_148, "bdp_2fs74_148", "di_sel", 14), | ||
51 | GATE_BDP(CLK_BDP_DISPFMT_B, "bdp_b", "mm_sel", 15), | ||
52 | GATE_BDP(CLK_BDP_VDO_DRAM, "bdp_vdo_d", "mm_sel", 16), | ||
53 | GATE_BDP(CLK_BDP_VDO_2FS, "bdp_vdo_2fs", "di_sel", 17), | ||
54 | GATE_BDP(CLK_BDP_VDO_B, "bdp_vdo_b", "mm_sel", 18), | ||
55 | GATE_BDP(CLK_BDP_WR_CHANNEL_DI_PXL, "bdp_di_pxl", "di_sel", 19), | ||
56 | GATE_BDP(CLK_BDP_WR_CHANNEL_DI_DRAM, "bdp_di_d", "mm_sel", 20), | ||
57 | GATE_BDP(CLK_BDP_WR_CHANNEL_DI_B, "bdp_di_b", "mm_sel", 21), | ||
58 | GATE_BDP(CLK_BDP_NR_AGENT, "bdp_nr_agent", "nr_sel", 22), | ||
59 | GATE_BDP(CLK_BDP_NR_DRAM, "bdp_nr_d", "mm_sel", 23), | ||
60 | GATE_BDP(CLK_BDP_NR_B, "bdp_nr_b", "mm_sel", 24), | ||
61 | GATE_BDP(CLK_BDP_BRIDGE_RT_B, "bdp_bridge_rt_b", "mm_sel", 25), | ||
62 | GATE_BDP(CLK_BDP_BRIDGE_RT_DRAM, "bdp_bridge_rt_d", "mm_sel", 26), | ||
63 | GATE_BDP(CLK_BDP_LARB_RT_DRAM, "bdp_larb_rt_d", "mm_sel", 27), | ||
64 | GATE_BDP(CLK_BDP_TVD_TDC, "bdp_tvd_tdc", "mm_sel", 28), | ||
65 | GATE_BDP(CLK_BDP_TVD_54, "bdp_tvd_clk_54", "tvd_sel", 29), | ||
66 | GATE_BDP(CLK_BDP_TVD_CBUS, "bdp_tvd_cbus", "mm_sel", 30), | ||
67 | }; | ||
68 | |||
69 | static int clk_mt2712_bdp_probe(struct platform_device *pdev) | ||
70 | { | ||
71 | struct clk_onecell_data *clk_data; | ||
72 | int r; | ||
73 | struct device_node *node = pdev->dev.of_node; | ||
74 | |||
75 | clk_data = mtk_alloc_clk_data(CLK_BDP_NR_CLK); | ||
76 | |||
77 | mtk_clk_register_gates(node, bdp_clks, ARRAY_SIZE(bdp_clks), | ||
78 | clk_data); | ||
79 | |||
80 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
81 | |||
82 | if (r != 0) | ||
83 | pr_err("%s(): could not register clock provider: %d\n", | ||
84 | __func__, r); | ||
85 | |||
86 | return r; | ||
87 | } | ||
88 | |||
89 | static const struct of_device_id of_match_clk_mt2712_bdp[] = { | ||
90 | { .compatible = "mediatek,mt2712-bdpsys", }, | ||
91 | {} | ||
92 | }; | ||
93 | |||
94 | static struct platform_driver clk_mt2712_bdp_drv = { | ||
95 | .probe = clk_mt2712_bdp_probe, | ||
96 | .driver = { | ||
97 | .name = "clk-mt2712-bdp", | ||
98 | .of_match_table = of_match_clk_mt2712_bdp, | ||
99 | }, | ||
100 | }; | ||
101 | |||
102 | builtin_platform_driver(clk_mt2712_bdp_drv); | ||
diff --git a/drivers/clk/mediatek/clk-mt2712-img.c b/drivers/clk/mediatek/clk-mt2712-img.c new file mode 100644 index 000000000000..139ff55d495e --- /dev/null +++ b/drivers/clk/mediatek/clk-mt2712-img.c | |||
@@ -0,0 +1,80 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2017 MediaTek Inc. | ||
3 | * Author: Weiyi Lu <weiyi.lu@mediatek.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/clk-provider.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #include "clk-mtk.h" | ||
19 | #include "clk-gate.h" | ||
20 | |||
21 | #include <dt-bindings/clock/mt2712-clk.h> | ||
22 | |||
23 | static const struct mtk_gate_regs img_cg_regs = { | ||
24 | .set_ofs = 0x0, | ||
25 | .clr_ofs = 0x0, | ||
26 | .sta_ofs = 0x0, | ||
27 | }; | ||
28 | |||
29 | #define GATE_IMG(_id, _name, _parent, _shift) { \ | ||
30 | .id = _id, \ | ||
31 | .name = _name, \ | ||
32 | .parent_name = _parent, \ | ||
33 | .regs = &img_cg_regs, \ | ||
34 | .shift = _shift, \ | ||
35 | .ops = &mtk_clk_gate_ops_no_setclr, \ | ||
36 | } | ||
37 | |||
38 | static const struct mtk_gate img_clks[] = { | ||
39 | GATE_IMG(CLK_IMG_SMI_LARB2, "img_smi_larb2", "mm_sel", 0), | ||
40 | GATE_IMG(CLK_IMG_SENINF_SCAM_EN, "img_scam_en", "csi0", 3), | ||
41 | GATE_IMG(CLK_IMG_SENINF_CAM_EN, "img_cam_en", "mm_sel", 8), | ||
42 | GATE_IMG(CLK_IMG_CAM_SV_EN, "img_cam_sv_en", "mm_sel", 9), | ||
43 | GATE_IMG(CLK_IMG_CAM_SV1_EN, "img_cam_sv1_en", "mm_sel", 10), | ||
44 | GATE_IMG(CLK_IMG_CAM_SV2_EN, "img_cam_sv2_en", "mm_sel", 11), | ||
45 | }; | ||
46 | |||
47 | static int clk_mt2712_img_probe(struct platform_device *pdev) | ||
48 | { | ||
49 | struct clk_onecell_data *clk_data; | ||
50 | int r; | ||
51 | struct device_node *node = pdev->dev.of_node; | ||
52 | |||
53 | clk_data = mtk_alloc_clk_data(CLK_IMG_NR_CLK); | ||
54 | |||
55 | mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks), | ||
56 | clk_data); | ||
57 | |||
58 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
59 | |||
60 | if (r != 0) | ||
61 | pr_err("%s(): could not register clock provider: %d\n", | ||
62 | __func__, r); | ||
63 | |||
64 | return r; | ||
65 | } | ||
66 | |||
67 | static const struct of_device_id of_match_clk_mt2712_img[] = { | ||
68 | { .compatible = "mediatek,mt2712-imgsys", }, | ||
69 | {} | ||
70 | }; | ||
71 | |||
72 | static struct platform_driver clk_mt2712_img_drv = { | ||
73 | .probe = clk_mt2712_img_probe, | ||
74 | .driver = { | ||
75 | .name = "clk-mt2712-img", | ||
76 | .of_match_table = of_match_clk_mt2712_img, | ||
77 | }, | ||
78 | }; | ||
79 | |||
80 | builtin_platform_driver(clk_mt2712_img_drv); | ||
diff --git a/drivers/clk/mediatek/clk-mt2712-jpgdec.c b/drivers/clk/mediatek/clk-mt2712-jpgdec.c new file mode 100644 index 000000000000..c7d4aada4892 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt2712-jpgdec.c | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2017 MediaTek Inc. | ||
3 | * Author: Weiyi Lu <weiyi.lu@mediatek.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/clk-provider.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #include "clk-mtk.h" | ||
19 | #include "clk-gate.h" | ||
20 | |||
21 | #include <dt-bindings/clock/mt2712-clk.h> | ||
22 | |||
23 | static const struct mtk_gate_regs jpgdec_cg_regs = { | ||
24 | .set_ofs = 0x4, | ||
25 | .clr_ofs = 0x8, | ||
26 | .sta_ofs = 0x0, | ||
27 | }; | ||
28 | |||
29 | #define GATE_JPGDEC(_id, _name, _parent, _shift) { \ | ||
30 | .id = _id, \ | ||
31 | .name = _name, \ | ||
32 | .parent_name = _parent, \ | ||
33 | .regs = &jpgdec_cg_regs, \ | ||
34 | .shift = _shift, \ | ||
35 | .ops = &mtk_clk_gate_ops_setclr_inv, \ | ||
36 | } | ||
37 | |||
38 | static const struct mtk_gate jpgdec_clks[] = { | ||
39 | GATE_JPGDEC(CLK_JPGDEC_JPGDEC1, "jpgdec_jpgdec1", "jpgdec_sel", 0), | ||
40 | GATE_JPGDEC(CLK_JPGDEC_JPGDEC, "jpgdec_jpgdec", "jpgdec_sel", 4), | ||
41 | }; | ||
42 | |||
43 | static int clk_mt2712_jpgdec_probe(struct platform_device *pdev) | ||
44 | { | ||
45 | struct clk_onecell_data *clk_data; | ||
46 | int r; | ||
47 | struct device_node *node = pdev->dev.of_node; | ||
48 | |||
49 | clk_data = mtk_alloc_clk_data(CLK_JPGDEC_NR_CLK); | ||
50 | |||
51 | mtk_clk_register_gates(node, jpgdec_clks, ARRAY_SIZE(jpgdec_clks), | ||
52 | clk_data); | ||
53 | |||
54 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
55 | |||
56 | if (r != 0) | ||
57 | pr_err("%s(): could not register clock provider: %d\n", | ||
58 | __func__, r); | ||
59 | |||
60 | return r; | ||
61 | } | ||
62 | |||
63 | static const struct of_device_id of_match_clk_mt2712_jpgdec[] = { | ||
64 | { .compatible = "mediatek,mt2712-jpgdecsys", }, | ||
65 | {} | ||
66 | }; | ||
67 | |||
68 | static struct platform_driver clk_mt2712_jpgdec_drv = { | ||
69 | .probe = clk_mt2712_jpgdec_probe, | ||
70 | .driver = { | ||
71 | .name = "clk-mt2712-jpgdec", | ||
72 | .of_match_table = of_match_clk_mt2712_jpgdec, | ||
73 | }, | ||
74 | }; | ||
75 | |||
76 | builtin_platform_driver(clk_mt2712_jpgdec_drv); | ||
diff --git a/drivers/clk/mediatek/clk-mt2712-mfg.c b/drivers/clk/mediatek/clk-mt2712-mfg.c new file mode 100644 index 000000000000..570f72d48d4d --- /dev/null +++ b/drivers/clk/mediatek/clk-mt2712-mfg.c | |||
@@ -0,0 +1,75 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2017 MediaTek Inc. | ||
3 | * Author: Weiyi Lu <weiyi.lu@mediatek.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/clk-provider.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #include "clk-mtk.h" | ||
19 | #include "clk-gate.h" | ||
20 | |||
21 | #include <dt-bindings/clock/mt2712-clk.h> | ||
22 | |||
23 | static const struct mtk_gate_regs mfg_cg_regs = { | ||
24 | .set_ofs = 0x4, | ||
25 | .clr_ofs = 0x8, | ||
26 | .sta_ofs = 0x0, | ||
27 | }; | ||
28 | |||
29 | #define GATE_MFG(_id, _name, _parent, _shift) { \ | ||
30 | .id = _id, \ | ||
31 | .name = _name, \ | ||
32 | .parent_name = _parent, \ | ||
33 | .regs = &mfg_cg_regs, \ | ||
34 | .shift = _shift, \ | ||
35 | .ops = &mtk_clk_gate_ops_setclr, \ | ||
36 | } | ||
37 | |||
38 | static const struct mtk_gate mfg_clks[] = { | ||
39 | GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_sel", 0), | ||
40 | }; | ||
41 | |||
42 | static int clk_mt2712_mfg_probe(struct platform_device *pdev) | ||
43 | { | ||
44 | struct clk_onecell_data *clk_data; | ||
45 | int r; | ||
46 | struct device_node *node = pdev->dev.of_node; | ||
47 | |||
48 | clk_data = mtk_alloc_clk_data(CLK_MFG_NR_CLK); | ||
49 | |||
50 | mtk_clk_register_gates(node, mfg_clks, ARRAY_SIZE(mfg_clks), | ||
51 | clk_data); | ||
52 | |||
53 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
54 | |||
55 | if (r != 0) | ||
56 | pr_err("%s(): could not register clock provider: %d\n", | ||
57 | __func__, r); | ||
58 | |||
59 | return r; | ||
60 | } | ||
61 | |||
62 | static const struct of_device_id of_match_clk_mt2712_mfg[] = { | ||
63 | { .compatible = "mediatek,mt2712-mfgcfg", }, | ||
64 | {} | ||
65 | }; | ||
66 | |||
67 | static struct platform_driver clk_mt2712_mfg_drv = { | ||
68 | .probe = clk_mt2712_mfg_probe, | ||
69 | .driver = { | ||
70 | .name = "clk-mt2712-mfg", | ||
71 | .of_match_table = of_match_clk_mt2712_mfg, | ||
72 | }, | ||
73 | }; | ||
74 | |||
75 | builtin_platform_driver(clk_mt2712_mfg_drv); | ||
diff --git a/drivers/clk/mediatek/clk-mt2712-mm.c b/drivers/clk/mediatek/clk-mt2712-mm.c new file mode 100644 index 000000000000..a8b4b6d42488 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt2712-mm.c | |||
@@ -0,0 +1,170 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2017 MediaTek Inc. | ||
3 | * Author: Weiyi Lu <weiyi.lu@mediatek.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/clk-provider.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #include "clk-mtk.h" | ||
19 | #include "clk-gate.h" | ||
20 | |||
21 | #include <dt-bindings/clock/mt2712-clk.h> | ||
22 | |||
23 | static const struct mtk_gate_regs mm0_cg_regs = { | ||
24 | .set_ofs = 0x104, | ||
25 | .clr_ofs = 0x108, | ||
26 | .sta_ofs = 0x100, | ||
27 | }; | ||
28 | |||
29 | static const struct mtk_gate_regs mm1_cg_regs = { | ||
30 | .set_ofs = 0x114, | ||
31 | .clr_ofs = 0x118, | ||
32 | .sta_ofs = 0x110, | ||
33 | }; | ||
34 | |||
35 | static const struct mtk_gate_regs mm2_cg_regs = { | ||
36 | .set_ofs = 0x224, | ||
37 | .clr_ofs = 0x228, | ||
38 | .sta_ofs = 0x220, | ||
39 | }; | ||
40 | |||
41 | #define GATE_MM0(_id, _name, _parent, _shift) { \ | ||
42 | .id = _id, \ | ||
43 | .name = _name, \ | ||
44 | .parent_name = _parent, \ | ||
45 | .regs = &mm0_cg_regs, \ | ||
46 | .shift = _shift, \ | ||
47 | .ops = &mtk_clk_gate_ops_setclr, \ | ||
48 | } | ||
49 | |||
50 | #define GATE_MM1(_id, _name, _parent, _shift) { \ | ||
51 | .id = _id, \ | ||
52 | .name = _name, \ | ||
53 | .parent_name = _parent, \ | ||
54 | .regs = &mm1_cg_regs, \ | ||
55 | .shift = _shift, \ | ||
56 | .ops = &mtk_clk_gate_ops_setclr, \ | ||
57 | } | ||
58 | |||
59 | #define GATE_MM2(_id, _name, _parent, _shift) { \ | ||
60 | .id = _id, \ | ||
61 | .name = _name, \ | ||
62 | .parent_name = _parent, \ | ||
63 | .regs = &mm2_cg_regs, \ | ||
64 | .shift = _shift, \ | ||
65 | .ops = &mtk_clk_gate_ops_setclr, \ | ||
66 | } | ||
67 | |||
68 | static const struct mtk_gate mm_clks[] = { | ||
69 | /* MM0 */ | ||
70 | GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 0), | ||
71 | GATE_MM0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1), | ||
72 | GATE_MM0(CLK_MM_CAM_MDP, "mm_cam_mdp", "mm_sel", 2), | ||
73 | GATE_MM0(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_sel", 3), | ||
74 | GATE_MM0(CLK_MM_MDP_RDMA1, "mm_mdp_rdma1", "mm_sel", 4), | ||
75 | GATE_MM0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 5), | ||
76 | GATE_MM0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 6), | ||
77 | GATE_MM0(CLK_MM_MDP_RSZ2, "mm_mdp_rsz2", "mm_sel", 7), | ||
78 | GATE_MM0(CLK_MM_MDP_TDSHP0, "mm_mdp_tdshp0", "mm_sel", 8), | ||
79 | GATE_MM0(CLK_MM_MDP_TDSHP1, "mm_mdp_tdshp1", "mm_sel", 9), | ||
80 | GATE_MM0(CLK_MM_MDP_CROP, "mm_mdp_crop", "mm_sel", 10), | ||
81 | GATE_MM0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "mm_sel", 11), | ||
82 | GATE_MM0(CLK_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_sel", 12), | ||
83 | GATE_MM0(CLK_MM_MDP_WROT1, "mm_mdp_wrot1", "mm_sel", 13), | ||
84 | GATE_MM0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 14), | ||
85 | GATE_MM0(CLK_MM_MUTEX_32K, "mm_mutex_32k", "clk32k", 15), | ||
86 | GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "mm_sel", 16), | ||
87 | GATE_MM0(CLK_MM_DISP_OVL1, "mm_disp_ovl1", "mm_sel", 17), | ||
88 | GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_sel", 18), | ||
89 | GATE_MM0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 19), | ||
90 | GATE_MM0(CLK_MM_DISP_RDMA2, "mm_disp_rdma2", "mm_sel", 20), | ||
91 | GATE_MM0(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_sel", 21), | ||
92 | GATE_MM0(CLK_MM_DISP_WDMA1, "mm_disp_wdma1", "mm_sel", 22), | ||
93 | GATE_MM0(CLK_MM_DISP_COLOR0, "mm_disp_color0", "mm_sel", 23), | ||
94 | GATE_MM0(CLK_MM_DISP_COLOR1, "mm_disp_color1", "mm_sel", 24), | ||
95 | GATE_MM0(CLK_MM_DISP_AAL, "mm_disp_aal", "mm_sel", 25), | ||
96 | GATE_MM0(CLK_MM_DISP_GAMMA, "mm_disp_gamma", "mm_sel", 26), | ||
97 | GATE_MM0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "mm_sel", 27), | ||
98 | GATE_MM0(CLK_MM_DISP_SPLIT0, "mm_disp_split0", "mm_sel", 28), | ||
99 | GATE_MM0(CLK_MM_DISP_OD, "mm_disp_od", "mm_sel", 31), | ||
100 | /* MM1 */ | ||
101 | GATE_MM1(CLK_MM_DISP_PWM0_MM, "mm_pwm0_mm", "mm_sel", 0), | ||
102 | GATE_MM1(CLK_MM_DISP_PWM0_26M, "mm_pwm0_26m", "pwm_sel", 1), | ||
103 | GATE_MM1(CLK_MM_DISP_PWM1_MM, "mm_pwm1_mm", "mm_sel", 2), | ||
104 | GATE_MM1(CLK_MM_DISP_PWM1_26M, "mm_pwm1_26m", "pwm_sel", 3), | ||
105 | GATE_MM1(CLK_MM_DSI0_ENGINE, "mm_dsi0_engine", "mm_sel", 4), | ||
106 | GATE_MM1(CLK_MM_DSI0_DIGITAL, "mm_dsi0_digital", "dsi0_lntc", 5), | ||
107 | GATE_MM1(CLK_MM_DSI1_ENGINE, "mm_dsi1_engine", "mm_sel", 6), | ||
108 | GATE_MM1(CLK_MM_DSI1_DIGITAL, "mm_dsi1_digital", "dsi1_lntc", 7), | ||
109 | GATE_MM1(CLK_MM_DPI_PIXEL, "mm_dpi_pixel", "vpll_dpix", 8), | ||
110 | GATE_MM1(CLK_MM_DPI_ENGINE, "mm_dpi_engine", "mm_sel", 9), | ||
111 | GATE_MM1(CLK_MM_DPI1_PIXEL, "mm_dpi1_pixel", "vpll3_dpix", 10), | ||
112 | GATE_MM1(CLK_MM_DPI1_ENGINE, "mm_dpi1_engine", "mm_sel", 11), | ||
113 | GATE_MM1(CLK_MM_LVDS_PIXEL, "mm_lvds_pixel", "vpll_dpix", 16), | ||
114 | GATE_MM1(CLK_MM_LVDS_CTS, "mm_lvds_cts", "lvdstx", 17), | ||
115 | GATE_MM1(CLK_MM_SMI_LARB4, "mm_smi_larb4", "mm_sel", 18), | ||
116 | GATE_MM1(CLK_MM_SMI_COMMON1, "mm_smi_common1", "mm_sel", 21), | ||
117 | GATE_MM1(CLK_MM_SMI_LARB5, "mm_smi_larb5", "mm_sel", 22), | ||
118 | GATE_MM1(CLK_MM_MDP_RDMA2, "mm_mdp_rdma2", "mm_sel", 23), | ||
119 | GATE_MM1(CLK_MM_MDP_TDSHP2, "mm_mdp_tdshp2", "mm_sel", 24), | ||
120 | GATE_MM1(CLK_MM_DISP_OVL2, "mm_disp_ovl2", "mm_sel", 25), | ||
121 | GATE_MM1(CLK_MM_DISP_WDMA2, "mm_disp_wdma2", "mm_sel", 26), | ||
122 | GATE_MM1(CLK_MM_DISP_COLOR2, "mm_disp_color2", "mm_sel", 27), | ||
123 | GATE_MM1(CLK_MM_DISP_AAL1, "mm_disp_aal1", "mm_sel", 28), | ||
124 | GATE_MM1(CLK_MM_DISP_OD1, "mm_disp_od1", "mm_sel", 29), | ||
125 | GATE_MM1(CLK_MM_LVDS1_PIXEL, "mm_lvds1_pixel", "vpll3_dpix", 30), | ||
126 | GATE_MM1(CLK_MM_LVDS1_CTS, "mm_lvds1_cts", "lvdstx3", 31), | ||
127 | /* MM2 */ | ||
128 | GATE_MM2(CLK_MM_SMI_LARB7, "mm_smi_larb7", "mm_sel", 0), | ||
129 | GATE_MM2(CLK_MM_MDP_RDMA3, "mm_mdp_rdma3", "mm_sel", 1), | ||
130 | GATE_MM2(CLK_MM_MDP_WROT2, "mm_mdp_wrot2", "mm_sel", 2), | ||
131 | GATE_MM2(CLK_MM_DSI2, "mm_dsi2", "mm_sel", 3), | ||
132 | GATE_MM2(CLK_MM_DSI2_DIGITAL, "mm_dsi2_digital", "dsi0_lntc", 4), | ||
133 | GATE_MM2(CLK_MM_DSI3, "mm_dsi3", "mm_sel", 5), | ||
134 | GATE_MM2(CLK_MM_DSI3_DIGITAL, "mm_dsi3_digital", "dsi1_lntc", 6), | ||
135 | }; | ||
136 | |||
137 | static int clk_mt2712_mm_probe(struct platform_device *pdev) | ||
138 | { | ||
139 | struct clk_onecell_data *clk_data; | ||
140 | int r; | ||
141 | struct device_node *node = pdev->dev.of_node; | ||
142 | |||
143 | clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK); | ||
144 | |||
145 | mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks), | ||
146 | clk_data); | ||
147 | |||
148 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
149 | |||
150 | if (r != 0) | ||
151 | pr_err("%s(): could not register clock provider: %d\n", | ||
152 | __func__, r); | ||
153 | |||
154 | return r; | ||
155 | } | ||
156 | |||
157 | static const struct of_device_id of_match_clk_mt2712_mm[] = { | ||
158 | { .compatible = "mediatek,mt2712-mmsys", }, | ||
159 | {} | ||
160 | }; | ||
161 | |||
162 | static struct platform_driver clk_mt2712_mm_drv = { | ||
163 | .probe = clk_mt2712_mm_probe, | ||
164 | .driver = { | ||
165 | .name = "clk-mt2712-mm", | ||
166 | .of_match_table = of_match_clk_mt2712_mm, | ||
167 | }, | ||
168 | }; | ||
169 | |||
170 | builtin_platform_driver(clk_mt2712_mm_drv); | ||
diff --git a/drivers/clk/mediatek/clk-mt2712-vdec.c b/drivers/clk/mediatek/clk-mt2712-vdec.c new file mode 100644 index 000000000000..55c64ee8cc91 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt2712-vdec.c | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2017 MediaTek Inc. | ||
3 | * Author: Weiyi Lu <weiyi.lu@mediatek.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/clk-provider.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #include "clk-mtk.h" | ||
19 | #include "clk-gate.h" | ||
20 | |||
21 | #include <dt-bindings/clock/mt2712-clk.h> | ||
22 | |||
23 | static const struct mtk_gate_regs vdec0_cg_regs = { | ||
24 | .set_ofs = 0x0, | ||
25 | .clr_ofs = 0x4, | ||
26 | .sta_ofs = 0x0, | ||
27 | }; | ||
28 | |||
29 | static const struct mtk_gate_regs vdec1_cg_regs = { | ||
30 | .set_ofs = 0x8, | ||
31 | .clr_ofs = 0xc, | ||
32 | .sta_ofs = 0x8, | ||
33 | }; | ||
34 | |||
35 | #define GATE_VDEC0(_id, _name, _parent, _shift) { \ | ||
36 | .id = _id, \ | ||
37 | .name = _name, \ | ||
38 | .parent_name = _parent, \ | ||
39 | .regs = &vdec0_cg_regs, \ | ||
40 | .shift = _shift, \ | ||
41 | .ops = &mtk_clk_gate_ops_setclr_inv, \ | ||
42 | } | ||
43 | |||
44 | #define GATE_VDEC1(_id, _name, _parent, _shift) { \ | ||
45 | .id = _id, \ | ||
46 | .name = _name, \ | ||
47 | .parent_name = _parent, \ | ||
48 | .regs = &vdec1_cg_regs, \ | ||
49 | .shift = _shift, \ | ||
50 | .ops = &mtk_clk_gate_ops_setclr_inv, \ | ||
51 | } | ||
52 | |||
53 | static const struct mtk_gate vdec_clks[] = { | ||
54 | /* VDEC0 */ | ||
55 | GATE_VDEC0(CLK_VDEC_CKEN, "vdec_cken", "vdec_sel", 0), | ||
56 | /* VDEC1 */ | ||
57 | GATE_VDEC1(CLK_VDEC_LARB1_CKEN, "vdec_larb1_cken", "vdec_sel", 0), | ||
58 | GATE_VDEC1(CLK_VDEC_IMGRZ_CKEN, "vdec_imgrz_cken", "vdec_sel", 1), | ||
59 | }; | ||
60 | |||
61 | static int clk_mt2712_vdec_probe(struct platform_device *pdev) | ||
62 | { | ||
63 | struct clk_onecell_data *clk_data; | ||
64 | int r; | ||
65 | struct device_node *node = pdev->dev.of_node; | ||
66 | |||
67 | clk_data = mtk_alloc_clk_data(CLK_VDEC_NR_CLK); | ||
68 | |||
69 | mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks), | ||
70 | clk_data); | ||
71 | |||
72 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
73 | |||
74 | if (r != 0) | ||
75 | pr_err("%s(): could not register clock provider: %d\n", | ||
76 | __func__, r); | ||
77 | |||
78 | return r; | ||
79 | } | ||
80 | |||
81 | static const struct of_device_id of_match_clk_mt2712_vdec[] = { | ||
82 | { .compatible = "mediatek,mt2712-vdecsys", }, | ||
83 | {} | ||
84 | }; | ||
85 | |||
86 | static struct platform_driver clk_mt2712_vdec_drv = { | ||
87 | .probe = clk_mt2712_vdec_probe, | ||
88 | .driver = { | ||
89 | .name = "clk-mt2712-vdec", | ||
90 | .of_match_table = of_match_clk_mt2712_vdec, | ||
91 | }, | ||
92 | }; | ||
93 | |||
94 | builtin_platform_driver(clk_mt2712_vdec_drv); | ||
diff --git a/drivers/clk/mediatek/clk-mt2712-venc.c b/drivers/clk/mediatek/clk-mt2712-venc.c new file mode 100644 index 000000000000..ccbfe98777c8 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt2712-venc.c | |||
@@ -0,0 +1,77 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2017 MediaTek Inc. | ||
3 | * Author: Weiyi Lu <weiyi.lu@mediatek.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/clk-provider.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #include "clk-mtk.h" | ||
19 | #include "clk-gate.h" | ||
20 | |||
21 | #include <dt-bindings/clock/mt2712-clk.h> | ||
22 | |||
23 | static const struct mtk_gate_regs venc_cg_regs = { | ||
24 | .set_ofs = 0x4, | ||
25 | .clr_ofs = 0x8, | ||
26 | .sta_ofs = 0x0, | ||
27 | }; | ||
28 | |||
29 | #define GATE_VENC(_id, _name, _parent, _shift) { \ | ||
30 | .id = _id, \ | ||
31 | .name = _name, \ | ||
32 | .parent_name = _parent, \ | ||
33 | .regs = &venc_cg_regs, \ | ||
34 | .shift = _shift, \ | ||
35 | .ops = &mtk_clk_gate_ops_setclr_inv, \ | ||
36 | } | ||
37 | |||
38 | static const struct mtk_gate venc_clks[] = { | ||
39 | GATE_VENC(CLK_VENC_SMI_COMMON_CON, "venc_smi", "mm_sel", 0), | ||
40 | GATE_VENC(CLK_VENC_VENC, "venc_venc", "venc_sel", 4), | ||
41 | GATE_VENC(CLK_VENC_SMI_LARB6, "venc_smi_larb6", "jpgdec_sel", 12), | ||
42 | }; | ||
43 | |||
44 | static int clk_mt2712_venc_probe(struct platform_device *pdev) | ||
45 | { | ||
46 | struct clk_onecell_data *clk_data; | ||
47 | int r; | ||
48 | struct device_node *node = pdev->dev.of_node; | ||
49 | |||
50 | clk_data = mtk_alloc_clk_data(CLK_VENC_NR_CLK); | ||
51 | |||
52 | mtk_clk_register_gates(node, venc_clks, ARRAY_SIZE(venc_clks), | ||
53 | clk_data); | ||
54 | |||
55 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
56 | |||
57 | if (r != 0) | ||
58 | pr_err("%s(): could not register clock provider: %d\n", | ||
59 | __func__, r); | ||
60 | |||
61 | return r; | ||
62 | } | ||
63 | |||
64 | static const struct of_device_id of_match_clk_mt2712_venc[] = { | ||
65 | { .compatible = "mediatek,mt2712-vencsys", }, | ||
66 | {} | ||
67 | }; | ||
68 | |||
69 | static struct platform_driver clk_mt2712_venc_drv = { | ||
70 | .probe = clk_mt2712_venc_probe, | ||
71 | .driver = { | ||
72 | .name = "clk-mt2712-venc", | ||
73 | .of_match_table = of_match_clk_mt2712_venc, | ||
74 | }, | ||
75 | }; | ||
76 | |||
77 | builtin_platform_driver(clk_mt2712_venc_drv); | ||
diff --git a/drivers/clk/mediatek/clk-mt2712.c b/drivers/clk/mediatek/clk-mt2712.c new file mode 100644 index 000000000000..498d13799388 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt2712.c | |||
@@ -0,0 +1,1435 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2017 MediaTek Inc. | ||
3 | * Author: Weiyi Lu <weiyi.lu@mediatek.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/clk.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/mfd/syscon.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/of_address.h> | ||
20 | #include <linux/of_device.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/slab.h> | ||
23 | |||
24 | #include "clk-mtk.h" | ||
25 | #include "clk-gate.h" | ||
26 | |||
27 | #include <dt-bindings/clock/mt2712-clk.h> | ||
28 | |||
29 | static DEFINE_SPINLOCK(mt2712_clk_lock); | ||
30 | |||
31 | static const struct mtk_fixed_clk top_fixed_clks[] = { | ||
32 | FIXED_CLK(CLK_TOP_VPLL3_DPIX, "vpll3_dpix", NULL, 200000000), | ||
33 | FIXED_CLK(CLK_TOP_VPLL_DPIX, "vpll_dpix", NULL, 200000000), | ||
34 | FIXED_CLK(CLK_TOP_LTEPLL_FS26M, "ltepll_fs26m", NULL, 26000000), | ||
35 | FIXED_CLK(CLK_TOP_DMPLL, "dmpll_ck", NULL, 350000000), | ||
36 | FIXED_CLK(CLK_TOP_DSI0_LNTC, "dsi0_lntc", NULL, 143000000), | ||
37 | FIXED_CLK(CLK_TOP_DSI1_LNTC, "dsi1_lntc", NULL, 143000000), | ||
38 | FIXED_CLK(CLK_TOP_LVDSTX3_CLKDIG_CTS, "lvdstx3", NULL, 140000000), | ||
39 | FIXED_CLK(CLK_TOP_LVDSTX_CLKDIG_CTS, "lvdstx", NULL, 140000000), | ||
40 | FIXED_CLK(CLK_TOP_CLKRTC_EXT, "clkrtc_ext", NULL, 32768), | ||
41 | FIXED_CLK(CLK_TOP_CLKRTC_INT, "clkrtc_int", NULL, 32747), | ||
42 | FIXED_CLK(CLK_TOP_CSI0, "csi0", NULL, 26000000), | ||
43 | FIXED_CLK(CLK_TOP_CVBSPLL, "cvbspll", NULL, 108000000), | ||
44 | }; | ||
45 | |||
46 | static const struct mtk_fixed_factor top_early_divs[] = { | ||
47 | FACTOR(CLK_TOP_SYS_26M, "sys_26m", "clk26m", 1, | ||
48 | 1), | ||
49 | FACTOR(CLK_TOP_CLK26M_D2, "clk26m_d2", "sys_26m", 1, | ||
50 | 2), | ||
51 | }; | ||
52 | |||
53 | static const struct mtk_fixed_factor top_divs[] = { | ||
54 | FACTOR(CLK_TOP_ARMCA35PLL, "armca35pll_ck", "armca35pll", 1, | ||
55 | 1), | ||
56 | FACTOR(CLK_TOP_ARMCA35PLL_600M, "armca35pll_600m", "armca35pll_ck", 1, | ||
57 | 2), | ||
58 | FACTOR(CLK_TOP_ARMCA35PLL_400M, "armca35pll_400m", "armca35pll_ck", 1, | ||
59 | 3), | ||
60 | FACTOR(CLK_TOP_ARMCA72PLL, "armca72pll_ck", "armca72pll", 1, | ||
61 | 1), | ||
62 | FACTOR(CLK_TOP_SYSPLL, "syspll_ck", "mainpll", 1, | ||
63 | 1), | ||
64 | FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "syspll_ck", 1, | ||
65 | 2), | ||
66 | FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "syspll_d2", 1, | ||
67 | 2), | ||
68 | FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "syspll_d2", 1, | ||
69 | 4), | ||
70 | FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "syspll_d2", 1, | ||
71 | 8), | ||
72 | FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "syspll_d2", 1, | ||
73 | 16), | ||
74 | FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "syspll_ck", 1, | ||
75 | 3), | ||
76 | FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "syspll_d3", 1, | ||
77 | 2), | ||
78 | FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "syspll_d3", 1, | ||
79 | 4), | ||
80 | FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "syspll_ck", 1, | ||
81 | 5), | ||
82 | FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "syspll_d5", 1, | ||
83 | 2), | ||
84 | FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "syspll_d5", 1, | ||
85 | 4), | ||
86 | FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "syspll_ck", 1, | ||
87 | 7), | ||
88 | FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "syspll_d7", 1, | ||
89 | 2), | ||
90 | FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "syspll_d7", 1, | ||
91 | 4), | ||
92 | FACTOR(CLK_TOP_UNIVPLL, "univpll_ck", "univpll", 1, | ||
93 | 1), | ||
94 | FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll_ck", 1, | ||
95 | 7), | ||
96 | FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll_ck", 1, | ||
97 | 26), | ||
98 | FACTOR(CLK_TOP_UNIVPLL_D52, "univpll_d52", "univpll_ck", 1, | ||
99 | 52), | ||
100 | FACTOR(CLK_TOP_UNIVPLL_D104, "univpll_d104", "univpll_ck", 1, | ||
101 | 104), | ||
102 | FACTOR(CLK_TOP_UNIVPLL_D208, "univpll_d208", "univpll_ck", 1, | ||
103 | 208), | ||
104 | FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll_ck", 1, | ||
105 | 2), | ||
106 | FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_d2", 1, | ||
107 | 2), | ||
108 | FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_d2", 1, | ||
109 | 4), | ||
110 | FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_d2", 1, | ||
111 | 8), | ||
112 | FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll_ck", 1, | ||
113 | 3), | ||
114 | FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_d3", 1, | ||
115 | 2), | ||
116 | FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_d3", 1, | ||
117 | 4), | ||
118 | FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_d3", 1, | ||
119 | 8), | ||
120 | FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll_ck", 1, | ||
121 | 5), | ||
122 | FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll_d5", 1, | ||
123 | 2), | ||
124 | FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll_d5", 1, | ||
125 | 4), | ||
126 | FACTOR(CLK_TOP_UNIVPLL3_D8, "univpll3_d8", "univpll_d5", 1, | ||
127 | 8), | ||
128 | FACTOR(CLK_TOP_F_MP0_PLL1, "f_mp0_pll1_ck", "univpll_d2", 1, | ||
129 | 1), | ||
130 | FACTOR(CLK_TOP_F_MP0_PLL2, "f_mp0_pll2_ck", "univpll1_d2", 1, | ||
131 | 1), | ||
132 | FACTOR(CLK_TOP_F_BIG_PLL1, "f_big_pll1_ck", "univpll_d2", 1, | ||
133 | 1), | ||
134 | FACTOR(CLK_TOP_F_BIG_PLL2, "f_big_pll2_ck", "univpll1_d2", 1, | ||
135 | 1), | ||
136 | FACTOR(CLK_TOP_F_BUS_PLL1, "f_bus_pll1_ck", "univpll_d2", 1, | ||
137 | 1), | ||
138 | FACTOR(CLK_TOP_F_BUS_PLL2, "f_bus_pll2_ck", "univpll1_d2", 1, | ||
139 | 1), | ||
140 | FACTOR(CLK_TOP_APLL1, "apll1_ck", "apll1", 1, | ||
141 | 1), | ||
142 | FACTOR(CLK_TOP_APLL1_D2, "apll1_d2", "apll1_ck", 1, | ||
143 | 2), | ||
144 | FACTOR(CLK_TOP_APLL1_D4, "apll1_d4", "apll1_ck", 1, | ||
145 | 4), | ||
146 | FACTOR(CLK_TOP_APLL1_D8, "apll1_d8", "apll1_ck", 1, | ||
147 | 8), | ||
148 | FACTOR(CLK_TOP_APLL1_D16, "apll1_d16", "apll1_ck", 1, | ||
149 | 16), | ||
150 | FACTOR(CLK_TOP_APLL2, "apll2_ck", "apll2", 1, | ||
151 | 1), | ||
152 | FACTOR(CLK_TOP_APLL2_D2, "apll2_d2", "apll2_ck", 1, | ||
153 | 2), | ||
154 | FACTOR(CLK_TOP_APLL2_D4, "apll2_d4", "apll2_ck", 1, | ||
155 | 4), | ||
156 | FACTOR(CLK_TOP_APLL2_D8, "apll2_d8", "apll2_ck", 1, | ||
157 | 8), | ||
158 | FACTOR(CLK_TOP_APLL2_D16, "apll2_d16", "apll2_ck", 1, | ||
159 | 16), | ||
160 | FACTOR(CLK_TOP_LVDSPLL, "lvdspll_ck", "lvdspll", 1, | ||
161 | 1), | ||
162 | FACTOR(CLK_TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll_ck", 1, | ||
163 | 2), | ||
164 | FACTOR(CLK_TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll_ck", 1, | ||
165 | 4), | ||
166 | FACTOR(CLK_TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll_ck", 1, | ||
167 | 8), | ||
168 | FACTOR(CLK_TOP_LVDSPLL2, "lvdspll2_ck", "lvdspll2", 1, | ||
169 | 1), | ||
170 | FACTOR(CLK_TOP_LVDSPLL2_D2, "lvdspll2_d2", "lvdspll2_ck", 1, | ||
171 | 2), | ||
172 | FACTOR(CLK_TOP_LVDSPLL2_D4, "lvdspll2_d4", "lvdspll2_ck", 1, | ||
173 | 4), | ||
174 | FACTOR(CLK_TOP_LVDSPLL2_D8, "lvdspll2_d8", "lvdspll2_ck", 1, | ||
175 | 8), | ||
176 | FACTOR(CLK_TOP_ETHERPLL_125M, "etherpll_125m", "etherpll", 1, | ||
177 | 1), | ||
178 | FACTOR(CLK_TOP_ETHERPLL_50M, "etherpll_50m", "etherpll", 1, | ||
179 | 1), | ||
180 | FACTOR(CLK_TOP_CVBS, "cvbs", "cvbspll", 1, | ||
181 | 1), | ||
182 | FACTOR(CLK_TOP_CVBS_D2, "cvbs_d2", "cvbs", 1, | ||
183 | 2), | ||
184 | FACTOR(CLK_TOP_MMPLL, "mmpll_ck", "mmpll", 1, | ||
185 | 1), | ||
186 | FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll_ck", 1, | ||
187 | 2), | ||
188 | FACTOR(CLK_TOP_VENCPLL, "vencpll_ck", "vencpll", 1, | ||
189 | 1), | ||
190 | FACTOR(CLK_TOP_VENCPLL_D2, "vencpll_d2", "vencpll_ck", 1, | ||
191 | 2), | ||
192 | FACTOR(CLK_TOP_VCODECPLL, "vcodecpll_ck", "vcodecpll", 1, | ||
193 | 1), | ||
194 | FACTOR(CLK_TOP_VCODECPLL_D2, "vcodecpll_d2", "vcodecpll_ck", 1, | ||
195 | 2), | ||
196 | FACTOR(CLK_TOP_TVDPLL, "tvdpll_ck", "tvdpll", 1, | ||
197 | 1), | ||
198 | FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll_ck", 1, | ||
199 | 2), | ||
200 | FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll_ck", 1, | ||
201 | 4), | ||
202 | FACTOR(CLK_TOP_TVDPLL_D8, "tvdpll_d8", "tvdpll_ck", 1, | ||
203 | 8), | ||
204 | FACTOR(CLK_TOP_TVDPLL_429M, "tvdpll_429m", "tvdpll", 1, | ||
205 | 1), | ||
206 | FACTOR(CLK_TOP_TVDPLL_429M_D2, "tvdpll_429m_d2", "tvdpll_429m", 1, | ||
207 | 2), | ||
208 | FACTOR(CLK_TOP_TVDPLL_429M_D4, "tvdpll_429m_d4", "tvdpll_429m", 1, | ||
209 | 4), | ||
210 | FACTOR(CLK_TOP_MSDCPLL, "msdcpll_ck", "msdcpll", 1, | ||
211 | 1), | ||
212 | FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll_ck", 1, | ||
213 | 2), | ||
214 | FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll_ck", 1, | ||
215 | 4), | ||
216 | FACTOR(CLK_TOP_MSDCPLL2, "msdcpll2_ck", "msdcpll2", 1, | ||
217 | 1), | ||
218 | FACTOR(CLK_TOP_MSDCPLL2_D2, "msdcpll2_d2", "msdcpll2_ck", 1, | ||
219 | 2), | ||
220 | FACTOR(CLK_TOP_MSDCPLL2_D4, "msdcpll2_d4", "msdcpll2_ck", 1, | ||
221 | 4), | ||
222 | FACTOR(CLK_TOP_D2A_ULCLK_6P5M, "d2a_ulclk_6p5m", "clk26m", 1, | ||
223 | 4), | ||
224 | }; | ||
225 | |||
226 | static const char * const axi_parents[] = { | ||
227 | "clk26m", | ||
228 | "syspll1_d2", | ||
229 | "syspll_d5", | ||
230 | "syspll1_d4", | ||
231 | "univpll_d5", | ||
232 | "univpll2_d2", | ||
233 | "msdcpll2_ck" | ||
234 | }; | ||
235 | |||
236 | static const char * const mem_parents[] = { | ||
237 | "clk26m", | ||
238 | "dmpll_ck" | ||
239 | }; | ||
240 | |||
241 | static const char * const mm_parents[] = { | ||
242 | "clk26m", | ||
243 | "vencpll_ck", | ||
244 | "syspll_d3", | ||
245 | "syspll1_d2", | ||
246 | "syspll_d5", | ||
247 | "syspll1_d4", | ||
248 | "univpll1_d2", | ||
249 | "univpll2_d2" | ||
250 | }; | ||
251 | |||
252 | static const char * const pwm_parents[] = { | ||
253 | "clk26m", | ||
254 | "univpll2_d4", | ||
255 | "univpll3_d2", | ||
256 | "univpll1_d4" | ||
257 | }; | ||
258 | |||
259 | static const char * const vdec_parents[] = { | ||
260 | "clk26m", | ||
261 | "vcodecpll_ck", | ||
262 | "tvdpll_429m", | ||
263 | "univpll_d3", | ||
264 | "vencpll_ck", | ||
265 | "syspll_d3", | ||
266 | "univpll1_d2", | ||
267 | "mmpll_d2", | ||
268 | "syspll3_d2", | ||
269 | "tvdpll_ck" | ||
270 | }; | ||
271 | |||
272 | static const char * const venc_parents[] = { | ||
273 | "clk26m", | ||
274 | "univpll1_d2", | ||
275 | "mmpll_d2", | ||
276 | "tvdpll_d2", | ||
277 | "syspll1_d2", | ||
278 | "univpll_d5", | ||
279 | "vcodecpll_d2", | ||
280 | "univpll2_d2", | ||
281 | "syspll3_d2" | ||
282 | }; | ||
283 | |||
284 | static const char * const mfg_parents[] = { | ||
285 | "clk26m", | ||
286 | "mmpll_ck", | ||
287 | "univpll_d3", | ||
288 | "clk26m", | ||
289 | "clk26m", | ||
290 | "clk26m", | ||
291 | "clk26m", | ||
292 | "clk26m", | ||
293 | "clk26m", | ||
294 | "syspll_d3", | ||
295 | "syspll1_d2", | ||
296 | "syspll_d5", | ||
297 | "univpll_d3", | ||
298 | "univpll1_d2", | ||
299 | "univpll_d5", | ||
300 | "univpll2_d2" | ||
301 | }; | ||
302 | |||
303 | static const char * const camtg_parents[] = { | ||
304 | "clk26m", | ||
305 | "univpll_d52", | ||
306 | "univpll_d208", | ||
307 | "univpll_d104", | ||
308 | "clk26m_d2", | ||
309 | "univpll_d26", | ||
310 | "univpll2_d8", | ||
311 | "syspll3_d4", | ||
312 | "syspll3_d2", | ||
313 | "univpll1_d4", | ||
314 | "univpll2_d2" | ||
315 | }; | ||
316 | |||
317 | static const char * const uart_parents[] = { | ||
318 | "clk26m", | ||
319 | "univpll2_d8" | ||
320 | }; | ||
321 | |||
322 | static const char * const spi_parents[] = { | ||
323 | "clk26m", | ||
324 | "univpll2_d4", | ||
325 | "univpll1_d4", | ||
326 | "univpll2_d2", | ||
327 | "univpll3_d2", | ||
328 | "univpll1_d8" | ||
329 | }; | ||
330 | |||
331 | static const char * const usb20_parents[] = { | ||
332 | "clk26m", | ||
333 | "univpll1_d8", | ||
334 | "univpll3_d4" | ||
335 | }; | ||
336 | |||
337 | static const char * const usb30_parents[] = { | ||
338 | "clk26m", | ||
339 | "univpll3_d2", | ||
340 | "univpll3_d4", | ||
341 | "univpll2_d4" | ||
342 | }; | ||
343 | |||
344 | static const char * const msdc50_0_h_parents[] = { | ||
345 | "clk26m", | ||
346 | "syspll1_d2", | ||
347 | "syspll2_d2", | ||
348 | "syspll4_d2", | ||
349 | "univpll_d5", | ||
350 | "univpll1_d4" | ||
351 | }; | ||
352 | |||
353 | static const char * const msdc50_0_parents[] = { | ||
354 | "clk26m", | ||
355 | "msdcpll_ck", | ||
356 | "msdcpll_d2", | ||
357 | "univpll1_d4", | ||
358 | "syspll2_d2", | ||
359 | "msdcpll_d4", | ||
360 | "vencpll_d2", | ||
361 | "univpll1_d2", | ||
362 | "msdcpll2_ck", | ||
363 | "msdcpll2_d2", | ||
364 | "msdcpll2_d4" | ||
365 | }; | ||
366 | |||
367 | static const char * const msdc30_1_parents[] = { | ||
368 | "clk26m", | ||
369 | "univpll2_d2", | ||
370 | "msdcpll_d2", | ||
371 | "univpll1_d4", | ||
372 | "syspll2_d2", | ||
373 | "univpll_d7", | ||
374 | "vencpll_d2" | ||
375 | }; | ||
376 | |||
377 | static const char * const msdc30_3_parents[] = { | ||
378 | "clk26m", | ||
379 | "msdcpll2_ck", | ||
380 | "msdcpll2_d2", | ||
381 | "univpll2_d2", | ||
382 | "msdcpll2_d4", | ||
383 | "univpll1_d4", | ||
384 | "syspll2_d2", | ||
385 | "syspll_d7", | ||
386 | "univpll_d7", | ||
387 | "vencpll_d2", | ||
388 | "msdcpll_ck", | ||
389 | "msdcpll_d2", | ||
390 | "msdcpll_d4" | ||
391 | }; | ||
392 | |||
393 | static const char * const audio_parents[] = { | ||
394 | "clk26m", | ||
395 | "syspll3_d4", | ||
396 | "syspll4_d4", | ||
397 | "syspll1_d16" | ||
398 | }; | ||
399 | |||
400 | static const char * const aud_intbus_parents[] = { | ||
401 | "clk26m", | ||
402 | "syspll1_d4", | ||
403 | "syspll4_d2", | ||
404 | "univpll3_d2", | ||
405 | "univpll2_d8", | ||
406 | "syspll3_d2", | ||
407 | "syspll3_d4" | ||
408 | }; | ||
409 | |||
410 | static const char * const pmicspi_parents[] = { | ||
411 | "clk26m", | ||
412 | "syspll1_d8", | ||
413 | "syspll3_d4", | ||
414 | "syspll1_d16", | ||
415 | "univpll3_d4", | ||
416 | "univpll_d26", | ||
417 | "syspll3_d4" | ||
418 | }; | ||
419 | |||
420 | static const char * const dpilvds1_parents[] = { | ||
421 | "clk26m", | ||
422 | "lvdspll2_ck", | ||
423 | "lvdspll2_d2", | ||
424 | "lvdspll2_d4", | ||
425 | "lvdspll2_d8", | ||
426 | "clkfpc" | ||
427 | }; | ||
428 | |||
429 | static const char * const atb_parents[] = { | ||
430 | "clk26m", | ||
431 | "syspll1_d2", | ||
432 | "univpll_d5", | ||
433 | "syspll_d5" | ||
434 | }; | ||
435 | |||
436 | static const char * const nr_parents[] = { | ||
437 | "clk26m", | ||
438 | "univpll1_d4", | ||
439 | "syspll2_d2", | ||
440 | "syspll1_d4", | ||
441 | "univpll1_d8", | ||
442 | "univpll3_d2", | ||
443 | "univpll2_d2", | ||
444 | "syspll_d5" | ||
445 | }; | ||
446 | |||
447 | static const char * const nfi2x_parents[] = { | ||
448 | "clk26m", | ||
449 | "syspll4_d4", | ||
450 | "univpll3_d4", | ||
451 | "univpll1_d8", | ||
452 | "syspll2_d4", | ||
453 | "univpll3_d2", | ||
454 | "syspll_d7", | ||
455 | "syspll2_d2", | ||
456 | "univpll2_d2", | ||
457 | "syspll_d5", | ||
458 | "syspll1_d2" | ||
459 | }; | ||
460 | |||
461 | static const char * const irda_parents[] = { | ||
462 | "clk26m", | ||
463 | "univpll2_d4", | ||
464 | "syspll2_d4", | ||
465 | "univpll2_d8" | ||
466 | }; | ||
467 | |||
468 | static const char * const cci400_parents[] = { | ||
469 | "clk26m", | ||
470 | "vencpll_ck", | ||
471 | "armca35pll_600m", | ||
472 | "armca35pll_400m", | ||
473 | "univpll_d2", | ||
474 | "syspll_d2", | ||
475 | "msdcpll_ck", | ||
476 | "univpll_d3" | ||
477 | }; | ||
478 | |||
479 | static const char * const aud_1_parents[] = { | ||
480 | "clk26m", | ||
481 | "apll1_ck", | ||
482 | "univpll2_d4", | ||
483 | "univpll2_d8" | ||
484 | }; | ||
485 | |||
486 | static const char * const aud_2_parents[] = { | ||
487 | "clk26m", | ||
488 | "apll2_ck", | ||
489 | "univpll2_d4", | ||
490 | "univpll2_d8" | ||
491 | }; | ||
492 | |||
493 | static const char * const mem_mfg_parents[] = { | ||
494 | "clk26m", | ||
495 | "mmpll_ck", | ||
496 | "univpll_d3" | ||
497 | }; | ||
498 | |||
499 | static const char * const axi_mfg_parents[] = { | ||
500 | "clk26m", | ||
501 | "axi_sel", | ||
502 | "univpll_d5" | ||
503 | }; | ||
504 | |||
505 | static const char * const scam_parents[] = { | ||
506 | "clk26m", | ||
507 | "syspll3_d2", | ||
508 | "univpll2_d4", | ||
509 | "syspll2_d4" | ||
510 | }; | ||
511 | |||
512 | static const char * const nfiecc_parents[] = { | ||
513 | "clk26m", | ||
514 | "nfi2x_sel", | ||
515 | "syspll_d7", | ||
516 | "syspll2_d2", | ||
517 | "univpll2_d2", | ||
518 | "univpll_d5", | ||
519 | "syspll1_d2" | ||
520 | }; | ||
521 | |||
522 | static const char * const pe2_mac_p0_parents[] = { | ||
523 | "clk26m", | ||
524 | "syspll1_d8", | ||
525 | "syspll4_d2", | ||
526 | "syspll2_d4", | ||
527 | "univpll2_d4", | ||
528 | "syspll3_d2" | ||
529 | }; | ||
530 | |||
531 | static const char * const dpilvds_parents[] = { | ||
532 | "clk26m", | ||
533 | "lvdspll_ck", | ||
534 | "lvdspll_d2", | ||
535 | "lvdspll_d4", | ||
536 | "lvdspll_d8", | ||
537 | "clkfpc" | ||
538 | }; | ||
539 | |||
540 | static const char * const hdcp_parents[] = { | ||
541 | "clk26m", | ||
542 | "syspll4_d2", | ||
543 | "syspll3_d4", | ||
544 | "univpll2_d4" | ||
545 | }; | ||
546 | |||
547 | static const char * const hdcp_24m_parents[] = { | ||
548 | "clk26m", | ||
549 | "univpll_d26", | ||
550 | "univpll_d52", | ||
551 | "univpll2_d8" | ||
552 | }; | ||
553 | |||
554 | static const char * const rtc_parents[] = { | ||
555 | "clkrtc_int", | ||
556 | "clkrtc_ext", | ||
557 | "clk26m", | ||
558 | "univpll3_d8" | ||
559 | }; | ||
560 | |||
561 | static const char * const spinor_parents[] = { | ||
562 | "clk26m", | ||
563 | "clk26m_d2", | ||
564 | "syspll4_d4", | ||
565 | "univpll2_d8", | ||
566 | "univpll3_d4", | ||
567 | "syspll4_d2", | ||
568 | "syspll2_d4", | ||
569 | "univpll2_d4", | ||
570 | "etherpll_125m", | ||
571 | "syspll1_d4" | ||
572 | }; | ||
573 | |||
574 | static const char * const apll_parents[] = { | ||
575 | "clk26m", | ||
576 | "apll1_ck", | ||
577 | "apll1_d2", | ||
578 | "apll1_d4", | ||
579 | "apll1_d8", | ||
580 | "apll1_d16", | ||
581 | "apll2_ck", | ||
582 | "apll2_d2", | ||
583 | "apll2_d4", | ||
584 | "apll2_d8", | ||
585 | "apll2_d16", | ||
586 | "clk26m", | ||
587 | "clk26m" | ||
588 | }; | ||
589 | |||
590 | static const char * const a1sys_hp_parents[] = { | ||
591 | "clk26m", | ||
592 | "apll1_ck", | ||
593 | "apll1_d2", | ||
594 | "apll1_d4", | ||
595 | "apll1_d8" | ||
596 | }; | ||
597 | |||
598 | static const char * const a2sys_hp_parents[] = { | ||
599 | "clk26m", | ||
600 | "apll2_ck", | ||
601 | "apll2_d2", | ||
602 | "apll2_d4", | ||
603 | "apll2_d8" | ||
604 | }; | ||
605 | |||
606 | static const char * const asm_l_parents[] = { | ||
607 | "clk26m", | ||
608 | "univpll2_d4", | ||
609 | "univpll2_d2", | ||
610 | "syspll_d5" | ||
611 | }; | ||
612 | |||
613 | static const char * const i2so1_parents[] = { | ||
614 | "clk26m", | ||
615 | "apll1_ck", | ||
616 | "apll2_ck" | ||
617 | }; | ||
618 | |||
619 | static const char * const ether_125m_parents[] = { | ||
620 | "clk26m", | ||
621 | "etherpll_125m", | ||
622 | "univpll3_d2" | ||
623 | }; | ||
624 | |||
625 | static const char * const ether_50m_parents[] = { | ||
626 | "clk26m", | ||
627 | "etherpll_50m", | ||
628 | "univpll_d26", | ||
629 | "univpll3_d4" | ||
630 | }; | ||
631 | |||
632 | static const char * const jpgdec_parents[] = { | ||
633 | "clk26m", | ||
634 | "univpll_d3", | ||
635 | "tvdpll_429m", | ||
636 | "vencpll_ck", | ||
637 | "syspll_d3", | ||
638 | "vcodecpll_ck", | ||
639 | "univpll1_d2", | ||
640 | "armca35pll_400m", | ||
641 | "tvdpll_429m_d2", | ||
642 | "tvdpll_429m_d4" | ||
643 | }; | ||
644 | |||
645 | static const char * const spislv_parents[] = { | ||
646 | "clk26m", | ||
647 | "univpll2_d4", | ||
648 | "univpll1_d4", | ||
649 | "univpll2_d2", | ||
650 | "univpll3_d2", | ||
651 | "univpll1_d8", | ||
652 | "univpll1_d2", | ||
653 | "univpll_d5" | ||
654 | }; | ||
655 | |||
656 | static const char * const ether_parents[] = { | ||
657 | "clk26m", | ||
658 | "etherpll_50m", | ||
659 | "univpll_d26" | ||
660 | }; | ||
661 | |||
662 | static const char * const di_parents[] = { | ||
663 | "clk26m", | ||
664 | "tvdpll_d2", | ||
665 | "tvdpll_d4", | ||
666 | "tvdpll_d8", | ||
667 | "vencpll_ck", | ||
668 | "vencpll_d2", | ||
669 | "cvbs", | ||
670 | "cvbs_d2" | ||
671 | }; | ||
672 | |||
673 | static const char * const tvd_parents[] = { | ||
674 | "clk26m", | ||
675 | "cvbs_d2", | ||
676 | "univpll2_d8" | ||
677 | }; | ||
678 | |||
679 | static const char * const i2c_parents[] = { | ||
680 | "clk26m", | ||
681 | "univpll_d26", | ||
682 | "univpll2_d4", | ||
683 | "univpll3_d2", | ||
684 | "univpll1_d4" | ||
685 | }; | ||
686 | |||
687 | static const char * const msdc0p_aes_parents[] = { | ||
688 | "clk26m", | ||
689 | "msdcpll_ck", | ||
690 | "univpll_d3", | ||
691 | "vcodecpll_ck" | ||
692 | }; | ||
693 | |||
694 | static const char * const cmsys_parents[] = { | ||
695 | "clk26m", | ||
696 | "univpll_d3", | ||
697 | "syspll_d3", | ||
698 | "syspll1_d2", | ||
699 | "syspll2_d2" | ||
700 | }; | ||
701 | |||
702 | static const char * const gcpu_parents[] = { | ||
703 | "clk26m", | ||
704 | "syspll_d3", | ||
705 | "syspll1_d2", | ||
706 | "univpll1_d2", | ||
707 | "univpll_d5", | ||
708 | "univpll3_d2", | ||
709 | "univpll_d3" | ||
710 | }; | ||
711 | |||
712 | static const char * const aud_apll1_parents[] = { | ||
713 | "apll1", | ||
714 | "clkaud_ext_i_1" | ||
715 | }; | ||
716 | |||
717 | static const char * const aud_apll2_parents[] = { | ||
718 | "apll2", | ||
719 | "clkaud_ext_i_2" | ||
720 | }; | ||
721 | |||
722 | static const char * const audull_vtx_parents[] = { | ||
723 | "d2a_ulclk_6p5m", | ||
724 | "clkaud_ext_i_0" | ||
725 | }; | ||
726 | |||
727 | static struct mtk_composite top_muxes[] = { | ||
728 | /* CLK_CFG_0 */ | ||
729 | MUX_GATE_FLAGS(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, 0x040, 0, 3, | ||
730 | 7, CLK_IS_CRITICAL), | ||
731 | MUX_GATE_FLAGS(CLK_TOP_MEM_SEL, "mem_sel", mem_parents, 0x040, 8, 1, | ||
732 | 15, CLK_IS_CRITICAL), | ||
733 | MUX_GATE(CLK_TOP_MM_SEL, "mm_sel", | ||
734 | mm_parents, 0x040, 24, 3, 31), | ||
735 | /* CLK_CFG_1 */ | ||
736 | MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel", | ||
737 | pwm_parents, 0x050, 0, 2, 7), | ||
738 | MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel", | ||
739 | vdec_parents, 0x050, 8, 4, 15), | ||
740 | MUX_GATE(CLK_TOP_VENC_SEL, "venc_sel", | ||
741 | venc_parents, 0x050, 16, 4, 23), | ||
742 | MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel", | ||
743 | mfg_parents, 0x050, 24, 4, 31), | ||
744 | /* CLK_CFG_2 */ | ||
745 | MUX_GATE(CLK_TOP_CAMTG_SEL, "camtg_sel", | ||
746 | camtg_parents, 0x060, 0, 4, 7), | ||
747 | MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", | ||
748 | uart_parents, 0x060, 8, 1, 15), | ||
749 | MUX_GATE(CLK_TOP_SPI_SEL, "spi_sel", | ||
750 | spi_parents, 0x060, 16, 3, 23), | ||
751 | MUX_GATE(CLK_TOP_USB20_SEL, "usb20_sel", | ||
752 | usb20_parents, 0x060, 24, 2, 31), | ||
753 | /* CLK_CFG_3 */ | ||
754 | MUX_GATE(CLK_TOP_USB30_SEL, "usb30_sel", | ||
755 | usb30_parents, 0x070, 0, 2, 7), | ||
756 | MUX_GATE(CLK_TOP_MSDC50_0_HCLK_SEL, "msdc50_0_h_sel", | ||
757 | msdc50_0_h_parents, 0x070, 8, 3, 15), | ||
758 | MUX_GATE(CLK_TOP_MSDC50_0_SEL, "msdc50_0_sel", | ||
759 | msdc50_0_parents, 0x070, 16, 4, 23), | ||
760 | MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", | ||
761 | msdc30_1_parents, 0x070, 24, 3, 31), | ||
762 | /* CLK_CFG_4 */ | ||
763 | MUX_GATE(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel", | ||
764 | msdc30_1_parents, 0x080, 0, 3, 7), | ||
765 | MUX_GATE(CLK_TOP_MSDC30_3_SEL, "msdc30_3_sel", | ||
766 | msdc30_3_parents, 0x080, 8, 4, 15), | ||
767 | MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", | ||
768 | audio_parents, 0x080, 16, 2, 23), | ||
769 | MUX_GATE(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel", | ||
770 | aud_intbus_parents, 0x080, 24, 3, 31), | ||
771 | /* CLK_CFG_5 */ | ||
772 | MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", | ||
773 | pmicspi_parents, 0x090, 0, 3, 7), | ||
774 | MUX_GATE(CLK_TOP_DPILVDS1_SEL, "dpilvds1_sel", | ||
775 | dpilvds1_parents, 0x090, 8, 3, 15), | ||
776 | MUX_GATE(CLK_TOP_ATB_SEL, "atb_sel", | ||
777 | atb_parents, 0x090, 16, 2, 23), | ||
778 | MUX_GATE(CLK_TOP_NR_SEL, "nr_sel", | ||
779 | nr_parents, 0x090, 24, 3, 31), | ||
780 | /* CLK_CFG_6 */ | ||
781 | MUX_GATE(CLK_TOP_NFI2X_SEL, "nfi2x_sel", | ||
782 | nfi2x_parents, 0x0a0, 0, 4, 7), | ||
783 | MUX_GATE(CLK_TOP_IRDA_SEL, "irda_sel", | ||
784 | irda_parents, 0x0a0, 8, 2, 15), | ||
785 | MUX_GATE(CLK_TOP_CCI400_SEL, "cci400_sel", | ||
786 | cci400_parents, 0x0a0, 16, 3, 23), | ||
787 | MUX_GATE(CLK_TOP_AUD_1_SEL, "aud_1_sel", | ||
788 | aud_1_parents, 0x0a0, 24, 2, 31), | ||
789 | /* CLK_CFG_7 */ | ||
790 | MUX_GATE(CLK_TOP_AUD_2_SEL, "aud_2_sel", | ||
791 | aud_2_parents, 0x0b0, 0, 2, 7), | ||
792 | MUX_GATE(CLK_TOP_MEM_MFG_IN_AS_SEL, "mem_mfg_sel", | ||
793 | mem_mfg_parents, 0x0b0, 8, 2, 15), | ||
794 | MUX_GATE(CLK_TOP_AXI_MFG_IN_AS_SEL, "axi_mfg_sel", | ||
795 | axi_mfg_parents, 0x0b0, 16, 2, 23), | ||
796 | MUX_GATE(CLK_TOP_SCAM_SEL, "scam_sel", | ||
797 | scam_parents, 0x0b0, 24, 2, 31), | ||
798 | /* CLK_CFG_8 */ | ||
799 | MUX_GATE(CLK_TOP_NFIECC_SEL, "nfiecc_sel", | ||
800 | nfiecc_parents, 0x0c0, 0, 3, 7), | ||
801 | MUX_GATE(CLK_TOP_PE2_MAC_P0_SEL, "pe2_mac_p0_sel", | ||
802 | pe2_mac_p0_parents, 0x0c0, 8, 3, 15), | ||
803 | MUX_GATE(CLK_TOP_PE2_MAC_P1_SEL, "pe2_mac_p1_sel", | ||
804 | pe2_mac_p0_parents, 0x0c0, 16, 3, 23), | ||
805 | MUX_GATE(CLK_TOP_DPILVDS_SEL, "dpilvds_sel", | ||
806 | dpilvds_parents, 0x0c0, 24, 3, 31), | ||
807 | /* CLK_CFG_9 */ | ||
808 | MUX_GATE(CLK_TOP_MSDC50_3_HCLK_SEL, "msdc50_3_h_sel", | ||
809 | msdc50_0_h_parents, 0x0d0, 0, 3, 7), | ||
810 | MUX_GATE(CLK_TOP_HDCP_SEL, "hdcp_sel", | ||
811 | hdcp_parents, 0x0d0, 8, 2, 15), | ||
812 | MUX_GATE(CLK_TOP_HDCP_24M_SEL, "hdcp_24m_sel", | ||
813 | hdcp_24m_parents, 0x0d0, 16, 2, 23), | ||
814 | MUX_GATE_FLAGS(CLK_TOP_RTC_SEL, "rtc_sel", rtc_parents, 0x0d0, 24, 2, | ||
815 | 31, CLK_IS_CRITICAL), | ||
816 | /* CLK_CFG_10 */ | ||
817 | MUX_GATE(CLK_TOP_SPINOR_SEL, "spinor_sel", | ||
818 | spinor_parents, 0x500, 0, 4, 7), | ||
819 | MUX_GATE(CLK_TOP_APLL_SEL, "apll_sel", | ||
820 | apll_parents, 0x500, 8, 4, 15), | ||
821 | MUX_GATE(CLK_TOP_APLL2_SEL, "apll2_sel", | ||
822 | apll_parents, 0x500, 16, 4, 23), | ||
823 | MUX_GATE(CLK_TOP_A1SYS_HP_SEL, "a1sys_hp_sel", | ||
824 | a1sys_hp_parents, 0x500, 24, 3, 31), | ||
825 | /* CLK_CFG_11 */ | ||
826 | MUX_GATE(CLK_TOP_A2SYS_HP_SEL, "a2sys_hp_sel", | ||
827 | a2sys_hp_parents, 0x510, 0, 3, 7), | ||
828 | MUX_GATE(CLK_TOP_ASM_L_SEL, "asm_l_sel", | ||
829 | asm_l_parents, 0x510, 8, 2, 15), | ||
830 | MUX_GATE(CLK_TOP_ASM_M_SEL, "asm_m_sel", | ||
831 | asm_l_parents, 0x510, 16, 2, 23), | ||
832 | MUX_GATE(CLK_TOP_ASM_H_SEL, "asm_h_sel", | ||
833 | asm_l_parents, 0x510, 24, 2, 31), | ||
834 | /* CLK_CFG_12 */ | ||
835 | MUX_GATE(CLK_TOP_I2SO1_SEL, "i2so1_sel", | ||
836 | i2so1_parents, 0x520, 0, 2, 7), | ||
837 | MUX_GATE(CLK_TOP_I2SO2_SEL, "i2so2_sel", | ||
838 | i2so1_parents, 0x520, 8, 2, 15), | ||
839 | MUX_GATE(CLK_TOP_I2SO3_SEL, "i2so3_sel", | ||
840 | i2so1_parents, 0x520, 16, 2, 23), | ||
841 | MUX_GATE(CLK_TOP_TDMO0_SEL, "tdmo0_sel", | ||
842 | i2so1_parents, 0x520, 24, 2, 31), | ||
843 | /* CLK_CFG_13 */ | ||
844 | MUX_GATE(CLK_TOP_TDMO1_SEL, "tdmo1_sel", | ||
845 | i2so1_parents, 0x530, 0, 2, 7), | ||
846 | MUX_GATE(CLK_TOP_I2SI1_SEL, "i2si1_sel", | ||
847 | i2so1_parents, 0x530, 8, 2, 15), | ||
848 | MUX_GATE(CLK_TOP_I2SI2_SEL, "i2si2_sel", | ||
849 | i2so1_parents, 0x530, 16, 2, 23), | ||
850 | MUX_GATE(CLK_TOP_I2SI3_SEL, "i2si3_sel", | ||
851 | i2so1_parents, 0x530, 24, 2, 31), | ||
852 | /* CLK_CFG_14 */ | ||
853 | MUX_GATE(CLK_TOP_ETHER_125M_SEL, "ether_125m_sel", | ||
854 | ether_125m_parents, 0x540, 0, 2, 7), | ||
855 | MUX_GATE(CLK_TOP_ETHER_50M_SEL, "ether_50m_sel", | ||
856 | ether_50m_parents, 0x540, 8, 2, 15), | ||
857 | MUX_GATE(CLK_TOP_JPGDEC_SEL, "jpgdec_sel", | ||
858 | jpgdec_parents, 0x540, 16, 4, 23), | ||
859 | MUX_GATE(CLK_TOP_SPISLV_SEL, "spislv_sel", | ||
860 | spislv_parents, 0x540, 24, 3, 31), | ||
861 | /* CLK_CFG_15 */ | ||
862 | MUX_GATE(CLK_TOP_ETHER_50M_RMII_SEL, "ether_sel", | ||
863 | ether_parents, 0x550, 0, 2, 7), | ||
864 | MUX_GATE(CLK_TOP_CAM2TG_SEL, "cam2tg_sel", | ||
865 | camtg_parents, 0x550, 8, 4, 15), | ||
866 | MUX_GATE(CLK_TOP_DI_SEL, "di_sel", | ||
867 | di_parents, 0x550, 16, 3, 23), | ||
868 | MUX_GATE(CLK_TOP_TVD_SEL, "tvd_sel", | ||
869 | tvd_parents, 0x550, 24, 2, 31), | ||
870 | /* CLK_CFG_16 */ | ||
871 | MUX_GATE(CLK_TOP_I2C_SEL, "i2c_sel", | ||
872 | i2c_parents, 0x560, 0, 3, 7), | ||
873 | MUX_GATE(CLK_TOP_PWM_INFRA_SEL, "pwm_infra_sel", | ||
874 | pwm_parents, 0x560, 8, 2, 15), | ||
875 | MUX_GATE(CLK_TOP_MSDC0P_AES_SEL, "msdc0p_aes_sel", | ||
876 | msdc0p_aes_parents, 0x560, 16, 2, 23), | ||
877 | MUX_GATE(CLK_TOP_CMSYS_SEL, "cmsys_sel", | ||
878 | cmsys_parents, 0x560, 24, 3, 31), | ||
879 | /* CLK_CFG_17 */ | ||
880 | MUX_GATE(CLK_TOP_GCPU_SEL, "gcpu_sel", | ||
881 | gcpu_parents, 0x570, 0, 3, 7), | ||
882 | /* CLK_AUDDIV_4 */ | ||
883 | MUX(CLK_TOP_AUD_APLL1_SEL, "aud_apll1_sel", | ||
884 | aud_apll1_parents, 0x134, 0, 1), | ||
885 | MUX(CLK_TOP_AUD_APLL2_SEL, "aud_apll2_sel", | ||
886 | aud_apll2_parents, 0x134, 1, 1), | ||
887 | MUX(CLK_TOP_DA_AUDULL_VTX_6P5M_SEL, "audull_vtx_sel", | ||
888 | audull_vtx_parents, 0x134, 31, 1), | ||
889 | }; | ||
890 | |||
891 | static const char * const mcu_mp0_parents[] = { | ||
892 | "clk26m", | ||
893 | "armca35pll_ck", | ||
894 | "f_mp0_pll1_ck", | ||
895 | "f_mp0_pll2_ck" | ||
896 | }; | ||
897 | |||
898 | static const char * const mcu_mp2_parents[] = { | ||
899 | "clk26m", | ||
900 | "armca72pll_ck", | ||
901 | "f_big_pll1_ck", | ||
902 | "f_big_pll2_ck" | ||
903 | }; | ||
904 | |||
905 | static const char * const mcu_bus_parents[] = { | ||
906 | "clk26m", | ||
907 | "cci400_sel", | ||
908 | "f_bus_pll1_ck", | ||
909 | "f_bus_pll2_ck" | ||
910 | }; | ||
911 | |||
912 | static struct mtk_composite mcu_muxes[] = { | ||
913 | /* mp0_pll_divider_cfg */ | ||
914 | MUX_GATE_FLAGS(CLK_MCU_MP0_SEL, "mcu_mp0_sel", mcu_mp0_parents, 0x7A0, | ||
915 | 9, 2, -1, CLK_IS_CRITICAL), | ||
916 | /* mp2_pll_divider_cfg */ | ||
917 | MUX_GATE_FLAGS(CLK_MCU_MP2_SEL, "mcu_mp2_sel", mcu_mp2_parents, 0x7A8, | ||
918 | 9, 2, -1, CLK_IS_CRITICAL), | ||
919 | /* bus_pll_divider_cfg */ | ||
920 | MUX_GATE_FLAGS(CLK_MCU_BUS_SEL, "mcu_bus_sel", mcu_bus_parents, 0x7C0, | ||
921 | 9, 2, -1, CLK_IS_CRITICAL), | ||
922 | }; | ||
923 | |||
924 | static const struct mtk_clk_divider top_adj_divs[] = { | ||
925 | DIV_ADJ(CLK_TOP_APLL_DIV0, "apll_div0", "i2so1_sel", 0x124, 0, 8), | ||
926 | DIV_ADJ(CLK_TOP_APLL_DIV1, "apll_div1", "i2so2_sel", 0x124, 8, 8), | ||
927 | DIV_ADJ(CLK_TOP_APLL_DIV2, "apll_div2", "i2so3_sel", 0x124, 16, 8), | ||
928 | DIV_ADJ(CLK_TOP_APLL_DIV3, "apll_div3", "tdmo0_sel", 0x124, 24, 8), | ||
929 | DIV_ADJ(CLK_TOP_APLL_DIV4, "apll_div4", "tdmo1_sel", 0x128, 0, 8), | ||
930 | DIV_ADJ(CLK_TOP_APLL_DIV5, "apll_div5", "i2si1_sel", 0x128, 8, 8), | ||
931 | DIV_ADJ(CLK_TOP_APLL_DIV6, "apll_div6", "i2si2_sel", 0x128, 16, 8), | ||
932 | DIV_ADJ(CLK_TOP_APLL_DIV7, "apll_div7", "i2si3_sel", 0x128, 24, 8), | ||
933 | }; | ||
934 | |||
935 | static const struct mtk_gate_regs top_cg_regs = { | ||
936 | .set_ofs = 0x120, | ||
937 | .clr_ofs = 0x120, | ||
938 | .sta_ofs = 0x120, | ||
939 | }; | ||
940 | |||
941 | #define GATE_TOP(_id, _name, _parent, _shift) { \ | ||
942 | .id = _id, \ | ||
943 | .name = _name, \ | ||
944 | .parent_name = _parent, \ | ||
945 | .regs = &top_cg_regs, \ | ||
946 | .shift = _shift, \ | ||
947 | .ops = &mtk_clk_gate_ops_no_setclr, \ | ||
948 | } | ||
949 | |||
950 | static const struct mtk_gate top_clks[] = { | ||
951 | GATE_TOP(CLK_TOP_APLL_DIV_PDN0, "apll_div_pdn0", "i2so1_sel", 0), | ||
952 | GATE_TOP(CLK_TOP_APLL_DIV_PDN1, "apll_div_pdn1", "i2so2_sel", 1), | ||
953 | GATE_TOP(CLK_TOP_APLL_DIV_PDN2, "apll_div_pdn2", "i2so3_sel", 2), | ||
954 | GATE_TOP(CLK_TOP_APLL_DIV_PDN3, "apll_div_pdn3", "tdmo0_sel", 3), | ||
955 | GATE_TOP(CLK_TOP_APLL_DIV_PDN4, "apll_div_pdn4", "tdmo1_sel", 4), | ||
956 | GATE_TOP(CLK_TOP_APLL_DIV_PDN5, "apll_div_pdn5", "i2si1_sel", 5), | ||
957 | GATE_TOP(CLK_TOP_APLL_DIV_PDN6, "apll_div_pdn6", "i2si2_sel", 6), | ||
958 | GATE_TOP(CLK_TOP_APLL_DIV_PDN7, "apll_div_pdn7", "i2si3_sel", 7), | ||
959 | }; | ||
960 | |||
961 | static const struct mtk_gate_regs infra_cg_regs = { | ||
962 | .set_ofs = 0x40, | ||
963 | .clr_ofs = 0x44, | ||
964 | .sta_ofs = 0x40, | ||
965 | }; | ||
966 | |||
967 | #define GATE_INFRA(_id, _name, _parent, _shift) { \ | ||
968 | .id = _id, \ | ||
969 | .name = _name, \ | ||
970 | .parent_name = _parent, \ | ||
971 | .regs = &infra_cg_regs, \ | ||
972 | .shift = _shift, \ | ||
973 | .ops = &mtk_clk_gate_ops_setclr, \ | ||
974 | } | ||
975 | |||
976 | static const struct mtk_gate infra_clks[] = { | ||
977 | GATE_INFRA(CLK_INFRA_DBGCLK, "infra_dbgclk", "axi_sel", 0), | ||
978 | GATE_INFRA(CLK_INFRA_GCE, "infra_gce", "axi_sel", 6), | ||
979 | GATE_INFRA(CLK_INFRA_M4U, "infra_m4u", "mem_sel", 8), | ||
980 | GATE_INFRA(CLK_INFRA_KP, "infra_kp", "axi_sel", 16), | ||
981 | GATE_INFRA(CLK_INFRA_AO_SPI0, "infra_ao_spi0", "spi_sel", 24), | ||
982 | GATE_INFRA(CLK_INFRA_AO_SPI1, "infra_ao_spi1", "spislv_sel", 25), | ||
983 | GATE_INFRA(CLK_INFRA_AO_UART5, "infra_ao_uart5", "axi_sel", 26), | ||
984 | }; | ||
985 | |||
986 | static const struct mtk_gate_regs peri0_cg_regs = { | ||
987 | .set_ofs = 0x8, | ||
988 | .clr_ofs = 0x10, | ||
989 | .sta_ofs = 0x18, | ||
990 | }; | ||
991 | |||
992 | static const struct mtk_gate_regs peri1_cg_regs = { | ||
993 | .set_ofs = 0xc, | ||
994 | .clr_ofs = 0x14, | ||
995 | .sta_ofs = 0x1c, | ||
996 | }; | ||
997 | |||
998 | static const struct mtk_gate_regs peri2_cg_regs = { | ||
999 | .set_ofs = 0x42c, | ||
1000 | .clr_ofs = 0x42c, | ||
1001 | .sta_ofs = 0x42c, | ||
1002 | }; | ||
1003 | |||
1004 | #define GATE_PERI0(_id, _name, _parent, _shift) { \ | ||
1005 | .id = _id, \ | ||
1006 | .name = _name, \ | ||
1007 | .parent_name = _parent, \ | ||
1008 | .regs = &peri0_cg_regs, \ | ||
1009 | .shift = _shift, \ | ||
1010 | .ops = &mtk_clk_gate_ops_setclr, \ | ||
1011 | } | ||
1012 | |||
1013 | #define GATE_PERI1(_id, _name, _parent, _shift) { \ | ||
1014 | .id = _id, \ | ||
1015 | .name = _name, \ | ||
1016 | .parent_name = _parent, \ | ||
1017 | .regs = &peri1_cg_regs, \ | ||
1018 | .shift = _shift, \ | ||
1019 | .ops = &mtk_clk_gate_ops_setclr, \ | ||
1020 | } | ||
1021 | |||
1022 | #define GATE_PERI2(_id, _name, _parent, _shift) { \ | ||
1023 | .id = _id, \ | ||
1024 | .name = _name, \ | ||
1025 | .parent_name = _parent, \ | ||
1026 | .regs = &peri2_cg_regs, \ | ||
1027 | .shift = _shift, \ | ||
1028 | .ops = &mtk_clk_gate_ops_no_setclr_inv, \ | ||
1029 | } | ||
1030 | |||
1031 | static const struct mtk_gate peri_clks[] = { | ||
1032 | /* PERI0 */ | ||
1033 | GATE_PERI0(CLK_PERI_NFI, "per_nfi", | ||
1034 | "axi_sel", 0), | ||
1035 | GATE_PERI0(CLK_PERI_THERM, "per_therm", | ||
1036 | "axi_sel", 1), | ||
1037 | GATE_PERI0(CLK_PERI_PWM0, "per_pwm0", | ||
1038 | "pwm_sel", 2), | ||
1039 | GATE_PERI0(CLK_PERI_PWM1, "per_pwm1", | ||
1040 | "pwm_sel", 3), | ||
1041 | GATE_PERI0(CLK_PERI_PWM2, "per_pwm2", | ||
1042 | "pwm_sel", 4), | ||
1043 | GATE_PERI0(CLK_PERI_PWM3, "per_pwm3", | ||
1044 | "pwm_sel", 5), | ||
1045 | GATE_PERI0(CLK_PERI_PWM4, "per_pwm4", | ||
1046 | "pwm_sel", 6), | ||
1047 | GATE_PERI0(CLK_PERI_PWM5, "per_pwm5", | ||
1048 | "pwm_sel", 7), | ||
1049 | GATE_PERI0(CLK_PERI_PWM6, "per_pwm6", | ||
1050 | "pwm_sel", 8), | ||
1051 | GATE_PERI0(CLK_PERI_PWM7, "per_pwm7", | ||
1052 | "pwm_sel", 9), | ||
1053 | GATE_PERI0(CLK_PERI_PWM, "per_pwm", | ||
1054 | "pwm_sel", 10), | ||
1055 | GATE_PERI0(CLK_PERI_AP_DMA, "per_ap_dma", | ||
1056 | "axi_sel", 13), | ||
1057 | GATE_PERI0(CLK_PERI_MSDC30_0, "per_msdc30_0", | ||
1058 | "msdc50_0_sel", 14), | ||
1059 | GATE_PERI0(CLK_PERI_MSDC30_1, "per_msdc30_1", | ||
1060 | "msdc30_1_sel", 15), | ||
1061 | GATE_PERI0(CLK_PERI_MSDC30_2, "per_msdc30_2", | ||
1062 | "msdc30_2_sel", 16), | ||
1063 | GATE_PERI0(CLK_PERI_MSDC30_3, "per_msdc30_3", | ||
1064 | "msdc30_3_sel", 17), | ||
1065 | GATE_PERI0(CLK_PERI_UART0, "per_uart0", | ||
1066 | "uart_sel", 20), | ||
1067 | GATE_PERI0(CLK_PERI_UART1, "per_uart1", | ||
1068 | "uart_sel", 21), | ||
1069 | GATE_PERI0(CLK_PERI_UART2, "per_uart2", | ||
1070 | "uart_sel", 22), | ||
1071 | GATE_PERI0(CLK_PERI_UART3, "per_uart3", | ||
1072 | "uart_sel", 23), | ||
1073 | GATE_PERI0(CLK_PERI_I2C0, "per_i2c0", | ||
1074 | "axi_sel", 24), | ||
1075 | GATE_PERI0(CLK_PERI_I2C1, "per_i2c1", | ||
1076 | "axi_sel", 25), | ||
1077 | GATE_PERI0(CLK_PERI_I2C2, "per_i2c2", | ||
1078 | "axi_sel", 26), | ||
1079 | GATE_PERI0(CLK_PERI_I2C3, "per_i2c3", | ||
1080 | "axi_sel", 27), | ||
1081 | GATE_PERI0(CLK_PERI_I2C4, "per_i2c4", | ||
1082 | "axi_sel", 28), | ||
1083 | GATE_PERI0(CLK_PERI_AUXADC, "per_auxadc", | ||
1084 | "ltepll_fs26m", 29), | ||
1085 | GATE_PERI0(CLK_PERI_SPI0, "per_spi0", | ||
1086 | "spi_sel", 30), | ||
1087 | /* PERI1 */ | ||
1088 | GATE_PERI1(CLK_PERI_SPI, "per_spi", | ||
1089 | "spinor_sel", 1), | ||
1090 | GATE_PERI1(CLK_PERI_I2C5, "per_i2c5", | ||
1091 | "axi_sel", 3), | ||
1092 | GATE_PERI1(CLK_PERI_SPI2, "per_spi2", | ||
1093 | "spi_sel", 5), | ||
1094 | GATE_PERI1(CLK_PERI_SPI3, "per_spi3", | ||
1095 | "spi_sel", 6), | ||
1096 | GATE_PERI1(CLK_PERI_SPI5, "per_spi5", | ||
1097 | "spi_sel", 8), | ||
1098 | GATE_PERI1(CLK_PERI_UART4, "per_uart4", | ||
1099 | "uart_sel", 9), | ||
1100 | GATE_PERI1(CLK_PERI_SFLASH, "per_sflash", | ||
1101 | "uart_sel", 11), | ||
1102 | GATE_PERI1(CLK_PERI_GMAC, "per_gmac", | ||
1103 | "uart_sel", 12), | ||
1104 | GATE_PERI1(CLK_PERI_PCIE0, "per_pcie0", | ||
1105 | "uart_sel", 14), | ||
1106 | GATE_PERI1(CLK_PERI_PCIE1, "per_pcie1", | ||
1107 | "uart_sel", 15), | ||
1108 | GATE_PERI1(CLK_PERI_GMAC_PCLK, "per_gmac_pclk", | ||
1109 | "uart_sel", 16), | ||
1110 | /* PERI2 */ | ||
1111 | GATE_PERI2(CLK_PERI_MSDC50_0_EN, "per_msdc50_0_en", | ||
1112 | "msdc50_0_sel", 0), | ||
1113 | GATE_PERI2(CLK_PERI_MSDC30_1_EN, "per_msdc30_1_en", | ||
1114 | "msdc30_1_sel", 1), | ||
1115 | GATE_PERI2(CLK_PERI_MSDC30_2_EN, "per_msdc30_2_en", | ||
1116 | "msdc30_2_sel", 2), | ||
1117 | GATE_PERI2(CLK_PERI_MSDC30_3_EN, "per_msdc30_3_en", | ||
1118 | "msdc30_3_sel", 3), | ||
1119 | GATE_PERI2(CLK_PERI_MSDC50_0_HCLK_EN, "per_msdc50_0_h", | ||
1120 | "msdc50_0_h_sel", 4), | ||
1121 | GATE_PERI2(CLK_PERI_MSDC50_3_HCLK_EN, "per_msdc50_3_h", | ||
1122 | "msdc50_3_h_sel", 5), | ||
1123 | }; | ||
1124 | |||
1125 | #define MT2712_PLL_FMAX (3000UL * MHZ) | ||
1126 | |||
1127 | #define CON0_MT2712_RST_BAR BIT(24) | ||
1128 | |||
1129 | #define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \ | ||
1130 | _pd_reg, _pd_shift, _tuner_reg, _tuner_en_reg, \ | ||
1131 | _tuner_en_bit, _pcw_reg, _pcw_shift, \ | ||
1132 | _div_table) { \ | ||
1133 | .id = _id, \ | ||
1134 | .name = _name, \ | ||
1135 | .reg = _reg, \ | ||
1136 | .pwr_reg = _pwr_reg, \ | ||
1137 | .en_mask = _en_mask, \ | ||
1138 | .flags = _flags, \ | ||
1139 | .rst_bar_mask = CON0_MT2712_RST_BAR, \ | ||
1140 | .fmax = MT2712_PLL_FMAX, \ | ||
1141 | .pcwbits = _pcwbits, \ | ||
1142 | .pd_reg = _pd_reg, \ | ||
1143 | .pd_shift = _pd_shift, \ | ||
1144 | .tuner_reg = _tuner_reg, \ | ||
1145 | .tuner_en_reg = _tuner_en_reg, \ | ||
1146 | .tuner_en_bit = _tuner_en_bit, \ | ||
1147 | .pcw_reg = _pcw_reg, \ | ||
1148 | .pcw_shift = _pcw_shift, \ | ||
1149 | .div_table = _div_table, \ | ||
1150 | } | ||
1151 | |||
1152 | #define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \ | ||
1153 | _pd_reg, _pd_shift, _tuner_reg, _tuner_en_reg, \ | ||
1154 | _tuner_en_bit, _pcw_reg, _pcw_shift) \ | ||
1155 | PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, \ | ||
1156 | _pcwbits, _pd_reg, _pd_shift, _tuner_reg, \ | ||
1157 | _tuner_en_reg, _tuner_en_bit, _pcw_reg, \ | ||
1158 | _pcw_shift, NULL) | ||
1159 | |||
1160 | static const struct mtk_pll_div_table armca35pll_div_table[] = { | ||
1161 | { .div = 0, .freq = MT2712_PLL_FMAX }, | ||
1162 | { .div = 1, .freq = 1202500000 }, | ||
1163 | { .div = 2, .freq = 500500000 }, | ||
1164 | { .div = 3, .freq = 315250000 }, | ||
1165 | { .div = 4, .freq = 157625000 }, | ||
1166 | { } /* sentinel */ | ||
1167 | }; | ||
1168 | |||
1169 | static const struct mtk_pll_div_table armca72pll_div_table[] = { | ||
1170 | { .div = 0, .freq = MT2712_PLL_FMAX }, | ||
1171 | { .div = 1, .freq = 994500000 }, | ||
1172 | { .div = 2, .freq = 520000000 }, | ||
1173 | { .div = 3, .freq = 315250000 }, | ||
1174 | { .div = 4, .freq = 157625000 }, | ||
1175 | { } /* sentinel */ | ||
1176 | }; | ||
1177 | |||
1178 | static const struct mtk_pll_div_table mmpll_div_table[] = { | ||
1179 | { .div = 0, .freq = MT2712_PLL_FMAX }, | ||
1180 | { .div = 1, .freq = 1001000000 }, | ||
1181 | { .div = 2, .freq = 601250000 }, | ||
1182 | { .div = 3, .freq = 250250000 }, | ||
1183 | { .div = 4, .freq = 125125000 }, | ||
1184 | { } /* sentinel */ | ||
1185 | }; | ||
1186 | |||
1187 | static const struct mtk_pll_data plls[] = { | ||
1188 | PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x0230, 0x023C, 0xf0000101, | ||
1189 | HAVE_RST_BAR, 31, 0x0230, 4, 0, 0, 0, 0x0234, 0), | ||
1190 | PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x0240, 0x024C, 0xfe000101, | ||
1191 | HAVE_RST_BAR, 31, 0x0240, 4, 0, 0, 0, 0x0244, 0), | ||
1192 | PLL(CLK_APMIXED_VCODECPLL, "vcodecpll", 0x0320, 0x032C, 0xc0000101, | ||
1193 | 0, 31, 0x0320, 4, 0, 0, 0, 0x0324, 0), | ||
1194 | PLL(CLK_APMIXED_VENCPLL, "vencpll", 0x0280, 0x028C, 0x00000101, | ||
1195 | 0, 31, 0x0280, 4, 0, 0, 0, 0x0284, 0), | ||
1196 | PLL(CLK_APMIXED_APLL1, "apll1", 0x0330, 0x0340, 0x00000101, | ||
1197 | 0, 31, 0x0330, 4, 0x0338, 0x0014, 0, 0x0334, 0), | ||
1198 | PLL(CLK_APMIXED_APLL2, "apll2", 0x0350, 0x0360, 0x00000101, | ||
1199 | 0, 31, 0x0350, 4, 0x0358, 0x0014, 1, 0x0354, 0), | ||
1200 | PLL(CLK_APMIXED_LVDSPLL, "lvdspll", 0x0370, 0x037c, 0x00000101, | ||
1201 | 0, 31, 0x0370, 4, 0, 0, 0, 0x0374, 0), | ||
1202 | PLL(CLK_APMIXED_LVDSPLL2, "lvdspll2", 0x0390, 0x039C, 0x00000101, | ||
1203 | 0, 31, 0x0390, 4, 0, 0, 0, 0x0394, 0), | ||
1204 | PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0270, 0x027C, 0x00000101, | ||
1205 | 0, 31, 0x0270, 4, 0, 0, 0, 0x0274, 0), | ||
1206 | PLL(CLK_APMIXED_MSDCPLL2, "msdcpll2", 0x0410, 0x041C, 0x00000101, | ||
1207 | 0, 31, 0x0410, 4, 0, 0, 0, 0x0414, 0), | ||
1208 | PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x0290, 0x029C, 0xc0000101, | ||
1209 | 0, 31, 0x0290, 4, 0, 0, 0, 0x0294, 0), | ||
1210 | PLL_B(CLK_APMIXED_MMPLL, "mmpll", 0x0250, 0x0260, 0x00000101, | ||
1211 | 0, 31, 0x0250, 4, 0, 0, 0, 0x0254, 0, | ||
1212 | mmpll_div_table), | ||
1213 | PLL_B(CLK_APMIXED_ARMCA35PLL, "armca35pll", 0x0100, 0x0110, 0xf0000101, | ||
1214 | HAVE_RST_BAR, 31, 0x0100, 4, 0, 0, 0, 0x0104, 0, | ||
1215 | armca35pll_div_table), | ||
1216 | PLL_B(CLK_APMIXED_ARMCA72PLL, "armca72pll", 0x0210, 0x0220, 0x00000101, | ||
1217 | 0, 31, 0x0210, 4, 0, 0, 0, 0x0214, 0, | ||
1218 | armca72pll_div_table), | ||
1219 | PLL(CLK_APMIXED_ETHERPLL, "etherpll", 0x0300, 0x030C, 0xc0000101, | ||
1220 | 0, 31, 0x0300, 4, 0, 0, 0, 0x0304, 0), | ||
1221 | }; | ||
1222 | |||
1223 | static int clk_mt2712_apmixed_probe(struct platform_device *pdev) | ||
1224 | { | ||
1225 | struct clk_onecell_data *clk_data; | ||
1226 | int r; | ||
1227 | struct device_node *node = pdev->dev.of_node; | ||
1228 | |||
1229 | clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK); | ||
1230 | |||
1231 | mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); | ||
1232 | |||
1233 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
1234 | |||
1235 | if (r != 0) | ||
1236 | pr_err("%s(): could not register clock provider: %d\n", | ||
1237 | __func__, r); | ||
1238 | |||
1239 | return r; | ||
1240 | } | ||
1241 | |||
1242 | static struct clk_onecell_data *top_clk_data; | ||
1243 | |||
1244 | static void clk_mt2712_top_init_early(struct device_node *node) | ||
1245 | { | ||
1246 | int r, i; | ||
1247 | |||
1248 | if (!top_clk_data) { | ||
1249 | top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); | ||
1250 | |||
1251 | for (i = 0; i < CLK_TOP_NR_CLK; i++) | ||
1252 | top_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER); | ||
1253 | } | ||
1254 | |||
1255 | mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs), | ||
1256 | top_clk_data); | ||
1257 | |||
1258 | r = of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data); | ||
1259 | if (r) | ||
1260 | pr_err("%s(): could not register clock provider: %d\n", | ||
1261 | __func__, r); | ||
1262 | } | ||
1263 | |||
1264 | CLK_OF_DECLARE_DRIVER(mt2712_topckgen, "mediatek,mt2712-topckgen", | ||
1265 | clk_mt2712_top_init_early); | ||
1266 | |||
1267 | static int clk_mt2712_top_probe(struct platform_device *pdev) | ||
1268 | { | ||
1269 | int r, i; | ||
1270 | struct device_node *node = pdev->dev.of_node; | ||
1271 | void __iomem *base; | ||
1272 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1273 | |||
1274 | base = devm_ioremap_resource(&pdev->dev, res); | ||
1275 | if (IS_ERR(base)) { | ||
1276 | pr_err("%s(): ioremap failed\n", __func__); | ||
1277 | return PTR_ERR(base); | ||
1278 | } | ||
1279 | |||
1280 | if (!top_clk_data) { | ||
1281 | top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); | ||
1282 | } else { | ||
1283 | for (i = 0; i < CLK_TOP_NR_CLK; i++) { | ||
1284 | if (top_clk_data->clks[i] == ERR_PTR(-EPROBE_DEFER)) | ||
1285 | top_clk_data->clks[i] = ERR_PTR(-ENOENT); | ||
1286 | } | ||
1287 | } | ||
1288 | |||
1289 | mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), | ||
1290 | top_clk_data); | ||
1291 | mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs), | ||
1292 | top_clk_data); | ||
1293 | mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data); | ||
1294 | mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base, | ||
1295 | &mt2712_clk_lock, top_clk_data); | ||
1296 | mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs), base, | ||
1297 | &mt2712_clk_lock, top_clk_data); | ||
1298 | mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks), | ||
1299 | top_clk_data); | ||
1300 | |||
1301 | r = of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data); | ||
1302 | |||
1303 | if (r != 0) | ||
1304 | pr_err("%s(): could not register clock provider: %d\n", | ||
1305 | __func__, r); | ||
1306 | |||
1307 | return r; | ||
1308 | } | ||
1309 | |||
1310 | static int clk_mt2712_infra_probe(struct platform_device *pdev) | ||
1311 | { | ||
1312 | struct clk_onecell_data *clk_data; | ||
1313 | int r; | ||
1314 | struct device_node *node = pdev->dev.of_node; | ||
1315 | |||
1316 | clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK); | ||
1317 | |||
1318 | mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), | ||
1319 | clk_data); | ||
1320 | |||
1321 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
1322 | |||
1323 | if (r != 0) | ||
1324 | pr_err("%s(): could not register clock provider: %d\n", | ||
1325 | __func__, r); | ||
1326 | |||
1327 | mtk_register_reset_controller(node, 2, 0x30); | ||
1328 | |||
1329 | return r; | ||
1330 | } | ||
1331 | |||
1332 | static int clk_mt2712_peri_probe(struct platform_device *pdev) | ||
1333 | { | ||
1334 | struct clk_onecell_data *clk_data; | ||
1335 | int r; | ||
1336 | struct device_node *node = pdev->dev.of_node; | ||
1337 | |||
1338 | clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK); | ||
1339 | |||
1340 | mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks), | ||
1341 | clk_data); | ||
1342 | |||
1343 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
1344 | |||
1345 | if (r != 0) | ||
1346 | pr_err("%s(): could not register clock provider: %d\n", | ||
1347 | __func__, r); | ||
1348 | |||
1349 | mtk_register_reset_controller(node, 2, 0); | ||
1350 | |||
1351 | return r; | ||
1352 | } | ||
1353 | |||
1354 | static int clk_mt2712_mcu_probe(struct platform_device *pdev) | ||
1355 | { | ||
1356 | struct clk_onecell_data *clk_data; | ||
1357 | int r; | ||
1358 | struct device_node *node = pdev->dev.of_node; | ||
1359 | void __iomem *base; | ||
1360 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1361 | |||
1362 | base = devm_ioremap_resource(&pdev->dev, res); | ||
1363 | if (IS_ERR(base)) { | ||
1364 | pr_err("%s(): ioremap failed\n", __func__); | ||
1365 | return PTR_ERR(base); | ||
1366 | } | ||
1367 | |||
1368 | clk_data = mtk_alloc_clk_data(CLK_MCU_NR_CLK); | ||
1369 | |||
1370 | mtk_clk_register_composites(mcu_muxes, ARRAY_SIZE(mcu_muxes), base, | ||
1371 | &mt2712_clk_lock, clk_data); | ||
1372 | |||
1373 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
1374 | |||
1375 | if (r != 0) | ||
1376 | pr_err("%s(): could not register clock provider: %d\n", | ||
1377 | __func__, r); | ||
1378 | |||
1379 | return r; | ||
1380 | } | ||
1381 | |||
1382 | static const struct of_device_id of_match_clk_mt2712[] = { | ||
1383 | { | ||
1384 | .compatible = "mediatek,mt2712-apmixedsys", | ||
1385 | .data = clk_mt2712_apmixed_probe, | ||
1386 | }, { | ||
1387 | .compatible = "mediatek,mt2712-topckgen", | ||
1388 | .data = clk_mt2712_top_probe, | ||
1389 | }, { | ||
1390 | .compatible = "mediatek,mt2712-infracfg", | ||
1391 | .data = clk_mt2712_infra_probe, | ||
1392 | }, { | ||
1393 | .compatible = "mediatek,mt2712-pericfg", | ||
1394 | .data = clk_mt2712_peri_probe, | ||
1395 | }, { | ||
1396 | .compatible = "mediatek,mt2712-mcucfg", | ||
1397 | .data = clk_mt2712_mcu_probe, | ||
1398 | }, { | ||
1399 | /* sentinel */ | ||
1400 | } | ||
1401 | }; | ||
1402 | |||
1403 | static int clk_mt2712_probe(struct platform_device *pdev) | ||
1404 | { | ||
1405 | int (*clk_probe)(struct platform_device *); | ||
1406 | int r; | ||
1407 | |||
1408 | clk_probe = of_device_get_match_data(&pdev->dev); | ||
1409 | if (!clk_probe) | ||
1410 | return -EINVAL; | ||
1411 | |||
1412 | r = clk_probe(pdev); | ||
1413 | if (r != 0) | ||
1414 | dev_err(&pdev->dev, | ||
1415 | "could not register clock provider: %s: %d\n", | ||
1416 | pdev->name, r); | ||
1417 | |||
1418 | return r; | ||
1419 | } | ||
1420 | |||
1421 | static struct platform_driver clk_mt2712_drv = { | ||
1422 | .probe = clk_mt2712_probe, | ||
1423 | .driver = { | ||
1424 | .name = "clk-mt2712", | ||
1425 | .owner = THIS_MODULE, | ||
1426 | .of_match_table = of_match_clk_mt2712, | ||
1427 | }, | ||
1428 | }; | ||
1429 | |||
1430 | static int __init clk_mt2712_init(void) | ||
1431 | { | ||
1432 | return platform_driver_register(&clk_mt2712_drv); | ||
1433 | } | ||
1434 | |||
1435 | arch_initcall(clk_mt2712_init); | ||
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h index f5d6b70ce189..f48df75cc901 100644 --- a/drivers/clk/mediatek/clk-mtk.h +++ b/drivers/clk/mediatek/clk-mtk.h | |||
@@ -207,6 +207,8 @@ struct mtk_pll_data { | |||
207 | uint32_t en_mask; | 207 | uint32_t en_mask; |
208 | uint32_t pd_reg; | 208 | uint32_t pd_reg; |
209 | uint32_t tuner_reg; | 209 | uint32_t tuner_reg; |
210 | uint32_t tuner_en_reg; | ||
211 | uint8_t tuner_en_bit; | ||
210 | int pd_shift; | 212 | int pd_shift; |
211 | unsigned int flags; | 213 | unsigned int flags; |
212 | const struct clk_ops *ops; | 214 | const struct clk_ops *ops; |
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c index a409142e9346..3c546bae6955 100644 --- a/drivers/clk/mediatek/clk-pll.c +++ b/drivers/clk/mediatek/clk-pll.c | |||
@@ -47,6 +47,7 @@ struct mtk_clk_pll { | |||
47 | void __iomem *pd_addr; | 47 | void __iomem *pd_addr; |
48 | void __iomem *pwr_addr; | 48 | void __iomem *pwr_addr; |
49 | void __iomem *tuner_addr; | 49 | void __iomem *tuner_addr; |
50 | void __iomem *tuner_en_addr; | ||
50 | void __iomem *pcw_addr; | 51 | void __iomem *pcw_addr; |
51 | const struct mtk_pll_data *data; | 52 | const struct mtk_pll_data *data; |
52 | }; | 53 | }; |
@@ -227,7 +228,10 @@ static int mtk_pll_prepare(struct clk_hw *hw) | |||
227 | r |= pll->data->en_mask; | 228 | r |= pll->data->en_mask; |
228 | writel(r, pll->base_addr + REG_CON0); | 229 | writel(r, pll->base_addr + REG_CON0); |
229 | 230 | ||
230 | if (pll->tuner_addr) { | 231 | if (pll->tuner_en_addr) { |
232 | r = readl(pll->tuner_en_addr) | BIT(pll->data->tuner_en_bit); | ||
233 | writel(r, pll->tuner_en_addr); | ||
234 | } else if (pll->tuner_addr) { | ||
231 | r = readl(pll->tuner_addr) | AUDPLL_TUNER_EN; | 235 | r = readl(pll->tuner_addr) | AUDPLL_TUNER_EN; |
232 | writel(r, pll->tuner_addr); | 236 | writel(r, pll->tuner_addr); |
233 | } | 237 | } |
@@ -254,7 +258,10 @@ static void mtk_pll_unprepare(struct clk_hw *hw) | |||
254 | writel(r, pll->base_addr + REG_CON0); | 258 | writel(r, pll->base_addr + REG_CON0); |
255 | } | 259 | } |
256 | 260 | ||
257 | if (pll->tuner_addr) { | 261 | if (pll->tuner_en_addr) { |
262 | r = readl(pll->tuner_en_addr) & ~BIT(pll->data->tuner_en_bit); | ||
263 | writel(r, pll->tuner_en_addr); | ||
264 | } else if (pll->tuner_addr) { | ||
258 | r = readl(pll->tuner_addr) & ~AUDPLL_TUNER_EN; | 265 | r = readl(pll->tuner_addr) & ~AUDPLL_TUNER_EN; |
259 | writel(r, pll->tuner_addr); | 266 | writel(r, pll->tuner_addr); |
260 | } | 267 | } |
@@ -297,6 +304,8 @@ static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data, | |||
297 | pll->pcw_addr = base + data->pcw_reg; | 304 | pll->pcw_addr = base + data->pcw_reg; |
298 | if (data->tuner_reg) | 305 | if (data->tuner_reg) |
299 | pll->tuner_addr = base + data->tuner_reg; | 306 | pll->tuner_addr = base + data->tuner_reg; |
307 | if (data->tuner_en_reg) | ||
308 | pll->tuner_en_addr = base + data->tuner_en_reg; | ||
300 | pll->hw.init = &init; | 309 | pll->hw.init = &init; |
301 | pll->data = data; | 310 | pll->data = data; |
302 | 311 | ||