]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
soc: amlogic: clk-measure: Define MSR_CLK's register offset separately
authorChuan Liu <chuan.liu@amlogic.com>
Tue, 15 Apr 2025 02:45:24 +0000 (10:45 +0800)
committerNeil Armstrong <neil.armstrong@linaro.org>
Tue, 22 Apr 2025 12:15:18 +0000 (14:15 +0200)
Since the MSR_CLK register offset differs between chip variants, we
replace the macro-based definition with chip-specific assignments.

Change the max_register in regmap_config to be retrieved from DTS.

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Chuan Liu <chuan.liu@amlogic.com>
Link: https://lore.kernel.org/r/20250415-clk-measure-v3-1-9b8551dd33b4@amlogic.com
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
drivers/soc/amlogic/meson-clk-measure.c

index 39638d6a593c938c422da257efa662f54f708929..3594ef5b7ff037a9ea8cbf13590b8c9714ade557 100644 (file)
 
 static DEFINE_MUTEX(measure_lock);
 
-#define MSR_CLK_DUTY           0x0
-#define MSR_CLK_REG0           0x4
-#define MSR_CLK_REG1           0x8
-#define MSR_CLK_REG2           0xc
-
 #define MSR_DURATION           GENMASK(15, 0)
 #define MSR_ENABLE             BIT(16)
 #define MSR_CONT               BIT(17) /* continuous measurement */
@@ -39,9 +34,17 @@ struct meson_msr_id {
        const char *name;
 };
 
+struct msr_reg_offset {
+       unsigned int duty_val;
+       unsigned int freq_ctrl;
+       unsigned int duty_ctrl;
+       unsigned int freq_val;
+};
+
 struct meson_msr_data {
        struct meson_msr_id *msr_table;
        unsigned int msr_count;
+       const struct msr_reg_offset *reg;
 };
 
 struct meson_msr {
@@ -495,6 +498,7 @@ static int meson_measure_id(struct meson_msr_id *clk_msr_id,
                            unsigned int duration)
 {
        struct meson_msr *priv = clk_msr_id->priv;
+       const struct msr_reg_offset *reg = priv->data.reg;
        unsigned int val;
        int ret;
 
@@ -502,22 +506,22 @@ static int meson_measure_id(struct meson_msr_id *clk_msr_id,
        if (ret)
                return ret;
 
-       regmap_write(priv->regmap, MSR_CLK_REG0, 0);
+       regmap_write(priv->regmap, reg->freq_ctrl, 0);
 
        /* Set measurement duration */
-       regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_DURATION,
+       regmap_update_bits(priv->regmap, reg->freq_ctrl, MSR_DURATION,
                           FIELD_PREP(MSR_DURATION, duration - 1));
 
        /* Set ID */
-       regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_CLK_SRC,
+       regmap_update_bits(priv->regmap, reg->freq_ctrl, MSR_CLK_SRC,
                           FIELD_PREP(MSR_CLK_SRC, clk_msr_id->id));
 
        /* Enable & Start */
-       regmap_update_bits(priv->regmap, MSR_CLK_REG0,
+       regmap_update_bits(priv->regmap, reg->freq_ctrl,
                           MSR_RUN | MSR_ENABLE,
                           MSR_RUN | MSR_ENABLE);
 
-       ret = regmap_read_poll_timeout(priv->regmap, MSR_CLK_REG0,
+       ret = regmap_read_poll_timeout(priv->regmap, reg->freq_ctrl,
                                       val, !(val & MSR_BUSY), 10, 10000);
        if (ret) {
                mutex_unlock(&measure_lock);
@@ -525,10 +529,10 @@ static int meson_measure_id(struct meson_msr_id *clk_msr_id,
        }
 
        /* Disable */
-       regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_ENABLE, 0);
+       regmap_update_bits(priv->regmap, reg->freq_ctrl, MSR_ENABLE, 0);
 
        /* Get the value in multiple of gate time counts */
-       regmap_read(priv->regmap, MSR_CLK_REG2, &val);
+       regmap_read(priv->regmap, reg->freq_val, &val);
 
        mutex_unlock(&measure_lock);
 
@@ -599,11 +603,10 @@ static int clk_msr_summary_show(struct seq_file *s, void *data)
 }
 DEFINE_SHOW_ATTRIBUTE(clk_msr_summary);
 
-static const struct regmap_config meson_clk_msr_regmap_config = {
+static struct regmap_config meson_clk_msr_regmap_config = {
        .reg_bits = 32,
        .val_bits = 32,
        .reg_stride = 4,
-       .max_register = MSR_CLK_REG2,
 };
 
 static int meson_msr_probe(struct platform_device *pdev)
@@ -611,6 +614,7 @@ static int meson_msr_probe(struct platform_device *pdev)
        const struct meson_msr_data *match_data;
        struct meson_msr *priv;
        struct dentry *root, *clks;
+       struct resource *res;
        void __iomem *base;
        int i;
 
@@ -636,15 +640,24 @@ static int meson_msr_probe(struct platform_device *pdev)
               match_data->msr_count * sizeof(struct meson_msr_id));
        priv->data.msr_count = match_data->msr_count;
 
-       base = devm_platform_ioremap_resource(pdev, 0);
+       base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
        if (IS_ERR(base))
                return PTR_ERR(base);
 
+       meson_clk_msr_regmap_config.max_register = resource_size(res) - 4;
        priv->regmap = devm_regmap_init_mmio(&pdev->dev, base,
                                             &meson_clk_msr_regmap_config);
        if (IS_ERR(priv->regmap))
                return PTR_ERR(priv->regmap);
 
+       priv->data.reg = devm_kzalloc(&pdev->dev, sizeof(struct msr_reg_offset),
+                                     GFP_KERNEL);
+       if (!priv->data.reg)
+               return -ENOMEM;
+
+       memcpy((void *)priv->data.reg, match_data->reg,
+              sizeof(struct msr_reg_offset));
+
        root = debugfs_create_dir("meson-clk-msr", NULL);
        clks = debugfs_create_dir("clks", root);
 
@@ -664,29 +677,41 @@ static int meson_msr_probe(struct platform_device *pdev)
        return 0;
 }
 
+static const struct msr_reg_offset msr_reg_offset = {
+       .duty_val = 0x0,
+       .freq_ctrl = 0x4,
+       .duty_ctrl = 0x8,
+       .freq_val = 0xc,
+};
+
 static const struct meson_msr_data clk_msr_gx_data = {
        .msr_table = (void *)clk_msr_gx,
        .msr_count = ARRAY_SIZE(clk_msr_gx),
+       .reg = &msr_reg_offset,
 };
 
 static const struct meson_msr_data clk_msr_m8_data = {
        .msr_table = (void *)clk_msr_m8,
        .msr_count = ARRAY_SIZE(clk_msr_m8),
+       .reg = &msr_reg_offset,
 };
 
 static const struct meson_msr_data clk_msr_axg_data = {
        .msr_table = (void *)clk_msr_axg,
        .msr_count = ARRAY_SIZE(clk_msr_axg),
+       .reg = &msr_reg_offset,
 };
 
 static const struct meson_msr_data clk_msr_g12a_data = {
        .msr_table = (void *)clk_msr_g12a,
        .msr_count = ARRAY_SIZE(clk_msr_g12a),
+       .reg = &msr_reg_offset,
 };
 
 static const struct meson_msr_data clk_msr_sm1_data = {
        .msr_table = (void *)clk_msr_sm1,
        .msr_count = ARRAY_SIZE(clk_msr_sm1),
+       .reg = &msr_reg_offset,
 };
 
 static const struct of_device_id meson_msr_match_table[] = {