Commit 4c02c9af authored by AngeloGioacchino Del Regno's avatar AngeloGioacchino Del Regno Committed by Stephen Boyd
Browse files

clk: mediatek: mt8173: Break down clock drivers and allow module build



Split the giant clock driver for MT8173 into smaller drivers and
make it possible to build the non boot critical clock controller
drivers as modules by adding remove functions and both module
description and license where needed.
While at it, also change a mtk_register_reset_controller() call
to mtk_register_reset_controller_with_dev() in mt8173-infracfg.

Some spare code style cleanups were also performed.

Signed-off-by: default avatarAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://lore.kernel.org/r/20230120092053.182923-11-angelogioacchino.delregno@collabora.com


Tested-by: default avatarMingming Su <mingming.su@mediatek.com>
Signed-off-by: default avatarStephen Boyd <sboyd@kernel.org>
parent a87d143c
Loading
Loading
Loading
Loading
+27 −5
Original line number Diff line number Diff line
@@ -457,20 +457,42 @@ config COMMON_CLK_MT8167_VDECSYS
	  This driver supports MediaTek MT8167 vdecsys clocks.

config COMMON_CLK_MT8173
	bool "Clock driver for MediaTek MT8173"
	depends on ARCH_MEDIATEK || COMPILE_TEST
	tristate "Clock driver for MediaTek MT8173"
	depends on ARM64 || COMPILE_TEST
	select COMMON_CLK_MEDIATEK
	default ARCH_MEDIATEK
	help
	  This driver supports MediaTek MT8173 clocks.
	  This driver supports MediaTek MT8173 basic clocks and clocks
	  required for various peripherals found on MediaTek.

config COMMON_CLK_MT8173_IMGSYS
	tristate "Clock driver for MediaTek MT8173 imgsys"
	depends on COMMON_CLK_MT8173
	default COMMON_CLK_MT8173
	help
	  This driver supports MediaTek MT8173 imgsys clocks.

config COMMON_CLK_MT8173_MMSYS
	bool "Clock driver for MediaTek MT8173 mmsys"
       tristate "Clock driver for MediaTek MT8173 mmsys"
       depends on COMMON_CLK_MT8173
	default COMMON_CLK_MT8173
       help
         This driver supports MediaTek MT8173 mmsys clocks.

config COMMON_CLK_MT8173_VDECSYS
	tristate "Clock driver for MediaTek MT8173 VDECSYS"
	depends on COMMON_CLK_MT8173
	default COMMON_CLK_MT8173
	help
	  This driver supports MediaTek MT8173 vdecsys clocks.

config COMMON_CLK_MT8173_VENCSYS
	tristate "Clock driver for MediaTek MT8173 VENCSYS"
	depends on COMMON_CLK_MT8173
	default COMMON_CLK_MT8173
	help
	  This driver supports MediaTek MT8173 vencsys clocks.

config COMMON_CLK_MT8183
	bool "Clock driver for MediaTek MT8183"
	depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+5 −1
Original line number Diff line number Diff line
@@ -64,8 +64,12 @@ obj-$(CONFIG_COMMON_CLK_MT8167_IMGSYS) += clk-mt8167-img.o
obj-$(CONFIG_COMMON_CLK_MT8167_MFGCFG) += clk-mt8167-mfgcfg.o
obj-$(CONFIG_COMMON_CLK_MT8167_MMSYS) += clk-mt8167-mm.o
obj-$(CONFIG_COMMON_CLK_MT8167_VDECSYS) += clk-mt8167-vdec.o
obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o
obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173-apmixedsys.o clk-mt8173-infracfg.o \
				   clk-mt8173-pericfg.o clk-mt8173-topckgen.o
obj-$(CONFIG_COMMON_CLK_MT8173_IMGSYS) += clk-mt8173-img.o
obj-$(CONFIG_COMMON_CLK_MT8173_MMSYS) += clk-mt8173-mm.o
obj-$(CONFIG_COMMON_CLK_MT8173_VDECSYS) += clk-mt8173-vdecsys.o
obj-$(CONFIG_COMMON_CLK_MT8173_VENCSYS) += clk-mt8173-vencsys.o
obj-$(CONFIG_COMMON_CLK_MT8183) += clk-mt8183.o
obj-$(CONFIG_COMMON_CLK_MT8183_AUDIOSYS) += clk-mt8183-audio.o
obj-$(CONFIG_COMMON_CLK_MT8183_CAMSYS) += clk-mt8183-cam.o
+157 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2014 MediaTek Inc.
 * Copyright (c) 2022 Collabora Ltd.
 * Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
 */

#include <dt-bindings/clock/mt8173-clk.h>
#include <linux/of_address.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include "clk-mtk.h"
#include "clk-pll.h"

#define REGOFF_REF2USB		0x8
#define REGOFF_HDMI_REF		0x40

#define MT8173_PLL_FMAX		(3000UL * MHZ)

#define CON0_MT8173_RST_BAR	BIT(24)

#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,	\
			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg,	\
			_pcw_shift, _div_table) {			\
		.id = _id,						\
		.name = _name,						\
		.reg = _reg,						\
		.pwr_reg = _pwr_reg,					\
		.en_mask = _en_mask,					\
		.flags = _flags,					\
		.rst_bar_mask = CON0_MT8173_RST_BAR,			\
		.fmax = MT8173_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,				\
	}

#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,	\
			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg,	\
			_pcw_shift)					\
		PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, \
			NULL)

static const struct mtk_pll_div_table mmpll_div_table[] = {
	{ .div = 0, .freq = MT8173_PLL_FMAX },
	{ .div = 1, .freq = 1000000000 },
	{ .div = 2, .freq = 702000000 },
	{ .div = 3, .freq = 253500000 },
	{ .div = 4, .freq = 126750000 },
	{ } /* sentinel */
};

static const struct mtk_pll_data plls[] = {
	PLL(CLK_APMIXED_ARMCA15PLL, "armca15pll", 0x200, 0x20c, 0, PLL_AO,
	    21, 0x204, 24, 0x0, 0x204, 0),
	PLL(CLK_APMIXED_ARMCA7PLL, "armca7pll", 0x210, 0x21c, 0, PLL_AO,
	    21, 0x214, 24, 0x0, 0x214, 0),
	PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x220, 0x22c, 0xf0000100, HAVE_RST_BAR, 21,
	    0x220, 4, 0x0, 0x224, 0),
	PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x230, 0x23c, 0xfe000000, HAVE_RST_BAR, 7,
	    0x230, 4, 0x0, 0x234, 14),
	PLL_B(CLK_APMIXED_MMPLL, "mmpll", 0x240, 0x24c, 0, 0, 21, 0x244, 24, 0x0,
	      0x244, 0, mmpll_div_table),
	PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x250, 0x25c, 0, 0, 21, 0x250, 4, 0x0, 0x254, 0),
	PLL(CLK_APMIXED_VENCPLL, "vencpll", 0x260, 0x26c, 0, 0, 21, 0x260, 4, 0x0, 0x264, 0),
	PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x270, 0x27c, 0, 0, 21, 0x270, 4, 0x0, 0x274, 0),
	PLL(CLK_APMIXED_MPLL, "mpll", 0x280, 0x28c, 0, 0, 21, 0x280, 4, 0x0, 0x284, 0),
	PLL(CLK_APMIXED_VCODECPLL, "vcodecpll", 0x290, 0x29c, 0, 0, 21, 0x290, 4, 0x0, 0x294, 0),
	PLL(CLK_APMIXED_APLL1, "apll1", 0x2a0, 0x2b0, 0, 0, 31, 0x2a0, 4, 0x2a4, 0x2a4, 0),
	PLL(CLK_APMIXED_APLL2, "apll2", 0x2b4, 0x2c4, 0, 0, 31, 0x2b4, 4, 0x2b8, 0x2b8, 0),
	PLL(CLK_APMIXED_LVDSPLL, "lvdspll", 0x2d0, 0x2dc, 0, 0, 21, 0x2d0, 4, 0x0, 0x2d4, 0),
	PLL(CLK_APMIXED_MSDCPLL2, "msdcpll2", 0x2f0, 0x2fc, 0, 0, 21, 0x2f0, 4, 0x0, 0x2f4, 0),
};

static const struct of_device_id of_match_clk_mt8173_apmixed[] = {
	{ .compatible = "mediatek,mt8173-apmixedsys" },
	{ /* sentinel */ }
};

static int clk_mt8173_apmixed_probe(struct platform_device *pdev)
{
	struct device_node *node = pdev->dev.of_node;
	struct clk_hw_onecell_data *clk_data;
	void __iomem *base;
	struct clk_hw *hw;
	int r;

	base = of_iomap(node, 0);
	if (!base)
		return PTR_ERR(base);

	clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
	if (IS_ERR_OR_NULL(clk_data))
		return -ENOMEM;

	r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
	if (r)
		goto free_clk_data;

	hw = mtk_clk_register_ref2usb_tx("ref2usb_tx", "clk26m", base + REGOFF_REF2USB);
	if (IS_ERR(hw)) {
		r = PTR_ERR(hw);
		dev_err(&pdev->dev, "Failed to register ref2usb_tx: %d\n", r);
		goto unregister_plls;
	}
	clk_data->hws[CLK_APMIXED_REF2USB_TX] = hw;

	hw = devm_clk_hw_register_divider(&pdev->dev, "hdmi_ref", "tvdpll_594m", 0,
					  base + REGOFF_HDMI_REF, 16, 3,
					  CLK_DIVIDER_POWER_OF_TWO, NULL);
	clk_data->hws[CLK_APMIXED_HDMI_REF] = hw;

	r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
	if (r)
		goto unregister_ref2usb;

	return 0;

unregister_ref2usb:
	mtk_clk_unregister_ref2usb_tx(clk_data->hws[CLK_APMIXED_REF2USB_TX]);
unregister_plls:
	mtk_clk_unregister_plls(plls, ARRAY_SIZE(plls), clk_data);
free_clk_data:
	mtk_free_clk_data(clk_data);
	return r;
}

static int clk_mt8173_apmixed_remove(struct platform_device *pdev)
{
	struct device_node *node = pdev->dev.of_node;
	struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev);

	of_clk_del_provider(node);
	mtk_clk_unregister_ref2usb_tx(clk_data->hws[CLK_APMIXED_REF2USB_TX]);
	mtk_clk_unregister_plls(plls, ARRAY_SIZE(plls), clk_data);
	mtk_free_clk_data(clk_data);

	return 0;
}

static struct platform_driver clk_mt8173_apmixed_drv = {
	.probe = clk_mt8173_apmixed_probe,
	.remove = clk_mt8173_apmixed_remove,
	.driver = {
		.name = "clk-mt8173-apmixed",
		.of_match_table = of_match_clk_mt8173_apmixed,
	},
};
module_platform_driver(clk_mt8173_apmixed_drv);

MODULE_DESCRIPTION("MediaTek MT8173 apmixed clocks driver");
MODULE_LICENSE("GPL");
+55 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2014 MediaTek Inc.
 * Copyright (c) 2022 Collabora Ltd.
 * Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
 */

#include <dt-bindings/clock/mt8173-clk.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include "clk-gate.h"
#include "clk-mtk.h"

static const struct mtk_gate_regs img_cg_regs = {
	.set_ofs = 0x0004,
	.clr_ofs = 0x0008,
	.sta_ofs = 0x0000,
};

#define GATE_IMG(_id, _name, _parent, _shift)			\
	GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_setclr)

static const struct mtk_gate img_clks[] = {
	GATE_DUMMY(CLK_DUMMY, "img_dummy"),
	GATE_IMG(CLK_IMG_LARB2_SMI, "img_larb2_smi", "mm_sel", 0),
	GATE_IMG(CLK_IMG_CAM_SMI, "img_cam_smi", "mm_sel", 5),
	GATE_IMG(CLK_IMG_CAM_CAM, "img_cam_cam", "mm_sel", 6),
	GATE_IMG(CLK_IMG_SEN_TG, "img_sen_tg", "camtg_sel", 7),
	GATE_IMG(CLK_IMG_SEN_CAM, "img_sen_cam", "mm_sel", 8),
	GATE_IMG(CLK_IMG_CAM_SV, "img_cam_sv", "mm_sel", 9),
	GATE_IMG(CLK_IMG_FD, "img_fd", "mm_sel", 11),
};

static const struct mtk_clk_desc img_desc = {
	.clks = img_clks,
	.num_clks = ARRAY_SIZE(img_clks),
};

static const struct of_device_id of_match_clk_mt8173_imgsys[] = {
	{ .compatible = "mediatek,mt8173-imgsys", .data = &img_desc },
	{ /* sentinel */ }
};

static struct platform_driver clk_mt8173_vdecsys_drv = {
	.probe = mtk_clk_simple_probe,
	.remove = mtk_clk_simple_remove,
	.driver = {
		.name = "clk-mt8173-imgsys",
		.of_match_table = of_match_clk_mt8173_imgsys,
	},
};
module_platform_driver(clk_mt8173_vdecsys_drv);

MODULE_DESCRIPTION("MediaTek MT8173 vdecsys clocks driver");
MODULE_LICENSE("GPL");
+155 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2014 MediaTek Inc.
 * Copyright (c) 2022 Collabora Ltd.
 * Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
 */

#include <dt-bindings/clock/mt8173-clk.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include "clk-cpumux.h"
#include "clk-gate.h"
#include "clk-mtk.h"
#include "reset.h"

#define GATE_ICG(_id, _name, _parent, _shift)			\
		GATE_MTK(_id, _name, _parent, &infra_cg_regs,	\
			 _shift, &mtk_clk_gate_ops_setclr)

static struct clk_hw_onecell_data *infra_clk_data;

static const struct mtk_gate_regs infra_cg_regs = {
	.set_ofs = 0x0040,
	.clr_ofs = 0x0044,
	.sta_ofs = 0x0048,
};

static const char * const ca53_parents[] __initconst = {
	"clk26m",
	"armca7pll",
	"mainpll",
	"univpll"
};

static const char * const ca72_parents[] __initconst = {
	"clk26m",
	"armca15pll",
	"mainpll",
	"univpll"
};

static const struct mtk_composite cpu_muxes[] = {
	MUX(CLK_INFRA_CA53SEL, "infra_ca53_sel", ca53_parents, 0x0000, 0, 2),
	MUX(CLK_INFRA_CA72SEL, "infra_ca72_sel", ca72_parents, 0x0000, 2, 2),
};

static const struct mtk_fixed_factor infra_early_divs[] = {
	FACTOR(CLK_INFRA_CLK_13M, "clk13m", "clk26m", 1, 2),
};

static const struct mtk_gate infra_gates[] = {
	GATE_ICG(CLK_INFRA_DBGCLK, "infra_dbgclk", "axi_sel", 0),
	GATE_ICG(CLK_INFRA_SMI, "infra_smi", "mm_sel", 1),
	GATE_ICG(CLK_INFRA_AUDIO, "infra_audio", "aud_intbus_sel", 5),
	GATE_ICG(CLK_INFRA_GCE, "infra_gce", "axi_sel", 6),
	GATE_ICG(CLK_INFRA_L2C_SRAM, "infra_l2c_sram", "axi_sel", 7),
	GATE_ICG(CLK_INFRA_M4U, "infra_m4u", "mem_sel", 8),
	GATE_ICG(CLK_INFRA_CPUM, "infra_cpum", "cpum_ck", 15),
	GATE_ICG(CLK_INFRA_KP, "infra_kp", "axi_sel", 16),
	GATE_ICG(CLK_INFRA_CEC, "infra_cec", "clk26m", 18),
	GATE_ICG(CLK_INFRA_PMICSPI, "infra_pmicspi", "pmicspi_sel", 22),
	GATE_ICG(CLK_INFRA_PMICWRAP, "infra_pmicwrap", "axi_sel", 23),
};

static u16 infrasys_rst_ofs[] = { 0x30, 0x34 };

static const struct mtk_clk_rst_desc clk_rst_desc = {
	.version = MTK_RST_SIMPLE,
	.rst_bank_ofs = infrasys_rst_ofs,
	.rst_bank_nr = ARRAY_SIZE(infrasys_rst_ofs),
};

static const struct of_device_id of_match_clk_mt8173_infracfg[] = {
	{ .compatible = "mediatek,mt8173-infracfg" },
	{ /* sentinel */ }
};

static void clk_mt8173_infra_init_early(struct device_node *node)
{
	int i;

	infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
	if (!infra_clk_data)
		return;

	for (i = 0; i < CLK_INFRA_NR_CLK; i++)
		infra_clk_data->hws[i] = ERR_PTR(-EPROBE_DEFER);

	mtk_clk_register_factors(infra_early_divs,
				 ARRAY_SIZE(infra_early_divs), infra_clk_data);

	of_clk_add_hw_provider(node, of_clk_hw_onecell_get, infra_clk_data);
}
CLK_OF_DECLARE_DRIVER(mtk_infrasys, "mediatek,mt8173-infracfg",
		      clk_mt8173_infra_init_early);

static int clk_mt8173_infracfg_probe(struct platform_device *pdev)
{
	struct device_node *node = pdev->dev.of_node;
	int r;

	r = mtk_clk_register_gates(&pdev->dev, node, infra_gates,
				   ARRAY_SIZE(infra_gates), infra_clk_data);
	if (r)
		return r;

	r = mtk_clk_register_cpumuxes(&pdev->dev, node, cpu_muxes,
				      ARRAY_SIZE(cpu_muxes), infra_clk_data);
	if (r)
		goto unregister_gates;

	r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, infra_clk_data);
	if (r)
		goto unregister_cpumuxes;

	r = mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
	if (r)
		goto unregister_clk_hw;

	return 0;

unregister_clk_hw:
	of_clk_del_provider(node);
unregister_cpumuxes:
	mtk_clk_unregister_cpumuxes(cpu_muxes, ARRAY_SIZE(cpu_muxes), infra_clk_data);
unregister_gates:
	mtk_clk_unregister_gates(infra_gates, ARRAY_SIZE(infra_gates), infra_clk_data);
	return r;
}

static int clk_mt8173_infracfg_remove(struct platform_device *pdev)
{
	struct device_node *node = pdev->dev.of_node;
	struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev);

	of_clk_del_provider(node);
	mtk_clk_unregister_cpumuxes(cpu_muxes, ARRAY_SIZE(cpu_muxes), clk_data);
	mtk_clk_unregister_gates(infra_gates, ARRAY_SIZE(infra_gates), clk_data);
	mtk_free_clk_data(clk_data);

	return 0;
}

static struct platform_driver clk_mt8173_infracfg_drv = {
	.driver = {
		.name = "clk-mt8173-infracfg",
		.of_match_table = of_match_clk_mt8173_infracfg,
	},
	.probe = clk_mt8173_infracfg_probe,
	.remove = clk_mt8173_infracfg_remove,
};
module_platform_driver(clk_mt8173_infracfg_drv);

MODULE_DESCRIPTION("MediaTek MT8173 infracfg clocks driver");
MODULE_LICENSE("GPL");
Loading