* [PATCH v4 00/13] PolarFire SoC reset controller & clock cleanups
@ 2022-08-30 12:50 Conor Dooley
2022-08-30 12:52 ` [PATCH v4 01/13] clk: microchip: mpfs: fix clk_cfg array bounds violation Conor Dooley
` (12 more replies)
0 siblings, 13 replies; 26+ messages in thread
From: Conor Dooley @ 2022-08-30 12:50 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Palmer Dabbelt, Conor Dooley, Daire McNamara
Cc: Paul Walmsley, Albert Ou, Claudiu Beznea, linux-clk, devicetree,
linux-kernel, linux-riscv
Hey all,
Kinda two things happening in this series, but I sent it together to
ensure the second part would apply correctly.
The first is the reset controller that I promised after discovering the
issue triggered by CONFIG_PM & the phy not coming up correctly. I have
now removed all the messing with resets from clock enable/disable
functions & now use the aux bus to set up a reset controller driver.
Since I needed something to test it, I hooked up the reset for the
Cadence MACB on PolarFire SoC. This has been split into a second series
for v2 (and is now in v6.0-rcN):
https://lore.kernel.org/all/20220704114511.1892332-1-conor.dooley@microchip.com/
The second part adds rate control for the MSS PLL clock, followed by
some simplifications to the driver & conversions of some custom structs
to the corresponding structs in the framework.
I'll take the dts patch myself when the rest of this is okay-ed.
Thanks,
Conor.
Changes since v3:
- return results directly in probe() & reset_controller_register()
Changes since v2:
- reorder reset Makefile/Kconfig entries
- fix a pre-existing bug exposed by clang with this series applied
- add Padmarao who co-authored the original driver to the authors
Conor Dooley (13):
clk: microchip: mpfs: fix clk_cfg array bounds violation
dt-bindings: clk: microchip: mpfs: add reset controller support
clk: microchip: mpfs: add reset controller
reset: add polarfire soc reset support
MAINTAINERS: add polarfire soc reset controller
riscv: dts: microchip: add mpfs specific macb reset support
clk: microchip: mpfs: add MSS pll's set & round rate
clk: microchip: mpfs: move id & offset out of clock structs
clk: microchip: mpfs: simplify control reg access
clk: microchip: mpfs: delete 2 line mpfs_clk_register_foo()
clk: microchip: mpfs: convert cfg_clk to clk_divider
clk: microchip: mpfs: convert periph_clk to clk_gate
clk: microchip: mpfs: update module authorship & licencing
.../bindings/clock/microchip,mpfs.yaml | 17 +-
MAINTAINERS | 1 +
arch/riscv/boot/dts/microchip/mpfs.dtsi | 7 +-
drivers/clk/microchip/Kconfig | 1 +
drivers/clk/microchip/clk-mpfs.c | 380 +++++++++---------
drivers/reset/Kconfig | 7 +
drivers/reset/Makefile | 2 +-
drivers/reset/reset-mpfs.c | 157 ++++++++
include/soc/microchip/mpfs.h | 8 +
9 files changed, 384 insertions(+), 196 deletions(-)
create mode 100644 drivers/reset/reset-mpfs.c
base-commit: 568035b01cfb107af8d2e4bd2fb9aea22cf5b868
--
2.36.1
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v4 01/13] clk: microchip: mpfs: fix clk_cfg array bounds violation
2022-08-30 12:50 [PATCH v4 00/13] PolarFire SoC reset controller & clock cleanups Conor Dooley
@ 2022-08-30 12:52 ` Conor Dooley
2022-08-31 17:03 ` Conor.Dooley
2022-09-08 6:44 ` Claudiu.Beznea
2022-08-30 12:52 ` [PATCH v4 02/13] dt-bindings: clk: microchip: mpfs: add reset controller support Conor Dooley
` (11 subsequent siblings)
12 siblings, 2 replies; 26+ messages in thread
From: Conor Dooley @ 2022-08-30 12:52 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Palmer Dabbelt, Conor Dooley, Daire McNamara
Cc: Paul Walmsley, Albert Ou, Claudiu Beznea, linux-clk, devicetree,
linux-kernel, linux-riscv, Nathan Chancellor
Unnoticed in current code, there is an array bounds violation present
during clock registration. This seems to fail gracefully in v6.0-rc1,
and life carrys on. While converting the driver to use standard clock
structs/ops, kernel panics were seen during boot when built with clang:
[ 0.581754] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000b1
[ 0.591520] Oops [#1]
[ 0.594045] Modules linked in:
[ 0.597435] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.0.0-rc1-00011-g8e1459cf4eca #1
[ 0.606188] Hardware name: Microchip PolarFire-SoC Icicle Kit (DT)
[ 0.613012] epc : __clk_register+0x4a6/0x85c
[ 0.617759] ra : __clk_register+0x49e/0x85c
[ 0.622489] epc : ffffffff803faf7c ra : ffffffff803faf74 sp : ffffffc80400b720
[ 0.630466] gp : ffffffff810e93f8 tp : ffffffe77fe60000 t0 : ffffffe77ffb3800
[ 0.638443] t1 : 000000000000000a t2 : ffffffffffffffff s0 : ffffffc80400b7c0
[ 0.646420] s1 : 0000000000000001 a0 : 0000000000000001 a1 : 0000000000000000
[ 0.654396] a2 : 0000000000000001 a3 : 0000000000000000 a4 : 0000000000000000
[ 0.662373] a5 : ffffffff803a5810 a6 : 0000000200000022 a7 : 0000000000000006
[ 0.670350] s2 : ffffffff81099d48 s3 : ffffffff80d6e28e s4 : 0000000000000028
[ 0.678327] s5 : ffffffff810ed3c8 s6 : ffffffff810ed3d0 s7 : ffffffe77ffbc100
[ 0.686304] s8 : ffffffe77ffb1540 s9 : ffffffe77ffb1540 s10: 0000000000000008
[ 0.694281] s11: 0000000000000000 t3 : 00000000000000c6 t4 : 0000000000000007
[ 0.702258] t5 : ffffffff810c78c0 t6 : ffffffe77ff88cd0
[ 0.708125] status: 0000000200000120 badaddr: 00000000000000b1 cause: 000000000000000d
[ 0.716869] [<ffffffff803fb892>] devm_clk_hw_register+0x62/0xaa
[ 0.723420] [<ffffffff80403412>] mpfs_clk_probe+0x1e0/0x244
It fails on "clk_periph_timer" - which uses a different parent, that it
tries to find using the macro:
\#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT].cfg.hw)
If parent is RTCREF, so the macro becomes: &mpfs_cfg_clks[33].cfg.hw
which is well beyond the end of the array. Amazingly, builds with GCC
11.1 see no problem here, booting correctly and hooking the parent up
etc. Builds with clang-15 do not, with the above panic.
Drop the macro for the RTCREF and use the array directly to avoid the
panic, using a newly added define that brings the index into the valid
range.
Fixes: 1c6a7ea32b8c ("clk: microchip: mpfs: add RTCREF clock control")
CC: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
drivers/clk/microchip/clk-mpfs.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
index 070c3b896559..9e41f07b3fa6 100644
--- a/drivers/clk/microchip/clk-mpfs.c
+++ b/drivers/clk/microchip/clk-mpfs.c
@@ -27,6 +27,8 @@
#define MSSPLL_POSTDIV_WIDTH 0x07u
#define MSSPLL_FIXED_DIV 4u
+#define RTCREF_OFFSET (CLK_RTCREF - CLK_ENVM)
+
struct mpfs_clock_data {
void __iomem *base;
void __iomem *msspll_base;
@@ -381,7 +383,8 @@ static struct mpfs_periph_hw_clock mpfs_periph_clks[] = {
CLK_PERIPH(CLK_MAC0, "clk_periph_mac0", PARENT_CLK(AHB), 1, 0),
CLK_PERIPH(CLK_MAC1, "clk_periph_mac1", PARENT_CLK(AHB), 2, 0),
CLK_PERIPH(CLK_MMC, "clk_periph_mmc", PARENT_CLK(AHB), 3, 0),
- CLK_PERIPH(CLK_TIMER, "clk_periph_timer", PARENT_CLK(RTCREF), 4, 0),
+ CLK_PERIPH(CLK_TIMER, "clk_periph_timer",
+ &mpfs_cfg_clks[CLK_RTCREF - RTCREF_OFFSET].hw, 4, 0),
CLK_PERIPH(CLK_MMUART0, "clk_periph_mmuart0", PARENT_CLK(AHB), 5, CLK_IS_CRITICAL),
CLK_PERIPH(CLK_MMUART1, "clk_periph_mmuart1", PARENT_CLK(AHB), 6, 0),
CLK_PERIPH(CLK_MMUART2, "clk_periph_mmuart2", PARENT_CLK(AHB), 7, 0),
--
2.36.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 02/13] dt-bindings: clk: microchip: mpfs: add reset controller support
2022-08-30 12:50 [PATCH v4 00/13] PolarFire SoC reset controller & clock cleanups Conor Dooley
2022-08-30 12:52 ` [PATCH v4 01/13] clk: microchip: mpfs: fix clk_cfg array bounds violation Conor Dooley
@ 2022-08-30 12:52 ` Conor Dooley
2022-08-30 12:52 ` [PATCH v4 03/13] clk: microchip: mpfs: add reset controller Conor Dooley
` (10 subsequent siblings)
12 siblings, 0 replies; 26+ messages in thread
From: Conor Dooley @ 2022-08-30 12:52 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Palmer Dabbelt, Conor Dooley, Daire McNamara
Cc: Paul Walmsley, Albert Ou, Claudiu Beznea, linux-clk, devicetree,
linux-kernel, linux-riscv, Rob Herring
The "peripheral" devices on PolarFire SoC can be put into reset, so
update the device tree binding to reflect the presence of a reset
controller.
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
.../bindings/clock/microchip,mpfs.yaml | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/clock/microchip,mpfs.yaml b/Documentation/devicetree/bindings/clock/microchip,mpfs.yaml
index 016a4f378b9b..1d0b6a4fda42 100644
--- a/Documentation/devicetree/bindings/clock/microchip,mpfs.yaml
+++ b/Documentation/devicetree/bindings/clock/microchip,mpfs.yaml
@@ -40,8 +40,21 @@ properties:
const: 1
description: |
The clock consumer should specify the desired clock by having the clock
- ID in its "clocks" phandle cell. See include/dt-bindings/clock/microchip,mpfs-clock.h
- for the full list of PolarFire clock IDs.
+ ID in its "clocks" phandle cell.
+ See include/dt-bindings/clock/microchip,mpfs-clock.h for the full list of
+ PolarFire clock IDs.
+
+ resets:
+ maxItems: 1
+
+ '#reset-cells':
+ description:
+ The AHB/AXI peripherals on the PolarFire SoC have reset support, so from
+ CLK_ENVM to CLK_CFM. The reset consumer should specify the desired
+ peripheral via the clock ID in its "resets" phandle cell.
+ See include/dt-bindings/clock/microchip,mpfs-clock.h for the full list of
+ PolarFire clock IDs.
+ const: 1
required:
- compatible
--
2.36.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 03/13] clk: microchip: mpfs: add reset controller
2022-08-30 12:50 [PATCH v4 00/13] PolarFire SoC reset controller & clock cleanups Conor Dooley
2022-08-30 12:52 ` [PATCH v4 01/13] clk: microchip: mpfs: fix clk_cfg array bounds violation Conor Dooley
2022-08-30 12:52 ` [PATCH v4 02/13] dt-bindings: clk: microchip: mpfs: add reset controller support Conor Dooley
@ 2022-08-30 12:52 ` Conor Dooley
2022-09-08 6:45 ` Claudiu.Beznea
2022-08-30 12:52 ` [PATCH v4 04/13] reset: add polarfire soc reset support Conor Dooley
` (9 subsequent siblings)
12 siblings, 1 reply; 26+ messages in thread
From: Conor Dooley @ 2022-08-30 12:52 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Palmer Dabbelt, Conor Dooley, Daire McNamara
Cc: Paul Walmsley, Albert Ou, Claudiu Beznea, linux-clk, devicetree,
linux-kernel, linux-riscv
Add a reset controller to PolarFire SoC's clock driver. This reset
controller is registered as an aux device and read/write functions
exported to the drivers namespace so that the reset controller can
access the peripheral device reset register.
Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
drivers/clk/microchip/Kconfig | 1 +
drivers/clk/microchip/clk-mpfs.c | 110 +++++++++++++++++++++++++++----
include/soc/microchip/mpfs.h | 8 +++
3 files changed, 107 insertions(+), 12 deletions(-)
diff --git a/drivers/clk/microchip/Kconfig b/drivers/clk/microchip/Kconfig
index a5a99873c4f5..b46e864b3bd8 100644
--- a/drivers/clk/microchip/Kconfig
+++ b/drivers/clk/microchip/Kconfig
@@ -6,5 +6,6 @@ config COMMON_CLK_PIC32
config MCHP_CLK_MPFS
bool "Clk driver for PolarFire SoC"
depends on (RISCV && SOC_MICROCHIP_POLARFIRE) || COMPILE_TEST
+ select AUXILIARY_BUS
help
Supports Clock Configuration for PolarFire SoC
diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
index 9e41f07b3fa6..43cc9583cd14 100644
--- a/drivers/clk/microchip/clk-mpfs.c
+++ b/drivers/clk/microchip/clk-mpfs.c
@@ -3,12 +3,14 @@
* Daire McNamara,<daire.mcnamara@microchip.com>
* Copyright (C) 2020 Microchip Technology Inc. All rights reserved.
*/
+#include <linux/auxiliary_bus.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <dt-bindings/clock/microchip,mpfs-clock.h>
+#include <soc/microchip/mpfs.h>
/* address offset of control registers */
#define REG_MSSPLL_REF_CR 0x08u
@@ -30,6 +32,7 @@
#define RTCREF_OFFSET (CLK_RTCREF - CLK_ENVM)
struct mpfs_clock_data {
+ struct device *dev;
void __iomem *base;
void __iomem *msspll_base;
struct clk_hw_onecell_data hw_data;
@@ -304,10 +307,6 @@ static int mpfs_periph_clk_enable(struct clk_hw *hw)
spin_lock_irqsave(&mpfs_clk_lock, flags);
- reg = readl_relaxed(base_addr + REG_SUBBLK_RESET_CR);
- val = reg & ~(1u << periph->shift);
- writel_relaxed(val, base_addr + REG_SUBBLK_RESET_CR);
-
reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
val = reg | (1u << periph->shift);
writel_relaxed(val, base_addr + REG_SUBBLK_CLOCK_CR);
@@ -341,12 +340,9 @@ static int mpfs_periph_clk_is_enabled(struct clk_hw *hw)
void __iomem *base_addr = periph_hw->sys_base;
u32 reg;
- reg = readl_relaxed(base_addr + REG_SUBBLK_RESET_CR);
- if ((reg & (1u << periph->shift)) == 0u) {
- reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
- if (reg & (1u << periph->shift))
- return 1;
- }
+ reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
+ if (reg & (1u << periph->shift))
+ return 1;
return 0;
}
@@ -441,6 +437,94 @@ static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_c
return 0;
}
+/*
+ * Peripheral clock resets
+ */
+
+#if IS_ENABLED(CONFIG_RESET_CONTROLLER)
+
+u32 mpfs_reset_read(struct device *dev)
+{
+ struct mpfs_clock_data *clock_data = dev_get_drvdata(dev->parent);
+
+ return readl_relaxed(clock_data->base + REG_SUBBLK_RESET_CR);
+}
+EXPORT_SYMBOL_NS_GPL(mpfs_reset_read, MCHP_CLK_MPFS);
+
+void mpfs_reset_write(struct device *dev, u32 val)
+{
+ struct mpfs_clock_data *clock_data = dev_get_drvdata(dev->parent);
+
+ writel_relaxed(val, clock_data->base + REG_SUBBLK_RESET_CR);
+}
+EXPORT_SYMBOL_NS_GPL(mpfs_reset_write, MCHP_CLK_MPFS);
+
+static void mpfs_reset_unregister_adev(void *_adev)
+{
+ struct auxiliary_device *adev = _adev;
+
+ auxiliary_device_delete(adev);
+}
+
+static void mpfs_reset_adev_release(struct device *dev)
+{
+ struct auxiliary_device *adev = to_auxiliary_dev(dev);
+
+ auxiliary_device_uninit(adev);
+
+ kfree(adev);
+}
+
+static struct auxiliary_device *mpfs_reset_adev_alloc(struct mpfs_clock_data *clk_data)
+{
+ struct auxiliary_device *adev;
+ int ret;
+
+ adev = kzalloc(sizeof(*adev), GFP_KERNEL);
+ if (!adev)
+ return ERR_PTR(-ENOMEM);
+
+ adev->name = "reset-mpfs";
+ adev->dev.parent = clk_data->dev;
+ adev->dev.release = mpfs_reset_adev_release;
+ adev->id = 666u;
+
+ ret = auxiliary_device_init(adev);
+ if (ret) {
+ kfree(adev);
+ return ERR_PTR(ret);
+ }
+
+ return adev;
+}
+
+static int mpfs_reset_controller_register(struct mpfs_clock_data *clk_data)
+{
+ struct auxiliary_device *adev;
+ int ret;
+
+ adev = mpfs_reset_adev_alloc(clk_data);
+ if (IS_ERR(adev))
+ return PTR_ERR(adev);
+
+ ret = auxiliary_device_add(adev);
+ if (ret) {
+ auxiliary_device_uninit(adev);
+ return ret;
+ }
+
+ return devm_add_action_or_reset(clk_data->dev, mpfs_reset_unregister_adev, adev);
+}
+
+#else /* !CONFIG_RESET_CONTROLLER */
+
+static int mpfs_reset_controller_register(struct mpfs_clock_data *clk_data)
+{
+ return 0;
+}
+
+#endif /* !CONFIG_RESET_CONTROLLER */
+
static int mpfs_clk_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -465,6 +549,8 @@ static int mpfs_clk_probe(struct platform_device *pdev)
return PTR_ERR(clk_data->msspll_base);
clk_data->hw_data.num = num_clks;
+ clk_data->dev = dev;
+ dev_set_drvdata(dev, clk_data);
ret = mpfs_clk_register_mssplls(dev, mpfs_msspll_clks, ARRAY_SIZE(mpfs_msspll_clks),
clk_data);
@@ -484,14 +570,14 @@ static int mpfs_clk_probe(struct platform_device *pdev)
if (ret)
return ret;
- return ret;
+ return mpfs_reset_controller_register(clk_data);
}
static const struct of_device_id mpfs_clk_of_match_table[] = {
{ .compatible = "microchip,mpfs-clkcfg", },
{}
};
-MODULE_DEVICE_TABLE(of, mpfs_clk_match_table);
+MODULE_DEVICE_TABLE(of, mpfs_clk_of_match_table);
static struct platform_driver mpfs_clk_driver = {
.probe = mpfs_clk_probe,
diff --git a/include/soc/microchip/mpfs.h b/include/soc/microchip/mpfs.h
index 6466515262bd..f916dcde457f 100644
--- a/include/soc/microchip/mpfs.h
+++ b/include/soc/microchip/mpfs.h
@@ -40,4 +40,12 @@ struct mpfs_sys_controller *mpfs_sys_controller_get(struct device *dev);
#endif /* if IS_ENABLED(CONFIG_POLARFIRE_SOC_SYS_CTRL) */
+#if IS_ENABLED(CONFIG_MCHP_CLK_MPFS)
+
+u32 mpfs_reset_read(struct device *dev);
+
+void mpfs_reset_write(struct device *dev, u32 val);
+
+#endif /* if IS_ENABLED(CONFIG_MCHP_CLK_MPFS) */
+
#endif /* __SOC_MPFS_H__ */
--
2.36.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 04/13] reset: add polarfire soc reset support
2022-08-30 12:50 [PATCH v4 00/13] PolarFire SoC reset controller & clock cleanups Conor Dooley
` (2 preceding siblings ...)
2022-08-30 12:52 ` [PATCH v4 03/13] clk: microchip: mpfs: add reset controller Conor Dooley
@ 2022-08-30 12:52 ` Conor Dooley
2022-09-08 6:44 ` Claudiu.Beznea
2022-08-30 12:52 ` [PATCH v4 05/13] MAINTAINERS: add polarfire soc reset controller Conor Dooley
` (8 subsequent siblings)
12 siblings, 1 reply; 26+ messages in thread
From: Conor Dooley @ 2022-08-30 12:52 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Palmer Dabbelt, Conor Dooley, Daire McNamara
Cc: Paul Walmsley, Albert Ou, Claudiu Beznea, linux-clk, devicetree,
linux-kernel, linux-riscv, Philipp Zabel
Add support for the resets on Microchip's PolarFire SoC (MPFS).
Reset control is a single register, wedged in between registers for
clock control. To fit with existed DT etc, the reset controller is
created using the aux device framework & set up in the clock driver.
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
drivers/reset/Kconfig | 7 ++
drivers/reset/Makefile | 2 +-
drivers/reset/reset-mpfs.c | 157 +++++++++++++++++++++++++++++++++++++
3 files changed, 165 insertions(+), 1 deletion(-)
create mode 100644 drivers/reset/reset-mpfs.c
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 806773e88832..85f7abde3766 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -152,6 +152,13 @@ config RESET_PISTACHIO
help
This enables the reset driver for ImgTec Pistachio SoCs.
+config RESET_POLARFIRE_SOC
+ bool "Microchip PolarFire SoC (MPFS) Reset Driver"
+ depends on AUXILIARY_BUS && MCHP_CLK_MPFS
+ default MCHP_CLK_MPFS
+ help
+ This driver supports peripheral reset for the Microchip PolarFire SoC
+
config RESET_QCOM_AOSS
tristate "Qcom AOSS Reset Driver"
depends on ARCH_QCOM || COMPILE_TEST
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index cd5cf8e7c6a7..3e7e5fd633a8 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_RESET_MESON_AUDIO_ARB) += reset-meson-audio-arb.o
obj-$(CONFIG_RESET_NPCM) += reset-npcm.o
obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o
obj-$(CONFIG_RESET_PISTACHIO) += reset-pistachio.o
+obj-$(CONFIG_RESET_POLARFIRE_SOC) += reset-mpfs.o
obj-$(CONFIG_RESET_QCOM_AOSS) += reset-qcom-aoss.o
obj-$(CONFIG_RESET_QCOM_PDC) += reset-qcom-pdc.o
obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o
@@ -40,4 +41,3 @@ obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
obj-$(CONFIG_RESET_UNIPHIER_GLUE) += reset-uniphier-glue.o
obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o
obj-$(CONFIG_ARCH_ZYNQMP) += reset-zynqmp.o
-
diff --git a/drivers/reset/reset-mpfs.c b/drivers/reset/reset-mpfs.c
new file mode 100644
index 000000000000..1580d1b68d61
--- /dev/null
+++ b/drivers/reset/reset-mpfs.c
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * PolarFire SoC (MPFS) Peripheral Clock Reset Controller
+ *
+ * Author: Conor Dooley <conor.dooley@microchip.com>
+ * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries.
+ *
+ */
+#include <linux/auxiliary_bus.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <dt-bindings/clock/microchip,mpfs-clock.h>
+#include <soc/microchip/mpfs.h>
+
+/*
+ * The ENVM reset is the lowest bit in the register & I am using the CLK_FOO
+ * defines in the dt to make things easier to configure - so this is accounting
+ * for the offset of 3 there.
+ */
+#define MPFS_PERIPH_OFFSET CLK_ENVM
+#define MPFS_NUM_RESETS 30u
+#define MPFS_SLEEP_MIN_US 100
+#define MPFS_SLEEP_MAX_US 200
+
+/* block concurrent access to the soft reset register */
+static DEFINE_SPINLOCK(mpfs_reset_lock);
+
+/*
+ * Peripheral clock resets
+ */
+
+static int mpfs_assert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+ unsigned long flags;
+ u32 reg;
+
+ spin_lock_irqsave(&mpfs_reset_lock, flags);
+
+ reg = mpfs_reset_read(rcdev->dev);
+ reg |= BIT(id);
+ mpfs_reset_write(rcdev->dev, reg);
+
+ spin_unlock_irqrestore(&mpfs_reset_lock, flags);
+
+ return 0;
+}
+
+static int mpfs_deassert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+ unsigned long flags;
+ u32 reg, val;
+
+ spin_lock_irqsave(&mpfs_reset_lock, flags);
+
+ reg = mpfs_reset_read(rcdev->dev);
+ val = reg & ~BIT(id);
+ mpfs_reset_write(rcdev->dev, val);
+
+ spin_unlock_irqrestore(&mpfs_reset_lock, flags);
+
+ return 0;
+}
+
+static int mpfs_status(struct reset_controller_dev *rcdev, unsigned long id)
+{
+ u32 reg = mpfs_reset_read(rcdev->dev);
+
+ /*
+ * It is safe to return here as MPFS_NUM_RESETS makes sure the sign bit
+ * is never hit.
+ */
+ return (reg & BIT(id));
+}
+
+static int mpfs_reset(struct reset_controller_dev *rcdev, unsigned long id)
+{
+ mpfs_assert(rcdev, id);
+
+ usleep_range(MPFS_SLEEP_MIN_US, MPFS_SLEEP_MAX_US);
+
+ mpfs_deassert(rcdev, id);
+
+ return 0;
+}
+
+static const struct reset_control_ops mpfs_reset_ops = {
+ .reset = mpfs_reset,
+ .assert = mpfs_assert,
+ .deassert = mpfs_deassert,
+ .status = mpfs_status,
+};
+
+static int mpfs_reset_xlate(struct reset_controller_dev *rcdev,
+ const struct of_phandle_args *reset_spec)
+{
+ unsigned int index = reset_spec->args[0];
+
+ /*
+ * CLK_RESERVED does not map to a clock, but it does map to a reset,
+ * so it has to be accounted for here. It is the reset for the fabric,
+ * so if this reset gets called - do not reset it.
+ */
+ if (index == CLK_RESERVED) {
+ dev_err(rcdev->dev, "Resetting the fabric is not supported\n");
+ return -EINVAL;
+ }
+
+ if (index < MPFS_PERIPH_OFFSET || index >= (MPFS_PERIPH_OFFSET + rcdev->nr_resets)) {
+ dev_err(rcdev->dev, "Invalid reset index %u\n", index);
+ return -EINVAL;
+ }
+
+ return index - MPFS_PERIPH_OFFSET;
+}
+
+static int mpfs_reset_probe(struct auxiliary_device *adev,
+ const struct auxiliary_device_id *id)
+{
+ struct device *dev = &adev->dev;
+ struct reset_controller_dev *rcdev;
+
+ rcdev = devm_kzalloc(dev, sizeof(*rcdev), GFP_KERNEL);
+ if (!rcdev)
+ return -ENOMEM;
+
+ rcdev->dev = dev;
+ rcdev->dev->parent = dev->parent;
+ rcdev->ops = &mpfs_reset_ops;
+ rcdev->of_node = dev->parent->of_node;
+ rcdev->of_reset_n_cells = 1;
+ rcdev->of_xlate = mpfs_reset_xlate;
+ rcdev->nr_resets = MPFS_NUM_RESETS;
+
+ return devm_reset_controller_register(dev, rcdev);
+}
+
+static const struct auxiliary_device_id mpfs_reset_ids[] = {
+ {
+ .name = "clk_mpfs.reset-mpfs",
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(auxiliary, mpfs_reset_ids);
+
+static struct auxiliary_driver mpfs_reset_driver = {
+ .probe = mpfs_reset_probe,
+ .id_table = mpfs_reset_ids,
+};
+
+module_auxiliary_driver(mpfs_reset_driver);
+
+MODULE_DESCRIPTION("Microchip PolarFire SoC Reset Driver");
+MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(MCHP_CLK_MPFS);
--
2.36.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 05/13] MAINTAINERS: add polarfire soc reset controller
2022-08-30 12:50 [PATCH v4 00/13] PolarFire SoC reset controller & clock cleanups Conor Dooley
` (3 preceding siblings ...)
2022-08-30 12:52 ` [PATCH v4 04/13] reset: add polarfire soc reset support Conor Dooley
@ 2022-08-30 12:52 ` Conor Dooley
2022-08-30 12:52 ` [PATCH v4 06/13] riscv: dts: microchip: add mpfs specific macb reset support Conor Dooley
` (7 subsequent siblings)
12 siblings, 0 replies; 26+ messages in thread
From: Conor Dooley @ 2022-08-30 12:52 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Palmer Dabbelt, Conor Dooley, Daire McNamara
Cc: Paul Walmsley, Albert Ou, Claudiu Beznea, linux-clk, devicetree,
linux-kernel, linux-riscv
Add the newly added reset controller for the PolarFire SoC (MPFS) to
the existing MAINTAINERS entry.
Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
MAINTAINERS | 1 +
1 file changed, 1 insertion(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 8a5012ba6ff9..6136b1b22e2c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17532,6 +17532,7 @@ F: drivers/char/hw_random/mpfs-rng.c
F: drivers/clk/microchip/clk-mpfs.c
F: drivers/mailbox/mailbox-mpfs.c
F: drivers/pci/controller/pcie-microchip-host.c
+F: drivers/reset/reset-mpfs.c
F: drivers/rtc/rtc-mpfs.c
F: drivers/soc/microchip/
F: drivers/spi/spi-microchip-core.c
--
2.36.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 06/13] riscv: dts: microchip: add mpfs specific macb reset support
2022-08-30 12:50 [PATCH v4 00/13] PolarFire SoC reset controller & clock cleanups Conor Dooley
` (4 preceding siblings ...)
2022-08-30 12:52 ` [PATCH v4 05/13] MAINTAINERS: add polarfire soc reset controller Conor Dooley
@ 2022-08-30 12:52 ` Conor Dooley
2022-08-30 12:52 ` [PATCH v4 07/13] clk: microchip: mpfs: add MSS pll's set & round rate Conor Dooley
` (6 subsequent siblings)
12 siblings, 0 replies; 26+ messages in thread
From: Conor Dooley @ 2022-08-30 12:52 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Palmer Dabbelt, Conor Dooley, Daire McNamara
Cc: Paul Walmsley, Albert Ou, Claudiu Beznea, linux-clk, devicetree,
linux-kernel, linux-riscv
The macb on PolarFire SoC has reset support which the generic compatible
does not use. Add the newly introduced MPFS specific compatible as the
primary compatible to avail of this support & wire up the reset to the
clock controllers devicetree entry.
Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
arch/riscv/boot/dts/microchip/mpfs.dtsi | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/boot/dts/microchip/mpfs.dtsi b/arch/riscv/boot/dts/microchip/mpfs.dtsi
index 499c2e63ad35..ae5839534d9c 100644
--- a/arch/riscv/boot/dts/microchip/mpfs.dtsi
+++ b/arch/riscv/boot/dts/microchip/mpfs.dtsi
@@ -234,6 +234,7 @@ clkcfg: clkcfg@20002000 {
reg = <0x0 0x20002000 0x0 0x1000>, <0x0 0x3E001000 0x0 0x1000>;
clocks = <&refclk>;
#clock-cells = <1>;
+ #reset-cells = <1>;
};
mmuart0: serial@20000000 {
@@ -383,7 +384,7 @@ can1: can@2010d000 {
};
mac0: ethernet@20110000 {
- compatible = "cdns,macb";
+ compatible = "microchip,mpfs-macb", "cdns,macb";
reg = <0x0 0x20110000 0x0 0x2000>;
#address-cells = <1>;
#size-cells = <0>;
@@ -392,11 +393,12 @@ mac0: ethernet@20110000 {
local-mac-address = [00 00 00 00 00 00];
clocks = <&clkcfg CLK_MAC0>, <&clkcfg CLK_AHB>;
clock-names = "pclk", "hclk";
+ resets = <&clkcfg CLK_MAC0>;
status = "disabled";
};
mac1: ethernet@20112000 {
- compatible = "cdns,macb";
+ compatible = "microchip,mpfs-macb", "cdns,macb";
reg = <0x0 0x20112000 0x0 0x2000>;
#address-cells = <1>;
#size-cells = <0>;
@@ -405,6 +407,7 @@ mac1: ethernet@20112000 {
local-mac-address = [00 00 00 00 00 00];
clocks = <&clkcfg CLK_MAC1>, <&clkcfg CLK_AHB>;
clock-names = "pclk", "hclk";
+ resets = <&clkcfg CLK_MAC1>;
status = "disabled";
};
--
2.36.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 07/13] clk: microchip: mpfs: add MSS pll's set & round rate
2022-08-30 12:50 [PATCH v4 00/13] PolarFire SoC reset controller & clock cleanups Conor Dooley
` (5 preceding siblings ...)
2022-08-30 12:52 ` [PATCH v4 06/13] riscv: dts: microchip: add mpfs specific macb reset support Conor Dooley
@ 2022-08-30 12:52 ` Conor Dooley
2022-09-08 6:46 ` Claudiu.Beznea
2022-08-30 12:52 ` [PATCH v4 08/13] clk: microchip: mpfs: move id & offset out of clock structs Conor Dooley
` (5 subsequent siblings)
12 siblings, 1 reply; 26+ messages in thread
From: Conor Dooley @ 2022-08-30 12:52 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Palmer Dabbelt, Conor Dooley, Daire McNamara
Cc: Paul Walmsley, Albert Ou, Claudiu Beznea, linux-clk, devicetree,
linux-kernel, linux-riscv
The MSS pll is not a fixed frequency clock, so add set() & round_rate()
support.
Control is limited to a 7 bit output divider as other devices on the
FPGA occupy the other three outputs of the PLL & prevent changing
the multiplier.
Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
drivers/clk/microchip/clk-mpfs.c | 54 ++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
index 43cc9583cd14..008b76d81485 100644
--- a/drivers/clk/microchip/clk-mpfs.c
+++ b/drivers/clk/microchip/clk-mpfs.c
@@ -131,8 +131,62 @@ static unsigned long mpfs_clk_msspll_recalc_rate(struct clk_hw *hw, unsigned lon
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;
+}
+
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) { \
--
2.36.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 08/13] clk: microchip: mpfs: move id & offset out of clock structs
2022-08-30 12:50 [PATCH v4 00/13] PolarFire SoC reset controller & clock cleanups Conor Dooley
` (6 preceding siblings ...)
2022-08-30 12:52 ` [PATCH v4 07/13] clk: microchip: mpfs: add MSS pll's set & round rate Conor Dooley
@ 2022-08-30 12:52 ` Conor Dooley
2022-09-08 6:46 ` Claudiu.Beznea
2022-08-30 12:52 ` [PATCH v4 09/13] clk: microchip: mpfs: simplify control reg access Conor Dooley
` (4 subsequent siblings)
12 siblings, 1 reply; 26+ messages in thread
From: Conor Dooley @ 2022-08-30 12:52 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Palmer Dabbelt, Conor Dooley, Daire McNamara
Cc: Paul Walmsley, Albert Ou, Claudiu Beznea, linux-clk, devicetree,
linux-kernel, linux-riscv
The id and offset are the only thing differentiating the clock structs
from "regular" clock structures. On the pretext of converting to more
normal structures, move the id and offset out of the clock structs and
into the hw structs instead.
Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
drivers/clk/microchip/clk-mpfs.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
index 008b76d81485..845658751690 100644
--- a/drivers/clk/microchip/clk-mpfs.c
+++ b/drivers/clk/microchip/clk-mpfs.c
@@ -53,8 +53,6 @@ struct mpfs_msspll_hw_clock {
struct mpfs_cfg_clock {
const struct clk_div_table *table;
- unsigned int id;
- u32 reg_offset;
u8 shift;
u8 width;
u8 flags;
@@ -65,12 +63,13 @@ struct mpfs_cfg_hw_clock {
void __iomem *sys_base;
struct clk_hw hw;
struct clk_init_data init;
+ unsigned int id;
+ u32 reg_offset;
};
#define to_mpfs_cfg_clk(_hw) container_of(_hw, struct mpfs_cfg_hw_clock, hw)
struct mpfs_periph_clock {
- unsigned int id;
u8 shift;
};
@@ -78,6 +77,7 @@ struct mpfs_periph_hw_clock {
struct mpfs_periph_clock periph;
void __iomem *sys_base;
struct clk_hw hw;
+ unsigned int id;
};
#define to_mpfs_periph_clk(_hw) container_of(_hw, struct mpfs_periph_hw_clock, hw)
@@ -243,7 +243,7 @@ static unsigned long mpfs_cfg_clk_recalc_rate(struct clk_hw *hw, unsigned long p
void __iomem *base_addr = cfg_hw->sys_base;
u32 val;
- val = readl_relaxed(base_addr + cfg->reg_offset) >> cfg->shift;
+ val = readl_relaxed(base_addr + cfg_hw->reg_offset) >> cfg->shift;
val &= clk_div_mask(cfg->width);
return divider_recalc_rate(hw, prate, val, cfg->table, cfg->flags, cfg->width);
@@ -272,10 +272,10 @@ static int mpfs_cfg_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned
return divider_setting;
spin_lock_irqsave(&mpfs_clk_lock, flags);
- val = readl_relaxed(base_addr + cfg->reg_offset);
+ val = readl_relaxed(base_addr + cfg_hw->reg_offset);
val &= ~(clk_div_mask(cfg->width) << cfg_hw->cfg.shift);
val |= divider_setting << cfg->shift;
- writel_relaxed(val, base_addr + cfg->reg_offset);
+ writel_relaxed(val, base_addr + cfg_hw->reg_offset);
spin_unlock_irqrestore(&mpfs_clk_lock, flags);
@@ -289,11 +289,11 @@ static const struct clk_ops mpfs_clk_cfg_ops = {
};
#define CLK_CFG(_id, _name, _parent, _shift, _width, _table, _flags, _offset) { \
- .cfg.id = _id, \
+ .id = _id, \
.cfg.shift = _shift, \
.cfg.width = _width, \
.cfg.table = _table, \
- .cfg.reg_offset = _offset, \
+ .reg_offset = _offset, \
.cfg.flags = _flags, \
.hw.init = CLK_HW_INIT(_name, _parent, &mpfs_clk_cfg_ops, 0), \
}
@@ -306,11 +306,11 @@ static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = {
CLK_CFG(CLK_AHB, "clk_ahb", "clk_msspll", 4, 2, mpfs_div_ahb_table, 0,
REG_CLOCK_CONFIG_CR),
{
- .cfg.id = CLK_RTCREF,
+ .id = CLK_RTCREF,
.cfg.shift = 0,
.cfg.width = 12,
.cfg.table = mpfs_div_rtcref_table,
- .cfg.reg_offset = REG_RTC_CLOCK_CR,
+ .reg_offset = REG_RTC_CLOCK_CR,
.cfg.flags = CLK_DIVIDER_ONE_BASED,
.hw.init =
CLK_HW_INIT_PARENTS_DATA("clk_rtcref", mpfs_ext_ref, &mpfs_clk_cfg_ops, 0),
@@ -338,9 +338,9 @@ static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock *
ret = mpfs_clk_register_cfg(dev, cfg_hw, sys_base);
if (ret)
return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
- cfg_hw->cfg.id);
+ cfg_hw->id);
- id = cfg_hw->cfg.id;
+ id = cfg_hw->id;
data->hw_data.hws[id] = &cfg_hw->hw;
}
@@ -408,7 +408,7 @@ static const struct clk_ops mpfs_periph_clk_ops = {
};
#define CLK_PERIPH(_id, _name, _parent, _shift, _flags) { \
- .periph.id = _id, \
+ .id = _id, \
.periph.shift = _shift, \
.hw.init = CLK_HW_INIT_HW(_name, _parent, &mpfs_periph_clk_ops, \
_flags), \
@@ -482,9 +482,9 @@ static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_c
ret = mpfs_clk_register_periph(dev, periph_hw, sys_base);
if (ret)
return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
- periph_hw->periph.id);
+ periph_hw->id);
- id = periph_hws[i].periph.id;
+ id = periph_hws[i].id;
data->hw_data.hws[id] = &periph_hw->hw;
}
--
2.36.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 09/13] clk: microchip: mpfs: simplify control reg access
2022-08-30 12:50 [PATCH v4 00/13] PolarFire SoC reset controller & clock cleanups Conor Dooley
` (7 preceding siblings ...)
2022-08-30 12:52 ` [PATCH v4 08/13] clk: microchip: mpfs: move id & offset out of clock structs Conor Dooley
@ 2022-08-30 12:52 ` Conor Dooley
2022-09-08 6:46 ` Claudiu.Beznea
2022-08-30 12:52 ` [PATCH v4 10/13] clk: microchip: mpfs: delete 2 line mpfs_clk_register_foo() Conor Dooley
` (3 subsequent siblings)
12 siblings, 1 reply; 26+ messages in thread
From: Conor Dooley @ 2022-08-30 12:52 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Palmer Dabbelt, Conor Dooley, Daire McNamara
Cc: Paul Walmsley, Albert Ou, Claudiu Beznea, linux-clk, devicetree,
linux-kernel, linux-riscv
The control reg addresses are known when the clocks are registered, so
we can, instead of assigning a base pointer to the structs, assign the
control reg addresses directly. Accordingly, remove the interim
variables used during reads/writes to those registers.
Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
drivers/clk/microchip/clk-mpfs.c | 42 +++++++++++++-------------------
1 file changed, 17 insertions(+), 25 deletions(-)
diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
index 845658751690..60e1e82912fe 100644
--- a/drivers/clk/microchip/clk-mpfs.c
+++ b/drivers/clk/microchip/clk-mpfs.c
@@ -52,6 +52,7 @@ struct mpfs_msspll_hw_clock {
#define to_mpfs_msspll_clk(_hw) container_of(_hw, struct mpfs_msspll_hw_clock, hw)
struct mpfs_cfg_clock {
+ void __iomem *reg;
const struct clk_div_table *table;
u8 shift;
u8 width;
@@ -60,7 +61,6 @@ struct mpfs_cfg_clock {
struct mpfs_cfg_hw_clock {
struct mpfs_cfg_clock cfg;
- void __iomem *sys_base;
struct clk_hw hw;
struct clk_init_data init;
unsigned int id;
@@ -70,12 +70,12 @@ struct mpfs_cfg_hw_clock {
#define to_mpfs_cfg_clk(_hw) container_of(_hw, struct mpfs_cfg_hw_clock, hw)
struct mpfs_periph_clock {
+ void __iomem *reg;
u8 shift;
};
struct mpfs_periph_hw_clock {
struct mpfs_periph_clock periph;
- void __iomem *sys_base;
struct clk_hw hw;
unsigned int id;
};
@@ -214,14 +214,13 @@ static int mpfs_clk_register_msspll(struct device *dev, struct mpfs_msspll_hw_cl
static int mpfs_clk_register_mssplls(struct device *dev, struct mpfs_msspll_hw_clock *msspll_hws,
unsigned int num_clks, struct mpfs_clock_data *data)
{
- void __iomem *base = data->msspll_base;
unsigned int i;
int ret;
for (i = 0; i < num_clks; i++) {
struct mpfs_msspll_hw_clock *msspll_hw = &msspll_hws[i];
- ret = mpfs_clk_register_msspll(dev, msspll_hw, base);
+ ret = mpfs_clk_register_msspll(dev, msspll_hw, data->msspll_base);
if (ret)
return dev_err_probe(dev, ret, "failed to register msspll id: %d\n",
CLK_MSSPLL);
@@ -240,10 +239,9 @@ static unsigned long mpfs_cfg_clk_recalc_rate(struct clk_hw *hw, unsigned long p
{
struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
- void __iomem *base_addr = cfg_hw->sys_base;
u32 val;
- val = readl_relaxed(base_addr + cfg_hw->reg_offset) >> cfg->shift;
+ val = readl_relaxed(cfg->reg) >> cfg->shift;
val &= clk_div_mask(cfg->width);
return divider_recalc_rate(hw, prate, val, cfg->table, cfg->flags, cfg->width);
@@ -261,7 +259,6 @@ static int mpfs_cfg_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned
{
struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
- void __iomem *base_addr = cfg_hw->sys_base;
unsigned long flags;
u32 val;
int divider_setting;
@@ -272,10 +269,10 @@ static int mpfs_cfg_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned
return divider_setting;
spin_lock_irqsave(&mpfs_clk_lock, flags);
- val = readl_relaxed(base_addr + cfg_hw->reg_offset);
+ val = readl_relaxed(cfg->reg);
val &= ~(clk_div_mask(cfg->width) << cfg_hw->cfg.shift);
val |= divider_setting << cfg->shift;
- writel_relaxed(val, base_addr + cfg_hw->reg_offset);
+ writel_relaxed(val, cfg->reg);
spin_unlock_irqrestore(&mpfs_clk_lock, flags);
@@ -318,9 +315,9 @@ static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = {
};
static int mpfs_clk_register_cfg(struct device *dev, struct mpfs_cfg_hw_clock *cfg_hw,
- void __iomem *sys_base)
+ void __iomem *base)
{
- cfg_hw->sys_base = sys_base;
+ cfg_hw->cfg.reg = base + cfg_hw->reg_offset;
return devm_clk_hw_register(dev, &cfg_hw->hw);
}
@@ -328,14 +325,13 @@ static int mpfs_clk_register_cfg(struct device *dev, struct mpfs_cfg_hw_clock *c
static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock *cfg_hws,
unsigned int num_clks, struct mpfs_clock_data *data)
{
- void __iomem *sys_base = data->base;
unsigned int i, id;
int ret;
for (i = 0; i < num_clks; i++) {
struct mpfs_cfg_hw_clock *cfg_hw = &cfg_hws[i];
- ret = mpfs_clk_register_cfg(dev, cfg_hw, sys_base);
+ ret = mpfs_clk_register_cfg(dev, cfg_hw, data->base);
if (ret)
return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
cfg_hw->id);
@@ -355,15 +351,14 @@ static int mpfs_periph_clk_enable(struct clk_hw *hw)
{
struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
struct mpfs_periph_clock *periph = &periph_hw->periph;
- void __iomem *base_addr = periph_hw->sys_base;
u32 reg, val;
unsigned long flags;
spin_lock_irqsave(&mpfs_clk_lock, flags);
- reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
+ reg = readl_relaxed(periph->reg);
val = reg | (1u << periph->shift);
- writel_relaxed(val, base_addr + REG_SUBBLK_CLOCK_CR);
+ writel_relaxed(val, periph->reg);
spin_unlock_irqrestore(&mpfs_clk_lock, flags);
@@ -374,15 +369,14 @@ static void mpfs_periph_clk_disable(struct clk_hw *hw)
{
struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
struct mpfs_periph_clock *periph = &periph_hw->periph;
- void __iomem *base_addr = periph_hw->sys_base;
u32 reg, val;
unsigned long flags;
spin_lock_irqsave(&mpfs_clk_lock, flags);
- reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
+ reg = readl_relaxed(periph->reg);
val = reg & ~(1u << periph->shift);
- writel_relaxed(val, base_addr + REG_SUBBLK_CLOCK_CR);
+ writel_relaxed(val, periph->reg);
spin_unlock_irqrestore(&mpfs_clk_lock, flags);
}
@@ -391,10 +385,9 @@ static int mpfs_periph_clk_is_enabled(struct clk_hw *hw)
{
struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
struct mpfs_periph_clock *periph = &periph_hw->periph;
- void __iomem *base_addr = periph_hw->sys_base;
u32 reg;
- reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
+ reg = readl_relaxed(periph->reg);
if (reg & (1u << periph->shift))
return 1;
@@ -462,9 +455,9 @@ static struct mpfs_periph_hw_clock mpfs_periph_clks[] = {
};
static int mpfs_clk_register_periph(struct device *dev, struct mpfs_periph_hw_clock *periph_hw,
- void __iomem *sys_base)
+ void __iomem *base)
{
- periph_hw->sys_base = sys_base;
+ periph_hw->periph.reg = base + REG_SUBBLK_CLOCK_CR;
return devm_clk_hw_register(dev, &periph_hw->hw);
}
@@ -472,14 +465,13 @@ static int mpfs_clk_register_periph(struct device *dev, struct mpfs_periph_hw_cl
static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_clock *periph_hws,
int num_clks, struct mpfs_clock_data *data)
{
- void __iomem *sys_base = data->base;
unsigned int i, id;
int ret;
for (i = 0; i < num_clks; i++) {
struct mpfs_periph_hw_clock *periph_hw = &periph_hws[i];
- ret = mpfs_clk_register_periph(dev, periph_hw, sys_base);
+ ret = mpfs_clk_register_periph(dev, periph_hw, data->base);
if (ret)
return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
periph_hw->id);
--
2.36.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 10/13] clk: microchip: mpfs: delete 2 line mpfs_clk_register_foo()
2022-08-30 12:50 [PATCH v4 00/13] PolarFire SoC reset controller & clock cleanups Conor Dooley
` (8 preceding siblings ...)
2022-08-30 12:52 ` [PATCH v4 09/13] clk: microchip: mpfs: simplify control reg access Conor Dooley
@ 2022-08-30 12:52 ` Conor Dooley
2022-09-08 6:47 ` Claudiu.Beznea
2022-08-30 12:52 ` [PATCH v4 11/13] clk: microchip: mpfs: convert cfg_clk to clk_divider Conor Dooley
` (2 subsequent siblings)
12 siblings, 1 reply; 26+ messages in thread
From: Conor Dooley @ 2022-08-30 12:52 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Palmer Dabbelt, Conor Dooley, Daire McNamara
Cc: Paul Walmsley, Albert Ou, Claudiu Beznea, linux-clk, devicetree,
linux-kernel, linux-riscv
The register functions are now comprised of only a single operation
each and no longer add anything to the driver. Delete them.
Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
drivers/clk/microchip/clk-mpfs.c | 33 ++++++--------------------------
1 file changed, 6 insertions(+), 27 deletions(-)
diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
index 60e1e82912fe..538cb589d232 100644
--- a/drivers/clk/microchip/clk-mpfs.c
+++ b/drivers/clk/microchip/clk-mpfs.c
@@ -203,14 +203,6 @@ static struct mpfs_msspll_hw_clock mpfs_msspll_clks[] = {
MSSPLL_FBDIV_WIDTH, 0, REG_MSSPLL_SSCG_2_CR),
};
-static int mpfs_clk_register_msspll(struct device *dev, struct mpfs_msspll_hw_clock *msspll_hw,
- void __iomem *base)
-{
- msspll_hw->base = base;
-
- return devm_clk_hw_register(dev, &msspll_hw->hw);
-}
-
static int mpfs_clk_register_mssplls(struct device *dev, struct mpfs_msspll_hw_clock *msspll_hws,
unsigned int num_clks, struct mpfs_clock_data *data)
{
@@ -220,7 +212,8 @@ static int mpfs_clk_register_mssplls(struct device *dev, struct mpfs_msspll_hw_c
for (i = 0; i < num_clks; i++) {
struct mpfs_msspll_hw_clock *msspll_hw = &msspll_hws[i];
- ret = mpfs_clk_register_msspll(dev, msspll_hw, data->msspll_base);
+ msspll_hw->base = data->msspll_base;
+ 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);
@@ -314,14 +307,6 @@ static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = {
}
};
-static int mpfs_clk_register_cfg(struct device *dev, struct mpfs_cfg_hw_clock *cfg_hw,
- void __iomem *base)
-{
- cfg_hw->cfg.reg = base + cfg_hw->reg_offset;
-
- return devm_clk_hw_register(dev, &cfg_hw->hw);
-}
-
static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock *cfg_hws,
unsigned int num_clks, struct mpfs_clock_data *data)
{
@@ -331,7 +316,8 @@ static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock *
for (i = 0; i < num_clks; i++) {
struct mpfs_cfg_hw_clock *cfg_hw = &cfg_hws[i];
- ret = mpfs_clk_register_cfg(dev, cfg_hw, data->base);
+ cfg_hw->cfg.reg = data->base + cfg_hw->reg_offset;
+ ret = devm_clk_hw_register(dev, &cfg_hw->hw);
if (ret)
return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
cfg_hw->id);
@@ -454,14 +440,6 @@ static struct mpfs_periph_hw_clock mpfs_periph_clks[] = {
CLK_PERIPH(CLK_CFM, "clk_periph_cfm", PARENT_CLK(AHB), 29, 0),
};
-static int mpfs_clk_register_periph(struct device *dev, struct mpfs_periph_hw_clock *periph_hw,
- void __iomem *base)
-{
- periph_hw->periph.reg = base + REG_SUBBLK_CLOCK_CR;
-
- return devm_clk_hw_register(dev, &periph_hw->hw);
-}
-
static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_clock *periph_hws,
int num_clks, struct mpfs_clock_data *data)
{
@@ -471,7 +449,8 @@ static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_c
for (i = 0; i < num_clks; i++) {
struct mpfs_periph_hw_clock *periph_hw = &periph_hws[i];
- ret = mpfs_clk_register_periph(dev, periph_hw, data->base);
+ periph_hw->periph.reg = data->base + REG_SUBBLK_CLOCK_CR;
+ ret = devm_clk_hw_register(dev, &periph_hw->hw);
if (ret)
return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
periph_hw->id);
--
2.36.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 11/13] clk: microchip: mpfs: convert cfg_clk to clk_divider
2022-08-30 12:50 [PATCH v4 00/13] PolarFire SoC reset controller & clock cleanups Conor Dooley
` (9 preceding siblings ...)
2022-08-30 12:52 ` [PATCH v4 10/13] clk: microchip: mpfs: delete 2 line mpfs_clk_register_foo() Conor Dooley
@ 2022-08-30 12:52 ` Conor Dooley
2022-09-08 6:47 ` Claudiu.Beznea
2022-08-30 12:52 ` [PATCH v4 12/13] clk: microchip: mpfs: convert periph_clk to clk_gate Conor Dooley
2022-08-30 12:52 ` [PATCH v4 13/13] clk: microchip: mpfs: update module authorship & licencing Conor Dooley
12 siblings, 1 reply; 26+ messages in thread
From: Conor Dooley @ 2022-08-30 12:52 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Palmer Dabbelt, Conor Dooley, Daire McNamara
Cc: Paul Walmsley, Albert Ou, Claudiu Beznea, linux-clk, devicetree,
linux-kernel, linux-riscv
The cfg_clk struct is now just a redefinition of the clk_divider struct
with custom implentations of the ops, that implement an extra level of
redirection. Remove the custom struct and replace it with clk_divider.
Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
drivers/clk/microchip/clk-mpfs.c | 78 ++++----------------------------
1 file changed, 9 insertions(+), 69 deletions(-)
diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
index 538cb589d232..88a200e88e54 100644
--- a/drivers/clk/microchip/clk-mpfs.c
+++ b/drivers/clk/microchip/clk-mpfs.c
@@ -51,24 +51,13 @@ struct mpfs_msspll_hw_clock {
#define to_mpfs_msspll_clk(_hw) container_of(_hw, struct mpfs_msspll_hw_clock, hw)
-struct mpfs_cfg_clock {
- void __iomem *reg;
- const struct clk_div_table *table;
- u8 shift;
- u8 width;
- u8 flags;
-};
-
struct mpfs_cfg_hw_clock {
- struct mpfs_cfg_clock cfg;
- struct clk_hw hw;
+ struct clk_divider cfg;
struct clk_init_data init;
unsigned int id;
u32 reg_offset;
};
-#define to_mpfs_cfg_clk(_hw) container_of(_hw, struct mpfs_cfg_hw_clock, hw)
-
struct mpfs_periph_clock {
void __iomem *reg;
u8 shift;
@@ -228,56 +217,6 @@ static int mpfs_clk_register_mssplls(struct device *dev, struct mpfs_msspll_hw_c
* "CFG" clocks
*/
-static unsigned long mpfs_cfg_clk_recalc_rate(struct clk_hw *hw, unsigned long prate)
-{
- struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
- struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
- u32 val;
-
- val = readl_relaxed(cfg->reg) >> cfg->shift;
- val &= clk_div_mask(cfg->width);
-
- return divider_recalc_rate(hw, prate, val, cfg->table, cfg->flags, cfg->width);
-}
-
-static long mpfs_cfg_clk_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate)
-{
- struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
- struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
-
- return divider_round_rate(hw, rate, prate, cfg->table, cfg->width, 0);
-}
-
-static int mpfs_cfg_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate)
-{
- struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
- struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
- unsigned long flags;
- u32 val;
- int divider_setting;
-
- divider_setting = divider_get_val(rate, prate, cfg->table, cfg->width, 0);
-
- if (divider_setting < 0)
- return divider_setting;
-
- spin_lock_irqsave(&mpfs_clk_lock, flags);
- val = readl_relaxed(cfg->reg);
- val &= ~(clk_div_mask(cfg->width) << cfg_hw->cfg.shift);
- val |= divider_setting << cfg->shift;
- writel_relaxed(val, cfg->reg);
-
- spin_unlock_irqrestore(&mpfs_clk_lock, flags);
-
- return 0;
-}
-
-static const struct clk_ops mpfs_clk_cfg_ops = {
- .recalc_rate = mpfs_cfg_clk_recalc_rate,
- .round_rate = mpfs_cfg_clk_round_rate,
- .set_rate = mpfs_cfg_clk_set_rate,
-};
-
#define CLK_CFG(_id, _name, _parent, _shift, _width, _table, _flags, _offset) { \
.id = _id, \
.cfg.shift = _shift, \
@@ -285,7 +224,8 @@ static const struct clk_ops mpfs_clk_cfg_ops = {
.cfg.table = _table, \
.reg_offset = _offset, \
.cfg.flags = _flags, \
- .hw.init = CLK_HW_INIT(_name, _parent, &mpfs_clk_cfg_ops, 0), \
+ .cfg.hw.init = CLK_HW_INIT(_name, _parent, &clk_divider_ops, 0), \
+ .cfg.lock = &mpfs_clk_lock, \
}
static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = {
@@ -302,8 +242,8 @@ static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = {
.cfg.table = mpfs_div_rtcref_table,
.reg_offset = REG_RTC_CLOCK_CR,
.cfg.flags = CLK_DIVIDER_ONE_BASED,
- .hw.init =
- CLK_HW_INIT_PARENTS_DATA("clk_rtcref", mpfs_ext_ref, &mpfs_clk_cfg_ops, 0),
+ .cfg.hw.init =
+ CLK_HW_INIT_PARENTS_DATA("clk_rtcref", mpfs_ext_ref, &clk_divider_ops, 0),
}
};
@@ -317,13 +257,13 @@ static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock *
struct mpfs_cfg_hw_clock *cfg_hw = &cfg_hws[i];
cfg_hw->cfg.reg = data->base + cfg_hw->reg_offset;
- ret = devm_clk_hw_register(dev, &cfg_hw->hw);
+ ret = devm_clk_hw_register(dev, &cfg_hw->cfg.hw);
if (ret)
return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
cfg_hw->id);
id = cfg_hw->id;
- data->hw_data.hws[id] = &cfg_hw->hw;
+ data->hw_data.hws[id] = &cfg_hw->cfg.hw;
}
return 0;
@@ -393,7 +333,7 @@ static const struct clk_ops mpfs_periph_clk_ops = {
_flags), \
}
-#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT].hw)
+#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT].cfg.hw)
/*
* Critical clocks:
@@ -413,7 +353,7 @@ static struct mpfs_periph_hw_clock mpfs_periph_clks[] = {
CLK_PERIPH(CLK_MAC1, "clk_periph_mac1", PARENT_CLK(AHB), 2, 0),
CLK_PERIPH(CLK_MMC, "clk_periph_mmc", PARENT_CLK(AHB), 3, 0),
CLK_PERIPH(CLK_TIMER, "clk_periph_timer",
- &mpfs_cfg_clks[CLK_RTCREF - RTCREF_OFFSET].hw, 4, 0),
+ &mpfs_cfg_clks[CLK_RTCREF - RTCREF_OFFSET].cfg.hw, 4, 0),
CLK_PERIPH(CLK_MMUART0, "clk_periph_mmuart0", PARENT_CLK(AHB), 5, CLK_IS_CRITICAL),
CLK_PERIPH(CLK_MMUART1, "clk_periph_mmuart1", PARENT_CLK(AHB), 6, 0),
CLK_PERIPH(CLK_MMUART2, "clk_periph_mmuart2", PARENT_CLK(AHB), 7, 0),
--
2.36.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 12/13] clk: microchip: mpfs: convert periph_clk to clk_gate
2022-08-30 12:50 [PATCH v4 00/13] PolarFire SoC reset controller & clock cleanups Conor Dooley
` (10 preceding siblings ...)
2022-08-30 12:52 ` [PATCH v4 11/13] clk: microchip: mpfs: convert cfg_clk to clk_divider Conor Dooley
@ 2022-08-30 12:52 ` Conor Dooley
2022-09-08 6:47 ` Claudiu.Beznea
2022-08-30 12:52 ` [PATCH v4 13/13] clk: microchip: mpfs: update module authorship & licencing Conor Dooley
12 siblings, 1 reply; 26+ messages in thread
From: Conor Dooley @ 2022-08-30 12:52 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Palmer Dabbelt, Conor Dooley, Daire McNamara
Cc: Paul Walmsley, Albert Ou, Claudiu Beznea, linux-clk, devicetree,
linux-kernel, linux-riscv
With the reset code moved to the recently added reset controller, there
is no need for custom ops any longer. Remove the custom ops and the
custom struct by converting to a clk_gate.
Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
drivers/clk/microchip/clk-mpfs.c | 72 +++-----------------------------
1 file changed, 6 insertions(+), 66 deletions(-)
diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
index 88a200e88e54..fa46176eb9ca 100644
--- a/drivers/clk/microchip/clk-mpfs.c
+++ b/drivers/clk/microchip/clk-mpfs.c
@@ -58,19 +58,11 @@ struct mpfs_cfg_hw_clock {
u32 reg_offset;
};
-struct mpfs_periph_clock {
- void __iomem *reg;
- u8 shift;
-};
-
struct mpfs_periph_hw_clock {
- struct mpfs_periph_clock periph;
- struct clk_hw hw;
+ struct clk_gate periph;
unsigned int id;
};
-#define to_mpfs_periph_clk(_hw) container_of(_hw, struct mpfs_periph_hw_clock, hw)
-
/*
* mpfs_clk_lock prevents anything else from writing to the
* mpfs clk block while a software locked register is being written.
@@ -273,64 +265,12 @@ static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock *
* peripheral clocks - devices connected to axi or ahb buses.
*/
-static int mpfs_periph_clk_enable(struct clk_hw *hw)
-{
- struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
- struct mpfs_periph_clock *periph = &periph_hw->periph;
- u32 reg, val;
- unsigned long flags;
-
- spin_lock_irqsave(&mpfs_clk_lock, flags);
-
- reg = readl_relaxed(periph->reg);
- val = reg | (1u << periph->shift);
- writel_relaxed(val, periph->reg);
-
- spin_unlock_irqrestore(&mpfs_clk_lock, flags);
-
- return 0;
-}
-
-static void mpfs_periph_clk_disable(struct clk_hw *hw)
-{
- struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
- struct mpfs_periph_clock *periph = &periph_hw->periph;
- u32 reg, val;
- unsigned long flags;
-
- spin_lock_irqsave(&mpfs_clk_lock, flags);
-
- reg = readl_relaxed(periph->reg);
- val = reg & ~(1u << periph->shift);
- writel_relaxed(val, periph->reg);
-
- spin_unlock_irqrestore(&mpfs_clk_lock, flags);
-}
-
-static int mpfs_periph_clk_is_enabled(struct clk_hw *hw)
-{
- struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
- struct mpfs_periph_clock *periph = &periph_hw->periph;
- u32 reg;
-
- reg = readl_relaxed(periph->reg);
- if (reg & (1u << periph->shift))
- return 1;
-
- return 0;
-}
-
-static const struct clk_ops mpfs_periph_clk_ops = {
- .enable = mpfs_periph_clk_enable,
- .disable = mpfs_periph_clk_disable,
- .is_enabled = mpfs_periph_clk_is_enabled,
-};
-
#define CLK_PERIPH(_id, _name, _parent, _shift, _flags) { \
.id = _id, \
- .periph.shift = _shift, \
- .hw.init = CLK_HW_INIT_HW(_name, _parent, &mpfs_periph_clk_ops, \
+ .periph.bit_idx = _shift, \
+ .periph.hw.init = CLK_HW_INIT_HW(_name, _parent, &clk_gate_ops, \
_flags), \
+ .periph.lock = &mpfs_clk_lock, \
}
#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT].cfg.hw)
@@ -390,13 +330,13 @@ static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_c
struct mpfs_periph_hw_clock *periph_hw = &periph_hws[i];
periph_hw->periph.reg = data->base + REG_SUBBLK_CLOCK_CR;
- ret = devm_clk_hw_register(dev, &periph_hw->hw);
+ ret = devm_clk_hw_register(dev, &periph_hw->periph.hw);
if (ret)
return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
periph_hw->id);
id = periph_hws[i].id;
- data->hw_data.hws[id] = &periph_hw->hw;
+ data->hw_data.hws[id] = &periph_hw->periph.hw;
}
return 0;
--
2.36.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 13/13] clk: microchip: mpfs: update module authorship & licencing
2022-08-30 12:50 [PATCH v4 00/13] PolarFire SoC reset controller & clock cleanups Conor Dooley
` (11 preceding siblings ...)
2022-08-30 12:52 ` [PATCH v4 12/13] clk: microchip: mpfs: convert periph_clk to clk_gate Conor Dooley
@ 2022-08-30 12:52 ` Conor Dooley
12 siblings, 0 replies; 26+ messages in thread
From: Conor Dooley @ 2022-08-30 12:52 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Palmer Dabbelt, Conor Dooley, Daire McNamara
Cc: Paul Walmsley, Albert Ou, Claudiu Beznea, linux-clk, devicetree,
linux-kernel, linux-riscv
Padmarao wrote the driver in its original, pre upstream form.
Daire & myself have been responsible for getting it upstreamable and
subsequent development.
Move Daire out of the blurb & into a MODULE_AUTHOR entry & add entries
for myself and Padmarao.
While we are at it, convert the MODULE_LICENSE field to its preferred
form of "GPL".
Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
drivers/clk/microchip/clk-mpfs.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
index fa46176eb9ca..253a55a04084 100644
--- a/drivers/clk/microchip/clk-mpfs.c
+++ b/drivers/clk/microchip/clk-mpfs.c
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Daire McNamara,<daire.mcnamara@microchip.com>
- * Copyright (C) 2020 Microchip Technology Inc. All rights reserved.
+ * PolarFire SoC MSS/core complex clock control
+ *
+ * Copyright (C) 2020-2022 Microchip Technology Inc. All rights reserved.
*/
#include <linux/auxiliary_bus.h>
#include <linux/clk-provider.h>
@@ -505,4 +506,7 @@ static void __exit clk_mpfs_exit(void)
module_exit(clk_mpfs_exit);
MODULE_DESCRIPTION("Microchip PolarFire SoC Clock Driver");
-MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Padmarao Begari <padmarao.begari@microchip.com>");
+MODULE_AUTHOR("Daire McNamara <daire.mcnamara@microchip.com>");
+MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
+MODULE_LICENSE("GPL");
--
2.36.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v4 01/13] clk: microchip: mpfs: fix clk_cfg array bounds violation
2022-08-30 12:52 ` [PATCH v4 01/13] clk: microchip: mpfs: fix clk_cfg array bounds violation Conor Dooley
@ 2022-08-31 17:03 ` Conor.Dooley
2022-09-08 6:44 ` Claudiu.Beznea
1 sibling, 0 replies; 26+ messages in thread
From: Conor.Dooley @ 2022-08-31 17:03 UTC (permalink / raw)
To: sboyd, Daire.McNamara
Cc: paul.walmsley, robh+dt, krzysztof.kozlowski+dt, palmer, aou,
mturquette, Claudiu.Beznea, linux-clk, devicetree, linux-kernel,
linux-riscv, nathan
Hey Stephen,
On 30/08/2022 13:52, Conor Dooley wrote:
> Unnoticed in current code, there is an array bounds violation present
Looks like the "Unnoticed in current code" is not accurate. For certain
compiler/kernel version combinations that can be triggered without the
rest of the patchset. Apparently the default yocto gcc used by our BSP &
v6.0-rcN does the trick...
Could you take this one patch onto clk-fixes or would you like me to
resend individually?
Thanks,
Conor.
> during clock registration. This seems to fail gracefully in v6.0-rc1,
> and life carrys on. While converting the driver to use standard clock
> structs/ops, kernel panics were seen during boot when built with clang:
>
> [ 0.581754] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000b1
> [ 0.591520] Oops [#1]
> [ 0.594045] Modules linked in:
> [ 0.597435] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.0.0-rc1-00011-g8e1459cf4eca #1
> [ 0.606188] Hardware name: Microchip PolarFire-SoC Icicle Kit (DT)
> [ 0.613012] epc : __clk_register+0x4a6/0x85c
> [ 0.617759] ra : __clk_register+0x49e/0x85c
> [ 0.622489] epc : ffffffff803faf7c ra : ffffffff803faf74 sp : ffffffc80400b720
> [ 0.630466] gp : ffffffff810e93f8 tp : ffffffe77fe60000 t0 : ffffffe77ffb3800
> [ 0.638443] t1 : 000000000000000a t2 : ffffffffffffffff s0 : ffffffc80400b7c0
> [ 0.646420] s1 : 0000000000000001 a0 : 0000000000000001 a1 : 0000000000000000
> [ 0.654396] a2 : 0000000000000001 a3 : 0000000000000000 a4 : 0000000000000000
> [ 0.662373] a5 : ffffffff803a5810 a6 : 0000000200000022 a7 : 0000000000000006
> [ 0.670350] s2 : ffffffff81099d48 s3 : ffffffff80d6e28e s4 : 0000000000000028
> [ 0.678327] s5 : ffffffff810ed3c8 s6 : ffffffff810ed3d0 s7 : ffffffe77ffbc100
> [ 0.686304] s8 : ffffffe77ffb1540 s9 : ffffffe77ffb1540 s10: 0000000000000008
> [ 0.694281] s11: 0000000000000000 t3 : 00000000000000c6 t4 : 0000000000000007
> [ 0.702258] t5 : ffffffff810c78c0 t6 : ffffffe77ff88cd0
> [ 0.708125] status: 0000000200000120 badaddr: 00000000000000b1 cause: 000000000000000d
> [ 0.716869] [<ffffffff803fb892>] devm_clk_hw_register+0x62/0xaa
> [ 0.723420] [<ffffffff80403412>] mpfs_clk_probe+0x1e0/0x244
>
> It fails on "clk_periph_timer" - which uses a different parent, that it
> tries to find using the macro:
> \#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT].cfg.hw)
>
> If parent is RTCREF, so the macro becomes: &mpfs_cfg_clks[33].cfg.hw
> which is well beyond the end of the array. Amazingly, builds with GCC
> 11.1 see no problem here, booting correctly and hooking the parent up
> etc. Builds with clang-15 do not, with the above panic.
>
> Drop the macro for the RTCREF and use the array directly to avoid the
> panic, using a newly added define that brings the index into the valid
> range.
>
> Fixes: 1c6a7ea32b8c ("clk: microchip: mpfs: add RTCREF clock control")
> CC: Nathan Chancellor <nathan@kernel.org>
> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
> ---
> drivers/clk/microchip/clk-mpfs.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
> index 070c3b896559..9e41f07b3fa6 100644
> --- a/drivers/clk/microchip/clk-mpfs.c
> +++ b/drivers/clk/microchip/clk-mpfs.c
> @@ -27,6 +27,8 @@
> #define MSSPLL_POSTDIV_WIDTH 0x07u
> #define MSSPLL_FIXED_DIV 4u
>
> +#define RTCREF_OFFSET (CLK_RTCREF - CLK_ENVM)
> +
> struct mpfs_clock_data {
> void __iomem *base;
> void __iomem *msspll_base;
> @@ -381,7 +383,8 @@ static struct mpfs_periph_hw_clock mpfs_periph_clks[] = {
> CLK_PERIPH(CLK_MAC0, "clk_periph_mac0", PARENT_CLK(AHB), 1, 0),
> CLK_PERIPH(CLK_MAC1, "clk_periph_mac1", PARENT_CLK(AHB), 2, 0),
> CLK_PERIPH(CLK_MMC, "clk_periph_mmc", PARENT_CLK(AHB), 3, 0),
> - CLK_PERIPH(CLK_TIMER, "clk_periph_timer", PARENT_CLK(RTCREF), 4, 0),
> + CLK_PERIPH(CLK_TIMER, "clk_periph_timer",
> + &mpfs_cfg_clks[CLK_RTCREF - RTCREF_OFFSET].hw, 4, 0),
> CLK_PERIPH(CLK_MMUART0, "clk_periph_mmuart0", PARENT_CLK(AHB), 5, CLK_IS_CRITICAL),
> CLK_PERIPH(CLK_MMUART1, "clk_periph_mmuart1", PARENT_CLK(AHB), 6, 0),
> CLK_PERIPH(CLK_MMUART2, "clk_periph_mmuart2", PARENT_CLK(AHB), 7, 0),
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 01/13] clk: microchip: mpfs: fix clk_cfg array bounds violation
2022-08-30 12:52 ` [PATCH v4 01/13] clk: microchip: mpfs: fix clk_cfg array bounds violation Conor Dooley
2022-08-31 17:03 ` Conor.Dooley
@ 2022-09-08 6:44 ` Claudiu.Beznea
2022-09-08 6:48 ` Conor.Dooley
1 sibling, 1 reply; 26+ messages in thread
From: Claudiu.Beznea @ 2022-09-08 6:44 UTC (permalink / raw)
To: Conor.Dooley, mturquette, sboyd, robh+dt, krzysztof.kozlowski+dt,
palmer, Daire.McNamara
Cc: paul.walmsley, aou, linux-clk, devicetree, linux-kernel,
linux-riscv, nathan
On 30.08.2022 15:52, Conor Dooley wrote:
> Unnoticed in current code, there is an array bounds violation present
> during clock registration. This seems to fail gracefully in v6.0-rc1,
> and life carrys on. While converting the driver to use standard clock
> structs/ops, kernel panics were seen during boot when built with clang:
>
> [ 0.581754] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000b1
> [ 0.591520] Oops [#1]
> [ 0.594045] Modules linked in:
> [ 0.597435] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.0.0-rc1-00011-g8e1459cf4eca #1
> [ 0.606188] Hardware name: Microchip PolarFire-SoC Icicle Kit (DT)
> [ 0.613012] epc : __clk_register+0x4a6/0x85c
> [ 0.617759] ra : __clk_register+0x49e/0x85c
> [ 0.622489] epc : ffffffff803faf7c ra : ffffffff803faf74 sp : ffffffc80400b720
> [ 0.630466] gp : ffffffff810e93f8 tp : ffffffe77fe60000 t0 : ffffffe77ffb3800
> [ 0.638443] t1 : 000000000000000a t2 : ffffffffffffffff s0 : ffffffc80400b7c0
> [ 0.646420] s1 : 0000000000000001 a0 : 0000000000000001 a1 : 0000000000000000
> [ 0.654396] a2 : 0000000000000001 a3 : 0000000000000000 a4 : 0000000000000000
> [ 0.662373] a5 : ffffffff803a5810 a6 : 0000000200000022 a7 : 0000000000000006
> [ 0.670350] s2 : ffffffff81099d48 s3 : ffffffff80d6e28e s4 : 0000000000000028
> [ 0.678327] s5 : ffffffff810ed3c8 s6 : ffffffff810ed3d0 s7 : ffffffe77ffbc100
> [ 0.686304] s8 : ffffffe77ffb1540 s9 : ffffffe77ffb1540 s10: 0000000000000008
> [ 0.694281] s11: 0000000000000000 t3 : 00000000000000c6 t4 : 0000000000000007
> [ 0.702258] t5 : ffffffff810c78c0 t6 : ffffffe77ff88cd0
> [ 0.708125] status: 0000000200000120 badaddr: 00000000000000b1 cause: 000000000000000d
> [ 0.716869] [<ffffffff803fb892>] devm_clk_hw_register+0x62/0xaa
> [ 0.723420] [<ffffffff80403412>] mpfs_clk_probe+0x1e0/0x244
>
> It fails on "clk_periph_timer" - which uses a different parent, that it
> tries to find using the macro:
> \#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT].cfg.hw)
>
> If parent is RTCREF, so the macro becomes: &mpfs_cfg_clks[33].cfg.hw
> which is well beyond the end of the array. Amazingly, builds with GCC
> 11.1 see no problem here, booting correctly and hooking the parent up
> etc. Builds with clang-15 do not, with the above panic.
>
> Drop the macro for the RTCREF and use the array directly to avoid the
> panic, using a newly added define that brings the index into the valid
> range.
>
> Fixes: 1c6a7ea32b8c ("clk: microchip: mpfs: add RTCREF clock control")
> CC: Nathan Chancellor <nathan@kernel.org>
> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
> ---
> drivers/clk/microchip/clk-mpfs.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
> index 070c3b896559..9e41f07b3fa6 100644
> --- a/drivers/clk/microchip/clk-mpfs.c
> +++ b/drivers/clk/microchip/clk-mpfs.c
> @@ -27,6 +27,8 @@
> #define MSSPLL_POSTDIV_WIDTH 0x07u
> #define MSSPLL_FIXED_DIV 4u
>
> +#define RTCREF_OFFSET (CLK_RTCREF - CLK_ENVM)
> +
> struct mpfs_clock_data {
> void __iomem *base;
> void __iomem *msspll_base;
> @@ -381,7 +383,8 @@ static struct mpfs_periph_hw_clock mpfs_periph_clks[] = {
> CLK_PERIPH(CLK_MAC0, "clk_periph_mac0", PARENT_CLK(AHB), 1, 0),
> CLK_PERIPH(CLK_MAC1, "clk_periph_mac1", PARENT_CLK(AHB), 2, 0),
> CLK_PERIPH(CLK_MMC, "clk_periph_mmc", PARENT_CLK(AHB), 3, 0),
> - CLK_PERIPH(CLK_TIMER, "clk_periph_timer", PARENT_CLK(RTCREF), 4, 0),
> + CLK_PERIPH(CLK_TIMER, "clk_periph_timer",
> + &mpfs_cfg_clks[CLK_RTCREF - RTCREF_OFFSET].hw, 4, 0),
A personal taste: as clk IDs and clk indexes in mpfs_cfg_clks[] array are
different thing (ID for clk_periph_timer is already different) and the
CLK_RTCREF - RTCREF_OFFSET here is in the end CLK_ENVM = 3 maybe easier to
follow the code would be to add new macros like:
#define CLK_CPU_OFF 0
#define CLK_AXI_OFF 1
#define CLK_AHB_OFF 2
#define CLK_RTCREF_OFF 3
and change the CLK_PARENT() macro something as follows:
#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT##_OFF].hw)
> CLK_PERIPH(CLK_MMUART0, "clk_periph_mmuart0", PARENT_CLK(AHB), 5, CLK_IS_CRITICAL),
> CLK_PERIPH(CLK_MMUART1, "clk_periph_mmuart1", PARENT_CLK(AHB), 6, 0),
> CLK_PERIPH(CLK_MMUART2, "clk_periph_mmuart2", PARENT_CLK(AHB), 7, 0),
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 04/13] reset: add polarfire soc reset support
2022-08-30 12:52 ` [PATCH v4 04/13] reset: add polarfire soc reset support Conor Dooley
@ 2022-09-08 6:44 ` Claudiu.Beznea
0 siblings, 0 replies; 26+ messages in thread
From: Claudiu.Beznea @ 2022-09-08 6:44 UTC (permalink / raw)
To: Conor.Dooley, mturquette, sboyd, robh+dt, krzysztof.kozlowski+dt,
palmer, Daire.McNamara
Cc: paul.walmsley, aou, linux-clk, devicetree, linux-kernel,
linux-riscv, p.zabel
On 30.08.2022 15:52, Conor Dooley wrote:
> Add support for the resets on Microchip's PolarFire SoC (MPFS).
> Reset control is a single register, wedged in between registers for
> clock control. To fit with existed DT etc, the reset controller is
> created using the aux device framework & set up in the clock driver.
>
> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
> Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
> Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
> ---
> drivers/reset/Kconfig | 7 ++
> drivers/reset/Makefile | 2 +-
> drivers/reset/reset-mpfs.c | 157 +++++++++++++++++++++++++++++++++++++
> 3 files changed, 165 insertions(+), 1 deletion(-)
> create mode 100644 drivers/reset/reset-mpfs.c
>
> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
> index 806773e88832..85f7abde3766 100644
> --- a/drivers/reset/Kconfig
> +++ b/drivers/reset/Kconfig
> @@ -152,6 +152,13 @@ config RESET_PISTACHIO
> help
> This enables the reset driver for ImgTec Pistachio SoCs.
>
> +config RESET_POLARFIRE_SOC
> + bool "Microchip PolarFire SoC (MPFS) Reset Driver"
> + depends on AUXILIARY_BUS && MCHP_CLK_MPFS
> + default MCHP_CLK_MPFS
> + help
> + This driver supports peripheral reset for the Microchip PolarFire SoC
> +
> config RESET_QCOM_AOSS
> tristate "Qcom AOSS Reset Driver"
> depends on ARCH_QCOM || COMPILE_TEST
> diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
> index cd5cf8e7c6a7..3e7e5fd633a8 100644
> --- a/drivers/reset/Makefile
> +++ b/drivers/reset/Makefile
> @@ -22,6 +22,7 @@ obj-$(CONFIG_RESET_MESON_AUDIO_ARB) += reset-meson-audio-arb.o
> obj-$(CONFIG_RESET_NPCM) += reset-npcm.o
> obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o
> obj-$(CONFIG_RESET_PISTACHIO) += reset-pistachio.o
> +obj-$(CONFIG_RESET_POLARFIRE_SOC) += reset-mpfs.o
> obj-$(CONFIG_RESET_QCOM_AOSS) += reset-qcom-aoss.o
> obj-$(CONFIG_RESET_QCOM_PDC) += reset-qcom-pdc.o
> obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o
> @@ -40,4 +41,3 @@ obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
> obj-$(CONFIG_RESET_UNIPHIER_GLUE) += reset-uniphier-glue.o
> obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o
> obj-$(CONFIG_ARCH_ZYNQMP) += reset-zynqmp.o
> -
> diff --git a/drivers/reset/reset-mpfs.c b/drivers/reset/reset-mpfs.c
> new file mode 100644
> index 000000000000..1580d1b68d61
> --- /dev/null
> +++ b/drivers/reset/reset-mpfs.c
> @@ -0,0 +1,157 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * PolarFire SoC (MPFS) Peripheral Clock Reset Controller
> + *
> + * Author: Conor Dooley <conor.dooley@microchip.com>
> + * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries.
> + *
> + */
> +#include <linux/auxiliary_bus.h>
> +#include <linux/delay.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/reset-controller.h>
> +#include <dt-bindings/clock/microchip,mpfs-clock.h>
> +#include <soc/microchip/mpfs.h>
> +
> +/*
> + * The ENVM reset is the lowest bit in the register & I am using the CLK_FOO
> + * defines in the dt to make things easier to configure - so this is accounting
> + * for the offset of 3 there.
> + */
> +#define MPFS_PERIPH_OFFSET CLK_ENVM
> +#define MPFS_NUM_RESETS 30u
> +#define MPFS_SLEEP_MIN_US 100
> +#define MPFS_SLEEP_MAX_US 200
> +
> +/* block concurrent access to the soft reset register */
> +static DEFINE_SPINLOCK(mpfs_reset_lock);
> +
> +/*
> + * Peripheral clock resets
> + */
> +
> +static int mpfs_assert(struct reset_controller_dev *rcdev, unsigned long id)
> +{
> + unsigned long flags;
> + u32 reg;
> +
> + spin_lock_irqsave(&mpfs_reset_lock, flags);
> +
> + reg = mpfs_reset_read(rcdev->dev);
> + reg |= BIT(id);
> + mpfs_reset_write(rcdev->dev, reg);
> +
> + spin_unlock_irqrestore(&mpfs_reset_lock, flags);
> +
> + return 0;
> +}
> +
> +static int mpfs_deassert(struct reset_controller_dev *rcdev, unsigned long id)
> +{
> + unsigned long flags;
> + u32 reg, val;
Using either reg or val in this function should be enough.
Other than this:
Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
> +
> + spin_lock_irqsave(&mpfs_reset_lock, flags);
> +
> + reg = mpfs_reset_read(rcdev->dev);
> + val = reg & ~BIT(id);
> + mpfs_reset_write(rcdev->dev, val);
> +
> + spin_unlock_irqrestore(&mpfs_reset_lock, flags);
> +
> + return 0;
> +}
> +
> +static int mpfs_status(struct reset_controller_dev *rcdev, unsigned long id)
> +{
> + u32 reg = mpfs_reset_read(rcdev->dev);
> +
> + /*
> + * It is safe to return here as MPFS_NUM_RESETS makes sure the sign bit
> + * is never hit.
> + */
> + return (reg & BIT(id));
> +}
> +
> +static int mpfs_reset(struct reset_controller_dev *rcdev, unsigned long id)
> +{
> + mpfs_assert(rcdev, id);
> +
> + usleep_range(MPFS_SLEEP_MIN_US, MPFS_SLEEP_MAX_US);
> +
> + mpfs_deassert(rcdev, id);
> +
> + return 0;
> +}
> +
> +static const struct reset_control_ops mpfs_reset_ops = {
> + .reset = mpfs_reset,
> + .assert = mpfs_assert,
> + .deassert = mpfs_deassert,
> + .status = mpfs_status,
> +};
> +
> +static int mpfs_reset_xlate(struct reset_controller_dev *rcdev,
> + const struct of_phandle_args *reset_spec)
> +{
> + unsigned int index = reset_spec->args[0];
> +
> + /*
> + * CLK_RESERVED does not map to a clock, but it does map to a reset,
> + * so it has to be accounted for here. It is the reset for the fabric,
> + * so if this reset gets called - do not reset it.
> + */
> + if (index == CLK_RESERVED) {
> + dev_err(rcdev->dev, "Resetting the fabric is not supported\n");
> + return -EINVAL;
> + }
> +
> + if (index < MPFS_PERIPH_OFFSET || index >= (MPFS_PERIPH_OFFSET + rcdev->nr_resets)) {
> + dev_err(rcdev->dev, "Invalid reset index %u\n", index);
> + return -EINVAL;
> + }
> +
> + return index - MPFS_PERIPH_OFFSET;
> +}
> +
> +static int mpfs_reset_probe(struct auxiliary_device *adev,
> + const struct auxiliary_device_id *id)
> +{
> + struct device *dev = &adev->dev;
> + struct reset_controller_dev *rcdev;
> +
> + rcdev = devm_kzalloc(dev, sizeof(*rcdev), GFP_KERNEL);
> + if (!rcdev)
> + return -ENOMEM;
> +
> + rcdev->dev = dev;
> + rcdev->dev->parent = dev->parent;
> + rcdev->ops = &mpfs_reset_ops;
> + rcdev->of_node = dev->parent->of_node;
> + rcdev->of_reset_n_cells = 1;
> + rcdev->of_xlate = mpfs_reset_xlate;
> + rcdev->nr_resets = MPFS_NUM_RESETS;
> +
> + return devm_reset_controller_register(dev, rcdev);
> +}
> +
> +static const struct auxiliary_device_id mpfs_reset_ids[] = {
> + {
> + .name = "clk_mpfs.reset-mpfs",
> + },
> + { }
> +};
> +MODULE_DEVICE_TABLE(auxiliary, mpfs_reset_ids);
> +
> +static struct auxiliary_driver mpfs_reset_driver = {
> + .probe = mpfs_reset_probe,
> + .id_table = mpfs_reset_ids,
> +};
> +
> +module_auxiliary_driver(mpfs_reset_driver);
> +
> +MODULE_DESCRIPTION("Microchip PolarFire SoC Reset Driver");
> +MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
> +MODULE_LICENSE("GPL");
> +MODULE_IMPORT_NS(MCHP_CLK_MPFS);
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 03/13] clk: microchip: mpfs: add reset controller
2022-08-30 12:52 ` [PATCH v4 03/13] clk: microchip: mpfs: add reset controller Conor Dooley
@ 2022-09-08 6:45 ` Claudiu.Beznea
0 siblings, 0 replies; 26+ messages in thread
From: Claudiu.Beznea @ 2022-09-08 6:45 UTC (permalink / raw)
To: Conor.Dooley, mturquette, sboyd, robh+dt, krzysztof.kozlowski+dt,
palmer, Daire.McNamara
Cc: paul.walmsley, aou, linux-clk, devicetree, linux-kernel,
linux-riscv
On 30.08.2022 15:52, Conor Dooley wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>
> Add a reset controller to PolarFire SoC's clock driver. This reset
> controller is registered as an aux device and read/write functions
> exported to the drivers namespace so that the reset controller can
> access the peripheral device reset register.
>
> Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
> ---
> drivers/clk/microchip/Kconfig | 1 +
> drivers/clk/microchip/clk-mpfs.c | 110 +++++++++++++++++++++++++++----
> include/soc/microchip/mpfs.h | 8 +++
> 3 files changed, 107 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/clk/microchip/Kconfig b/drivers/clk/microchip/Kconfig
> index a5a99873c4f5..b46e864b3bd8 100644
> --- a/drivers/clk/microchip/Kconfig
> +++ b/drivers/clk/microchip/Kconfig
> @@ -6,5 +6,6 @@ config COMMON_CLK_PIC32
> config MCHP_CLK_MPFS
> bool "Clk driver for PolarFire SoC"
> depends on (RISCV && SOC_MICROCHIP_POLARFIRE) || COMPILE_TEST
> + select AUXILIARY_BUS
> help
> Supports Clock Configuration for PolarFire SoC
> diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
> index 9e41f07b3fa6..43cc9583cd14 100644
> --- a/drivers/clk/microchip/clk-mpfs.c
> +++ b/drivers/clk/microchip/clk-mpfs.c
> @@ -3,12 +3,14 @@
> * Daire McNamara,<daire.mcnamara@microchip.com>
> * Copyright (C) 2020 Microchip Technology Inc. All rights reserved.
> */
> +#include <linux/auxiliary_bus.h>
> #include <linux/clk-provider.h>
> #include <linux/io.h>
> #include <linux/module.h>
> #include <linux/platform_device.h>
> #include <linux/slab.h>
> #include <dt-bindings/clock/microchip,mpfs-clock.h>
> +#include <soc/microchip/mpfs.h>
>
> /* address offset of control registers */
> #define REG_MSSPLL_REF_CR 0x08u
> @@ -30,6 +32,7 @@
> #define RTCREF_OFFSET (CLK_RTCREF - CLK_ENVM)
>
> struct mpfs_clock_data {
> + struct device *dev;
> void __iomem *base;
> void __iomem *msspll_base;
> struct clk_hw_onecell_data hw_data;
> @@ -304,10 +307,6 @@ static int mpfs_periph_clk_enable(struct clk_hw *hw)
>
> spin_lock_irqsave(&mpfs_clk_lock, flags);
>
> - reg = readl_relaxed(base_addr + REG_SUBBLK_RESET_CR);
> - val = reg & ~(1u << periph->shift);
> - writel_relaxed(val, base_addr + REG_SUBBLK_RESET_CR);
> -
> reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
> val = reg | (1u << periph->shift);
> writel_relaxed(val, base_addr + REG_SUBBLK_CLOCK_CR);
> @@ -341,12 +340,9 @@ static int mpfs_periph_clk_is_enabled(struct clk_hw *hw)
> void __iomem *base_addr = periph_hw->sys_base;
> u32 reg;
>
> - reg = readl_relaxed(base_addr + REG_SUBBLK_RESET_CR);
> - if ((reg & (1u << periph->shift)) == 0u) {
> - reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
> - if (reg & (1u << periph->shift))
> - return 1;
> - }
> + reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
> + if (reg & (1u << periph->shift))
> + return 1;
>
> return 0;
> }
> @@ -441,6 +437,94 @@ static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_c
> return 0;
> }
>
> +/*
> + * Peripheral clock resets
> + */
> +
> +#if IS_ENABLED(CONFIG_RESET_CONTROLLER)
> +
> +u32 mpfs_reset_read(struct device *dev)
> +{
> + struct mpfs_clock_data *clock_data = dev_get_drvdata(dev->parent);
> +
> + return readl_relaxed(clock_data->base + REG_SUBBLK_RESET_CR);
> +}
> +EXPORT_SYMBOL_NS_GPL(mpfs_reset_read, MCHP_CLK_MPFS);
> +
> +void mpfs_reset_write(struct device *dev, u32 val)
> +{
> + struct mpfs_clock_data *clock_data = dev_get_drvdata(dev->parent);
> +
> + writel_relaxed(val, clock_data->base + REG_SUBBLK_RESET_CR);
> +}
> +EXPORT_SYMBOL_NS_GPL(mpfs_reset_write, MCHP_CLK_MPFS);
> +
> +static void mpfs_reset_unregister_adev(void *_adev)
> +{
> + struct auxiliary_device *adev = _adev;
> +
> + auxiliary_device_delete(adev);
> +}
> +
> +static void mpfs_reset_adev_release(struct device *dev)
> +{
> + struct auxiliary_device *adev = to_auxiliary_dev(dev);
> +
> + auxiliary_device_uninit(adev);
> +
> + kfree(adev);
> +}
> +
> +static struct auxiliary_device *mpfs_reset_adev_alloc(struct mpfs_clock_data *clk_data)
> +{
> + struct auxiliary_device *adev;
> + int ret;
> +
> + adev = kzalloc(sizeof(*adev), GFP_KERNEL);
> + if (!adev)
> + return ERR_PTR(-ENOMEM);
> +
> + adev->name = "reset-mpfs";
> + adev->dev.parent = clk_data->dev;
> + adev->dev.release = mpfs_reset_adev_release;
> + adev->id = 666u;
> +
> + ret = auxiliary_device_init(adev);
> + if (ret) {
> + kfree(adev);
> + return ERR_PTR(ret);
> + }
> +
> + return adev;
> +}
> +
> +static int mpfs_reset_controller_register(struct mpfs_clock_data *clk_data)
> +{
> + struct auxiliary_device *adev;
> + int ret;
> +
> + adev = mpfs_reset_adev_alloc(clk_data);
> + if (IS_ERR(adev))
> + return PTR_ERR(adev);
> +
> + ret = auxiliary_device_add(adev);
> + if (ret) {
> + auxiliary_device_uninit(adev);
> + return ret;
> + }
> +
> + return devm_add_action_or_reset(clk_data->dev, mpfs_reset_unregister_adev, adev);
> +}
> +
> +#else /* !CONFIG_RESET_CONTROLLER */
> +
> +static int mpfs_reset_controller_register(struct mpfs_clock_data *clk_data)
> +{
> + return 0;
> +}
> +
> +#endif /* !CONFIG_RESET_CONTROLLER */
> +
> static int mpfs_clk_probe(struct platform_device *pdev)
> {
> struct device *dev = &pdev->dev;
> @@ -465,6 +549,8 @@ static int mpfs_clk_probe(struct platform_device *pdev)
> return PTR_ERR(clk_data->msspll_base);
>
> clk_data->hw_data.num = num_clks;
> + clk_data->dev = dev;
> + dev_set_drvdata(dev, clk_data);
>
> ret = mpfs_clk_register_mssplls(dev, mpfs_msspll_clks, ARRAY_SIZE(mpfs_msspll_clks),
> clk_data);
> @@ -484,14 +570,14 @@ static int mpfs_clk_probe(struct platform_device *pdev)
> if (ret)
> return ret;
>
> - return ret;
> + return mpfs_reset_controller_register(clk_data);
> }
>
> static const struct of_device_id mpfs_clk_of_match_table[] = {
> { .compatible = "microchip,mpfs-clkcfg", },
> {}
> };
> -MODULE_DEVICE_TABLE(of, mpfs_clk_match_table);
> +MODULE_DEVICE_TABLE(of, mpfs_clk_of_match_table);
>
> static struct platform_driver mpfs_clk_driver = {
> .probe = mpfs_clk_probe,
> diff --git a/include/soc/microchip/mpfs.h b/include/soc/microchip/mpfs.h
> index 6466515262bd..f916dcde457f 100644
> --- a/include/soc/microchip/mpfs.h
> +++ b/include/soc/microchip/mpfs.h
> @@ -40,4 +40,12 @@ struct mpfs_sys_controller *mpfs_sys_controller_get(struct device *dev);
>
> #endif /* if IS_ENABLED(CONFIG_POLARFIRE_SOC_SYS_CTRL) */
>
> +#if IS_ENABLED(CONFIG_MCHP_CLK_MPFS)
> +
> +u32 mpfs_reset_read(struct device *dev);
> +
> +void mpfs_reset_write(struct device *dev, u32 val);
> +
> +#endif /* if IS_ENABLED(CONFIG_MCHP_CLK_MPFS) */
> +
> #endif /* __SOC_MPFS_H__ */
> --
> 2.36.1
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 07/13] clk: microchip: mpfs: add MSS pll's set & round rate
2022-08-30 12:52 ` [PATCH v4 07/13] clk: microchip: mpfs: add MSS pll's set & round rate Conor Dooley
@ 2022-09-08 6:46 ` Claudiu.Beznea
0 siblings, 0 replies; 26+ messages in thread
From: Claudiu.Beznea @ 2022-09-08 6:46 UTC (permalink / raw)
To: Conor.Dooley, mturquette, sboyd, robh+dt, krzysztof.kozlowski+dt,
palmer, Daire.McNamara
Cc: paul.walmsley, aou, linux-clk, devicetree, linux-kernel,
linux-riscv
On 30.08.2022 15:52, Conor Dooley wrote:
> The MSS pll is not a fixed frequency clock, so add set() & round_rate()
> support.
> Control is limited to a 7 bit output divider as other devices on the
> FPGA occupy the other three outputs of the PLL & prevent changing
> the multiplier.
>
> Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
> ---
> drivers/clk/microchip/clk-mpfs.c | 54 ++++++++++++++++++++++++++++++++
> 1 file changed, 54 insertions(+)
>
> diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
> index 43cc9583cd14..008b76d81485 100644
> --- a/drivers/clk/microchip/clk-mpfs.c
> +++ b/drivers/clk/microchip/clk-mpfs.c
> @@ -131,8 +131,62 @@ static unsigned long mpfs_clk_msspll_recalc_rate(struct clk_hw *hw, unsigned lon
> 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;
> +}
> +
> 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) { \
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 08/13] clk: microchip: mpfs: move id & offset out of clock structs
2022-08-30 12:52 ` [PATCH v4 08/13] clk: microchip: mpfs: move id & offset out of clock structs Conor Dooley
@ 2022-09-08 6:46 ` Claudiu.Beznea
0 siblings, 0 replies; 26+ messages in thread
From: Claudiu.Beznea @ 2022-09-08 6:46 UTC (permalink / raw)
To: Conor.Dooley, mturquette, sboyd, robh+dt, krzysztof.kozlowski+dt,
palmer, Daire.McNamara
Cc: paul.walmsley, aou, linux-clk, devicetree, linux-kernel,
linux-riscv
On 30.08.2022 15:52, Conor Dooley wrote:
> The id and offset are the only thing differentiating the clock structs
> from "regular" clock structures. On the pretext of converting to more
> normal structures, move the id and offset out of the clock structs and
> into the hw structs instead.
>
> Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
> ---
> drivers/clk/microchip/clk-mpfs.c | 30 +++++++++++++++---------------
> 1 file changed, 15 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
> index 008b76d81485..845658751690 100644
> --- a/drivers/clk/microchip/clk-mpfs.c
> +++ b/drivers/clk/microchip/clk-mpfs.c
> @@ -53,8 +53,6 @@ struct mpfs_msspll_hw_clock {
>
> struct mpfs_cfg_clock {
> const struct clk_div_table *table;
> - unsigned int id;
> - u32 reg_offset;
> u8 shift;
> u8 width;
> u8 flags;
> @@ -65,12 +63,13 @@ struct mpfs_cfg_hw_clock {
> void __iomem *sys_base;
> struct clk_hw hw;
> struct clk_init_data init;
> + unsigned int id;
> + u32 reg_offset;
> };
>
> #define to_mpfs_cfg_clk(_hw) container_of(_hw, struct mpfs_cfg_hw_clock, hw)
>
> struct mpfs_periph_clock {
> - unsigned int id;
> u8 shift;
> };
>
> @@ -78,6 +77,7 @@ struct mpfs_periph_hw_clock {
> struct mpfs_periph_clock periph;
> void __iomem *sys_base;
> struct clk_hw hw;
> + unsigned int id;
> };
>
> #define to_mpfs_periph_clk(_hw) container_of(_hw, struct mpfs_periph_hw_clock, hw)
> @@ -243,7 +243,7 @@ static unsigned long mpfs_cfg_clk_recalc_rate(struct clk_hw *hw, unsigned long p
> void __iomem *base_addr = cfg_hw->sys_base;
> u32 val;
>
> - val = readl_relaxed(base_addr + cfg->reg_offset) >> cfg->shift;
> + val = readl_relaxed(base_addr + cfg_hw->reg_offset) >> cfg->shift;
> val &= clk_div_mask(cfg->width);
>
> return divider_recalc_rate(hw, prate, val, cfg->table, cfg->flags, cfg->width);
> @@ -272,10 +272,10 @@ static int mpfs_cfg_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned
> return divider_setting;
>
> spin_lock_irqsave(&mpfs_clk_lock, flags);
> - val = readl_relaxed(base_addr + cfg->reg_offset);
> + val = readl_relaxed(base_addr + cfg_hw->reg_offset);
> val &= ~(clk_div_mask(cfg->width) << cfg_hw->cfg.shift);
> val |= divider_setting << cfg->shift;
> - writel_relaxed(val, base_addr + cfg->reg_offset);
> + writel_relaxed(val, base_addr + cfg_hw->reg_offset);
>
> spin_unlock_irqrestore(&mpfs_clk_lock, flags);
>
> @@ -289,11 +289,11 @@ static const struct clk_ops mpfs_clk_cfg_ops = {
> };
>
> #define CLK_CFG(_id, _name, _parent, _shift, _width, _table, _flags, _offset) { \
> - .cfg.id = _id, \
> + .id = _id, \
> .cfg.shift = _shift, \
> .cfg.width = _width, \
> .cfg.table = _table, \
> - .cfg.reg_offset = _offset, \
> + .reg_offset = _offset, \
> .cfg.flags = _flags, \
> .hw.init = CLK_HW_INIT(_name, _parent, &mpfs_clk_cfg_ops, 0), \
> }
> @@ -306,11 +306,11 @@ static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = {
> CLK_CFG(CLK_AHB, "clk_ahb", "clk_msspll", 4, 2, mpfs_div_ahb_table, 0,
> REG_CLOCK_CONFIG_CR),
> {
> - .cfg.id = CLK_RTCREF,
> + .id = CLK_RTCREF,
> .cfg.shift = 0,
> .cfg.width = 12,
> .cfg.table = mpfs_div_rtcref_table,
> - .cfg.reg_offset = REG_RTC_CLOCK_CR,
> + .reg_offset = REG_RTC_CLOCK_CR,
> .cfg.flags = CLK_DIVIDER_ONE_BASED,
> .hw.init =
> CLK_HW_INIT_PARENTS_DATA("clk_rtcref", mpfs_ext_ref, &mpfs_clk_cfg_ops, 0),
> @@ -338,9 +338,9 @@ static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock *
> ret = mpfs_clk_register_cfg(dev, cfg_hw, sys_base);
> if (ret)
> return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
> - cfg_hw->cfg.id);
> + cfg_hw->id);
>
> - id = cfg_hw->cfg.id;
> + id = cfg_hw->id;
> data->hw_data.hws[id] = &cfg_hw->hw;
> }
>
> @@ -408,7 +408,7 @@ static const struct clk_ops mpfs_periph_clk_ops = {
> };
>
> #define CLK_PERIPH(_id, _name, _parent, _shift, _flags) { \
> - .periph.id = _id, \
> + .id = _id, \
> .periph.shift = _shift, \
> .hw.init = CLK_HW_INIT_HW(_name, _parent, &mpfs_periph_clk_ops, \
> _flags), \
> @@ -482,9 +482,9 @@ static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_c
> ret = mpfs_clk_register_periph(dev, periph_hw, sys_base);
> if (ret)
> return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
> - periph_hw->periph.id);
> + periph_hw->id);
>
> - id = periph_hws[i].periph.id;
> + id = periph_hws[i].id;
> data->hw_data.hws[id] = &periph_hw->hw;
> }
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 09/13] clk: microchip: mpfs: simplify control reg access
2022-08-30 12:52 ` [PATCH v4 09/13] clk: microchip: mpfs: simplify control reg access Conor Dooley
@ 2022-09-08 6:46 ` Claudiu.Beznea
0 siblings, 0 replies; 26+ messages in thread
From: Claudiu.Beznea @ 2022-09-08 6:46 UTC (permalink / raw)
To: Conor.Dooley, mturquette, sboyd, robh+dt, krzysztof.kozlowski+dt,
palmer, Daire.McNamara
Cc: paul.walmsley, aou, linux-clk, devicetree, linux-kernel,
linux-riscv
On 30.08.2022 15:52, Conor Dooley wrote:
> The control reg addresses are known when the clocks are registered, so
> we can, instead of assigning a base pointer to the structs, assign the
> control reg addresses directly. Accordingly, remove the interim
> variables used during reads/writes to those registers.
>
> Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
> ---
> drivers/clk/microchip/clk-mpfs.c | 42 +++++++++++++-------------------
> 1 file changed, 17 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
> index 845658751690..60e1e82912fe 100644
> --- a/drivers/clk/microchip/clk-mpfs.c
> +++ b/drivers/clk/microchip/clk-mpfs.c
> @@ -52,6 +52,7 @@ struct mpfs_msspll_hw_clock {
> #define to_mpfs_msspll_clk(_hw) container_of(_hw, struct mpfs_msspll_hw_clock, hw)
>
> struct mpfs_cfg_clock {
> + void __iomem *reg;
> const struct clk_div_table *table;
> u8 shift;
> u8 width;
> @@ -60,7 +61,6 @@ struct mpfs_cfg_clock {
>
> struct mpfs_cfg_hw_clock {
> struct mpfs_cfg_clock cfg;
> - void __iomem *sys_base;
> struct clk_hw hw;
> struct clk_init_data init;
> unsigned int id;
> @@ -70,12 +70,12 @@ struct mpfs_cfg_hw_clock {
> #define to_mpfs_cfg_clk(_hw) container_of(_hw, struct mpfs_cfg_hw_clock, hw)
>
> struct mpfs_periph_clock {
> + void __iomem *reg;
> u8 shift;
> };
>
> struct mpfs_periph_hw_clock {
> struct mpfs_periph_clock periph;
> - void __iomem *sys_base;
> struct clk_hw hw;
> unsigned int id;
> };
> @@ -214,14 +214,13 @@ static int mpfs_clk_register_msspll(struct device *dev, struct mpfs_msspll_hw_cl
> static int mpfs_clk_register_mssplls(struct device *dev, struct mpfs_msspll_hw_clock *msspll_hws,
> unsigned int num_clks, struct mpfs_clock_data *data)
> {
> - void __iomem *base = data->msspll_base;
> unsigned int i;
> int ret;
>
> for (i = 0; i < num_clks; i++) {
> struct mpfs_msspll_hw_clock *msspll_hw = &msspll_hws[i];
>
> - ret = mpfs_clk_register_msspll(dev, msspll_hw, base);
> + ret = mpfs_clk_register_msspll(dev, msspll_hw, data->msspll_base);
> if (ret)
> return dev_err_probe(dev, ret, "failed to register msspll id: %d\n",
> CLK_MSSPLL);
> @@ -240,10 +239,9 @@ static unsigned long mpfs_cfg_clk_recalc_rate(struct clk_hw *hw, unsigned long p
> {
> struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
> struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
> - void __iomem *base_addr = cfg_hw->sys_base;
> u32 val;
>
> - val = readl_relaxed(base_addr + cfg_hw->reg_offset) >> cfg->shift;
> + val = readl_relaxed(cfg->reg) >> cfg->shift;
> val &= clk_div_mask(cfg->width);
>
> return divider_recalc_rate(hw, prate, val, cfg->table, cfg->flags, cfg->width);
> @@ -261,7 +259,6 @@ static int mpfs_cfg_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned
> {
> struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
> struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
> - void __iomem *base_addr = cfg_hw->sys_base;
> unsigned long flags;
> u32 val;
> int divider_setting;
> @@ -272,10 +269,10 @@ static int mpfs_cfg_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned
> return divider_setting;
>
> spin_lock_irqsave(&mpfs_clk_lock, flags);
> - val = readl_relaxed(base_addr + cfg_hw->reg_offset);
> + val = readl_relaxed(cfg->reg);
> val &= ~(clk_div_mask(cfg->width) << cfg_hw->cfg.shift);
> val |= divider_setting << cfg->shift;
> - writel_relaxed(val, base_addr + cfg_hw->reg_offset);
> + writel_relaxed(val, cfg->reg);
>
> spin_unlock_irqrestore(&mpfs_clk_lock, flags);
>
> @@ -318,9 +315,9 @@ static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = {
> };
>
> static int mpfs_clk_register_cfg(struct device *dev, struct mpfs_cfg_hw_clock *cfg_hw,
> - void __iomem *sys_base)
> + void __iomem *base)
> {
> - cfg_hw->sys_base = sys_base;
> + cfg_hw->cfg.reg = base + cfg_hw->reg_offset;
>
> return devm_clk_hw_register(dev, &cfg_hw->hw);
> }
> @@ -328,14 +325,13 @@ static int mpfs_clk_register_cfg(struct device *dev, struct mpfs_cfg_hw_clock *c
> static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock *cfg_hws,
> unsigned int num_clks, struct mpfs_clock_data *data)
> {
> - void __iomem *sys_base = data->base;
> unsigned int i, id;
> int ret;
>
> for (i = 0; i < num_clks; i++) {
> struct mpfs_cfg_hw_clock *cfg_hw = &cfg_hws[i];
>
> - ret = mpfs_clk_register_cfg(dev, cfg_hw, sys_base);
> + ret = mpfs_clk_register_cfg(dev, cfg_hw, data->base);
> if (ret)
> return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
> cfg_hw->id);
> @@ -355,15 +351,14 @@ static int mpfs_periph_clk_enable(struct clk_hw *hw)
> {
> struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
> struct mpfs_periph_clock *periph = &periph_hw->periph;
> - void __iomem *base_addr = periph_hw->sys_base;
> u32 reg, val;
> unsigned long flags;
>
> spin_lock_irqsave(&mpfs_clk_lock, flags);
>
> - reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
> + reg = readl_relaxed(periph->reg);
> val = reg | (1u << periph->shift);
> - writel_relaxed(val, base_addr + REG_SUBBLK_CLOCK_CR);
> + writel_relaxed(val, periph->reg);
>
> spin_unlock_irqrestore(&mpfs_clk_lock, flags);
>
> @@ -374,15 +369,14 @@ static void mpfs_periph_clk_disable(struct clk_hw *hw)
> {
> struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
> struct mpfs_periph_clock *periph = &periph_hw->periph;
> - void __iomem *base_addr = periph_hw->sys_base;
> u32 reg, val;
> unsigned long flags;
>
> spin_lock_irqsave(&mpfs_clk_lock, flags);
>
> - reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
> + reg = readl_relaxed(periph->reg);
> val = reg & ~(1u << periph->shift);
> - writel_relaxed(val, base_addr + REG_SUBBLK_CLOCK_CR);
> + writel_relaxed(val, periph->reg);
>
> spin_unlock_irqrestore(&mpfs_clk_lock, flags);
> }
> @@ -391,10 +385,9 @@ static int mpfs_periph_clk_is_enabled(struct clk_hw *hw)
> {
> struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
> struct mpfs_periph_clock *periph = &periph_hw->periph;
> - void __iomem *base_addr = periph_hw->sys_base;
> u32 reg;
>
> - reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
> + reg = readl_relaxed(periph->reg);
> if (reg & (1u << periph->shift))
> return 1;
>
> @@ -462,9 +455,9 @@ static struct mpfs_periph_hw_clock mpfs_periph_clks[] = {
> };
>
> static int mpfs_clk_register_periph(struct device *dev, struct mpfs_periph_hw_clock *periph_hw,
> - void __iomem *sys_base)
> + void __iomem *base)
> {
> - periph_hw->sys_base = sys_base;
> + periph_hw->periph.reg = base + REG_SUBBLK_CLOCK_CR;
>
> return devm_clk_hw_register(dev, &periph_hw->hw);
> }
> @@ -472,14 +465,13 @@ static int mpfs_clk_register_periph(struct device *dev, struct mpfs_periph_hw_cl
> static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_clock *periph_hws,
> int num_clks, struct mpfs_clock_data *data)
> {
> - void __iomem *sys_base = data->base;
> unsigned int i, id;
> int ret;
>
> for (i = 0; i < num_clks; i++) {
> struct mpfs_periph_hw_clock *periph_hw = &periph_hws[i];
>
> - ret = mpfs_clk_register_periph(dev, periph_hw, sys_base);
> + ret = mpfs_clk_register_periph(dev, periph_hw, data->base);
> if (ret)
> return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
> periph_hw->id);
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 10/13] clk: microchip: mpfs: delete 2 line mpfs_clk_register_foo()
2022-08-30 12:52 ` [PATCH v4 10/13] clk: microchip: mpfs: delete 2 line mpfs_clk_register_foo() Conor Dooley
@ 2022-09-08 6:47 ` Claudiu.Beznea
0 siblings, 0 replies; 26+ messages in thread
From: Claudiu.Beznea @ 2022-09-08 6:47 UTC (permalink / raw)
To: Conor.Dooley, mturquette, sboyd, robh+dt, krzysztof.kozlowski+dt,
palmer, Daire.McNamara
Cc: paul.walmsley, aou, linux-clk, devicetree, linux-kernel,
linux-riscv
On 30.08.2022 15:52, Conor Dooley wrote:
> The register functions are now comprised of only a single operation
> each and no longer add anything to the driver. Delete them.
>
> Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
> ---
> drivers/clk/microchip/clk-mpfs.c | 33 ++++++--------------------------
> 1 file changed, 6 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
> index 60e1e82912fe..538cb589d232 100644
> --- a/drivers/clk/microchip/clk-mpfs.c
> +++ b/drivers/clk/microchip/clk-mpfs.c
> @@ -203,14 +203,6 @@ static struct mpfs_msspll_hw_clock mpfs_msspll_clks[] = {
> MSSPLL_FBDIV_WIDTH, 0, REG_MSSPLL_SSCG_2_CR),
> };
>
> -static int mpfs_clk_register_msspll(struct device *dev, struct mpfs_msspll_hw_clock *msspll_hw,
> - void __iomem *base)
> -{
> - msspll_hw->base = base;
> -
> - return devm_clk_hw_register(dev, &msspll_hw->hw);
> -}
> -
> static int mpfs_clk_register_mssplls(struct device *dev, struct mpfs_msspll_hw_clock *msspll_hws,
> unsigned int num_clks, struct mpfs_clock_data *data)
> {
> @@ -220,7 +212,8 @@ static int mpfs_clk_register_mssplls(struct device *dev, struct mpfs_msspll_hw_c
> for (i = 0; i < num_clks; i++) {
> struct mpfs_msspll_hw_clock *msspll_hw = &msspll_hws[i];
>
> - ret = mpfs_clk_register_msspll(dev, msspll_hw, data->msspll_base);
> + msspll_hw->base = data->msspll_base;
> + 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);
> @@ -314,14 +307,6 @@ static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = {
> }
> };
>
> -static int mpfs_clk_register_cfg(struct device *dev, struct mpfs_cfg_hw_clock *cfg_hw,
> - void __iomem *base)
> -{
> - cfg_hw->cfg.reg = base + cfg_hw->reg_offset;
> -
> - return devm_clk_hw_register(dev, &cfg_hw->hw);
> -}
> -
> static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock *cfg_hws,
> unsigned int num_clks, struct mpfs_clock_data *data)
> {
> @@ -331,7 +316,8 @@ static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock *
> for (i = 0; i < num_clks; i++) {
> struct mpfs_cfg_hw_clock *cfg_hw = &cfg_hws[i];
>
> - ret = mpfs_clk_register_cfg(dev, cfg_hw, data->base);
> + cfg_hw->cfg.reg = data->base + cfg_hw->reg_offset;
> + ret = devm_clk_hw_register(dev, &cfg_hw->hw);
> if (ret)
> return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
> cfg_hw->id);
> @@ -454,14 +440,6 @@ static struct mpfs_periph_hw_clock mpfs_periph_clks[] = {
> CLK_PERIPH(CLK_CFM, "clk_periph_cfm", PARENT_CLK(AHB), 29, 0),
> };
>
> -static int mpfs_clk_register_periph(struct device *dev, struct mpfs_periph_hw_clock *periph_hw,
> - void __iomem *base)
> -{
> - periph_hw->periph.reg = base + REG_SUBBLK_CLOCK_CR;
> -
> - return devm_clk_hw_register(dev, &periph_hw->hw);
> -}
> -
> static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_clock *periph_hws,
> int num_clks, struct mpfs_clock_data *data)
> {
> @@ -471,7 +449,8 @@ static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_c
> for (i = 0; i < num_clks; i++) {
> struct mpfs_periph_hw_clock *periph_hw = &periph_hws[i];
>
> - ret = mpfs_clk_register_periph(dev, periph_hw, data->base);
> + periph_hw->periph.reg = data->base + REG_SUBBLK_CLOCK_CR;
> + ret = devm_clk_hw_register(dev, &periph_hw->hw);
> if (ret)
> return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
> periph_hw->id);
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 11/13] clk: microchip: mpfs: convert cfg_clk to clk_divider
2022-08-30 12:52 ` [PATCH v4 11/13] clk: microchip: mpfs: convert cfg_clk to clk_divider Conor Dooley
@ 2022-09-08 6:47 ` Claudiu.Beznea
0 siblings, 0 replies; 26+ messages in thread
From: Claudiu.Beznea @ 2022-09-08 6:47 UTC (permalink / raw)
To: Conor.Dooley, mturquette, sboyd, robh+dt, krzysztof.kozlowski+dt,
palmer, Daire.McNamara
Cc: paul.walmsley, aou, linux-clk, devicetree, linux-kernel,
linux-riscv
On 30.08.2022 15:52, Conor Dooley wrote:
> The cfg_clk struct is now just a redefinition of the clk_divider struct
> with custom implentations of the ops, that implement an extra level of
> redirection. Remove the custom struct and replace it with clk_divider.
>
> Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
> ---
> drivers/clk/microchip/clk-mpfs.c | 78 ++++----------------------------
> 1 file changed, 9 insertions(+), 69 deletions(-)
>
> diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
> index 538cb589d232..88a200e88e54 100644
> --- a/drivers/clk/microchip/clk-mpfs.c
> +++ b/drivers/clk/microchip/clk-mpfs.c
> @@ -51,24 +51,13 @@ struct mpfs_msspll_hw_clock {
>
> #define to_mpfs_msspll_clk(_hw) container_of(_hw, struct mpfs_msspll_hw_clock, hw)
>
> -struct mpfs_cfg_clock {
> - void __iomem *reg;
> - const struct clk_div_table *table;
> - u8 shift;
> - u8 width;
> - u8 flags;
> -};
> -
> struct mpfs_cfg_hw_clock {
> - struct mpfs_cfg_clock cfg;
> - struct clk_hw hw;
> + struct clk_divider cfg;
> struct clk_init_data init;
> unsigned int id;
> u32 reg_offset;
> };
>
> -#define to_mpfs_cfg_clk(_hw) container_of(_hw, struct mpfs_cfg_hw_clock, hw)
> -
> struct mpfs_periph_clock {
> void __iomem *reg;
> u8 shift;
> @@ -228,56 +217,6 @@ static int mpfs_clk_register_mssplls(struct device *dev, struct mpfs_msspll_hw_c
> * "CFG" clocks
> */
>
> -static unsigned long mpfs_cfg_clk_recalc_rate(struct clk_hw *hw, unsigned long prate)
> -{
> - struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
> - struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
> - u32 val;
> -
> - val = readl_relaxed(cfg->reg) >> cfg->shift;
> - val &= clk_div_mask(cfg->width);
> -
> - return divider_recalc_rate(hw, prate, val, cfg->table, cfg->flags, cfg->width);
> -}
> -
> -static long mpfs_cfg_clk_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate)
> -{
> - struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
> - struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
> -
> - return divider_round_rate(hw, rate, prate, cfg->table, cfg->width, 0);
> -}
> -
> -static int mpfs_cfg_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate)
> -{
> - struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
> - struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
> - unsigned long flags;
> - u32 val;
> - int divider_setting;
> -
> - divider_setting = divider_get_val(rate, prate, cfg->table, cfg->width, 0);
> -
> - if (divider_setting < 0)
> - return divider_setting;
> -
> - spin_lock_irqsave(&mpfs_clk_lock, flags);
> - val = readl_relaxed(cfg->reg);
> - val &= ~(clk_div_mask(cfg->width) << cfg_hw->cfg.shift);
> - val |= divider_setting << cfg->shift;
> - writel_relaxed(val, cfg->reg);
> -
> - spin_unlock_irqrestore(&mpfs_clk_lock, flags);
> -
> - return 0;
> -}
> -
> -static const struct clk_ops mpfs_clk_cfg_ops = {
> - .recalc_rate = mpfs_cfg_clk_recalc_rate,
> - .round_rate = mpfs_cfg_clk_round_rate,
> - .set_rate = mpfs_cfg_clk_set_rate,
> -};
> -
> #define CLK_CFG(_id, _name, _parent, _shift, _width, _table, _flags, _offset) { \
> .id = _id, \
> .cfg.shift = _shift, \
> @@ -285,7 +224,8 @@ static const struct clk_ops mpfs_clk_cfg_ops = {
> .cfg.table = _table, \
> .reg_offset = _offset, \
> .cfg.flags = _flags, \
> - .hw.init = CLK_HW_INIT(_name, _parent, &mpfs_clk_cfg_ops, 0), \
> + .cfg.hw.init = CLK_HW_INIT(_name, _parent, &clk_divider_ops, 0), \
> + .cfg.lock = &mpfs_clk_lock, \
> }
>
> static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = {
> @@ -302,8 +242,8 @@ static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = {
> .cfg.table = mpfs_div_rtcref_table,
> .reg_offset = REG_RTC_CLOCK_CR,
> .cfg.flags = CLK_DIVIDER_ONE_BASED,
> - .hw.init =
> - CLK_HW_INIT_PARENTS_DATA("clk_rtcref", mpfs_ext_ref, &mpfs_clk_cfg_ops, 0),
> + .cfg.hw.init =
> + CLK_HW_INIT_PARENTS_DATA("clk_rtcref", mpfs_ext_ref, &clk_divider_ops, 0),
> }
> };
>
> @@ -317,13 +257,13 @@ static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock *
> struct mpfs_cfg_hw_clock *cfg_hw = &cfg_hws[i];
>
> cfg_hw->cfg.reg = data->base + cfg_hw->reg_offset;
> - ret = devm_clk_hw_register(dev, &cfg_hw->hw);
> + ret = devm_clk_hw_register(dev, &cfg_hw->cfg.hw);
> if (ret)
> return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
> cfg_hw->id);
>
> id = cfg_hw->id;
> - data->hw_data.hws[id] = &cfg_hw->hw;
> + data->hw_data.hws[id] = &cfg_hw->cfg.hw;
> }
>
> return 0;
> @@ -393,7 +333,7 @@ static const struct clk_ops mpfs_periph_clk_ops = {
> _flags), \
> }
>
> -#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT].hw)
> +#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT].cfg.hw)
>
> /*
> * Critical clocks:
> @@ -413,7 +353,7 @@ static struct mpfs_periph_hw_clock mpfs_periph_clks[] = {
> CLK_PERIPH(CLK_MAC1, "clk_periph_mac1", PARENT_CLK(AHB), 2, 0),
> CLK_PERIPH(CLK_MMC, "clk_periph_mmc", PARENT_CLK(AHB), 3, 0),
> CLK_PERIPH(CLK_TIMER, "clk_periph_timer",
> - &mpfs_cfg_clks[CLK_RTCREF - RTCREF_OFFSET].hw, 4, 0),
> + &mpfs_cfg_clks[CLK_RTCREF - RTCREF_OFFSET].cfg.hw, 4, 0),
> CLK_PERIPH(CLK_MMUART0, "clk_periph_mmuart0", PARENT_CLK(AHB), 5, CLK_IS_CRITICAL),
> CLK_PERIPH(CLK_MMUART1, "clk_periph_mmuart1", PARENT_CLK(AHB), 6, 0),
> CLK_PERIPH(CLK_MMUART2, "clk_periph_mmuart2", PARENT_CLK(AHB), 7, 0),
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 12/13] clk: microchip: mpfs: convert periph_clk to clk_gate
2022-08-30 12:52 ` [PATCH v4 12/13] clk: microchip: mpfs: convert periph_clk to clk_gate Conor Dooley
@ 2022-09-08 6:47 ` Claudiu.Beznea
0 siblings, 0 replies; 26+ messages in thread
From: Claudiu.Beznea @ 2022-09-08 6:47 UTC (permalink / raw)
To: Conor.Dooley, mturquette, sboyd, robh+dt, krzysztof.kozlowski+dt,
palmer, Daire.McNamara
Cc: paul.walmsley, aou, linux-clk, devicetree, linux-kernel,
linux-riscv
On 30.08.2022 15:52, Conor Dooley wrote:
> With the reset code moved to the recently added reset controller, there
> is no need for custom ops any longer. Remove the custom ops and the
> custom struct by converting to a clk_gate.
>
> Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
> ---
> drivers/clk/microchip/clk-mpfs.c | 72 +++-----------------------------
> 1 file changed, 6 insertions(+), 66 deletions(-)
>
> diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
> index 88a200e88e54..fa46176eb9ca 100644
> --- a/drivers/clk/microchip/clk-mpfs.c
> +++ b/drivers/clk/microchip/clk-mpfs.c
> @@ -58,19 +58,11 @@ struct mpfs_cfg_hw_clock {
> u32 reg_offset;
> };
>
> -struct mpfs_periph_clock {
> - void __iomem *reg;
> - u8 shift;
> -};
> -
> struct mpfs_periph_hw_clock {
> - struct mpfs_periph_clock periph;
> - struct clk_hw hw;
> + struct clk_gate periph;
> unsigned int id;
> };
>
> -#define to_mpfs_periph_clk(_hw) container_of(_hw, struct mpfs_periph_hw_clock, hw)
> -
> /*
> * mpfs_clk_lock prevents anything else from writing to the
> * mpfs clk block while a software locked register is being written.
> @@ -273,64 +265,12 @@ static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock *
> * peripheral clocks - devices connected to axi or ahb buses.
> */
>
> -static int mpfs_periph_clk_enable(struct clk_hw *hw)
> -{
> - struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
> - struct mpfs_periph_clock *periph = &periph_hw->periph;
> - u32 reg, val;
> - unsigned long flags;
> -
> - spin_lock_irqsave(&mpfs_clk_lock, flags);
> -
> - reg = readl_relaxed(periph->reg);
> - val = reg | (1u << periph->shift);
> - writel_relaxed(val, periph->reg);
> -
> - spin_unlock_irqrestore(&mpfs_clk_lock, flags);
> -
> - return 0;
> -}
> -
> -static void mpfs_periph_clk_disable(struct clk_hw *hw)
> -{
> - struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
> - struct mpfs_periph_clock *periph = &periph_hw->periph;
> - u32 reg, val;
> - unsigned long flags;
> -
> - spin_lock_irqsave(&mpfs_clk_lock, flags);
> -
> - reg = readl_relaxed(periph->reg);
> - val = reg & ~(1u << periph->shift);
> - writel_relaxed(val, periph->reg);
> -
> - spin_unlock_irqrestore(&mpfs_clk_lock, flags);
> -}
> -
> -static int mpfs_periph_clk_is_enabled(struct clk_hw *hw)
> -{
> - struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
> - struct mpfs_periph_clock *periph = &periph_hw->periph;
> - u32 reg;
> -
> - reg = readl_relaxed(periph->reg);
> - if (reg & (1u << periph->shift))
> - return 1;
> -
> - return 0;
> -}
> -
> -static const struct clk_ops mpfs_periph_clk_ops = {
> - .enable = mpfs_periph_clk_enable,
> - .disable = mpfs_periph_clk_disable,
> - .is_enabled = mpfs_periph_clk_is_enabled,
> -};
> -
> #define CLK_PERIPH(_id, _name, _parent, _shift, _flags) { \
> .id = _id, \
> - .periph.shift = _shift, \
> - .hw.init = CLK_HW_INIT_HW(_name, _parent, &mpfs_periph_clk_ops, \
> + .periph.bit_idx = _shift, \
> + .periph.hw.init = CLK_HW_INIT_HW(_name, _parent, &clk_gate_ops, \
> _flags), \
> + .periph.lock = &mpfs_clk_lock, \
> }
>
> #define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT].cfg.hw)
> @@ -390,13 +330,13 @@ static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_c
> struct mpfs_periph_hw_clock *periph_hw = &periph_hws[i];
>
> periph_hw->periph.reg = data->base + REG_SUBBLK_CLOCK_CR;
> - ret = devm_clk_hw_register(dev, &periph_hw->hw);
> + ret = devm_clk_hw_register(dev, &periph_hw->periph.hw);
> if (ret)
> return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
> periph_hw->id);
>
> id = periph_hws[i].id;
> - data->hw_data.hws[id] = &periph_hw->hw;
> + data->hw_data.hws[id] = &periph_hw->periph.hw;
> }
>
> return 0;
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 01/13] clk: microchip: mpfs: fix clk_cfg array bounds violation
2022-09-08 6:44 ` Claudiu.Beznea
@ 2022-09-08 6:48 ` Conor.Dooley
2022-09-09 11:01 ` Conor.Dooley
0 siblings, 1 reply; 26+ messages in thread
From: Conor.Dooley @ 2022-09-08 6:48 UTC (permalink / raw)
To: Claudiu.Beznea, mturquette, sboyd, robh+dt,
krzysztof.kozlowski+dt, palmer, Daire.McNamara
Cc: paul.walmsley, aou, linux-clk, devicetree, linux-kernel,
linux-riscv, nathan
On 08/09/2022 07:44, Claudiu Beznea - M18063 wrote:
> On 30.08.2022 15:52, Conor Dooley wrote:
>> Unnoticed in current code, there is an array bounds violation present
>> during clock registration. This seems to fail gracefully in v6.0-rc1,
>> and life carrys on. While converting the driver to use standard clock
>> structs/ops, kernel panics were seen during boot when built with clang:
>>
>> [ 0.581754] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000b1
>> [ 0.591520] Oops [#1]
>> [ 0.594045] Modules linked in:
>> [ 0.597435] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.0.0-rc1-00011-g8e1459cf4eca #1
>> [ 0.606188] Hardware name: Microchip PolarFire-SoC Icicle Kit (DT)
>> [ 0.613012] epc : __clk_register+0x4a6/0x85c
>> [ 0.617759] ra : __clk_register+0x49e/0x85c
>> [ 0.622489] epc : ffffffff803faf7c ra : ffffffff803faf74 sp : ffffffc80400b720
>> [ 0.630466] gp : ffffffff810e93f8 tp : ffffffe77fe60000 t0 : ffffffe77ffb3800
>> [ 0.638443] t1 : 000000000000000a t2 : ffffffffffffffff s0 : ffffffc80400b7c0
>> [ 0.646420] s1 : 0000000000000001 a0 : 0000000000000001 a1 : 0000000000000000
>> [ 0.654396] a2 : 0000000000000001 a3 : 0000000000000000 a4 : 0000000000000000
>> [ 0.662373] a5 : ffffffff803a5810 a6 : 0000000200000022 a7 : 0000000000000006
>> [ 0.670350] s2 : ffffffff81099d48 s3 : ffffffff80d6e28e s4 : 0000000000000028
>> [ 0.678327] s5 : ffffffff810ed3c8 s6 : ffffffff810ed3d0 s7 : ffffffe77ffbc100
>> [ 0.686304] s8 : ffffffe77ffb1540 s9 : ffffffe77ffb1540 s10: 0000000000000008
>> [ 0.694281] s11: 0000000000000000 t3 : 00000000000000c6 t4 : 0000000000000007
>> [ 0.702258] t5 : ffffffff810c78c0 t6 : ffffffe77ff88cd0
>> [ 0.708125] status: 0000000200000120 badaddr: 00000000000000b1 cause: 000000000000000d
>> [ 0.716869] [<ffffffff803fb892>] devm_clk_hw_register+0x62/0xaa
>> [ 0.723420] [<ffffffff80403412>] mpfs_clk_probe+0x1e0/0x244
>>
>> It fails on "clk_periph_timer" - which uses a different parent, that it
>> tries to find using the macro:
>> \#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT].cfg.hw)
>>
>> If parent is RTCREF, so the macro becomes: &mpfs_cfg_clks[33].cfg.hw
>> which is well beyond the end of the array. Amazingly, builds with GCC
>> 11.1 see no problem here, booting correctly and hooking the parent up
>> etc. Builds with clang-15 do not, with the above panic.
>>
>> Drop the macro for the RTCREF and use the array directly to avoid the
>> panic, using a newly added define that brings the index into the valid
>> range.
>>
>> Fixes: 1c6a7ea32b8c ("clk: microchip: mpfs: add RTCREF clock control")
>> CC: Nathan Chancellor <nathan@kernel.org>
>> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
>> ---
>> drivers/clk/microchip/clk-mpfs.c | 5 ++++-
>> 1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
>> index 070c3b896559..9e41f07b3fa6 100644
>> --- a/drivers/clk/microchip/clk-mpfs.c
>> +++ b/drivers/clk/microchip/clk-mpfs.c
>> @@ -27,6 +27,8 @@
>> #define MSSPLL_POSTDIV_WIDTH 0x07u
>> #define MSSPLL_FIXED_DIV 4u
>>
>> +#define RTCREF_OFFSET (CLK_RTCREF - CLK_ENVM)
>> +
>> struct mpfs_clock_data {
>> void __iomem *base;
>> void __iomem *msspll_base;
>> @@ -381,7 +383,8 @@ static struct mpfs_periph_hw_clock mpfs_periph_clks[] = {
>> CLK_PERIPH(CLK_MAC0, "clk_periph_mac0", PARENT_CLK(AHB), 1, 0),
>> CLK_PERIPH(CLK_MAC1, "clk_periph_mac1", PARENT_CLK(AHB), 2, 0),
>> CLK_PERIPH(CLK_MMC, "clk_periph_mmc", PARENT_CLK(AHB), 3, 0),
>> - CLK_PERIPH(CLK_TIMER, "clk_periph_timer", PARENT_CLK(RTCREF), 4, 0),
>> + CLK_PERIPH(CLK_TIMER, "clk_periph_timer",
>> + &mpfs_cfg_clks[CLK_RTCREF - RTCREF_OFFSET].hw, 4, 0),
>
> A personal taste: as clk IDs and clk indexes in mpfs_cfg_clks[] array are
> different thing (ID for clk_periph_timer is already different) and the
> CLK_RTCREF - RTCREF_OFFSET here is in the end CLK_ENVM = 3 maybe easier to
> follow the code would be to add new macros like:
>
> #define CLK_CPU_OFF 0
> #define CLK_AXI_OFF 1
> #define CLK_AHB_OFF 2
> #define CLK_RTCREF_OFF 3
>
> and change the CLK_PARENT() macro something as follows:
>
> #define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT##_OFF].hw)
Sure, but that is out-of-scope for this fix which needs backporting.
>
>> CLK_PERIPH(CLK_MMUART0, "clk_periph_mmuart0", PARENT_CLK(AHB), 5, CLK_IS_CRITICAL),
>> CLK_PERIPH(CLK_MMUART1, "clk_periph_mmuart1", PARENT_CLK(AHB), 6, 0),
>> CLK_PERIPH(CLK_MMUART2, "clk_periph_mmuart2", PARENT_CLK(AHB), 7, 0),
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 01/13] clk: microchip: mpfs: fix clk_cfg array bounds violation
2022-09-08 6:48 ` Conor.Dooley
@ 2022-09-09 11:01 ` Conor.Dooley
0 siblings, 0 replies; 26+ messages in thread
From: Conor.Dooley @ 2022-09-09 11:01 UTC (permalink / raw)
To: Claudiu.Beznea, mturquette, sboyd, robh+dt,
krzysztof.kozlowski+dt, palmer, Daire.McNamara
Cc: paul.walmsley, aou, linux-clk, devicetree, linux-kernel,
linux-riscv, nathan
On 08/09/2022 07:48, Conor Dooley wrote:
> On 08/09/2022 07:44, Claudiu Beznea - M18063 wrote:
>> On 30.08.2022 15:52, Conor Dooley wrote:
>>> Unnoticed in current code, there is an array bounds violation present
>>> during clock registration. This seems to fail gracefully in v6.0-rc1,
>>> and life carrys on. While converting the driver to use standard clock
>>> structs/ops, kernel panics were seen during boot when built with clang:
>>>
>>> [ 0.581754] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000b1
>>> [ 0.591520] Oops [#1]
>>> [ 0.594045] Modules linked in:
>>> [ 0.597435] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.0.0-rc1-00011-g8e1459cf4eca #1
>>> [ 0.606188] Hardware name: Microchip PolarFire-SoC Icicle Kit (DT)
>>> [ 0.613012] epc : __clk_register+0x4a6/0x85c
>>> [ 0.617759] ra : __clk_register+0x49e/0x85c
>>> [ 0.622489] epc : ffffffff803faf7c ra : ffffffff803faf74 sp : ffffffc80400b720
>>> [ 0.630466] gp : ffffffff810e93f8 tp : ffffffe77fe60000 t0 : ffffffe77ffb3800
>>> [ 0.638443] t1 : 000000000000000a t2 : ffffffffffffffff s0 : ffffffc80400b7c0
>>> [ 0.646420] s1 : 0000000000000001 a0 : 0000000000000001 a1 : 0000000000000000
>>> [ 0.654396] a2 : 0000000000000001 a3 : 0000000000000000 a4 : 0000000000000000
>>> [ 0.662373] a5 : ffffffff803a5810 a6 : 0000000200000022 a7 : 0000000000000006
>>> [ 0.670350] s2 : ffffffff81099d48 s3 : ffffffff80d6e28e s4 : 0000000000000028
>>> [ 0.678327] s5 : ffffffff810ed3c8 s6 : ffffffff810ed3d0 s7 : ffffffe77ffbc100
>>> [ 0.686304] s8 : ffffffe77ffb1540 s9 : ffffffe77ffb1540 s10: 0000000000000008
>>> [ 0.694281] s11: 0000000000000000 t3 : 00000000000000c6 t4 : 0000000000000007
>>> [ 0.702258] t5 : ffffffff810c78c0 t6 : ffffffe77ff88cd0
>>> [ 0.708125] status: 0000000200000120 badaddr: 00000000000000b1 cause: 000000000000000d
>>> [ 0.716869] [<ffffffff803fb892>] devm_clk_hw_register+0x62/0xaa
>>> [ 0.723420] [<ffffffff80403412>] mpfs_clk_probe+0x1e0/0x244
>>>
>>> It fails on "clk_periph_timer" - which uses a different parent, that it
>>> tries to find using the macro:
>>> \#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT].cfg.hw)
>>>
>>> If parent is RTCREF, so the macro becomes: &mpfs_cfg_clks[33].cfg.hw
>>> which is well beyond the end of the array. Amazingly, builds with GCC
>>> 11.1 see no problem here, booting correctly and hooking the parent up
>>> etc. Builds with clang-15 do not, with the above panic.
>>>
>>> Drop the macro for the RTCREF and use the array directly to avoid the
>>> panic, using a newly added define that brings the index into the valid
>>> range.
>>>
>>> Fixes: 1c6a7ea32b8c ("clk: microchip: mpfs: add RTCREF clock control")
>>> CC: Nathan Chancellor <nathan@kernel.org>
>>> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
>>> ---
>>> drivers/clk/microchip/clk-mpfs.c | 5 ++++-
>>> 1 file changed, 4 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
>>> index 070c3b896559..9e41f07b3fa6 100644
>>> --- a/drivers/clk/microchip/clk-mpfs.c
>>> +++ b/drivers/clk/microchip/clk-mpfs.c
>>> @@ -27,6 +27,8 @@
>>> #define MSSPLL_POSTDIV_WIDTH 0x07u
>>> #define MSSPLL_FIXED_DIV 4u
>>> +#define RTCREF_OFFSET (CLK_RTCREF - CLK_ENVM)
>>> +
>>> struct mpfs_clock_data {
>>> void __iomem *base;
>>> void __iomem *msspll_base;
>>> @@ -381,7 +383,8 @@ static struct mpfs_periph_hw_clock mpfs_periph_clks[] = {
>>> CLK_PERIPH(CLK_MAC0, "clk_periph_mac0", PARENT_CLK(AHB), 1, 0),
>>> CLK_PERIPH(CLK_MAC1, "clk_periph_mac1", PARENT_CLK(AHB), 2, 0),
>>> CLK_PERIPH(CLK_MMC, "clk_periph_mmc", PARENT_CLK(AHB), 3, 0),
>>> - CLK_PERIPH(CLK_TIMER, "clk_periph_timer", PARENT_CLK(RTCREF), 4, 0),
>>> + CLK_PERIPH(CLK_TIMER, "clk_periph_timer",
>>> + &mpfs_cfg_clks[CLK_RTCREF - RTCREF_OFFSET].hw, 4, 0),
>>
>> A personal taste: as clk IDs and clk indexes in mpfs_cfg_clks[] array are
>> different thing (ID for clk_periph_timer is already different) and the
>> CLK_RTCREF - RTCREF_OFFSET here is in the end CLK_ENVM = 3 maybe easier to
>> follow the code would be to add new macros like:
>>
>> #define CLK_CPU_OFF 0
>> #define CLK_AXI_OFF 1
>> #define CLK_AHB_OFF 2
>> #define CLK_RTCREF_OFF 3
>>
>> and change the CLK_PARENT() macro something as follows:
>>
>> #define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT##_OFF].hw)
>
> Sure, but that is out-of-scope for this fix which needs backporting.
I think I mis-interpreted your suggestion. Gonna give it a go & unless
clang screams and yells at me I think I like it more than relying on
the relationships between the binding numbers.
Thanks,
Conor.
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2022-09-09 11:02 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-08-30 12:50 [PATCH v4 00/13] PolarFire SoC reset controller & clock cleanups Conor Dooley
2022-08-30 12:52 ` [PATCH v4 01/13] clk: microchip: mpfs: fix clk_cfg array bounds violation Conor Dooley
2022-08-31 17:03 ` Conor.Dooley
2022-09-08 6:44 ` Claudiu.Beznea
2022-09-08 6:48 ` Conor.Dooley
2022-09-09 11:01 ` Conor.Dooley
2022-08-30 12:52 ` [PATCH v4 02/13] dt-bindings: clk: microchip: mpfs: add reset controller support Conor Dooley
2022-08-30 12:52 ` [PATCH v4 03/13] clk: microchip: mpfs: add reset controller Conor Dooley
2022-09-08 6:45 ` Claudiu.Beznea
2022-08-30 12:52 ` [PATCH v4 04/13] reset: add polarfire soc reset support Conor Dooley
2022-09-08 6:44 ` Claudiu.Beznea
2022-08-30 12:52 ` [PATCH v4 05/13] MAINTAINERS: add polarfire soc reset controller Conor Dooley
2022-08-30 12:52 ` [PATCH v4 06/13] riscv: dts: microchip: add mpfs specific macb reset support Conor Dooley
2022-08-30 12:52 ` [PATCH v4 07/13] clk: microchip: mpfs: add MSS pll's set & round rate Conor Dooley
2022-09-08 6:46 ` Claudiu.Beznea
2022-08-30 12:52 ` [PATCH v4 08/13] clk: microchip: mpfs: move id & offset out of clock structs Conor Dooley
2022-09-08 6:46 ` Claudiu.Beznea
2022-08-30 12:52 ` [PATCH v4 09/13] clk: microchip: mpfs: simplify control reg access Conor Dooley
2022-09-08 6:46 ` Claudiu.Beznea
2022-08-30 12:52 ` [PATCH v4 10/13] clk: microchip: mpfs: delete 2 line mpfs_clk_register_foo() Conor Dooley
2022-09-08 6:47 ` Claudiu.Beznea
2022-08-30 12:52 ` [PATCH v4 11/13] clk: microchip: mpfs: convert cfg_clk to clk_divider Conor Dooley
2022-09-08 6:47 ` Claudiu.Beznea
2022-08-30 12:52 ` [PATCH v4 12/13] clk: microchip: mpfs: convert periph_clk to clk_gate Conor Dooley
2022-09-08 6:47 ` Claudiu.Beznea
2022-08-30 12:52 ` [PATCH v4 13/13] clk: microchip: mpfs: update module authorship & licencing Conor Dooley
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).