clk: mediatek: clk-mux: Support custom parent indices for muxes
authorAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Fri, 3 Nov 2023 10:25:31 +0000 (11:25 +0100)
committerStephen Boyd <sboyd@kernel.org>
Wed, 3 Jan 2024 23:55:02 +0000 (15:55 -0800)
Add support for customized parent indices for MediaTek muxes: this is
necessary for the case in which we want to exclude some clocks from
a mux's parent clocks list, where the exclusions are not from the
very bottom of the list but either in the middle or the beginning.

Example:
- MUX1 (all parents)
  - parent1; idx=0
  - parent2; idx=1
  - parent3; idx=2

- MUX1 (wanted parents)
  - parent1; idx=0
  - parent3; idx=2

To achieve that add a `parent_index` array pointer to struct mtk_mux,
then in .set_parent(), .get_parent() callbacks check if this array
was populated and eventually get the index from that.

Also, to avoid updating all clock drivers for all SoCs, rename the
"main" macro to __GATE_CLR_SET_UPD_FLAGS (so, `__` was added) and
add the new member to it; furthermore, GATE_CLK_SET_UPD_FLAGS has
been reintroduced as being fully compatible with the older version.

The new parent_index can be specified with the new `_INDEXED`
variants of the MUX_GATE_CLR_SET_UPD_xxxx macros.

Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://lore.kernel.org/r/20231103102533.69280-2-angelogioacchino.delregno@collabora.com
Tested-by: Fei Shao <fshao@chromium.org>
Reviewed-by: Fei Shao <fshao@chromium.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
drivers/clk/mediatek/clk-mux.c
drivers/clk/mediatek/clk-mux.h

index c93bc7f..6099029 100644 (file)
@@ -89,6 +89,17 @@ static u8 mtk_clk_mux_get_parent(struct clk_hw *hw)
        regmap_read(mux->regmap, mux->data->mux_ofs, &val);
        val = (val >> mux->data->mux_shift) & mask;
 
+       if (mux->data->parent_index) {
+               int i;
+
+               for (i = 0; i < mux->data->num_parents; i++)
+                       if (mux->data->parent_index[i] == val)
+                               return i;
+
+               /* Not found: return an impossible index to generate error */
+               return mux->data->num_parents + 1;
+       }
+
        return val;
 }
 
@@ -104,6 +115,9 @@ static int mtk_clk_mux_set_parent_setclr_lock(struct clk_hw *hw, u8 index)
        else
                __acquire(mux->lock);
 
+       if (mux->data->parent_index)
+               index = mux->data->parent_index[index];
+
        regmap_read(mux->regmap, mux->data->mux_ofs, &orig);
        val = (orig & ~(mask << mux->data->mux_shift))
                        | (index << mux->data->mux_shift);
index 7ecb963..943ad1d 100644 (file)
@@ -21,6 +21,7 @@ struct mtk_mux {
        int id;
        const char *name;
        const char * const *parent_names;
+       const u8 *parent_index;
        unsigned int flags;
 
        u32 mux_ofs;
@@ -37,9 +38,10 @@ struct mtk_mux {
        signed char num_parents;
 };
 
-#define GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,         \
-                       _mux_set_ofs, _mux_clr_ofs, _shift, _width,     \
-                       _gate, _upd_ofs, _upd, _flags, _ops) {          \
+#define __GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _paridx,                \
+                        _num_parents, _mux_ofs, _mux_set_ofs,          \
+                        _mux_clr_ofs, _shift, _width, _gate, _upd_ofs, \
+                        _upd, _flags, _ops) {                          \
                .id = _id,                                              \
                .name = _name,                                          \
                .mux_ofs = _mux_ofs,                                    \
@@ -51,11 +53,28 @@ struct mtk_mux {
                .gate_shift = _gate,                                    \
                .upd_shift = _upd,                                      \
                .parent_names = _parents,                               \
-               .num_parents = ARRAY_SIZE(_parents),                    \
+               .parent_index = _paridx,                                \
+               .num_parents = _num_parents,                            \
                .flags = _flags,                                        \
                .ops = &_ops,                                           \
        }
 
+#define GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,         \
+                       _mux_set_ofs, _mux_clr_ofs, _shift, _width,     \
+                       _gate, _upd_ofs, _upd, _flags, _ops)            \
+               __GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents,          \
+                       NULL, ARRAY_SIZE(_parents), _mux_ofs,           \
+                       _mux_set_ofs, _mux_clr_ofs, _shift, _width,     \
+                       _gate, _upd_ofs, _upd, _flags, _ops)            \
+
+#define GATE_CLR_SET_UPD_FLAGS_INDEXED(_id, _name, _parents, _paridx,  \
+                        _mux_ofs, _mux_set_ofs, _mux_clr_ofs, _shift,  \
+                        _width, _gate, _upd_ofs, _upd, _flags, _ops)   \
+               __GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents,          \
+                       _paridx, ARRAY_SIZE(_paridx), _mux_ofs,         \
+                       _mux_set_ofs, _mux_clr_ofs, _shift, _width,     \
+                       _gate, _upd_ofs, _upd, _flags, _ops)            \
+
 extern const struct clk_ops mtk_mux_clr_set_upd_ops;
 extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops;
 
@@ -67,6 +86,14 @@ extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops;
                        _gate, _upd_ofs, _upd, _flags,                  \
                        mtk_mux_gate_clr_set_upd_ops)
 
+#define MUX_GATE_CLR_SET_UPD_FLAGS_INDEXED(_id, _name, _parents,       \
+                       _paridx, _mux_ofs, _mux_set_ofs, _mux_clr_ofs,  \
+                       _shift, _width, _gate, _upd_ofs, _upd, _flags)  \
+               GATE_CLR_SET_UPD_FLAGS_INDEXED(_id, _name, _parents,    \
+                       _paridx, _mux_ofs, _mux_set_ofs, _mux_clr_ofs,  \
+                       _shift, _width, _gate, _upd_ofs, _upd, _flags,  \
+                       mtk_mux_gate_clr_set_upd_ops)
+
 #define MUX_GATE_CLR_SET_UPD(_id, _name, _parents, _mux_ofs,           \
                        _mux_set_ofs, _mux_clr_ofs, _shift, _width,     \
                        _gate, _upd_ofs, _upd)                          \
@@ -75,6 +102,14 @@ extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops;
                        _width, _gate, _upd_ofs, _upd,                  \
                        CLK_SET_RATE_PARENT)
 
+#define MUX_GATE_CLR_SET_UPD_INDEXED(_id, _name, _parents, _paridx,    \
+                       _mux_ofs, _mux_set_ofs, _mux_clr_ofs, _shift,   \
+                       _width, _gate, _upd_ofs, _upd)                  \
+               MUX_GATE_CLR_SET_UPD_FLAGS_INDEXED(_id, _name,          \
+                       _parents, _paridx, _mux_ofs, _mux_set_ofs,      \
+                       _mux_clr_ofs, _shift, _width, _gate, _upd_ofs,  \
+                       _upd, CLK_SET_RATE_PARENT)
+
 #define MUX_CLR_SET_UPD(_id, _name, _parents, _mux_ofs,                        \
                        _mux_set_ofs, _mux_clr_ofs, _shift, _width,     \
                        _upd_ofs, _upd)                                 \