forked from coolsnowwolf/lede
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mediatek: backport clk driver for MT7981 SoC
Backport driver for common clocks in MT7981 SoC. The driver has also been submitted upstream and became part of Linux 6.3. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
- Loading branch information
Showing
10 changed files
with
1,185 additions
and
0 deletions.
There are no files selected for viewing
102 changes: 102 additions & 0 deletions
102
target/linux/mediatek/files-5.15/drivers/clk/mediatek/clk-mt7981-apmixed.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Copyright (c) 2021 MediaTek Inc. | ||
* Author: Sam Shih <sam.shih@mediatek.com> | ||
* Author: Wenzhen Yu <wenzhen.yu@mediatek.com> | ||
* Author: Jianhui Zhao <zhaojh329@gmail.com> | ||
* Author: Daniel Golle <daniel@makrotopia.org> | ||
*/ | ||
|
||
#include <linux/clk-provider.h> | ||
#include <linux/of.h> | ||
#include <linux/of_address.h> | ||
#include <linux/of_device.h> | ||
#include <linux/platform_device.h> | ||
#include "clk-mtk.h" | ||
#include "clk-gate.h" | ||
#include "clk-mux.h" | ||
|
||
#include <dt-bindings/clock/mediatek,mt7981-clk.h> | ||
#include <linux/clk.h> | ||
|
||
#define MT7981_PLL_FMAX (2500UL * MHZ) | ||
#define CON0_MT7981_RST_BAR BIT(27) | ||
|
||
#define PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \ | ||
_pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, \ | ||
_div_table, _parent_name) \ | ||
{ \ | ||
.id = _id, .name = _name, .reg = _reg, .pwr_reg = _pwr_reg, \ | ||
.en_mask = _en_mask, .flags = _flags, \ | ||
.rst_bar_mask = CON0_MT7981_RST_BAR, .fmax = MT7981_PLL_FMAX, \ | ||
.pcwbits = _pcwbits, .pd_reg = _pd_reg, .pd_shift = _pd_shift, \ | ||
.tuner_reg = _tuner_reg, .pcw_reg = _pcw_reg, \ | ||
.pcw_shift = _pcw_shift, .div_table = _div_table, \ | ||
.parent_name = _parent_name, \ | ||
} | ||
|
||
#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, \ | ||
_pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) \ | ||
PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \ | ||
_pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, NULL, \ | ||
"clkxtal") | ||
|
||
static const struct mtk_pll_data plls[] = { | ||
PLL(CLK_APMIXED_ARMPLL, "armpll", 0x0200, 0x020C, 0x00000001, PLL_AO, | ||
32, 0x0200, 4, 0, 0x0204, 0), | ||
PLL(CLK_APMIXED_NET2PLL, "net2pll", 0x0210, 0x021C, 0x00000001, 0, 32, | ||
0x0210, 4, 0, 0x0214, 0), | ||
PLL(CLK_APMIXED_MMPLL, "mmpll", 0x0220, 0x022C, 0x00000001, 0, 32, | ||
0x0220, 4, 0, 0x0224, 0), | ||
PLL(CLK_APMIXED_SGMPLL, "sgmpll", 0x0230, 0x023C, 0x00000001, 0, 32, | ||
0x0230, 4, 0, 0x0234, 0), | ||
PLL(CLK_APMIXED_WEDMCUPLL, "wedmcupll", 0x0240, 0x024C, 0x00000001, 0, 32, | ||
0x0240, 4, 0, 0x0244, 0), | ||
PLL(CLK_APMIXED_NET1PLL, "net1pll", 0x0250, 0x025C, 0x00000001, 0, 32, | ||
0x0250, 4, 0, 0x0254, 0), | ||
PLL(CLK_APMIXED_MPLL, "mpll", 0x0260, 0x0270, 0x00000001, 0, 32, | ||
0x0260, 4, 0, 0x0264, 0), | ||
PLL(CLK_APMIXED_APLL2, "apll2", 0x0278, 0x0288, 0x00000001, 0, 32, | ||
0x0278, 4, 0, 0x027C, 0), | ||
}; | ||
|
||
static const struct of_device_id of_match_clk_mt7981_apmixed[] = { | ||
{ .compatible = "mediatek,mt7981-apmixedsys", }, | ||
{} | ||
}; | ||
|
||
static int clk_mt7981_apmixed_probe(struct platform_device *pdev) | ||
{ | ||
struct clk_onecell_data *clk_data; | ||
struct device_node *node = pdev->dev.of_node; | ||
int r; | ||
|
||
clk_data = mtk_alloc_clk_data(ARRAY_SIZE(plls)); | ||
if (!clk_data) | ||
return -ENOMEM; | ||
|
||
mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); | ||
|
||
clk_prepare_enable(clk_data->clks[CLK_APMIXED_ARMPLL]); | ||
|
||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
if (r) { | ||
pr_err("%s(): could not register clock provider: %d\n", | ||
__func__, r); | ||
goto free_apmixed_data; | ||
} | ||
return r; | ||
|
||
free_apmixed_data: | ||
mtk_free_clk_data(clk_data); | ||
return r; | ||
} | ||
|
||
static struct platform_driver clk_mt7981_apmixed_drv = { | ||
.probe = clk_mt7981_apmixed_probe, | ||
.driver = { | ||
.name = "clk-mt7981-apmixed", | ||
.of_match_table = of_match_clk_mt7981_apmixed, | ||
}, | ||
}; | ||
builtin_platform_driver(clk_mt7981_apmixed_drv); |
139 changes: 139 additions & 0 deletions
139
target/linux/mediatek/files-5.15/drivers/clk/mediatek/clk-mt7981-eth.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Copyright (c) 2021 MediaTek Inc. | ||
* Author: Sam Shih <sam.shih@mediatek.com> | ||
* Author: Wenzhen Yu <wenzhen.yu@mediatek.com> | ||
* Author: Jianhui Zhao <zhaojh329@gmail.com> | ||
* Author: Daniel Golle <daniel@makrotopia.org> | ||
*/ | ||
|
||
#include <linux/clk-provider.h> | ||
#include <linux/of.h> | ||
#include <linux/of_address.h> | ||
#include <linux/of_device.h> | ||
#include <linux/platform_device.h> | ||
|
||
#include "clk-mtk.h" | ||
#include "clk-gate.h" | ||
|
||
#include <dt-bindings/clock/mediatek,mt7981-clk.h> | ||
|
||
static const struct mtk_gate_regs sgmii0_cg_regs = { | ||
.set_ofs = 0xE4, | ||
.clr_ofs = 0xE4, | ||
.sta_ofs = 0xE4, | ||
}; | ||
|
||
#define GATE_SGMII0(_id, _name, _parent, _shift) { \ | ||
.id = _id, \ | ||
.name = _name, \ | ||
.parent_name = _parent, \ | ||
.regs = &sgmii0_cg_regs, \ | ||
.shift = _shift, \ | ||
.ops = &mtk_clk_gate_ops_no_setclr_inv, \ | ||
} | ||
|
||
static const struct mtk_gate sgmii0_clks[] __initconst = { | ||
GATE_SGMII0(CLK_SGM0_TX_EN, "sgm0_tx_en", "usb_tx250m", 2), | ||
GATE_SGMII0(CLK_SGM0_RX_EN, "sgm0_rx_en", "usb_eq_rx250m", 3), | ||
GATE_SGMII0(CLK_SGM0_CK0_EN, "sgm0_ck0_en", "usb_ln0", 4), | ||
GATE_SGMII0(CLK_SGM0_CDR_CK0_EN, "sgm0_cdr_ck0_en", "usb_cdr", 5), | ||
}; | ||
|
||
static const struct mtk_gate_regs sgmii1_cg_regs = { | ||
.set_ofs = 0xE4, | ||
.clr_ofs = 0xE4, | ||
.sta_ofs = 0xE4, | ||
}; | ||
|
||
#define GATE_SGMII1(_id, _name, _parent, _shift) { \ | ||
.id = _id, \ | ||
.name = _name, \ | ||
.parent_name = _parent, \ | ||
.regs = &sgmii1_cg_regs, \ | ||
.shift = _shift, \ | ||
.ops = &mtk_clk_gate_ops_no_setclr_inv, \ | ||
} | ||
|
||
static const struct mtk_gate sgmii1_clks[] __initconst = { | ||
GATE_SGMII1(CLK_SGM1_TX_EN, "sgm1_tx_en", "usb_tx250m", 2), | ||
GATE_SGMII1(CLK_SGM1_RX_EN, "sgm1_rx_en", "usb_eq_rx250m", 3), | ||
GATE_SGMII1(CLK_SGM1_CK1_EN, "sgm1_ck1_en", "usb_ln0", 4), | ||
GATE_SGMII1(CLK_SGM1_CDR_CK1_EN, "sgm1_cdr_ck1_en", "usb_cdr", 5), | ||
}; | ||
|
||
static const struct mtk_gate_regs eth_cg_regs = { | ||
.set_ofs = 0x30, | ||
.clr_ofs = 0x30, | ||
.sta_ofs = 0x30, | ||
}; | ||
|
||
#define GATE_ETH(_id, _name, _parent, _shift) { \ | ||
.id = _id, \ | ||
.name = _name, \ | ||
.parent_name = _parent, \ | ||
.regs = ð_cg_regs, \ | ||
.shift = _shift, \ | ||
.ops = &mtk_clk_gate_ops_no_setclr_inv, \ | ||
} | ||
|
||
static const struct mtk_gate eth_clks[] __initconst = { | ||
GATE_ETH(CLK_ETH_FE_EN, "eth_fe_en", "netsys_2x", 6), | ||
GATE_ETH(CLK_ETH_GP2_EN, "eth_gp2_en", "sgm_325m", 7), | ||
GATE_ETH(CLK_ETH_GP1_EN, "eth_gp1_en", "sgm_325m", 8), | ||
GATE_ETH(CLK_ETH_WOCPU0_EN, "eth_wocpu0_en", "netsys_wed_mcu", 15), | ||
}; | ||
|
||
static void __init mtk_sgmiisys_0_init(struct device_node *node) | ||
{ | ||
struct clk_onecell_data *clk_data; | ||
int r; | ||
|
||
clk_data = mtk_alloc_clk_data(ARRAY_SIZE(sgmii0_clks)); | ||
|
||
mtk_clk_register_gates(node, sgmii0_clks, ARRAY_SIZE(sgmii0_clks), | ||
clk_data); | ||
|
||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
if (r) | ||
pr_err("%s(): could not register clock provider: %d\n", | ||
__func__, r); | ||
} | ||
CLK_OF_DECLARE(mtk_sgmiisys_0, "mediatek,mt7981-sgmiisys_0", | ||
mtk_sgmiisys_0_init); | ||
|
||
static void __init mtk_sgmiisys_1_init(struct device_node *node) | ||
{ | ||
struct clk_onecell_data *clk_data; | ||
int r; | ||
|
||
clk_data = mtk_alloc_clk_data(ARRAY_SIZE(sgmii1_clks)); | ||
|
||
mtk_clk_register_gates(node, sgmii1_clks, ARRAY_SIZE(sgmii1_clks), | ||
clk_data); | ||
|
||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
|
||
if (r) | ||
pr_err("%s(): could not register clock provider: %d\n", | ||
__func__, r); | ||
} | ||
CLK_OF_DECLARE(mtk_sgmiisys_1, "mediatek,mt7981-sgmiisys_1", | ||
mtk_sgmiisys_1_init); | ||
|
||
static void __init mtk_ethsys_init(struct device_node *node) | ||
{ | ||
struct clk_onecell_data *clk_data; | ||
int r; | ||
|
||
clk_data = mtk_alloc_clk_data(ARRAY_SIZE(eth_clks)); | ||
|
||
mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks), clk_data); | ||
|
||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
|
||
if (r) | ||
pr_err("%s(): could not register clock provider: %d\n", | ||
__func__, r); | ||
} | ||
CLK_OF_DECLARE(mtk_ethsys, "mediatek,mt7981-ethsys", mtk_ethsys_init); |
Oops, something went wrong.