@@ -12442,6 +12442,7 @@ M: Yassine Oudjana <y.oudjana@protonmail.com>
L: linux-clk@vger.kernel.org
L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
S: Maintained
+F: drivers/clk/mediatek/clk-mt6735-apmixed.c
F: include/dt-bindings/clock/mediatek,mt6735-apmixedsys.h
F: include/dt-bindings/clock/mediatek,mt6735-infracfg.h
F: include/dt-bindings/clock/mediatek,mt6735-pericfg.h
@@ -117,6 +117,13 @@ config COMMON_CLK_MT2712_VENCSYS
help
This driver supports MediaTek MT2712 vencsys clocks.
+config COMMON_CLK_MT6735_APMIXED
+ tristate "Clock driver for MediaTek MT6735 apmixedsys"
+ depends on ARCH_MEDIATEK || COMPILE_TEST
+ select COMMON_CLK_MEDIATEK
+ help
+ This driver supports MediaTek MT6735 apmixedsys clocks.
+
config COMMON_CLK_MT6765
bool "Clock driver for MediaTek MT6765"
depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o reset.o clk-mux.o
+obj-$(CONFIG_COMMON_CLK_MT6735_APMIXED) += clk-mt6735-apmixed.o
obj-$(CONFIG_COMMON_CLK_MT6765) += clk-mt6765.o
obj-$(CONFIG_COMMON_CLK_MT6765_AUDIOSYS) += clk-mt6765-audio.o
obj-$(CONFIG_COMMON_CLK_MT6765_CAMSYS) += clk-mt6765-cam.o
new file mode 100644
@@ -0,0 +1,274 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 Yassine Oudjana <y.oudjana@protonmail.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-pll.h"
+
+#include <dt-bindings/clock/mediatek,mt6735-apmixedsys.h>
+
+#define AP_PLL_CON_5 0x014
+#define ARMPLL_CON0 0x200
+#define ARMPLL_CON1 0x204
+#define ARMPLL_PWR_CON0 0x20c
+#define MAINPLL_CON0 0x210
+#define MAINPLL_CON1 0x214
+#define MAINPLL_PWR_CON0 0x21c
+#define UNIVPLL_CON0 0x220
+#define UNIVPLL_CON1 0x224
+#define UNIVPLL_PWR_CON0 0x22c
+#define MMPLL_CON0 0x230
+#define MMPLL_CON1 0x234
+#define MMPLL_PWR_CON0 0x23c
+#define MSDCPLL_CON0 0x240
+#define MSDCPLL_CON1 0x244
+#define MSDCPLL_PWR_CON0 0x24c
+#define VENCPLL_CON0 0x250
+#define VENCPLL_CON1 0x254
+#define VENCPLL_PWR_CON0 0x25c
+#define TVDPLL_CON0 0x260
+#define TVDPLL_CON1 0x264
+#define TVDPLL_PWR_CON0 0x26c
+#define APLL1_CON0 0x270
+#define APLL1_CON1 0x274
+#define APLL1_CON2 0x278
+#define APLL1_PWR_CON0 0x27c
+#define APLL2_CON0 0x280
+#define APLL2_CON1 0x284
+#define APLL2_CON2 0x288
+#define APLL2_PWR_CON0 0x28c
+
+#define CON0_RST_BAR BIT(24)
+
+static const struct mtk_pll_data apmixed_plls[] = {
+ {
+ .id = ARMPLL,
+ .name = "armpll",
+ .parent_name = "clk26m",
+
+ .reg = ARMPLL_CON0,
+ .pwr_reg = ARMPLL_PWR_CON0,
+ .en_mask = 0x00000001,
+
+ .pd_reg = ARMPLL_CON1,
+ .pd_shift = 24,
+
+ .pcw_reg = ARMPLL_CON1,
+ .pcw_chg_reg = ARMPLL_CON1,
+ .pcwbits = 21,
+
+ .flags = PLL_AO
+ },
+ {
+ .id = MAINPLL,
+ .name = "mainpll",
+ .parent_name = "clk26m",
+
+ .reg = MAINPLL_CON0,
+ .pwr_reg = MAINPLL_PWR_CON0,
+ .en_mask = 0xf0000101,
+
+ .pd_reg = MAINPLL_CON1,
+ .pd_shift = 24,
+
+ .pcw_reg = MAINPLL_CON1,
+ .pcw_chg_reg = MAINPLL_CON1,
+ .pcwbits = 21,
+
+ .flags = HAVE_RST_BAR,
+ .rst_bar_mask = CON0_RST_BAR
+ },
+ {
+ .id = UNIVPLL,
+ .name = "univpll",
+ .parent_name = "clk26m",
+
+ .reg = UNIVPLL_CON0,
+ .pwr_reg = UNIVPLL_PWR_CON0,
+ .en_mask = 0xfc000001,
+
+ .pd_reg = UNIVPLL_CON1,
+ .pd_shift = 24,
+
+ .pcw_reg = UNIVPLL_CON1,
+ .pcw_chg_reg = UNIVPLL_CON1,
+ .pcwbits = 21,
+
+ .flags = HAVE_RST_BAR,
+ .rst_bar_mask = CON0_RST_BAR
+ },
+ {
+ .id = MMPLL,
+ .name = "mmpll",
+ .parent_name = "clk26m",
+
+ .reg = MMPLL_CON0,
+ .pwr_reg = MMPLL_PWR_CON0,
+ .en_mask = 0x00000001,
+
+ .pd_reg = MMPLL_CON1,
+ .pd_shift = 24,
+
+ .pcw_reg = MMPLL_CON1,
+ .pcw_chg_reg = MMPLL_CON1,
+ .pcwbits = 21
+ },
+ {
+ .id = MSDCPLL,
+ .name = "msdcpll",
+ .parent_name = "clk26m",
+
+ .reg = MSDCPLL_CON0,
+ .pwr_reg = MSDCPLL_PWR_CON0,
+ .en_mask = 0x00000001,
+
+ .pd_reg = MSDCPLL_CON1,
+ .pd_shift = 24,
+
+ .pcw_reg = MSDCPLL_CON1,
+ .pcw_chg_reg = MSDCPLL_CON1,
+ .pcwbits = 21,
+ },
+ {
+ .id = VENCPLL,
+ .name = "vencpll",
+ .parent_name = "clk26m",
+
+ .reg = VENCPLL_CON0,
+ .pwr_reg = VENCPLL_PWR_CON0,
+ .en_mask = 0x00000001,
+
+ .pd_reg = VENCPLL_CON1,
+ .pd_shift = 24,
+
+ .pcw_reg = VENCPLL_CON1,
+ .pcw_chg_reg = VENCPLL_CON1,
+ .pcwbits = 21,
+
+ .flags = HAVE_RST_BAR,
+ .rst_bar_mask = CON0_RST_BAR
+ },
+ {
+ .id = TVDPLL,
+ .name = "tvdpll",
+ .parent_name = "clk26m",
+
+ .reg = TVDPLL_CON0,
+ .pwr_reg = TVDPLL_PWR_CON0,
+ .en_mask = 0x00000001,
+
+ .pd_reg = TVDPLL_CON1,
+ .pd_shift = 24,
+
+ .pcw_reg = TVDPLL_CON1,
+ .pcw_chg_reg = TVDPLL_CON1,
+ .pcwbits = 21
+ },
+ {
+ .id = APLL1,
+ .name = "apll1",
+ .parent_name = "clk26m",
+
+ .reg = APLL1_CON0,
+ .pwr_reg = APLL1_PWR_CON0,
+ .en_mask = 0x00000001,
+
+ .pd_reg = APLL1_CON0,
+ .pd_shift = 4,
+
+ .pcw_reg = APLL1_CON1,
+ .pcw_chg_reg = APLL1_CON1,
+ .pcwbits = 31,
+
+ .tuner_reg = APLL1_CON2,
+ .tuner_en_reg = AP_PLL_CON_5,
+ .tuner_en_bit = 0
+ },
+ {
+ .id = APLL2,
+ .name = "apll2",
+ .parent_name = "clk26m",
+
+ .reg = APLL2_CON0,
+ .pwr_reg = APLL2_PWR_CON0,
+ .en_mask = 0x00000001,
+
+ .pd_reg = APLL2_CON0,
+ .pd_shift = 4,
+
+ .pcw_reg = APLL2_CON1,
+ .pcw_chg_reg = APLL2_CON1,
+ .pcwbits = 31,
+
+ .tuner_reg = APLL1_CON2,
+ .tuner_en_reg = AP_PLL_CON_5,
+ .tuner_en_bit = 1
+ }
+};
+
+int clk_mt6735_apmixed_probe(struct platform_device *pdev)
+{
+ void __iomem *base;
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ struct clk_onecell_data *clk_data;
+ int ret;
+
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ clk_data = mtk_alloc_clk_data(ARRAY_SIZE(apmixed_plls));
+ if (!clk_data)
+ return -ENOMEM;
+ platform_set_drvdata(pdev, clk_data);
+
+ ret = mtk_clk_register_plls(pdev->dev.of_node, apmixed_plls,
+ ARRAY_SIZE(apmixed_plls), clk_data);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to register PLLs: %pe\n",
+ ERR_PTR(ret));
+ return ret;
+ }
+
+ ret = of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get,
+ clk_data);
+ if (ret)
+ dev_err(&pdev->dev, "Failed to register clock provider: %pe\n",
+ ERR_PTR(ret));
+
+ return ret;
+}
+
+int clk_mt6735_apmixed_remove(struct platform_device *pdev)
+{
+ struct clk_onecell_data *clk_data = platform_get_drvdata(pdev);
+
+ of_clk_del_provider(pdev->dev.of_node);
+ mtk_clk_unregister_plls(apmixed_plls, ARRAY_SIZE(apmixed_plls), clk_data);
+ mtk_free_clk_data(clk_data);
+
+ return 0;
+}
+
+static const struct of_device_id of_match_mt6735_apmixedsys[] = {
+ { .compatible = "mediatek,mt6735-apmixedsys" },
+ { /* sentinel */ }
+};
+
+static struct platform_driver clk_mt6735_apmixed = {
+ .probe = clk_mt6735_apmixed_probe,
+ .remove = clk_mt6735_apmixed_remove,
+ .driver = {
+ .name = "clk-mt6735-apmixed",
+ .of_match_table = of_match_mt6735_apmixedsys,
+ },
+};
+module_platform_driver(clk_mt6735_apmixed);
+
+MODULE_AUTHOR("Yassine Oudjana <y.oudjana@protonmail.com>");
+MODULE_DESCRIPTION("Mediatek MT6735 apmixedsys clock driver");
+MODULE_LICENSE("GPL");