2023-12-08 17:13:18

by Conor Dooley

[permalink] [raw]
Subject: [PATCH RESEND v1 0/7] MPFS clock fixes required for correct CAN clock modeling

From: Conor Dooley <[email protected]>

Resending cos I accidentally only sent the cover letter a few minutes
prior to this series, due to screwing up a dry run of sending.
:clown_face:

While reviewing a CAN clock driver internally for MPFS [1], I realised
that the modeling of the MSSPLL such that one one of its outputs could
be used was not correct. The CAN controllers on MPFS take 2 input
clocks - one that is the bus clock, acquired from the main MSSPLL and
a second clock for the AHB interface to the result of the SoC.
Currently the binding for the CAN controllers and the represetnation
of the MSSPLL only allows for one of these clocks.
Modify the binding and devicetree to expect two clocks and rework the
main clock controller driver for MPFS such that it is capable of
providing multiple outputs from the MSSPLL.

Cheers,
Conor.

1 - Hopefully that'll show up on the lists soon, once we are happy with
it ourselves.

CC: Conor Dooley <[email protected]>
CC: Daire McNamara <[email protected]>
CC: Wolfgang Grandegger <[email protected]>
CC: Marc Kleine-Budde <[email protected]>
CC: "David S. Miller" <[email protected]>
CC: Eric Dumazet <[email protected]>
CC: Jakub Kicinski <[email protected]>
CC: Paolo Abeni <[email protected]>
CC: Rob Herring <[email protected]>
CC: Krzysztof Kozlowski <[email protected]>
CC: Paul Walmsley <[email protected]>
CC: Palmer Dabbelt <[email protected]>
CC: Albert Ou <[email protected]>
CC: Michael Turquette <[email protected]>
CC: Stephen Boyd <[email protected]>
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]

Conor Dooley (7):
dt-bindings: clock: mpfs: add more MSSPLL output definitions
dt-bindings: can: mpfs: add missing required clock
clk: microchip: mpfs: split MSSPLL in two
clk: microchip: mpfs: setup for using other mss pll outputs
clk: microchip: mpfs: add missing MSSPLL outputs
clk: microchip: mpfs: convert MSSPLL outputs to clk_divider
riscv: dts: microchip: add missing CAN bus clocks

.../bindings/net/can/microchip,mpfs-can.yaml | 7 +-
arch/riscv/boot/dts/microchip/mpfs.dtsi | 4 +-
drivers/clk/microchip/clk-mpfs.c | 154 ++++++++++--------
.../dt-bindings/clock/microchip,mpfs-clock.h | 5 +
4 files changed, 99 insertions(+), 71 deletions(-)

--
2.39.2


2023-12-08 17:13:22

by Conor Dooley

[permalink] [raw]
Subject: [PATCH RESEND v1 2/7] dt-bindings: can: mpfs: add missing required clock

From: Conor Dooley <[email protected]>

The CAN controller on PolarFire SoC has an AHB peripheral clock _and_ a
CAN bus clock. The bus clock was omitted when the binding was written,
but is required for operation. Make up for lost time and add it.

Cautionary tale in adding bindings without having implemented a real
user for them perhaps.

Fixes: c878d518d7b6 ("dt-bindings: can: mpfs: document the mpfs CAN controller")
Signed-off-by: Conor Dooley <[email protected]>
---
.../devicetree/bindings/net/can/microchip,mpfs-can.yaml | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml b/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml
index 45aa3de7cf01..05f680f15b17 100644
--- a/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml
+++ b/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml
@@ -24,7 +24,10 @@ properties:
maxItems: 1

clocks:
- maxItems: 1
+ maxItems: 2
+ items:
+ - description: AHB peripheral clock
+ - description: CAN bus clock

required:
- compatible
@@ -39,7 +42,7 @@ examples:
can@2010c000 {
compatible = "microchip,mpfs-can";
reg = <0x2010c000 0x1000>;
- clocks = <&clkcfg 17>;
+ clocks = <&clkcfg 17>, <&clkcfg 37>;
interrupt-parent = <&plic>;
interrupts = <56>;
};
--
2.39.2

2023-12-08 17:13:31

by Conor Dooley

[permalink] [raw]
Subject: [PATCH RESEND v1 5/7] clk: microchip: mpfs: add missing MSSPLL outputs

From: Conor Dooley <[email protected]>

The MSSPLL has 4 outputs, of which only the cpu/axi/ahb clock parent is
currently implemented.
Add the CAN clock too, as that'll be needed by the driver for the CAN
controller and uses output 3.
While we are here, the other two missing clocks, used by the eMMC/SD
controller and by the "user crypto".

Signed-off-by: Conor Dooley <[email protected]>
---
drivers/clk/microchip/clk-mpfs.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
index 9edd0333e693..f62269320b2a 100644
--- a/drivers/clk/microchip/clk-mpfs.c
+++ b/drivers/clk/microchip/clk-mpfs.c
@@ -28,6 +28,7 @@
#define MSSPLL_REFDIV_SHIFT 0x08u
#define MSSPLL_REFDIV_WIDTH 0x06u
#define MSSPLL_POSTDIV02_SHIFT 0x08u
+#define MSSPLL_POSTDIV13_SHIFT 0x18u
#define MSSPLL_POSTDIV_WIDTH 0x07u
#define MSSPLL_FIXED_DIV 4u

@@ -240,6 +241,12 @@ static const struct clk_ops mpfs_clk_msspll_out_ops = {
static struct mpfs_msspll_out_hw_clock mpfs_msspll_out_clks[] = {
CLK_PLL_OUT(CLK_MSSPLL, "clk_msspll", "clk_msspll_internal", 0,
MSSPLL_POSTDIV02_SHIFT, MSSPLL_POSTDIV_WIDTH, REG_MSSPLL_POSTDIV01_CR),
+ CLK_PLL_OUT(CLK_MSSPLL1, "clk_msspll1", "clk_msspll_internal", 0,
+ MSSPLL_POSTDIV13_SHIFT, MSSPLL_POSTDIV_WIDTH, REG_MSSPLL_POSTDIV01_CR),
+ CLK_PLL_OUT(CLK_MSSPLL2, "clk_msspll2", "clk_msspll_internal", 0,
+ MSSPLL_POSTDIV02_SHIFT, MSSPLL_POSTDIV_WIDTH, REG_MSSPLL_POSTDIV23_CR),
+ CLK_PLL_OUT(CLK_MSSPLL3, "clk_msspll3", "clk_msspll_internal", 0,
+ MSSPLL_POSTDIV13_SHIFT, MSSPLL_POSTDIV_WIDTH, REG_MSSPLL_POSTDIV23_CR),
};

static int mpfs_clk_register_msspll_outs(struct device *dev,
--
2.39.2

2023-12-08 17:13:45

by Conor Dooley

[permalink] [raw]
Subject: [PATCH RESEND v1 6/7] clk: microchip: mpfs: convert MSSPLL outputs to clk_divider

From: Conor Dooley <[email protected]>

After splitting the MSSPLL in two, the PLL outputs have become
open-coded versions of clk_divider. Drop the custom clk ops structs, and
instead use the generic clk_divider_ops.

Signed-off-by: Conor Dooley <[email protected]>
---
drivers/clk/microchip/clk-mpfs.c | 81 ++++++--------------------------
1 file changed, 14 insertions(+), 67 deletions(-)

diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
index f62269320b2a..ef4511186a23 100644
--- a/drivers/clk/microchip/clk-mpfs.c
+++ b/drivers/clk/microchip/clk-mpfs.c
@@ -61,13 +61,10 @@ struct mpfs_msspll_hw_clock {

struct mpfs_msspll_out_hw_clock {
void __iomem *base;
- struct clk_hw hw;
+ struct clk_divider output;
struct clk_init_data init;
unsigned int id;
u32 reg_offset;
- u32 shift;
- u32 width;
- u32 flags;
};

#define to_mpfs_msspll_out_clk(_hw) container_of(_hw, struct mpfs_msspll_out_hw_clock, hw)
@@ -177,75 +174,25 @@ static int mpfs_clk_register_mssplls(struct device *dev, struct mpfs_msspll_hw_c
* MSS PLL output clocks
*/

-static unsigned long mpfs_clk_msspll_out_recalc_rate(struct clk_hw *hw, unsigned long prate)
-{
- struct mpfs_msspll_out_hw_clock *msspll_out_hw = to_mpfs_msspll_out_clk(hw);
- void __iomem *postdiv_addr = msspll_out_hw->base + msspll_out_hw->reg_offset;
- u32 postdiv;
-
- postdiv = readl_relaxed(postdiv_addr) >> msspll_out_hw->shift;
- postdiv &= clk_div_mask(msspll_out_hw->width);
-
- return prate / postdiv;
-}
-
-static long mpfs_clk_msspll_out_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
-{
- struct mpfs_msspll_out_hw_clock *msspll_out_hw = to_mpfs_msspll_out_clk(hw);
-
- return divider_round_rate(hw, rate, prate, NULL, msspll_out_hw->width,
- msspll_out_hw->flags);
-}
-
-static int mpfs_clk_msspll_out_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate)
-{
- struct mpfs_msspll_out_hw_clock *msspll_out_hw = to_mpfs_msspll_out_clk(hw);
- void __iomem *postdiv_addr = msspll_out_hw->base + msspll_out_hw->reg_offset;
- u32 postdiv;
- int divider_setting;
- unsigned long flags;
-
- divider_setting = divider_get_val(rate, prate, NULL, msspll_out_hw->width,
- msspll_out_hw->flags);
-
- if (divider_setting < 0)
- return divider_setting;
-
- spin_lock_irqsave(&mpfs_clk_lock, flags);
-
- postdiv = readl_relaxed(postdiv_addr);
- postdiv &= ~(clk_div_mask(msspll_out_hw->width) << msspll_out_hw->shift);
- writel_relaxed(postdiv, postdiv_addr);
-
- spin_unlock_irqrestore(&mpfs_clk_lock, flags);
-
- return 0;
-}
-
-static const struct clk_ops mpfs_clk_msspll_out_ops = {
- .recalc_rate = mpfs_clk_msspll_out_recalc_rate,
- .round_rate = mpfs_clk_msspll_out_round_rate,
- .set_rate = mpfs_clk_msspll_out_set_rate,
-};
-
#define CLK_PLL_OUT(_id, _name, _parent, _flags, _shift, _width, _offset) { \
.id = _id, \
- .shift = _shift, \
- .width = _width, \
+ .output.shift = _shift, \
+ .output.width = _width, \
+ .output.table = NULL, \
.reg_offset = _offset, \
- .flags = _flags, \
- .hw.init = CLK_HW_INIT(_name, _parent, &mpfs_clk_msspll_out_ops, 0), \
+ .output.flags = _flags, \
+ .output.hw.init = CLK_HW_INIT(_name, _parent, &clk_divider_ops, 0), \
+ .output.lock = &mpfs_clk_lock, \
}

static struct mpfs_msspll_out_hw_clock mpfs_msspll_out_clks[] = {
- CLK_PLL_OUT(CLK_MSSPLL, "clk_msspll", "clk_msspll_internal", 0,
+ CLK_PLL_OUT(CLK_MSSPLL, "clk_msspll", "clk_msspll_internal", CLK_DIVIDER_ONE_BASED,
MSSPLL_POSTDIV02_SHIFT, MSSPLL_POSTDIV_WIDTH, REG_MSSPLL_POSTDIV01_CR),
- CLK_PLL_OUT(CLK_MSSPLL1, "clk_msspll1", "clk_msspll_internal", 0,
+ CLK_PLL_OUT(CLK_MSSPLL1, "clk_msspll1", "clk_msspll_internal", CLK_DIVIDER_ONE_BASED,
MSSPLL_POSTDIV13_SHIFT, MSSPLL_POSTDIV_WIDTH, REG_MSSPLL_POSTDIV01_CR),
- CLK_PLL_OUT(CLK_MSSPLL2, "clk_msspll2", "clk_msspll_internal", 0,
+ CLK_PLL_OUT(CLK_MSSPLL2, "clk_msspll2", "clk_msspll_internal", CLK_DIVIDER_ONE_BASED,
MSSPLL_POSTDIV02_SHIFT, MSSPLL_POSTDIV_WIDTH, REG_MSSPLL_POSTDIV23_CR),
- CLK_PLL_OUT(CLK_MSSPLL3, "clk_msspll3", "clk_msspll_internal", 0,
+ CLK_PLL_OUT(CLK_MSSPLL3, "clk_msspll3", "clk_msspll_internal", CLK_DIVIDER_ONE_BASED,
MSSPLL_POSTDIV13_SHIFT, MSSPLL_POSTDIV_WIDTH, REG_MSSPLL_POSTDIV23_CR),
};

@@ -259,13 +206,13 @@ static int mpfs_clk_register_msspll_outs(struct device *dev,
for (i = 0; i < num_clks; i++) {
struct mpfs_msspll_out_hw_clock *msspll_out_hw = &msspll_out_hws[i];

- msspll_out_hw->base = data->msspll_base;
- ret = devm_clk_hw_register(dev, &msspll_out_hw->hw);
+ msspll_out_hw->output.reg = data->msspll_base + msspll_out_hw->reg_offset;
+ ret = devm_clk_hw_register(dev, &msspll_out_hw->output.hw);
if (ret)
return dev_err_probe(dev, ret, "failed to register msspll out id: %d\n",
msspll_out_hw->id);

- data->hw_data.hws[msspll_out_hw->id] = &msspll_out_hw->hw;
+ data->hw_data.hws[msspll_out_hw->id] = &msspll_out_hw->output.hw;
}

return 0;
--
2.39.2

2023-12-08 17:13:48

by Conor Dooley

[permalink] [raw]
Subject: [PATCH RESEND v1 3/7] clk: microchip: mpfs: split MSSPLL in two

From: Conor Dooley <[email protected]>

The MSSPLL is really two stages - there's the PLL itself and 4 outputs,
each with their own divider. The current driver models this as a single
entity, outputting a single clock, used for both the CPU and AHB/AXI
buses. The other 3 outputs are used for the eMMC, "user crypto" and CAN
controller. Split the MSSPLL in two, as a precursor to adding support
for the other 3 outputs, with the PLL itself as one "hw" clock and the
output divider stage as another.

Signed-off-by: Conor Dooley <[email protected]>
---
drivers/clk/microchip/clk-mpfs.c | 188 ++++++++++++++++++++-----------
1 file changed, 123 insertions(+), 65 deletions(-)

diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
index c8ffa755b58d..b05bdab10cdc 100644
--- a/drivers/clk/microchip/clk-mpfs.c
+++ b/drivers/clk/microchip/clk-mpfs.c
@@ -30,6 +30,13 @@
#define MSSPLL_POSTDIV_WIDTH 0x07u
#define MSSPLL_FIXED_DIV 4u

+/*
+ * This clock ID is defined here, rather than the binding headers, as it is an
+ * internal clock only, and therefore has no consumers in other peripheral
+ * blocks.
+ */
+#define CLK_MSSPLL_INTERNAL 38u
+
struct mpfs_clock_data {
struct device *dev;
void __iomem *base;
@@ -39,17 +46,27 @@ struct mpfs_clock_data {

struct mpfs_msspll_hw_clock {
void __iomem *base;
+ struct clk_hw hw;
+ struct clk_init_data init;
unsigned int id;
u32 reg_offset;
u32 shift;
u32 width;
u32 flags;
- struct clk_hw hw;
- struct clk_init_data init;
};

#define to_mpfs_msspll_clk(_hw) container_of(_hw, struct mpfs_msspll_hw_clock, hw)

+struct mpfs_msspll_out_hw_clock {
+ void __iomem *base;
+ struct clk_hw hw;
+ struct clk_init_data init;
+ unsigned int id;
+ u32 flags;
+};
+
+#define to_mpfs_msspll_out_clk(_hw) container_of(_hw, struct mpfs_msspll_out_hw_clock, hw)
+
struct mpfs_cfg_hw_clock {
struct clk_divider cfg;
struct clk_init_data init;
@@ -93,93 +110,40 @@ static const struct clk_div_table mpfs_div_rtcref_table[] = {
{ 0, 0 }
};

+/*
+ * MSS PLL internal clock
+ */
+
static unsigned long mpfs_clk_msspll_recalc_rate(struct clk_hw *hw, unsigned long prate)
-{
- struct mpfs_msspll_hw_clock *msspll_hw = to_mpfs_msspll_clk(hw);
- void __iomem *mult_addr = msspll_hw->base + msspll_hw->reg_offset;
- void __iomem *ref_div_addr = msspll_hw->base + REG_MSSPLL_REF_CR;
- void __iomem *postdiv_addr = msspll_hw->base + REG_MSSPLL_POSTDIV_CR;
- u32 mult, ref_div, postdiv;
-
- mult = readl_relaxed(mult_addr) >> MSSPLL_FBDIV_SHIFT;
- mult &= clk_div_mask(MSSPLL_FBDIV_WIDTH);
- ref_div = readl_relaxed(ref_div_addr) >> MSSPLL_REFDIV_SHIFT;
- ref_div &= clk_div_mask(MSSPLL_REFDIV_WIDTH);
- postdiv = readl_relaxed(postdiv_addr) >> MSSPLL_POSTDIV_SHIFT;
- postdiv &= clk_div_mask(MSSPLL_POSTDIV_WIDTH);
-
- return prate * mult / (ref_div * MSSPLL_FIXED_DIV * postdiv);
-}
-
-static long mpfs_clk_msspll_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate)
{
struct mpfs_msspll_hw_clock *msspll_hw = to_mpfs_msspll_clk(hw);
void __iomem *mult_addr = msspll_hw->base + msspll_hw->reg_offset;
void __iomem *ref_div_addr = msspll_hw->base + REG_MSSPLL_REF_CR;
u32 mult, ref_div;
- unsigned long rate_before_ctrl;

mult = readl_relaxed(mult_addr) >> MSSPLL_FBDIV_SHIFT;
mult &= clk_div_mask(MSSPLL_FBDIV_WIDTH);
ref_div = readl_relaxed(ref_div_addr) >> MSSPLL_REFDIV_SHIFT;
ref_div &= clk_div_mask(MSSPLL_REFDIV_WIDTH);

- rate_before_ctrl = rate * (ref_div * MSSPLL_FIXED_DIV) / mult;
-
- return divider_round_rate(hw, rate_before_ctrl, prate, NULL, MSSPLL_POSTDIV_WIDTH,
- msspll_hw->flags);
-}
-
-static int mpfs_clk_msspll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate)
-{
- struct mpfs_msspll_hw_clock *msspll_hw = to_mpfs_msspll_clk(hw);
- void __iomem *mult_addr = msspll_hw->base + msspll_hw->reg_offset;
- void __iomem *ref_div_addr = msspll_hw->base + REG_MSSPLL_REF_CR;
- void __iomem *postdiv_addr = msspll_hw->base + REG_MSSPLL_POSTDIV_CR;
- u32 mult, ref_div, postdiv;
- int divider_setting;
- unsigned long rate_before_ctrl, flags;
-
- mult = readl_relaxed(mult_addr) >> MSSPLL_FBDIV_SHIFT;
- mult &= clk_div_mask(MSSPLL_FBDIV_WIDTH);
- ref_div = readl_relaxed(ref_div_addr) >> MSSPLL_REFDIV_SHIFT;
- ref_div &= clk_div_mask(MSSPLL_REFDIV_WIDTH);
-
- rate_before_ctrl = rate * (ref_div * MSSPLL_FIXED_DIV) / mult;
- divider_setting = divider_get_val(rate_before_ctrl, prate, NULL, MSSPLL_POSTDIV_WIDTH,
- msspll_hw->flags);
-
- if (divider_setting < 0)
- return divider_setting;
-
- spin_lock_irqsave(&mpfs_clk_lock, flags);
-
- postdiv = readl_relaxed(postdiv_addr);
- postdiv &= ~(clk_div_mask(MSSPLL_POSTDIV_WIDTH) << MSSPLL_POSTDIV_SHIFT);
- writel_relaxed(postdiv, postdiv_addr);
-
- spin_unlock_irqrestore(&mpfs_clk_lock, flags);
-
- return 0;
+ return prate * mult / (ref_div * MSSPLL_FIXED_DIV);
}

static const struct clk_ops mpfs_clk_msspll_ops = {
.recalc_rate = mpfs_clk_msspll_recalc_rate,
- .round_rate = mpfs_clk_msspll_round_rate,
- .set_rate = mpfs_clk_msspll_set_rate,
};

#define CLK_PLL(_id, _name, _parent, _shift, _width, _flags, _offset) { \
.id = _id, \
+ .flags = _flags, \
.shift = _shift, \
.width = _width, \
.reg_offset = _offset, \
- .flags = _flags, \
.hw.init = CLK_HW_INIT_PARENTS_DATA(_name, _parent, &mpfs_clk_msspll_ops, 0), \
}

static struct mpfs_msspll_hw_clock mpfs_msspll_clks[] = {
- CLK_PLL(CLK_MSSPLL, "clk_msspll", mpfs_ext_ref, MSSPLL_FBDIV_SHIFT,
+ CLK_PLL(CLK_MSSPLL_INTERNAL, "clk_msspll_internal", mpfs_ext_ref, MSSPLL_FBDIV_SHIFT,
MSSPLL_FBDIV_WIDTH, 0, REG_MSSPLL_SSCG_2_CR),
};

@@ -196,7 +160,7 @@ static int mpfs_clk_register_mssplls(struct device *dev, struct mpfs_msspll_hw_c
ret = devm_clk_hw_register(dev, &msspll_hw->hw);
if (ret)
return dev_err_probe(dev, ret, "failed to register msspll id: %d\n",
- CLK_MSSPLL);
+ CLK_MSSPLL_INTERNAL);

data->hw_data.hws[msspll_hw->id] = &msspll_hw->hw;
}
@@ -204,6 +168,94 @@ static int mpfs_clk_register_mssplls(struct device *dev, struct mpfs_msspll_hw_c
return 0;
}

+/*
+ * MSS PLL output clocks
+ */
+
+static unsigned long mpfs_clk_msspll_out_recalc_rate(struct clk_hw *hw, unsigned long prate)
+{
+ struct mpfs_msspll_out_hw_clock *msspll_out_hw = to_mpfs_msspll_out_clk(hw);
+ void __iomem *postdiv_addr = msspll_out_hw->base + REG_MSSPLL_POSTDIV_CR;
+ u32 postdiv;
+
+ postdiv = readl_relaxed(postdiv_addr) >> MSSPLL_POSTDIV_SHIFT;
+ postdiv &= clk_div_mask(MSSPLL_POSTDIV_WIDTH);
+
+ return prate / postdiv;
+}
+
+static long mpfs_clk_msspll_out_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct mpfs_msspll_out_hw_clock *msspll_out_hw = to_mpfs_msspll_out_clk(hw);
+
+ return divider_round_rate(hw, rate, prate, NULL, MSSPLL_POSTDIV_WIDTH,
+ msspll_out_hw->flags);
+}
+
+static int mpfs_clk_msspll_out_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate)
+{
+ struct mpfs_msspll_out_hw_clock *msspll_out_hw = to_mpfs_msspll_out_clk(hw);
+ void __iomem *postdiv_addr = msspll_out_hw->base + REG_MSSPLL_POSTDIV_CR;
+ u32 postdiv;
+ int divider_setting;
+ unsigned long flags;
+
+ divider_setting = divider_get_val(rate, prate, NULL, MSSPLL_POSTDIV_WIDTH,
+ msspll_out_hw->flags);
+
+ if (divider_setting < 0)
+ return divider_setting;
+
+ spin_lock_irqsave(&mpfs_clk_lock, flags);
+
+ postdiv = readl_relaxed(postdiv_addr);
+ postdiv &= ~(clk_div_mask(MSSPLL_POSTDIV_WIDTH) << MSSPLL_POSTDIV_SHIFT);
+ writel_relaxed(postdiv, postdiv_addr);
+
+ spin_unlock_irqrestore(&mpfs_clk_lock, flags);
+
+ return 0;
+}
+
+static const struct clk_ops mpfs_clk_msspll_out_ops = {
+ .recalc_rate = mpfs_clk_msspll_out_recalc_rate,
+ .round_rate = mpfs_clk_msspll_out_round_rate,
+ .set_rate = mpfs_clk_msspll_out_set_rate,
+};
+
+#define CLK_PLL_OUT(_id, _name, _parent, _flags) { \
+ .id = _id, \
+ .flags = _flags, \
+ .hw.init = CLK_HW_INIT(_name, _parent, &mpfs_clk_msspll_out_ops, 0), \
+}
+
+static struct mpfs_msspll_out_hw_clock mpfs_msspll_out_clks[] = {
+ CLK_PLL_OUT(CLK_MSSPLL, "clk_msspll", "clk_msspll_internal", 0),
+};
+
+static int mpfs_clk_register_msspll_outs(struct device *dev,
+ struct mpfs_msspll_out_hw_clock *msspll_out_hws,
+ unsigned int num_clks, struct mpfs_clock_data *data)
+{
+ unsigned int i;
+ int ret;
+
+ for (i = 0; i < num_clks; i++) {
+ struct mpfs_msspll_out_hw_clock *msspll_out_hw = &msspll_out_hws[i];
+
+ msspll_out_hw->base = data->msspll_base;
+ ret = devm_clk_hw_register(dev, &msspll_out_hw->hw);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to register msspll out id: %d\n",
+ msspll_out_hw->id);
+
+ data->hw_data.hws[msspll_out_hw->id] = &msspll_out_hw->hw;
+ }
+
+ return 0;
+}
+
/*
* "CFG" clocks
*/
@@ -442,8 +494,8 @@ static int mpfs_clk_probe(struct platform_device *pdev)
int ret;

/* CLK_RESERVED is not part of clock arrays, so add 1 */
- num_clks = ARRAY_SIZE(mpfs_msspll_clks) + ARRAY_SIZE(mpfs_cfg_clks)
- + ARRAY_SIZE(mpfs_periph_clks) + 1;
+ num_clks = ARRAY_SIZE(mpfs_msspll_clks) + ARRAY_SIZE(mpfs_msspll_out_clks)
+ + ARRAY_SIZE(mpfs_cfg_clks) + ARRAY_SIZE(mpfs_periph_clks) + 1;

clk_data = devm_kzalloc(dev, struct_size(clk_data, hw_data.hws, num_clks), GFP_KERNEL);
if (!clk_data)
@@ -466,6 +518,12 @@ static int mpfs_clk_probe(struct platform_device *pdev)
if (ret)
return ret;

+ ret = mpfs_clk_register_msspll_outs(dev, mpfs_msspll_out_clks,
+ ARRAY_SIZE(mpfs_msspll_out_clks),
+ clk_data);
+ if (ret)
+ return ret;
+
ret = mpfs_clk_register_cfgs(dev, mpfs_cfg_clks, ARRAY_SIZE(mpfs_cfg_clks), clk_data);
if (ret)
return ret;
--
2.39.2

2023-12-08 17:13:57

by Conor Dooley

[permalink] [raw]
Subject: [PATCH RESEND v1 4/7] clk: microchip: mpfs: setup for using other mss pll outputs

From: Conor Dooley <[email protected]>

Now that the MSSPLL is split, and the "postdiv" divider of the
cpu/AHB/AXI bus clock is represented by its own "hw" struct, make the
shifts, register offset and width a parameter of the initialisation
macro, rather than using defines that only work for one of the four
outputs.
Configuring this at initialisaion paves the way for using the other
three output clocks, where the register offset, and the bit shift
within that register, will differ.

Signed-off-by: Conor Dooley <[email protected]>
---
drivers/clk/microchip/clk-mpfs.c | 30 +++++++++++++++++++-----------
1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
index b05bdab10cdc..9edd0333e693 100644
--- a/drivers/clk/microchip/clk-mpfs.c
+++ b/drivers/clk/microchip/clk-mpfs.c
@@ -15,7 +15,8 @@

/* address offset of control registers */
#define REG_MSSPLL_REF_CR 0x08u
-#define REG_MSSPLL_POSTDIV_CR 0x10u
+#define REG_MSSPLL_POSTDIV01_CR 0x10u
+#define REG_MSSPLL_POSTDIV23_CR 0x14u
#define REG_MSSPLL_SSCG_2_CR 0x2Cu
#define REG_CLOCK_CONFIG_CR 0x08u
#define REG_RTC_CLOCK_CR 0x0Cu
@@ -26,7 +27,7 @@
#define MSSPLL_FBDIV_WIDTH 0x0Cu
#define MSSPLL_REFDIV_SHIFT 0x08u
#define MSSPLL_REFDIV_WIDTH 0x06u
-#define MSSPLL_POSTDIV_SHIFT 0x08u
+#define MSSPLL_POSTDIV02_SHIFT 0x08u
#define MSSPLL_POSTDIV_WIDTH 0x07u
#define MSSPLL_FIXED_DIV 4u

@@ -62,6 +63,9 @@ struct mpfs_msspll_out_hw_clock {
struct clk_hw hw;
struct clk_init_data init;
unsigned int id;
+ u32 reg_offset;
+ u32 shift;
+ u32 width;
u32 flags;
};

@@ -175,11 +179,11 @@ static int mpfs_clk_register_mssplls(struct device *dev, struct mpfs_msspll_hw_c
static unsigned long mpfs_clk_msspll_out_recalc_rate(struct clk_hw *hw, unsigned long prate)
{
struct mpfs_msspll_out_hw_clock *msspll_out_hw = to_mpfs_msspll_out_clk(hw);
- void __iomem *postdiv_addr = msspll_out_hw->base + REG_MSSPLL_POSTDIV_CR;
+ void __iomem *postdiv_addr = msspll_out_hw->base + msspll_out_hw->reg_offset;
u32 postdiv;

- postdiv = readl_relaxed(postdiv_addr) >> MSSPLL_POSTDIV_SHIFT;
- postdiv &= clk_div_mask(MSSPLL_POSTDIV_WIDTH);
+ postdiv = readl_relaxed(postdiv_addr) >> msspll_out_hw->shift;
+ postdiv &= clk_div_mask(msspll_out_hw->width);

return prate / postdiv;
}
@@ -189,19 +193,19 @@ static long mpfs_clk_msspll_out_round_rate(struct clk_hw *hw, unsigned long rate
{
struct mpfs_msspll_out_hw_clock *msspll_out_hw = to_mpfs_msspll_out_clk(hw);

- return divider_round_rate(hw, rate, prate, NULL, MSSPLL_POSTDIV_WIDTH,
+ return divider_round_rate(hw, rate, prate, NULL, msspll_out_hw->width,
msspll_out_hw->flags);
}

static int mpfs_clk_msspll_out_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate)
{
struct mpfs_msspll_out_hw_clock *msspll_out_hw = to_mpfs_msspll_out_clk(hw);
- void __iomem *postdiv_addr = msspll_out_hw->base + REG_MSSPLL_POSTDIV_CR;
+ void __iomem *postdiv_addr = msspll_out_hw->base + msspll_out_hw->reg_offset;
u32 postdiv;
int divider_setting;
unsigned long flags;

- divider_setting = divider_get_val(rate, prate, NULL, MSSPLL_POSTDIV_WIDTH,
+ divider_setting = divider_get_val(rate, prate, NULL, msspll_out_hw->width,
msspll_out_hw->flags);

if (divider_setting < 0)
@@ -210,7 +214,7 @@ static int mpfs_clk_msspll_out_set_rate(struct clk_hw *hw, unsigned long rate, u
spin_lock_irqsave(&mpfs_clk_lock, flags);

postdiv = readl_relaxed(postdiv_addr);
- postdiv &= ~(clk_div_mask(MSSPLL_POSTDIV_WIDTH) << MSSPLL_POSTDIV_SHIFT);
+ postdiv &= ~(clk_div_mask(msspll_out_hw->width) << msspll_out_hw->shift);
writel_relaxed(postdiv, postdiv_addr);

spin_unlock_irqrestore(&mpfs_clk_lock, flags);
@@ -224,14 +228,18 @@ static const struct clk_ops mpfs_clk_msspll_out_ops = {
.set_rate = mpfs_clk_msspll_out_set_rate,
};

-#define CLK_PLL_OUT(_id, _name, _parent, _flags) { \
+#define CLK_PLL_OUT(_id, _name, _parent, _flags, _shift, _width, _offset) { \
.id = _id, \
+ .shift = _shift, \
+ .width = _width, \
+ .reg_offset = _offset, \
.flags = _flags, \
.hw.init = CLK_HW_INIT(_name, _parent, &mpfs_clk_msspll_out_ops, 0), \
}

static struct mpfs_msspll_out_hw_clock mpfs_msspll_out_clks[] = {
- CLK_PLL_OUT(CLK_MSSPLL, "clk_msspll", "clk_msspll_internal", 0),
+ CLK_PLL_OUT(CLK_MSSPLL, "clk_msspll", "clk_msspll_internal", 0,
+ MSSPLL_POSTDIV02_SHIFT, MSSPLL_POSTDIV_WIDTH, REG_MSSPLL_POSTDIV01_CR),
};

static int mpfs_clk_register_msspll_outs(struct device *dev,
--
2.39.2

2023-12-08 17:14:01

by Conor Dooley

[permalink] [raw]
Subject: [PATCH RESEND v1 7/7] riscv: dts: microchip: add missing CAN bus clocks

From: Conor Dooley <[email protected]>

The CAN controller on PolarFire SoC has an AHB peripheral clock _and_ a
CAN bus clock. The bus clock was omitted when the binding was written,
but is required for operation. Make up for lost time and add to the DT.

Fixes: 38a71fc04895 ("riscv: dts: microchip: add mpfs's CAN controllers")
Signed-off-by: Conor Dooley <[email protected]>
---
arch/riscv/boot/dts/microchip/mpfs.dtsi | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/boot/dts/microchip/mpfs.dtsi b/arch/riscv/boot/dts/microchip/mpfs.dtsi
index 266489d43912..4d70df0f908c 100644
--- a/arch/riscv/boot/dts/microchip/mpfs.dtsi
+++ b/arch/riscv/boot/dts/microchip/mpfs.dtsi
@@ -416,7 +416,7 @@ i2c1: i2c@2010b000 {
can0: can@2010c000 {
compatible = "microchip,mpfs-can";
reg = <0x0 0x2010c000 0x0 0x1000>;
- clocks = <&clkcfg CLK_CAN0>;
+ clocks = <&clkcfg CLK_CAN0>, <&clkcfg CLK_MSSPLL3>;
interrupt-parent = <&plic>;
interrupts = <56>;
status = "disabled";
@@ -425,7 +425,7 @@ can0: can@2010c000 {
can1: can@2010d000 {
compatible = "microchip,mpfs-can";
reg = <0x0 0x2010d000 0x0 0x1000>;
- clocks = <&clkcfg CLK_CAN1>;
+ clocks = <&clkcfg CLK_CAN1>, <&clkcfg CLK_MSSPLL3>;
interrupt-parent = <&plic>;
interrupts = <57>;
status = "disabled";
--
2.39.2

2023-12-08 17:21:30

by Marc Kleine-Budde

[permalink] [raw]
Subject: Re: [PATCH RESEND v1 0/7] MPFS clock fixes required for correct CAN clock modeling

On 08.12.2023 17:12:22, Conor Dooley wrote:
> From: Conor Dooley <[email protected]>
>
> Resending cos I accidentally only sent the cover letter a few minutes
> prior to this series, due to screwing up a dry run of sending.
> :clown_face:
>
> While reviewing a CAN clock driver internally for MPFS [1]

> 1 - Hopefully that'll show up on the lists soon, once we are happy with
> it ourselves.

A CAN clock driver or a complete CAN driver?

Marc

--
Pengutronix e.K. | Marc Kleine-Budde |
Embedded Linux | https://www.pengutronix.de |
Vertretung Nürnberg | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |


Attachments:
(No filename) (741.00 B)
signature.asc (499.00 B)
Download all attachments

2023-12-08 17:22:23

by Conor Dooley

[permalink] [raw]
Subject: Re: [PATCH RESEND v1 0/7] MPFS clock fixes required for correct CAN clock modeling

On Fri, Dec 08, 2023 at 06:17:54PM +0100, Marc Kleine-Budde wrote:
> On 08.12.2023 17:12:22, Conor Dooley wrote:
> > From: Conor Dooley <[email protected]>
> >
> > Resending cos I accidentally only sent the cover letter a few minutes
> > prior to this series, due to screwing up a dry run of sending.
> > :clown_face:
> >
> > While reviewing a CAN clock driver internally for MPFS [1]
>
> > 1 - Hopefully that'll show up on the lists soon, once we are happy with
> > it ourselves.
>
> A CAN clock driver or a complete CAN driver?

Heh, should have proof read it again in the time afforded to me by the
accident release of the dry run.. It's the latter, sorry.


Attachments:
(No filename) (692.00 B)
signature.asc (235.00 B)
Download all attachments

2023-12-08 18:31:56

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH RESEND v1 2/7] dt-bindings: can: mpfs: add missing required clock


On Fri, 08 Dec 2023 17:12:24 +0000, Conor Dooley wrote:
> From: Conor Dooley <[email protected]>
>
> The CAN controller on PolarFire SoC has an AHB peripheral clock _and_ a
> CAN bus clock. The bus clock was omitted when the binding was written,
> but is required for operation. Make up for lost time and add it.
>
> Cautionary tale in adding bindings without having implemented a real
> user for them perhaps.
>
> Fixes: c878d518d7b6 ("dt-bindings: can: mpfs: document the mpfs CAN controller")
> Signed-off-by: Conor Dooley <[email protected]>
> ---
> .../devicetree/bindings/net/can/microchip,mpfs-can.yaml | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml: properties:clocks: {'maxItems': 2, 'items': [{'description': 'AHB peripheral clock'}, {'description': 'CAN bus clock'}]} should not be valid under {'required': ['maxItems']}
hint: "maxItems" is not needed with an "items" list
from schema $id: http://devicetree.org/meta-schemas/items.yaml#

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20231208-palpitate-passable-c79bacf2036c@spud

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.

2023-12-08 19:26:04

by Conor Dooley

[permalink] [raw]
Subject: Re: [PATCH RESEND v1 2/7] dt-bindings: can: mpfs: add missing required clock

On Fri, Dec 08, 2023 at 12:31:00PM -0600, Rob Herring wrote:
>
> On Fri, 08 Dec 2023 17:12:24 +0000, Conor Dooley wrote:
> > From: Conor Dooley <[email protected]>
> >
> > The CAN controller on PolarFire SoC has an AHB peripheral clock _and_ a
> > CAN bus clock. The bus clock was omitted when the binding was written,
> > but is required for operation. Make up for lost time and add it.
> >
> > Cautionary tale in adding bindings without having implemented a real
> > user for them perhaps.
> >
> > Fixes: c878d518d7b6 ("dt-bindings: can: mpfs: document the mpfs CAN controller")
> > Signed-off-by: Conor Dooley <[email protected]>
> > ---
> > .../devicetree/bindings/net/can/microchip,mpfs-can.yaml | 7 +++++--
> > 1 file changed, 5 insertions(+), 2 deletions(-)
> >
>
> My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
>
> yamllint warnings/errors:
>
> dtschema/dtc warnings/errors:
> /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml: properties:clocks: {'maxItems': 2, 'items': [{'description': 'AHB peripheral clock'}, {'description': 'CAN bus clock'}]} should not be valid under {'required': ['maxItems']}
> hint: "maxItems" is not needed with an "items" list
> from schema $id: http://devicetree.org/meta-schemas/items.yaml#


Oh dear, me of all people.


Attachments:
(No filename) (1.42 kB)
signature.asc (235.00 B)
Download all attachments

2023-12-08 21:46:29

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH RESEND v1 2/7] dt-bindings: can: mpfs: add missing required clock

On Fri, Dec 08, 2023 at 07:25:39PM +0000, Conor Dooley wrote:
> On Fri, Dec 08, 2023 at 12:31:00PM -0600, Rob Herring wrote:
> >
> > On Fri, 08 Dec 2023 17:12:24 +0000, Conor Dooley wrote:
> > > From: Conor Dooley <[email protected]>
> > >
> > > The CAN controller on PolarFire SoC has an AHB peripheral clock _and_ a
> > > CAN bus clock. The bus clock was omitted when the binding was written,
> > > but is required for operation. Make up for lost time and add it.
> > >
> > > Cautionary tale in adding bindings without having implemented a real
> > > user for them perhaps.
> > >
> > > Fixes: c878d518d7b6 ("dt-bindings: can: mpfs: document the mpfs CAN controller")
> > > Signed-off-by: Conor Dooley <[email protected]>
> > > ---
> > > .../devicetree/bindings/net/can/microchip,mpfs-can.yaml | 7 +++++--
> > > 1 file changed, 5 insertions(+), 2 deletions(-)
> > >
> >
> > My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> > on your patch (DT_CHECKER_FLAGS is new in v5.13):
> >
> > yamllint warnings/errors:
> >
> > dtschema/dtc warnings/errors:
> > /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml: properties:clocks: {'maxItems': 2, 'items': [{'description': 'AHB peripheral clock'}, {'description': 'CAN bus clock'}]} should not be valid under {'required': ['maxItems']}
> > hint: "maxItems" is not needed with an "items" list
> > from schema $id: http://devicetree.org/meta-schemas/items.yaml#
>
>
> Oh dear, me of all people.

Happens to the best of us. :)

2023-12-12 20:52:59

by Marc Kleine-Budde

[permalink] [raw]
Subject: Re: [PATCH RESEND v1 2/7] dt-bindings: can: mpfs: add missing required clock

On 08.12.2023 17:12:24, Conor Dooley wrote:
> From: Conor Dooley <[email protected]>
>
> The CAN controller on PolarFire SoC has an AHB peripheral clock _and_ a
> CAN bus clock. The bus clock was omitted when the binding was written,
> but is required for operation. Make up for lost time and add it.
>
> Cautionary tale in adding bindings without having implemented a real
> user for them perhaps.
>
> Fixes: c878d518d7b6 ("dt-bindings: can: mpfs: document the mpfs CAN controller")
> Signed-off-by: Conor Dooley <[email protected]>
> ---
> .../devicetree/bindings/net/can/microchip,mpfs-can.yaml | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml b/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml
> index 45aa3de7cf01..05f680f15b17 100644
> --- a/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml
> +++ b/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml
> @@ -24,7 +24,10 @@ properties:
> maxItems: 1
>
> clocks:
> - maxItems: 1
> + maxItems: 2
> + items:
> + - description: AHB peripheral clock
> + - description: CAN bus clock

Do we we want to have a "clock-names" property, as we need the clock
rate of the CAN bus clock.

Marc

>
> required:
> - compatible
> @@ -39,7 +42,7 @@ examples:
> can@2010c000 {
> compatible = "microchip,mpfs-can";
> reg = <0x2010c000 0x1000>;
> - clocks = <&clkcfg 17>;
> + clocks = <&clkcfg 17>, <&clkcfg 37>;
> interrupt-parent = <&plic>;
> interrupts = <56>;
> };

Marc

--
Pengutronix e.K. | Marc Kleine-Budde |
Embedded Linux | https://www.pengutronix.de |
Vertretung Nürnberg | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |


Attachments:
(No filename) (1.94 kB)
signature.asc (499.00 B)
Download all attachments

2023-12-13 13:03:46

by Conor Dooley

[permalink] [raw]
Subject: Re: [PATCH RESEND v1 2/7] dt-bindings: can: mpfs: add missing required clock

On Tue, Dec 12, 2023 at 09:49:41PM +0100, Marc Kleine-Budde wrote:
> On 08.12.2023 17:12:24, Conor Dooley wrote:
> > From: Conor Dooley <[email protected]>
> >
> > The CAN controller on PolarFire SoC has an AHB peripheral clock _and_ a
> > CAN bus clock. The bus clock was omitted when the binding was written,
> > but is required for operation. Make up for lost time and add it.
> >
> > Cautionary tale in adding bindings without having implemented a real
> > user for them perhaps.
> >
> > Fixes: c878d518d7b6 ("dt-bindings: can: mpfs: document the mpfs CAN controller")
> > Signed-off-by: Conor Dooley <[email protected]>
> > ---
> > .../devicetree/bindings/net/can/microchip,mpfs-can.yaml | 7 +++++--
> > 1 file changed, 5 insertions(+), 2 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml b/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml
> > index 45aa3de7cf01..05f680f15b17 100644
> > --- a/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml
> > +++ b/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml
> > @@ -24,7 +24,10 @@ properties:
> > maxItems: 1
> >
> > clocks:
> > - maxItems: 1
> > + maxItems: 2
> > + items:
> > + - description: AHB peripheral clock
> > + - description: CAN bus clock
>
> Do we we want to have a "clock-names" property, as we need the clock
> rate of the CAN bus clock.

We should not need the clock-names property to be able to get both of
the clocks. clk_bulk_get_all() for example should be usable here.

Cheers,
Conor.


Attachments:
(No filename) (1.61 kB)
signature.asc (235.00 B)
Download all attachments

2023-12-14 11:32:03

by Marc Kleine-Budde

[permalink] [raw]
Subject: Re: [PATCH RESEND v1 2/7] dt-bindings: can: mpfs: add missing required clock

On 13.12.2023 13:02:49, Conor Dooley wrote:
> On Tue, Dec 12, 2023 at 09:49:41PM +0100, Marc Kleine-Budde wrote:
> > On 08.12.2023 17:12:24, Conor Dooley wrote:
> > > From: Conor Dooley <[email protected]>
> > >
> > > The CAN controller on PolarFire SoC has an AHB peripheral clock _and_ a
> > > CAN bus clock. The bus clock was omitted when the binding was written,
> > > but is required for operation. Make up for lost time and add it.
> > >
> > > Cautionary tale in adding bindings without having implemented a real
> > > user for them perhaps.
> > >
> > > Fixes: c878d518d7b6 ("dt-bindings: can: mpfs: document the mpfs CAN controller")
> > > Signed-off-by: Conor Dooley <[email protected]>
> > > ---
> > > .../devicetree/bindings/net/can/microchip,mpfs-can.yaml | 7 +++++--
> > > 1 file changed, 5 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml b/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml
> > > index 45aa3de7cf01..05f680f15b17 100644
> > > --- a/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml
> > > +++ b/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml
> > > @@ -24,7 +24,10 @@ properties:
> > > maxItems: 1
> > >
> > > clocks:
> > > - maxItems: 1
> > > + maxItems: 2
> > > + items:
> > > + - description: AHB peripheral clock
> > > + - description: CAN bus clock
> >
> > Do we we want to have a "clock-names" property, as we need the clock
> > rate of the CAN bus clock.
>
> We should not need the clock-names property to be able to get both of
> the clocks. clk_bulk_get_all() for example should be usable here.

ACK, but we need the clock rate of CAN clock. Does this binding check
that the CAN clock rate is the 2nd one?

regards,
Marc

--
Pengutronix e.K. | Marc Kleine-Budde |
Embedded Linux | https://www.pengutronix.de |
Vertretung Nürnberg | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |


Attachments:
(No filename) (2.10 kB)
signature.asc (499.00 B)
Download all attachments

2023-12-14 13:17:48

by Conor Dooley

[permalink] [raw]
Subject: Re: [PATCH RESEND v1 2/7] dt-bindings: can: mpfs: add missing required clock

On Thu, Dec 14, 2023 at 12:31:04PM +0100, Marc Kleine-Budde wrote:
> On 13.12.2023 13:02:49, Conor Dooley wrote:
> > On Tue, Dec 12, 2023 at 09:49:41PM +0100, Marc Kleine-Budde wrote:
> > > On 08.12.2023 17:12:24, Conor Dooley wrote:
> > > > From: Conor Dooley <[email protected]>
> > > >
> > > > The CAN controller on PolarFire SoC has an AHB peripheral clock _and_ a
> > > > CAN bus clock. The bus clock was omitted when the binding was written,
> > > > but is required for operation. Make up for lost time and add it.
> > > >
> > > > Cautionary tale in adding bindings without having implemented a real
> > > > user for them perhaps.
> > > >
> > > > Fixes: c878d518d7b6 ("dt-bindings: can: mpfs: document the mpfs CAN controller")
> > > > Signed-off-by: Conor Dooley <[email protected]>
> > > > ---
> > > > .../devicetree/bindings/net/can/microchip,mpfs-can.yaml | 7 +++++--
> > > > 1 file changed, 5 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml b/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml
> > > > index 45aa3de7cf01..05f680f15b17 100644
> > > > --- a/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml
> > > > +++ b/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml
> > > > @@ -24,7 +24,10 @@ properties:
> > > > maxItems: 1
> > > >
> > > > clocks:
> > > > - maxItems: 1
> > > > + maxItems: 2
> > > > + items:
> > > > + - description: AHB peripheral clock
> > > > + - description: CAN bus clock
> > >
> > > Do we we want to have a "clock-names" property, as we need the clock
> > > rate of the CAN bus clock.
> >
> > We should not need the clock-names property to be able to get both of
> > the clocks. clk_bulk_get_all() for example should be usable here.
>
> ACK, but we need the clock rate of CAN clock. Does this binding check
> that the CAN clock rate is the 2nd one?

The items list requires that the can clock be the second one, so drivers
etc can rely on that ordering.


Attachments:
(No filename) (2.07 kB)
signature.asc (235.00 B)
Download all attachments

2023-12-14 13:21:07

by Marc Kleine-Budde

[permalink] [raw]
Subject: Re: [PATCH RESEND v1 2/7] dt-bindings: can: mpfs: add missing required clock

On 14.12.2023 13:16:55, Conor Dooley wrote:
> > > > > --- a/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml
> > > > > +++ b/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml
> > > > > @@ -24,7 +24,10 @@ properties:
> > > > > maxItems: 1
> > > > >
> > > > > clocks:
> > > > > - maxItems: 1
> > > > > + maxItems: 2
> > > > > + items:
> > > > > + - description: AHB peripheral clock
> > > > > + - description: CAN bus clock
> > > >
> > > > Do we we want to have a "clock-names" property, as we need the clock
> > > > rate of the CAN bus clock.
> > >
> > > We should not need the clock-names property to be able to get both of
> > > the clocks. clk_bulk_get_all() for example should be usable here.
> >
> > ACK, but we need the clock rate of CAN clock. Does this binding check
> > that the CAN clock rate is the 2nd one?
>
> The items list requires that the can clock be the second one, so drivers
> etc can rely on that ordering.

Thanks for the clarification,
Marc

--
Pengutronix e.K. | Marc Kleine-Budde |
Embedded Linux | https://www.pengutronix.de |
Vertretung Nürnberg | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |


Attachments:
(No filename) (1.29 kB)
signature.asc (499.00 B)
Download all attachments