Skip to content

Commit 4b47194

Browse files
SamShih33bebarino
authored andcommitted
clk: mediatek: add drivers for MT7988 SoC
Add APMIXED, ETH, INFRACFG and TOPCKGEN clock drivers which are typical MediaTek designs. Also add driver for XFIPLL clock generating the 156.25MHz clock for the XFI SerDes. It needs an undocumented software workaround and has an unknown internal design. Signed-off-by: Sam Shih <[email protected]> Signed-off-by: Daniel Golle <[email protected]> Reviewed-by: AngeloGioacchino Del Regno <[email protected]> Link: https://lore.kernel.org/r/c7574d808e2da1a530182f0fd790c1337c336e1b.1702849494.git.daniel@makrotopia.org [[email protected]: Add module license to infracfg file] Signed-off-by: Stephen Boyd <[email protected]>
1 parent d9bf944 commit 4b47194

File tree

7 files changed

+960
-0
lines changed

7 files changed

+960
-0
lines changed

drivers/clk/mediatek/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,15 @@ config COMMON_CLK_MT7986_ETHSYS
423423
This driver adds support for clocks for Ethernet and SGMII
424424
required on MediaTek MT7986 SoC.
425425

426+
config COMMON_CLK_MT7988
427+
tristate "Clock driver for MediaTek MT7988"
428+
depends on ARCH_MEDIATEK || COMPILE_TEST
429+
select COMMON_CLK_MEDIATEK
430+
default ARCH_MEDIATEK
431+
help
432+
This driver supports MediaTek MT7988 basic clocks and clocks
433+
required for various periperals found on this SoC.
434+
426435
config COMMON_CLK_MT8135
427436
tristate "Clock driver for MediaTek MT8135"
428437
depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST

drivers/clk/mediatek/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-apmixed.o
6262
obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-topckgen.o
6363
obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-infracfg.o
6464
obj-$(CONFIG_COMMON_CLK_MT7986_ETHSYS) += clk-mt7986-eth.o
65+
obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-apmixed.o
66+
obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-topckgen.o
67+
obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-infracfg.o
68+
obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-eth.o
69+
obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-xfipll.o
6570
obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135-apmixedsys.o clk-mt8135.o
6671
obj-$(CONFIG_COMMON_CLK_MT8167) += clk-mt8167-apmixedsys.o clk-mt8167.o
6772
obj-$(CONFIG_COMMON_CLK_MT8167_AUDSYS) += clk-mt8167-aud.o
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Copyright (c) 2023 MediaTek Inc.
4+
* Author: Sam Shih <[email protected]>
5+
* Author: Xiufeng Li <[email protected]>
6+
*/
7+
8+
#include <linux/clk-provider.h>
9+
#include <linux/of.h>
10+
#include <linux/of_address.h>
11+
#include <linux/of_device.h>
12+
#include <linux/platform_device.h>
13+
#include "clk-mtk.h"
14+
#include "clk-gate.h"
15+
#include "clk-mux.h"
16+
#include "clk-pll.h"
17+
#include <dt-bindings/clock/mediatek,mt7988-clk.h>
18+
19+
#define MT7988_PLL_FMAX (2500UL * MHZ)
20+
#define MT7988_PCW_CHG_BIT 2
21+
22+
#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _rst_bar_mask, _pcwbits, _pd_reg, \
23+
_pd_shift, _tuner_reg, _tuner_en_reg, _tuner_en_bit, _pcw_reg, _pcw_shift, \
24+
_pcw_chg_reg) \
25+
{ \
26+
.id = _id, \
27+
.name = _name, \
28+
.reg = _reg, \
29+
.pwr_reg = _pwr_reg, \
30+
.en_mask = _en_mask, \
31+
.flags = _flags, \
32+
.rst_bar_mask = BIT(_rst_bar_mask), \
33+
.fmax = MT7988_PLL_FMAX, \
34+
.pcwbits = _pcwbits, \
35+
.pd_reg = _pd_reg, \
36+
.pd_shift = _pd_shift, \
37+
.tuner_reg = _tuner_reg, \
38+
.tuner_en_reg = _tuner_en_reg, \
39+
.tuner_en_bit = _tuner_en_bit, \
40+
.pcw_reg = _pcw_reg, \
41+
.pcw_shift = _pcw_shift, \
42+
.pcw_chg_reg = _pcw_chg_reg, \
43+
.pcw_chg_bit = MT7988_PCW_CHG_BIT, \
44+
.parent_name = "clkxtal", \
45+
}
46+
47+
static const struct mtk_pll_data plls[] = {
48+
PLL(CLK_APMIXED_NETSYSPLL, "netsyspll", 0x0104, 0x0110, 0x00000001, 0, 0, 32, 0x0104, 4, 0,
49+
0, 0, 0x0108, 0, 0x0104),
50+
PLL(CLK_APMIXED_MPLL, "mpll", 0x0114, 0x0120, 0xff000001, HAVE_RST_BAR, 23, 32, 0x0114, 4,
51+
0, 0, 0, 0x0118, 0, 0x0114),
52+
PLL(CLK_APMIXED_MMPLL, "mmpll", 0x0124, 0x0130, 0xff000001, HAVE_RST_BAR, 23, 32, 0x0124, 4,
53+
0, 0, 0, 0x0128, 0, 0x0124),
54+
PLL(CLK_APMIXED_APLL2, "apll2", 0x0134, 0x0140, 0x00000001, 0, 0, 32, 0x0134, 4, 0x0704,
55+
0x0700, 1, 0x0138, 0, 0x0134),
56+
PLL(CLK_APMIXED_NET1PLL, "net1pll", 0x0144, 0x0150, 0xff000001, HAVE_RST_BAR, 23, 32,
57+
0x0144, 4, 0, 0, 0, 0x0148, 0, 0x0144),
58+
PLL(CLK_APMIXED_NET2PLL, "net2pll", 0x0154, 0x0160, 0xff000001, (HAVE_RST_BAR | PLL_AO), 23,
59+
32, 0x0154, 4, 0, 0, 0, 0x0158, 0, 0x0154),
60+
PLL(CLK_APMIXED_WEDMCUPLL, "wedmcupll", 0x0164, 0x0170, 0x00000001, 0, 0, 32, 0x0164, 4, 0,
61+
0, 0, 0x0168, 0, 0x0164),
62+
PLL(CLK_APMIXED_SGMPLL, "sgmpll", 0x0174, 0x0180, 0x00000001, 0, 0, 32, 0x0174, 4, 0, 0, 0,
63+
0x0178, 0, 0x0174),
64+
PLL(CLK_APMIXED_ARM_B, "arm_b", 0x0204, 0x0210, 0xff000001, (HAVE_RST_BAR | PLL_AO), 23, 32,
65+
0x0204, 4, 0, 0, 0, 0x0208, 0, 0x0204),
66+
PLL(CLK_APMIXED_CCIPLL2_B, "ccipll2_b", 0x0214, 0x0220, 0xff000001, HAVE_RST_BAR, 23, 32,
67+
0x0214, 4, 0, 0, 0, 0x0218, 0, 0x0214),
68+
PLL(CLK_APMIXED_USXGMIIPLL, "usxgmiipll", 0x0304, 0x0310, 0xff000001, HAVE_RST_BAR, 23, 32,
69+
0x0304, 4, 0, 0, 0, 0x0308, 0, 0x0304),
70+
PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0314, 0x0320, 0x00000001, 0, 0, 32, 0x0314, 4, 0, 0,
71+
0, 0x0318, 0, 0x0314),
72+
};
73+
74+
static const struct of_device_id of_match_clk_mt7988_apmixed[] = {
75+
{ .compatible = "mediatek,mt7988-apmixedsys" },
76+
{ /* sentinel */ }
77+
};
78+
79+
static int clk_mt7988_apmixed_probe(struct platform_device *pdev)
80+
{
81+
struct clk_hw_onecell_data *clk_data;
82+
struct device_node *node = pdev->dev.of_node;
83+
int r;
84+
85+
clk_data = mtk_alloc_clk_data(ARRAY_SIZE(plls));
86+
if (!clk_data)
87+
return -ENOMEM;
88+
89+
r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
90+
if (r)
91+
goto free_apmixed_data;
92+
93+
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
94+
if (r)
95+
goto unregister_plls;
96+
97+
return r;
98+
99+
unregister_plls:
100+
mtk_clk_unregister_plls(plls, ARRAY_SIZE(plls), clk_data);
101+
free_apmixed_data:
102+
mtk_free_clk_data(clk_data);
103+
return r;
104+
}
105+
106+
static struct platform_driver clk_mt7988_apmixed_drv = {
107+
.probe = clk_mt7988_apmixed_probe,
108+
.driver = {
109+
.name = "clk-mt7988-apmixed",
110+
.of_match_table = of_match_clk_mt7988_apmixed,
111+
},
112+
};
113+
builtin_platform_driver(clk_mt7988_apmixed_drv);
114+
MODULE_LICENSE("GPL");

drivers/clk/mediatek/clk-mt7988-eth.c

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Copyright (c) 2023 MediaTek Inc.
4+
* Author: Sam Shih <[email protected]>
5+
* Author: Xiufeng Li <[email protected]>
6+
*/
7+
8+
#include <linux/clk-provider.h>
9+
#include <linux/of.h>
10+
#include <linux/of_address.h>
11+
#include <linux/of_device.h>
12+
#include <linux/platform_device.h>
13+
#include "clk-mtk.h"
14+
#include "clk-gate.h"
15+
#include "reset.h"
16+
#include <dt-bindings/clock/mediatek,mt7988-clk.h>
17+
#include <dt-bindings/reset/mediatek,mt7988-resets.h>
18+
19+
static const struct mtk_gate_regs ethdma_cg_regs = {
20+
.set_ofs = 0x30,
21+
.clr_ofs = 0x30,
22+
.sta_ofs = 0x30,
23+
};
24+
25+
#define GATE_ETHDMA(_id, _name, _parent, _shift) \
26+
{ \
27+
.id = _id, \
28+
.name = _name, \
29+
.parent_name = _parent, \
30+
.regs = &ethdma_cg_regs, \
31+
.shift = _shift, \
32+
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
33+
}
34+
35+
static const struct mtk_gate ethdma_clks[] = {
36+
GATE_ETHDMA(CLK_ETHDMA_XGP1_EN, "ethdma_xgp1_en", "top_xtal", 0),
37+
GATE_ETHDMA(CLK_ETHDMA_XGP2_EN, "ethdma_xgp2_en", "top_xtal", 1),
38+
GATE_ETHDMA(CLK_ETHDMA_XGP3_EN, "ethdma_xgp3_en", "top_xtal", 2),
39+
GATE_ETHDMA(CLK_ETHDMA_FE_EN, "ethdma_fe_en", "netsys_2x_sel", 6),
40+
GATE_ETHDMA(CLK_ETHDMA_GP2_EN, "ethdma_gp2_en", "top_xtal", 7),
41+
GATE_ETHDMA(CLK_ETHDMA_GP1_EN, "ethdma_gp1_en", "top_xtal", 8),
42+
GATE_ETHDMA(CLK_ETHDMA_GP3_EN, "ethdma_gp3_en", "top_xtal", 10),
43+
GATE_ETHDMA(CLK_ETHDMA_ESW_EN, "ethdma_esw_en", "netsys_gsw_sel", 16),
44+
GATE_ETHDMA(CLK_ETHDMA_CRYPT0_EN, "ethdma_crypt0_en", "eip197_sel", 29),
45+
};
46+
47+
static const struct mtk_clk_desc ethdma_desc = {
48+
.clks = ethdma_clks,
49+
.num_clks = ARRAY_SIZE(ethdma_clks),
50+
};
51+
52+
static const struct mtk_gate_regs sgmii_cg_regs = {
53+
.set_ofs = 0xe4,
54+
.clr_ofs = 0xe4,
55+
.sta_ofs = 0xe4,
56+
};
57+
58+
#define GATE_SGMII(_id, _name, _parent, _shift) \
59+
{ \
60+
.id = _id, \
61+
.name = _name, \
62+
.parent_name = _parent, \
63+
.regs = &sgmii_cg_regs, \
64+
.shift = _shift, \
65+
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
66+
}
67+
68+
static const struct mtk_gate sgmii0_clks[] = {
69+
GATE_SGMII(CLK_SGM0_TX_EN, "sgm0_tx_en", "top_xtal", 2),
70+
GATE_SGMII(CLK_SGM0_RX_EN, "sgm0_rx_en", "top_xtal", 3),
71+
};
72+
73+
static const struct mtk_clk_desc sgmii0_desc = {
74+
.clks = sgmii0_clks,
75+
.num_clks = ARRAY_SIZE(sgmii0_clks),
76+
};
77+
78+
static const struct mtk_gate sgmii1_clks[] = {
79+
GATE_SGMII(CLK_SGM1_TX_EN, "sgm1_tx_en", "top_xtal", 2),
80+
GATE_SGMII(CLK_SGM1_RX_EN, "sgm1_rx_en", "top_xtal", 3),
81+
};
82+
83+
static const struct mtk_clk_desc sgmii1_desc = {
84+
.clks = sgmii1_clks,
85+
.num_clks = ARRAY_SIZE(sgmii1_clks),
86+
};
87+
88+
static const struct mtk_gate_regs ethwarp_cg_regs = {
89+
.set_ofs = 0x14,
90+
.clr_ofs = 0x14,
91+
.sta_ofs = 0x14,
92+
};
93+
94+
#define GATE_ETHWARP(_id, _name, _parent, _shift) \
95+
{ \
96+
.id = _id, \
97+
.name = _name, \
98+
.parent_name = _parent, \
99+
.regs = &ethwarp_cg_regs, \
100+
.shift = _shift, \
101+
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
102+
}
103+
104+
static const struct mtk_gate ethwarp_clks[] = {
105+
GATE_ETHWARP(CLK_ETHWARP_WOCPU2_EN, "ethwarp_wocpu2_en", "netsys_mcu_sel", 13),
106+
GATE_ETHWARP(CLK_ETHWARP_WOCPU1_EN, "ethwarp_wocpu1_en", "netsys_mcu_sel", 14),
107+
GATE_ETHWARP(CLK_ETHWARP_WOCPU0_EN, "ethwarp_wocpu0_en", "netsys_mcu_sel", 15),
108+
};
109+
110+
static u16 ethwarp_rst_ofs[] = { 0x8 };
111+
112+
static u16 ethwarp_idx_map[] = {
113+
[MT7988_ETHWARP_RST_SWITCH] = 9,
114+
};
115+
116+
static const struct mtk_clk_rst_desc ethwarp_rst_desc = {
117+
.version = MTK_RST_SIMPLE,
118+
.rst_bank_ofs = ethwarp_rst_ofs,
119+
.rst_bank_nr = ARRAY_SIZE(ethwarp_rst_ofs),
120+
.rst_idx_map = ethwarp_idx_map,
121+
.rst_idx_map_nr = ARRAY_SIZE(ethwarp_idx_map),
122+
};
123+
124+
static const struct mtk_clk_desc ethwarp_desc = {
125+
.clks = ethwarp_clks,
126+
.num_clks = ARRAY_SIZE(ethwarp_clks),
127+
.rst_desc = &ethwarp_rst_desc,
128+
};
129+
130+
static const struct of_device_id of_match_clk_mt7988_eth[] = {
131+
{ .compatible = "mediatek,mt7988-ethsys", .data = &ethdma_desc },
132+
{ .compatible = "mediatek,mt7988-sgmiisys0", .data = &sgmii0_desc },
133+
{ .compatible = "mediatek,mt7988-sgmiisys1", .data = &sgmii1_desc },
134+
{ .compatible = "mediatek,mt7988-ethwarp", .data = &ethwarp_desc },
135+
{ /* sentinel */ }
136+
};
137+
MODULE_DEVICE_TABLE(of, of_match_clk_mt7988_eth);
138+
139+
static struct platform_driver clk_mt7988_eth_drv = {
140+
.driver = {
141+
.name = "clk-mt7988-eth",
142+
.of_match_table = of_match_clk_mt7988_eth,
143+
},
144+
.probe = mtk_clk_simple_probe,
145+
.remove_new = mtk_clk_simple_remove,
146+
};
147+
module_platform_driver(clk_mt7988_eth_drv);
148+
149+
MODULE_DESCRIPTION("MediaTek MT7988 Ethernet clocks driver");
150+
MODULE_LICENSE("GPL");

0 commit comments

Comments
 (0)