clk: rs9: Support device specific dif bit calculation
authorAlexander Stein <alexander.stein@ew.tq-group.com>
Fri, 10 Mar 2023 07:55:34 +0000 (08:55 +0100)
committerStephen Boyd <sboyd@kernel.org>
Mon, 27 Mar 2023 17:50:57 +0000 (10:50 -0700)
The calculation DIFx is BIT(n) +1 is only true for 9FGV0241. With
additional devices this is getting more complicated.
Support a base bit for the DIF calculation, currently only devices
with consecutive bits are supported, e.g. the 6-channel device needs
additional logic.

Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
Reviewed-by: Marek Vasut <marex@denx.de>
Link: https://lore.kernel.org/r/20230310075535.3476580-3-alexander.stein@ew.tq-group.com
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
drivers/clk/clk-renesas-pcie.c

index 3873c52..0036bd1 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/regmap.h>
 
 #define RS9_REG_OE                             0x0
-#define RS9_REG_OE_DIF_OE(n)                   BIT((n) + 1)
 #define RS9_REG_SS                             0x1
 #define RS9_REG_SS_AMP_0V6                     0x0
 #define RS9_REG_SS_AMP_0V7                     0x1
@@ -31,9 +30,6 @@
 #define RS9_REG_SS_SSC_MASK                    (3 << 3)
 #define RS9_REG_SS_SSC_LOCK                    BIT(5)
 #define RS9_REG_SR                             0x2
-#define RS9_REG_SR_2V0_DIF(n)                  0
-#define RS9_REG_SR_3V0_DIF(n)                  BIT((n) + 1)
-#define RS9_REG_SR_DIF_MASK(n)         BIT((n) + 1)
 #define RS9_REG_REF                            0x3
 #define RS9_REG_REF_OE                         BIT(4)
 #define RS9_REG_REF_OD                         BIT(5)
@@ -159,17 +155,27 @@ static const struct regmap_config rs9_regmap_config = {
        .reg_read = rs9_regmap_i2c_read,
 };
 
+static u8 rs9_calc_dif(const struct rs9_driver_data *rs9, int idx)
+{
+       enum rs9_model model = rs9->chip_info->model;
+
+       if (model == RENESAS_9FGV0241)
+               return BIT(idx) + 1;
+
+       return 0;
+}
+
 static int rs9_get_output_config(struct rs9_driver_data *rs9, int idx)
 {
        struct i2c_client *client = rs9->client;
+       u8 dif = rs9_calc_dif(rs9, idx);
        unsigned char name[5] = "DIF0";
        struct device_node *np;
        int ret;
        u32 sr;
 
        /* Set defaults */
-       rs9->clk_dif_sr &= ~RS9_REG_SR_DIF_MASK(idx);
-       rs9->clk_dif_sr |= RS9_REG_SR_3V0_DIF(idx);
+       rs9->clk_dif_sr |= dif;
 
        snprintf(name, 5, "DIF%d", idx);
        np = of_get_child_by_name(client->dev.of_node, name);
@@ -181,11 +187,9 @@ static int rs9_get_output_config(struct rs9_driver_data *rs9, int idx)
        of_node_put(np);
        if (!ret) {
                if (sr == 2000000) {            /* 2V/ns */
-                       rs9->clk_dif_sr &= ~RS9_REG_SR_DIF_MASK(idx);
-                       rs9->clk_dif_sr |= RS9_REG_SR_2V0_DIF(idx);
+                       rs9->clk_dif_sr &= ~dif;
                } else if (sr == 3000000) {     /* 3V/ns (default) */
-                       rs9->clk_dif_sr &= ~RS9_REG_SR_DIF_MASK(idx);
-                       rs9->clk_dif_sr |= RS9_REG_SR_3V0_DIF(idx);
+                       rs9->clk_dif_sr |= dif;
                } else
                        ret = dev_err_probe(&client->dev, -EINVAL,
                                            "Invalid renesas,slew-rate value\n");
@@ -256,11 +260,13 @@ static void rs9_update_config(struct rs9_driver_data *rs9)
        }
 
        for (i = 0; i < rs9->chip_info->num_clks; i++) {
-               if (rs9->clk_dif_sr & RS9_REG_SR_3V0_DIF(i))
+               u8 dif = rs9_calc_dif(rs9, i);
+
+               if (rs9->clk_dif_sr & dif)
                        continue;
 
-               regmap_update_bits(rs9->regmap, RS9_REG_SR, RS9_REG_SR_3V0_DIF(i),
-                                  rs9->clk_dif_sr & RS9_REG_SR_3V0_DIF(i));
+               regmap_update_bits(rs9->regmap, RS9_REG_SR, dif,
+                                  rs9->clk_dif_sr & dif);
        }
 }