summaryrefslogtreecommitdiff
path: root/drivers/clk/mediatek/clk-mt8188-topckgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/mediatek/clk-mt8188-topckgen.c')
-rw-r--r--drivers/clk/mediatek/clk-mt8188-topckgen.c84
1 files changed, 48 insertions, 36 deletions
diff --git a/drivers/clk/mediatek/clk-mt8188-topckgen.c b/drivers/clk/mediatek/clk-mt8188-topckgen.c
index c56ec42cb15f..6b07abe9a8f5 100644
--- a/drivers/clk/mediatek/clk-mt8188-topckgen.c
+++ b/drivers/clk/mediatek/clk-mt8188-topckgen.c
@@ -5,7 +5,7 @@
*/
#include <dt-bindings/clock/mediatek,mt8188-clk.h>
-#include <linux/of_device.h>
+#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include "clk-gate.h"
@@ -342,11 +342,14 @@ static const char * const dsp7_parents[] = {
"univpll_d3"
};
+/*
+ * MFG can be also parented to "univpll_d6" and "univpll_d7":
+ * these have been removed from the parents list to let us
+ * achieve GPU DVFS without any special clock handlers.
+ */
static const char * const mfg_core_tmp_parents[] = {
"clk26m",
- "mainpll_d5_d2",
- "univpll_d6",
- "univpll_d7"
+ "mainpll_d5_d2"
};
static const char * const camtg_parents[] = {
@@ -475,29 +478,28 @@ static const char * const sspm_parents[] = {
"mainpll_d4_d2"
};
+/*
+ * Both DP/eDP can be parented to TVDPLL1 and TVDPLL2, but we force using
+ * TVDPLL1 on eDP and TVDPLL2 on DP to avoid changing the "other" PLL rate
+ * in dual output case, which would lead to corruption of functionality loss.
+ */
static const char * const dp_parents[] = {
"clk26m",
- "tvdpll1_d2",
"tvdpll2_d2",
- "tvdpll1_d4",
"tvdpll2_d4",
- "tvdpll1_d8",
"tvdpll2_d8",
- "tvdpll1_d16",
"tvdpll2_d16"
};
+static const u8 dp_parents_idx[] = { 0, 2, 4, 6, 8 };
static const char * const edp_parents[] = {
"clk26m",
"tvdpll1_d2",
- "tvdpll2_d2",
"tvdpll1_d4",
- "tvdpll2_d4",
"tvdpll1_d8",
- "tvdpll2_d8",
- "tvdpll1_d16",
- "tvdpll2_d16"
+ "tvdpll1_d16"
};
+static const u8 edp_parents_idx[] = { 0, 1, 3, 5, 7 };
static const char * const dpi_parents[] = {
"clk26m",
@@ -954,13 +956,17 @@ static const struct mtk_mux top_mtk_muxes[] = {
* spm_sel and scp_sel are main clocks in always-on co-processor.
*/
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_AXI, "top_axi", axi_parents,
- 0x020, 0x024, 0x028, 0, 4, 7, 0x04, 0, CLK_IS_CRITICAL),
+ 0x020, 0x024, 0x028, 0, 4, 7, 0x04, 0,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SPM, "top_spm", spm_parents,
- 0x020, 0x024, 0x028, 8, 4, 15, 0x04, 1, CLK_IS_CRITICAL),
+ 0x020, 0x024, 0x028, 8, 4, 15, 0x04, 1,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SCP, "top_scp", scp_parents,
- 0x020, 0x024, 0x028, 16, 4, 23, 0x04, 2, CLK_IS_CRITICAL),
+ 0x020, 0x024, 0x028, 16, 4, 23, 0x04, 2,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_BUS_AXIMEM, "top_bus_aximem", bus_aximem_parents,
- 0x020, 0x024, 0x028, 24, 4, 31, 0x04, 3, CLK_IS_CRITICAL),
+ 0x020, 0x024, 0x028, 24, 4, 31, 0x04, 3,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
/* CLK_CFG_1 */
MUX_GATE_CLR_SET_UPD(CLK_TOP_VPP, "top_vpp",
vpp_parents, 0x02C, 0x030, 0x034, 0, 4, 7, 0x04, 4),
@@ -1011,15 +1017,15 @@ static const struct mtk_mux top_mtk_muxes[] = {
uart_parents, 0x068, 0x06C, 0x070, 0, 4, 7, 0x04, 24),
MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI, "top_spi",
spi_parents, 0x068, 0x06C, 0x070, 8, 4, 15, 0x04, 25),
- MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0_HCLK, "top_msdc5hclk",
- msdc5hclk_parents, 0x068, 0x06C, 0x070, 16, 4, 23, 0x04, 26),
- MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0, "top_msdc50_0",
- msdc50_0_parents, 0x068, 0x06C, 0x070, 24, 4, 31, 0x04, 27),
+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_MSDC50_0_HCLK, "top_msdc5hclk",
+ msdc5hclk_parents, 0x068, 0x06C, 0x070, 16, 4, 23, 0x04, 26, 0),
+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_MSDC50_0, "top_msdc50_0",
+ msdc50_0_parents, 0x068, 0x06C, 0x070, 24, 4, 31, 0x04, 27, 0),
/* CLK_CFG_7 */
- MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_1, "top_msdc30_1",
- msdc30_1_parents, 0x074, 0x078, 0x07C, 0, 4, 7, 0x04, 28),
- MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_2, "top_msdc30_2",
- msdc30_2_parents, 0x074, 0x078, 0x07C, 8, 4, 15, 0x04, 29),
+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_MSDC30_1, "top_msdc30_1",
+ msdc30_1_parents, 0x074, 0x078, 0x07C, 0, 4, 7, 0x04, 28, 0),
+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_MSDC30_2, "top_msdc30_2",
+ msdc30_2_parents, 0x074, 0x078, 0x07C, 8, 4, 15, 0x04, 29, 0),
MUX_GATE_CLR_SET_UPD(CLK_TOP_INTDIR, "top_intdir",
intdir_parents, 0x074, 0x078, 0x07C, 16, 4, 23, 0x04, 30),
MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_INTBUS, "top_aud_intbus",
@@ -1034,10 +1040,12 @@ static const struct mtk_mux top_mtk_muxes[] = {
MUX_GATE_CLR_SET_UPD(CLK_TOP_SSPM, "top_sspm",
sspm_parents, 0x080, 0x084, 0x088, 24, 4, 31, 0x08, 3),
/* CLK_CFG_9 */
- MUX_GATE_CLR_SET_UPD(CLK_TOP_DP, "top_dp",
- dp_parents, 0x08C, 0x090, 0x094, 0, 4, 7, 0x08, 4),
- MUX_GATE_CLR_SET_UPD(CLK_TOP_EDP, "top_edp",
- edp_parents, 0x08C, 0x090, 0x094, 8, 4, 15, 0x08, 5),
+ MUX_GATE_CLR_SET_UPD_INDEXED(CLK_TOP_DP, "top_dp",
+ dp_parents, dp_parents_idx, 0x08C, 0x090, 0x094,
+ 0, 4, 7, 0x08, 4),
+ MUX_GATE_CLR_SET_UPD_INDEXED(CLK_TOP_EDP, "top_edp",
+ edp_parents, edp_parents_idx, 0x08C, 0x090, 0x094,
+ 8, 4, 15, 0x08, 5),
MUX_GATE_CLR_SET_UPD(CLK_TOP_DPI, "top_dpi",
dpi_parents, 0x08C, 0x090, 0x094, 16, 4, 23, 0x08, 6),
MUX_GATE_CLR_SET_UPD(CLK_TOP_DISP_PWM0, "top_disp_pwm0",
@@ -1078,7 +1086,8 @@ static const struct mtk_mux top_mtk_muxes[] = {
MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM, "top_pwm",
pwm_parents, 0x0BC, 0x0C0, 0x0C4, 8, 4, 15, 0x08, 21),
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_MCUPM, "top_mcupm", mcupm_parents,
- 0x0BC, 0x0C0, 0x0C4, 16, 4, 23, 0x08, 22, CLK_IS_CRITICAL),
+ 0x0BC, 0x0C0, 0x0C4, 16, 4, 23, 0x08, 22,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
MUX_GATE_CLR_SET_UPD(CLK_TOP_SPMI_P_MST, "top_spmi_p_mst",
spmi_p_mst_parents, 0x0BC, 0x0C0, 0x0C4, 24, 4, 31, 0x08, 23),
/*
@@ -1088,7 +1097,8 @@ static const struct mtk_mux top_mtk_muxes[] = {
MUX_GATE_CLR_SET_UPD(CLK_TOP_SPMI_M_MST, "top_spmi_m_mst",
spmi_m_mst_parents, 0x0C8, 0x0CC, 0x0D0, 0, 4, 7, 0x08, 24),
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DVFSRC, "top_dvfsrc", dvfsrc_parents,
- 0x0C8, 0x0CC, 0x0D0, 8, 4, 15, 0x08, 25, CLK_IS_CRITICAL),
+ 0x0C8, 0x0CC, 0x0D0, 8, 4, 15, 0x08, 25,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
MUX_GATE_CLR_SET_UPD(CLK_TOP_TL, "top_tl",
tl_parents, 0x0C8, 0x0CC, 0x0D0, 16, 4, 23, 0x08, 26),
MUX_GATE_CLR_SET_UPD(CLK_TOP_AES_MSDCFDE, "top_aes_msdcfde",
@@ -1164,9 +1174,11 @@ static const struct mtk_mux top_mtk_muxes[] = {
MUX_GATE_CLR_SET_UPD(CLK_TOP_SPINOR, "top_spinor",
spinor_parents, 0x0128, 0x012C, 0x0130, 0, 4, 7, 0x0C, 24),
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_ULPOSC, "top_ulposc", ulposc_parents,
- 0x0128, 0x012C, 0x0130, 8, 4, 15, 0x0C, 25, CLK_IS_CRITICAL),
+ 0x0128, 0x012C, 0x0130, 8, 4, 15, 0x0C, 25,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SRCK, "top_srck", srck_parents,
- 0x0128, 0x012C, 0x0130, 16, 4, 23, 0x0C, 26, CLK_IS_CRITICAL),
+ 0x0128, 0x012C, 0x0130, 16, 4, 23, 0x0C, 26,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
};
static const struct mtk_composite top_adj_divs[] = {
@@ -1322,7 +1334,7 @@ free_top_data:
return r;
}
-static int clk_mt8188_topck_remove(struct platform_device *pdev)
+static void clk_mt8188_topck_remove(struct platform_device *pdev)
{
struct clk_hw_onecell_data *top_clk_data = platform_get_drvdata(pdev);
struct device_node *node = pdev->dev.of_node;
@@ -1334,8 +1346,6 @@ static int clk_mt8188_topck_remove(struct platform_device *pdev)
mtk_clk_unregister_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
mtk_clk_unregister_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), top_clk_data);
mtk_free_clk_data(top_clk_data);
-
- return 0;
}
static struct platform_driver clk_mt8188_topck_drv = {
@@ -1347,4 +1357,6 @@ static struct platform_driver clk_mt8188_topck_drv = {
},
};
module_platform_driver(clk_mt8188_topck_drv);
+
+MODULE_DESCRIPTION("MediaTek MT8188 top clock generators driver");
MODULE_LICENSE("GPL");