1
0
Fork 0

MLK-24980 clk: imx8mp: Add audio pll debug monitor on imx8mp

this support is similar as i.MX8MM.

   for userspace monitor control of the K-divider dynamically,
    we provide two interfaces to userspace: delta_k & pll_parameter

    1): delta_k is used to adjust the K divider in PLL based on small
        steps;
    2): the pll_parameter interface is used for get PLL's current
        M-divider, P-divider, S-divider & K-divider setting in PLL register

    example for the usage of these two interfaces:
    A): Get the current PLL setting of dividers:
            root@imx8mmevk:~# cat /sys/kernel/debug/audio_pll_monitor/audio_pll1/pll_parameter
            Mdiv: 0x106; Pdiv: 0x2; Sdiv: 0x3; Kdiv: 0x24dd

    B): if want to adjust the K-divider by a delta_k '1', then
            echo 0x1 > /sys/kernel/debug/audio_pll_monitor/audio_pll1/delta_k;

            root@imx8mmevk:~# cat /sys/kernel/debug/audio_pll_monitor/audio_pll1/pll_parameter
            Mdiv: 0x106; Pdiv: 0x2; Sdiv: 0x3; Kdiv: 0x24de

    C): if want to adjust the K-divider by a delta_k '-1', then
            echo -1 > /sys/kernel/debug/audio_pll_monitor/audio_pll1/delta_k;

            root@imx8mmevk:~# cat /sys/kernel/debug/audio_pll_monitor/audio_pll1/pll_parameter
            Mdiv: 0x106; Pdiv: 0x2; Sdiv: 0x3; Kdiv: 0x24dc

Signed-off-by: Jacky Bai <ping.bai@nxp.com>
Tested-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Reviewed-by: Anson Huang <anson.huang@nxp.com>
zero-colors
Jacky Bai 2020-11-09 17:42:31 +08:00
parent e72f9c741d
commit 05d0b49db6
1 changed files with 81 additions and 0 deletions

View File

@ -5,6 +5,7 @@
#include <dt-bindings/clock/imx8mp-clock.h>
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
@ -894,3 +895,83 @@ module_platform_driver(imx8mp_clk_driver);
MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
MODULE_DESCRIPTION("NXP i.MX8MP clock driver");
MODULE_LICENSE("GPL v2");
#ifndef MODULE
/*
* Debugfs interface for audio PLL K divider change dynamically.
* Monitor control for the Audio PLL K-Divider
*/
#ifdef CONFIG_DEBUG_FS
#define KDIV_MASK GENMASK(15, 0)
#define MDIV_SHIFT 12
#define MDIV_MASK GENMASK(21, 12)
#define PDIV_SHIFT 4
#define PDIV_MASK GENMASK(9, 4)
#define SDIV_SHIFT 0
#define SDIV_MASK GENMASK(2, 0)
static int pll_delta_k_set(void *data, u64 val)
{
struct clk_hw *hw;
short int delta_k;
hw = __clk_get_hw(data);
delta_k = (short int) (val & KDIV_MASK);
clk_set_delta_k(hw, val);
pr_debug("the delta k is %d\n", delta_k);
return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE(delta_k_fops, NULL, pll_delta_k_set, "%lld\n");
static int pll_setting_show(struct seq_file *s, void *data)
{
struct clk *pll_clk;
struct clk_hw *hw;
u32 pll_div_ctrl0, pll_div_ctrl1;
u32 mdiv, pdiv, sdiv, kdiv;
pll_clk = s->private;
hw = __clk_get_hw(pll_clk);
clk_get_pll_setting(hw, &pll_div_ctrl0, &pll_div_ctrl1);
mdiv = (pll_div_ctrl0 & MDIV_MASK) >> MDIV_SHIFT;
pdiv = (pll_div_ctrl0 & PDIV_MASK) >> PDIV_SHIFT;
sdiv = (pll_div_ctrl0 & SDIV_MASK) >> SDIV_SHIFT;
kdiv = (pll_div_ctrl1 & KDIV_MASK);
seq_printf(s, "Mdiv: 0x%x; Pdiv: 0x%x; Sdiv: 0x%x; Kdiv: 0x%x\n",
mdiv, pdiv, sdiv, kdiv);
return 0;
}
DEFINE_SHOW_ATTRIBUTE(pll_setting);
static int __init pll_debug_init(void)
{
struct dentry *root, *audio_pll1, *audio_pll2;
if (of_machine_is_compatible("fsl,imx8mp")) {
/* create a root dir for audio pll monitor */
root = debugfs_create_dir("audio_pll_monitor", NULL);
audio_pll1 = debugfs_create_dir("audio_pll1", root);
audio_pll2 = debugfs_create_dir("audio_pll2", root);
debugfs_create_file_unsafe("delta_k", 0444, audio_pll1,
clks[IMX8MP_AUDIO_PLL1], &delta_k_fops);
debugfs_create_file("pll_parameter", 0x444, audio_pll1,
clks[IMX8MP_AUDIO_PLL1], &pll_setting_fops);
debugfs_create_file_unsafe("delta_k", 0444, audio_pll2,
clks[IMX8MP_AUDIO_PLL2], &delta_k_fops);
debugfs_create_file("pll_parameter", 0x444, audio_pll2,
clks[IMX8MP_AUDIO_PLL2], &pll_setting_fops);
}
return 0;
}
late_initcall(pll_debug_init);
#endif /* CONFIG_DEBUG_FS */
#endif /* MODULE */