2020-11-01 19:24:35

by Michael Walle

[permalink] [raw]
Subject: [PATCH 1/4] dt-bindings: clock: document the fsl-flexspi-clk driver

Signed-off-by: Michael Walle <[email protected]>
---
.../bindings/clock/fsl,flexspi-clock.yaml | 55 +++++++++++++++++++
1 file changed, 55 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/fsl,flexspi-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/fsl,flexspi-clock.yaml b/Documentation/devicetree/bindings/clock/fsl,flexspi-clock.yaml
new file mode 100644
index 000000000000..1fa390ee7b9b
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/fsl,flexspi-clock.yaml
@@ -0,0 +1,55 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/fsl,flexspi-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale FlexSPI clock driver for Layerscape SoCs
+
+maintainers:
+ - Michael Walle <[email protected]>
+
+description:
+ The Freescale Layerscape SoCs have a special FlexSPI clock which is
+ derived from the platform PLL.
+
+properties:
+ compatible:
+ enum:
+ - fsl,ls1028a-flexspi-clk
+ - fsl,lx2160a-flexspi-clk
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ '#clock-cells':
+ const: 0
+
+ clock-output-names:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ dcfg {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ fspi_clk: clock-controller@900 {
+ compatible = "fsl,ls1028a-flexspi-clk";
+ reg = <0x900 0x4>;
+ #clock-cells = <0>;
+ clocks = <&parentclk>;
+ clock-output-names = "fspi_clk";
+ };
+ };
--
2.20.1


2020-11-01 19:24:35

by Michael Walle

[permalink] [raw]
Subject: [PATCH 3/4] arm64: dts: ls1028a: fix FlexSPI clock

Now that we have a proper driver for the FlexSPI interface use it. This
will fix SCK frequency switching on Layerscape SoCs.

This was tested on the Kontron sl28 board.

Signed-off-by: Michael Walle <[email protected]>
---
arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
index f223396b8266..ee88bf60f9a9 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
@@ -197,9 +197,20 @@
};

dcfg: syscon@1e00000 {
- compatible = "fsl,ls1028a-dcfg", "syscon";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,ls1028a-dcfg", "syscon", "simple-mfd";
reg = <0x0 0x1e00000 0x0 0x10000>;
+ ranges = <0x0 0x0 0x1e00000 0x10000>;
little-endian;
+
+ fspi_clk: clock-controller@900 {
+ compatible = "fsl,ls1028a-flexspi-clk";
+ reg = <0x900 0x4>;
+ #clock-cells = <0>;
+ clocks = <&clockgen 4 0>;
+ clock-output-names = "fspi_clk";
+ };
};

rst: syscon@1e60000 {
@@ -309,7 +320,7 @@
<0x0 0x20000000 0x0 0x10000000>;
reg-names = "fspi_base", "fspi_mmap";
interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+ clocks = <&clockgen 4 3>, <&fspi_clk>;
clock-names = "fspi_en", "fspi";
status = "disabled";
};
--
2.20.1

2020-11-01 19:24:35

by Michael Walle

[permalink] [raw]
Subject: [PATCH 4/4] arm64: dts: lx2160a: fix FlexSPI clock

Now that we have a proper driver for the FlexSPI interface use it. This
will fix SCK frequency switching on Layerscape SoCs.

This was only compile time tested.

Signed-off-by: Michael Walle <[email protected]>
---
arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
index 83072da6f6c6..6e375e80bd35 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
@@ -659,9 +659,20 @@
};

dcfg: syscon@1e00000 {
- compatible = "fsl,lx2160a-dcfg", "syscon";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,lx2160a-dcfg", "syscon", "simple-mfd";
reg = <0x0 0x1e00000 0x0 0x10000>;
+ ranges = <0x0 0x0 0x1e00000 0x10000>;
little-endian;
+
+ fspi_clk: clock-controller@900 {
+ compatible = "fsl,lx2160a-flexspi-clk";
+ reg = <0x900 0x4>;
+ #clock-cells = <0>;
+ clocks = <&clockgen 4 0>;
+ clock-output-names = "fspi_clk";
+ };
};

tmu: tmu@1f80000 {
@@ -776,7 +787,7 @@
<0x0 0x20000000 0x0 0x10000000>;
reg-names = "fspi_base", "fspi_mmap";
interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+ clocks = <&clockgen 4 3>, <&fspi_clk>;
clock-names = "fspi_en", "fspi";
status = "disabled";
};
--
2.20.1

2020-11-01 19:27:09

by Michael Walle

[permalink] [raw]
Subject: [PATCH 2/4] clk: fsl-flexspi: new driver

Add support for the FlexSPI clock on Freescale Layerscape SoCs. The
clock is a simple divider based one and is located inside the device
configuration space (DCFG).

This will allow switching the SCK frequencies for the FlexSPI interface
on the LS1028A and the LX2160A.

Signed-off-by: Michael Walle <[email protected]>
---
drivers/clk/Kconfig | 8 +++
drivers/clk/Makefile | 1 +
drivers/clk/clk-fsl-flexspi.c | 118 ++++++++++++++++++++++++++++++++++
3 files changed, 127 insertions(+)
create mode 100644 drivers/clk/clk-fsl-flexspi.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index c715d4681a0b..0066f5af9e77 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -188,6 +188,14 @@ config COMMON_CLK_CS2000_CP
help
If you say yes here you get support for the CS2000 clock multiplier.

+config COMMON_CLK_FSL_FLEXSPI
+ tristate "Clock driver for FlexSPI on Layerscape SoCs"
+ depends on ARCH_LAYERSCAPE || COMPILE_TEST
+ default ARCH_LAYERSCAPE && SPI_NXP_FLEXSPI
+ help
+ On Layerscape SoCs there is a special clock for the FlexSPI
+ interface.
+
config COMMON_CLK_FSL_SAI
bool "Clock driver for BCLK of Freescale SAI cores"
depends on ARCH_LAYERSCAPE || COMPILE_TEST
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index da8fcf147eb1..dbdc590e7de3 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o
obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
obj-$(CONFIG_ARCH_SPARX5) += clk-sparx5.o
obj-$(CONFIG_COMMON_CLK_FIXED_MMIO) += clk-fixed-mmio.o
+obj-$(CONFIG_COMMON_CLK_FSL_FLEXSPI) += clk-fsl-flexspi.o
obj-$(CONFIG_COMMON_CLK_FSL_SAI) += clk-fsl-sai.o
obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o
obj-$(CONFIG_COMMON_CLK_ASPEED) += clk-aspeed.o
diff --git a/drivers/clk/clk-fsl-flexspi.c b/drivers/clk/clk-fsl-flexspi.c
new file mode 100644
index 000000000000..9d26268917e7
--- /dev/null
+++ b/drivers/clk/clk-fsl-flexspi.c
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Layerscape FlexSPI clock driver
+ *
+ * Copyright 2020 Michael Walle <[email protected]>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+static const struct clk_div_table ls1028a_flexspi_divs[] = {
+ { .val = 0, .div = 1, },
+ { .val = 1, .div = 2, },
+ { .val = 2, .div = 3, },
+ { .val = 3, .div = 4, },
+ { .val = 4, .div = 5, },
+ { .val = 5, .div = 6, },
+ { .val = 6, .div = 7, },
+ { .val = 7, .div = 8, },
+ { .val = 11, .div = 12, },
+ { .val = 15, .div = 16, },
+ { .val = 16, .div = 20, },
+ { .val = 17, .div = 24, },
+ { .val = 18, .div = 28, },
+ { .val = 19, .div = 32, },
+ { .val = 20, .div = 80, },
+ {}
+};
+
+static const struct clk_div_table lx2160a_flexspi_divs[] = {
+ { .val = 1, .div = 2, },
+ { .val = 3, .div = 4, },
+ { .val = 5, .div = 6, },
+ { .val = 7, .div = 8, },
+ { .val = 11, .div = 12, },
+ { .val = 15, .div = 16, },
+ { .val = 16, .div = 20, },
+ { .val = 17, .div = 24, },
+ { .val = 18, .div = 28, },
+ { .val = 19, .div = 32, },
+ { .val = 20, .div = 80, },
+ {}
+};
+
+static int fsl_flexspi_clk_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ const char *clk_name = np->name;
+ const char *clk_parent;
+ struct resource *res;
+ void __iomem *reg;
+ struct clk_hw *hw;
+ const struct clk_div_table *divs;
+
+ divs = device_get_match_data(dev);
+ if (!divs)
+ return -ENOENT;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENOENT;
+
+ /*
+ * Can't use devm_ioremap_resource() or devm_of_iomap() because the
+ * resource might already be taken by the parent device.
+ */
+ reg = devm_ioremap(dev, res->start, resource_size(res));
+ if (!reg)
+ return -ENOMEM;
+
+ clk_parent = of_clk_get_parent_name(np, 0);
+ if (!clk_parent)
+ return -EINVAL;
+
+ of_property_read_string(np, "clock-output-names", &clk_name);
+
+ hw = clk_hw_register_divider_table(dev, clk_name, clk_parent, 0,
+ reg, 0, 5, 0, divs, NULL);
+ if (IS_ERR(hw))
+ return PTR_ERR(hw);
+
+ platform_set_drvdata(pdev, hw);
+
+ return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
+}
+
+static int fsl_flexspi_clk_remove(struct platform_device *pdev)
+{
+ struct clk_hw *hw = platform_get_drvdata(pdev);
+
+ clk_hw_unregister_divider(hw);
+
+ return 0;
+}
+
+static const struct of_device_id fsl_flexspi_clk_dt_ids[] = {
+ { .compatible = "fsl,ls1028a-flexspi-clk", .data = &ls1028a_flexspi_divs },
+ { .compatible = "fsl,lx2160a-flexspi-clk", .data = &lx2160a_flexspi_divs },
+ {}
+};
+
+static struct platform_driver fsl_flexspi_clk_driver = {
+ .driver = {
+ .name = "fsl-flexspi-clk",
+ .of_match_table = fsl_flexspi_clk_dt_ids,
+ },
+ .probe = fsl_flexspi_clk_probe,
+ .remove = fsl_flexspi_clk_remove,
+};
+module_platform_driver(fsl_flexspi_clk_driver);
+
+MODULE_DESCRIPTION("FlexSPI clock driver for Layerscape SoCs");
+MODULE_AUTHOR("Michael Walle <[email protected]>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:fsl-flexspi-clk");
--
2.20.1

2020-11-01 19:29:03

by Michael Walle

[permalink] [raw]
Subject: Re: [PATCH 1/4] dt-bindings: clock: document the fsl-flexspi-clk driver

Hi,

Sorry, I've forgot the cover letter. Next version will have one.

On Layerscape SoCs which feature the FlexSPI controller there is
a single register which can control the divider value. The base
frequency is the platform PLL.

Right now the LS1028A and the LX2160A aren't able to switch the
SCK frequency on the FlexSPI interface. Add a new clock driver
which operate on said register.

-michael

2020-11-04 22:39:31

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH 1/4] dt-bindings: clock: document the fsl-flexspi-clk driver

On Sun, 01 Nov 2020 20:20:50 +0100, Michael Walle wrote:
> Signed-off-by: Michael Walle <[email protected]>
> ---
> .../bindings/clock/fsl,flexspi-clock.yaml | 55 +++++++++++++++++++
> 1 file changed, 55 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/clock/fsl,flexspi-clock.yaml
>

Reviewed-by: Rob Herring <[email protected]>