aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/clk/mediatek/clk-mt8173.c483
1 files changed, 276 insertions, 207 deletions
diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index e3786fd64726..0163d27e8795 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -7,6 +7,8 @@
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
#include "clk-cpumux.h"
#include "clk-gate.h"
@@ -15,6 +17,9 @@
#include <dt-bindings/clock/mt8173-clk.h>
+#define REGOFF_REF2USB 0x8
+#define REGOFF_HDMI_REF 0x40
+
/*
* For some clocks, we don't care what their actual rates are. And these
* clocks may change their rate on different products or different scenarios.
@@ -24,7 +29,7 @@
static DEFINE_SPINLOCK(mt8173_clk_lock);
-static const struct mtk_fixed_clk fixed_clks[] __initconst = {
+static const struct mtk_fixed_clk fixed_clks[] = {
FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", DUMMY_RATE),
FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", DUMMY_RATE),
@@ -33,7 +38,7 @@ static const struct mtk_fixed_clk fixed_clks[] __initconst = {
FIXED_CLK(CLK_TOP_LVDS_CTS, "lvds_cts", "lvdspll", DUMMY_RATE),
};
-static const struct mtk_fixed_factor top_divs[] __initconst = {
+static const struct mtk_fixed_factor top_divs[] = {
FACTOR(CLK_TOP_ARMCA7PLL_754M, "armca7pll_754m", "armca7pll", 1, 2),
FACTOR(CLK_TOP_ARMCA7PLL_502M, "armca7pll_502m", "armca7pll", 1, 3),
@@ -129,7 +134,7 @@ static const struct mtk_fixed_factor top_divs[] __initconst = {
FACTOR(CLK_TOP_VENCPLL_D4, "vencpll_d4", "vencpll", 1, 4),
};
-static const char * const axi_parents[] __initconst = {
+static const char * const axi_parents[] = {
"clk26m",
"syspll1_d2",
"syspll_d5",
@@ -140,17 +145,17 @@ static const char * const axi_parents[] __initconst = {
"dmpll_d4"
};
-static const char * const mem_parents[] __initconst = {
+static const char * const mem_parents[] = {
"clk26m",
"dmpll_ck"
};
-static const char * const ddrphycfg_parents[] __initconst = {
+static const char * const ddrphycfg_parents[] = {
"clk26m",
"syspll1_d8"
};
-static const char * const mm_parents[] __initconst = {
+static const char * const mm_parents[] = {
"clk26m",
"vencpll_d2",
"main_h364m",
@@ -162,14 +167,14 @@ static const char * const mm_parents[] __initconst = {
"dmpll_d2"
};
-static const char * const pwm_parents[] __initconst = {
+static const char * const pwm_parents[] = {
"clk26m",
"univpll2_d4",
"univpll3_d2",
"univpll1_d4"
};
-static const char * const vdec_parents[] __initconst = {
+static const char * const vdec_parents[] = {
"clk26m",
"vcodecpll_ck",
"tvdpll_445p5m",
@@ -182,7 +187,7 @@ static const char * const vdec_parents[] __initconst = {
"dmpll_d4"
};
-static const char * const venc_parents[] __initconst = {
+static const char * const venc_parents[] = {
"clk26m",
"vcodecpll_ck",
"tvdpll_445p5m",
@@ -195,7 +200,7 @@ static const char * const venc_parents[] __initconst = {
"dmpll_d4"
};
-static const char * const mfg_parents[] __initconst = {
+static const char * const mfg_parents[] = {
"clk26m",
"mmpll_ck",
"dmpll_ck",
@@ -214,7 +219,7 @@ static const char * const mfg_parents[] __initconst = {
"univpll2_d2"
};
-static const char * const camtg_parents[] __initconst = {
+static const char * const camtg_parents[] = {
"clk26m",
"univpll_d26",
"univpll2_d2",
@@ -223,12 +228,12 @@ static const char * const camtg_parents[] __initconst = {
"univpll1_d4"
};
-static const char * const uart_parents[] __initconst = {
+static const char * const uart_parents[] = {
"clk26m",
"univpll2_d8"
};
-static const char * const spi_parents[] __initconst = {
+static const char * const spi_parents[] = {
"clk26m",
"syspll3_d2",
"syspll1_d4",
@@ -238,20 +243,20 @@ static const char * const spi_parents[] __initconst = {
"univpll1_d8"
};
-static const char * const usb20_parents[] __initconst = {
+static const char * const usb20_parents[] = {
"clk26m",
"univpll1_d8",
"univpll3_d4"
};
-static const char * const usb30_parents[] __initconst = {
+static const char * const usb30_parents[] = {
"clk26m",
"univpll3_d2",
"usb_syspll_125m",
"univpll2_d4"
};
-static const char * const msdc50_0_h_parents[] __initconst = {
+static const char * const msdc50_0_h_parents[] = {
"clk26m",
"syspll1_d2",
"syspll2_d2",
@@ -260,7 +265,7 @@ static const char * const msdc50_0_h_parents[] __initconst = {
"univpll1_d4"
};
-static const char * const msdc50_0_parents[] __initconst = {
+static const char * const msdc50_0_parents[] = {
"clk26m",
"msdcpll_ck",
"msdcpll_d2",
@@ -278,7 +283,7 @@ static const char * const msdc50_0_parents[] __initconst = {
"msdcpll2_d4"
};
-static const char * const msdc30_1_parents[] __initconst = {
+static const char * const msdc30_1_parents[] = {
"clk26m",
"univpll2_d2",
"msdcpll_d4",
@@ -289,7 +294,7 @@ static const char * const msdc30_1_parents[] __initconst = {
"vencpll_d4"
};
-static const char * const msdc30_2_parents[] __initconst = {
+static const char * const msdc30_2_parents[] = {
"clk26m",
"univpll2_d2",
"msdcpll_d4",
@@ -300,7 +305,7 @@ static const char * const msdc30_2_parents[] __initconst = {
"vencpll_d2"
};
-static const char * const msdc30_3_parents[] __initconst = {
+static const char * const msdc30_3_parents[] = {
"clk26m",
"msdcpll2_ck",
"msdcpll2_d2",
@@ -317,14 +322,14 @@ static const char * const msdc30_3_parents[] __initconst = {
"msdcpll_d4"
};
-static const char * const audio_parents[] __initconst = {
+static const char * const audio_parents[] = {
"clk26m",
"syspll3_d4",
"syspll4_d4",
"syspll1_d16"
};
-static const char * const aud_intbus_parents[] __initconst = {
+static const char * const aud_intbus_parents[] = {
"clk26m",
"syspll1_d4",
"syspll4_d2",
@@ -334,7 +339,7 @@ static const char * const aud_intbus_parents[] __initconst = {
"dmpll_d8"
};
-static const char * const pmicspi_parents[] __initconst = {
+static const char * const pmicspi_parents[] = {
"clk26m",
"syspll1_d8",
"syspll3_d4",
@@ -345,7 +350,7 @@ static const char * const pmicspi_parents[] __initconst = {
"dmpll_d16"
};
-static const char * const scp_parents[] __initconst = {
+static const char * const scp_parents[] = {
"clk26m",
"syspll1_d2",
"univpll_d5",
@@ -354,14 +359,14 @@ static const char * const scp_parents[] __initconst = {
"dmpll_d4"
};
-static const char * const atb_parents[] __initconst = {
+static const char * const atb_parents[] = {
"clk26m",
"syspll1_d2",
"univpll_d5",
"dmpll_d2"
};
-static const char * const venc_lt_parents[] __initconst = {
+static const char * const venc_lt_parents[] = {
"clk26m",
"univpll_d3",
"vcodecpll_ck",
@@ -376,7 +381,7 @@ static const char * const venc_lt_parents[] __initconst = {
"dmpll_ck"
};
-static const char * const dpi0_parents[] __initconst = {
+static const char * const dpi0_parents[] = {
"clk26m",
"tvdpll_d2",
"tvdpll_d4",
@@ -386,13 +391,13 @@ static const char * const dpi0_parents[] __initconst = {
"tvdpll_d16"
};
-static const char * const irda_parents[] __initconst = {
+static const char * const irda_parents[] = {
"clk26m",
"univpll2_d4",
"syspll2_d4"
};
-static const char * const cci400_parents[] __initconst = {
+static const char * const cci400_parents[] = {
"clk26m",
"vencpll_ck",
"armca7pll_754m",
@@ -403,41 +408,41 @@ static const char * const cci400_parents[] __initconst = {
"dmpll_ck"
};
-static const char * const aud_1_parents[] __initconst = {
+static const char * const aud_1_parents[] = {
"clk26m",
"apll1_ck",
"univpll2_d4",
"univpll2_d8"
};
-static const char * const aud_2_parents[] __initconst = {
+static const char * const aud_2_parents[] = {
"clk26m",
"apll2_ck",
"univpll2_d4",
"univpll2_d8"
};
-static const char * const mem_mfg_in_parents[] __initconst = {
+static const char * const mem_mfg_in_parents[] = {
"clk26m",
"mmpll_ck",
"dmpll_ck",
"clk26m"
};
-static const char * const axi_mfg_in_parents[] __initconst = {
+static const char * const axi_mfg_in_parents[] = {
"clk26m",
"axi_sel",
"dmpll_d2"
};
-static const char * const scam_parents[] __initconst = {
+static const char * const scam_parents[] = {
"clk26m",
"syspll3_d2",
"univpll2_d4",
"dmpll_d4"
};
-static const char * const spinfi_ifr_parents[] __initconst = {
+static const char * const spinfi_ifr_parents[] = {
"clk26m",
"univpll2_d8",
"univpll3_d4",
@@ -448,14 +453,14 @@ static const char * const spinfi_ifr_parents[] __initconst = {
"univpll1_d4"
};
-static const char * const hdmi_parents[] __initconst = {
+static const char * const hdmi_parents[] = {
"clk26m",
"hdmitx_dig_cts",
"hdmitxpll_d2",
"hdmitxpll_d3"
};
-static const char * const dpilvds_parents[] __initconst = {
+static const char * const dpilvds_parents[] = {
"clk26m",
"lvdspll",
"lvdspll_d2",
@@ -464,7 +469,7 @@ static const char * const dpilvds_parents[] __initconst = {
"fpc_ck"
};
-static const char * const msdc50_2_h_parents[] __initconst = {
+static const char * const msdc50_2_h_parents[] = {
"clk26m",
"syspll1_d2",
"syspll2_d2",
@@ -473,72 +478,72 @@ static const char * const msdc50_2_h_parents[] __initconst = {
"univpll1_d4"
};
-static const char * const hdcp_parents[] __initconst = {
+static const char * const hdcp_parents[] = {
"clk26m",
"syspll4_d2",
"syspll3_d4",
"univpll2_d4"
};
-static const char * const hdcp_24m_parents[] __initconst = {
+static const char * const hdcp_24m_parents[] = {
"clk26m",
"univpll_d26",
"univpll_d52",
"univpll2_d8"
};
-static const char * const rtc_parents[] __initconst = {
+static const char * const rtc_parents[] = {
"clkrtc_int",
"clkrtc_ext",
"clk26m",
"univpll3_d8"
};
-static const char * const i2s0_m_ck_parents[] __initconst = {
+static const char * const i2s0_m_ck_parents[] = {
"apll1_div1",
"apll2_div1"
};
-static const char * const i2s1_m_ck_parents[] __initconst = {
+static const char * const i2s1_m_ck_parents[] = {
"apll1_div2",
"apll2_div2"
};
-static const char * const i2s2_m_ck_parents[] __initconst = {
+static const char * const i2s2_m_ck_parents[] = {
"apll1_div3",
"apll2_div3"
};
-static const char * const i2s3_m_ck_parents[] __initconst = {
+static const char * const i2s3_m_ck_parents[] = {
"apll1_div4",
"apll2_div4"
};
-static const char * const i2s3_b_ck_parents[] __initconst = {
+static const char * const i2s3_b_ck_parents[] = {
"apll1_div5",
"apll2_div5"
};
-static const char * const ca53_parents[] __initconst = {
+static const char * const ca53_parents[] = {
"clk26m",
"armca7pll",
"mainpll",
"univpll"
};
-static const char * const ca72_parents[] __initconst = {
+static const char * const ca72_parents[] = {
"clk26m",
"armca15pll",
"mainpll",
"univpll"
};
-static const struct mtk_composite cpu_muxes[] __initconst = {
+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_composite top_muxes[] __initconst = {
+static const struct mtk_composite top_muxes[] = {
/* CLK_CFG_0 */
MUX(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, 0x0040, 0, 3),
MUX(CLK_TOP_MEM_SEL, "mem_sel", mem_parents, 0x0040, 8, 1),
@@ -614,7 +619,7 @@ static const struct mtk_composite top_muxes[] __initconst = {
MUX(CLK_TOP_I2S3_B_SEL, "i2s3_b_ck_sel", i2s3_b_ck_parents, 0x120, 8, 1),
};
-static const struct mtk_gate_regs infra_cg_regs __initconst = {
+static const struct mtk_gate_regs infra_cg_regs = {
.set_ofs = 0x0040,
.clr_ofs = 0x0044,
.sta_ofs = 0x0048,
@@ -629,7 +634,7 @@ static const struct mtk_gate_regs infra_cg_regs __initconst = {
.ops = &mtk_clk_gate_ops_setclr, \
}
-static const struct mtk_gate infra_clks[] __initconst = {
+static const struct mtk_gate infra_clks[] = {
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),
@@ -643,17 +648,17 @@ static const struct mtk_gate infra_clks[] __initconst = {
GATE_ICG(CLK_INFRA_PMICWRAP, "infra_pmicwrap", "axi_sel", 23),
};
-static const struct mtk_fixed_factor infra_divs[] __initconst = {
+static const struct mtk_fixed_factor infra_early_divs[] = {
FACTOR(CLK_INFRA_CLK_13M, "clk13m", "clk26m", 1, 2),
};
-static const struct mtk_gate_regs peri0_cg_regs __initconst = {
+static const struct mtk_gate_regs peri0_cg_regs = {
.set_ofs = 0x0008,
.clr_ofs = 0x0010,
.sta_ofs = 0x0018,
};
-static const struct mtk_gate_regs peri1_cg_regs __initconst = {
+static const struct mtk_gate_regs peri1_cg_regs = {
.set_ofs = 0x000c,
.clr_ofs = 0x0014,
.sta_ofs = 0x001c,
@@ -677,7 +682,7 @@ static const struct mtk_gate_regs peri1_cg_regs __initconst = {
.ops = &mtk_clk_gate_ops_setclr, \
}
-static const struct mtk_gate peri_gates[] __initconst = {
+static const struct mtk_gate peri_gates[] = {
/* PERI0 */
GATE_PERI0(CLK_PERI_NFI, "peri_nfi", "axi_sel", 0),
GATE_PERI0(CLK_PERI_THERM, "peri_therm", "axi_sel", 1),
@@ -717,19 +722,19 @@ static const struct mtk_gate peri_gates[] __initconst = {
GATE_PERI1(CLK_PERI_I2C6, "peri_i2c6", "axi_sel", 2),
};
-static const char * const uart_ck_sel_parents[] __initconst = {
+static const char * const uart_ck_sel_parents[] = {
"clk26m",
"uart_sel",
};
-static const struct mtk_composite peri_clks[] __initconst = {
+static const struct mtk_composite peri_clks[] = {
MUX(CLK_PERI_UART0_SEL, "uart0_ck_sel", uart_ck_sel_parents, 0x40c, 0, 1),
MUX(CLK_PERI_UART1_SEL, "uart1_ck_sel", uart_ck_sel_parents, 0x40c, 1, 1),
MUX(CLK_PERI_UART2_SEL, "uart2_ck_sel", uart_ck_sel_parents, 0x40c, 2, 1),
MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1),
};
-static const struct mtk_gate_regs cg_regs_4_8_0 __initconst = {
+static const struct mtk_gate_regs cg_regs_4_8_0 = {
.set_ofs = 0x0004,
.clr_ofs = 0x0008,
.sta_ofs = 0x0000,
@@ -744,7 +749,8 @@ static const struct mtk_gate_regs cg_regs_4_8_0 __initconst = {
.ops = &mtk_clk_gate_ops_setclr, \
}
-static const struct mtk_gate img_clks[] __initconst = {
+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),
@@ -754,13 +760,13 @@ static const struct mtk_gate img_clks[] __initconst = {
GATE_IMG(CLK_IMG_FD, "img_fd", "mm_sel", 11),
};
-static const struct mtk_gate_regs vdec0_cg_regs __initconst = {
+static const struct mtk_gate_regs vdec0_cg_regs = {
.set_ofs = 0x0000,
.clr_ofs = 0x0004,
.sta_ofs = 0x0000,
};
-static const struct mtk_gate_regs vdec1_cg_regs __initconst = {
+static const struct mtk_gate_regs vdec1_cg_regs = {
.set_ofs = 0x0008,
.clr_ofs = 0x000c,
.sta_ofs = 0x0008,
@@ -784,7 +790,8 @@ static const struct mtk_gate_regs vdec1_cg_regs __initconst = {
.ops = &mtk_clk_gate_ops_setclr_inv, \
}
-static const struct mtk_gate vdec_clks[] __initconst = {
+static const struct mtk_gate vdec_clks[] = {
+ GATE_DUMMY(CLK_DUMMY, "vdec_dummy"),
GATE_VDEC0(CLK_VDEC_CKEN, "vdec_cken", "vdec_sel", 0),
GATE_VDEC1(CLK_VDEC_LARB_CKEN, "vdec_larb_cken", "mm_sel", 0),
};
@@ -798,7 +805,8 @@ static const struct mtk_gate vdec_clks[] __initconst = {
.ops = &mtk_clk_gate_ops_setclr_inv, \
}
-static const struct mtk_gate venc_clks[] __initconst = {
+static const struct mtk_gate venc_clks[] = {
+ GATE_DUMMY(CLK_DUMMY, "venc_dummy"),
GATE_VENC(CLK_VENC_CKE0, "venc_cke0", "mm_sel", 0),
GATE_VENC(CLK_VENC_CKE1, "venc_cke1", "venc_sel", 4),
GATE_VENC(CLK_VENC_CKE2, "venc_cke2", "venc_sel", 8),
@@ -814,7 +822,8 @@ static const struct mtk_gate venc_clks[] __initconst = {
.ops = &mtk_clk_gate_ops_setclr_inv, \
}
-static const struct mtk_gate venclt_clks[] __initconst = {
+static const struct mtk_gate venclt_clks[] = {
+ GATE_DUMMY(CLK_DUMMY, "venclt_dummy"),
GATE_VENCLT(CLK_VENCLT_CKE0, "venclt_cke0", "mm_sel", 0),
GATE_VENCLT(CLK_VENCLT_CKE1, "venclt_cke1", "venclt_sel", 4),
};
@@ -837,10 +846,11 @@ static const struct mtk_clk_rst_desc clk_rst_desc[] = {
}
};
-static struct clk_hw_onecell_data *mt8173_top_clk_data __initdata;
-static struct clk_hw_onecell_data *mt8173_pll_clk_data __initdata;
+static struct clk_hw_onecell_data *mt8173_top_clk_data;
+static struct clk_hw_onecell_data *mt8173_pll_clk_data;
+static struct clk_hw_onecell_data *infra_clk_data;
-static void __init mtk_clk_enable_critical(void)
+static void mtk_clk_enable_critical(void)
{
if (!mt8173_top_clk_data || !mt8173_pll_clk_data)
return;
@@ -853,104 +863,152 @@ static void __init mtk_clk_enable_critical(void)
clk_prepare_enable(mt8173_top_clk_data->hws[CLK_TOP_RTC_SEL]->clk);
}
-static void __init mtk_topckgen_init(struct device_node *node)
+static int clk_mt8173_topck_probe(struct platform_device *pdev)
{
+ struct device_node *node = pdev->dev.of_node;
struct clk_hw_onecell_data *clk_data;
void __iomem *base;
int r;
- base = of_iomap(node, 0);
- if (!base) {
- pr_err("%s(): ioremap failed\n", __func__);
- return;
- }
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
mt8173_top_clk_data = clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
+ if (IS_ERR_OR_NULL(clk_data))
+ return -ENOMEM;
- mtk_clk_register_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks), clk_data);
- mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
- mtk_clk_register_composites(NULL, top_muxes,
- ARRAY_SIZE(top_muxes), base,
- &mt8173_clk_lock, clk_data);
+ r = mtk_clk_register_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks), clk_data);
+ if (r)
+ goto free_clk_data;
+
+ r = mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
+ if (r)
+ goto unregister_fixed_clks;
+
+ r = mtk_clk_register_composites(&pdev->dev, top_muxes,
+ ARRAY_SIZE(top_muxes), base,
+ &mt8173_clk_lock, clk_data);
+ if (r)
+ goto unregister_factors;
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
if (r)
- pr_err("%s(): could not register clock provider: %d\n",
- __func__, r);
+ goto unregister_composites;
mtk_clk_enable_critical();
+ return 0;
+
+unregister_composites:
+ mtk_clk_unregister_composites(top_muxes, ARRAY_SIZE(top_muxes), clk_data);
+unregister_factors:
+ mtk_clk_unregister_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
+unregister_fixed_clks:
+ mtk_clk_unregister_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks), clk_data);
+free_clk_data:
+ mtk_free_clk_data(clk_data);
+ return r;
}
-CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt8173-topckgen", mtk_topckgen_init);
-static void __init mtk_infrasys_init(struct device_node *node)
+static void clk_mt8173_infra_init_early(struct device_node *node)
{
- struct clk_hw_onecell_data *clk_data;
+ 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_infra_probe(struct platform_device *pdev)
+{
+ struct device_node *node = pdev->dev.of_node;
int r;
- clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
+ r = mtk_clk_register_gates(&pdev->dev, node, infra_clks,
+ ARRAY_SIZE(infra_clks), infra_clk_data);
+ if (r)
+ return r;
- mtk_clk_register_gates(NULL, node, infra_clks,
- ARRAY_SIZE(infra_clks), clk_data);
- mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
+ r = mtk_clk_register_cpumuxes(&pdev->dev, node, cpu_muxes,
+ ARRAY_SIZE(cpu_muxes), infra_clk_data);
+ if (r)
+ goto unregister_gates;
- mtk_clk_register_cpumuxes(NULL, node, cpu_muxes,
- ARRAY_SIZE(cpu_muxes), clk_data);
+ r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, infra_clk_data);
+ if (r)
+ goto unregister_cpumuxes;
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+ r = mtk_register_reset_controller(node, &clk_rst_desc[0]);
if (r)
- pr_err("%s(): could not register clock provider: %d\n",
- __func__, r);
+ goto unregister_clk_hw;
+
+ return 0;
- mtk_register_reset_controller(node, &clk_rst_desc[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_clks, ARRAY_SIZE(infra_clks), infra_clk_data);
+ return r;
}
-CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt8173-infracfg", mtk_infrasys_init);
-static void __init mtk_pericfg_init(struct device_node *node)
+static int clk_mt8173_peri_probe(struct platform_device *pdev)
{
+ struct device_node *node = pdev->dev.of_node;
struct clk_hw_onecell_data *clk_data;
int r;
void __iomem *base;
- base = of_iomap(node, 0);
- if (!base) {
- pr_err("%s(): ioremap failed\n", __func__);
- return;
- }
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
+ if (IS_ERR_OR_NULL(clk_data))
+ return -ENOMEM;
- mtk_clk_register_gates(NULL, node, peri_gates,
- ARRAY_SIZE(peri_gates), clk_data);
- mtk_clk_register_composites(NULL, peri_clks,
- ARRAY_SIZE(peri_clks), base,
- &mt8173_clk_lock, clk_data);
+ r = mtk_clk_register_gates(&pdev->dev, node, peri_gates,
+ ARRAY_SIZE(peri_gates), clk_data);
+ if (r)
+ goto free_clk_data;
+
+ r = mtk_clk_register_composites(&pdev->dev, peri_clks,
+ ARRAY_SIZE(peri_clks), base,
+ &mt8173_clk_lock, clk_data);
+ if (r)
+ goto unregister_gates;
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
if (r)
- pr_err("%s(): could not register clock provider: %d\n",
- __func__, r);
+ goto unregister_composites;
- mtk_register_reset_controller(node, &clk_rst_desc[1]);
+ r = mtk_register_reset_controller(node, &clk_rst_desc[1]);
+ if (r)
+ goto unregister_clk_hw;
+
+ return 0;
+
+unregister_clk_hw:
+ of_clk_del_provider(node);
+unregister_composites:
+ mtk_clk_unregister_composites(peri_clks, ARRAY_SIZE(peri_clks), clk_data);
+unregister_gates:
+ mtk_clk_unregister_gates(peri_gates, ARRAY_SIZE(peri_gates), clk_data);
+free_clk_data:
+ mtk_free_clk_data(clk_data);
+ return r;
}
-CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8173-pericfg", mtk_pericfg_init);
-
-struct mtk_clk_usb {
- int id;
- const char *name;
- const char *parent;
- u32 reg_ofs;
-};
-
-#define APMIXED_USB(_id, _name, _parent, _reg_ofs) { \
- .id = _id, \
- .name = _name, \
- .parent = _parent, \
- .reg_ofs = _reg_ofs, \
- }
-
-static const struct mtk_clk_usb apmixed_usb[] __initconst = {
- APMIXED_USB(CLK_APMIXED_REF2USB_TX, "ref2usb_tx", "clk26m", 0x8),
-};
#define MT8173_PLL_FMAX (3000UL * MHZ)
@@ -1009,119 +1067,130 @@ static const struct mtk_pll_data plls[] = {
PLL(CLK_APMIXED_MSDCPLL2, "msdcpll2", 0x2f0, 0x2fc, 0, 0, 21, 0x2f0, 4, 0x0, 0x2f4, 0),
};
-static void __init mtk_apmixedsys_init(struct device_node *node)
+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, i;
+ int r;
base = of_iomap(node, 0);
- if (!base) {
- pr_err("%s(): ioremap failed\n", __func__);
- return;
- }
+ if (!base)
+ return PTR_ERR(base);
mt8173_pll_clk_data = clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
- if (!clk_data) {
- iounmap(base);
- return;
- }
-
- mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+ if (IS_ERR_OR_NULL(clk_data))
+ return -ENOMEM;
- for (i = 0; i < ARRAY_SIZE(apmixed_usb); i++) {
- const struct mtk_clk_usb *cku = &apmixed_usb[i];
-
- hw = mtk_clk_register_ref2usb_tx(cku->name, cku->parent, base + cku->reg_ofs);
- if (IS_ERR(hw)) {
- pr_err("Failed to register clk %s: %ld\n", cku->name, PTR_ERR(hw));
- continue;
- }
+ r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+ if (r)
+ goto free_clk_data;
- clk_data->hws[cku->id] = hw;
+ 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 = clk_hw_register_divider(NULL, "hdmi_ref", "tvdpll_594m", 0,
- base + 0x40, 16, 3, CLK_DIVIDER_POWER_OF_TWO,
- NULL);
+ 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)
- pr_err("%s(): could not register clock provider: %d\n",
- __func__, r);
+ goto unregister_ref2usb;
mtk_clk_enable_critical();
+ 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;
}
-CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8173-apmixedsys",
- mtk_apmixedsys_init);
-
-static void __init mtk_imgsys_init(struct device_node *node)
-{
- struct clk_hw_onecell_data *clk_data;
- int r;
-
- clk_data = mtk_alloc_clk_data(CLK_IMG_NR_CLK);
- mtk_clk_register_gates(NULL, node, img_clks,
- ARRAY_SIZE(img_clks), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+static const struct mtk_clk_desc img_desc = {
+ .clks = img_clks,
+ .num_clks = ARRAY_SIZE(img_clks),
+};
- if (r)
- pr_err("%s(): could not register clock provider: %d\n",
- __func__, r);
-}
-CLK_OF_DECLARE(mtk_imgsys, "mediatek,mt8173-imgsys", mtk_imgsys_init);
+static const struct mtk_clk_desc vdec_desc = {
+ .clks = vdec_clks,
+ .num_clks = ARRAY_SIZE(vdec_clks),
+};
-static void __init mtk_vdecsys_init(struct device_node *node)
-{
- struct clk_hw_onecell_data *clk_data;
- int r;
+static const struct mtk_clk_desc venc_desc = {
+ .clks = venc_clks,
+ .num_clks = ARRAY_SIZE(venc_clks),
+};
- clk_data = mtk_alloc_clk_data(CLK_VDEC_NR_CLK);
+static const struct mtk_clk_desc venc_lt_desc = {
+ .clks = venclt_clks,
+ .num_clks = ARRAY_SIZE(venclt_clks),
+};
- mtk_clk_register_gates(NULL, node, vdec_clks,
- ARRAY_SIZE(vdec_clks), clk_data);
+static const struct of_device_id of_match_clk_mt8173_simple[] = {
+ { .compatible = "mediatek,mt8173-imgsys", .data = &img_desc },
+ { .compatible = "mediatek,mt8173-vdecsys", .data = &vdec_desc },
+ { .compatible = "mediatek,mt8173-vencsys", .data = &venc_desc },
+ { .compatible = "mediatek,mt8173-vencltsys", .data = &venc_lt_desc },
+ { /* sentinel */ }
+};
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r)
- pr_err("%s(): could not register clock provider: %d\n",
- __func__, r);
-}
-CLK_OF_DECLARE(mtk_vdecsys, "mediatek,mt8173-vdecsys", mtk_vdecsys_init);
+static struct platform_driver clk_mt8173_simple_drv = {
+ .driver = {
+ .name = "clk-mt8173-simple",
+ .of_match_table = of_match_clk_mt8173_simple,
+ },
+ .probe = mtk_clk_simple_probe,
+ .remove = mtk_clk_simple_remove,
+};
-static void __init mtk_vencsys_init(struct device_node *node)
+static int clk_mt8173_probe(struct platform_device *pdev)
{
- struct clk_hw_onecell_data *clk_data;
+ int (*clk_probe)(struct platform_device *pdev);
int r;
- clk_data = mtk_alloc_clk_data(CLK_VENC_NR_CLK);
+ clk_probe = of_device_get_match_data(&pdev->dev);
+ if (!clk_probe)
+ return -EINVAL;
- mtk_clk_register_gates(NULL, node, venc_clks,
- ARRAY_SIZE(venc_clks), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+ r = clk_probe(pdev);
if (r)
- pr_err("%s(): could not register clock provider: %d\n",
- __func__, r);
+ dev_err(&pdev->dev, "could not register clock provider: %s: %d\n", pdev->name, r);
+
+ return r;
}
-CLK_OF_DECLARE(mtk_vencsys, "mediatek,mt8173-vencsys", mtk_vencsys_init);
-static void __init mtk_vencltsys_init(struct device_node *node)
-{
- struct clk_hw_onecell_data *clk_data;
- int r;
+static const struct of_device_id of_match_clk_mt8173[] = {
+ { .compatible = "mediatek,mt8173-apmixedsys", .data = clk_mt8173_apmixed_probe },
+ { .compatible = "mediatek,mt8173-infracfg", .data = clk_mt8173_infra_probe },
+ { .compatible = "mediatek,mt8173-topckgen", .data = clk_mt8173_topck_probe },
+ { .compatible = "mediatek,mt8173-pericfg", .data = clk_mt8173_peri_probe },
+ { /* sentinel */ }
+};
- clk_data = mtk_alloc_clk_data(CLK_VENCLT_NR_CLK);
+static struct platform_driver clk_mt8173_drv = {
+ .probe = clk_mt8173_probe,
+ .driver = {
+ .name = "clk-mt8173",
+ .of_match_table = of_match_clk_mt8173,
+ },
+};
- mtk_clk_register_gates(NULL, node, venclt_clks,
- ARRAY_SIZE(venclt_clks), clk_data);
+static int __init clk_mt8173_init(void)
+{
+ int ret = platform_driver_register(&clk_mt8173_drv);
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r)
- pr_err("%s(): could not register clock provider: %d\n",
- __func__, r);
+ if (ret)
+ return ret;
+ return platform_driver_register(&clk_mt8173_simple_drv);
}
-CLK_OF_DECLARE(mtk_vencltsys, "mediatek,mt8173-vencltsys", mtk_vencltsys_init);
+arch_initcall(clk_mt8173_init);