diff mbox series

[06/13] clk: mediatek: Add driver for MT6735 apmixedsys

Message ID 20220504122601.335495-7-y.oudjana@protonmail.com (mailing list archive)
State New
Headers show
Series Mediatek MT6735 main clock and reset drivers | expand

Commit Message

Yassine Oudjana May 4, 2022, 12:25 p.m. UTC
From: Yassine Oudjana <y.oudjana@protonmail.com>

Add a driver for MT6735 apmixedsys PLLs.

Signed-off-by: Yassine Oudjana <y.oudjana@protonmail.com>
---
 MAINTAINERS                               |   1 +
 drivers/clk/mediatek/Kconfig              |   7 +
 drivers/clk/mediatek/Makefile             |   1 +
 drivers/clk/mediatek/clk-mt6735-apmixed.c | 274 ++++++++++++++++++++++
 4 files changed, 283 insertions(+)
 create mode 100644 drivers/clk/mediatek/clk-mt6735-apmixed.c
diff mbox series

Patch

diff --git a/MAINTAINERS b/MAINTAINERS
index de15c3d50d2d..1077712edb4b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -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
diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
index d5936cfb3bee..ab364892f602 100644
--- a/drivers/clk/mediatek/Kconfig
+++ b/drivers/clk/mediatek/Kconfig
@@ -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
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index caf2ce93d666..7f45a22c6178 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -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
diff --git a/drivers/clk/mediatek/clk-mt6735-apmixed.c b/drivers/clk/mediatek/clk-mt6735-apmixed.c
new file mode 100644
index 000000000000..6c4ec77d1d19
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6735-apmixed.c
@@ -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");