* [PATCH RFC/RFT 1/6] clk: core: add support for generic big endian accesses
2019-04-08 10:20 [PATCH RFC/RFT 0/6] clk: make register endianness a run-time property Jonas Gorski
@ 2019-04-08 10:20 ` Jonas Gorski
2019-04-08 20:12 ` Stephen Boyd
2019-04-08 10:20 ` [PATCH RFC/RFT 2/6] clk: gate: make endian-aware Jonas Gorski
` (4 subsequent siblings)
5 siblings, 1 reply; 8+ messages in thread
From: Jonas Gorski @ 2019-04-08 10:20 UTC (permalink / raw)
To: linux-clk, linuxppc-dev
Cc: Stephen Boyd, Michael Turquette, Paul Mackerras,
Anatolij Gustschin
Add a generic flag to mark a clock as big endian register based, and add
accessors following these.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
drivers/clk/clk.c | 1 +
include/linux/clk-provider.h | 27 +++++++++++++++++++++++++++
2 files changed, 28 insertions(+)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 96053a96fe2f..b706022bb83d 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -2859,6 +2859,7 @@ static const struct {
ENTRY(CLK_IS_CRITICAL),
ENTRY(CLK_OPS_PARENT_ENABLE),
ENTRY(CLK_DUTY_CYCLE_PARENT),
+ ENTRY(CLK_IS_BIG_ENDIAN),
#undef ENTRY
};
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index b7cf80a71293..2c7c17652d75 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -35,6 +35,7 @@
#define CLK_OPS_PARENT_ENABLE BIT(12)
/* duty cycle call may be forwarded to the parent clock */
#define CLK_DUTY_CYCLE_PARENT BIT(13)
+#define CLK_IS_BIG_ENDIAN BIT(14) /* clk registers are big endian */
struct clk;
struct clk_hw;
@@ -1024,6 +1025,32 @@ static inline void clk_writel(u32 val, u32 __iomem *reg)
#endif /* platform dependent I/O accessors */
+static inline u32 clk_readl_be(u32 __iomem *reg)
+{
+ return ioread32be(reg);
+}
+
+static inline void clk_writel_be(u32 val, u32 __iomem *reg)
+{
+ iowrite32be(val, reg);
+}
+
+static inline u32 clk_hw_readl(struct clk_hw *clk, u32 __iomem *reg)
+{
+ if (clk_hw_get_flags(clk) & CLK_IS_BIG_ENDIAN)
+ return clk_readl_be(reg);
+ else
+ return clk_readl(reg);
+}
+
+static inline void clk_hw_writel(struct clk_hw *clk, u32 val, u32 __iomem *reg)
+{
+ if (clk_hw_get_flags(clk) & CLK_IS_BIG_ENDIAN)
+ clk_writel_be(val, reg);
+ else
+ clk_writel(val, reg);
+}
+
void clk_gate_restore_context(struct clk_hw *hw);
#endif /* CONFIG_COMMON_CLK */
--
2.13.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH RFC/RFT 1/6] clk: core: add support for generic big endian accesses
2019-04-08 10:20 ` [PATCH RFC/RFT 1/6] clk: core: add support for generic big endian accesses Jonas Gorski
@ 2019-04-08 20:12 ` Stephen Boyd
0 siblings, 0 replies; 8+ messages in thread
From: Stephen Boyd @ 2019-04-08 20:12 UTC (permalink / raw)
To: Jonas Gorski, linux-clk, linuxppc-dev
Cc: Michael Turquette, Anatolij Gustschin, Paul Mackerras
Quoting Jonas Gorski (2019-04-08 03:20:34)
> Add a generic flag to mark a clock as big endian register based, and add
> accessors following these.
I like the idea of getting rid of clk_readl() and clk_writel(), but I'd
rather see that this flag is per-basic clk type instead of global to all
clks. Mostly because I don't see it as a clk property that's applicable
in general. So we would either have a flag for dividers and gates that
goes into the respective CLK_{GATE,DIVIDER}_* flag space, or some
wrapper functions like:
clk_gate_register_be()
clk_divider_register_be()
that passes this information through to the basic clk types somehow.
Then if there's no other user left of clk_readl() and clk_writel() I'd
just slam in a patch to all the files that use it to convert them to
readl() and writel(). After that, it would be great to drop the io.h
include from clk-provider.h and push that include out to any code that's
relying on it implicitly.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH RFC/RFT 2/6] clk: gate: make endian-aware
2019-04-08 10:20 [PATCH RFC/RFT 0/6] clk: make register endianness a run-time property Jonas Gorski
2019-04-08 10:20 ` [PATCH RFC/RFT 1/6] clk: core: add support for generic big endian accesses Jonas Gorski
@ 2019-04-08 10:20 ` Jonas Gorski
2019-04-08 10:20 ` [PATCH RFC/RFT 3/6] clk: divider: make endian aware Jonas Gorski
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Jonas Gorski @ 2019-04-08 10:20 UTC (permalink / raw)
To: linux-clk, linuxppc-dev
Cc: Stephen Boyd, Michael Turquette, Paul Mackerras,
Anatolij Gustschin
Switch clk-gate to the endianness aware accessors to allow big endian
gated clocks on a per device level.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
drivers/clk/clk-gate.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index f05823cd9b21..0e585ac133c7 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -55,7 +55,7 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable)
if (set)
reg |= BIT(gate->bit_idx);
} else {
- reg = clk_readl(gate->reg);
+ reg = clk_hw_readl(hw, gate->reg);
if (set)
reg |= BIT(gate->bit_idx);
@@ -63,7 +63,7 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable)
reg &= ~BIT(gate->bit_idx);
}
- clk_writel(reg, gate->reg);
+ clk_hw_writel(hw, reg, gate->reg);
if (gate->lock)
spin_unlock_irqrestore(gate->lock, flags);
@@ -88,7 +88,7 @@ int clk_gate_is_enabled(struct clk_hw *hw)
u32 reg;
struct clk_gate *gate = to_clk_gate(hw);
- reg = clk_readl(gate->reg);
+ reg = clk_hw_readl(hw, gate->reg);
/* if a set bit disables this clk, flip it before masking */
if (gate->flags & CLK_GATE_SET_TO_DISABLE)
--
2.13.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH RFC/RFT 3/6] clk: divider: make endian aware
2019-04-08 10:20 [PATCH RFC/RFT 0/6] clk: make register endianness a run-time property Jonas Gorski
2019-04-08 10:20 ` [PATCH RFC/RFT 1/6] clk: core: add support for generic big endian accesses Jonas Gorski
2019-04-08 10:20 ` [PATCH RFC/RFT 2/6] clk: gate: make endian-aware Jonas Gorski
@ 2019-04-08 10:20 ` Jonas Gorski
2019-04-08 10:20 ` [PATCH RFC/RFT 4/6] clk: mux: " Jonas Gorski
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Jonas Gorski @ 2019-04-08 10:20 UTC (permalink / raw)
To: linux-clk, linuxppc-dev
Cc: Stephen Boyd, Michael Turquette, Paul Mackerras,
Anatolij Gustschin
Switch clk-divider to the endianness aware accessors to allow big endian
divider clocks on a per device level.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
drivers/clk/clk-divider.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index e5a17265cfaf..63cb8617a007 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -135,7 +135,7 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
struct clk_divider *divider = to_clk_divider(hw);
unsigned int val;
- val = clk_readl(divider->reg) >> divider->shift;
+ val = clk_hw_readl(hw, divider->reg) >> divider->shift;
val &= clk_div_mask(divider->width);
return divider_recalc_rate(hw, parent_rate, val, divider->table,
@@ -370,7 +370,7 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
if (divider->flags & CLK_DIVIDER_READ_ONLY) {
u32 val;
- val = clk_readl(divider->reg) >> divider->shift;
+ val = clk_hw_readl(hw, divider->reg) >> divider->shift;
val &= clk_div_mask(divider->width);
return divider_ro_round_rate(hw, rate, prate, divider->table,
@@ -420,11 +420,11 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
val = clk_div_mask(divider->width) << (divider->shift + 16);
} else {
- val = clk_readl(divider->reg);
+ val = clk_hw_readl(hw, divider->reg);
val &= ~(clk_div_mask(divider->width) << divider->shift);
}
val |= (u32)value << divider->shift;
- clk_writel(val, divider->reg);
+ clk_hw_writel(hw, val, divider->reg);
if (divider->lock)
spin_unlock_irqrestore(divider->lock, flags);
--
2.13.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH RFC/RFT 4/6] clk: mux: make endian aware
2019-04-08 10:20 [PATCH RFC/RFT 0/6] clk: make register endianness a run-time property Jonas Gorski
` (2 preceding siblings ...)
2019-04-08 10:20 ` [PATCH RFC/RFT 3/6] clk: divider: make endian aware Jonas Gorski
@ 2019-04-08 10:20 ` Jonas Gorski
2019-04-08 10:20 ` [PATCH RFC/RFT 5/6] powerpc/512x: mark clocks as big endian Jonas Gorski
2019-04-08 10:20 ` [PATCH RFC/RFT 6/6] clk: core: remove powerpc special handling Jonas Gorski
5 siblings, 0 replies; 8+ messages in thread
From: Jonas Gorski @ 2019-04-08 10:20 UTC (permalink / raw)
To: linux-clk, linuxppc-dev
Cc: Stephen Boyd, Michael Turquette, Paul Mackerras,
Anatolij Gustschin
Switch clk-mux to the endianness aware accessors to allow big endian
mux clocks on a per device level.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
drivers/clk/clk-mux.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index 2ad2df2e8909..4a02db06eb29 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -73,7 +73,7 @@ static u8 clk_mux_get_parent(struct clk_hw *hw)
struct clk_mux *mux = to_clk_mux(hw);
u32 val;
- val = clk_readl(mux->reg) >> mux->shift;
+ val = clk_hw_readl(hw, mux->reg) >> mux->shift;
val &= mux->mask;
return clk_mux_val_to_index(hw, mux->table, mux->flags, val);
@@ -94,12 +94,12 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
if (mux->flags & CLK_MUX_HIWORD_MASK) {
reg = mux->mask << (mux->shift + 16);
} else {
- reg = clk_readl(mux->reg);
+ reg = clk_hw_readl(hw, mux->reg);
reg &= ~(mux->mask << mux->shift);
}
val = val << mux->shift;
reg |= val;
- clk_writel(reg, mux->reg);
+ clk_hw_writel(hw, reg, mux->reg);
if (mux->lock)
spin_unlock_irqrestore(mux->lock, flags);
--
2.13.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH RFC/RFT 5/6] powerpc/512x: mark clocks as big endian
2019-04-08 10:20 [PATCH RFC/RFT 0/6] clk: make register endianness a run-time property Jonas Gorski
` (3 preceding siblings ...)
2019-04-08 10:20 ` [PATCH RFC/RFT 4/6] clk: mux: " Jonas Gorski
@ 2019-04-08 10:20 ` Jonas Gorski
2019-04-08 10:20 ` [PATCH RFC/RFT 6/6] clk: core: remove powerpc special handling Jonas Gorski
5 siblings, 0 replies; 8+ messages in thread
From: Jonas Gorski @ 2019-04-08 10:20 UTC (permalink / raw)
To: linux-clk, linuxppc-dev
Cc: Stephen Boyd, Michael Turquette, Paul Mackerras,
Anatolij Gustschin
These clocks' registers are accessed as big endian, so mark them as
such.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
arch/powerpc/platforms/512x/clock-commonclk.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c
index b3097fe6441b..af86a65128f1 100644
--- a/arch/powerpc/platforms/512x/clock-commonclk.c
+++ b/arch/powerpc/platforms/512x/clock-commonclk.c
@@ -239,8 +239,9 @@ static inline struct clk *mpc512x_clk_divider(
const char *name, const char *parent_name, u8 clkflags,
u32 __iomem *reg, u8 pos, u8 len, int divflags)
{
- return clk_register_divider(NULL, name, parent_name, clkflags,
- reg, pos, len, divflags, &clklock);
+ return clk_register_divider(NULL, name, parent_name,
+ clkflags | CLK_IS_BIG_ENDIAN, reg, pos, len,
+ divflags, &clklock);
}
static inline struct clk *mpc512x_clk_divtable(
@@ -248,10 +249,12 @@ static inline struct clk *mpc512x_clk_divtable(
u32 __iomem *reg, u8 pos, u8 len,
const struct clk_div_table *divtab)
{
+ int clkflags;
u8 divflags;
+ clkflags = CLK_IS_BIG_ENDIAN;
divflags = 0;
- return clk_register_divider_table(NULL, name, parent_name, 0,
+ return clk_register_divider_table(NULL, name, parent_name, clkflags,
reg, pos, len, divflags,
divtab, &clklock);
}
@@ -262,7 +265,7 @@ static inline struct clk *mpc512x_clk_gated(
{
int clkflags;
- clkflags = CLK_SET_RATE_PARENT;
+ clkflags = CLK_SET_RATE_PARENT | CLK_IS_BIG_ENDIAN;
return clk_register_gate(NULL, name, parent_name, clkflags,
reg, pos, 0, &clklock);
}
@@ -274,7 +277,7 @@ static inline struct clk *mpc512x_clk_muxed(const char *name,
int clkflags;
u8 muxflags;
- clkflags = CLK_SET_RATE_PARENT;
+ clkflags = CLK_SET_RATE_PARENT | CLK_IS_BIG_ENDIAN;
muxflags = 0;
return clk_register_mux(NULL, name,
parent_names, parent_count, clkflags,
--
2.13.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH RFC/RFT 6/6] clk: core: remove powerpc special handling
2019-04-08 10:20 [PATCH RFC/RFT 0/6] clk: make register endianness a run-time property Jonas Gorski
` (4 preceding siblings ...)
2019-04-08 10:20 ` [PATCH RFC/RFT 5/6] powerpc/512x: mark clocks as big endian Jonas Gorski
@ 2019-04-08 10:20 ` Jonas Gorski
5 siblings, 0 replies; 8+ messages in thread
From: Jonas Gorski @ 2019-04-08 10:20 UTC (permalink / raw)
To: linux-clk, linuxppc-dev
Cc: Stephen Boyd, Michael Turquette, Paul Mackerras,
Anatolij Gustschin
Now that the powerpc clocks are properly marked as big endian, we can
remove the special handling for PowerPC.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
include/linux/clk-provider.h | 16 ----------------
1 file changed, 16 deletions(-)
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 2c7c17652d75..6755befb6cee 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -999,20 +999,6 @@ static inline int of_clk_detect_critical(struct device_node *np, int index,
* for improved portability across platforms
*/
-#if IS_ENABLED(CONFIG_PPC)
-
-static inline u32 clk_readl(u32 __iomem *reg)
-{
- return ioread32be(reg);
-}
-
-static inline void clk_writel(u32 val, u32 __iomem *reg)
-{
- iowrite32be(val, reg);
-}
-
-#else /* platform dependent I/O accessors */
-
static inline u32 clk_readl(u32 __iomem *reg)
{
return readl(reg);
@@ -1023,8 +1009,6 @@ static inline void clk_writel(u32 val, u32 __iomem *reg)
writel(val, reg);
}
-#endif /* platform dependent I/O accessors */
-
static inline u32 clk_readl_be(u32 __iomem *reg)
{
return ioread32be(reg);
--
2.13.2
^ permalink raw reply related [flat|nested] 8+ messages in thread