1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2014 MediaTek Inc.
4 * Copyright (c) 2022 Collabora Ltd.
5 * Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
8 #include <dt-bindings/clock/mt8173-clk.h>
9 #include <linux/module.h>
10 #include <linux/platform_device.h>
11 #include "clk-cpumux.h"
16 #define GATE_ICG(_id, _name, _parent, _shift) \
17 GATE_MTK(_id, _name, _parent, &infra_cg_regs, \
18 _shift, &mtk_clk_gate_ops_setclr)
20 static struct clk_hw_onecell_data
*infra_clk_data
;
22 static const struct mtk_gate_regs infra_cg_regs
= {
28 static const char * const ca53_parents
[] __initconst
= {
35 static const char * const ca72_parents
[] __initconst
= {
42 static const struct mtk_composite cpu_muxes
[] = {
43 MUX(CLK_INFRA_CA53SEL
, "infra_ca53_sel", ca53_parents
, 0x0000, 0, 2),
44 MUX(CLK_INFRA_CA72SEL
, "infra_ca72_sel", ca72_parents
, 0x0000, 2, 2),
47 static const struct mtk_fixed_factor infra_early_divs
[] = {
48 FACTOR(CLK_INFRA_CLK_13M
, "clk13m", "clk26m", 1, 2),
51 static const struct mtk_gate infra_gates
[] = {
52 GATE_ICG(CLK_INFRA_DBGCLK
, "infra_dbgclk", "axi_sel", 0),
53 GATE_ICG(CLK_INFRA_SMI
, "infra_smi", "mm_sel", 1),
54 GATE_ICG(CLK_INFRA_AUDIO
, "infra_audio", "aud_intbus_sel", 5),
55 GATE_ICG(CLK_INFRA_GCE
, "infra_gce", "axi_sel", 6),
56 GATE_ICG(CLK_INFRA_L2C_SRAM
, "infra_l2c_sram", "axi_sel", 7),
57 GATE_ICG(CLK_INFRA_M4U
, "infra_m4u", "mem_sel", 8),
58 GATE_ICG(CLK_INFRA_CPUM
, "infra_cpum", "cpum_ck", 15),
59 GATE_ICG(CLK_INFRA_KP
, "infra_kp", "axi_sel", 16),
60 GATE_ICG(CLK_INFRA_CEC
, "infra_cec", "clk26m", 18),
61 GATE_ICG(CLK_INFRA_PMICSPI
, "infra_pmicspi", "pmicspi_sel", 22),
62 GATE_ICG(CLK_INFRA_PMICWRAP
, "infra_pmicwrap", "axi_sel", 23),
65 static u16 infrasys_rst_ofs
[] = { 0x30, 0x34 };
67 static const struct mtk_clk_rst_desc clk_rst_desc
= {
68 .version
= MTK_RST_SIMPLE
,
69 .rst_bank_ofs
= infrasys_rst_ofs
,
70 .rst_bank_nr
= ARRAY_SIZE(infrasys_rst_ofs
),
73 static const struct of_device_id of_match_clk_mt8173_infracfg
[] = {
74 { .compatible
= "mediatek,mt8173-infracfg" },
77 MODULE_DEVICE_TABLE(of
, of_match_clk_mt8173_infracfg
);
79 static void clk_mt8173_infra_init_early(struct device_node
*node
)
83 infra_clk_data
= mtk_alloc_clk_data(CLK_INFRA_NR_CLK
);
87 for (i
= 0; i
< CLK_INFRA_NR_CLK
; i
++)
88 infra_clk_data
->hws
[i
] = ERR_PTR(-EPROBE_DEFER
);
90 mtk_clk_register_factors(infra_early_divs
,
91 ARRAY_SIZE(infra_early_divs
), infra_clk_data
);
93 of_clk_add_hw_provider(node
, of_clk_hw_onecell_get
, infra_clk_data
);
95 CLK_OF_DECLARE_DRIVER(mtk_infrasys
, "mediatek,mt8173-infracfg",
96 clk_mt8173_infra_init_early
);
98 static int clk_mt8173_infracfg_probe(struct platform_device
*pdev
)
100 struct device_node
*node
= pdev
->dev
.of_node
;
103 if (!infra_clk_data
) {
104 infra_clk_data
= mtk_alloc_clk_data(CLK_INFRA_NR_CLK
);
108 for (i
= 0; i
< CLK_INFRA_NR_CLK
; i
++)
109 if (infra_clk_data
->hws
[i
] == ERR_PTR(-EPROBE_DEFER
))
110 infra_clk_data
->hws
[i
] = ERR_PTR(-ENOENT
);
113 r
= mtk_clk_register_gates(&pdev
->dev
, node
, infra_gates
,
114 ARRAY_SIZE(infra_gates
), infra_clk_data
);
118 r
= mtk_clk_register_cpumuxes(&pdev
->dev
, node
, cpu_muxes
,
119 ARRAY_SIZE(cpu_muxes
), infra_clk_data
);
121 goto unregister_gates
;
123 r
= of_clk_add_hw_provider(node
, of_clk_hw_onecell_get
, infra_clk_data
);
125 goto unregister_cpumuxes
;
127 r
= mtk_register_reset_controller_with_dev(&pdev
->dev
, &clk_rst_desc
);
129 goto unregister_clk_hw
;
134 of_clk_del_provider(node
);
136 mtk_clk_unregister_cpumuxes(cpu_muxes
, ARRAY_SIZE(cpu_muxes
), infra_clk_data
);
138 mtk_clk_unregister_gates(infra_gates
, ARRAY_SIZE(infra_gates
), infra_clk_data
);
142 static void clk_mt8173_infracfg_remove(struct platform_device
*pdev
)
144 struct device_node
*node
= pdev
->dev
.of_node
;
145 struct clk_hw_onecell_data
*clk_data
= platform_get_drvdata(pdev
);
147 of_clk_del_provider(node
);
148 mtk_clk_unregister_cpumuxes(cpu_muxes
, ARRAY_SIZE(cpu_muxes
), clk_data
);
149 mtk_clk_unregister_gates(infra_gates
, ARRAY_SIZE(infra_gates
), clk_data
);
150 mtk_free_clk_data(clk_data
);
153 static struct platform_driver clk_mt8173_infracfg_drv
= {
155 .name
= "clk-mt8173-infracfg",
156 .of_match_table
= of_match_clk_mt8173_infracfg
,
158 .probe
= clk_mt8173_infracfg_probe
,
159 .remove
= clk_mt8173_infracfg_remove
,
161 module_platform_driver(clk_mt8173_infracfg_drv
);
163 MODULE_DESCRIPTION("MediaTek MT8173 infracfg clocks driver");
164 MODULE_LICENSE("GPL");