Lines Matching +full:mmp2 +full:- +full:clock
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * MMP Audio Clock Controller driver
8 #include <linux/clk-provider.h>
15 #include <dt-bindings/clock/marvell,mmp2-audio.h>
125 aud_pll_ctrl0 = readl(priv->mmio_base + SSPA_AUD_PLL_CTRL0); in audio_pll_recalc_rate()
133 aud_pll_ctrl1 = readl(priv->mmio_base + SSPA_AUD_PLL_CTRL1); in audio_pll_recalc_rate()
216 writel(val, priv->mmio_base + SSPA_AUD_PLL_CTRL0); in audio_pll_set_rate()
220 writel(val, priv->mmio_base + SSPA_AUD_PLL_CTRL1); in audio_pll_set_rate()
226 return -ERANGE; in audio_pll_set_rate()
238 { .hw = &priv->audio_pll_hw }, in register_clocks()
242 { .hw = &priv->audio_pll_hw }, in register_clocks()
247 priv->audio_pll_hw.init = CLK_HW_INIT_FW_NAME("audio_pll", in register_clocks()
250 ret = devm_clk_hw_register(dev, &priv->audio_pll_hw); in register_clocks()
254 priv->sspa_mux.hw.init = CLK_HW_INIT_PARENTS_DATA("sspa_mux", in register_clocks()
257 priv->sspa_mux.reg = priv->mmio_base + SSPA_AUD_CTRL; in register_clocks()
258 priv->sspa_mux.mask = 1; in register_clocks()
259 priv->sspa_mux.shift = SSPA_AUD_CTRL_SSPA0_MUX_SHIFT; in register_clocks()
260 ret = devm_clk_hw_register(dev, &priv->sspa_mux.hw); in register_clocks()
264 priv->sysclk_div.hw.init = CLK_HW_INIT_HW("sys_div", in register_clocks()
265 &priv->sspa_mux.hw, &clk_divider_ops, in register_clocks()
267 priv->sysclk_div.reg = priv->mmio_base + SSPA_AUD_CTRL; in register_clocks()
268 priv->sysclk_div.shift = SSPA_AUD_CTRL_SYSCLK_DIV_SHIFT; in register_clocks()
269 priv->sysclk_div.width = 6; in register_clocks()
270 priv->sysclk_div.flags = CLK_DIVIDER_ONE_BASED; in register_clocks()
271 priv->sysclk_div.flags |= CLK_DIVIDER_ROUND_CLOSEST; in register_clocks()
272 priv->sysclk_div.flags |= CLK_DIVIDER_ALLOW_ZERO; in register_clocks()
273 ret = devm_clk_hw_register(dev, &priv->sysclk_div.hw); in register_clocks()
277 priv->sysclk_gate.hw.init = CLK_HW_INIT_HW("sys_clk", in register_clocks()
278 &priv->sysclk_div.hw, &clk_gate_ops, in register_clocks()
280 priv->sysclk_gate.reg = priv->mmio_base + SSPA_AUD_CTRL; in register_clocks()
281 priv->sysclk_gate.bit_idx = SSPA_AUD_CTRL_SYSCLK_SHIFT; in register_clocks()
282 ret = devm_clk_hw_register(dev, &priv->sysclk_gate.hw); in register_clocks()
286 priv->sspa0_div.hw.init = CLK_HW_INIT_HW("sspa0_div", in register_clocks()
287 &priv->sspa_mux.hw, &clk_divider_ops, 0); in register_clocks()
288 priv->sspa0_div.reg = priv->mmio_base + SSPA_AUD_CTRL; in register_clocks()
289 priv->sspa0_div.shift = SSPA_AUD_CTRL_SSPA0_DIV_SHIFT; in register_clocks()
290 priv->sspa0_div.width = 6; in register_clocks()
291 priv->sspa0_div.flags = CLK_DIVIDER_ONE_BASED; in register_clocks()
292 priv->sspa0_div.flags |= CLK_DIVIDER_ROUND_CLOSEST; in register_clocks()
293 priv->sspa0_div.flags |= CLK_DIVIDER_ALLOW_ZERO; in register_clocks()
294 ret = devm_clk_hw_register(dev, &priv->sspa0_div.hw); in register_clocks()
298 priv->sspa0_gate.hw.init = CLK_HW_INIT_HW("sspa0_clk", in register_clocks()
299 &priv->sspa0_div.hw, &clk_gate_ops, in register_clocks()
301 priv->sspa0_gate.reg = priv->mmio_base + SSPA_AUD_CTRL; in register_clocks()
302 priv->sspa0_gate.bit_idx = SSPA_AUD_CTRL_SSPA0_SHIFT; in register_clocks()
303 ret = devm_clk_hw_register(dev, &priv->sspa0_gate.hw); in register_clocks()
307 priv->sspa1_mux.hw.init = CLK_HW_INIT_PARENTS_DATA("sspa1_mux", in register_clocks()
310 priv->sspa1_mux.reg = priv->mmio_base + SSPA_AUD_CTRL; in register_clocks()
311 priv->sspa1_mux.mask = 1; in register_clocks()
312 priv->sspa1_mux.shift = SSPA_AUD_CTRL_SSPA1_MUX_SHIFT; in register_clocks()
313 ret = devm_clk_hw_register(dev, &priv->sspa1_mux.hw); in register_clocks()
317 priv->sspa1_div.hw.init = CLK_HW_INIT_HW("sspa1_div", in register_clocks()
318 &priv->sspa1_mux.hw, &clk_divider_ops, 0); in register_clocks()
319 priv->sspa1_div.reg = priv->mmio_base + SSPA_AUD_CTRL; in register_clocks()
320 priv->sspa1_div.shift = SSPA_AUD_CTRL_SSPA1_DIV_SHIFT; in register_clocks()
321 priv->sspa1_div.width = 6; in register_clocks()
322 priv->sspa1_div.flags = CLK_DIVIDER_ONE_BASED; in register_clocks()
323 priv->sspa1_div.flags |= CLK_DIVIDER_ROUND_CLOSEST; in register_clocks()
324 priv->sspa1_div.flags |= CLK_DIVIDER_ALLOW_ZERO; in register_clocks()
325 ret = devm_clk_hw_register(dev, &priv->sspa1_div.hw); in register_clocks()
329 priv->sspa1_gate.hw.init = CLK_HW_INIT_HW("sspa1_clk", in register_clocks()
330 &priv->sspa1_div.hw, &clk_gate_ops, in register_clocks()
332 priv->sspa1_gate.reg = priv->mmio_base + SSPA_AUD_CTRL; in register_clocks()
333 priv->sspa1_gate.bit_idx = SSPA_AUD_CTRL_SSPA1_SHIFT; in register_clocks()
334 ret = devm_clk_hw_register(dev, &priv->sspa1_gate.hw); in register_clocks()
338 priv->clk_data.hws[MMP2_CLK_AUDIO_SYSCLK] = &priv->sysclk_gate.hw; in register_clocks()
339 priv->clk_data.hws[MMP2_CLK_AUDIO_SSPA0] = &priv->sspa0_gate.hw; in register_clocks()
340 priv->clk_data.hws[MMP2_CLK_AUDIO_SSPA1] = &priv->sspa1_gate.hw; in register_clocks()
341 priv->clk_data.num = CLK_AUDIO_NR_CLKS; in register_clocks()
343 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, in register_clocks()
344 &priv->clk_data); in register_clocks()
352 priv = devm_kzalloc(&pdev->dev, in mmp2_audio_clk_probe()
357 return -ENOMEM; in mmp2_audio_clk_probe()
359 spin_lock_init(&priv->lock); in mmp2_audio_clk_probe()
362 priv->mmio_base = devm_platform_ioremap_resource(pdev, 0); in mmp2_audio_clk_probe()
363 if (IS_ERR(priv->mmio_base)) in mmp2_audio_clk_probe()
364 return PTR_ERR(priv->mmio_base); in mmp2_audio_clk_probe()
366 pm_runtime_enable(&pdev->dev); in mmp2_audio_clk_probe()
367 ret = pm_clk_create(&pdev->dev); in mmp2_audio_clk_probe()
371 ret = pm_clk_add(&pdev->dev, "audio"); in mmp2_audio_clk_probe()
375 ret = register_clocks(priv, &pdev->dev); in mmp2_audio_clk_probe()
382 pm_clk_destroy(&pdev->dev); in mmp2_audio_clk_probe()
384 pm_runtime_disable(&pdev->dev); in mmp2_audio_clk_probe()
391 pm_clk_destroy(&pdev->dev); in mmp2_audio_clk_remove()
392 pm_runtime_disable(&pdev->dev); in mmp2_audio_clk_remove()
400 priv->aud_ctrl = readl(priv->mmio_base + SSPA_AUD_CTRL); in mmp2_audio_clk_suspend()
401 priv->aud_pll_ctrl0 = readl(priv->mmio_base + SSPA_AUD_PLL_CTRL0); in mmp2_audio_clk_suspend()
402 priv->aud_pll_ctrl1 = readl(priv->mmio_base + SSPA_AUD_PLL_CTRL1); in mmp2_audio_clk_suspend()
413 writel(priv->aud_ctrl, priv->mmio_base + SSPA_AUD_CTRL); in mmp2_audio_clk_resume()
414 writel(priv->aud_pll_ctrl0, priv->mmio_base + SSPA_AUD_PLL_CTRL0); in mmp2_audio_clk_resume()
415 writel(priv->aud_pll_ctrl1, priv->mmio_base + SSPA_AUD_PLL_CTRL1); in mmp2_audio_clk_resume()
426 { .compatible = "marvell,mmp2-audio-clock" },
434 .name = "mmp2-audio-clock",
444 MODULE_DESCRIPTION("Clock driver for MMP2 Audio subsystem");