Skip to content

Commit ae333e6

Browse files
committed
clk: mediatek: mt8183: Add clk mux notifier for MFG mux
When the MFG PLL clock, which is upstream of the MFG clock, is changed, the downstream clock and consumers need to be switched away from the PLL over to a stable clock to avoid glitches. This is done through the use of the newly added clk mux notifier. The notifier is set on the mux itself instead of the upstream PLL, but in practice this works, as the rate change notifitcations are propogated throughout the sub-tree hanging off the PLL. Just before rate changes, the MFG mux is temporarily and transparently switched to the 26 MHz main crystal. After the rate change, the mux is switched back. Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> [Angelo: Rebased to assign clk_ops in mtk_mux_nb] Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Link: https://lore.kernel.org/r/20220927101128.44758-5-angelogioacchino.delregno@collabora.com Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
1 parent b66add7 commit ae333e6

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

drivers/clk/mediatek/clk-mt8183.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,10 +1198,33 @@ static void clk_mt8183_top_init_early(struct device_node *node)
11981198
CLK_OF_DECLARE_DRIVER(mt8183_topckgen, "mediatek,mt8183-topckgen",
11991199
clk_mt8183_top_init_early);
12001200

1201+
/* Register mux notifier for MFG mux */
1202+
static int clk_mt8183_reg_mfg_mux_notifier(struct device *dev, struct clk *clk)
1203+
{
1204+
struct mtk_mux_nb *mfg_mux_nb;
1205+
int i;
1206+
1207+
mfg_mux_nb = devm_kzalloc(dev, sizeof(*mfg_mux_nb), GFP_KERNEL);
1208+
if (!mfg_mux_nb)
1209+
return -ENOMEM;
1210+
1211+
for (i = 0; i < ARRAY_SIZE(top_muxes); i++)
1212+
if (top_muxes[i].id == CLK_TOP_MUX_MFG)
1213+
break;
1214+
if (i == ARRAY_SIZE(top_muxes))
1215+
return -EINVAL;
1216+
1217+
mfg_mux_nb->ops = top_muxes[i].ops;
1218+
mfg_mux_nb->bypass_index = 0; /* Bypass to 26M crystal */
1219+
1220+
return devm_mtk_clk_mux_notifier_register(dev, clk, mfg_mux_nb);
1221+
}
1222+
12011223
static int clk_mt8183_top_probe(struct platform_device *pdev)
12021224
{
12031225
void __iomem *base;
12041226
struct device_node *node = pdev->dev.of_node;
1227+
int ret;
12051228

12061229
base = devm_platform_ioremap_resource(pdev, 0);
12071230
if (IS_ERR(base))
@@ -1227,6 +1250,11 @@ static int clk_mt8183_top_probe(struct platform_device *pdev)
12271250
mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
12281251
top_clk_data);
12291252

1253+
ret = clk_mt8183_reg_mfg_mux_notifier(&pdev->dev,
1254+
top_clk_data->hws[CLK_TOP_MUX_MFG]->clk);
1255+
if (ret)
1256+
return ret;
1257+
12301258
return of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
12311259
top_clk_data);
12321260
}

0 commit comments

Comments
 (0)