diff options
author | Jonas Gorski <jonas.gorski@gmail.com> | 2019-04-18 07:12:08 -0400 |
---|---|---|
committer | Stephen Boyd <sboyd@kernel.org> | 2019-04-23 13:57:48 -0400 |
commit | 3a727519651228d92793291516727d62c6887607 (patch) | |
tree | a42041be2089ae8724b54e771950069c67447e35 | |
parent | 9427b71a850581112538c0b92f444d19a7aae28b (diff) |
clk: mux: add explicit big endian support
Add a clock specific flag to switch register accesses to big endian, to
allow runtime configuration of big endian mux clocks.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
-rw-r--r-- | drivers/clk/clk-mux.c | 22 | ||||
-rw-r--r-- | include/linux/clk-provider.h | 4 |
2 files changed, 23 insertions, 3 deletions
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index 2ad2df2e8909..61ad331b7ff4 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c | |||
@@ -23,6 +23,22 @@ | |||
23 | * parent - parent is adjustable through clk_set_parent | 23 | * parent - parent is adjustable through clk_set_parent |
24 | */ | 24 | */ |
25 | 25 | ||
26 | static inline u32 clk_mux_readl(struct clk_mux *mux) | ||
27 | { | ||
28 | if (mux->flags & CLK_MUX_BIG_ENDIAN) | ||
29 | return ioread32be(mux->reg); | ||
30 | |||
31 | return clk_readl(mux->reg); | ||
32 | } | ||
33 | |||
34 | static inline void clk_mux_writel(struct clk_mux *mux, u32 val) | ||
35 | { | ||
36 | if (mux->flags & CLK_MUX_BIG_ENDIAN) | ||
37 | iowrite32be(val, mux->reg); | ||
38 | else | ||
39 | clk_writel(val, mux->reg); | ||
40 | } | ||
41 | |||
26 | int clk_mux_val_to_index(struct clk_hw *hw, u32 *table, unsigned int flags, | 42 | int clk_mux_val_to_index(struct clk_hw *hw, u32 *table, unsigned int flags, |
27 | unsigned int val) | 43 | unsigned int val) |
28 | { | 44 | { |
@@ -73,7 +89,7 @@ static u8 clk_mux_get_parent(struct clk_hw *hw) | |||
73 | struct clk_mux *mux = to_clk_mux(hw); | 89 | struct clk_mux *mux = to_clk_mux(hw); |
74 | u32 val; | 90 | u32 val; |
75 | 91 | ||
76 | val = clk_readl(mux->reg) >> mux->shift; | 92 | val = clk_mux_readl(mux) >> mux->shift; |
77 | val &= mux->mask; | 93 | val &= mux->mask; |
78 | 94 | ||
79 | return clk_mux_val_to_index(hw, mux->table, mux->flags, val); | 95 | return clk_mux_val_to_index(hw, mux->table, mux->flags, val); |
@@ -94,12 +110,12 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index) | |||
94 | if (mux->flags & CLK_MUX_HIWORD_MASK) { | 110 | if (mux->flags & CLK_MUX_HIWORD_MASK) { |
95 | reg = mux->mask << (mux->shift + 16); | 111 | reg = mux->mask << (mux->shift + 16); |
96 | } else { | 112 | } else { |
97 | reg = clk_readl(mux->reg); | 113 | reg = clk_mux_readl(mux); |
98 | reg &= ~(mux->mask << mux->shift); | 114 | reg &= ~(mux->mask << mux->shift); |
99 | } | 115 | } |
100 | val = val << mux->shift; | 116 | val = val << mux->shift; |
101 | reg |= val; | 117 | reg |= val; |
102 | clk_writel(reg, mux->reg); | 118 | clk_mux_writel(mux, reg); |
103 | 119 | ||
104 | if (mux->lock) | 120 | if (mux->lock) |
105 | spin_unlock_irqrestore(mux->lock, flags); | 121 | spin_unlock_irqrestore(mux->lock, flags); |
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 0bc6d6f80b1a..4ae2257b63c6 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h | |||
@@ -509,6 +509,9 @@ void clk_hw_unregister_divider(struct clk_hw *hw); | |||
509 | * indicate changing mux bits. | 509 | * indicate changing mux bits. |
510 | * CLK_MUX_ROUND_CLOSEST - Use the parent rate that is closest to the desired | 510 | * CLK_MUX_ROUND_CLOSEST - Use the parent rate that is closest to the desired |
511 | * frequency. | 511 | * frequency. |
512 | * CLK_MUX_BIG_ENDIAN - By default little endian register accesses are used for | ||
513 | * the mux register. Setting this flag makes the register accesses big | ||
514 | * endian. | ||
512 | */ | 515 | */ |
513 | struct clk_mux { | 516 | struct clk_mux { |
514 | struct clk_hw hw; | 517 | struct clk_hw hw; |
@@ -527,6 +530,7 @@ struct clk_mux { | |||
527 | #define CLK_MUX_HIWORD_MASK BIT(2) | 530 | #define CLK_MUX_HIWORD_MASK BIT(2) |
528 | #define CLK_MUX_READ_ONLY BIT(3) /* mux can't be changed */ | 531 | #define CLK_MUX_READ_ONLY BIT(3) /* mux can't be changed */ |
529 | #define CLK_MUX_ROUND_CLOSEST BIT(4) | 532 | #define CLK_MUX_ROUND_CLOSEST BIT(4) |
533 | #define CLK_MUX_BIG_ENDIAN BIT(5) | ||
530 | 534 | ||
531 | extern const struct clk_ops clk_mux_ops; | 535 | extern const struct clk_ops clk_mux_ops; |
532 | extern const struct clk_ops clk_mux_ro_ops; | 536 | extern const struct clk_ops clk_mux_ro_ops; |