linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/10] Adding support for Microchip Sparx5 SoC
@ 2020-06-15 13:32 Lars Povlsen
  2020-06-15 13:32 ` [PATCH v3 01/10] dt-bindings: arm: sparx5: Add documentation " Lars Povlsen
                   ` (10 more replies)
  0 siblings, 11 replies; 20+ messages in thread
From: Lars Povlsen @ 2020-06-15 13:32 UTC (permalink / raw)
  To: SoC Team, Arnd Bergmann, Stephen Boyd, Linus Walleij
  Cc: Lars Povlsen, Steen Hegelund, Microchip Linux Driver Support,
	Olof Johansson, Michael Turquette, devicetree, linux-clk,
	linux-gpio, linux-arm-kernel, linux-kernel, Alexandre Belloni

This patch series adds support for Microchip Sparx5 SoC, the CPU
system of a advanced, TSN capable gigabit switch. The CPU is an armv8
x 2 CPU core (A53).

Although this is an ARM core, it shares some peripherals with the
Microsemi Ocelot MIPS SoC.

Changes in v3:
- a "gpio-restart" node has been added to the pcb134/pcb135 DT files.
- pinctrl-ocelot.c: ENOTSUPP replaced by EOPNOTSUPP. Fixed non-static
  ocelot_pinconf_set(), Fixed ocelot_hw_get_value() not returning proper
  read value.
- Rebased on v5.8-rc1

Changes in v2:
- Misc fixes to bindings/arm/microchip,sparx5.yaml
- Changed clock driver to platform driver, using bitfields, recalc
  properly implented, using proper clock parent.
- arch/arm64/boot/dts/microchip/sparx5.dtsi:
 - Added pmu and psci node, using PSCI
 - Updates to GICv3 register spaces (GICV/GICH)
 - Updated timer interrupt specifiers
- pinctrl: ocelot: Fixed symbol clashes from powerpc

Lars Povlsen (10):
  dt-bindings: arm: sparx5: Add documentation for Microchip Sparx5 SoC
  arm64: sparx5: Add support for Microchip 2xA53 SoC
  arm64: dts: sparx5: Add basic cpu support
  arm64: dts: sparx5: Add pinctrl support
  pinctrl: ocelot: Add Sparx5 SoC support
  dt-bindings: clock: sparx5: Add Sparx5 SoC DPLL clock
  dt-bindings: clock: sparx5: Add bindings include file
  clk: sparx5: Add Sparx5 SoC DPLL clock driver
  arm64: dts: sparx5: Add Sparx5 SoC DPLL clock
  arm64: dts: sparx5: Add i2c devices, i2c muxes

 .../bindings/arm/microchip,sparx5.yaml        |  65 +++
 .../bindings/clock/microchip,sparx5-dpll.yaml |  52 +++
 .../devicetree/bindings/mfd/syscon.yaml       |   1 +
 MAINTAINERS                                   |   9 +
 arch/arm64/Kconfig.platforms                  |  14 +
 arch/arm64/boot/dts/Makefile                  |   1 +
 arch/arm64/boot/dts/microchip/Makefile        |   4 +
 arch/arm64/boot/dts/microchip/sparx5.dtsi     | 213 +++++++++
 .../boot/dts/microchip/sparx5_pcb125.dts      |  21 +
 .../boot/dts/microchip/sparx5_pcb134.dts      |  17 +
 .../dts/microchip/sparx5_pcb134_board.dtsi    | 252 ++++++++++
 .../boot/dts/microchip/sparx5_pcb134_emmc.dts |  17 +
 .../boot/dts/microchip/sparx5_pcb135.dts      |  17 +
 .../dts/microchip/sparx5_pcb135_board.dtsi    |  92 ++++
 .../boot/dts/microchip/sparx5_pcb135_emmc.dts |  17 +
 .../boot/dts/microchip/sparx5_pcb_common.dtsi |  19 +
 drivers/clk/Makefile                          |   1 +
 drivers/clk/clk-sparx5.c                      | 312 +++++++++++++
 drivers/pinctrl/pinctrl-ocelot.c              | 430 +++++++++++++++++-
 include/dt-bindings/clock/microchip,sparx5.h  |  23 +
 20 files changed, 1576 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/arm/microchip,sparx5.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/microchip,sparx5-dpll.yaml
 create mode 100644 arch/arm64/boot/dts/microchip/Makefile
 create mode 100644 arch/arm64/boot/dts/microchip/sparx5.dtsi
 create mode 100644 arch/arm64/boot/dts/microchip/sparx5_pcb125.dts
 create mode 100644 arch/arm64/boot/dts/microchip/sparx5_pcb134.dts
 create mode 100644 arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi
 create mode 100644 arch/arm64/boot/dts/microchip/sparx5_pcb134_emmc.dts
 create mode 100644 arch/arm64/boot/dts/microchip/sparx5_pcb135.dts
 create mode 100644 arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi
 create mode 100644 arch/arm64/boot/dts/microchip/sparx5_pcb135_emmc.dts
 create mode 100644 arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi
 create mode 100644 drivers/clk/clk-sparx5.c
 create mode 100644 include/dt-bindings/clock/microchip,sparx5.h

-- 
2.27.0


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

* [PATCH v3 01/10] dt-bindings: arm: sparx5: Add documentation for Microchip Sparx5 SoC
  2020-06-15 13:32 [PATCH v3 00/10] Adding support for Microchip Sparx5 SoC Lars Povlsen
@ 2020-06-15 13:32 ` Lars Povlsen
  2020-07-13 18:40   ` Rob Herring
  2020-06-15 13:32 ` [PATCH v3 02/10] arm64: sparx5: Add support for Microchip 2xA53 SoC Lars Povlsen
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Lars Povlsen @ 2020-06-15 13:32 UTC (permalink / raw)
  To: SoC Team, Arnd Bergmann, Stephen Boyd, Linus Walleij, Rob Herring
  Cc: Lars Povlsen, Steen Hegelund, Microchip Linux Driver Support,
	Olof Johansson, Michael Turquette, devicetree, linux-clk,
	linux-gpio, linux-arm-kernel, linux-kernel, Alexandre Belloni

This adds the main Sparx5 SoC DT documentation file, with information
abut the supported board types.

Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>
---
 .../bindings/arm/microchip,sparx5.yaml        | 65 +++++++++++++++++++
 .../devicetree/bindings/mfd/syscon.yaml       |  1 +
 2 files changed, 66 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/microchip,sparx5.yaml

diff --git a/Documentation/devicetree/bindings/arm/microchip,sparx5.yaml b/Documentation/devicetree/bindings/arm/microchip,sparx5.yaml
new file mode 100644
index 0000000000000..ecf6fa12e6ad2
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/microchip,sparx5.yaml
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/microchip,sparx5.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip Sparx5 Boards Device Tree Bindings
+
+maintainers:
+  - Lars Povlsen <lars.povlsen@microchip.com>
+
+description: |+
+   The Microchip Sparx5 SoC is a ARMv8-based used in a family of
+   gigabit TSN-capable gigabit switches.
+
+   The SparX-5 Ethernet switch family provides a rich set of switching
+   features such as advanced TCAM-based VLAN and QoS processing
+   enabling delivery of differentiated services, and security through
+   TCAM-based frame processing using versatile content aware processor
+   (VCAP)
+
+properties:
+  $nodename:
+    const: '/'
+  compatible:
+    oneOf:
+      - description: The Sparx5 pcb125 board is a modular board,
+          which has both spi-nor and eMMC storage. The modular design
+          allows for connection of different network ports.
+        items:
+          - const: microchip,sparx5-pcb125
+          - const: microchip,sparx5
+
+      - description: The Sparx5 pcb134 is a pizzabox form factor
+          gigabit switch with 20 SFP ports. It features spi-nor and
+          either spi-nand or eMMC storage (mount option).
+        items:
+          - const: microchip,sparx5-pcb134
+          - const: microchip,sparx5
+
+      - description: The Sparx5 pcb135 is a pizzabox form factor
+          gigabit switch with 48+4 Cu ports. It features spi-nor and
+          either spi-nand or eMMC storage (mount option).
+        items:
+          - const: microchip,sparx5-pcb135
+          - const: microchip,sparx5
+
+  axi@600000000:
+    type: object
+    description: the root node in the Sparx5 platforms must contain
+      an axi bus child node. They are always at physical address
+      0x600000000 in all the Sparx5 variants.
+    properties:
+      compatible:
+        items:
+          - const: simple-bus
+
+    required:
+      - compatible
+
+required:
+  - compatible
+  - axi@600000000
+
+...
diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
index 19bdaf781853b..f3fba860d3cc5 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
@@ -38,6 +38,7 @@ properties:
               - allwinner,sun8i-h3-system-controller
               - allwinner,sun8i-v3s-system-controller
               - allwinner,sun50i-a64-system-controller
+              - microchip,sparx5-cpu-syscon
 
           - const: syscon
 
-- 
2.27.0


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

* [PATCH v3 02/10] arm64: sparx5: Add support for Microchip 2xA53 SoC
  2020-06-15 13:32 [PATCH v3 00/10] Adding support for Microchip Sparx5 SoC Lars Povlsen
  2020-06-15 13:32 ` [PATCH v3 01/10] dt-bindings: arm: sparx5: Add documentation " Lars Povlsen
@ 2020-06-15 13:32 ` Lars Povlsen
  2020-06-15 13:32 ` [PATCH v3 03/10] arm64: dts: sparx5: Add basic cpu support Lars Povlsen
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Lars Povlsen @ 2020-06-15 13:32 UTC (permalink / raw)
  To: SoC Team, Arnd Bergmann, Stephen Boyd, Linus Walleij
  Cc: Lars Povlsen, Steen Hegelund, Microchip Linux Driver Support,
	Olof Johansson, Michael Turquette, devicetree, linux-clk,
	linux-gpio, linux-arm-kernel, linux-kernel, Alexandre Belloni

This adds support for the Microchip Sparx5 ARMv8-based SoC family of
TSN-capable gigabit switches.

Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>
---
 MAINTAINERS                  |  8 ++++++++
 arch/arm64/Kconfig.platforms | 14 ++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 68f21d46614c4..13553b77ed4f7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2111,6 +2111,14 @@ X:	drivers/net/wireless/atmel/
 N:	at91
 N:	atmel
 
+ARM/Microchip Sparx5 SoC support
+M:	Lars Povlsen <lars.povlsen@microchip.com>
+M:	Steen Hegelund <Steen.Hegelund@microchip.com>
+M:	Microchip Linux Driver Support <UNGLinuxDriver@microchip.com>
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:	Supported
+N:	sparx5
+
 ARM/MIOA701 MACHINE SUPPORT
 M:	Robert Jarzmik <robert.jarzmik@free.fr>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 8dd05b2a925c5..8939e4e6e34c2 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -89,6 +89,20 @@ config ARCH_EXYNOS
 	help
 	  This enables support for ARMv8 based Samsung Exynos SoC family.
 
+config ARCH_SPARX5
+	bool "ARMv8 based Microchip Sparx5 SoC family"
+	select PINCTRL
+	select DW_APB_TIMER_OF
+	help
+	  This enables support for the Microchip Sparx5 ARMv8-based
+	  SoC family of TSN-capable gigabit switches.
+
+	  The SparX-5 Ethernet switch family provides a rich set of
+	  switching features such as advanced TCAM-based VLAN and QoS
+	  processing enabling delivery of differentiated services, and
+	  security through TCAM-based frame processing using versatile
+	  content aware processor (VCAP).
+
 config ARCH_K3
 	bool "Texas Instruments Inc. K3 multicore SoC architecture"
 	select PM_GENERIC_DOMAINS if PM
-- 
2.27.0


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

* [PATCH v3 03/10] arm64: dts: sparx5: Add basic cpu support
  2020-06-15 13:32 [PATCH v3 00/10] Adding support for Microchip Sparx5 SoC Lars Povlsen
  2020-06-15 13:32 ` [PATCH v3 01/10] dt-bindings: arm: sparx5: Add documentation " Lars Povlsen
  2020-06-15 13:32 ` [PATCH v3 02/10] arm64: sparx5: Add support for Microchip 2xA53 SoC Lars Povlsen
@ 2020-06-15 13:32 ` Lars Povlsen
  2020-06-15 13:32 ` [PATCH v3 04/10] arm64: dts: sparx5: Add pinctrl support Lars Povlsen
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Lars Povlsen @ 2020-06-15 13:32 UTC (permalink / raw)
  To: SoC Team, Arnd Bergmann, Stephen Boyd, Linus Walleij
  Cc: Lars Povlsen, Steen Hegelund, Microchip Linux Driver Support,
	Olof Johansson, Michael Turquette, devicetree, linux-clk,
	linux-gpio, linux-arm-kernel, linux-kernel, Alexandre Belloni

This adds the basic DT structure for the Microchip Sparx5 SoC, and the
reference boards, pcb125, pcb134 and pcb135. The two latter have a
NAND vs a eMMC centric variant (as a mount option).

Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>
---
 MAINTAINERS                                   |   1 +
 arch/arm64/boot/dts/Makefile                  |   1 +
 arch/arm64/boot/dts/microchip/Makefile        |   4 +
 arch/arm64/boot/dts/microchip/sparx5.dtsi     | 142 ++++++++++++++++++
 .../boot/dts/microchip/sparx5_pcb125.dts      |  17 +++
 .../boot/dts/microchip/sparx5_pcb134.dts      |  17 +++
 .../dts/microchip/sparx5_pcb134_board.dtsi    |  10 ++
 .../boot/dts/microchip/sparx5_pcb134_emmc.dts |  17 +++
 .../boot/dts/microchip/sparx5_pcb135.dts      |  17 +++
 .../dts/microchip/sparx5_pcb135_board.dtsi    |  10 ++
 .../boot/dts/microchip/sparx5_pcb135_emmc.dts |  17 +++
 .../boot/dts/microchip/sparx5_pcb_common.dtsi |  15 ++
 12 files changed, 268 insertions(+)
 create mode 100644 arch/arm64/boot/dts/microchip/Makefile
 create mode 100644 arch/arm64/boot/dts/microchip/sparx5.dtsi
 create mode 100644 arch/arm64/boot/dts/microchip/sparx5_pcb125.dts
 create mode 100644 arch/arm64/boot/dts/microchip/sparx5_pcb134.dts
 create mode 100644 arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi
 create mode 100644 arch/arm64/boot/dts/microchip/sparx5_pcb134_emmc.dts
 create mode 100644 arch/arm64/boot/dts/microchip/sparx5_pcb135.dts
 create mode 100644 arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi
 create mode 100644 arch/arm64/boot/dts/microchip/sparx5_pcb135_emmc.dts
 create mode 100644 arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi

diff --git a/MAINTAINERS b/MAINTAINERS
index 13553b77ed4f7..20056e369e9e4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2117,6 +2117,7 @@ M:	Steen Hegelund <Steen.Hegelund@microchip.com>
 M:	Microchip Linux Driver Support <UNGLinuxDriver@microchip.com>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Supported
+F:	arch/arm64/boot/dts/microchip/
 N:	sparx5
 
 ARM/MIOA701 MACHINE SUPPORT
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index f19b762c008d8..9680a7f20c307 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -17,6 +17,7 @@ subdir-y += intel
 subdir-y += lg
 subdir-y += marvell
 subdir-y += mediatek
+subdir-y += microchip
 subdir-y += nvidia
 subdir-y += qcom
 subdir-y += realtek
diff --git a/arch/arm64/boot/dts/microchip/Makefile b/arch/arm64/boot/dts/microchip/Makefile
new file mode 100644
index 0000000000000..c6e0313eea0f9
--- /dev/null
+++ b/arch/arm64/boot/dts/microchip/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_SPARX5) += sparx5_pcb125.dtb
+dtb-$(CONFIG_ARCH_SPARX5) += sparx5_pcb134.dtb sparx5_pcb134_emmc.dtb
+dtb-$(CONFIG_ARCH_SPARX5) += sparx5_pcb135.dtb sparx5_pcb135_emmc.dtb
diff --git a/arch/arm64/boot/dts/microchip/sparx5.dtsi b/arch/arm64/boot/dts/microchip/sparx5.dtsi
new file mode 100644
index 0000000000000..4a54b7d039167
--- /dev/null
+++ b/arch/arm64/boot/dts/microchip/sparx5.dtsi
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2020 Microchip Technology Inc. and its subsidiaries.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	compatible = "microchip,sparx5";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <1>;
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+				core1 {
+					cpu = <&cpu1>;
+				};
+			};
+		};
+		cpu0: cpu@0 {
+			compatible = "arm,cortex-a53";
+			device_type = "cpu";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			next-level-cache = <&L2_0>;
+		};
+		cpu1: cpu@1 {
+			compatible = "arm,cortex-a53";
+			device_type = "cpu";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			next-level-cache = <&L2_0>;
+		};
+		L2_0: l2-cache0 {
+			compatible = "cache";
+		};
+	};
+
+	arm-pmu {
+		compatible = "arm,cortex-a53-pmu";
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>, <&cpu1>;
+	};
+
+	psci {
+		compatible = "arm,psci-0.2";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	clocks: clocks {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges;
+		ahb_clk: ahb-clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <250000000>;
+		};
+		sys_clk: sys-clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <625000000>;
+		};
+	};
+
+	axi: axi@600000000 {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges;
+
+		gic: interrupt-controller@600300000 {
+			compatible = "arm,gic-v3";
+			#interrupt-cells = <3>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			interrupt-controller;
+			reg = <0x6 0x00300000 0x10000>,	/* GIC Dist */
+			      <0x6 0x00340000 0xc0000>,	/* GICR */
+			      <0x6 0x00200000 0x2000>,	/* GICC */
+			      <0x6 0x00210000 0x2000>,  /* GICV */
+			      <0x6 0x00220000 0x2000>;  /* GICH */
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		uart0: serial@600100000 {
+			compatible = "ns16550a";
+			reg = <0x6 0x00100000 0x20>;
+			clocks = <&ahb_clk>;
+			reg-io-width = <4>;
+			reg-shift = <2>;
+			interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+
+			status = "disabled";
+		};
+
+		uart1: serial@600102000 {
+			compatible = "ns16550a";
+			reg = <0x6 0x00102000 0x20>;
+			clocks = <&ahb_clk>;
+			reg-io-width = <4>;
+			reg-shift = <2>;
+			interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+
+			status = "disabled";
+		};
+
+		timer1: timer@600105000 {
+			compatible = "snps,dw-apb-timer";
+			reg = <0x6 0x00105000 0x1000>;
+			clocks = <&ahb_clk>;
+			clock-names = "timer";
+			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+	};
+};
diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb125.dts b/arch/arm64/boot/dts/microchip/sparx5_pcb125.dts
new file mode 100644
index 0000000000000..d7f985f7ee020
--- /dev/null
+++ b/arch/arm64/boot/dts/microchip/sparx5_pcb125.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2020 Microchip Technology Inc. and its subsidiaries.
+ */
+
+/dts-v1/;
+#include "sparx5_pcb_common.dtsi"
+
+/ {
+	model = "Sparx5 PCB125 Reference Board";
+	compatible = "microchip,sparx5-pcb125", "microchip,sparx5";
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x00000000 0x00000000 0x10000000>;
+	};
+};
diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb134.dts b/arch/arm64/boot/dts/microchip/sparx5_pcb134.dts
new file mode 100644
index 0000000000000..feee4e99ff57c
--- /dev/null
+++ b/arch/arm64/boot/dts/microchip/sparx5_pcb134.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2020 Microchip Technology Inc. and its subsidiaries.
+ */
+
+/dts-v1/;
+#include "sparx5_pcb134_board.dtsi"
+
+/ {
+	model = "Sparx5 PCB134 Reference Board (NAND)";
+	compatible = "microchip,sparx5-pcb134", "microchip,sparx5";
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x00000000 0x00000000 0x10000000>;
+	};
+};
diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi b/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi
new file mode 100644
index 0000000000000..005cf6babb9b3
--- /dev/null
+++ b/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2020 Microchip Technology Inc. and its subsidiaries.
+ */
+
+/dts-v1/;
+#include "sparx5_pcb_common.dtsi"
+
+/{
+};
diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb134_emmc.dts b/arch/arm64/boot/dts/microchip/sparx5_pcb134_emmc.dts
new file mode 100644
index 0000000000000..10081a66961bb
--- /dev/null
+++ b/arch/arm64/boot/dts/microchip/sparx5_pcb134_emmc.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2020 Microchip Technology Inc. and its subsidiaries.
+ */
+
+/dts-v1/;
+#include "sparx5_pcb134_board.dtsi"
+
+/ {
+	model = "Sparx5 PCB134 Reference Board (eMMC enabled)";
+	compatible = "microchip,sparx5-pcb134", "microchip,sparx5";
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x00000000 0x00000000 0x10000000>;
+	};
+};
diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb135.dts b/arch/arm64/boot/dts/microchip/sparx5_pcb135.dts
new file mode 100644
index 0000000000000..20e409a9be196
--- /dev/null
+++ b/arch/arm64/boot/dts/microchip/sparx5_pcb135.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2020 Microchip Technology Inc. and its subsidiaries.
+ */
+
+/dts-v1/;
+#include "sparx5_pcb135_board.dtsi"
+
+/ {
+	model = "Sparx5 PCB135 Reference Board (NAND)";
+	compatible = "microchip,sparx5-pcb135", "microchip,sparx5";
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x00000000 0x00000000 0x10000000>;
+	};
+};
diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi b/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi
new file mode 100644
index 0000000000000..005cf6babb9b3
--- /dev/null
+++ b/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2020 Microchip Technology Inc. and its subsidiaries.
+ */
+
+/dts-v1/;
+#include "sparx5_pcb_common.dtsi"
+
+/{
+};
diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb135_emmc.dts b/arch/arm64/boot/dts/microchip/sparx5_pcb135_emmc.dts
new file mode 100644
index 0000000000000..741f0e12260e5
--- /dev/null
+++ b/arch/arm64/boot/dts/microchip/sparx5_pcb135_emmc.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2020 Microchip Technology Inc. and its subsidiaries.
+ */
+
+/dts-v1/;
+#include "sparx5_pcb135_board.dtsi"
+
+/ {
+	model = "Sparx5 PCB135 Reference Board (eMMC enabled)";
+	compatible = "microchip,sparx5-pcb135", "microchip,sparx5";
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x00000000 0x00000000 0x10000000>;
+	};
+};
diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi b/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi
new file mode 100644
index 0000000000000..1f99d0db1284f
--- /dev/null
+++ b/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2020 Microchip Technology Inc. and its subsidiaries.
+ */
+
+/dts-v1/;
+#include "sparx5.dtsi"
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
-- 
2.27.0


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

* [PATCH v3 04/10] arm64: dts: sparx5: Add pinctrl support
  2020-06-15 13:32 [PATCH v3 00/10] Adding support for Microchip Sparx5 SoC Lars Povlsen
                   ` (2 preceding siblings ...)
  2020-06-15 13:32 ` [PATCH v3 03/10] arm64: dts: sparx5: Add basic cpu support Lars Povlsen
@ 2020-06-15 13:32 ` Lars Povlsen
  2020-06-15 13:32 ` [PATCH v3 05/10] pinctrl: ocelot: Add Sparx5 SoC support Lars Povlsen
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Lars Povlsen @ 2020-06-15 13:32 UTC (permalink / raw)
  To: SoC Team, Arnd Bergmann, Stephen Boyd, Linus Walleij
  Cc: Lars Povlsen, Steen Hegelund, Microchip Linux Driver Support,
	Olof Johansson, Michael Turquette, devicetree, linux-clk,
	linux-gpio, linux-arm-kernel, linux-kernel, Alexandre Belloni

This add pinctrl support to the Microchip Sparx5 SoC.

Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>
---
 arch/arm64/boot/dts/microchip/sparx5.dtsi     | 26 +++++++++++++++++++
 .../dts/microchip/sparx5_pcb134_board.dtsi    |  5 ++++
 .../dts/microchip/sparx5_pcb135_board.dtsi    |  5 ++++
 3 files changed, 36 insertions(+)

diff --git a/arch/arm64/boot/dts/microchip/sparx5.dtsi b/arch/arm64/boot/dts/microchip/sparx5.dtsi
index 4a54b7d039167..baf4176ce1dfe 100644
--- a/arch/arm64/boot/dts/microchip/sparx5.dtsi
+++ b/arch/arm64/boot/dts/microchip/sparx5.dtsi
@@ -109,6 +109,8 @@ gic: interrupt-controller@600300000 {
 		};
 
 		uart0: serial@600100000 {
+			pinctrl-0 = <&uart_pins>;
+			pinctrl-names = "default";
 			compatible = "ns16550a";
 			reg = <0x6 0x00100000 0x20>;
 			clocks = <&ahb_clk>;
@@ -120,6 +122,8 @@ uart0: serial@600100000 {
 		};
 
 		uart1: serial@600102000 {
+			pinctrl-0 = <&uart2_pins>;
+			pinctrl-names = "default";
 			compatible = "ns16550a";
 			reg = <0x6 0x00102000 0x20>;
 			clocks = <&ahb_clk>;
@@ -138,5 +142,27 @@ timer1: timer@600105000 {
 			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		gpio: pinctrl@6110101e0 {
+			compatible = "microchip,sparx5-pinctrl";
+			reg = <0x6 0x110101e0 0x90>, <0x6 0x10508010 0x100>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&gpio 0 0 64>;
+			interrupt-controller;
+			interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+			#interrupt-cells = <2>;
+
+			uart_pins: uart-pins {
+				pins = "GPIO_10", "GPIO_11";
+				function = "uart";
+			};
+
+			uart2_pins: uart2-pins {
+				pins = "GPIO_26", "GPIO_27";
+				function = "uart2";
+			};
+
+		};
+
 	};
 };
diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi b/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi
index 005cf6babb9b3..9b2aec400101b 100644
--- a/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi
+++ b/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi
@@ -7,4 +7,9 @@
 #include "sparx5_pcb_common.dtsi"
 
 /{
+	gpio-restart {
+		compatible = "gpio-restart";
+		gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+		priority = <200>;
+	};
 };
diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi b/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi
index 005cf6babb9b3..9b2aec400101b 100644
--- a/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi
+++ b/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi
@@ -7,4 +7,9 @@
 #include "sparx5_pcb_common.dtsi"
 
 /{
+	gpio-restart {
+		compatible = "gpio-restart";
+		gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+		priority = <200>;
+	};
 };
-- 
2.27.0


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

* [PATCH v3 05/10] pinctrl: ocelot: Add Sparx5 SoC support
  2020-06-15 13:32 [PATCH v3 00/10] Adding support for Microchip Sparx5 SoC Lars Povlsen
                   ` (3 preceding siblings ...)
  2020-06-15 13:32 ` [PATCH v3 04/10] arm64: dts: sparx5: Add pinctrl support Lars Povlsen
@ 2020-06-15 13:32 ` Lars Povlsen
  2020-06-20 21:10   ` Linus Walleij
  2020-07-07 11:58   ` Linus Walleij
  2020-06-15 13:32 ` [PATCH v3 06/10] dt-bindings: clock: sparx5: Add Sparx5 SoC DPLL clock Lars Povlsen
                   ` (5 subsequent siblings)
  10 siblings, 2 replies; 20+ messages in thread
From: Lars Povlsen @ 2020-06-15 13:32 UTC (permalink / raw)
  To: SoC Team, Arnd Bergmann, Stephen Boyd, Linus Walleij
  Cc: Lars Povlsen, Steen Hegelund, Microchip Linux Driver Support,
	Olof Johansson, Michael Turquette, devicetree, linux-clk,
	linux-gpio, linux-arm-kernel, linux-kernel, Alexandre Belloni

This add support for Sparx5 pinctrl, using the ocelot drives as
basis. It adds pinconfig support as well, as supported by the
platform.

Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>
---
 drivers/pinctrl/pinctrl-ocelot.c | 430 ++++++++++++++++++++++++++++++-
 1 file changed, 429 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c
index 95c225bc7572f..425a3d764f009 100644
--- a/drivers/pinctrl/pinctrl-ocelot.c
+++ b/drivers/pinctrl/pinctrl-ocelot.c
@@ -25,6 +25,23 @@
 #include "pinconf.h"
 #include "pinmux.h"
 
+#define ocelot_clrsetbits(addr, clear, set) \
+	writel((readl(addr) & ~(clear)) | (set), (addr))
+
+/* PINCONFIG bits (sparx5 only) */
+enum {
+	PINCONF_BIAS,
+	PINCONF_SCHMITT,
+	PINCONF_DRIVE_STRENGTH,
+};
+
+#define BIAS_PD_BIT BIT(4)
+#define BIAS_PU_BIT BIT(3)
+#define BIAS_BITS   (BIAS_PD_BIT|BIAS_PU_BIT)
+#define SCHMITT_BIT BIT(2)
+#define DRIVE_BITS  GENMASK(1, 0)
+
+/* GPIO standard registers */
 #define OCELOT_GPIO_OUT_SET	0x0
 #define OCELOT_GPIO_OUT_CLR	0x4
 #define OCELOT_GPIO_OUT		0x8
@@ -42,12 +59,17 @@
 enum {
 	FUNC_NONE,
 	FUNC_GPIO,
+	FUNC_IRQ0,
 	FUNC_IRQ0_IN,
 	FUNC_IRQ0_OUT,
+	FUNC_IRQ1,
 	FUNC_IRQ1_IN,
 	FUNC_IRQ1_OUT,
+	FUNC_EXT_IRQ,
 	FUNC_MIIM,
+	FUNC_PHY_LED,
 	FUNC_PCI_WAKE,
+	FUNC_MD,
 	FUNC_PTP0,
 	FUNC_PTP1,
 	FUNC_PTP2,
@@ -59,24 +81,36 @@ enum {
 	FUNC_SG1,
 	FUNC_SG2,
 	FUNC_SI,
+	FUNC_SI2,
 	FUNC_TACHO,
 	FUNC_TWI,
 	FUNC_TWI2,
+	FUNC_TWI3,
 	FUNC_TWI_SCL_M,
 	FUNC_UART,
 	FUNC_UART2,
+	FUNC_UART3,
+	FUNC_PLL_STAT,
+	FUNC_EMMC,
+	FUNC_REF_CLK,
+	FUNC_RCVRD_CLK,
 	FUNC_MAX
 };
 
 static const char *const ocelot_function_names[] = {
 	[FUNC_NONE]		= "none",
 	[FUNC_GPIO]		= "gpio",
+	[FUNC_IRQ0]		= "irq0",
 	[FUNC_IRQ0_IN]		= "irq0_in",
 	[FUNC_IRQ0_OUT]		= "irq0_out",
+	[FUNC_IRQ1]		= "irq1",
 	[FUNC_IRQ1_IN]		= "irq1_in",
 	[FUNC_IRQ1_OUT]		= "irq1_out",
+	[FUNC_EXT_IRQ]		= "ext_irq",
 	[FUNC_MIIM]		= "miim",
+	[FUNC_PHY_LED]		= "phy_led",
 	[FUNC_PCI_WAKE]		= "pci_wake",
+	[FUNC_MD]		= "md",
 	[FUNC_PTP0]		= "ptp0",
 	[FUNC_PTP1]		= "ptp1",
 	[FUNC_PTP2]		= "ptp2",
@@ -88,12 +122,19 @@ static const char *const ocelot_function_names[] = {
 	[FUNC_SG1]		= "sg1",
 	[FUNC_SG2]		= "sg2",
 	[FUNC_SI]		= "si",
+	[FUNC_SI2]		= "si2",
 	[FUNC_TACHO]		= "tacho",
 	[FUNC_TWI]		= "twi",
 	[FUNC_TWI2]		= "twi2",
+	[FUNC_TWI3]		= "twi3",
 	[FUNC_TWI_SCL_M]	= "twi_scl_m",
 	[FUNC_UART]		= "uart",
 	[FUNC_UART2]		= "uart2",
+	[FUNC_UART3]		= "uart3",
+	[FUNC_PLL_STAT]		= "pll_stat",
+	[FUNC_EMMC]		= "emmc",
+	[FUNC_REF_CLK]		= "ref_clk",
+	[FUNC_RCVRD_CLK]	= "rcvrd_clk",
 };
 
 struct ocelot_pmx_func {
@@ -111,6 +152,7 @@ struct ocelot_pinctrl {
 	struct pinctrl_dev *pctl;
 	struct gpio_chip gpio_chip;
 	struct regmap *map;
+	void __iomem *pincfg;
 	struct pinctrl_desc *desc;
 	struct ocelot_pmx_func func[FUNC_MAX];
 	u8 stride;
@@ -324,6 +366,152 @@ static const struct pinctrl_pin_desc jaguar2_pins[] = {
 	JAGUAR2_PIN(63),
 };
 
+#define SPARX5_P(p, f0, f1, f2)					\
+static struct ocelot_pin_caps sparx5_pin_##p = {			\
+	.pin = p,							\
+	.functions = {							\
+		FUNC_GPIO, FUNC_##f0, FUNC_##f1, FUNC_##f2		\
+	},								\
+}
+
+SPARX5_P(0,  SG0,       PLL_STAT,  NONE);
+SPARX5_P(1,  SG0,       NONE,      NONE);
+SPARX5_P(2,  SG0,       NONE,      NONE);
+SPARX5_P(3,  SG0,       NONE,      NONE);
+SPARX5_P(4,  SG1,       NONE,      NONE);
+SPARX5_P(5,  SG1,       NONE,      NONE);
+SPARX5_P(6,  IRQ0_IN,   IRQ0_OUT,  SFP);
+SPARX5_P(7,  IRQ1_IN,   IRQ1_OUT,  SFP);
+SPARX5_P(8,  PTP0,      NONE,      SFP);
+SPARX5_P(9,  PTP1,      SFP,       TWI_SCL_M);
+SPARX5_P(10, UART,      NONE,      NONE);
+SPARX5_P(11, UART,      NONE,      NONE);
+SPARX5_P(12, SG1,       NONE,      NONE);
+SPARX5_P(13, SG1,       NONE,      NONE);
+SPARX5_P(14, TWI,       TWI_SCL_M, NONE);
+SPARX5_P(15, TWI,       NONE,      NONE);
+SPARX5_P(16, SI,        TWI_SCL_M, SFP);
+SPARX5_P(17, SI,        TWI_SCL_M, SFP);
+SPARX5_P(18, SI,        TWI_SCL_M, SFP);
+SPARX5_P(19, PCI_WAKE,  TWI_SCL_M, SFP);
+SPARX5_P(20, IRQ0_OUT,  TWI_SCL_M, SFP);
+SPARX5_P(21, IRQ1_OUT,  TACHO,     SFP);
+SPARX5_P(22, TACHO,     IRQ0_OUT,  TWI_SCL_M);
+SPARX5_P(23, PWM,       UART3,     TWI_SCL_M);
+SPARX5_P(24, PTP2,      UART3,     TWI_SCL_M);
+SPARX5_P(25, PTP3,      SI,        TWI_SCL_M);
+SPARX5_P(26, UART2,     SI,        TWI_SCL_M);
+SPARX5_P(27, UART2,     SI,        TWI_SCL_M);
+SPARX5_P(28, TWI2,      SI,        SFP);
+SPARX5_P(29, TWI2,      SI,        SFP);
+SPARX5_P(30, SG2,       SI,        PWM);
+SPARX5_P(31, SG2,       SI,        TWI_SCL_M);
+SPARX5_P(32, SG2,       SI,        TWI_SCL_M);
+SPARX5_P(33, SG2,       SI,        SFP);
+SPARX5_P(34, NONE,      TWI_SCL_M, EMMC);
+SPARX5_P(35, SFP,       TWI_SCL_M, EMMC);
+SPARX5_P(36, SFP,       TWI_SCL_M, EMMC);
+SPARX5_P(37, SFP,       NONE,      EMMC);
+SPARX5_P(38, NONE,      TWI_SCL_M, EMMC);
+SPARX5_P(39, SI2,       TWI_SCL_M, EMMC);
+SPARX5_P(40, SI2,       TWI_SCL_M, EMMC);
+SPARX5_P(41, SI2,       TWI_SCL_M, EMMC);
+SPARX5_P(42, SI2,       TWI_SCL_M, EMMC);
+SPARX5_P(43, SI2,       TWI_SCL_M, EMMC);
+SPARX5_P(44, SI,        SFP,       EMMC);
+SPARX5_P(45, SI,        SFP,       EMMC);
+SPARX5_P(46, NONE,      SFP,       EMMC);
+SPARX5_P(47, NONE,      SFP,       EMMC);
+SPARX5_P(48, TWI3,      SI,        SFP);
+SPARX5_P(49, TWI3,      NONE,      SFP);
+SPARX5_P(50, SFP,       NONE,      TWI_SCL_M);
+SPARX5_P(51, SFP,       SI,        TWI_SCL_M);
+SPARX5_P(52, SFP,       MIIM,      TWI_SCL_M);
+SPARX5_P(53, SFP,       MIIM,      TWI_SCL_M);
+SPARX5_P(54, SFP,       PTP2,      TWI_SCL_M);
+SPARX5_P(55, SFP,       PTP3,      PCI_WAKE);
+SPARX5_P(56, MIIM,      SFP,       TWI_SCL_M);
+SPARX5_P(57, MIIM,      SFP,       TWI_SCL_M);
+SPARX5_P(58, MIIM,      SFP,       TWI_SCL_M);
+SPARX5_P(59, MIIM,      SFP,       NONE);
+SPARX5_P(60, RECO_CLK,  NONE,      NONE);
+SPARX5_P(61, RECO_CLK,  NONE,      NONE);
+SPARX5_P(62, RECO_CLK,  PLL_STAT,  NONE);
+SPARX5_P(63, RECO_CLK,  NONE,      NONE);
+
+#define SPARX5_PIN(n) {					\
+	.number = n,						\
+	.name = "GPIO_"#n,					\
+	.drv_data = &sparx5_pin_##n				\
+}
+
+static const struct pinctrl_pin_desc sparx5_pins[] = {
+	SPARX5_PIN(0),
+	SPARX5_PIN(1),
+	SPARX5_PIN(2),
+	SPARX5_PIN(3),
+	SPARX5_PIN(4),
+	SPARX5_PIN(5),
+	SPARX5_PIN(6),
+	SPARX5_PIN(7),
+	SPARX5_PIN(8),
+	SPARX5_PIN(9),
+	SPARX5_PIN(10),
+	SPARX5_PIN(11),
+	SPARX5_PIN(12),
+	SPARX5_PIN(13),
+	SPARX5_PIN(14),
+	SPARX5_PIN(15),
+	SPARX5_PIN(16),
+	SPARX5_PIN(17),
+	SPARX5_PIN(18),
+	SPARX5_PIN(19),
+	SPARX5_PIN(20),
+	SPARX5_PIN(21),
+	SPARX5_PIN(22),
+	SPARX5_PIN(23),
+	SPARX5_PIN(24),
+	SPARX5_PIN(25),
+	SPARX5_PIN(26),
+	SPARX5_PIN(27),
+	SPARX5_PIN(28),
+	SPARX5_PIN(29),
+	SPARX5_PIN(30),
+	SPARX5_PIN(31),
+	SPARX5_PIN(32),
+	SPARX5_PIN(33),
+	SPARX5_PIN(34),
+	SPARX5_PIN(35),
+	SPARX5_PIN(36),
+	SPARX5_PIN(37),
+	SPARX5_PIN(38),
+	SPARX5_PIN(39),
+	SPARX5_PIN(40),
+	SPARX5_PIN(41),
+	SPARX5_PIN(42),
+	SPARX5_PIN(43),
+	SPARX5_PIN(44),
+	SPARX5_PIN(45),
+	SPARX5_PIN(46),
+	SPARX5_PIN(47),
+	SPARX5_PIN(48),
+	SPARX5_PIN(49),
+	SPARX5_PIN(50),
+	SPARX5_PIN(51),
+	SPARX5_PIN(52),
+	SPARX5_PIN(53),
+	SPARX5_PIN(54),
+	SPARX5_PIN(55),
+	SPARX5_PIN(56),
+	SPARX5_PIN(57),
+	SPARX5_PIN(58),
+	SPARX5_PIN(59),
+	SPARX5_PIN(60),
+	SPARX5_PIN(61),
+	SPARX5_PIN(62),
+	SPARX5_PIN(63),
+};
+
 static int ocelot_get_functions_count(struct pinctrl_dev *pctldev)
 {
 	return ARRAY_SIZE(ocelot_function_names);
@@ -382,6 +570,7 @@ static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev,
 	 * ALT[1]
 	 * This is racy because both registers can't be updated at the same time
 	 * but it doesn't matter much for now.
+	 * Note: ALT0/ALT1 are organized specially for 64 gpio targets
 	 */
 	regmap_update_bits(info->map, REG_ALT(0, info, pin->pin),
 			   BIT(p), f << p);
@@ -458,6 +647,219 @@ static int ocelot_pctl_get_group_pins(struct pinctrl_dev *pctldev,
 	return 0;
 }
 
+static int ocelot_hw_get_value(struct ocelot_pinctrl *info,
+			       unsigned int pin,
+			       unsigned int reg,
+			       int *val)
+{
+	int ret = -EOPNOTSUPP;
+
+	if (info->pincfg) {
+		u32 regcfg = readl(info->pincfg + (pin * sizeof(u32)));
+
+		ret = 0;
+		switch (reg) {
+		case PINCONF_BIAS:
+			*val = regcfg & BIAS_BITS;
+			break;
+
+		case PINCONF_SCHMITT:
+			*val = regcfg & SCHMITT_BIT;
+			break;
+
+		case PINCONF_DRIVE_STRENGTH:
+			*val = regcfg & DRIVE_BITS;
+			break;
+
+		default:
+			ret = -EOPNOTSUPP;
+			break;
+		}
+	}
+	return ret;
+}
+
+static int ocelot_hw_set_value(struct ocelot_pinctrl *info,
+			       unsigned int pin,
+			       unsigned int reg,
+			       int val)
+{
+	int ret = -EOPNOTSUPP;
+
+	if (info->pincfg) {
+		void __iomem *regaddr = info->pincfg + (pin * sizeof(u32));
+
+		ret = 0;
+		switch (reg) {
+		case PINCONF_BIAS:
+			ocelot_clrsetbits(regaddr, BIAS_BITS, val);
+			break;
+
+		case PINCONF_SCHMITT:
+			ocelot_clrsetbits(regaddr, SCHMITT_BIT, val);
+			break;
+
+		case PINCONF_DRIVE_STRENGTH:
+			if (val <= 3)
+				ocelot_clrsetbits(regaddr, DRIVE_BITS, val);
+			else
+				ret = -EINVAL;
+			break;
+
+		default:
+			ret = -EOPNOTSUPP;
+			break;
+		}
+	}
+	return ret;
+}
+
+static int ocelot_pinconf_get(struct pinctrl_dev *pctldev,
+			      unsigned int pin, unsigned long *config)
+{
+	struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	u32 param = pinconf_to_config_param(*config);
+	int val, err;
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+	case PIN_CONFIG_BIAS_PULL_UP:
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		err = ocelot_hw_get_value(info, pin, PINCONF_BIAS, &val);
+		if (err)
+			return err;
+		if (param == PIN_CONFIG_BIAS_DISABLE)
+			val = (val == 0 ? true : false);
+		else if (param == PIN_CONFIG_BIAS_PULL_DOWN)
+			val = (val & BIAS_PD_BIT ? true : false);
+		else    /* PIN_CONFIG_BIAS_PULL_UP */
+			val = (val & BIAS_PU_BIT ? true : false);
+		break;
+
+	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+		err = ocelot_hw_get_value(info, pin, PINCONF_SCHMITT, &val);
+		if (err)
+			return err;
+
+		val = (val & SCHMITT_BIT ? true : false);
+		break;
+
+	case PIN_CONFIG_DRIVE_STRENGTH:
+		err = ocelot_hw_get_value(info, pin, PINCONF_DRIVE_STRENGTH,
+					  &val);
+		if (err)
+			return err;
+		break;
+
+	case PIN_CONFIG_OUTPUT:
+		err = regmap_read(info->map, REG(OCELOT_GPIO_OUT, info, pin),
+				  &val);
+		if (err)
+			return err;
+		val = !!(val & BIT(pin % 32));
+		break;
+
+	case PIN_CONFIG_INPUT_ENABLE:
+	case PIN_CONFIG_OUTPUT_ENABLE:
+		err = regmap_read(info->map, REG(OCELOT_GPIO_OE, info, pin),
+				  &val);
+		if (err)
+			return err;
+		val = val & BIT(pin % 32);
+		if (param == PIN_CONFIG_OUTPUT_ENABLE)
+			val = !!val;
+		else
+			val = !val;
+		break;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	*config = pinconf_to_config_packed(param, val);
+
+	return 0;
+}
+
+static int ocelot_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+			      unsigned long *configs, unsigned int num_configs)
+{
+	struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	u32 param, arg, p;
+	int cfg, err = 0;
+
+	for (cfg = 0; cfg < num_configs; cfg++) {
+		param = pinconf_to_config_param(configs[cfg]);
+		arg = pinconf_to_config_argument(configs[cfg]);
+
+		switch (param) {
+		case PIN_CONFIG_BIAS_DISABLE:
+		case PIN_CONFIG_BIAS_PULL_UP:
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			arg = (param == PIN_CONFIG_BIAS_DISABLE) ? 0 :
+			(param == PIN_CONFIG_BIAS_PULL_UP) ? BIAS_PU_BIT :
+			BIAS_PD_BIT;
+
+			err = ocelot_hw_set_value(info, pin, PINCONF_BIAS, arg);
+			if (err)
+				goto err;
+
+			break;
+
+		case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+			arg = arg ? SCHMITT_BIT : 0;
+			err = ocelot_hw_set_value(info, pin, PINCONF_SCHMITT,
+						  arg);
+			if (err)
+				goto err;
+
+			break;
+
+		case PIN_CONFIG_DRIVE_STRENGTH:
+			err = ocelot_hw_set_value(info, pin,
+						  PINCONF_DRIVE_STRENGTH,
+						  arg);
+			if (err)
+				goto err;
+
+			break;
+
+		case PIN_CONFIG_OUTPUT_ENABLE:
+		case PIN_CONFIG_INPUT_ENABLE:
+		case PIN_CONFIG_OUTPUT:
+			p = pin % 32;
+			if (arg)
+				regmap_write(info->map,
+					     REG(OCELOT_GPIO_OUT_SET, info,
+						 pin),
+					     BIT(p));
+			else
+				regmap_write(info->map,
+					     REG(OCELOT_GPIO_OUT_CLR, info,
+						 pin),
+					     BIT(p));
+			regmap_update_bits(info->map,
+					   REG(OCELOT_GPIO_OE, info, pin),
+					   BIT(p),
+					   param == PIN_CONFIG_INPUT_ENABLE ?
+					   0 : BIT(p));
+			break;
+
+		default:
+			err = -EOPNOTSUPP;
+		}
+	}
+err:
+	return err;
+}
+
+static const struct pinconf_ops ocelot_confops = {
+	.is_generic = true,
+	.pin_config_get = ocelot_pinconf_get,
+	.pin_config_set = ocelot_pinconf_set,
+	.pin_config_config_dbg_show = pinconf_generic_dump_config,
+};
+
 static const struct pinctrl_ops ocelot_pctl_ops = {
 	.get_groups_count = ocelot_pctl_get_groups_count,
 	.get_group_name = ocelot_pctl_get_group_name,
@@ -484,6 +886,16 @@ static struct pinctrl_desc jaguar2_desc = {
 	.owner = THIS_MODULE,
 };
 
+static struct pinctrl_desc sparx5_desc = {
+	.name = "sparx5-pinctrl",
+	.pins = sparx5_pins,
+	.npins = ARRAY_SIZE(sparx5_pins),
+	.pctlops = &ocelot_pctl_ops,
+	.pmxops = &ocelot_pmx_ops,
+	.confops = &ocelot_confops,
+	.owner = THIS_MODULE,
+};
+
 static int ocelot_create_group_func_map(struct device *dev,
 					struct ocelot_pinctrl *info)
 {
@@ -511,7 +923,8 @@ static int ocelot_create_group_func_map(struct device *dev,
 		}
 
 		for (i = 0; i < npins; i++)
-			info->func[f].groups[i] = info->desc->pins[pins[i]].name;
+			info->func[f].groups[i] =
+				info->desc->pins[pins[i]].name;
 	}
 
 	kfree(pins);
@@ -744,6 +1157,7 @@ static int ocelot_gpiochip_register(struct platform_device *pdev,
 static const struct of_device_id ocelot_pinctrl_of_match[] = {
 	{ .compatible = "mscc,ocelot-pinctrl", .data = &ocelot_desc },
 	{ .compatible = "mscc,jaguar2-pinctrl", .data = &jaguar2_desc },
+	{ .compatible = "microchip,sparx5-pinctrl", .data = &sparx5_desc },
 	{},
 };
 
@@ -752,6 +1166,7 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct ocelot_pinctrl *info;
 	void __iomem *base;
+	struct resource *res;
 	int ret;
 	struct regmap_config regmap_config = {
 		.reg_bits = 32,
@@ -773,6 +1188,7 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
 	}
 
 	info->stride = 1 + (info->desc->npins - 1) / 32;
+
 	regmap_config.max_register = OCELOT_GPIO_SD_MAP * info->stride + 15 * 4;
 
 	info->map = devm_regmap_init_mmio(dev, base, &regmap_config);
@@ -783,6 +1199,16 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
 	dev_set_drvdata(dev, info->map);
 	info->dev = dev;
 
+	/* Pinconf registers */
+	if (info->desc->confops) {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+		base = devm_ioremap_resource(dev, res);
+		if (IS_ERR(base))
+			dev_dbg(dev, "Failed to ioremap config registers (no extended pinconf)\n");
+		else
+			info->pincfg = base;
+	}
+
 	ret = ocelot_pinctrl_register(pdev, info);
 	if (ret)
 		return ret;
@@ -791,6 +1217,8 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	dev_info(dev, "driver registered\n");
+
 	return 0;
 }
 
-- 
2.27.0


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

* [PATCH v3 06/10] dt-bindings: clock: sparx5: Add Sparx5 SoC DPLL clock
  2020-06-15 13:32 [PATCH v3 00/10] Adding support for Microchip Sparx5 SoC Lars Povlsen
                   ` (4 preceding siblings ...)
  2020-06-15 13:32 ` [PATCH v3 05/10] pinctrl: ocelot: Add Sparx5 SoC support Lars Povlsen
@ 2020-06-15 13:32 ` Lars Povlsen
  2020-07-13 18:41   ` Rob Herring
  2020-06-15 13:32 ` [PATCH v3 07/10] dt-bindings: clock: sparx5: Add bindings include file Lars Povlsen
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Lars Povlsen @ 2020-06-15 13:32 UTC (permalink / raw)
  To: SoC Team, Arnd Bergmann, Stephen Boyd, Linus Walleij, Rob Herring
  Cc: Lars Povlsen, Steen Hegelund, Microchip Linux Driver Support,
	Olof Johansson, Michael Turquette, devicetree, linux-clk,
	linux-gpio, linux-arm-kernel, linux-kernel, Alexandre Belloni

This add the DT bindings documentation for the Sparx5 SoC DPLL clock

Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>
---
 .../bindings/clock/microchip,sparx5-dpll.yaml | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/microchip,sparx5-dpll.yaml

diff --git a/Documentation/devicetree/bindings/clock/microchip,sparx5-dpll.yaml b/Documentation/devicetree/bindings/clock/microchip,sparx5-dpll.yaml
new file mode 100644
index 0000000000000..39559a0a598ad
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/microchip,sparx5-dpll.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/microchip,sparx5-dpll.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip Sparx5 DPLL Clock
+
+maintainers:
+  - Lars Povlsen <lars.povlsen@microchip.com>
+
+description: |
+  The Sparx5 DPLL clock controller generates and supplies clock to
+  various peripherals within the SoC.
+
+properties:
+  compatible:
+    const: microchip,sparx5-dpll
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+  # Clock provider for eMMC:
+  - |
+    lcpll_clk: lcpll-clk {
+        compatible = "fixed-clock";
+        #clock-cells = <0>;
+        clock-frequency = <2500000000>;
+    };
+    clks: clock-controller@61110000c {
+        compatible = "microchip,sparx5-dpll";
+        #clock-cells = <1>;
+        clocks = <&lcpll_clk>;
+        reg = <0x1110000c 0x24>;
+    };
+
+...
-- 
2.27.0


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

* [PATCH v3 07/10] dt-bindings: clock: sparx5: Add bindings include file
  2020-06-15 13:32 [PATCH v3 00/10] Adding support for Microchip Sparx5 SoC Lars Povlsen
                   ` (5 preceding siblings ...)
  2020-06-15 13:32 ` [PATCH v3 06/10] dt-bindings: clock: sparx5: Add Sparx5 SoC DPLL clock Lars Povlsen
@ 2020-06-15 13:32 ` Lars Povlsen
  2020-07-13 18:41   ` Rob Herring
  2020-06-15 13:32 ` [PATCH v3 08/10] clk: sparx5: Add Sparx5 SoC DPLL clock driver Lars Povlsen
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Lars Povlsen @ 2020-06-15 13:32 UTC (permalink / raw)
  To: SoC Team, Arnd Bergmann, Stephen Boyd, Linus Walleij, Rob Herring
  Cc: Lars Povlsen, Steen Hegelund, Microchip Linux Driver Support,
	Olof Johansson, Michael Turquette, devicetree, linux-clk,
	linux-gpio, linux-arm-kernel, linux-kernel, Alexandre Belloni

The Sparx5 support 9 different clock outputs. This include file has
defines for each supported clock ordinal.

Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>
---
 include/dt-bindings/clock/microchip,sparx5.h | 23 ++++++++++++++++++++
 1 file changed, 23 insertions(+)
 create mode 100644 include/dt-bindings/clock/microchip,sparx5.h

diff --git a/include/dt-bindings/clock/microchip,sparx5.h b/include/dt-bindings/clock/microchip,sparx5.h
new file mode 100644
index 0000000000000..4b04dabacec2c
--- /dev/null
+++ b/include/dt-bindings/clock/microchip,sparx5.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019 Microchip Inc.
+ *
+ * Author: Lars Povlsen <lars.povlsen@microchip.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_SPARX5_H
+#define _DT_BINDINGS_CLK_SPARX5_H
+
+#define CLK_ID_CORE	0
+#define CLK_ID_DDR	1
+#define CLK_ID_CPU2	2
+#define CLK_ID_ARM2	3
+#define CLK_ID_AUX1	4
+#define CLK_ID_AUX2	5
+#define CLK_ID_AUX3	6
+#define CLK_ID_AUX4	7
+#define CLK_ID_SYNCE	8
+
+#define N_CLOCKS	9
+
+#endif
-- 
2.27.0


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

* [PATCH v3 08/10] clk: sparx5: Add Sparx5 SoC DPLL clock driver
  2020-06-15 13:32 [PATCH v3 00/10] Adding support for Microchip Sparx5 SoC Lars Povlsen
                   ` (6 preceding siblings ...)
  2020-06-15 13:32 ` [PATCH v3 07/10] dt-bindings: clock: sparx5: Add bindings include file Lars Povlsen
@ 2020-06-15 13:32 ` Lars Povlsen
       [not found]   ` <159558008977.3847286.10561464126267966931@swboyd.mtv.corp.google.com>
  2020-06-15 13:32 ` [PATCH v3 09/10] arm64: dts: sparx5: Add Sparx5 SoC DPLL clock Lars Povlsen
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Lars Povlsen @ 2020-06-15 13:32 UTC (permalink / raw)
  To: SoC Team, Arnd Bergmann, Stephen Boyd, Linus Walleij
  Cc: Lars Povlsen, Steen Hegelund, Microchip Linux Driver Support,
	Olof Johansson, Michael Turquette, devicetree, linux-clk,
	linux-gpio, linux-arm-kernel, linux-kernel, Alexandre Belloni

This adds a device driver for the Sparx5 SoC DPLL clock

Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>
---
 drivers/clk/Makefile     |   1 +
 drivers/clk/clk-sparx5.c | 312 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 313 insertions(+)
 create mode 100644 drivers/clk/clk-sparx5.c

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index ca9af11d33913..da8fcf147eb13 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_COMMON_CLK_CDCE925)	+= clk-cdce925.o
 obj-$(CONFIG_ARCH_CLPS711X)		+= clk-clps711x.o
 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_SAI)	+= clk-fsl-sai.o
 obj-$(CONFIG_COMMON_CLK_GEMINI)		+= clk-gemini.o
diff --git a/drivers/clk/clk-sparx5.c b/drivers/clk/clk-sparx5.c
new file mode 100644
index 0000000000000..c2e7aa0214ebd
--- /dev/null
+++ b/drivers/clk/clk-sparx5.c
@@ -0,0 +1,312 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Microchip Sparx5 SoC Clock driver.
+ *
+ * Copyright (c) 2019 Microchip Inc.
+ *
+ * Author: Lars Povlsen <lars.povlsen@microchip.com>
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/clk-provider.h>
+#include <linux/bitfield.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/microchip,sparx5.h>
+
+#define PLL_DIV		GENMASK(7, 0)
+#define PLL_PRE_DIV	GENMASK(10, 8)
+#define PLL_ROT_DIR	BIT(11)
+#define PLL_ROT_SEL	GENMASK(13, 12)
+#define PLL_ROT_ENA	BIT(14)
+#define PLL_CLK_ENA	BIT(15)
+
+#define MAX_SEL 4
+#define MAX_PRE BIT(3)
+
+static const u8 sel_rates[MAX_SEL] = { 0, 2*8, 2*4, 2*2 };
+
+static const char *clk_names[N_CLOCKS] = {
+	"core", "ddr", "cpu2", "arm2",
+	"aux1", "aux2", "aux3", "aux4",
+	"synce",
+};
+
+struct s5_hw_clk {
+	struct clk_hw hw;
+	void __iomem *reg;
+	int index;
+};
+
+struct s5_clk_data {
+	void __iomem *base;
+	struct s5_hw_clk s5_hw[N_CLOCKS];
+};
+
+struct s5_pll_conf {
+	int freq;
+	u8 div;
+	bool rot_ena;
+	u8 rot_sel;
+	u8 rot_dir;
+	u8 pre_div;
+};
+
+#define to_s5_pll(hw) container_of(hw, struct s5_hw_clk, hw)
+
+static unsigned long s5_calc_freq(unsigned long parent_rate,
+				  const struct s5_pll_conf *conf)
+{
+	unsigned long rate = parent_rate / conf->div;
+
+	if (conf->rot_ena) {
+		int sign = conf->rot_dir ? -1 : 1;
+		int divt = sel_rates[conf->rot_sel] * (1 + conf->pre_div);
+		int divb = divt + sign;
+
+		rate = mult_frac(rate, divt, divb);
+		rate = roundup(rate, 1000);
+	}
+
+	return rate;
+}
+
+static void s5_search_fractional(unsigned long rate,
+				 unsigned long parent_rate,
+				 int div,
+				 struct s5_pll_conf *conf)
+{
+	struct s5_pll_conf best;
+	ulong cur_offset, best_offset = rate;
+	int d, i, j;
+
+	memset(conf, 0, sizeof(*conf));
+	conf->div = div;
+	conf->rot_ena = 1;	/* Fractional rate */
+
+	for (d = 0; best_offset > 0 && d <= 1 ; d++) {
+		conf->rot_dir = !!d;
+		for (i = 0; best_offset > 0 && i < MAX_PRE; i++) {
+			conf->pre_div = i;
+			for (j = 1; best_offset > 0 && j < MAX_SEL; j++) {
+				conf->rot_sel = j;
+				conf->freq = s5_calc_freq(parent_rate, conf);
+				cur_offset = abs(rate - conf->freq);
+				if (cur_offset < best_offset) {
+					best_offset = cur_offset;
+					best = *conf;
+				}
+			}
+		}
+	}
+
+	/* Best match */
+	*conf = best;
+}
+
+static unsigned long s5_calc_params(unsigned long rate,
+				    unsigned long parent_rate,
+				    struct s5_pll_conf *conf)
+{
+	if (parent_rate % rate) {
+		struct s5_pll_conf alt1, alt2;
+		int div;
+
+		div = DIV_ROUND_CLOSEST_ULL(parent_rate, rate);
+		s5_search_fractional(rate, parent_rate, div, &alt1);
+
+		/* Straight match? */
+		if (alt1.freq == rate) {
+			*conf = alt1;
+		} else {
+			/* Try without rounding divider */
+			div = parent_rate / rate;
+			if (div != alt1.div) {
+				s5_search_fractional(rate, parent_rate, div,
+						     &alt2);
+				/* Select the better match */
+				if (abs(rate - alt1.freq) <
+				    abs(rate - alt2.freq))
+					*conf = alt1;
+				else
+					*conf = alt2;
+			}
+		}
+	} else {
+		/* Straight fit */
+		memset(conf, 0, sizeof(*conf));
+		conf->div = parent_rate / rate;
+	}
+
+	return conf->freq;
+}
+
+static int s5_pll_enable(struct clk_hw *hw)
+{
+	struct s5_hw_clk *pll = to_s5_pll(hw);
+	u32 val = readl(pll->reg);
+
+	val |= PLL_CLK_ENA;
+	writel(val, pll->reg);
+
+	return 0;
+}
+
+static void s5_pll_disable(struct clk_hw *hw)
+{
+	struct s5_hw_clk *pll = to_s5_pll(hw);
+	u32 val = readl(pll->reg);
+
+	val &= ~PLL_CLK_ENA;
+	writel(val, pll->reg);
+}
+
+static int s5_pll_set_rate(struct clk_hw *hw,
+			   unsigned long rate,
+			   unsigned long parent_rate)
+{
+	struct s5_hw_clk *pll = to_s5_pll(hw);
+	struct s5_pll_conf conf;
+	unsigned long eff_rate;
+	u32 val;
+
+	eff_rate = s5_calc_params(rate, parent_rate, &conf);
+	if (eff_rate != rate)
+		return -EOPNOTSUPP;
+
+	val = readl(pll->reg) & PLL_CLK_ENA;
+	val |= FIELD_PREP(PLL_DIV, conf.div);
+	if (conf.rot_ena) {
+		val |= PLL_ROT_ENA;
+		val |= FIELD_PREP(PLL_ROT_SEL, conf.rot_sel);
+		val |= FIELD_PREP(PLL_PRE_DIV, conf.pre_div);
+		if (conf.rot_dir)
+			val |= PLL_ROT_DIR;
+	}
+	writel(val, pll->reg);
+
+	return 0;
+}
+
+static unsigned long s5_pll_recalc_rate(struct clk_hw *hw,
+					unsigned long parent_rate)
+{
+	struct s5_hw_clk *pll = to_s5_pll(hw);
+	struct s5_pll_conf conf;
+	u32 val;
+
+	val = readl(pll->reg);
+
+	if (val & PLL_CLK_ENA) {
+		conf.div     = FIELD_GET(PLL_DIV, val);
+		conf.pre_div = FIELD_GET(PLL_PRE_DIV, val);
+		conf.rot_ena = FIELD_GET(PLL_ROT_ENA, val);
+		conf.rot_dir = FIELD_GET(PLL_ROT_DIR, val);
+		conf.rot_sel = FIELD_GET(PLL_ROT_SEL, val);
+
+		conf.freq = s5_calc_freq(parent_rate, &conf);
+	} else
+		conf.freq = 0;
+
+	return conf.freq;
+}
+
+static long s5_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+			      unsigned long *parent_rate)
+{
+	struct s5_pll_conf conf;
+
+	return s5_calc_params(rate, *parent_rate, &conf);
+}
+
+static const struct clk_ops s5_pll_ops = {
+	.enable		= s5_pll_enable,
+	.disable	= s5_pll_disable,
+	.set_rate	= s5_pll_set_rate,
+	.round_rate	= s5_pll_round_rate,
+	.recalc_rate	= s5_pll_recalc_rate,
+};
+
+static struct clk_hw *s5_clk_hw_get(struct of_phandle_args *clkspec, void *data)
+{
+	struct s5_clk_data *s5_clk = data;
+	unsigned int idx = clkspec->args[0];
+
+	if (idx >= N_CLOCKS) {
+		pr_err("%s: invalid index %u\n", __func__, idx);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return &s5_clk->s5_hw[idx].hw;
+}
+
+static int s5_clk_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	int i, ret;
+	struct s5_clk_data *s5_clk;
+	const char *parent_name;
+	struct clk_init_data init = {
+		.ops = &s5_pll_ops,
+		.parent_names = &parent_name,
+		.num_parents = 1,
+	};
+
+	s5_clk = devm_kzalloc(dev, sizeof(*s5_clk), GFP_KERNEL);
+	if (!s5_clk)
+		return -ENOMEM;
+
+	s5_clk->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(s5_clk->base))
+		return PTR_ERR(s5_clk->base);
+
+	parent_name = of_clk_get_parent_name(np, 0);
+	if (!parent_name) {
+		dev_err(dev, "%pOFn: missing parent clock\n", np);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < N_CLOCKS; i++) {
+		struct s5_hw_clk *s5_hw = &s5_clk->s5_hw[i];
+
+		init.name = clk_names[i];
+		s5_hw->index = i;
+		s5_hw->reg = s5_clk->base + (i * sizeof(u32));
+		s5_hw->hw.init = &init;
+		ret = devm_clk_hw_register(dev, &s5_hw->hw);
+		if (ret) {
+			dev_err(dev, "failed to register %s clock\n",
+				init.name);
+			return ret;
+		}
+	}
+
+	return of_clk_add_hw_provider(np, s5_clk_hw_get, s5_clk);
+}
+
+static int s5_clk_remove(struct platform_device *pdev)
+{
+	of_clk_del_provider(pdev->dev.of_node);
+
+	return 0;
+}
+
+static const struct of_device_id s5_clk_dt_ids[] = {
+	{ .compatible = "microchip,sparx5-dpll", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, s5_clk_dt_ids);
+
+static struct platform_driver s5_clk_driver = {
+	.probe  = s5_clk_probe,
+	.remove = s5_clk_remove,
+	.driver = {
+		.name = "sparx5-clk",
+		.of_match_table = s5_clk_dt_ids,
+	},
+};
+builtin_platform_driver(s5_clk_driver);
-- 
2.27.0


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

* [PATCH v3 09/10] arm64: dts: sparx5: Add Sparx5 SoC DPLL clock
  2020-06-15 13:32 [PATCH v3 00/10] Adding support for Microchip Sparx5 SoC Lars Povlsen
                   ` (7 preceding siblings ...)
  2020-06-15 13:32 ` [PATCH v3 08/10] clk: sparx5: Add Sparx5 SoC DPLL clock driver Lars Povlsen
@ 2020-06-15 13:32 ` Lars Povlsen
  2020-06-15 13:32 ` [PATCH v3 10/10] arm64: dts: sparx5: Add i2c devices, i2c muxes Lars Povlsen
  2020-07-22 20:32 ` [PATCH v3 00/10] Adding support for Microchip Sparx5 SoC Arnd Bergmann
  10 siblings, 0 replies; 20+ messages in thread
From: Lars Povlsen @ 2020-06-15 13:32 UTC (permalink / raw)
  To: SoC Team, Arnd Bergmann, Stephen Boyd, Linus Walleij
  Cc: Lars Povlsen, Steen Hegelund, Microchip Linux Driver Support,
	Olof Johansson, Michael Turquette, devicetree, linux-clk,
	linux-gpio, linux-arm-kernel, linux-kernel, Alexandre Belloni

This adds a DPLL clock to the Sparx5 SoC. It is used to generate clock
to misc peripherals, specifically the SDHCI/eMMC controller.

Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>
---
 arch/arm64/boot/dts/microchip/sparx5.dtsi | 39 +++++++++++++----------
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/boot/dts/microchip/sparx5.dtsi b/arch/arm64/boot/dts/microchip/sparx5.dtsi
index baf4176ce1dfe..161846caf9c94 100644
--- a/arch/arm64/boot/dts/microchip/sparx5.dtsi
+++ b/arch/arm64/boot/dts/microchip/sparx5.dtsi
@@ -72,20 +72,29 @@ timer {
 			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
 	};
 
-	clocks: clocks {
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges;
-		ahb_clk: ahb-clk {
-			compatible = "fixed-clock";
-			#clock-cells = <0>;
-			clock-frequency = <250000000>;
-		};
-		sys_clk: sys-clk {
-			compatible = "fixed-clock";
-			#clock-cells = <0>;
-			clock-frequency = <625000000>;
-		};
+	lcpll_clk: lcpll-clk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <2500000000>;
+	};
+
+	clks: clock-controller@61110000c {
+		compatible = "microchip,sparx5-dpll";
+		#clock-cells = <1>;
+		clocks = <&lcpll_clk>;
+		reg = <0x6 0x1110000c 0x24>;
+	};
+
+	ahb_clk: ahb-clk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <250000000>;
+	};
+
+	sys_clk: sys-clk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <625000000>;
 	};
 
 	axi: axi@600000000 {
@@ -161,8 +170,6 @@ uart2_pins: uart2-pins {
 				pins = "GPIO_26", "GPIO_27";
 				function = "uart2";
 			};
-
 		};
-
 	};
 };
-- 
2.27.0


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

* [PATCH v3 10/10] arm64: dts: sparx5: Add i2c devices, i2c muxes
  2020-06-15 13:32 [PATCH v3 00/10] Adding support for Microchip Sparx5 SoC Lars Povlsen
                   ` (8 preceding siblings ...)
  2020-06-15 13:32 ` [PATCH v3 09/10] arm64: dts: sparx5: Add Sparx5 SoC DPLL clock Lars Povlsen
@ 2020-06-15 13:32 ` Lars Povlsen
  2020-07-22 20:32 ` [PATCH v3 00/10] Adding support for Microchip Sparx5 SoC Arnd Bergmann
  10 siblings, 0 replies; 20+ messages in thread
From: Lars Povlsen @ 2020-06-15 13:32 UTC (permalink / raw)
  To: SoC Team, Arnd Bergmann, Stephen Boyd, Linus Walleij
  Cc: Lars Povlsen, Steen Hegelund, Microchip Linux Driver Support,
	Olof Johansson, Michael Turquette, devicetree, linux-clk,
	linux-gpio, linux-arm-kernel, linux-kernel, Alexandre Belloni

This patch adds i2c devices and muxes to the Sparx5 reference boards.

Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>
---
 arch/arm64/boot/dts/microchip/sparx5.dtsi     |  38 +++
 .../boot/dts/microchip/sparx5_pcb125.dts      |   4 +
 .../dts/microchip/sparx5_pcb134_board.dtsi    | 237 ++++++++++++++++++
 .../dts/microchip/sparx5_pcb135_board.dtsi    |  77 ++++++
 .../boot/dts/microchip/sparx5_pcb_common.dtsi |   4 +
 5 files changed, 360 insertions(+)

diff --git a/arch/arm64/boot/dts/microchip/sparx5.dtsi b/arch/arm64/boot/dts/microchip/sparx5.dtsi
index 161846caf9c94..cf712e80615da 100644
--- a/arch/arm64/boot/dts/microchip/sparx5.dtsi
+++ b/arch/arm64/boot/dts/microchip/sparx5.dtsi
@@ -170,6 +170,44 @@ uart2_pins: uart2-pins {
 				pins = "GPIO_26", "GPIO_27";
 				function = "uart2";
 			};
+
+			i2c_pins: i2c-pins {
+				pins = "GPIO_14", "GPIO_15";
+				function = "twi";
+			};
+
+			i2c2_pins: i2c2-pins {
+				pins = "GPIO_28", "GPIO_29";
+				function = "twi2";
+			};
+		};
+
+		i2c0: i2c@600101000 {
+			compatible = "snps,designware-i2c";
+			status = "disabled";
+			pinctrl-0 = <&i2c_pins>;
+			pinctrl-names = "default";
+			reg = <0x6 0x00101000 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+			i2c-sda-hold-time-ns = <300>;
+			clock-frequency = <100000>;
+			clocks = <&ahb_clk>;
+		};
+
+		i2c1: i2c@600103000 {
+			compatible = "snps,designware-i2c";
+			status = "disabled";
+			pinctrl-0 = <&i2c2_pins>;
+			pinctrl-names = "default";
+			reg = <0x6 0x00103000 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+			i2c-sda-hold-time-ns = <300>;
+			clock-frequency = <100000>;
+			clocks = <&ahb_clk>;
 		};
 	};
 };
diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb125.dts b/arch/arm64/boot/dts/microchip/sparx5_pcb125.dts
index d7f985f7ee020..91ee5b6cfc37a 100644
--- a/arch/arm64/boot/dts/microchip/sparx5_pcb125.dts
+++ b/arch/arm64/boot/dts/microchip/sparx5_pcb125.dts
@@ -15,3 +15,7 @@ memory@0 {
 		reg = <0x00000000 0x00000000 0x10000000>;
 	};
 };
+
+&i2c1 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi b/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi
index 9b2aec400101b..18a535a043686 100644
--- a/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi
+++ b/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi
@@ -7,9 +7,246 @@
 #include "sparx5_pcb_common.dtsi"
 
 /{
+	aliases {
+	    i2c0   = &i2c0;
+	    i2c100 = &i2c100;
+	    i2c101 = &i2c101;
+	    i2c102 = &i2c102;
+	    i2c103 = &i2c103;
+	    i2c104 = &i2c104;
+	    i2c105 = &i2c105;
+	    i2c106 = &i2c106;
+	    i2c107 = &i2c107;
+	    i2c108 = &i2c108;
+	    i2c109 = &i2c109;
+	    i2c110 = &i2c110;
+	    i2c111 = &i2c111;
+	    i2c112 = &i2c112;
+	    i2c113 = &i2c113;
+	    i2c114 = &i2c114;
+	    i2c115 = &i2c115;
+	    i2c116 = &i2c116;
+	    i2c117 = &i2c117;
+	    i2c118 = &i2c118;
+	    i2c119 = &i2c119;
+	};
+
 	gpio-restart {
 		compatible = "gpio-restart";
 		gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
 		priority = <200>;
 	};
 };
+
+&gpio {
+	i2cmux_pins_i: i2cmux-pins-i {
+	       pins = "GPIO_16", "GPIO_17", "GPIO_18", "GPIO_19",
+		      "GPIO_20", "GPIO_22", "GPIO_36", "GPIO_35",
+		      "GPIO_50", "GPIO_51", "GPIO_56", "GPIO_57";
+		function = "twi_scl_m";
+		output-low;
+	};
+	i2cmux_0: i2cmux-0 {
+		pins = "GPIO_16";
+		function = "twi_scl_m";
+		output-high;
+	};
+	i2cmux_1: i2cmux-1 {
+		pins = "GPIO_17";
+		function = "twi_scl_m";
+		output-high;
+	};
+	i2cmux_2: i2cmux-2 {
+		pins = "GPIO_18";
+		function = "twi_scl_m";
+		output-high;
+	};
+	i2cmux_3: i2cmux-3 {
+		pins = "GPIO_19";
+		function = "twi_scl_m";
+		output-high;
+	};
+	i2cmux_4: i2cmux-4 {
+		pins = "GPIO_20";
+		function = "twi_scl_m";
+		output-high;
+	};
+	i2cmux_5: i2cmux-5 {
+		pins = "GPIO_22";
+		function = "twi_scl_m";
+		output-high;
+	};
+	i2cmux_6: i2cmux-6 {
+		pins = "GPIO_36";
+		function = "twi_scl_m";
+		output-high;
+	};
+	i2cmux_7: i2cmux-7 {
+		pins = "GPIO_35";
+		function = "twi_scl_m";
+		output-high;
+	};
+	i2cmux_8: i2cmux-8 {
+		pins = "GPIO_50";
+		function = "twi_scl_m";
+		output-high;
+	};
+	i2cmux_9: i2cmux-9 {
+		pins = "GPIO_51";
+		function = "twi_scl_m";
+		output-high;
+	};
+	i2cmux_10: i2cmux-10 {
+		pins = "GPIO_56";
+		function = "twi_scl_m";
+		output-high;
+	};
+	i2cmux_11: i2cmux-11 {
+		pins = "GPIO_57";
+		function = "twi_scl_m";
+		output-high;
+	};
+};
+
+&axi {
+	i2c0_imux: i2c0-imux@0 {
+		compatible = "i2c-mux-pinctrl";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		i2c-parent = <&i2c0>;
+	};
+	i2c0_emux: i2c0-emux@0 {
+		compatible = "i2c-mux-gpio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		i2c-parent = <&i2c0>;
+	};
+};
+
+&i2c0_imux {
+	pinctrl-names =
+		"i2c100", "i2c101", "i2c102", "i2c103",
+		"i2c104", "i2c105", "i2c106", "i2c107",
+		"i2c108", "i2c109", "i2c110", "i2c111", "idle";
+	pinctrl-0 = <&i2cmux_0>;
+	pinctrl-1 = <&i2cmux_1>;
+	pinctrl-2 = <&i2cmux_2>;
+	pinctrl-3 = <&i2cmux_3>;
+	pinctrl-4 = <&i2cmux_4>;
+	pinctrl-5 = <&i2cmux_5>;
+	pinctrl-6 = <&i2cmux_6>;
+	pinctrl-7 = <&i2cmux_7>;
+	pinctrl-8 = <&i2cmux_8>;
+	pinctrl-9 = <&i2cmux_9>;
+	pinctrl-10 = <&i2cmux_10>;
+	pinctrl-11 = <&i2cmux_11>;
+	pinctrl-12 = <&i2cmux_pins_i>;
+	i2c100: i2c_sfp1 {
+		reg = <0x0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c101: i2c_sfp2 {
+		reg = <0x1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c102: i2c_sfp3 {
+		reg = <0x2>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c103: i2c_sfp4 {
+		reg = <0x3>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c104: i2c_sfp5 {
+		reg = <0x4>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c105: i2c_sfp6 {
+		reg = <0x5>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c106: i2c_sfp7 {
+		reg = <0x6>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c107: i2c_sfp8 {
+		reg = <0x7>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c108: i2c_sfp9 {
+		reg = <0x8>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c109: i2c_sfp10 {
+		reg = <0x9>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c110: i2c_sfp11 {
+		reg = <0xa>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c111: i2c_sfp12 {
+		reg = <0xb>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+};
+
+&i2c0_emux {
+	mux-gpios = <&gpio 55 GPIO_ACTIVE_HIGH
+		     &gpio 60 GPIO_ACTIVE_HIGH
+		     &gpio 61 GPIO_ACTIVE_HIGH
+		     &gpio 54 GPIO_ACTIVE_HIGH>;
+	idle-state = <0x8>;
+	i2c112: i2c_sfp13 {
+		reg = <0x0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c113: i2c_sfp14 {
+		reg = <0x1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c114: i2c_sfp15 {
+		reg = <0x2>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c115: i2c_sfp16 {
+		reg = <0x3>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c116: i2c_sfp17 {
+		reg = <0x4>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c117: i2c_sfp18 {
+		reg = <0x5>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c118: i2c_sfp19 {
+		reg = <0x6>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c119: i2c_sfp20 {
+		reg = <0x7>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+};
diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi b/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi
index 9b2aec400101b..d71f11a10b3d2 100644
--- a/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi
+++ b/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi
@@ -7,9 +7,86 @@
 #include "sparx5_pcb_common.dtsi"
 
 /{
+	aliases {
+	    i2c0   = &i2c0;
+	    i2c152 = &i2c152;
+	    i2c153 = &i2c153;
+	    i2c154 = &i2c154;
+	    i2c155 = &i2c155;
+	};
+
 	gpio-restart {
 		compatible = "gpio-restart";
 		gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
 		priority = <200>;
 	};
 };
+
+&gpio {
+	i2cmux_pins_i: i2cmux-pins-i {
+	       pins = "GPIO_35", "GPIO_36",
+		      "GPIO_50", "GPIO_51";
+		function = "twi_scl_m";
+		output-low;
+	};
+	i2cmux_s29: i2cmux-0 {
+		pins = "GPIO_35";
+		function = "twi_scl_m";
+		output-high;
+	};
+	i2cmux_s30: i2cmux-1 {
+		pins = "GPIO_36";
+		function = "twi_scl_m";
+		output-high;
+	};
+	i2cmux_s31: i2cmux-2 {
+		pins = "GPIO_50";
+		function = "twi_scl_m";
+		output-high;
+	};
+	i2cmux_s32: i2cmux-3 {
+		pins = "GPIO_51";
+		function = "twi_scl_m";
+		output-high;
+	};
+};
+
+&axi {
+	i2c0_imux: i2c0-imux@0 {
+		compatible = "i2c-mux-pinctrl";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		i2c-parent = <&i2c0>;
+	};
+};
+
+&i2c0_imux {
+	pinctrl-names =
+		"i2c152", "i2c153", "i2c154", "i2c155",
+		"idle";
+	pinctrl-0 = <&i2cmux_s29>;
+	pinctrl-1 = <&i2cmux_s30>;
+	pinctrl-2 = <&i2cmux_s31>;
+	pinctrl-3 = <&i2cmux_s32>;
+	pinctrl-4 = <&i2cmux_pins_i>;
+	i2c152: i2c_sfp1 {
+		reg = <0x0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c153: i2c_sfp2 {
+		reg = <0x1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c154: i2c_sfp3 {
+		reg = <0x2>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+	i2c155: i2c_sfp4 {
+		reg = <0x3>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+};
diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi b/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi
index 1f99d0db1284f..9d1a082de3e29 100644
--- a/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi
+++ b/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi
@@ -13,3 +13,7 @@ &uart0 {
 &uart1 {
 	status = "okay";
 };
+
+&i2c0 {
+	status = "okay";
+};
-- 
2.27.0


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

* Re: [PATCH v3 05/10] pinctrl: ocelot: Add Sparx5 SoC support
  2020-06-15 13:32 ` [PATCH v3 05/10] pinctrl: ocelot: Add Sparx5 SoC support Lars Povlsen
@ 2020-06-20 21:10   ` Linus Walleij
  2020-06-22  7:54     ` Lars Povlsen
  2020-07-07 11:58   ` Linus Walleij
  1 sibling, 1 reply; 20+ messages in thread
From: Linus Walleij @ 2020-06-20 21:10 UTC (permalink / raw)
  To: Lars Povlsen
  Cc: SoC Team, Arnd Bergmann, Stephen Boyd, Steen Hegelund,
	Microchip Linux Driver Support, Olof Johansson,
	Michael Turquette,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-clk, open list:GPIO SUBSYSTEM, Linux ARM, linux-kernel,
	Alexandre Belloni

On Mon, Jun 15, 2020 at 3:33 PM Lars Povlsen <lars.povlsen@microchip.com> wrote:

> This add support for Sparx5 pinctrl, using the ocelot drives as
> basis. It adds pinconfig support as well, as supported by the
> platform.
>
> Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
> Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>

Is it fine if I just apply this driver to the pinctrl tree?
Otherwise Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

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

* Re: [PATCH v3 05/10] pinctrl: ocelot: Add Sparx5 SoC support
  2020-06-20 21:10   ` Linus Walleij
@ 2020-06-22  7:54     ` Lars Povlsen
  0 siblings, 0 replies; 20+ messages in thread
From: Lars Povlsen @ 2020-06-22  7:54 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Lars Povlsen, SoC Team, Arnd Bergmann, Stephen Boyd,
	Steen Hegelund, Microchip Linux Driver Support, Olof Johansson,
	Michael Turquette,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-clk, open list:GPIO SUBSYSTEM, Linux ARM, linux-kernel,
	Alexandre Belloni


Linus Walleij writes:

> On Mon, Jun 15, 2020 at 3:33 PM Lars Povlsen <lars.povlsen@microchip.com> wrote:
>
>> This add support for Sparx5 pinctrl, using the ocelot drives as
>> basis. It adds pinconfig support as well, as supported by the
>> platform.
>>
>> Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
>> Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>
>
> Is it fine if I just apply this driver to the pinctrl tree?
> Otherwise Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Hi Linus!

Yes it would be fine with me for sure...

Thank you very much.

---Lars

>
> Yours,
> Linus Walleij

-- 
Lars Povlsen,
Microchip

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

* Re: [PATCH v3 05/10] pinctrl: ocelot: Add Sparx5 SoC support
  2020-06-15 13:32 ` [PATCH v3 05/10] pinctrl: ocelot: Add Sparx5 SoC support Lars Povlsen
  2020-06-20 21:10   ` Linus Walleij
@ 2020-07-07 11:58   ` Linus Walleij
  1 sibling, 0 replies; 20+ messages in thread
From: Linus Walleij @ 2020-07-07 11:58 UTC (permalink / raw)
  To: Lars Povlsen
  Cc: SoC Team, Arnd Bergmann, Stephen Boyd, Steen Hegelund,
	Microchip Linux Driver Support, Olof Johansson,
	Michael Turquette,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-clk, open list:GPIO SUBSYSTEM, Linux ARM, linux-kernel,
	Alexandre Belloni

On Mon, Jun 15, 2020 at 3:33 PM Lars Povlsen <lars.povlsen@microchip.com> wrote:

> This add support for Sparx5 pinctrl, using the ocelot drives as
> basis. It adds pinconfig support as well, as supported by the
> platform.
>
> Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
> Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>

This one patch applied to the pinctrl tree.

Yours,
Linus Walleij

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

* Re: [PATCH v3 01/10] dt-bindings: arm: sparx5: Add documentation for Microchip Sparx5 SoC
  2020-06-15 13:32 ` [PATCH v3 01/10] dt-bindings: arm: sparx5: Add documentation " Lars Povlsen
@ 2020-07-13 18:40   ` Rob Herring
  0 siblings, 0 replies; 20+ messages in thread
From: Rob Herring @ 2020-07-13 18:40 UTC (permalink / raw)
  To: Lars Povlsen
  Cc: Michael Turquette, Stephen Boyd, linux-arm-kernel,
	Olof Johansson, Microchip Linux Driver Support, linux-kernel,
	Arnd Bergmann, linux-clk, SoC Team, linux-gpio, Rob Herring,
	Linus Walleij, Alexandre Belloni, devicetree, Steen Hegelund

On Mon, 15 Jun 2020 15:32:33 +0200, Lars Povlsen wrote:
> This adds the main Sparx5 SoC DT documentation file, with information
> abut the supported board types.
> 
> Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
> Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>
> ---
>  .../bindings/arm/microchip,sparx5.yaml        | 65 +++++++++++++++++++
>  .../devicetree/bindings/mfd/syscon.yaml       |  1 +
>  2 files changed, 66 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/microchip,sparx5.yaml
> 

Reviewed-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH v3 06/10] dt-bindings: clock: sparx5: Add Sparx5 SoC DPLL clock
  2020-06-15 13:32 ` [PATCH v3 06/10] dt-bindings: clock: sparx5: Add Sparx5 SoC DPLL clock Lars Povlsen
@ 2020-07-13 18:41   ` Rob Herring
  0 siblings, 0 replies; 20+ messages in thread
From: Rob Herring @ 2020-07-13 18:41 UTC (permalink / raw)
  To: Lars Povlsen
  Cc: devicetree, linux-clk, Alexandre Belloni,
	Microchip Linux Driver Support, linux-kernel, linux-gpio,
	Rob Herring, SoC Team, linux-arm-kernel, Olof Johansson,
	Linus Walleij, Michael Turquette, Steen Hegelund, Arnd Bergmann,
	Stephen Boyd

On Mon, 15 Jun 2020 15:32:38 +0200, Lars Povlsen wrote:
> This add the DT bindings documentation for the Sparx5 SoC DPLL clock
> 
> Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
> Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>
> ---
>  .../bindings/clock/microchip,sparx5-dpll.yaml | 52 +++++++++++++++++++
>  1 file changed, 52 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/microchip,sparx5-dpll.yaml
> 

Reviewed-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH v3 07/10] dt-bindings: clock: sparx5: Add bindings include file
  2020-06-15 13:32 ` [PATCH v3 07/10] dt-bindings: clock: sparx5: Add bindings include file Lars Povlsen
@ 2020-07-13 18:41   ` Rob Herring
  0 siblings, 0 replies; 20+ messages in thread
From: Rob Herring @ 2020-07-13 18:41 UTC (permalink / raw)
  To: Lars Povlsen
  Cc: devicetree, Olof Johansson, SoC Team, Linus Walleij,
	Alexandre Belloni, Stephen Boyd, linux-arm-kernel, linux-clk,
	Rob Herring, Michael Turquette, Steen Hegelund,
	Microchip Linux Driver Support, Arnd Bergmann, linux-gpio,
	linux-kernel

On Mon, 15 Jun 2020 15:32:39 +0200, Lars Povlsen wrote:
> The Sparx5 support 9 different clock outputs. This include file has
> defines for each supported clock ordinal.
> 
> Reviewed-by: Stephen Boyd <sboyd@kernel.org>
> Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
> Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>
> ---
>  include/dt-bindings/clock/microchip,sparx5.h | 23 ++++++++++++++++++++
>  1 file changed, 23 insertions(+)
>  create mode 100644 include/dt-bindings/clock/microchip,sparx5.h
> 

Reviewed-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH v3 00/10] Adding support for Microchip Sparx5 SoC
  2020-06-15 13:32 [PATCH v3 00/10] Adding support for Microchip Sparx5 SoC Lars Povlsen
                   ` (9 preceding siblings ...)
  2020-06-15 13:32 ` [PATCH v3 10/10] arm64: dts: sparx5: Add i2c devices, i2c muxes Lars Povlsen
@ 2020-07-22 20:32 ` Arnd Bergmann
  2020-07-23 10:09   ` Lars Povlsen
  10 siblings, 1 reply; 20+ messages in thread
From: Arnd Bergmann @ 2020-07-22 20:32 UTC (permalink / raw)
  To: Lars Povlsen
  Cc: SoC Team, Stephen Boyd, Linus Walleij, Steen Hegelund,
	Microchip Linux Driver Support, Olof Johansson,
	Michael Turquette, DTML, linux-clk, open list:GPIO SUBSYSTEM,
	Linux ARM, linux-kernel, Alexandre Belloni

On Mon, Jun 15, 2020 at 3:33 PM Lars Povlsen <lars.povlsen@microchip.com> wrote:
>
> This patch series adds support for Microchip Sparx5 SoC, the CPU
> system of a advanced, TSN capable gigabit switch. The CPU is an armv8
> x 2 CPU core (A53).
>
> Although this is an ARM core, it shares some peripherals with the
> Microsemi Ocelot MIPS SoC.

I've picked up this version of the series into an arm/newsoc branch in
the soc tree,
except for the pinctrl patch that Linus Walleij already merged.

I see you still have a few pending patches for other subsystems (spi, mmc)
and I'm not sure what the status is for those and am dropping them for the
moment.

Once the bindings are accepted by the respective subsystem maintainers,
please send any remaining DT patches as a follow-up to what I've already
merged.

      Arnd

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

* Re: [PATCH v3 00/10] Adding support for Microchip Sparx5 SoC
  2020-07-22 20:32 ` [PATCH v3 00/10] Adding support for Microchip Sparx5 SoC Arnd Bergmann
@ 2020-07-23 10:09   ` Lars Povlsen
  0 siblings, 0 replies; 20+ messages in thread
From: Lars Povlsen @ 2020-07-23 10:09 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Lars Povlsen, SoC Team, Stephen Boyd, Linus Walleij,
	Steen Hegelund, Microchip Linux Driver Support, Olof Johansson,
	Michael Turquette, DTML, linux-clk, open list:GPIO SUBSYSTEM,
	Linux ARM, linux-kernel, Alexandre Belloni, Adrian Hunter


Arnd Bergmann writes:

> On Mon, Jun 15, 2020 at 3:33 PM Lars Povlsen <lars.povlsen@microchip.com> wrote:
>>
>> This patch series adds support for Microchip Sparx5 SoC, the CPU
>> system of a advanced, TSN capable gigabit switch. The CPU is an armv8
>> x 2 CPU core (A53).
>>
>> Although this is an ARM core, it shares some peripherals with the
>> Microsemi Ocelot MIPS SoC.
>
> I've picked up this version of the series into an arm/newsoc branch in
> the soc tree,
> except for the pinctrl patch that Linus Walleij already merged.
>

Great! Thanks a lot for following up!

> I see you still have a few pending patches for other subsystems (spi, mmc)
> and I'm not sure what the status is for those and am dropping them for the
> moment.
>

Yes, I had a question out for the SPI maintainer but did not get any
feedback, so I was thinking just doing my own assumptions and refreshing
the series - probably tomorrow.

I also just bumped the MMC maintainer (Adrian) yesterday, as he did send
a me an 'Acked-by', but it hasn't been merged it seems.

> Once the bindings are accepted by the respective subsystem maintainers,
> please send any remaining DT patches as a follow-up to what I've already
> merged.
>

I'll try to work out the puzzle, might need to reach out directly to to
determine whats missing.

Later,

---Lars

>       Arnd

-- 
Lars Povlsen,
Microchip

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

* Re: [PATCH v3 08/10] clk: sparx5: Add Sparx5 SoC DPLL clock driver
       [not found]   ` <159558008977.3847286.10561464126267966931@swboyd.mtv.corp.google.com>
@ 2020-07-24 12:19     ` Lars Povlsen
  0 siblings, 0 replies; 20+ messages in thread
From: Lars Povlsen @ 2020-07-24 12:19 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Arnd Bergmann, Linus Walleij, SoC Team, Lars Povlsen,
	Steen Hegelund, Microchip Linux Driver Support, Olof Johansson,
	Michael Turquette, devicetree, linux-clk, linux-gpio,
	linux-arm-kernel, linux-kernel, Alexandre Belloni


Hi Stephen!

Thank you for your comments!

Stephen Boyd writes:

> Quoting Lars Povlsen (2020-06-15 06:32:40)
>> diff --git a/drivers/clk/clk-sparx5.c b/drivers/clk/clk-sparx5.c
>> new file mode 100644
>> index 0000000000000..c2e7aa0214ebd
>> --- /dev/null
>> +++ b/drivers/clk/clk-sparx5.c
>> @@ -0,0 +1,312 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Microchip Sparx5 SoC Clock driver.
>> + *
>> + * Copyright (c) 2019 Microchip Inc.
>> + *
>> + * Author: Lars Povlsen <lars.povlsen@microchip.com>
>> + */
>> +
>> +#include <linux/io.h>
>> +#include <linux/module.h>
>> +#include <linux/clk-provider.h>
>> +#include <linux/bitfield.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>
> Is this include used?

Nope, gone now.

>
>> +#include <linux/slab.h>
>> +#include <linux/platform_device.h>
>> +#include <dt-bindings/clock/microchip,sparx5.h>
>> +
>> +#define PLL_DIV                GENMASK(7, 0)
>> +#define PLL_PRE_DIV    GENMASK(10, 8)
>> +#define PLL_ROT_DIR    BIT(11)
>> +#define PLL_ROT_SEL    GENMASK(13, 12)
>> +#define PLL_ROT_ENA    BIT(14)
>> +#define PLL_CLK_ENA    BIT(15)
>> +
>> +#define MAX_SEL 4
>> +#define MAX_PRE BIT(3)
>> +
>> +static const u8 sel_rates[MAX_SEL] = { 0, 2*8, 2*4, 2*2 };
>> +
>> +static const char *clk_names[N_CLOCKS] = {
>> +       "core", "ddr", "cpu2", "arm2",
>> +       "aux1", "aux2", "aux3", "aux4",
>> +       "synce",
>> +};
>> +
>> +struct s5_hw_clk {
>> +       struct clk_hw hw;
>> +       void __iomem *reg;
>> +       int index;
>
> This looks unused. Drop it?
>

Yes, that was a leftover. Good find.

>> +};
>> +
>> +struct s5_clk_data {
>> +       void __iomem *base;
>> +       struct s5_hw_clk s5_hw[N_CLOCKS];
>> +};
>> +
>> +struct s5_pll_conf {
>> +       int freq;
>
> Why not unsigned long like the type that s5_calc_freq() returns?
>

Good point, changed it.

>> +       u8 div;
>> +       bool rot_ena;
>> +       u8 rot_sel;
>> +       u8 rot_dir;
>> +       u8 pre_div;
>> +};
>> +
>> +#define to_s5_pll(hw) container_of(hw, struct s5_hw_clk, hw)
>> +
>> +static unsigned long s5_calc_freq(unsigned long parent_rate,
>> +                                 const struct s5_pll_conf *conf)
>> +{
>> +       unsigned long rate = parent_rate / conf->div;
>> +
>> +       if (conf->rot_ena) {
>> +               int sign = conf->rot_dir ? -1 : 1;
>> +               int divt = sel_rates[conf->rot_sel] * (1 + conf->pre_div);
>> +               int divb = divt + sign;
>> +
>> +               rate = mult_frac(rate, divt, divb);
>> +               rate = roundup(rate, 1000);
>> +       }
>> +
>> +       return rate;
>> +}
>> +
>> +static void s5_search_fractional(unsigned long rate,
>> +                                unsigned long parent_rate,
>> +                                int div,
>> +                                struct s5_pll_conf *conf)
>> +{
>> +       struct s5_pll_conf best;
>> +       ulong cur_offset, best_offset = rate;
>> +       int d, i, j;
>> +
>> +       memset(conf, 0, sizeof(*conf));
>> +       conf->div = div;
>> +       conf->rot_ena = 1;      /* Fractional rate */
>> +
>> +       for (d = 0; best_offset > 0 && d <= 1 ; d++) {
>> +               conf->rot_dir = !!d;
>> +               for (i = 0; best_offset > 0 && i < MAX_PRE; i++) {
>> +                       conf->pre_div = i;
>> +                       for (j = 1; best_offset > 0 && j < MAX_SEL; j++) {
>> +                               conf->rot_sel = j;
>> +                               conf->freq = s5_calc_freq(parent_rate, conf);
>> +                               cur_offset = abs(rate - conf->freq);
>> +                               if (cur_offset < best_offset) {
>> +                                       best_offset = cur_offset;
>> +                                       best = *conf;
>> +                               }
>> +                       }
>> +               }
>> +       }
>> +
>> +       /* Best match */
>> +       *conf = best;
>> +}
>> +
>> +static unsigned long s5_calc_params(unsigned long rate,
>> +                                   unsigned long parent_rate,
>> +                                   struct s5_pll_conf *conf)
>> +{
>> +       if (parent_rate % rate) {
>> +               struct s5_pll_conf alt1, alt2;
>> +               int div;
>> +
>> +               div = DIV_ROUND_CLOSEST_ULL(parent_rate, rate);
>> +               s5_search_fractional(rate, parent_rate, div, &alt1);
>> +
>> +               /* Straight match? */
>> +               if (alt1.freq == rate) {
>> +                       *conf = alt1;
>> +               } else {
>> +                       /* Try without rounding divider */
>> +                       div = parent_rate / rate;
>> +                       if (div != alt1.div) {
>> +                               s5_search_fractional(rate, parent_rate, div,
>> +                                                    &alt2);
>> +                               /* Select the better match */
>> +                               if (abs(rate - alt1.freq) <
>> +                                   abs(rate - alt2.freq))
>> +                                       *conf = alt1;
>> +                               else
>> +                                       *conf = alt2;
>> +                       }
>> +               }
>> +       } else {
>> +               /* Straight fit */
>> +               memset(conf, 0, sizeof(*conf));
>> +               conf->div = parent_rate / rate;
>> +       }
>> +
>> +       return conf->freq;
>> +}
>> +
>> +static int s5_pll_enable(struct clk_hw *hw)
>> +{
>> +       struct s5_hw_clk *pll = to_s5_pll(hw);
>> +       u32 val = readl(pll->reg);
>> +
>> +       val |= PLL_CLK_ENA;
>> +       writel(val, pll->reg);
>> +
>> +       return 0;
>> +}
>> +
>> +static void s5_pll_disable(struct clk_hw *hw)
>> +{
>> +       struct s5_hw_clk *pll = to_s5_pll(hw);
>> +       u32 val = readl(pll->reg);
>> +
>> +       val &= ~PLL_CLK_ENA;
>> +       writel(val, pll->reg);
>> +}
>> +
>> +static int s5_pll_set_rate(struct clk_hw *hw,
>> +                          unsigned long rate,
>> +                          unsigned long parent_rate)
>> +{
>> +       struct s5_hw_clk *pll = to_s5_pll(hw);
>> +       struct s5_pll_conf conf;
>> +       unsigned long eff_rate;
>> +       u32 val;
>> +
>> +       eff_rate = s5_calc_params(rate, parent_rate, &conf);
>> +       if (eff_rate != rate)
>> +               return -EOPNOTSUPP;
>> +
>> +       val = readl(pll->reg) & PLL_CLK_ENA;
>> +       val |= FIELD_PREP(PLL_DIV, conf.div);
>> +       if (conf.rot_ena) {
>> +               val |= PLL_ROT_ENA;
>> +               val |= FIELD_PREP(PLL_ROT_SEL, conf.rot_sel);
>> +               val |= FIELD_PREP(PLL_PRE_DIV, conf.pre_div);
>> +               if (conf.rot_dir)
>> +                       val |= PLL_ROT_DIR;
>> +       }
>> +       writel(val, pll->reg);
>> +
>> +       return 0;
>> +}
>> +
>> +static unsigned long s5_pll_recalc_rate(struct clk_hw *hw,
>> +                                       unsigned long parent_rate)
>> +{
>> +       struct s5_hw_clk *pll = to_s5_pll(hw);
>> +       struct s5_pll_conf conf;
>> +       u32 val;
>> +
>> +       val = readl(pll->reg);
>> +
>> +       if (val & PLL_CLK_ENA) {
>> +               conf.div     = FIELD_GET(PLL_DIV, val);
>> +               conf.pre_div = FIELD_GET(PLL_PRE_DIV, val);
>> +               conf.rot_ena = FIELD_GET(PLL_ROT_ENA, val);
>> +               conf.rot_dir = FIELD_GET(PLL_ROT_DIR, val);
>> +               conf.rot_sel = FIELD_GET(PLL_ROT_SEL, val);
>> +
>> +               conf.freq = s5_calc_freq(parent_rate, &conf);
>> +       } else
>> +               conf.freq = 0;
>
> Nitpick: Please add braces on single line else statements when the if is
> multiline.
>

Done.

>> +
>> +       return conf.freq;
>> +}
>> +
>> +static long s5_pll_round_rate(struct clk_hw *hw, unsigned long rate,
>> +                             unsigned long *parent_rate)
>> +{
>> +       struct s5_pll_conf conf;
>> +
>> +       return s5_calc_params(rate, *parent_rate, &conf);
>> +}
>> +
>> +static const struct clk_ops s5_pll_ops = {
>> +       .enable         = s5_pll_enable,
>> +       .disable        = s5_pll_disable,
>> +       .set_rate       = s5_pll_set_rate,
>> +       .round_rate     = s5_pll_round_rate,
>> +       .recalc_rate    = s5_pll_recalc_rate,
>> +};
>> +
>> +static struct clk_hw *s5_clk_hw_get(struct of_phandle_args *clkspec, void *data)
>> +{
>> +       struct s5_clk_data *s5_clk = data;
>> +       unsigned int idx = clkspec->args[0];
>> +
>> +       if (idx >= N_CLOCKS) {
>> +               pr_err("%s: invalid index %u\n", __func__, idx);
>> +               return ERR_PTR(-EINVAL);
>> +       }
>> +
>> +       return &s5_clk->s5_hw[idx].hw;
>> +}
>> +
>> +static int s5_clk_probe(struct platform_device *pdev)
>> +{
>> +       struct device *dev = &pdev->dev;
>> +       struct device_node *np = dev->of_node;
>> +       int i, ret;
>> +       struct s5_clk_data *s5_clk;
>> +       const char *parent_name;
>> +       struct clk_init_data init = {
>> +               .ops = &s5_pll_ops,
>> +               .parent_names = &parent_name,
>
> It looks like with the binding you can drop parent_name and just use
> .parent_data = { .index = 0 } and event drop the .index = 0 bit because
> that's the default valjue.
>

Ok, I got rid of the parent_name and used .parent_data instead.


>> +               .num_parents = 1,
>> +       };
>> +
>> +       s5_clk = devm_kzalloc(dev, sizeof(*s5_clk), GFP_KERNEL);
>> +       if (!s5_clk)
>> +               return -ENOMEM;
>> +
>> +       s5_clk->base = devm_platform_ioremap_resource(pdev, 0);
>> +       if (IS_ERR(s5_clk->base))
>> +               return PTR_ERR(s5_clk->base);
>> +
>> +       parent_name = of_clk_get_parent_name(np, 0);
>> +       if (!parent_name) {
>> +               dev_err(dev, "%pOFn: missing parent clock\n", np);
>> +               return -EINVAL;
>> +       }
>
> It's nice because then this call goes away.
>

Yes.

>> +
>> +       for (i = 0; i < N_CLOCKS; i++) {
>> +               struct s5_hw_clk *s5_hw = &s5_clk->s5_hw[i];
>> +
>> +               init.name = clk_names[i];
>> +               s5_hw->index = i;
>> +               s5_hw->reg = s5_clk->base + (i * sizeof(u32));
>
> I'd prefer i * 4 because the hardware engineers probably don't care
> about the size of a u32 in bytes.
>

Sure.

>> +               s5_hw->hw.init = &init;
>> +               ret = devm_clk_hw_register(dev, &s5_hw->hw);
>> +               if (ret) {
>> +                       dev_err(dev, "failed to register %s clock\n",
>> +                               init.name);
>
> init.name will be destroyed. Just drop this error message? Maybe we
> should add it into the core framework because quite a few driver authors
> want it.
>
>> +                       return ret;
>> +               }
>> +       }
>> +
>> +       return of_clk_add_hw_provider(np, s5_clk_hw_get, s5_clk);
>
> Use devm_of_clk_add_hw_provider()?

Yes. Also removes 'np' variable.

>
>> +}
>> +
>> +static int s5_clk_remove(struct platform_device *pdev)
>> +{
>> +       of_clk_del_provider(pdev->dev.of_node);
>> +
>> +       return 0;
>> +}
>> +
>
> And then remove this whole remove function?
>

And yes.

>> +static const struct of_device_id s5_clk_dt_ids[] = {
>> +       { .compatible = "microchip,sparx5-dpll", },
>> +       { }
>> +};
>> +MODULE_DEVICE_TABLE(of, s5_clk_dt_ids);
>> +
>> +static struct platform_driver s5_clk_driver = {
>> +       .probe  = s5_clk_probe,
>> +       .remove = s5_clk_remove,
>> +       .driver = {
>> +               .name = "sparx5-clk",
>> +               .of_match_table = s5_clk_dt_ids,
>> +       },
>> +};

Thanks a lot for your comments - that shaved off some code!

I'll be refreshing the series shortly.

Cheers,

-- 
Lars Povlsen,
Microchip

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

end of thread, other threads:[~2020-07-24 12:19 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-15 13:32 [PATCH v3 00/10] Adding support for Microchip Sparx5 SoC Lars Povlsen
2020-06-15 13:32 ` [PATCH v3 01/10] dt-bindings: arm: sparx5: Add documentation " Lars Povlsen
2020-07-13 18:40   ` Rob Herring
2020-06-15 13:32 ` [PATCH v3 02/10] arm64: sparx5: Add support for Microchip 2xA53 SoC Lars Povlsen
2020-06-15 13:32 ` [PATCH v3 03/10] arm64: dts: sparx5: Add basic cpu support Lars Povlsen
2020-06-15 13:32 ` [PATCH v3 04/10] arm64: dts: sparx5: Add pinctrl support Lars Povlsen
2020-06-15 13:32 ` [PATCH v3 05/10] pinctrl: ocelot: Add Sparx5 SoC support Lars Povlsen
2020-06-20 21:10   ` Linus Walleij
2020-06-22  7:54     ` Lars Povlsen
2020-07-07 11:58   ` Linus Walleij
2020-06-15 13:32 ` [PATCH v3 06/10] dt-bindings: clock: sparx5: Add Sparx5 SoC DPLL clock Lars Povlsen
2020-07-13 18:41   ` Rob Herring
2020-06-15 13:32 ` [PATCH v3 07/10] dt-bindings: clock: sparx5: Add bindings include file Lars Povlsen
2020-07-13 18:41   ` Rob Herring
2020-06-15 13:32 ` [PATCH v3 08/10] clk: sparx5: Add Sparx5 SoC DPLL clock driver Lars Povlsen
     [not found]   ` <159558008977.3847286.10561464126267966931@swboyd.mtv.corp.google.com>
2020-07-24 12:19     ` Lars Povlsen
2020-06-15 13:32 ` [PATCH v3 09/10] arm64: dts: sparx5: Add Sparx5 SoC DPLL clock Lars Povlsen
2020-06-15 13:32 ` [PATCH v3 10/10] arm64: dts: sparx5: Add i2c devices, i2c muxes Lars Povlsen
2020-07-22 20:32 ` [PATCH v3 00/10] Adding support for Microchip Sparx5 SoC Arnd Bergmann
2020-07-23 10:09   ` Lars Povlsen

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).