linux-clk.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC/RFT 0/6] clk: make register endianness a run-time property
@ 2019-04-08 10:20 Jonas Gorski
  2019-04-08 10:20 ` [PATCH RFC/RFT 1/6] clk: core: add support for generic big endian accesses Jonas Gorski
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Jonas Gorski @ 2019-04-08 10:20 UTC (permalink / raw)
  To: linux-clk, linuxppc-dev
  Cc: Anatolij Gustschin, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Michael Turquette, Stephen Boyd

Currently the endianness for register accesses of basic clocks if fixed
based on the architecture (BE for PowerPC, LE for everyone else). This
is inconvenient for architectures that support both.

To avoid adding more rules to the #ifdef, this patchset adds a new
generic flag to tag the registers as BE and makes the basic clocks
follow it, then converts the only PowerPC user to use it.

That way we can drop the special casing for PowerPC, and allow other BE
platforms/drivers to make use of the basic clocks.

RFC because I am unsure if this should be common flag or a per-clock
flag.

Technically it's the wrong place for the former, but having a different
flag for each basic clock looks a bit messy IMHO. This could also lead
to easy mistakes by using the "wrong" basic clock's flag, then having no
or unexpected effects due to the next free flag bit different for each
basic clock. This might be avoidable by using a free bit common to all,
e.g. the highest bit of the flag fields.

I don't have any strong feelings one way or the other. I just used this
way because I needed to start somewhere ;-).

RFT because I don't have a PowerPC device to test, and especially not a
512x one. I did compile test it though!

I looked really hard, and this is the only place I could find where a 
PowerPC platform (indirectly) used the clk accessors.

None of the regular drivers in clk/ were selected in any of the powerpc
defconfigs, and this was the only platform code that registered basic
clocks.

Jonas Gorski (6):
  clk: core: add support for generic big endian accesses
  clk: gate: make endian-aware
  clk: divider: make endian aware
  clk: mux: make endian aware
  powerpc/512x: mark clocks as big endian
  clk: core: remove powerpc special handling

 arch/powerpc/platforms/512x/clock-commonclk.c | 13 ++++++-----
 drivers/clk/clk-divider.c                     |  8 +++----
 drivers/clk/clk-gate.c                        |  6 +++---
 drivers/clk/clk-mux.c                         |  6 +++---
 drivers/clk/clk.c                             |  1 +
 include/linux/clk-provider.h                  | 31 ++++++++++++++++++---------
 6 files changed, 40 insertions(+), 25 deletions(-)

-- 
2.13.2


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [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: Anatolij Gustschin, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Michael Turquette, Stephen Boyd

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

* [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: Anatolij Gustschin, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Michael Turquette, Stephen Boyd

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: Anatolij Gustschin, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Michael Turquette, Stephen Boyd

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: Anatolij Gustschin, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Michael Turquette, Stephen Boyd

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: Anatolij Gustschin, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Michael Turquette, Stephen Boyd

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: Anatolij Gustschin, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Michael Turquette, Stephen Boyd

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

* 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: Anatolij Gustschin, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Michael Turquette

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

end of thread, other threads:[~2019-04-08 20:12 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 20:12   ` Stephen Boyd
2019-04-08 10:20 ` [PATCH RFC/RFT 2/6] clk: gate: make endian-aware Jonas Gorski
2019-04-08 10:20 ` [PATCH RFC/RFT 3/6] clk: divider: make endian aware Jonas Gorski
2019-04-08 10:20 ` [PATCH RFC/RFT 4/6] clk: mux: " 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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).