LKML Archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay
@ 2024-08-20 14:36 Andrea della Porta
  2024-08-20 14:36 ` [PATCH 01/11] dt-bindings: clock: Add RaspberryPi RP1 clock bindings Andrea della Porta
                   ` (11 more replies)
  0 siblings, 12 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-08-20 14:36 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

RP1 is an MFD chipset that acts as a south-bridge PCIe endpoint sporting
a pletora of subdevices (i.e.  Ethernet, USB host controller, I2C, PWM, 
etc.) whose registers are all reachable starting from an offset from the
BAR address.  The main point here is that while the RP1 as an endpoint
itself is discoverable via usual PCI enumeraiton, the devices it contains
are not discoverable and must be declared e.g. via the devicetree.

This patchset is an attempt to provide a minimum infrastructure to allow
the RP1 chipset to be discovered and perpherals it contains to be added
from a devictree overlay loaded during RP1 PCI endpoint enumeration.
Followup patches should add support for the several peripherals contained
in RP1.

This work is based upon dowstream drivers code and the proposal from RH
et al. (see [1] and [2]). A similar approach is also pursued in [3].

The patches are ordered as follows:

-PATCHES 1 and 2: add binding schemas for clock and gpio peripherals 
 found in RP1. They are needed to support the other peripherals, e.g.
 the ethernet mac depends on a clock generated by RP1 and the phy is
 reset though the on-board gpio controller.

-PATCHES 3, 4 and 5: preparatory patches that fix the address mapping
 translation (especially wrt dma-ranges) and permit to place the dtbo
 binary blob to be put in non transient section.

-PATCH 6 and 7: add clock and gpio device drivers.

-PATCH 8: this is the main patch to support RP1 chipset and peripherals
 enabling through dtb overlay. It contains the dtso since its intimately
 coupled with the driver and will be linked in as binary blob in the driver
 obj, but of course it can be easily split in a separate patch if the
 maintainer feels it so. The real dtso is in devicetree folder while
 the dtso in driver folder is just a placeholder to include the real dtso.
 In this way it is possible to check the dtso against dt-bindings.

-PATCH 9: add the relevant kernel CONFIG_ options to defconfig.

-PATCHES 10 and 11: these (still unpolished) patches are not intended to
 be upstreamed (yet), they serve just as a test reference to be able to
 use the ethernet MAC contained in RP1.

This patchset is also a first attempt to be more agnostic wrt hardware
description standards such as OF devicetree and ACPI, where 'agnostic'
means "using DT in coexistence with ACPI", as been alredy promoted
by e.g. AL (see [4]). Although there's currently no evidence it will also
run out of the box on purely ACPI system, it is a first step towards
that direction.

Please note that albeit this patchset has no prerequisites in order to
be applied cleanly, it still depends on Stanimir's WIP patchset for BCM2712
PCIe controller (see [5]) in order to work at runtime.

Many thanks,
Andrea della Porta

Link:
- [1]: https://lpc.events/event/17/contributions/1421/attachments/1337/2680/LPC2023%20Non-discoverable%20devices%20in%20PCI.pdf
- [2]: https://lore.kernel.org/lkml/20230419231155.GA899497-robh@kernel.org/t/
- [3]: https://lore.kernel.org/all/20240808154658.247873-1-herve.codina@bootlin.com/#t
- [4]: https://lore.kernel.org/all/73e05c77-6d53-4aae-95ac-415456ff0ae4@lunn.ch/
- [5]: https://lore.kernel.org/all/20240626104544.14233-1-svarbanov@suse.de/

Andrea della Porta (11):
  dt-bindings: clock: Add RaspberryPi RP1 clock bindings
  dt-bindings: pinctrl: Add RaspberryPi RP1 gpio/pinctrl/pinmux bindings
  PCI: of_property: Sanitize 32 bit PCI address parsed from DT
  of: address: Preserve the flags portion on 1:1 dma-ranges mapping
  vmlinux.lds.h: Preserve DTB sections from being discarded after init
  clk: rp1: Add support for clocks provided by RP1
  pinctrl: rp1: Implement RaspberryPi RP1 gpio support
  misc: rp1: RaspberryPi RP1 misc driver
  arm64: defconfig: Enable RP1 misc/clock/gpio drivers as built-in
  net: macb: Add support for RP1's MACB variant
  arm64: dts: rp1: Add support for MACB contained in RP1

 .../clock/raspberrypi,rp1-clocks.yaml         |   87 +
 .../pinctrl/raspberrypi,rp1-gpio.yaml         |  177 ++
 MAINTAINERS                                   |   12 +
 arch/arm64/boot/dts/broadcom/rp1.dtso         |  175 ++
 arch/arm64/configs/defconfig                  |    3 +
 drivers/clk/Kconfig                           |    9 +
 drivers/clk/Makefile                          |    1 +
 drivers/clk/clk-rp1.c                         | 1655 +++++++++++++++++
 drivers/misc/Kconfig                          |    1 +
 drivers/misc/Makefile                         |    1 +
 drivers/misc/rp1/Kconfig                      |   20 +
 drivers/misc/rp1/Makefile                     |    3 +
 drivers/misc/rp1/rp1-pci.c                    |  333 ++++
 drivers/misc/rp1/rp1-pci.dtso                 |    8 +
 drivers/net/ethernet/cadence/macb.h           |   25 +
 drivers/net/ethernet/cadence/macb_main.c      |  152 +-
 drivers/of/address.c                          |    3 +-
 drivers/pci/of_property.c                     |    5 +-
 drivers/pci/quirks.c                          |    1 +
 drivers/pinctrl/Kconfig                       |   10 +
 drivers/pinctrl/Makefile                      |    1 +
 drivers/pinctrl/pinctrl-rp1.c                 |  719 +++++++
 include/asm-generic/vmlinux.lds.h             |    2 +-
 include/dt-bindings/clock/rp1.h               |   56 +
 include/dt-bindings/misc/rp1.h                |  235 +++
 include/linux/pci_ids.h                       |    3 +
 26 files changed, 3692 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
 create mode 100644 arch/arm64/boot/dts/broadcom/rp1.dtso
 create mode 100644 drivers/clk/clk-rp1.c
 create mode 100644 drivers/misc/rp1/Kconfig
 create mode 100644 drivers/misc/rp1/Makefile
 create mode 100644 drivers/misc/rp1/rp1-pci.c
 create mode 100644 drivers/misc/rp1/rp1-pci.dtso
 create mode 100644 drivers/pinctrl/pinctrl-rp1.c
 create mode 100644 include/dt-bindings/clock/rp1.h
 create mode 100644 include/dt-bindings/misc/rp1.h

-- 
2.35.3


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

* [PATCH 01/11] dt-bindings: clock: Add RaspberryPi RP1 clock bindings
  2024-08-20 14:36 [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay Andrea della Porta
@ 2024-08-20 14:36 ` Andrea della Porta
  2024-08-20 16:19   ` Conor Dooley
  2024-08-20 14:36 ` [PATCH 02/11] dt-bindings: pinctrl: Add RaspberryPi RP1 gpio/pinctrl/pinmux bindings Andrea della Porta
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-20 14:36 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Add device tree bindings for the clock generator found in RP1 multi
function device, and relative entries in MAINTAINERS file.

Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
---
 .../clock/raspberrypi,rp1-clocks.yaml         | 87 +++++++++++++++++++
 MAINTAINERS                                   |  6 ++
 include/dt-bindings/clock/rp1.h               | 56 ++++++++++++
 3 files changed, 149 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
 create mode 100644 include/dt-bindings/clock/rp1.h

diff --git a/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml b/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
new file mode 100644
index 000000000000..b27db86d0572
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
@@ -0,0 +1,87 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/raspberrypi,rp1-clocks.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RaspberryPi RP1 clock generator
+
+maintainers:
+  - Andrea della Porta <andrea.porta@suse.com>
+
+description: |
+  The RP1 contains a clock generator designed as three PLLs (CORE, AUDIO,
+  VIDEO), and each PLL output can be programmed though dividers to generate
+  the clocks to drive the sub-peripherals embedded inside the chipset.
+
+  Link to datasheet:
+  https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
+
+properties:
+  compatible:
+    const: raspberrypi,rp1-clocks
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    description:
+      The index in the assigned-clocks is mapped to the output clock as per
+      definitions in dt-bindings/clock/rp1.h.
+    const: 1
+
+  clocks:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rp1.h>
+
+    rp1 {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        rp1_clocks: clocks@18000 {
+            compatible = "raspberrypi,rp1-clocks";
+            reg = <0xc0 0x40018000 0x0 0x10038>;
+            #clock-cells = <1>;
+            clocks = <&clk_xosc>;
+
+            assigned-clocks = <&rp1_clocks RP1_PLL_SYS_CORE>,
+                              <&rp1_clocks RP1_PLL_AUDIO_CORE>,
+                              /* RP1_PLL_VIDEO_CORE and dividers are now managed by VEC,DPI drivers */
+                              <&rp1_clocks RP1_PLL_SYS>,
+                              <&rp1_clocks RP1_PLL_SYS_SEC>,
+                              <&rp1_clocks RP1_PLL_AUDIO>,
+                              <&rp1_clocks RP1_PLL_AUDIO_SEC>,
+                              <&rp1_clocks RP1_CLK_SYS>,
+                              <&rp1_clocks RP1_PLL_SYS_PRI_PH>,
+                              /* RP1_CLK_SLOW_SYS is used for the frequency counter (FC0) */
+                              <&rp1_clocks RP1_CLK_SLOW_SYS>,
+                              <&rp1_clocks RP1_CLK_SDIO_TIMER>,
+                              <&rp1_clocks RP1_CLK_SDIO_ALT_SRC>,
+                              <&rp1_clocks RP1_CLK_ETH_TSU>;
+
+            assigned-clock-rates = <1000000000>, // RP1_PLL_SYS_CORE
+                                   <1536000000>, // RP1_PLL_AUDIO_CORE
+                                   <200000000>,  // RP1_PLL_SYS
+                                   <125000000>,  // RP1_PLL_SYS_SEC
+                                   <61440000>,   // RP1_PLL_AUDIO
+                                   <192000000>,  // RP1_PLL_AUDIO_SEC
+                                   <200000000>,  // RP1_CLK_SYS
+                                   <100000000>,  // RP1_PLL_SYS_PRI_PH
+                                   /* Must match the XOSC frequency */
+                                   <50000000>, // RP1_CLK_SLOW_SYS
+                                   <1000000>, // RP1_CLK_SDIO_TIMER
+                                   <200000000>, // RP1_CLK_SDIO_ALT_SRC
+                                   <50000000>; // RP1_CLK_ETH_TSU
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 42decde38320..6e7db9bce278 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19116,6 +19116,12 @@ F:	Documentation/devicetree/bindings/media/raspberrypi,pispbe.yaml
 F:	drivers/media/platform/raspberrypi/pisp_be/
 F:	include/uapi/linux/media/raspberrypi/
 
+RASPBERRY PI RP1 PCI DRIVER
+M:	Andrea della Porta <andrea.porta@suse.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
+F:	include/dt-bindings/clock/rp1.h
+
 RC-CORE / LIRC FRAMEWORK
 M:	Sean Young <sean@mess.org>
 L:	linux-media@vger.kernel.org
diff --git a/include/dt-bindings/clock/rp1.h b/include/dt-bindings/clock/rp1.h
new file mode 100644
index 000000000000..1ed67b8a5229
--- /dev/null
+++ b/include/dt-bindings/clock/rp1.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright (C) 2021 Raspberry Pi Ltd.
+ */
+
+#define RP1_PLL_SYS_CORE		0
+#define RP1_PLL_AUDIO_CORE		1
+#define RP1_PLL_VIDEO_CORE		2
+
+#define RP1_PLL_SYS			3
+#define RP1_PLL_AUDIO			4
+#define RP1_PLL_VIDEO			5
+
+#define RP1_PLL_SYS_PRI_PH		6
+#define RP1_PLL_SYS_SEC_PH		7
+#define RP1_PLL_AUDIO_PRI_PH		8
+
+#define RP1_PLL_SYS_SEC			9
+#define RP1_PLL_AUDIO_SEC		10
+#define RP1_PLL_VIDEO_SEC		11
+
+#define RP1_CLK_SYS			12
+#define RP1_CLK_SLOW_SYS		13
+#define RP1_CLK_DMA			14
+#define RP1_CLK_UART			15
+#define RP1_CLK_ETH			16
+#define RP1_CLK_PWM0			17
+#define RP1_CLK_PWM1			18
+#define RP1_CLK_AUDIO_IN		19
+#define RP1_CLK_AUDIO_OUT		20
+#define RP1_CLK_I2S			21
+#define RP1_CLK_MIPI0_CFG		22
+#define RP1_CLK_MIPI1_CFG		23
+#define RP1_CLK_PCIE_AUX		24
+#define RP1_CLK_USBH0_MICROFRAME	25
+#define RP1_CLK_USBH1_MICROFRAME	26
+#define RP1_CLK_USBH0_SUSPEND		27
+#define RP1_CLK_USBH1_SUSPEND		28
+#define RP1_CLK_ETH_TSU			29
+#define RP1_CLK_ADC			30
+#define RP1_CLK_SDIO_TIMER		31
+#define RP1_CLK_SDIO_ALT_SRC		32
+#define RP1_CLK_GP0			33
+#define RP1_CLK_GP1			34
+#define RP1_CLK_GP2			35
+#define RP1_CLK_GP3			36
+#define RP1_CLK_GP4			37
+#define RP1_CLK_GP5			38
+#define RP1_CLK_VEC			39
+#define RP1_CLK_DPI			40
+#define RP1_CLK_MIPI0_DPI		41
+#define RP1_CLK_MIPI1_DPI		42
+
+/* Extra PLL output channels - RP1B0 only */
+#define RP1_PLL_VIDEO_PRI_PH		43
+#define RP1_PLL_AUDIO_TERN		44
-- 
2.35.3


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

* [PATCH 02/11] dt-bindings: pinctrl: Add RaspberryPi RP1 gpio/pinctrl/pinmux bindings
  2024-08-20 14:36 [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay Andrea della Porta
  2024-08-20 14:36 ` [PATCH 01/11] dt-bindings: clock: Add RaspberryPi RP1 clock bindings Andrea della Porta
@ 2024-08-20 14:36 ` Andrea della Porta
  2024-08-21  8:42   ` Krzysztof Kozlowski
  2024-08-20 14:36 ` [PATCH 03/11] PCI: of_property: Sanitize 32 bit PCI address parsed from DT Andrea della Porta
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-20 14:36 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Add device tree bindings for the gpio/pin/mux controller that is part of
the RP1 multi function device, and relative entries in MAINTAINERS file.

Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
---
 .../pinctrl/raspberrypi,rp1-gpio.yaml         | 177 +++++++++++++
 MAINTAINERS                                   |   2 +
 include/dt-bindings/misc/rp1.h                | 235 ++++++++++++++++++
 3 files changed, 414 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
 create mode 100644 include/dt-bindings/misc/rp1.h

diff --git a/Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml b/Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
new file mode 100644
index 000000000000..7011fa258363
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
@@ -0,0 +1,177 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/raspberrypi,rp1-gpio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RaspberryPi RP1 GPIO/Pinconf/Pinmux Controller submodule
+
+maintainers:
+  - Andrea della Porta <andrea.porta@suse.com>
+
+description:
+  The RP1 chipset is a Multi Function Device containing, among other sub-peripherals,
+  a gpio/pinconf/mux controller whose 54 pins are grouped into 3 banks. It works also
+  as an interrupt controller for those gpios.
+
+  Each pin configuration node lists the pin(s) to which it applies, and one or
+  more of the mux function to select on those pin(s), and their configuration.
+  The pin configuration and multiplexing supports the generic bindings.
+  For details on each properties (including the meaning of "pin configuration node"),
+  you can refer to ./pinctrl-bindings.txt.
+
+properties:
+  compatible:
+    const: raspberrypi,rp1-gpio
+
+  reg:
+    minItems: 3
+    maxItems: 3
+    description: One reg specifier for each one of the 3 pin banks.
+
+  '#gpio-cells':
+    description: The first cell is the pin number and the second cell is used
+      to specify the flags (see include/dt-bindings/gpio/gpio.h).
+    const: 2
+
+  gpio-controller: true
+
+  gpio-ranges:
+    maxItems: 1
+
+  gpio-line-names:
+    maxItems: 54
+
+  interrupts:
+    minItems: 3
+    maxItems: 3
+    description: One interrupt specifier for each one of the 3 pin banks.
+
+  '#interrupt-cells':
+    description:
+      Specifies the Bank number (as specified in include/dt-bindings/misc/rp1.h)
+      and Flags (as defined in (include/dt-bindings/interrupt-controller/irq.h).
+      Possible values for the Bank number are
+          RP1_INT_IO_BANK0
+          RP1_INT_IO_BANK1
+          RP1_INT_IO_BANK2
+    const: 2
+
+  interrupt-controller: true
+
+additionalProperties:
+  anyOf:
+    - type: object
+      additionalProperties: false
+      allOf:
+        - $ref: pincfg-node.yaml#
+        - $ref: pinmux-node.yaml#
+
+      description:
+        Pin controller client devices use pin configuration subnodes (children
+        and grandchildren) for desired pin configuration.
+        Client device subnodes use below standard properties.
+
+      properties:
+        pins:
+          description:
+            A string (or list of strings) adhering to the pattern "gpio[0-5][0-9]"
+        function: true
+        bias-disable: true
+        bias-pull-down: true
+        bias-pull-up: true
+        slew-rate:
+          description: 0 is slow slew rate, 1 is fast slew rate
+          enum: [ 0, 1 ]
+        drive-strength:
+          description: 0 -> 2mA, 1 -> 4mA, 2 -> 8mA, 3 -> 12mA
+          enum: [ 0, 1, 2, 3 ]
+
+    - type: object
+      additionalProperties:
+        $ref: "#/additionalProperties/anyOf/0"
+
+allOf:
+  - $ref: pinctrl.yaml#
+
+required:
+  - reg
+  - compatible
+  - "#gpio-cells"
+  - gpio-controller
+  - interrupts
+  - "#interrupt-cells"
+  - interrupt-controller
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/misc/rp1.h>
+
+    rp1 {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        rp1_gpio: pinctrl@c0400d0000 {
+            reg = <0xc0 0x400d0000  0x0 0xc000>,
+                  <0xc0 0x400e0000  0x0 0xc000>,
+                  <0xc0 0x400f0000  0x0 0xc000>;
+            compatible = "raspberrypi,rp1-gpio";
+            gpio-controller;
+            #gpio-cells = <2>;
+            interrupt-controller;
+            #interrupt-cells = <2>;
+            interrupts = <RP1_INT_IO_BANK0 IRQ_TYPE_LEVEL_HIGH>,
+                         <RP1_INT_IO_BANK1 IRQ_TYPE_LEVEL_HIGH>,
+                         <RP1_INT_IO_BANK2 IRQ_TYPE_LEVEL_HIGH>;
+            gpio-line-names =
+                   "ID_SDA", // GPIO0
+                   "ID_SCL", // GPIO1
+                   "GPIO2", "GPIO3", "GPIO4", "GPIO5", "GPIO6",
+                   "GPIO7", "GPIO8", "GPIO9", "GPIO10", "GPIO11",
+                   "GPIO12", "GPIO13", "GPIO14", "GPIO15", "GPIO16",
+                   "GPIO17", "GPIO18", "GPIO19", "GPIO20", "GPIO21",
+                   "GPIO22", "GPIO23", "GPIO24", "GPIO25", "GPIO26",
+                   "GPIO27",
+                   "PCIE_RP1_WAKE", // GPIO28
+                   "FAN_TACH", // GPIO29
+                   "HOST_SDA", // GPIO30
+                   "HOST_SCL", // GPIO31
+                   "ETH_RST_N", // GPIO32
+                   "", // GPIO33
+                   "CD0_IO0_MICCLK", // GPIO34
+                   "CD0_IO0_MICDAT0", // GPIO35
+                   "RP1_PCIE_CLKREQ_N", // GPIO36
+                   "", // GPIO37
+                   "CD0_SDA", // GPIO38
+                   "CD0_SCL", // GPIO39
+                   "CD1_SDA", // GPIO40
+                   "CD1_SCL", // GPIO41
+                   "USB_VBUS_EN", // GPIO42
+                   "USB_OC_N", // GPIO43
+                   "RP1_STAT_LED", // GPIO44
+                   "FAN_PWM", // GPIO45
+                   "CD1_IO0_MICCLK", // GPIO46
+                   "2712_WAKE", // GPIO47
+                   "CD1_IO1_MICDAT1", // GPIO48
+                   "EN_MAX_USB_CUR", // GPIO49
+                   "", // GPIO50
+                   "", // GPIO51
+                   "", // GPIO52
+                   ""; // GPIO53
+
+            rp1_uart0_14_15: rp1_uart0_14_15 {
+                pin_txd {
+                    function = "uart0";
+                    pins = "gpio14";
+                    bias-disable;
+                };
+
+                pin_rxd {
+                    function = "uart0";
+                    pins = "gpio15";
+                    bias-pull-up;
+                };
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 6e7db9bce278..c5018232c251 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19120,7 +19120,9 @@ RASPBERRY PI RP1 PCI DRIVER
 M:	Andrea della Porta <andrea.porta@suse.com>
 S:	Maintained
 F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
+F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
 F:	include/dt-bindings/clock/rp1.h
+F:	include/dt-bindings/misc/rp1.h
 
 RC-CORE / LIRC FRAMEWORK
 M:	Sean Young <sean@mess.org>
diff --git a/include/dt-bindings/misc/rp1.h b/include/dt-bindings/misc/rp1.h
new file mode 100644
index 000000000000..6dd5e23870c2
--- /dev/null
+++ b/include/dt-bindings/misc/rp1.h
@@ -0,0 +1,235 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * This header provides constants for the PY MFD.
+ */
+
+#ifndef _RP1_H
+#define _RP1_H
+
+/* Address map */
+#define RP1_SYSINFO_BASE 0x000000
+#define RP1_TBMAN_BASE 0x004000
+#define RP1_SYSCFG_BASE 0x008000
+#define RP1_OTP_BASE 0x00c000
+#define RP1_POWER_BASE 0x010000
+#define RP1_RESETS_BASE 0x014000
+#define RP1_CLOCKS_BANK_DEFAULT_BASE 0x018000
+#define RP1_CLOCKS_BANK_VIDEO_BASE 0x01c000
+#define RP1_PLL_SYS_BASE 0x020000
+#define RP1_PLL_AUDIO_BASE 0x024000
+#define RP1_PLL_VIDEO_BASE 0x028000
+#define RP1_UART0_BASE 0x030000
+#define RP1_UART1_BASE 0x034000
+#define RP1_UART2_BASE 0x038000
+#define RP1_UART3_BASE 0x03c000
+#define RP1_UART4_BASE 0x040000
+#define RP1_UART5_BASE 0x044000
+#define RP1_SPI8_BASE 0x04c000
+#define RP1_SPI0_BASE 0x050000
+#define RP1_SPI1_BASE 0x054000
+#define RP1_SPI2_BASE 0x058000
+#define RP1_SPI3_BASE 0x05c000
+#define RP1_SPI4_BASE 0x060000
+#define RP1_SPI5_BASE 0x064000
+#define RP1_SPI6_BASE 0x068000
+#define RP1_SPI7_BASE 0x06c000
+#define RP1_I2C0_BASE 0x070000
+#define RP1_I2C1_BASE 0x074000
+#define RP1_I2C2_BASE 0x078000
+#define RP1_I2C3_BASE 0x07c000
+#define RP1_I2C4_BASE 0x080000
+#define RP1_I2C5_BASE 0x084000
+#define RP1_I2C6_BASE 0x088000
+#define RP1_AUDIO_IN_BASE 0x090000
+#define RP1_AUDIO_OUT_BASE 0x094000
+#define RP1_PWM0_BASE 0x098000
+#define RP1_PWM1_BASE 0x09c000
+#define RP1_I2S0_BASE 0x0a0000
+#define RP1_I2S1_BASE 0x0a4000
+#define RP1_I2S2_BASE 0x0a8000
+#define RP1_TIMER_BASE 0x0ac000
+#define RP1_SDIO0_APBS_BASE 0x0b0000
+#define RP1_SDIO1_APBS_BASE 0x0b4000
+#define RP1_BUSFABRIC_MONITOR_BASE 0x0c0000
+#define RP1_BUSFABRIC_AXISHIM_BASE 0x0c4000
+#define RP1_ADC_BASE 0x0c8000
+#define RP1_IO_BANK0_BASE 0x0d0000
+#define RP1_IO_BANK1_BASE 0x0d4000
+#define RP1_IO_BANK2_BASE 0x0d8000
+#define RP1_SYS_RIO0_BASE 0x0e0000
+#define RP1_SYS_RIO1_BASE 0x0e4000
+#define RP1_SYS_RIO2_BASE 0x0e8000
+#define RP1_PADS_BANK0_BASE 0x0f0000
+#define RP1_PADS_BANK1_BASE 0x0f4000
+#define RP1_PADS_BANK2_BASE 0x0f8000
+#define RP1_PADS_ETH_BASE 0x0fc000
+#define RP1_ETH_IP_BASE 0x100000
+#define RP1_ETH_CFG_BASE 0x104000
+#define RP1_PCIE_APBS_BASE 0x108000
+#define RP1_MIPI0_CSIDMA_BASE 0x110000
+#define RP1_MIPI0_CSIHOST_BASE 0x114000
+#define RP1_MIPI0_DSIDMA_BASE 0x118000
+#define RP1_MIPI0_DSIHOST_BASE 0x11c000
+#define RP1_MIPI0_MIPICFG_BASE 0x120000
+#define RP1_MIPI0_ISP_BASE 0x124000
+#define RP1_MIPI1_CSIDMA_BASE 0x128000
+#define RP1_MIPI1_CSIHOST_BASE 0x12c000
+#define RP1_MIPI1_DSIDMA_BASE 0x130000
+#define RP1_MIPI1_DSIHOST_BASE 0x134000
+#define RP1_MIPI1_MIPICFG_BASE 0x138000
+#define RP1_MIPI1_ISP_BASE 0x13c000
+#define RP1_VIDEO_OUT_CFG_BASE 0x140000
+#define RP1_VIDEO_OUT_VEC_BASE 0x144000
+#define RP1_VIDEO_OUT_DPI_BASE 0x148000
+#define RP1_XOSC_BASE 0x150000
+#define RP1_WATCHDOG_BASE 0x154000
+#define RP1_DMA_TICK_BASE 0x158000
+#define RP1_SDIO_CLOCKS_BASE 0x15c000
+#define RP1_USBHOST0_APBS_BASE 0x160000
+#define RP1_USBHOST1_APBS_BASE 0x164000
+#define RP1_ROSC0_BASE 0x168000
+#define RP1_ROSC1_BASE 0x16c000
+#define RP1_VBUSCTRL_BASE 0x170000
+#define RP1_TICKS_BASE 0x174000
+#define RP1_PIO_APBS_BASE 0x178000
+#define RP1_SDIO0_AHBLS_BASE 0x180000
+#define RP1_SDIO1_AHBLS_BASE 0x184000
+#define RP1_DMA_BASE 0x188000
+#define RP1_RAM_BASE 0x1c0000
+#define RP1_RAM_SIZE 0x020000
+#define RP1_USBHOST0_AXIS_BASE 0x200000
+#define RP1_USBHOST1_AXIS_BASE 0x300000
+#define RP1_EXAC_BASE 0x400000
+
+/* Interrupts */
+
+#define RP1_INT_IO_BANK0 0
+#define RP1_INT_IO_BANK1 1
+#define RP1_INT_IO_BANK2 2
+#define RP1_INT_AUDIO_IN 3
+#define RP1_INT_AUDIO_OUT 4
+#define RP1_INT_PWM0 5
+#define RP1_INT_ETH 6
+#define RP1_INT_I2C0 7
+#define RP1_INT_I2C1 8
+#define RP1_INT_I2C2 9
+#define RP1_INT_I2C3 10
+#define RP1_INT_I2C4 11
+#define RP1_INT_I2C5 12
+#define RP1_INT_I2C6 13
+#define RP1_INT_I2S0 14
+#define RP1_INT_I2S1 15
+#define RP1_INT_I2S2 16
+#define RP1_INT_SDIO0 17
+#define RP1_INT_SDIO1 18
+#define RP1_INT_SPI0 19
+#define RP1_INT_SPI1 20
+#define RP1_INT_SPI2 21
+#define RP1_INT_SPI3 22
+#define RP1_INT_SPI4 23
+#define RP1_INT_SPI5 24
+#define RP1_INT_UART0 25
+#define RP1_INT_TIMER_0 26
+#define RP1_INT_TIMER_1 27
+#define RP1_INT_TIMER_2 28
+#define RP1_INT_TIMER_3 29
+#define RP1_INT_USBHOST0 30
+#define RP1_INT_USBHOST0_0 31
+#define RP1_INT_USBHOST0_1 32
+#define RP1_INT_USBHOST0_2 33
+#define RP1_INT_USBHOST0_3 34
+#define RP1_INT_USBHOST1 35
+#define RP1_INT_USBHOST1_0 36
+#define RP1_INT_USBHOST1_1 37
+#define RP1_INT_USBHOST1_2 38
+#define RP1_INT_USBHOST1_3 39
+#define RP1_INT_DMA 40
+#define RP1_INT_PWM1 41
+#define RP1_INT_UART1 42
+#define RP1_INT_UART2 43
+#define RP1_INT_UART3 44
+#define RP1_INT_UART4 45
+#define RP1_INT_UART5 46
+#define RP1_INT_MIPI0 47
+#define RP1_INT_MIPI1 48
+#define RP1_INT_VIDEO_OUT 49
+#define RP1_INT_PIO_0 50
+#define RP1_INT_PIO_1 51
+#define RP1_INT_ADC_FIFO 52
+#define RP1_INT_PCIE_OUT 53
+#define RP1_INT_SPI6 54
+#define RP1_INT_SPI7 55
+#define RP1_INT_SPI8 56
+#define RP1_INT_SYSCFG 58
+#define RP1_INT_CLOCKS_DEFAULT 59
+#define RP1_INT_VBUSCTRL 60
+#define RP1_INT_PROC_MISC 57
+#define RP1_INT_END 61
+
+/* DMA peripherals (for pacing) */
+#define RP1_DMA_I2C0_RX 0x0
+#define RP1_DMA_I2C0_TX 0x1
+#define RP1_DMA_I2C1_RX 0x2
+#define RP1_DMA_I2C1_TX 0x3
+#define RP1_DMA_I2C2_RX 0x4
+#define RP1_DMA_I2C2_TX 0x5
+#define RP1_DMA_I2C3_RX 0x6
+#define RP1_DMA_I2C3_TX 0x7
+#define RP1_DMA_I2C4_RX 0x8
+#define RP1_DMA_I2C4_TX 0x9
+#define RP1_DMA_I2C5_RX 0xa
+#define RP1_DMA_I2C5_TX 0xb
+#define RP1_DMA_SPI0_RX 0xc
+#define RP1_DMA_SPI0_TX 0xd
+#define RP1_DMA_SPI1_RX 0xe
+#define RP1_DMA_SPI1_TX 0xf
+#define RP1_DMA_SPI2_RX 0x10
+#define RP1_DMA_SPI2_TX 0x11
+#define RP1_DMA_SPI3_RX 0x12
+#define RP1_DMA_SPI3_TX 0x13
+#define RP1_DMA_SPI4_RX 0x14
+#define RP1_DMA_SPI4_TX 0x15
+#define RP1_DMA_SPI5_RX 0x16
+#define RP1_DMA_SPI5_TX 0x17
+#define RP1_DMA_PWM0 0x18
+#define RP1_DMA_UART0_RX 0x19
+#define RP1_DMA_UART0_TX 0x1a
+#define RP1_DMA_AUDIO_IN_CH0 0x1b
+#define RP1_DMA_AUDIO_IN_CH1 0x1c
+#define RP1_DMA_AUDIO_OUT 0x1d
+#define RP1_DMA_PWM1 0x1e
+#define RP1_DMA_I2S0_RX 0x1f
+#define RP1_DMA_I2S0_TX 0x20
+#define RP1_DMA_I2S1_RX 0x21
+#define RP1_DMA_I2S1_TX 0x22
+#define RP1_DMA_I2S2_RX 0x23
+#define RP1_DMA_I2S2_TX 0x24
+#define RP1_DMA_UART1_RX 0x25
+#define RP1_DMA_UART1_TX 0x26
+#define RP1_DMA_UART2_RX 0x27
+#define RP1_DMA_UART2_TX 0x28
+#define RP1_DMA_UART3_RX 0x29
+#define RP1_DMA_UART3_TX 0x2a
+#define RP1_DMA_UART4_RX 0x2b
+#define RP1_DMA_UART4_TX 0x2c
+#define RP1_DMA_UART5_RX 0x2d
+#define RP1_DMA_UART5_TX 0x2e
+#define RP1_DMA_ADC 0x2f
+#define RP1_DMA_DMA_TICK_TICK0 0x30
+#define RP1_DMA_DMA_TICK_TICK1 0x31
+#define RP1_DMA_SPI6_RX 0x32
+#define RP1_DMA_SPI6_TX 0x33
+#define RP1_DMA_SPI7_RX 0x34
+#define RP1_DMA_SPI7_TX 0x35
+#define RP1_DMA_SPI8_RX 0x36
+#define RP1_DMA_SPI8_TX 0x37
+#define RP1_DMA_PIO_CH0_TX 0x38
+#define RP1_DMA_PIO_CH0_RX 0x39
+#define RP1_DMA_PIO_CH1_TX 0x3a
+#define RP1_DMA_PIO_CH1_RX 0x3b
+#define RP1_DMA_PIO_CH2_TX 0x3c
+#define RP1_DMA_PIO_CH2_RX 0x3d
+#define RP1_DMA_PIO_CH3_TX 0x3e
+#define RP1_DMA_PIO_CH3_RX 0x3f
+
+#endif
-- 
2.35.3


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

* [PATCH 03/11] PCI: of_property: Sanitize 32 bit PCI address parsed from DT
  2024-08-20 14:36 [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay Andrea della Porta
  2024-08-20 14:36 ` [PATCH 01/11] dt-bindings: clock: Add RaspberryPi RP1 clock bindings Andrea della Porta
  2024-08-20 14:36 ` [PATCH 02/11] dt-bindings: pinctrl: Add RaspberryPi RP1 gpio/pinctrl/pinmux bindings Andrea della Porta
@ 2024-08-20 14:36 ` Andrea della Porta
  2024-08-21 15:24   ` Bjorn Helgaas
  2024-08-20 14:36 ` [PATCH 04/11] of: address: Preserve the flags portion on 1:1 dma-ranges mapping Andrea della Porta
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-20 14:36 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

The of_pci_set_address() function parse devicetree PCI range specifier
assuming the address is 'sanitized' at the origin, i.e. without checking
whether the incoming address is 32 or 64 bit has specified in the flags.
In this way an address with no OF_PCI_ADDR_SPACE_MEM64 set in the flagss
could leak through and the upper 32 bits of the address will be set too,
and this violates the PCI specs stating that ion 32 bit address the upper
bit should be zero.
This could cause mapping translation mismatch on PCI devices (e.g. RP1)
that are expected to be addressed with a 64 bit address while advertising
a 32 bit address in the PCI config region.
Add a check in of_pci_set_address() to set upper 32 bits to zero in case
the address has no 64 bit flag set.

Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
---
 drivers/pci/of_property.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/of_property.c b/drivers/pci/of_property.c
index 5a0b98e69795..77865facdb4a 100644
--- a/drivers/pci/of_property.c
+++ b/drivers/pci/of_property.c
@@ -60,7 +60,10 @@ static void of_pci_set_address(struct pci_dev *pdev, u32 *prop, u64 addr,
 	prop[0] |= flags | reg_num;
 	if (!reloc) {
 		prop[0] |= OF_PCI_ADDR_FIELD_NONRELOC;
-		prop[1] = upper_32_bits(addr);
+		if (FIELD_GET(OF_PCI_ADDR_FIELD_SS, flags) == OF_PCI_ADDR_SPACE_MEM64)
+			prop[1] = upper_32_bits(addr);
+		else
+			prop[1] = 0;
 		prop[2] = lower_32_bits(addr);
 	}
 }
-- 
2.35.3


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

* [PATCH 04/11] of: address: Preserve the flags portion on 1:1 dma-ranges mapping
  2024-08-20 14:36 [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay Andrea della Porta
                   ` (2 preceding siblings ...)
  2024-08-20 14:36 ` [PATCH 03/11] PCI: of_property: Sanitize 32 bit PCI address parsed from DT Andrea della Porta
@ 2024-08-20 14:36 ` Andrea della Porta
  2024-08-21  0:16   ` Rob Herring
  2024-08-20 14:36 ` [PATCH 05/11] vmlinux.lds.h: Preserve DTB sections from being discarded after init Andrea della Porta
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-20 14:36 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

A missing or empty dma-ranges in a DT node implies a 1:1 mapping for dma
translations. In this specific case, rhe current behaviour is to zero out
the entire specifier so that the translation could be carried on as an
offset from zero.  This includes address specifier that has flags (e.g.
PCI ranges).
Once the flags portion has been zeroed, the translation chain is broken
since the mapping functions will check the upcoming address specifier
against mismatching flags, always failing the 1:1 mapping and its entire
purpose of always succeeding.
Set to zero only the address portion while passing the flags through.

Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
---
 drivers/of/address.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/of/address.c b/drivers/of/address.c
index d669ce25b5f9..5a6d55a67aa8 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -443,7 +443,8 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
 	}
 	if (ranges == NULL || rlen == 0) {
 		offset = of_read_number(addr, na);
-		memset(addr, 0, pna * 4);
+		/* copy the address while preserving the flags */
+		memset(addr + pbus->flag_cells, 0, (pna - pbus->flag_cells) * 4);
 		pr_debug("empty ranges; 1:1 translation\n");
 		goto finish;
 	}
-- 
2.35.3


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

* [PATCH 05/11] vmlinux.lds.h: Preserve DTB sections from being discarded after init
  2024-08-20 14:36 [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay Andrea della Porta
                   ` (3 preceding siblings ...)
  2024-08-20 14:36 ` [PATCH 04/11] of: address: Preserve the flags portion on 1:1 dma-ranges mapping Andrea della Porta
@ 2024-08-20 14:36 ` Andrea della Porta
  2024-08-30 19:46   ` Stephen Boyd
  2024-08-20 14:36 ` [PATCH 06/11] clk: rp1: Add support for clocks provided by RP1 Andrea della Porta
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-20 14:36 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

The special section .dtb.init.rodata contains dtb and dtbo compiled
as objects inside the kernel and ends up in .init.data sectiion that
will be discarded early after the init phase. This is a problem for
builtin drivers that apply dtb overlay at runtime since this happens
later (e.g. during bus enumeration) and also for modules that should
be able to do it dynamically during runtime.
Move the dtb section to .data.

Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
---
 include/asm-generic/vmlinux.lds.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index ad6afc5c4918..3ae9097774b0 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -365,6 +365,7 @@
 	TRACE_PRINTKS()							\
 	BPF_RAW_TP()							\
 	TRACEPOINT_STR()						\
+	KERNEL_DTB()							\
 	KUNIT_TABLE()
 
 /*
@@ -683,7 +684,6 @@
 	TIMER_OF_TABLES()						\
 	CPU_METHOD_OF_TABLES()						\
 	CPUIDLE_METHOD_OF_TABLES()					\
-	KERNEL_DTB()							\
 	IRQCHIP_OF_MATCH_TABLE()					\
 	ACPI_PROBE_TABLE(irqchip)					\
 	ACPI_PROBE_TABLE(timer)						\
-- 
2.35.3


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

* [PATCH 06/11] clk: rp1: Add support for clocks provided by RP1
  2024-08-20 14:36 [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay Andrea della Porta
                   ` (4 preceding siblings ...)
  2024-08-20 14:36 ` [PATCH 05/11] vmlinux.lds.h: Preserve DTB sections from being discarded after init Andrea della Porta
@ 2024-08-20 14:36 ` Andrea della Porta
  2024-08-21 13:17   ` Simon Horman
  2024-08-20 14:36 ` [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support Andrea della Porta
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-20 14:36 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

RaspberryPi RP1 is an MFD providing, among other peripherals, several
clock generators and PLLs that drives the sub-peripherals.
Add the driver to support the clock providers.

Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
---
 MAINTAINERS           |    1 +
 drivers/clk/Kconfig   |    9 +
 drivers/clk/Makefile  |    1 +
 drivers/clk/clk-rp1.c | 1655 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 1666 insertions(+)
 create mode 100644 drivers/clk/clk-rp1.c

diff --git a/MAINTAINERS b/MAINTAINERS
index c5018232c251..4ce7b049d67e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19121,6 +19121,7 @@ M:	Andrea della Porta <andrea.porta@suse.com>
 S:	Maintained
 F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
 F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
+F:	drivers/clk/clk-rp1.c
 F:	include/dt-bindings/clock/rp1.h
 F:	include/dt-bindings/misc/rp1.h
 
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 983ef4f36d8c..f785b21a0870 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -88,6 +88,15 @@ config COMMON_CLK_RK808
 	  These multi-function devices have two fixed-rate oscillators, clocked at 32KHz each.
 	  Clkout1 is always on, Clkout2 can off by control register.
 
+config COMMON_CLK_RP1
+	tristate "Raspberry Pi RP1-based clock support"
+	depends on PCI || COMPILE_TEST
+	depends on COMMON_CLK
+	help
+	  Enable common clock framework support for Raspberry Pi RP1.
+	  This mutli-function device has 3 main PLLs and several clock
+	  generators to drive the internal sub-peripherals.
+
 config COMMON_CLK_HI655X
 	tristate "Clock driver for Hi655x" if EXPERT
 	depends on (MFD_HI655X_PMIC || COMPILE_TEST)
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index f793a16cad40..15ae26e062a8 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -58,6 +58,7 @@ obj-$(CONFIG_CLK_LS1028A_PLLDIG)	+= clk-plldig.o
 obj-$(CONFIG_COMMON_CLK_PWM)		+= clk-pwm.o
 obj-$(CONFIG_CLK_QORIQ)			+= clk-qoriq.o
 obj-$(CONFIG_COMMON_CLK_RK808)		+= clk-rk808.o
+obj-$(CONFIG_COMMON_CLK_RP1)            += clk-rp1.o
 obj-$(CONFIG_COMMON_CLK_HI655X)		+= clk-hi655x.o
 obj-$(CONFIG_COMMON_CLK_S2MPS11)	+= clk-s2mps11.o
 obj-$(CONFIG_COMMON_CLK_SCMI)           += clk-scmi.o
diff --git a/drivers/clk/clk-rp1.c b/drivers/clk/clk-rp1.c
new file mode 100644
index 000000000000..d18e711c0623
--- /dev/null
+++ b/drivers/clk/clk-rp1.c
@@ -0,0 +1,1655 @@
+// SPDX-License-Identifier: GPL
+/*
+ * Copyright (C) 2023 Raspberry Pi Ltd.
+ *
+ * Clock driver for RP1 PCIe multifunction chip.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/math64.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <asm/div64.h>
+
+#include <dt-bindings/clock/rp1.h>
+
+#define PLL_SYS_OFFSET			0x08000
+#define PLL_SYS_CS			(PLL_SYS_OFFSET + 0x00)
+#define PLL_SYS_PWR			(PLL_SYS_OFFSET + 0x04)
+#define PLL_SYS_FBDIV_INT		(PLL_SYS_OFFSET + 0x08)
+#define PLL_SYS_FBDIV_FRAC		(PLL_SYS_OFFSET + 0x0c)
+#define PLL_SYS_PRIM			(PLL_SYS_OFFSET + 0x10)
+#define PLL_SYS_SEC			(PLL_SYS_OFFSET + 0x14)
+
+#define PLL_AUDIO_OFFSET		0x0c000
+#define PLL_AUDIO_CS			(PLL_AUDIO_OFFSET + 0x00)
+#define PLL_AUDIO_PWR			(PLL_AUDIO_OFFSET + 0x04)
+#define PLL_AUDIO_FBDIV_INT		(PLL_AUDIO_OFFSET + 0x08)
+#define PLL_AUDIO_FBDIV_FRAC		(PLL_AUDIO_OFFSET + 0x0c)
+#define PLL_AUDIO_PRIM			(PLL_AUDIO_OFFSET + 0x10)
+#define PLL_AUDIO_SEC			(PLL_AUDIO_OFFSET + 0x14)
+#define PLL_AUDIO_TERN			(PLL_AUDIO_OFFSET + 0x18)
+
+#define PLL_VIDEO_OFFSET		0x10000
+#define PLL_VIDEO_CS			(PLL_VIDEO_OFFSET + 0x00)
+#define PLL_VIDEO_PWR			(PLL_VIDEO_OFFSET + 0x04)
+#define PLL_VIDEO_FBDIV_INT		(PLL_VIDEO_OFFSET + 0x08)
+#define PLL_VIDEO_FBDIV_FRAC		(PLL_VIDEO_OFFSET + 0x0c)
+#define PLL_VIDEO_PRIM			(PLL_VIDEO_OFFSET + 0x10)
+#define PLL_VIDEO_SEC			(PLL_VIDEO_OFFSET + 0x14)
+
+#define GPCLK_OE_CTRL			0x00000
+
+#define CLK_SYS_OFFSET			0x00014
+#define CLK_SYS_CTRL			(CLK_SYS_OFFSET + 0x00)
+#define CLK_SYS_DIV_INT			(CLK_SYS_OFFSET + 0x04)
+#define CLK_SYS_SEL			(CLK_SYS_OFFSET + 0x0c)
+
+#define CLK_SLOW_OFFSET			0x00024
+#define CLK_SLOW_SYS_CTRL		(CLK_SLOW_OFFSET + 0x00)
+#define CLK_SLOW_SYS_DIV_INT		(CLK_SLOW_OFFSET + 0x04)
+#define CLK_SLOW_SYS_SEL		(CLK_SLOW_OFFSET + 0x0c)
+
+#define CLK_DMA_OFFSET			0x00044
+#define CLK_DMA_CTRL			(CLK_DMA_OFFSET + 0x00)
+#define CLK_DMA_DIV_INT			(CLK_DMA_OFFSET + 0x04)
+#define CLK_DMA_SEL			(CLK_DMA_OFFSET + 0x0c)
+
+#define CLK_UART_OFFSET			0x00054
+#define CLK_UART_CTRL			(CLK_UART_OFFSET + 0x00)
+#define CLK_UART_DIV_INT		(CLK_UART_OFFSET + 0x04)
+#define CLK_UART_SEL			(CLK_UART_OFFSET + 0x0c)
+
+#define CLK_ETH_OFFSET			0x00064
+#define CLK_ETH_CTRL			(CLK_ETH_OFFSET + 0x00)
+#define CLK_ETH_DIV_INT			(CLK_ETH_OFFSET + 0x04)
+#define CLK_ETH_SEL			(CLK_ETH_OFFSET + 0x0c)
+
+#define CLK_PWM0_OFFSET			0x00074
+#define CLK_PWM0_CTRL			(CLK_PWM0_OFFSET + 0x00)
+#define CLK_PWM0_DIV_INT		(CLK_PWM0_OFFSET + 0x04)
+#define CLK_PWM0_DIV_FRAC		(CLK_PWM0_OFFSET + 0x08)
+#define CLK_PWM0_SEL			(CLK_PWM0_OFFSET + 0x0c)
+
+#define CLK_PWM1_OFFSET			0x00084
+#define CLK_PWM1_CTRL			(CLK_PWM1_OFFSET + 0x00)
+#define CLK_PWM1_DIV_INT		(CLK_PWM1_OFFSET + 0x04)
+#define CLK_PWM1_DIV_FRAC		(CLK_PWM1_OFFSET + 0x08)
+#define CLK_PWM1_SEL			(CLK_PWM1_OFFSET + 0x0c)
+
+#define CLK_AUDIO_IN_OFFSET		0x00094
+#define CLK_AUDIO_IN_CTRL		(CLK_AUDIO_IN_OFFSET + 0x00)
+#define CLK_AUDIO_IN_DIV_INT		(CLK_AUDIO_IN_OFFSET + 0x04)
+#define CLK_AUDIO_IN_SEL		(CLK_AUDIO_IN_OFFSET + 0x0c)
+
+#define CLK_AUDIO_OUT_OFFSET		0x000a4
+#define CLK_AUDIO_OUT_CTRL		(CLK_AUDIO_OUT_OFFSET + 0x00)
+#define CLK_AUDIO_OUT_DIV_INT		(CLK_AUDIO_OUT_OFFSET + 0x04)
+#define CLK_AUDIO_OUT_SEL		(CLK_AUDIO_OUT_OFFSET + 0x0c)
+
+#define CLK_I2S_OFFSET			0x000b4
+#define CLK_I2S_CTRL			(CLK_I2S_OFFSET + 0x00)
+#define CLK_I2S_DIV_INT			(CLK_I2S_OFFSET + 0x04)
+#define CLK_I2S_SEL			(CLK_I2S_OFFSET + 0x0c)
+
+#define CLK_MIPI0_CFG_OFFSET		0x000c4
+#define CLK_MIPI0_CFG_CTRL		(CLK_MIPI0_CFG_OFFSET + 0x00)
+#define CLK_MIPI0_CFG_DIV_INT		(CLK_MIPI0_CFG_OFFSET + 0x04)
+#define CLK_MIPI0_CFG_SEL		(CLK_MIPI0_CFG_OFFSET + 0x0c)
+
+#define CLK_MIPI1_CFG_OFFSET		0x000d4
+#define CLK_MIPI1_CFG_CTRL		(CLK_MIPI1_CFG_OFFSET + 0x00)
+#define CLK_MIPI1_CFG_DIV_INT		(CLK_MIPI1_CFG_OFFSET + 0x04)
+#define CLK_MIPI1_CFG_SEL		(CLK_MIPI1_CFG_OFFSET + 0x0c)
+
+#define CLK_PCIE_AUX_OFFSET		0x000e4
+#define CLK_PCIE_AUX_CTRL		(CLK_PCIE_AUX_OFFSET + 0x00)
+#define CLK_PCIE_AUX_DIV_INT		(CLK_PCIE_AUX_OFFSET + 0x04)
+#define CLK_PCIE_AUX_SEL		(CLK_PCIE_AUX_OFFSET + 0x0c)
+
+#define CLK_USBH0_MICROFRAME_OFFSET	0x000f4
+#define CLK_USBH0_MICROFRAME_CTRL	(CLK_USBH0_MICROFRAME_OFFSET + 0x00)
+#define CLK_USBH0_MICROFRAME_DIV_INT	(CLK_USBH0_MICROFRAME_OFFSET + 0x04)
+#define CLK_USBH0_MICROFRAME_SEL	(CLK_USBH0_MICROFRAME_OFFSET + 0x0c)
+
+#define CLK_USBH1_MICROFRAME_OFFSET	0x00104
+#define CLK_USBH1_MICROFRAME_CTRL	(CLK_USBH1_MICROFRAME_OFFSET + 0x00)
+#define CLK_USBH1_MICROFRAME_DIV_INT	(CLK_USBH1_MICROFRAME_OFFSET + 0x04)
+#define CLK_USBH1_MICROFRAME_SEL	(CLK_USBH1_MICROFRAME_OFFSET + 0x0c)
+
+#define CLK_USBH0_SUSPEND_OFFSET	0x00114
+#define CLK_USBH0_SUSPEND_CTRL		(CLK_USBH0_SUSPEND_OFFSET + 0x00)
+#define CLK_USBH0_SUSPEND_DIV_INT	(CLK_USBH0_SUSPEND_OFFSET + 0x04)
+#define CLK_USBH0_SUSPEND_SEL		(CLK_USBH0_SUSPEND_OFFSET + 0x0c)
+
+#define CLK_USBH1_SUSPEND_OFFSET	0x00124
+#define CLK_USBH1_SUSPEND_CTRL		(CLK_USBH1_SUSPEND_OFFSET + 0x00)
+#define CLK_USBH1_SUSPEND_DIV_INT	(CLK_USBH1_SUSPEND_OFFSET + 0x04)
+#define CLK_USBH1_SUSPEND_SEL		(CLK_USBH1_SUSPEND_OFFSET + 0x0c)
+
+#define CLK_ETH_TSU_OFFSET		0x00134
+#define CLK_ETH_TSU_CTRL		(CLK_ETH_TSU_OFFSET + 0x00)
+#define CLK_ETH_TSU_DIV_INT		(CLK_ETH_TSU_OFFSET + 0x04)
+#define CLK_ETH_TSU_SEL			(CLK_ETH_TSU_OFFSET + 0x0c)
+
+#define CLK_ADC_OFFSET			0x00144
+#define CLK_ADC_CTRL			(CLK_ADC_OFFSET + 0x00)
+#define CLK_ADC_DIV_INT			(CLK_ADC_OFFSET + 0x04)
+#define CLK_ADC_SEL			(CLK_ADC_OFFSET + 0x0c)
+
+#define CLK_SDIO_TIMER_OFFSET		0x00154
+#define CLK_SDIO_TIMER_CTRL		(CLK_SDIO_TIMER_OFFSET + 0x00)
+#define CLK_SDIO_TIMER_DIV_INT		(CLK_SDIO_TIMER_OFFSET + 0x04)
+#define CLK_SDIO_TIMER_SEL		(CLK_SDIO_TIMER_OFFSET + 0x0c)
+
+#define CLK_SDIO_ALT_SRC_OFFSET		0x00164
+#define CLK_SDIO_ALT_SRC_CTRL		(CLK_SDIO_ALT_SRC_OFFSET + 0x00)
+#define CLK_SDIO_ALT_SRC_DIV_INT	(CLK_SDIO_ALT_SRC_OFFSET + 0x04)
+#define CLK_SDIO_ALT_SRC_SEL		(CLK_SDIO_ALT_SRC_OFFSET + 0x0c)
+
+#define CLK_GP0_OFFSET			0x00174
+#define CLK_GP0_CTRL			(CLK_GP0_OFFSET + 0x00)
+#define CLK_GP0_DIV_INT			(CLK_GP0_OFFSET + 0x04)
+#define CLK_GP0_DIV_FRAC		(CLK_GP0_OFFSET + 0x08)
+#define CLK_GP0_SEL			(CLK_GP0_OFFSET + 0x0c)
+
+#define CLK_GP1_OFFSET			0x00184
+#define CLK_GP1_CTRL			(CLK_GP1_OFFSET + 0x00)
+#define CLK_GP1_DIV_INT			(CLK_GP1_OFFSET + 0x04)
+#define CLK_GP1_DIV_FRAC		(CLK_GP1_OFFSET + 0x08)
+#define CLK_GP1_SEL			(CLK_GP1_OFFSET + 0x0c)
+
+#define CLK_GP2_OFFSET			0x00194
+#define CLK_GP2_CTRL			(CLK_GP2_OFFSET + 0x00)
+#define CLK_GP2_DIV_INT			(CLK_GP2_OFFSET + 0x04)
+#define CLK_GP2_DIV_FRAC		(CLK_GP2_OFFSET + 0x08)
+#define CLK_GP2_SEL			(CLK_GP2_OFFSET + 0x0c)
+
+#define CLK_GP3_OFFSET			0x001a4
+#define CLK_GP3_CTRL			(CLK_GP3_OFFSET + 0x00)
+#define CLK_GP3_DIV_INT			(CLK_GP3_OFFSET + 0x04)
+#define CLK_GP3_DIV_FRAC		(CLK_GP3_OFFSET + 0x08)
+#define CLK_GP3_SEL			(CLK_GP3_OFFSET + 0x0c)
+
+#define CLK_GP4_OFFSET			0x001b4
+#define CLK_GP4_CTRL			(CLK_GP4_OFFSET + 0x00)
+#define CLK_GP4_DIV_INT			(CLK_GP4_OFFSET + 0x04)
+#define CLK_GP4_DIV_FRAC		(CLK_GP4_OFFSET + 0x08)
+#define CLK_GP4_SEL			(CLK_GP4_OFFSET + 0x0c)
+
+#define CLK_GP5_OFFSET			0x001c4
+#define CLK_GP5_CTRL			(CLK_GP5_OFFSET + 0x00)
+#define CLK_GP5_DIV_INT			(CLK_GP5_OFFSET + 0x04)
+#define CLK_GP5_DIV_FRAC		(CLK_GP5_OFFSET + 0x08)
+#define CLK_GP5_SEL			(CLK_GP5_OFFSET + 0x0c)
+
+#define CLK_SYS_RESUS_CTRL		0x0020c
+
+#define CLK_SLOW_SYS_RESUS_CTRL		0x00214
+
+#define FC0_OFFSET			0x0021c
+#define FC0_REF_KHZ			(FC0_OFFSET + 0x00)
+#define FC0_MIN_KHZ			(FC0_OFFSET + 0x04)
+#define FC0_MAX_KHZ			(FC0_OFFSET + 0x08)
+#define FC0_DELAY			(FC0_OFFSET + 0x0c)
+#define FC0_INTERVAL			(FC0_OFFSET + 0x10)
+#define FC0_SRC				(FC0_OFFSET + 0x14)
+#define FC0_STATUS			(FC0_OFFSET + 0x18)
+#define FC0_RESULT			(FC0_OFFSET + 0x1c)
+#define FC_SIZE				0x20
+#define FC_COUNT			8
+#define FC_NUM(idx, off)		((idx) * 32 + (off))
+
+#define AUX_SEL				1
+
+#define VIDEO_CLOCKS_OFFSET		0x4000
+#define VIDEO_CLK_VEC_CTRL		(VIDEO_CLOCKS_OFFSET + 0x0000)
+#define VIDEO_CLK_VEC_DIV_INT		(VIDEO_CLOCKS_OFFSET + 0x0004)
+#define VIDEO_CLK_VEC_SEL		(VIDEO_CLOCKS_OFFSET + 0x000c)
+#define VIDEO_CLK_DPI_CTRL		(VIDEO_CLOCKS_OFFSET + 0x0010)
+#define VIDEO_CLK_DPI_DIV_INT		(VIDEO_CLOCKS_OFFSET + 0x0014)
+#define VIDEO_CLK_DPI_SEL		(VIDEO_CLOCKS_OFFSET + 0x001c)
+#define VIDEO_CLK_MIPI0_DPI_CTRL	(VIDEO_CLOCKS_OFFSET + 0x0020)
+#define VIDEO_CLK_MIPI0_DPI_DIV_INT	(VIDEO_CLOCKS_OFFSET + 0x0024)
+#define VIDEO_CLK_MIPI0_DPI_DIV_FRAC	(VIDEO_CLOCKS_OFFSET + 0x0028)
+#define VIDEO_CLK_MIPI0_DPI_SEL		(VIDEO_CLOCKS_OFFSET + 0x002c)
+#define VIDEO_CLK_MIPI1_DPI_CTRL	(VIDEO_CLOCKS_OFFSET + 0x0030)
+#define VIDEO_CLK_MIPI1_DPI_DIV_INT	(VIDEO_CLOCKS_OFFSET + 0x0034)
+#define VIDEO_CLK_MIPI1_DPI_DIV_FRAC	(VIDEO_CLOCKS_OFFSET + 0x0038)
+#define VIDEO_CLK_MIPI1_DPI_SEL		(VIDEO_CLOCKS_OFFSET + 0x003c)
+
+#define DIV_INT_8BIT_MAX		GENMASK(7, 0)	/* max divide for most clocks */
+#define DIV_INT_16BIT_MAX		GENMASK(15, 0)	/* max divide for GPx, PWM */
+#define DIV_INT_24BIT_MAX               GENMASK(23, 0)	/* max divide for CLK_SYS */
+
+#define FC0_STATUS_DONE			BIT(4)
+#define FC0_STATUS_RUNNING		BIT(8)
+#define FC0_RESULT_FRAC_SHIFT		5
+
+#define PLL_PRIM_DIV1_SHIFT		16
+#define PLL_PRIM_DIV1_WIDTH		3
+#define PLL_PRIM_DIV1_MASK		GENMASK(PLL_PRIM_DIV1_SHIFT + \
+						PLL_PRIM_DIV1_WIDTH - 1, \
+						PLL_PRIM_DIV1_SHIFT)
+#define PLL_PRIM_DIV2_SHIFT		12
+#define PLL_PRIM_DIV2_WIDTH		3
+#define PLL_PRIM_DIV2_MASK		GENMASK(PLL_PRIM_DIV2_SHIFT + \
+						PLL_PRIM_DIV2_WIDTH - 1, \
+						PLL_PRIM_DIV2_SHIFT)
+
+#define PLL_SEC_DIV_SHIFT		8
+#define PLL_SEC_DIV_WIDTH		5
+#define PLL_SEC_DIV_MASK		GENMASK(PLL_SEC_DIV_SHIFT + \
+						PLL_SEC_DIV_WIDTH - 1, \
+						PLL_SEC_DIV_SHIFT)
+
+#define PLL_CS_LOCK			BIT(31)
+#define PLL_CS_REFDIV_SHIFT		0
+
+#define PLL_PWR_PD			BIT(0)
+#define PLL_PWR_DACPD			BIT(1)
+#define PLL_PWR_DSMPD			BIT(2)
+#define PLL_PWR_POSTDIVPD		BIT(3)
+#define PLL_PWR_4PHASEPD		BIT(4)
+#define PLL_PWR_VCOPD			BIT(5)
+#define PLL_PWR_MASK			GENMASK(5, 0)
+
+#define PLL_SEC_RST			BIT(16)
+#define PLL_SEC_IMPL			BIT(31)
+
+/* PLL phase output for both PRI and SEC */
+#define PLL_PH_EN			BIT(4)
+#define PLL_PH_PHASE_SHIFT		0
+
+#define RP1_PLL_PHASE_0			0
+#define RP1_PLL_PHASE_90		1
+#define RP1_PLL_PHASE_180		2
+#define RP1_PLL_PHASE_270		3
+
+/* Clock fields for all clocks */
+#define CLK_CTRL_ENABLE			BIT(11)
+#define CLK_CTRL_AUXSRC_SHIFT		5
+#define CLK_CTRL_AUXSRC_WIDTH		5
+#define CLK_CTRL_AUXSRC_MASK		GENMASK(CLK_CTRL_AUXSRC_SHIFT + \
+						CLK_CTRL_AUXSRC_WIDTH - 1, \
+						CLK_CTRL_AUXSRC_SHIFT)
+#define CLK_CTRL_SRC_SHIFT		0
+#define CLK_DIV_FRAC_BITS		16
+
+#define KHz				1000
+#define MHz				(KHz * KHz)
+#define LOCK_TIMEOUT_NS			100000000
+#define FC_TIMEOUT_NS			100000000
+
+#define MAX_CLK_PARENTS			16
+
+/*
+ * Names of the reference clock for the pll cores. This name must match
+ * the DT reference clock-output-name.
+ */
+//static const char *const ref_clock = "xosc";
+
+/*
+ * Secondary PLL channel output divider table.
+ * Divider values range from 8 to 19.
+ * Invalid values default to 19
+ */
+static const struct clk_div_table pll_sec_div_table[] = {
+	{ 0x00, 19 },
+	{ 0x01, 19 },
+	{ 0x02, 19 },
+	{ 0x03, 19 },
+	{ 0x04, 19 },
+	{ 0x05, 19 },
+	{ 0x06, 19 },
+	{ 0x07, 19 },
+	{ 0x08,  8 },
+	{ 0x09,  9 },
+	{ 0x0a, 10 },
+	{ 0x0b, 11 },
+	{ 0x0c, 12 },
+	{ 0x0d, 13 },
+	{ 0x0e, 14 },
+	{ 0x0f, 15 },
+	{ 0x10, 16 },
+	{ 0x11, 17 },
+	{ 0x12, 18 },
+	{ 0x13, 19 },
+	{ 0x14, 19 },
+	{ 0x15, 19 },
+	{ 0x16, 19 },
+	{ 0x17, 19 },
+	{ 0x18, 19 },
+	{ 0x19, 19 },
+	{ 0x1a, 19 },
+	{ 0x1b, 19 },
+	{ 0x1c, 19 },
+	{ 0x1d, 19 },
+	{ 0x1e, 19 },
+	{ 0x1f, 19 },
+	{ 0 }
+};
+
+struct rp1_clockman {
+	struct device *dev;
+	void __iomem *regs;
+	spinlock_t regs_lock; /* spinlock for all clocks */
+	struct clk_hw *hw_xosc; /* reference clock */
+
+	/* Must be last */
+	struct clk_hw_onecell_data onecell;
+};
+
+struct rp1_pll_core_data {
+	const char *name;
+	u32 cs_reg;
+	u32 pwr_reg;
+	u32 fbdiv_int_reg;
+	u32 fbdiv_frac_reg;
+	unsigned long flags;
+	u32 fc0_src;
+};
+
+struct rp1_pll_data {
+	const char *name;
+	const char *source_pll;
+	u32 ctrl_reg;
+	unsigned long flags;
+	u32 fc0_src;
+};
+
+struct rp1_pll_ph_data {
+	const char *name;
+	const char *source_pll;
+	unsigned int phase;
+	unsigned int fixed_divider;
+	u32 ph_reg;
+	unsigned long flags;
+	u32 fc0_src;
+};
+
+struct rp1_pll_divider_data {
+	const char *name;
+	const char *source_pll;
+	u32 sec_reg;
+	unsigned long flags;
+	u32 fc0_src;
+};
+
+struct rp1_clock_data {
+	const char *name;
+	const char *const parents[MAX_CLK_PARENTS];
+	int num_std_parents;
+	int num_aux_parents;
+	unsigned long flags;
+	u32 oe_mask;
+	u32 clk_src_mask;
+	u32 ctrl_reg;
+	u32 div_int_reg;
+	u32 div_frac_reg;
+	u32 sel_reg;
+	u32 div_int_max;
+	unsigned long max_freq;
+	u32 fc0_src;
+};
+
+struct rp1_pll_core {
+	struct clk_hw hw;
+	struct rp1_clockman *clockman;
+	unsigned long cached_rate;
+	const struct rp1_pll_core_data *data;
+};
+
+struct rp1_pll {
+	struct clk_hw hw;
+	struct rp1_clockman *clockman;
+	struct clk_divider div;
+	unsigned long cached_rate;
+	const struct rp1_pll_data *data;
+};
+
+struct rp1_pll_ph {
+	struct clk_hw hw;
+	struct rp1_clockman *clockman;
+	const struct rp1_pll_ph_data *data;
+};
+
+struct rp1_clock {
+	struct clk_hw hw;
+	struct rp1_clockman *clockman;
+	unsigned long cached_rate;
+	const struct rp1_clock_data *data;
+};
+
+struct rp1_clk_change {
+	struct clk_hw *hw;
+	unsigned long new_rate;
+};
+
+struct rp1_clk_desc {
+	struct clk_hw *(*clk_register)(struct rp1_clockman *clockman,
+				       const void *data);
+	const void *data;
+};
+
+static void rp1_debugfs_regset(struct rp1_clockman *clockman, u32 base,
+			       const struct debugfs_reg32 *regs,
+			       size_t nregs, struct dentry *dentry)
+{
+	struct debugfs_regset32 *regset;
+
+	regset = devm_kzalloc(clockman->dev, sizeof(*regset), GFP_KERNEL);
+	if (!regset)
+		return;
+
+	regset->regs = regs;
+	regset->nregs = nregs;
+	regset->base = clockman->regs + base;
+
+	debugfs_create_regset32("regdump", 0444, dentry, regset);
+}
+
+static inline u32 set_register_field(u32 reg, u32 val, u32 mask, u32 shift)
+{
+	reg &= ~mask;
+	reg |= (val << shift) & mask;
+	return reg;
+}
+
+static inline
+void clockman_write(struct rp1_clockman *clockman, u32 reg, u32 val)
+{
+	writel(val, clockman->regs + reg);
+}
+
+static inline u32 clockman_read(struct rp1_clockman *clockman, u32 reg)
+{
+	return readl(clockman->regs + reg);
+}
+
+static int rp1_pll_core_is_on(struct clk_hw *hw)
+{
+	struct rp1_pll_core *pll_core = container_of(hw, struct rp1_pll_core, hw);
+	struct rp1_clockman *clockman = pll_core->clockman;
+	const struct rp1_pll_core_data *data = pll_core->data;
+	u32 pwr = clockman_read(clockman, data->pwr_reg);
+
+	return (pwr & PLL_PWR_PD) || (pwr & PLL_PWR_POSTDIVPD);
+}
+
+static int rp1_pll_core_on(struct clk_hw *hw)
+{
+	struct rp1_pll_core *pll_core = container_of(hw, struct rp1_pll_core, hw);
+	struct rp1_clockman *clockman = pll_core->clockman;
+	const struct rp1_pll_core_data *data = pll_core->data;
+	u32 fbdiv_frac;
+	ktime_t timeout;
+
+	spin_lock(&clockman->regs_lock);
+
+	if (!(clockman_read(clockman, data->cs_reg) & PLL_CS_LOCK)) {
+		/* Reset to a known state. */
+		clockman_write(clockman, data->pwr_reg, PLL_PWR_MASK);
+		clockman_write(clockman, data->fbdiv_int_reg, 20);
+		clockman_write(clockman, data->fbdiv_frac_reg, 0);
+		clockman_write(clockman, data->cs_reg, 1 << PLL_CS_REFDIV_SHIFT);
+	}
+
+	/* Come out of reset. */
+	fbdiv_frac = clockman_read(clockman, data->fbdiv_frac_reg);
+	clockman_write(clockman, data->pwr_reg, fbdiv_frac ? 0 : PLL_PWR_DSMPD);
+	spin_unlock(&clockman->regs_lock);
+
+	/* Wait for the PLL to lock. */
+	timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS);
+	while (!(clockman_read(clockman, data->cs_reg) & PLL_CS_LOCK)) {
+		if (ktime_after(ktime_get(), timeout)) {
+			dev_err(clockman->dev, "%s: can't lock PLL\n",
+				clk_hw_get_name(hw));
+			return -ETIMEDOUT;
+		}
+		cpu_relax();
+	}
+
+	return 0;
+}
+
+static void rp1_pll_core_off(struct clk_hw *hw)
+{
+	struct rp1_pll_core *pll_core = container_of(hw, struct rp1_pll_core, hw);
+	struct rp1_clockman *clockman = pll_core->clockman;
+	const struct rp1_pll_core_data *data = pll_core->data;
+
+	spin_lock(&clockman->regs_lock);
+	clockman_write(clockman, data->pwr_reg, 0);
+	spin_unlock(&clockman->regs_lock);
+}
+
+static inline unsigned long get_pll_core_divider(struct clk_hw *hw,
+						 unsigned long rate,
+						 unsigned long parent_rate,
+						 u32 *div_int, u32 *div_frac)
+{
+	unsigned long calc_rate;
+	u32 fbdiv_int, fbdiv_frac;
+	u64 div_fp64; /* 32.32 fixed point fraction. */
+
+	/* Factor of reference clock to VCO frequency. */
+	div_fp64 = (u64)(rate) << 32;
+	div_fp64 = DIV_ROUND_CLOSEST_ULL(div_fp64, parent_rate);
+
+	/* Round the fractional component at 24 bits. */
+	div_fp64 += 1 << (32 - 24 - 1);
+
+	fbdiv_int = div_fp64 >> 32;
+	fbdiv_frac = (div_fp64 >> (32 - 24)) & 0xffffff;
+
+	calc_rate =
+		((u64)parent_rate * (((u64)fbdiv_int << 24) + fbdiv_frac) + (1 << 23)) >> 24;
+
+	*div_int = fbdiv_int;
+	*div_frac = fbdiv_frac;
+
+	return calc_rate;
+}
+
+static int rp1_pll_core_set_rate(struct clk_hw *hw,
+				 unsigned long rate, unsigned long parent_rate)
+{
+	struct rp1_pll_core *pll_core = container_of(hw, struct rp1_pll_core, hw);
+	struct rp1_clockman *clockman = pll_core->clockman;
+	const struct rp1_pll_core_data *data = pll_core->data;
+	unsigned long calc_rate;
+	u32 fbdiv_int, fbdiv_frac;
+
+	/* Disable dividers to start with. */
+	spin_lock(&clockman->regs_lock);
+	clockman_write(clockman, data->fbdiv_int_reg, 0);
+	clockman_write(clockman, data->fbdiv_frac_reg, 0);
+	spin_unlock(&clockman->regs_lock);
+
+	calc_rate = get_pll_core_divider(hw, rate, parent_rate,
+					 &fbdiv_int, &fbdiv_frac);
+
+	spin_lock(&clockman->regs_lock);
+	clockman_write(clockman, data->pwr_reg, fbdiv_frac ? 0 : PLL_PWR_DSMPD);
+	clockman_write(clockman, data->fbdiv_int_reg, fbdiv_int);
+	clockman_write(clockman, data->fbdiv_frac_reg, fbdiv_frac);
+	spin_unlock(&clockman->regs_lock);
+
+	/* Check that reference frequency is no greater than VCO / 16. */
+	if (WARN_ON_ONCE(parent_rate > (rate / 16)))
+		return -ERANGE;
+
+	pll_core->cached_rate = calc_rate;
+
+	spin_lock(&clockman->regs_lock);
+	/* Don't need to divide ref unless parent_rate > (output freq / 16) */
+	clockman_write(clockman, data->cs_reg,
+		       clockman_read(clockman, data->cs_reg) |
+				     (1 << PLL_CS_REFDIV_SHIFT));
+	spin_unlock(&clockman->regs_lock);
+
+	return 0;
+}
+
+static unsigned long rp1_pll_core_recalc_rate(struct clk_hw *hw,
+					      unsigned long parent_rate)
+{
+	struct rp1_pll_core *pll_core = container_of(hw, struct rp1_pll_core, hw);
+	struct rp1_clockman *clockman = pll_core->clockman;
+	const struct rp1_pll_core_data *data = pll_core->data;
+	u32 fbdiv_int, fbdiv_frac;
+	unsigned long calc_rate;
+
+	fbdiv_int = clockman_read(clockman, data->fbdiv_int_reg);
+	fbdiv_frac = clockman_read(clockman, data->fbdiv_frac_reg);
+	calc_rate =
+		((u64)parent_rate * (((u64)fbdiv_int << 24) + fbdiv_frac) + (1 << 23)) >> 24;
+
+	return calc_rate;
+}
+
+static long rp1_pll_core_round_rate(struct clk_hw *hw, unsigned long rate,
+				    unsigned long *parent_rate)
+{
+	u32 fbdiv_int, fbdiv_frac;
+	long calc_rate;
+
+	calc_rate = get_pll_core_divider(hw, rate, *parent_rate,
+					 &fbdiv_int, &fbdiv_frac);
+	return calc_rate;
+}
+
+static void rp1_pll_core_debug_init(struct clk_hw *hw, struct dentry *dentry)
+{
+	struct rp1_pll_core *pll_core = container_of(hw, struct rp1_pll_core, hw);
+	struct rp1_clockman *clockman = pll_core->clockman;
+	const struct rp1_pll_core_data *data = pll_core->data;
+	struct debugfs_reg32 *regs;
+
+	regs = devm_kcalloc(clockman->dev, 4, sizeof(*regs), GFP_KERNEL);
+	if (!regs)
+		return;
+
+	regs[0].name = "cs";
+	regs[0].offset = data->cs_reg;
+	regs[1].name = "pwr";
+	regs[1].offset = data->pwr_reg;
+	regs[2].name = "fbdiv_int";
+	regs[2].offset = data->fbdiv_int_reg;
+	regs[3].name = "fbdiv_frac";
+	regs[3].offset = data->fbdiv_frac_reg;
+
+	rp1_debugfs_regset(clockman, 0, regs, 4, dentry);
+}
+
+static void get_pll_prim_dividers(unsigned long rate, unsigned long parent_rate,
+				  u32 *divider1, u32 *divider2)
+{
+	unsigned int div1, div2;
+	unsigned int best_div1 = 7, best_div2 = 7;
+	unsigned long best_rate_diff =
+		abs_diff(DIV_ROUND_CLOSEST(parent_rate, best_div1 * best_div2), rate);
+	unsigned long rate_diff, calc_rate;
+
+	for (div1 = 1; div1 <= 7; div1++) {
+		for (div2 = 1; div2 <= div1; div2++) {
+			calc_rate = DIV_ROUND_CLOSEST(parent_rate, div1 * div2);
+			rate_diff = abs_diff(calc_rate, rate);
+
+			if (calc_rate == rate) {
+				best_div1 = div1;
+				best_div2 = div2;
+				goto done;
+			} else if (rate_diff < best_rate_diff) {
+				best_div1 = div1;
+				best_div2 = div2;
+				best_rate_diff = rate_diff;
+			}
+		}
+	}
+
+done:
+	*divider1 = best_div1;
+	*divider2 = best_div2;
+}
+
+static int rp1_pll_set_rate(struct clk_hw *hw,
+			    unsigned long rate, unsigned long parent_rate)
+{
+	struct rp1_pll *pll = container_of(hw, struct rp1_pll, hw);
+	struct rp1_clockman *clockman = pll->clockman;
+	const struct rp1_pll_data *data = pll->data;
+	u32 prim, prim_div1, prim_div2;
+
+	get_pll_prim_dividers(rate, parent_rate, &prim_div1, &prim_div2);
+
+	spin_lock(&clockman->regs_lock);
+	prim = clockman_read(clockman, data->ctrl_reg);
+	prim = set_register_field(prim, prim_div1, PLL_PRIM_DIV1_MASK,
+				  PLL_PRIM_DIV1_SHIFT);
+	prim = set_register_field(prim, prim_div2, PLL_PRIM_DIV2_MASK,
+				  PLL_PRIM_DIV2_SHIFT);
+	clockman_write(clockman, data->ctrl_reg, prim);
+	spin_unlock(&clockman->regs_lock);
+
+	return 0;
+}
+
+static unsigned long rp1_pll_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate)
+{
+	struct rp1_pll *pll = container_of(hw, struct rp1_pll, hw);
+	struct rp1_clockman *clockman = pll->clockman;
+	const struct rp1_pll_data *data = pll->data;
+	u32 prim, prim_div1, prim_div2;
+
+	prim = clockman_read(clockman, data->ctrl_reg);
+	prim_div1 = (prim & PLL_PRIM_DIV1_MASK) >> PLL_PRIM_DIV1_SHIFT;
+	prim_div2 = (prim & PLL_PRIM_DIV2_MASK) >> PLL_PRIM_DIV2_SHIFT;
+
+	if (!prim_div1 || !prim_div2) {
+		dev_err(clockman->dev, "%s: (%s) zero divider value\n",
+			__func__, data->name);
+		return 0;
+	}
+
+	return DIV_ROUND_CLOSEST(parent_rate, prim_div1 * prim_div2);
+}
+
+static long rp1_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+			       unsigned long *parent_rate)
+{
+	u32 div1, div2;
+
+	get_pll_prim_dividers(rate, *parent_rate, &div1, &div2);
+
+	return DIV_ROUND_CLOSEST(*parent_rate, div1 * div2);
+}
+
+static void rp1_pll_debug_init(struct clk_hw *hw,
+			       struct dentry *dentry)
+{
+	struct rp1_pll *pll = container_of(hw, struct rp1_pll, hw);
+	struct rp1_clockman *clockman = pll->clockman;
+	const struct rp1_pll_data *data = pll->data;
+	struct debugfs_reg32 *regs;
+
+	regs = devm_kcalloc(clockman->dev, 1, sizeof(*regs), GFP_KERNEL);
+	if (!regs)
+		return;
+
+	regs[0].name = "prim";
+	regs[0].offset = data->ctrl_reg;
+
+	rp1_debugfs_regset(clockman, 0, regs, 1, dentry);
+}
+
+static int rp1_pll_ph_is_on(struct clk_hw *hw)
+{
+	struct rp1_pll_ph *pll = container_of(hw, struct rp1_pll_ph, hw);
+	struct rp1_clockman *clockman = pll->clockman;
+	const struct rp1_pll_ph_data *data = pll->data;
+
+	return !!(clockman_read(clockman, data->ph_reg) & PLL_PH_EN);
+}
+
+static int rp1_pll_ph_on(struct clk_hw *hw)
+{
+	struct rp1_pll_ph *pll_ph = container_of(hw, struct rp1_pll_ph, hw);
+	struct rp1_clockman *clockman = pll_ph->clockman;
+	const struct rp1_pll_ph_data *data = pll_ph->data;
+	u32 ph_reg;
+
+	/* todo: ensure pri/sec is enabled! */
+	spin_lock(&clockman->regs_lock);
+	ph_reg = clockman_read(clockman, data->ph_reg);
+	ph_reg |= data->phase << PLL_PH_PHASE_SHIFT;
+	ph_reg |= PLL_PH_EN;
+	clockman_write(clockman, data->ph_reg, ph_reg);
+	spin_unlock(&clockman->regs_lock);
+
+	return 0;
+}
+
+static void rp1_pll_ph_off(struct clk_hw *hw)
+{
+	struct rp1_pll_ph *pll_ph = container_of(hw, struct rp1_pll_ph, hw);
+	struct rp1_clockman *clockman = pll_ph->clockman;
+	const struct rp1_pll_ph_data *data = pll_ph->data;
+
+	spin_lock(&clockman->regs_lock);
+	clockman_write(clockman, data->ph_reg,
+		       clockman_read(clockman, data->ph_reg) & ~PLL_PH_EN);
+	spin_unlock(&clockman->regs_lock);
+}
+
+static int rp1_pll_ph_set_rate(struct clk_hw *hw,
+			       unsigned long rate, unsigned long parent_rate)
+{
+	struct rp1_pll_ph *pll_ph = container_of(hw, struct rp1_pll_ph, hw);
+	const struct rp1_pll_ph_data *data = pll_ph->data;
+
+	/* Nothing really to do here! */
+	WARN_ON(data->fixed_divider != 1 && data->fixed_divider != 2);
+	WARN_ON(rate != parent_rate / data->fixed_divider);
+
+	return 0;
+}
+
+static unsigned long rp1_pll_ph_recalc_rate(struct clk_hw *hw,
+					    unsigned long parent_rate)
+{
+	struct rp1_pll_ph *pll_ph = container_of(hw, struct rp1_pll_ph, hw);
+	const struct rp1_pll_ph_data *data = pll_ph->data;
+
+	return parent_rate / data->fixed_divider;
+}
+
+static long rp1_pll_ph_round_rate(struct clk_hw *hw, unsigned long rate,
+				  unsigned long *parent_rate)
+{
+	struct rp1_pll_ph *pll_ph = container_of(hw, struct rp1_pll_ph, hw);
+	const struct rp1_pll_ph_data *data = pll_ph->data;
+
+	return *parent_rate / data->fixed_divider;
+}
+
+static void rp1_pll_ph_debug_init(struct clk_hw *hw,
+				  struct dentry *dentry)
+{
+	struct rp1_pll_ph *pll_ph = container_of(hw, struct rp1_pll_ph, hw);
+	const struct rp1_pll_ph_data *data = pll_ph->data;
+	struct rp1_clockman *clockman = pll_ph->clockman;
+	struct debugfs_reg32 *regs;
+
+	regs = devm_kcalloc(clockman->dev, 1, sizeof(*regs), GFP_KERNEL);
+	if (!regs)
+		return;
+
+	regs[0].name = "ph_reg";
+	regs[0].offset = data->ph_reg;
+
+	rp1_debugfs_regset(clockman, 0, regs, 1, dentry);
+}
+
+static int rp1_pll_divider_is_on(struct clk_hw *hw)
+{
+	struct rp1_pll *divider = container_of(hw, struct rp1_pll, div.hw);
+	struct rp1_clockman *clockman = divider->clockman;
+	const struct rp1_pll_data *data = divider->data;
+
+	return !(clockman_read(clockman, data->ctrl_reg) & PLL_SEC_RST);
+}
+
+static int rp1_pll_divider_on(struct clk_hw *hw)
+{
+	struct rp1_pll *divider = container_of(hw, struct rp1_pll, div.hw);
+	struct rp1_clockman *clockman = divider->clockman;
+	const struct rp1_pll_data *data = divider->data;
+
+	spin_lock(&clockman->regs_lock);
+	/* Check the implementation bit is set! */
+	WARN_ON(!(clockman_read(clockman, data->ctrl_reg) & PLL_SEC_IMPL));
+	clockman_write(clockman, data->ctrl_reg,
+		       clockman_read(clockman, data->ctrl_reg) & ~PLL_SEC_RST);
+	spin_unlock(&clockman->regs_lock);
+
+	return 0;
+}
+
+static void rp1_pll_divider_off(struct clk_hw *hw)
+{
+	struct rp1_pll *divider = container_of(hw, struct rp1_pll, div.hw);
+	struct rp1_clockman *clockman = divider->clockman;
+	const struct rp1_pll_data *data = divider->data;
+
+	spin_lock(&clockman->regs_lock);
+	clockman_write(clockman, data->ctrl_reg, PLL_SEC_RST);
+	spin_unlock(&clockman->regs_lock);
+}
+
+static int rp1_pll_divider_set_rate(struct clk_hw *hw,
+				    unsigned long rate,
+				    unsigned long parent_rate)
+{
+	struct rp1_pll *divider = container_of(hw, struct rp1_pll, div.hw);
+	struct rp1_clockman *clockman = divider->clockman;
+	const struct rp1_pll_data *data = divider->data;
+	u32 div, sec;
+
+	div = DIV_ROUND_UP_ULL(parent_rate, rate);
+	div = clamp(div, 8u, 19u);
+
+	spin_lock(&clockman->regs_lock);
+	sec = clockman_read(clockman, data->ctrl_reg);
+	sec = set_register_field(sec, div, PLL_SEC_DIV_MASK, PLL_SEC_DIV_SHIFT);
+
+	/* Must keep the divider in reset to change the value. */
+	sec |= PLL_SEC_RST;
+	clockman_write(clockman, data->ctrl_reg, sec);
+
+	// todo: must sleep 10 pll vco cycles
+	sec &= ~PLL_SEC_RST;
+	clockman_write(clockman, data->ctrl_reg, sec);
+	spin_unlock(&clockman->regs_lock);
+
+	return 0;
+}
+
+static unsigned long rp1_pll_divider_recalc_rate(struct clk_hw *hw,
+						 unsigned long parent_rate)
+{
+	return clk_divider_ops.recalc_rate(hw, parent_rate);
+}
+
+static long rp1_pll_divider_round_rate(struct clk_hw *hw,
+				       unsigned long rate,
+				       unsigned long *parent_rate)
+{
+	return clk_divider_ops.round_rate(hw, rate, parent_rate);
+}
+
+static void rp1_pll_divider_debug_init(struct clk_hw *hw, struct dentry *dentry)
+{
+	struct rp1_pll *divider = container_of(hw, struct rp1_pll, div.hw);
+	struct rp1_clockman *clockman = divider->clockman;
+	const struct rp1_pll_data *data = divider->data;
+	struct debugfs_reg32 *regs;
+
+	regs = devm_kcalloc(clockman->dev, 1, sizeof(*regs), GFP_KERNEL);
+	if (!regs)
+		return;
+
+	regs[0].name = "sec";
+	regs[0].offset = data->ctrl_reg;
+
+	rp1_debugfs_regset(clockman, 0, regs, 1, dentry);
+}
+
+static int rp1_clock_is_on(struct clk_hw *hw)
+{
+	struct rp1_clock *clock = container_of(hw, struct rp1_clock, hw);
+	struct rp1_clockman *clockman = clock->clockman;
+	const struct rp1_clock_data *data = clock->data;
+
+	return !!(clockman_read(clockman, data->ctrl_reg) & CLK_CTRL_ENABLE);
+}
+
+static unsigned long rp1_clock_recalc_rate(struct clk_hw *hw,
+					   unsigned long parent_rate)
+{
+	struct rp1_clock *clock = container_of(hw, struct rp1_clock, hw);
+	struct rp1_clockman *clockman = clock->clockman;
+	const struct rp1_clock_data *data = clock->data;
+	u64 calc_rate;
+	u64 div;
+
+	u32 frac;
+
+	div = clockman_read(clockman, data->div_int_reg);
+	frac = (data->div_frac_reg != 0) ?
+		clockman_read(clockman, data->div_frac_reg) : 0;
+
+	/* If the integer portion of the divider is 0, treat it as 2^16 */
+	if (!div)
+		div = 1 << 16;
+
+	div = (div << CLK_DIV_FRAC_BITS) | (frac >> (32 - CLK_DIV_FRAC_BITS));
+
+	calc_rate = (u64)parent_rate << CLK_DIV_FRAC_BITS;
+	calc_rate = div64_u64(calc_rate, div);
+
+	return calc_rate;
+}
+
+static int rp1_clock_on(struct clk_hw *hw)
+{
+	struct rp1_clock *clock = container_of(hw, struct rp1_clock, hw);
+	struct rp1_clockman *clockman = clock->clockman;
+	const struct rp1_clock_data *data = clock->data;
+
+	spin_lock(&clockman->regs_lock);
+	clockman_write(clockman, data->ctrl_reg,
+		       clockman_read(clockman, data->ctrl_reg) | CLK_CTRL_ENABLE);
+	/* If this is a GPCLK, turn on the output-enable */
+	if (data->oe_mask)
+		clockman_write(clockman, GPCLK_OE_CTRL,
+			       clockman_read(clockman, GPCLK_OE_CTRL) | data->oe_mask);
+	spin_unlock(&clockman->regs_lock);
+
+	return 0;
+}
+
+static void rp1_clock_off(struct clk_hw *hw)
+{
+	struct rp1_clock *clock = container_of(hw, struct rp1_clock, hw);
+	struct rp1_clockman *clockman = clock->clockman;
+	const struct rp1_clock_data *data = clock->data;
+
+	spin_lock(&clockman->regs_lock);
+	clockman_write(clockman, data->ctrl_reg,
+		       clockman_read(clockman, data->ctrl_reg) & ~CLK_CTRL_ENABLE);
+	/* If this is a GPCLK, turn off the output-enable */
+	if (data->oe_mask)
+		clockman_write(clockman, GPCLK_OE_CTRL,
+			       clockman_read(clockman, GPCLK_OE_CTRL) & ~data->oe_mask);
+	spin_unlock(&clockman->regs_lock);
+}
+
+static u32 rp1_clock_choose_div(unsigned long rate, unsigned long parent_rate,
+				const struct rp1_clock_data *data)
+{
+	u64 div;
+
+	/*
+	 * Due to earlier rounding, calculated parent_rate may differ from
+	 * expected value. Don't fail on a small discrepancy near unity divide.
+	 */
+	if (!rate || rate > parent_rate + (parent_rate >> CLK_DIV_FRAC_BITS))
+		return 0;
+
+	/*
+	 * Always express div in fixed-point format for fractional division;
+	 * If no fractional divider is present, the fraction part will be zero.
+	 */
+	if (data->div_frac_reg) {
+		div = (u64)parent_rate << CLK_DIV_FRAC_BITS;
+		div = DIV_ROUND_CLOSEST_ULL(div, rate);
+	} else {
+		div = DIV_ROUND_CLOSEST_ULL(parent_rate, rate);
+		div <<= CLK_DIV_FRAC_BITS;
+	}
+
+	div = clamp(div,
+		    1ull << CLK_DIV_FRAC_BITS,
+		    (u64)data->div_int_max << CLK_DIV_FRAC_BITS);
+
+	return div;
+}
+
+static u8 rp1_clock_get_parent(struct clk_hw *hw)
+{
+	struct rp1_clock *clock = container_of(hw, struct rp1_clock, hw);
+	struct rp1_clockman *clockman = clock->clockman;
+	const struct rp1_clock_data *data = clock->data;
+	u32 sel, ctrl;
+	u8 parent;
+
+	/* Sel is one-hot, so find the first bit set */
+	sel = clockman_read(clockman, data->sel_reg);
+	parent = ffs(sel) - 1;
+
+	/* sel == 0 implies the parent clock is not enabled yet. */
+	if (!sel) {
+		/* Read the clock src from the CTRL register instead */
+		ctrl = clockman_read(clockman, data->ctrl_reg);
+		parent = (ctrl & data->clk_src_mask) >> CLK_CTRL_SRC_SHIFT;
+	}
+
+	if (parent >= data->num_std_parents)
+		parent = AUX_SEL;
+
+	if (parent == AUX_SEL) {
+		/*
+		 * Clock parent is an auxiliary source, so get the parent from
+		 * the AUXSRC register field.
+		 */
+		ctrl = clockman_read(clockman, data->ctrl_reg);
+		parent = (ctrl & CLK_CTRL_AUXSRC_MASK) >> CLK_CTRL_AUXSRC_SHIFT;
+		parent += data->num_std_parents;
+	}
+
+	return parent;
+}
+
+static int rp1_clock_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct rp1_clock *clock = container_of(hw, struct rp1_clock, hw);
+	struct rp1_clockman *clockman = clock->clockman;
+	const struct rp1_clock_data *data = clock->data;
+	u32 ctrl, sel;
+
+	spin_lock(&clockman->regs_lock);
+	ctrl = clockman_read(clockman, data->ctrl_reg);
+
+	if (index >= data->num_std_parents) {
+		/* This is an aux source request */
+		if (index >= data->num_std_parents + data->num_aux_parents)
+			return -EINVAL;
+
+		/* Select parent from aux list */
+		ctrl = set_register_field(ctrl, index - data->num_std_parents,
+					  CLK_CTRL_AUXSRC_MASK,
+					  CLK_CTRL_AUXSRC_SHIFT);
+		/* Set src to aux list */
+		ctrl = set_register_field(ctrl, AUX_SEL, data->clk_src_mask,
+					  CLK_CTRL_SRC_SHIFT);
+	} else {
+		ctrl = set_register_field(ctrl, index, data->clk_src_mask,
+					  CLK_CTRL_SRC_SHIFT);
+	}
+
+	clockman_write(clockman, data->ctrl_reg, ctrl);
+	spin_unlock(&clockman->regs_lock);
+
+	sel = rp1_clock_get_parent(hw);
+	WARN(sel != index, "(%s): Parent index req %u returned back %u\n",
+	     data->name, index, sel);
+
+	return 0;
+}
+
+static int rp1_clock_set_rate_and_parent(struct clk_hw *hw,
+					 unsigned long rate,
+					 unsigned long parent_rate,
+					 u8 parent)
+{
+	struct rp1_clock *clock = container_of(hw, struct rp1_clock, hw);
+	struct rp1_clockman *clockman = clock->clockman;
+	const struct rp1_clock_data *data = clock->data;
+	u32 div = rp1_clock_choose_div(rate, parent_rate, data);
+
+	WARN(rate > 4000000000ll, "rate is -ve (%d)\n", (int)rate);
+
+	if (WARN(!div,
+		 "clk divider calculated as 0! (%s, rate %ld, parent rate %ld)\n",
+		 data->name, rate, parent_rate))
+		div = 1 << CLK_DIV_FRAC_BITS;
+
+	spin_lock(&clockman->regs_lock);
+
+	clockman_write(clockman, data->div_int_reg, div >> CLK_DIV_FRAC_BITS);
+	if (data->div_frac_reg)
+		clockman_write(clockman, data->div_frac_reg, div << (32 - CLK_DIV_FRAC_BITS));
+
+	spin_unlock(&clockman->regs_lock);
+
+	if (parent != 0xff)
+		rp1_clock_set_parent(hw, parent);
+
+	return 0;
+}
+
+static int rp1_clock_set_rate(struct clk_hw *hw, unsigned long rate,
+			      unsigned long parent_rate)
+{
+	return rp1_clock_set_rate_and_parent(hw, rate, parent_rate, 0xff);
+}
+
+static void rp1_clock_choose_div_and_prate(struct clk_hw *hw,
+					   int parent_idx,
+					   unsigned long rate,
+					   unsigned long *prate,
+					   unsigned long *calc_rate)
+{
+	struct rp1_clock *clock = container_of(hw, struct rp1_clock, hw);
+	const struct rp1_clock_data *data = clock->data;
+	struct clk_hw *parent;
+	u32 div;
+	u64 tmp;
+
+	parent = clk_hw_get_parent_by_index(hw, parent_idx);
+
+	*prate = clk_hw_get_rate(parent);
+	div = rp1_clock_choose_div(rate, *prate, data);
+
+	if (!div) {
+		*calc_rate = 0;
+		return;
+	}
+
+	/* Recalculate to account for rounding errors */
+	tmp = (u64)*prate << CLK_DIV_FRAC_BITS;
+	tmp = div_u64(tmp, div);
+
+	/*
+	 * Prevent overclocks - if all parent choices result in
+	 * a downstream clock in excess of the maximum, then the
+	 * call to set the clock will fail.
+	 */
+	if (tmp > clock->data->max_freq)
+		*calc_rate = 0;
+	else
+		*calc_rate = tmp;
+}
+
+static int rp1_clock_determine_rate(struct clk_hw *hw,
+				    struct clk_rate_request *req)
+{
+	struct clk_hw *parent, *best_parent = NULL;
+	unsigned long best_rate = 0;
+	unsigned long best_prate = 0;
+	unsigned long best_rate_diff = ULONG_MAX;
+	unsigned long prate, calc_rate;
+	size_t i;
+
+	/*
+	 * If the NO_REPARENT flag is set, try to use existing parent.
+	 */
+	if ((clk_hw_get_flags(hw) & CLK_SET_RATE_NO_REPARENT)) {
+		i = rp1_clock_get_parent(hw);
+		parent = clk_hw_get_parent_by_index(hw, i);
+		if (parent) {
+			rp1_clock_choose_div_and_prate(hw, i, req->rate, &prate,
+						       &calc_rate);
+			if (calc_rate > 0) {
+				req->best_parent_hw = parent;
+				req->best_parent_rate = prate;
+				req->rate = calc_rate;
+				return 0;
+			}
+		}
+	}
+
+	/*
+	 * Select parent clock that results in the closest rate (lower or
+	 * higher)
+	 */
+	for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
+		parent = clk_hw_get_parent_by_index(hw, i);
+		if (!parent)
+			continue;
+
+		rp1_clock_choose_div_and_prate(hw, i, req->rate, &prate,
+					       &calc_rate);
+
+		if (abs_diff(calc_rate, req->rate) < best_rate_diff) {
+			best_parent = parent;
+			best_prate = prate;
+			best_rate = calc_rate;
+			best_rate_diff = abs_diff(calc_rate, req->rate);
+
+			if (best_rate_diff == 0)
+				break;
+		}
+	}
+
+	if (best_rate == 0)
+		return -EINVAL;
+
+	req->best_parent_hw = best_parent;
+	req->best_parent_rate = best_prate;
+	req->rate = best_rate;
+
+	return 0;
+}
+
+static void rp1_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
+{
+	struct rp1_clock *clock = container_of(hw, struct rp1_clock, hw);
+	struct rp1_clockman *clockman = clock->clockman;
+	const struct rp1_clock_data *data = clock->data;
+	struct debugfs_reg32 *regs;
+	int i;
+
+	regs = devm_kcalloc(clockman->dev, 4, sizeof(*regs), GFP_KERNEL);
+	if (!regs)
+		return;
+
+	i = 0;
+	regs[i].name = "ctrl";
+	regs[i++].offset = data->ctrl_reg;
+	regs[i].name = "div_int";
+	regs[i++].offset = data->div_int_reg;
+	regs[i].name = "div_frac";
+	regs[i++].offset = data->div_frac_reg;
+	regs[i].name = "sel";
+	regs[i++].offset = data->sel_reg;
+
+	rp1_debugfs_regset(clockman, 0, regs, i, dentry);
+}
+
+static const struct clk_ops rp1_pll_core_ops = {
+	.is_prepared = rp1_pll_core_is_on,
+	.prepare = rp1_pll_core_on,
+	.unprepare = rp1_pll_core_off,
+	.set_rate = rp1_pll_core_set_rate,
+	.recalc_rate = rp1_pll_core_recalc_rate,
+	.round_rate = rp1_pll_core_round_rate,
+	.debug_init = rp1_pll_core_debug_init,
+};
+
+static const struct clk_ops rp1_pll_ops = {
+	.set_rate = rp1_pll_set_rate,
+	.recalc_rate = rp1_pll_recalc_rate,
+	.round_rate = rp1_pll_round_rate,
+	.debug_init = rp1_pll_debug_init,
+};
+
+static const struct clk_ops rp1_pll_ph_ops = {
+	.is_prepared = rp1_pll_ph_is_on,
+	.prepare = rp1_pll_ph_on,
+	.unprepare = rp1_pll_ph_off,
+	.set_rate = rp1_pll_ph_set_rate,
+	.recalc_rate = rp1_pll_ph_recalc_rate,
+	.round_rate = rp1_pll_ph_round_rate,
+	.debug_init = rp1_pll_ph_debug_init,
+};
+
+static const struct clk_ops rp1_pll_divider_ops = {
+	.is_prepared = rp1_pll_divider_is_on,
+	.prepare = rp1_pll_divider_on,
+	.unprepare = rp1_pll_divider_off,
+	.set_rate = rp1_pll_divider_set_rate,
+	.recalc_rate = rp1_pll_divider_recalc_rate,
+	.round_rate = rp1_pll_divider_round_rate,
+	.debug_init = rp1_pll_divider_debug_init,
+};
+
+static const struct clk_ops rp1_clk_ops = {
+	.is_prepared = rp1_clock_is_on,
+	.prepare = rp1_clock_on,
+	.unprepare = rp1_clock_off,
+	.recalc_rate = rp1_clock_recalc_rate,
+	.get_parent = rp1_clock_get_parent,
+	.set_parent = rp1_clock_set_parent,
+	.set_rate_and_parent = rp1_clock_set_rate_and_parent,
+	.set_rate = rp1_clock_set_rate,
+	.determine_rate = rp1_clock_determine_rate,
+	.debug_init = rp1_clk_debug_init,
+};
+
+static struct clk_hw *rp1_register_pll_core(struct rp1_clockman *clockman,
+					    const void *data)
+{
+	const char *ref_clk_name = clk_hw_get_name(clockman->hw_xosc);
+	const struct rp1_pll_core_data *pll_core_data = data;
+	struct rp1_pll_core *pll_core;
+	struct clk_init_data init;
+	int ret;
+
+	memset(&init, 0, sizeof(init));
+
+	/* All of the PLL cores derive from the external oscillator. */
+	init.parent_names = &ref_clk_name;
+	init.num_parents = 1;
+	init.name = pll_core_data->name;
+	init.ops = &rp1_pll_core_ops;
+	init.flags = pll_core_data->flags | CLK_IGNORE_UNUSED | CLK_IS_CRITICAL;
+
+	pll_core = devm_kzalloc(clockman->dev, sizeof(*pll_core), GFP_KERNEL);
+	if (!pll_core)
+		return NULL;
+
+	pll_core->clockman = clockman;
+	pll_core->data = pll_core_data;
+	pll_core->hw.init = &init;
+
+	ret = devm_clk_hw_register(clockman->dev, &pll_core->hw);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return &pll_core->hw;
+}
+
+static struct clk_hw *rp1_register_pll(struct rp1_clockman *clockman,
+				       const void *data)
+{
+	const struct rp1_pll_data *pll_data = data;
+	struct rp1_pll *pll;
+	struct clk_init_data init;
+	int ret;
+
+	memset(&init, 0, sizeof(init));
+
+	init.parent_names = &pll_data->source_pll;
+	init.num_parents = 1;
+	init.name = pll_data->name;
+	init.ops = &rp1_pll_ops;
+	init.flags = pll_data->flags | CLK_IGNORE_UNUSED | CLK_IS_CRITICAL;
+
+	pll = devm_kzalloc(clockman->dev, sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return NULL;
+
+	pll->clockman = clockman;
+	pll->data = pll_data;
+	pll->hw.init = &init;
+
+	ret = devm_clk_hw_register(clockman->dev, &pll->hw);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return &pll->hw;
+}
+
+static struct clk_hw *rp1_register_pll_ph(struct rp1_clockman *clockman,
+					  const void *data)
+{
+	const struct rp1_pll_ph_data *ph_data = data;
+	struct rp1_pll_ph *ph;
+	struct clk_init_data init;
+	int ret;
+
+	memset(&init, 0, sizeof(init));
+
+	init.parent_names = &ph_data->source_pll;
+	init.num_parents = 1;
+	init.name = ph_data->name;
+	init.ops = &rp1_pll_ph_ops;
+	init.flags = ph_data->flags | CLK_IGNORE_UNUSED;
+
+	ph = devm_kzalloc(clockman->dev, sizeof(*ph), GFP_KERNEL);
+	if (!ph)
+		return NULL;
+
+	ph->clockman = clockman;
+	ph->data = ph_data;
+	ph->hw.init = &init;
+
+	ret = devm_clk_hw_register(clockman->dev, &ph->hw);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return &ph->hw;
+}
+
+static struct clk_hw *rp1_register_pll_divider(struct rp1_clockman *clockman,
+					       const void *data)
+{
+	const struct rp1_pll_data *divider_data = data;
+	struct rp1_pll *divider;
+	struct clk_init_data init;
+	int ret;
+
+	memset(&init, 0, sizeof(init));
+
+	init.parent_names = &divider_data->source_pll;
+	init.num_parents = 1;
+	init.name = divider_data->name;
+	init.ops = &rp1_pll_divider_ops;
+	init.flags = divider_data->flags | CLK_IGNORE_UNUSED | CLK_IS_CRITICAL;
+
+	divider = devm_kzalloc(clockman->dev, sizeof(*divider), GFP_KERNEL);
+	if (!divider)
+		return NULL;
+
+	divider->div.reg = clockman->regs + divider_data->ctrl_reg;
+	divider->div.shift = PLL_SEC_DIV_SHIFT;
+	divider->div.width = PLL_SEC_DIV_WIDTH;
+	divider->div.flags = CLK_DIVIDER_ROUND_CLOSEST;
+	divider->div.flags |= CLK_IS_CRITICAL;
+	divider->div.lock = &clockman->regs_lock;
+	divider->div.hw.init = &init;
+	divider->div.table = pll_sec_div_table;
+
+	divider->clockman = clockman;
+	divider->data = divider_data;
+
+	ret = devm_clk_hw_register(clockman->dev, &divider->div.hw);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return &divider->div.hw;
+}
+
+static struct clk_hw *rp1_register_clock(struct rp1_clockman *clockman,
+					 const void *data)
+{
+	const struct rp1_clock_data *clock_data = data;
+	struct rp1_clock *clock;
+	struct clk_init_data init;
+	int ret;
+
+	if (WARN_ON_ONCE(MAX_CLK_PARENTS <
+	       clock_data->num_std_parents + clock_data->num_aux_parents))
+		return NULL;
+
+	/* There must be a gap for the AUX selector */
+	if (WARN_ON_ONCE(clock_data->num_std_parents > AUX_SEL &&
+	    strcmp("-", clock_data->parents[AUX_SEL])))
+		return NULL;
+
+	memset(&init, 0, sizeof(init));
+	init.parent_names = clock_data->parents;
+	init.num_parents = clock_data->num_std_parents +
+			   clock_data->num_aux_parents;
+	init.name = clock_data->name;
+	init.flags = clock_data->flags | CLK_IGNORE_UNUSED;
+	init.ops = &rp1_clk_ops;
+
+	clock = devm_kzalloc(clockman->dev, sizeof(*clock), GFP_KERNEL);
+	if (!clock)
+		return NULL;
+
+	clock->clockman = clockman;
+	clock->data = clock_data;
+	clock->hw.init = &init;
+
+	ret = devm_clk_hw_register(clockman->dev, &clock->hw);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return &clock->hw;
+}
+
+/* Assignment helper macros for different clock types. */
+#define _REGISTER(f, ...) { .clk_register = f, .data = __VA_ARGS__ }
+
+#define REGISTER_PLL_CORE(...)	_REGISTER(&rp1_register_pll_core,	\
+					  &(struct rp1_pll_core_data)	\
+					  {__VA_ARGS__})
+
+#define REGISTER_PLL(...)	_REGISTER(&rp1_register_pll,		\
+					  &(struct rp1_pll_data)	\
+					  {__VA_ARGS__})
+
+#define REGISTER_PLL_PH(...)	_REGISTER(&rp1_register_pll_ph,		\
+					  &(struct rp1_pll_ph_data)	\
+					  {__VA_ARGS__})
+
+#define REGISTER_PLL_DIV(...)	_REGISTER(&rp1_register_pll_divider,	\
+					  &(struct rp1_pll_data)	\
+					  {__VA_ARGS__})
+
+#define REGISTER_CLK(...)	_REGISTER(&rp1_register_clock,		\
+					  &(struct rp1_clock_data)	\
+					  {__VA_ARGS__})
+
+static const struct rp1_clk_desc clk_desc_array[] = {
+	[RP1_PLL_SYS_CORE] = REGISTER_PLL_CORE(
+				.name = "pll_sys_core",
+				.cs_reg = PLL_SYS_CS,
+				.pwr_reg = PLL_SYS_PWR,
+				.fbdiv_int_reg = PLL_SYS_FBDIV_INT,
+				.fbdiv_frac_reg = PLL_SYS_FBDIV_FRAC,
+				),
+
+	[RP1_PLL_AUDIO_CORE] = REGISTER_PLL_CORE(
+				.name = "pll_audio_core",
+				.cs_reg = PLL_AUDIO_CS,
+				.pwr_reg = PLL_AUDIO_PWR,
+				.fbdiv_int_reg = PLL_AUDIO_FBDIV_INT,
+				.fbdiv_frac_reg = PLL_AUDIO_FBDIV_FRAC,
+				),
+
+	[RP1_PLL_VIDEO_CORE] = REGISTER_PLL_CORE(
+				.name = "pll_video_core",
+				.cs_reg = PLL_VIDEO_CS,
+				.pwr_reg = PLL_VIDEO_PWR,
+				.fbdiv_int_reg = PLL_VIDEO_FBDIV_INT,
+				.fbdiv_frac_reg = PLL_VIDEO_FBDIV_FRAC,
+				),
+
+	[RP1_PLL_SYS] = REGISTER_PLL(
+				.name = "pll_sys",
+				.source_pll = "pll_sys_core",
+				.ctrl_reg = PLL_SYS_PRIM,
+				.fc0_src = FC_NUM(0, 2),
+				),
+
+	[RP1_PLL_SYS_PRI_PH] = REGISTER_PLL_PH(
+				.name = "pll_sys_pri_ph",
+				.source_pll = "pll_sys",
+				.ph_reg = PLL_SYS_PRIM,
+				.fixed_divider = 2,
+				.phase = RP1_PLL_PHASE_0,
+				.fc0_src = FC_NUM(1, 2),
+				),
+
+	[RP1_PLL_SYS_SEC] = REGISTER_PLL_DIV(
+				.name = "pll_sys_sec",
+				.source_pll = "pll_sys_core",
+				.ctrl_reg = PLL_SYS_SEC,
+				.fc0_src = FC_NUM(2, 2),
+				),
+
+	[RP1_CLK_ETH_TSU] = REGISTER_CLK(
+				.name = "clk_eth_tsu",
+				.parents = {"xosc"},
+				.num_std_parents = 0,
+				.num_aux_parents = 1,
+				.ctrl_reg = CLK_ETH_TSU_CTRL,
+				.div_int_reg = CLK_ETH_TSU_DIV_INT,
+				.sel_reg = CLK_ETH_TSU_SEL,
+				.div_int_max = DIV_INT_8BIT_MAX,
+				.max_freq = 50 * MHz,
+				.fc0_src = FC_NUM(5, 7),
+				),
+};
+
+static int rp1_clk_probe(struct platform_device *pdev)
+{
+	const size_t asize = ARRAY_SIZE(clk_desc_array);
+	const struct rp1_clk_desc *desc;
+	struct device *dev = &pdev->dev;
+	struct rp1_clockman *clockman;
+	struct clk *clk_xosc;
+	struct clk_hw **hws;
+	unsigned int i;
+
+	clockman = devm_kzalloc(dev, struct_size(clockman, onecell.hws, asize),
+				GFP_KERNEL);
+	if (!clockman)
+		return -ENOMEM;
+
+	spin_lock_init(&clockman->regs_lock);
+	clockman->dev = dev;
+
+	clockman->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(clockman->regs))
+		return PTR_ERR(clockman->regs);
+
+	clk_xosc = devm_clk_get_enabled(dev, NULL);
+	if (IS_ERR(clk_xosc))
+		return PTR_ERR(clk_xosc);
+
+	clockman->hw_xosc = __clk_get_hw(clk_xosc);
+	clockman->onecell.num = asize;
+	hws = clockman->onecell.hws;
+
+	for (i = 0; i < asize; i++) {
+		desc = &clk_desc_array[i];
+		if (desc->clk_register && desc->data) {
+			hws[i] = desc->clk_register(clockman, desc->data);
+			if (IS_ERR_OR_NULL(hws[i]))
+				dev_err(dev, "Unable to register clock: %s\n",
+					clk_hw_get_name(hws[i]));
+		}
+	}
+
+	platform_set_drvdata(pdev, clockman);
+
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					   &clockman->onecell);
+}
+
+static const struct of_device_id rp1_clk_of_match[] = {
+	{ .compatible = "raspberrypi,rp1-clocks" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, rp1_clk_of_match);
+
+static struct platform_driver rp1_clk_driver = {
+	.driver = {
+		.name = "rp1-clk",
+		.of_match_table = rp1_clk_of_match,
+	},
+	.probe = rp1_clk_probe,
+};
+
+static int __init rp1_clk_driver_init(void)
+{
+	return platform_driver_register(&rp1_clk_driver);
+}
+postcore_initcall(rp1_clk_driver_init);
+
+static void __exit rp1_clk_driver_exit(void)
+{
+	platform_driver_unregister(&rp1_clk_driver);
+}
+module_exit(rp1_clk_driver_exit);
+
+MODULE_AUTHOR("Naushir Patuck <naush@raspberrypi.com>");
+MODULE_DESCRIPTION("RP1 clock driver");
+MODULE_LICENSE("GPL");
-- 
2.35.3


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

* [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support
  2024-08-20 14:36 [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay Andrea della Porta
                   ` (5 preceding siblings ...)
  2024-08-20 14:36 ` [PATCH 06/11] clk: rp1: Add support for clocks provided by RP1 Andrea della Porta
@ 2024-08-20 14:36 ` Andrea della Porta
  2024-08-21  8:45   ` Krzysztof Kozlowski
                     ` (5 more replies)
  2024-08-20 14:36 ` [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver Andrea della Porta
                   ` (4 subsequent siblings)
  11 siblings, 6 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-08-20 14:36 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

The RP1 is an MFD supporting a gpio controller and /pinmux/pinctrl.
Add minimum support for the gpio only portion. The driver is in
pinctrl folder since upcoming patches will add the pinmux/pinctrl
support where the gpio part can be seen as an addition.

Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
---
 MAINTAINERS                   |   1 +
 drivers/pinctrl/Kconfig       |  10 +
 drivers/pinctrl/Makefile      |   1 +
 drivers/pinctrl/pinctrl-rp1.c | 719 ++++++++++++++++++++++++++++++++++
 4 files changed, 731 insertions(+)
 create mode 100644 drivers/pinctrl/pinctrl-rp1.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 4ce7b049d67e..67f460c36ea1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19122,6 +19122,7 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
 F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
 F:	drivers/clk/clk-rp1.c
+F:	drivers/pinctrl/pinctrl-rp1.c
 F:	include/dt-bindings/clock/rp1.h
 F:	include/dt-bindings/misc/rp1.h
 
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 7e4f93a3bc7a..18bb1a8bd102 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -565,6 +565,16 @@ config PINCTRL_MLXBF3
 	  each pin. This driver can also be built as a module called
 	  pinctrl-mlxbf3.
 
+config PINCTRL_RP1
+	bool "Pinctrl driver for RP1"
+	select PINMUX
+	select PINCONF
+	select GENERIC_PINCONF
+	select GPIOLIB_IRQCHIP
+	help
+	  Enable the gpio and pinctrl/mux  driver for RaspberryPi RP1
+	  multi function device. 
+
 source "drivers/pinctrl/actions/Kconfig"
 source "drivers/pinctrl/aspeed/Kconfig"
 source "drivers/pinctrl/bcm/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index cc809669405a..f1ca23b563f6 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_PINCTRL_PIC32)	+= pinctrl-pic32.o
 obj-$(CONFIG_PINCTRL_PISTACHIO)	+= pinctrl-pistachio.o
 obj-$(CONFIG_PINCTRL_RK805)	+= pinctrl-rk805.o
 obj-$(CONFIG_PINCTRL_ROCKCHIP)	+= pinctrl-rockchip.o
+obj-$(CONFIG_PINCTRL_RP1)       += pinctrl-rp1.o
 obj-$(CONFIG_PINCTRL_SCMI)	+= pinctrl-scmi.o
 obj-$(CONFIG_PINCTRL_SINGLE)	+= pinctrl-single.o
 obj-$(CONFIG_PINCTRL_ST) 	+= pinctrl-st.o
diff --git a/drivers/pinctrl/pinctrl-rp1.c b/drivers/pinctrl/pinctrl-rp1.c
new file mode 100644
index 000000000000..c035d2014505
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-rp1.c
@@ -0,0 +1,719 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for Raspberry Pi RP1 GPIO unit
+ *
+ * Copyright (C) 2023 Raspberry Pi Ltd.
+ *
+ * This driver is inspired by:
+ * pinctrl-bcm2835.c, please see original file for copyright information
+ */
+
+#include <linux/bitmap.h>
+#include <linux/bitops.h>
+#include <linux/bug.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/gpio/driver.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdesc.h>
+#include <linux/init.h>
+#include <linux/of_address.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/seq_file.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#define MODULE_NAME "pinctrl-rp1"
+#define RP1_NUM_GPIOS	54
+#define RP1_NUM_BANKS	3
+
+#define RP1_RW_OFFSET			0x0000
+#define RP1_XOR_OFFSET			(RP1_RW_OFFSET + 0x1000)
+#define RP1_SET_OFFSET			(RP1_RW_OFFSET + 0x2000)
+#define RP1_CLR_OFFSET			(RP1_RW_OFFSET + 0x3000)
+
+#define RP1_GPIO_REG_OFFSET		0x0000
+#define RP1_GPIO_STATUS			(RP1_GPIO_REG_OFFSET + 0x0000)
+#define RP1_GPIO_CTRL			(RP1_GPIO_REG_OFFSET + 0x0004)
+
+#define RP1_GPIO_EVENTS_SHIFT_RAW	20
+
+#define RP1_GPIO_CTRL_FUNCSEL_LSB	0
+#define RP1_GPIO_CTRL_FUNCSEL_MASK	GENMASK(RP1_GPIO_CTRL_FUNCSEL_LSB + 4, \
+						RP1_GPIO_CTRL_FUNCSEL_LSB)
+#define RP1_GPIO_CTRL_OUTOVER_LSB	12
+#define RP1_GPIO_CTRL_OUTOVER_MASK	GENMASK(RP1_GPIO_CTRL_OUTOVER_LSB + 1, \
+						RP1_GPIO_CTRL_OUTOVER_LSB)
+#define RP1_GPIO_CTRL_OEOVER_LSB	14
+#define RP1_GPIO_CTRL_OEOVER_MASK	GENMASK(RP1_GPIO_CTRL_OEOVER_LSB + 1, \
+						RP1_GPIO_CTRL_OEOVER_LSB)
+#define RP1_GPIO_CTRL_INOVER_LSB	16
+#define RP1_GPIO_CTRL_INOVER_MASK	GENMASK(RP1_GPIO_CTRL_INOVER_LSB + 1, \
+						RP1_GPIO_CTRL_INOVER_LSB)
+#define RP1_GPIO_CTRL_IRQEN_FALLING	BIT(20)
+#define RP1_GPIO_CTRL_IRQEN_RISING	BIT(21)
+#define RP1_GPIO_CTRL_IRQEN_LOW		BIT(22)
+#define RP1_GPIO_CTRL_IRQEN_HIGH	BIT(23)
+#define RP1_GPIO_CTRL_IRQEN_F_FALLING	BIT(24)
+#define RP1_GPIO_CTRL_IRQEN_F_RISING	BIT(25)
+#define RP1_GPIO_CTRL_IRQEN_F_LOW	BIT(26)
+#define RP1_GPIO_CTRL_IRQEN_F_HIGH	BIT(27)
+#define RP1_GPIO_CTRL_IRQRESET		BIT(28)
+#define RP1_GPIO_CTRL_IRQOVER_LSB	30
+#define RP1_GPIO_CTRL_IRQOVER_MASK	GENMASK(RP1_GPIO_CTRL_IRQOVER_LSB + 1, \
+						RP1_GPIO_CTRL_IRQOVER_LSB)
+
+#define RP1_INT_EDGE_FALLING		BIT(0)
+#define RP1_INT_EDGE_RISING		BIT(1)
+#define RP1_INT_LEVEL_LOW		BIT(2)
+#define RP1_INT_LEVEL_HIGH		BIT(3)
+#define RP1_INT_MASK			GENMASK(3, 0)
+
+#define RP1_INT_EDGE_BOTH		(RP1_INT_EDGE_FALLING |	\
+					 RP1_INT_EDGE_RISING)
+
+enum {
+	RP1_PUD_OFF			= 0,
+	RP1_PUD_DOWN			= 1,
+	RP1_PUD_UP			= 2,
+};
+
+#define RP1_FSEL_COUNT			9
+
+#define RP1_FSEL_ALT0			0x00
+#define RP1_FSEL_GPIO			0x05
+#define RP1_FSEL_NONE			0x09
+#define RP1_FSEL_NONE_HW		0x1f
+
+enum {
+	RP1_DIR_OUTPUT			= 0,
+	RP1_DIR_INPUT			= 1,
+};
+
+enum {
+	RP1_OUTOVER_PERI		= 0,
+	RP1_OUTOVER_INVPERI		= 1,
+	RP1_OUTOVER_LOW			= 2,
+	RP1_OUTOVER_HIGH		= 3,
+};
+
+enum {
+	RP1_OEOVER_PERI			= 0,
+	RP1_OEOVER_INVPERI		= 1,
+	RP1_OEOVER_DISABLE		= 2,
+	RP1_OEOVER_ENABLE		= 3,
+};
+
+enum {
+	RP1_INOVER_PERI			= 0,
+	RP1_INOVER_INVPERI		= 1,
+	RP1_INOVER_LOW			= 2,
+	RP1_INOVER_HIGH			= 3,
+};
+
+#define RP1_RIO_OUT			0x00
+#define RP1_RIO_OE			(RP1_RIO_OUT + 0x04)
+#define RP1_RIO_IN			(RP1_RIO_OUT + 0x08)
+
+#define RP1_PAD_SLEWFAST_LSB		0
+#define RP1_PAD_SLEWFAST_MASK		BIT(RP1_PAD_SLEWFAST_LSB)
+#define RP1_PAD_SCHMITT_LSB		1
+#define RP1_PAD_SCHMITT_MASK		BIT(RP1_PAD_SCHMITT_LSB)
+#define RP1_PAD_PULL_LSB		2
+#define RP1_PAD_PULL_MASK		GENMASK(RP1_PAD_PULL_LSB + 1, \
+						RP1_PAD_PULL_LSB)
+#define RP1_PAD_DRIVE_LSB		4
+#define RP1_PAD_DRIVE_MASK		GENMASK(RP1_PAD_DRIVE_LSB + 1, \
+						RP1_PAD_DRIVE_LSB)
+#define RP1_PAD_IN_ENABLE_LSB		6
+#define RP1_PAD_IN_ENABLE_MASK		BIT(RP1_PAD_IN_ENABLE_LSB)
+#define RP1_PAD_OUT_DISABLE_LSB		7
+#define RP1_PAD_OUT_DISABLE_MASK	BIT(RP1_PAD_OUT_DISABLE_LSB)
+
+#define RP1_PAD_DRIVE_2MA		0x00000000
+#define RP1_PAD_DRIVE_4MA		BIT(4)
+#define RP1_PAD_DRIVE_8MA		BIT(5)
+#define RP1_PAD_DRIVE_12MA		(RP1_PAD_DRIVE_4MA | \
+					RP1_PAD_DRIVE_8MA)
+
+#define FIELD_SET(_reg, _mask, _val)			\
+	({						\
+		_reg &= ~(_mask);				\
+		_reg |= FIELD_PREP((_mask), (_val));	\
+	})
+
+#define FUNC(f) \
+	[func_##f] = #f
+
+struct rp1_iobank_desc {
+	int min_gpio;
+	int num_gpios;
+	int gpio_offset;
+	int inte_offset;
+	int ints_offset;
+	int rio_offset;
+	int pads_offset;
+};
+
+struct rp1_pin_info {
+	u8 num;
+	u8 bank;
+	u8 offset;
+	u8 fsel;
+	u8 irq_type;
+
+	void __iomem *gpio;
+	void __iomem *rio;
+	void __iomem *inte;
+	void __iomem *ints;
+	void __iomem *pad;
+};
+
+struct rp1_pinctrl {
+	struct device *dev;
+	void __iomem *gpio_base;
+	void __iomem *rio_base;
+	void __iomem *pads_base;
+	int irq[RP1_NUM_BANKS];
+	struct rp1_pin_info pins[RP1_NUM_GPIOS];
+
+	struct pinctrl_dev *pctl_dev;
+	struct gpio_chip gpio_chip;
+	struct pinctrl_gpio_range gpio_range;
+
+	raw_spinlock_t irq_lock[RP1_NUM_BANKS];
+};
+
+const struct rp1_iobank_desc rp1_iobanks[RP1_NUM_BANKS] = {
+	/*         gpio   inte    ints     rio    pads */
+	{  0, 28, 0x0000, 0x011c, 0x0124, 0x0000, 0x0004 },
+	{ 28,  6, 0x4000, 0x411c, 0x4124, 0x4000, 0x4004 },
+	{ 34, 20, 0x8000, 0x811c, 0x8124, 0x8000, 0x8004 },
+};
+
+static int rp1_pinconf_set(struct rp1_pin_info *pin,
+			   unsigned int offset, unsigned long *configs,
+			   unsigned int num_configs);
+
+static struct rp1_pin_info *rp1_get_pin(struct gpio_chip *chip,
+					unsigned int offset)
+{
+	struct rp1_pinctrl *pc = gpiochip_get_data(chip);
+
+	if (pc && offset < RP1_NUM_GPIOS)
+		return &pc->pins[offset];
+	return NULL;
+}
+
+static void rp1_pad_update(struct rp1_pin_info *pin, u32 clr, u32 set)
+{
+	u32 padctrl = readl(pin->pad);
+
+	padctrl &= ~clr;
+	padctrl |= set;
+
+	writel(padctrl, pin->pad);
+}
+
+static void rp1_input_enable(struct rp1_pin_info *pin, int value)
+{
+	rp1_pad_update(pin, RP1_PAD_IN_ENABLE_MASK,
+		       value ? RP1_PAD_IN_ENABLE_MASK : 0);
+}
+
+static void rp1_output_enable(struct rp1_pin_info *pin, int value)
+{
+	rp1_pad_update(pin, RP1_PAD_OUT_DISABLE_MASK,
+		       value ? 0 : RP1_PAD_OUT_DISABLE_MASK);
+}
+
+static u32 rp1_get_fsel(struct rp1_pin_info *pin)
+{
+	u32 ctrl = readl(pin->gpio + RP1_GPIO_CTRL);
+	u32 oeover = FIELD_GET(RP1_GPIO_CTRL_OEOVER_MASK, ctrl);
+	u32 fsel = FIELD_GET(RP1_GPIO_CTRL_FUNCSEL_MASK, ctrl);
+
+	if (oeover != RP1_OEOVER_PERI || fsel >= RP1_FSEL_COUNT)
+		fsel = RP1_FSEL_NONE;
+
+	return fsel;
+}
+
+static void rp1_set_fsel(struct rp1_pin_info *pin, u32 fsel)
+{
+	u32 ctrl = readl(pin->gpio + RP1_GPIO_CTRL);
+
+	if (fsel >= RP1_FSEL_COUNT)
+		fsel = RP1_FSEL_NONE_HW;
+
+	rp1_input_enable(pin, 1);
+	rp1_output_enable(pin, 1);
+
+	if (fsel == RP1_FSEL_NONE) {
+		FIELD_SET(ctrl, RP1_GPIO_CTRL_OEOVER_MASK, RP1_OEOVER_DISABLE);
+	} else {
+		FIELD_SET(ctrl, RP1_GPIO_CTRL_OUTOVER_MASK, RP1_OUTOVER_PERI);
+		FIELD_SET(ctrl, RP1_GPIO_CTRL_OEOVER_MASK, RP1_OEOVER_PERI);
+	}
+
+	FIELD_SET(ctrl, RP1_GPIO_CTRL_FUNCSEL_MASK, fsel);
+	writel(ctrl, pin->gpio + RP1_GPIO_CTRL);
+}
+
+static int rp1_get_dir(struct rp1_pin_info *pin)
+{
+	return !(readl(pin->rio + RP1_RIO_OE) & (1 << pin->offset)) ?
+		RP1_DIR_INPUT : RP1_DIR_OUTPUT;
+}
+
+static void rp1_set_dir(struct rp1_pin_info *pin, bool is_input)
+{
+	int offset = is_input ? RP1_CLR_OFFSET : RP1_SET_OFFSET;
+
+	writel(1 << pin->offset, pin->rio + RP1_RIO_OE + offset);
+}
+
+static int rp1_get_value(struct rp1_pin_info *pin)
+{
+	return !!(readl(pin->rio + RP1_RIO_IN) & (1 << pin->offset));
+}
+
+static void rp1_set_value(struct rp1_pin_info *pin, int value)
+{
+	/* Assume the pin is already an output */
+	writel(1 << pin->offset,
+	       pin->rio + RP1_RIO_OUT + (value ? RP1_SET_OFFSET : RP1_CLR_OFFSET));
+}
+
+static int rp1_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct rp1_pin_info *pin = rp1_get_pin(chip, offset);
+	int ret;
+
+	if (!pin)
+		return -EINVAL;
+
+	ret = rp1_get_value(pin);
+
+	return ret;
+}
+
+static void rp1_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
+{
+	struct rp1_pin_info *pin = rp1_get_pin(chip, offset);
+
+	if (pin)
+		rp1_set_value(pin, value);
+}
+
+static int rp1_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
+{
+	struct rp1_pin_info *pin = rp1_get_pin(chip, offset);
+	u32 fsel;
+
+	if (!pin)
+		return -EINVAL;
+
+	fsel = rp1_get_fsel(pin);
+	if (fsel != RP1_FSEL_GPIO)
+		return -EINVAL;
+
+	return (rp1_get_dir(pin) == RP1_DIR_OUTPUT) ?
+		GPIO_LINE_DIRECTION_OUT :
+		GPIO_LINE_DIRECTION_IN;
+}
+
+static int rp1_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+	struct rp1_pin_info *pin = rp1_get_pin(chip, offset);
+
+	if (!pin)
+		return -EINVAL;
+	rp1_set_dir(pin, RP1_DIR_INPUT);
+	rp1_set_fsel(pin, RP1_FSEL_GPIO);
+
+	return 0;
+}
+
+static int rp1_gpio_direction_output(struct gpio_chip *chip, unsigned int offset,
+				     int value)
+{
+	struct rp1_pin_info *pin = rp1_get_pin(chip, offset);
+
+	if (!pin)
+		return -EINVAL;
+	rp1_set_value(pin, value);
+	rp1_set_dir(pin, RP1_DIR_OUTPUT);
+	rp1_set_fsel(pin, RP1_FSEL_GPIO);
+
+	return 0;
+}
+
+static int rp1_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
+			       unsigned long config)
+{
+	struct rp1_pin_info *pin = rp1_get_pin(chip, offset);
+	unsigned long configs[] = { config };
+
+	return rp1_pinconf_set(pin, offset, configs,
+			       ARRAY_SIZE(configs));
+}
+
+static const struct gpio_chip rp1_gpio_chip = {
+	.label = MODULE_NAME,
+	.owner = THIS_MODULE,
+	.request = gpiochip_generic_request,
+	.free = gpiochip_generic_free,
+	.direction_input = rp1_gpio_direction_input,
+	.direction_output = rp1_gpio_direction_output,
+	.get_direction = rp1_gpio_get_direction,
+	.get = rp1_gpio_get,
+	.set = rp1_gpio_set,
+	.base = -1,
+	.set_config = rp1_gpio_set_config,
+	.ngpio = RP1_NUM_GPIOS,
+	.can_sleep = false,
+};
+
+static void rp1_gpio_irq_handler(struct irq_desc *desc)
+{
+	struct gpio_chip *chip = irq_desc_get_handler_data(desc);
+	struct irq_chip *host_chip = irq_desc_get_chip(desc);
+	struct rp1_pinctrl *pc = gpiochip_get_data(chip);
+	const struct rp1_iobank_desc *bank;
+	int irq = irq_desc_get_irq(desc);
+	unsigned long ints;
+	int bit_pos;
+
+	if (pc->irq[0] == irq)
+		bank = &rp1_iobanks[0];
+	else if (pc->irq[1] == irq)
+		bank = &rp1_iobanks[1];
+	else
+		bank = &rp1_iobanks[2];
+
+	chained_irq_enter(host_chip, desc);
+
+	ints = readl(pc->gpio_base + bank->ints_offset);
+	for_each_set_bit(bit_pos, &ints, 32) {
+		struct rp1_pin_info *pin = rp1_get_pin(chip, bit_pos);
+
+		writel(RP1_GPIO_CTRL_IRQRESET,
+		       pin->gpio + RP1_SET_OFFSET + RP1_GPIO_CTRL);
+		generic_handle_irq(irq_linear_revmap(pc->gpio_chip.irq.domain,
+						     bank->gpio_offset + bit_pos));
+	}
+
+	chained_irq_exit(host_chip, desc);
+}
+
+static void rp1_gpio_irq_config(struct rp1_pin_info *pin, bool enable)
+{
+	writel(1 << pin->offset,
+	       pin->inte + (enable ? RP1_SET_OFFSET : RP1_CLR_OFFSET));
+	if (!enable)
+		/* Clear any latched events */
+		writel(RP1_GPIO_CTRL_IRQRESET,
+		       pin->gpio + RP1_SET_OFFSET + RP1_GPIO_CTRL);
+}
+
+static void rp1_gpio_irq_enable(struct irq_data *data)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	unsigned int gpio = irqd_to_hwirq(data);
+	struct rp1_pin_info *pin = rp1_get_pin(chip, gpio);
+
+	rp1_gpio_irq_config(pin, true);
+}
+
+static void rp1_gpio_irq_disable(struct irq_data *data)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	unsigned int gpio = irqd_to_hwirq(data);
+	struct rp1_pin_info *pin = rp1_get_pin(chip, gpio);
+
+	rp1_gpio_irq_config(pin, false);
+}
+
+static int rp1_irq_set_type(struct rp1_pin_info *pin, unsigned int type)
+{
+	u32 irq_flags;
+
+	switch (type) {
+	case IRQ_TYPE_NONE:
+		irq_flags = 0;
+		break;
+	case IRQ_TYPE_EDGE_RISING:
+		irq_flags = RP1_INT_EDGE_RISING;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		irq_flags = RP1_INT_EDGE_FALLING;
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		irq_flags = RP1_INT_EDGE_RISING | RP1_INT_EDGE_FALLING;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		irq_flags = RP1_INT_LEVEL_HIGH;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		irq_flags = RP1_INT_LEVEL_LOW;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	/* Clear them all */
+	writel(RP1_INT_MASK << RP1_GPIO_EVENTS_SHIFT_RAW,
+	       pin->gpio + RP1_CLR_OFFSET + RP1_GPIO_CTRL);
+	/* Set those that are needed */
+	writel(irq_flags << RP1_GPIO_EVENTS_SHIFT_RAW,
+	       pin->gpio + RP1_SET_OFFSET + RP1_GPIO_CTRL);
+	pin->irq_type = type;
+
+	return 0;
+}
+
+static int rp1_gpio_irq_set_type(struct irq_data *data, unsigned int type)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	unsigned int gpio = irqd_to_hwirq(data);
+	struct rp1_pin_info *pin = rp1_get_pin(chip, gpio);
+	struct rp1_pinctrl *pc = gpiochip_get_data(chip);
+	int bank = pin->bank;
+	unsigned long flags;
+	int ret;
+
+	raw_spin_lock_irqsave(&pc->irq_lock[bank], flags);
+
+	ret = rp1_irq_set_type(pin, type);
+	if (!ret) {
+		if (type & IRQ_TYPE_EDGE_BOTH)
+			irq_set_handler_locked(data, handle_edge_irq);
+		else
+			irq_set_handler_locked(data, handle_level_irq);
+	}
+
+	raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags);
+
+	return ret;
+}
+
+static void rp1_gpio_irq_ack(struct irq_data *data)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	unsigned int gpio = irqd_to_hwirq(data);
+	struct rp1_pin_info *pin = rp1_get_pin(chip, gpio);
+
+	/* Clear any latched events */
+	writel(RP1_GPIO_CTRL_IRQRESET, pin->gpio + RP1_SET_OFFSET + RP1_GPIO_CTRL);
+}
+
+static struct irq_chip rp1_gpio_irq_chip = {
+	.name = MODULE_NAME,
+	.irq_enable = rp1_gpio_irq_enable,
+	.irq_disable = rp1_gpio_irq_disable,
+	.irq_set_type = rp1_gpio_irq_set_type,
+	.irq_ack = rp1_gpio_irq_ack,
+	.irq_mask = rp1_gpio_irq_disable,
+	.irq_unmask = rp1_gpio_irq_enable,
+	.flags = IRQCHIP_IMMUTABLE,
+};
+
+static void rp1_pull_config_set(struct rp1_pin_info *pin, unsigned int arg)
+{
+	u32 padctrl = readl(pin->pad);
+
+	FIELD_SET(padctrl, RP1_PAD_PULL_MASK, arg & 0x3);
+	writel(padctrl, pin->pad);
+}
+
+static int rp1_pinconf_set(struct rp1_pin_info *pin, unsigned int offset,
+			   unsigned long *configs, unsigned int num_configs)
+{
+	u32 param, arg;
+	int i;
+
+	if (!pin)
+		return -EINVAL;
+
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
+		arg = pinconf_to_config_argument(configs[i]);
+
+		switch (param) {
+		case PIN_CONFIG_BIAS_DISABLE:
+			rp1_pull_config_set(pin, RP1_PUD_OFF);
+			break;
+
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			rp1_pull_config_set(pin, RP1_PUD_DOWN);
+			break;
+
+		case PIN_CONFIG_BIAS_PULL_UP:
+			rp1_pull_config_set(pin, RP1_PUD_UP);
+			break;
+
+		case PIN_CONFIG_INPUT_ENABLE:
+			rp1_input_enable(pin, arg);
+			break;
+
+		case PIN_CONFIG_OUTPUT_ENABLE:
+			rp1_output_enable(pin, arg);
+			break;
+
+		case PIN_CONFIG_OUTPUT:
+			rp1_set_value(pin, arg);
+			rp1_set_dir(pin, RP1_DIR_OUTPUT);
+			rp1_set_fsel(pin, RP1_FSEL_GPIO);
+			break;
+
+		case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+			rp1_pad_update(pin, RP1_PAD_SCHMITT_MASK,
+				       arg ? RP1_PAD_SCHMITT_MASK : 0);
+			break;
+
+		case PIN_CONFIG_SLEW_RATE:
+			rp1_pad_update(pin, RP1_PAD_SLEWFAST_MASK,
+				       arg ? RP1_PAD_SLEWFAST_MASK : 0);
+			break;
+
+		case PIN_CONFIG_DRIVE_STRENGTH:
+			switch (arg) {
+			case 2:
+				arg = RP1_PAD_DRIVE_2MA;
+				break;
+			case 4:
+				arg = RP1_PAD_DRIVE_4MA;
+				break;
+			case 8:
+				arg = RP1_PAD_DRIVE_8MA;
+				break;
+			case 12:
+				arg = RP1_PAD_DRIVE_12MA;
+				break;
+			default:
+				return -ENOTSUPP;
+			}
+			rp1_pad_update(pin, RP1_PAD_DRIVE_MASK, arg);
+			break;
+
+		default:
+			return -ENOTSUPP;
+
+		} /* switch param type */
+	} /* for each config */
+
+	return 0;
+}
+
+static const struct of_device_id rp1_pinctrl_match[] = {
+	{ .compatible = "raspberrypi,rp1-gpio" },
+	{},
+};
+
+static int rp1_pinctrl_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct gpio_irq_chip *girq;
+	struct rp1_pinctrl *pc;
+	int err, i;
+
+	pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
+	if (!pc)
+		return -ENOMEM;
+
+	pc->dev = dev;
+	pc->gpio_chip = rp1_gpio_chip;
+	pc->gpio_chip.parent = dev;
+
+	pc->gpio_base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(pc->gpio_base)) {
+		dev_err(dev, "could not get GPIO IO memory\n");
+		return PTR_ERR(pc->gpio_base);
+	}
+
+	pc->rio_base = devm_platform_ioremap_resource(pdev, 1);
+	if (IS_ERR(pc->rio_base)) {
+		dev_err(dev, "could not get RIO IO memory\n");
+		return PTR_ERR(pc->rio_base);
+	}
+
+	pc->pads_base = devm_platform_ioremap_resource(pdev, 2);
+	if (IS_ERR(pc->pads_base)) {
+		dev_err(dev, "could not get PADS IO memory\n");
+		return PTR_ERR(pc->pads_base);
+	}
+
+	for (i = 0; i < RP1_NUM_BANKS; i++) {
+		const struct rp1_iobank_desc *bank = &rp1_iobanks[i];
+		int j;
+
+		for (j = 0; j < bank->num_gpios; j++) {
+			struct rp1_pin_info *pin =
+				&pc->pins[bank->min_gpio + j];
+
+			pin->num = bank->min_gpio + j;
+			pin->bank = i;
+			pin->offset = j;
+
+			pin->gpio = pc->gpio_base + bank->gpio_offset +
+				    j * sizeof(u32) * 2;
+			pin->inte = pc->gpio_base + bank->inte_offset;
+			pin->ints = pc->gpio_base + bank->ints_offset;
+			pin->rio  = pc->rio_base + bank->rio_offset;
+			pin->pad  = pc->pads_base + bank->pads_offset +
+				    j * sizeof(u32);
+		}
+
+		raw_spin_lock_init(&pc->irq_lock[i]);
+	}
+
+	girq = &pc->gpio_chip.irq;
+	girq->chip = &rp1_gpio_irq_chip;
+	girq->parent_handler = rp1_gpio_irq_handler;
+	girq->num_parents = RP1_NUM_BANKS;
+	girq->parents = pc->irq;
+	girq->default_type = IRQ_TYPE_NONE;
+	girq->handler = handle_level_irq;
+
+	/*
+	 * Use the same handler for all groups: this is necessary
+	 * since we use one gpiochip to cover all lines - the
+	 * irq handler then needs to figure out which group and
+	 * bank that was firing the IRQ and look up the per-group
+	 * and bank data.
+	 */
+	for (i = 0; i < RP1_NUM_BANKS; i++) {
+		pc->irq[i] = irq_of_parse_and_map(np, i);
+		if (!pc->irq[i]) {
+			girq->num_parents = i;
+			break;
+		}
+	}
+
+	platform_set_drvdata(pdev, pc);
+
+	err = devm_gpiochip_add_data(dev, &pc->gpio_chip, pc);
+	if (err) {
+		dev_err(dev, "could not add GPIO chip\n");
+		return err;
+	}
+
+	return 0;
+}
+
+static struct platform_driver rp1_pinctrl_driver = {
+	.probe = rp1_pinctrl_probe,
+	.driver = {
+		.name = MODULE_NAME,
+		.of_match_table = rp1_pinctrl_match,
+		.suppress_bind_attrs = true,
+	},
+};
+builtin_platform_driver(rp1_pinctrl_driver);
-- 
2.35.3


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

* [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-20 14:36 [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay Andrea della Porta
                   ` (6 preceding siblings ...)
  2024-08-20 14:36 ` [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support Andrea della Porta
@ 2024-08-20 14:36 ` Andrea della Porta
  2024-08-21  8:38   ` Krzysztof Kozlowski
                     ` (6 more replies)
  2024-08-20 14:36 ` [PATCH 09/11] arm64: defconfig: Enable RP1 misc/clock/gpio drivers as built-in Andrea della Porta
                   ` (3 subsequent siblings)
  11 siblings, 7 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-08-20 14:36 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

The RaspberryPi RP1 is ia PCI multi function device containing
peripherals ranging from Ethernet to USB controller, I2C, SPI
and others.
Implement a bare minimum driver to operate the RP1, leveraging
actual OF based driver implementations for the on-borad peripherals
by loading a devicetree overlay during driver probe.
The peripherals are accessed by mapping MMIO registers starting
from PCI BAR1 region.
As a minimum driver, the peripherals will not be added to the
dtbo here, but in following patches.

Link: https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
---
 MAINTAINERS                           |   2 +
 arch/arm64/boot/dts/broadcom/rp1.dtso | 152 ++++++++++++
 drivers/misc/Kconfig                  |   1 +
 drivers/misc/Makefile                 |   1 +
 drivers/misc/rp1/Kconfig              |  20 ++
 drivers/misc/rp1/Makefile             |   3 +
 drivers/misc/rp1/rp1-pci.c            | 333 ++++++++++++++++++++++++++
 drivers/misc/rp1/rp1-pci.dtso         |   8 +
 drivers/pci/quirks.c                  |   1 +
 include/linux/pci_ids.h               |   3 +
 10 files changed, 524 insertions(+)
 create mode 100644 arch/arm64/boot/dts/broadcom/rp1.dtso
 create mode 100644 drivers/misc/rp1/Kconfig
 create mode 100644 drivers/misc/rp1/Makefile
 create mode 100644 drivers/misc/rp1/rp1-pci.c
 create mode 100644 drivers/misc/rp1/rp1-pci.dtso

diff --git a/MAINTAINERS b/MAINTAINERS
index 67f460c36ea1..1359538b76e8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19119,9 +19119,11 @@ F:	include/uapi/linux/media/raspberrypi/
 RASPBERRY PI RP1 PCI DRIVER
 M:	Andrea della Porta <andrea.porta@suse.com>
 S:	Maintained
+F:	arch/arm64/boot/dts/broadcom/rp1.dtso
 F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
 F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
 F:	drivers/clk/clk-rp1.c
+F:	drivers/misc/rp1/
 F:	drivers/pinctrl/pinctrl-rp1.c
 F:	include/dt-bindings/clock/rp1.h
 F:	include/dt-bindings/misc/rp1.h
diff --git a/arch/arm64/boot/dts/broadcom/rp1.dtso b/arch/arm64/boot/dts/broadcom/rp1.dtso
new file mode 100644
index 000000000000..d80178a278ee
--- /dev/null
+++ b/arch/arm64/boot/dts/broadcom/rp1.dtso
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/clock/rp1.h>
+#include <dt-bindings/misc/rp1.h>
+
+/dts-v1/;
+/plugin/;
+
+/ {
+	fragment@0 {
+		target-path="";
+		__overlay__ {
+			#address-cells = <3>;
+			#size-cells = <2>;
+
+			rp1: rp1@0 {
+				compatible = "simple-bus";
+				#address-cells = <2>;
+				#size-cells = <2>;
+				interrupt-controller;
+				interrupt-parent = <&rp1>;
+				#interrupt-cells = <2>;
+
+				// ranges and dma-ranges must be provided by the includer
+				ranges = <0xc0 0x40000000
+					  0x01/*0x02000000*/ 0x00 0x00000000
+					  0x00 0x00400000>;
+
+				dma-ranges =
+				// inbound RP1 1x_xxxxxxxx -> PCIe 1x_xxxxxxxx
+					     <0x10 0x00000000
+					      0x43000000 0x10 0x00000000
+					      0x10 0x00000000>;
+
+				clk_xosc: clk_xosc {
+					compatible = "fixed-clock";
+					#clock-cells = <0>;
+					clock-output-names = "xosc";
+					clock-frequency = <50000000>;
+				};
+
+				macb_pclk: macb_pclk {
+					compatible = "fixed-clock";
+					#clock-cells = <0>;
+					clock-output-names = "pclk";
+					clock-frequency = <200000000>;
+				};
+
+				macb_hclk: macb_hclk {
+					compatible = "fixed-clock";
+					#clock-cells = <0>;
+					clock-output-names = "hclk";
+					clock-frequency = <200000000>;
+				};
+
+				rp1_clocks: clocks@c040018000 {
+					compatible = "raspberrypi,rp1-clocks";
+					#clock-cells = <1>;
+					reg = <0xc0 0x40018000 0x0 0x10038>;
+					clocks = <&clk_xosc>;
+					clock-names = "xosc";
+
+					assigned-clocks = <&rp1_clocks RP1_PLL_SYS_CORE>,
+							  <&rp1_clocks RP1_PLL_AUDIO_CORE>,
+							  // RP1_PLL_VIDEO_CORE and dividers are now managed by VEC,DPI drivers
+							  <&rp1_clocks RP1_PLL_SYS>,
+							  <&rp1_clocks RP1_PLL_SYS_SEC>,
+							  <&rp1_clocks RP1_PLL_SYS_PRI_PH>,
+							  <&rp1_clocks RP1_CLK_ETH_TSU>;
+
+					assigned-clock-rates = <1000000000>, // RP1_PLL_SYS_CORE
+							       <1536000000>, // RP1_PLL_AUDIO_CORE
+							       <200000000>,  // RP1_PLL_SYS
+							       <125000000>,  // RP1_PLL_SYS_SEC
+							       <100000000>,  // RP1_PLL_SYS_PRI_PH
+							       <50000000>;   // RP1_CLK_ETH_TSU
+				};
+
+				rp1_gpio: pinctrl@c0400d0000 {
+					reg = <0xc0 0x400d0000  0x0 0xc000>,
+					      <0xc0 0x400e0000  0x0 0xc000>,
+					      <0xc0 0x400f0000  0x0 0xc000>;
+					compatible = "raspberrypi,rp1-gpio";
+					gpio-controller;
+					#gpio-cells = <2>;
+					interrupt-controller;
+					#interrupt-cells = <2>;
+					interrupts = <RP1_INT_IO_BANK0 IRQ_TYPE_LEVEL_HIGH>,
+						     <RP1_INT_IO_BANK1 IRQ_TYPE_LEVEL_HIGH>,
+						     <RP1_INT_IO_BANK2 IRQ_TYPE_LEVEL_HIGH>;
+					gpio-line-names =
+						"ID_SDA", // GPIO0
+						"ID_SCL", // GPIO1
+						"GPIO2", // GPIO2
+						"GPIO3", // GPIO3
+						"GPIO4", // GPIO4
+						"GPIO5", // GPIO5
+						"GPIO6", // GPIO6
+						"GPIO7", // GPIO7
+						"GPIO8", // GPIO8
+						"GPIO9", // GPIO9
+						"GPIO10", // GPIO10
+						"GPIO11", // GPIO11
+						"GPIO12", // GPIO12
+						"GPIO13", // GPIO13
+						"GPIO14", // GPIO14
+						"GPIO15", // GPIO15
+						"GPIO16", // GPIO16
+						"GPIO17", // GPIO17
+						"GPIO18", // GPIO18
+						"GPIO19", // GPIO19
+						"GPIO20", // GPIO20
+						"GPIO21", // GPIO21
+						"GPIO22", // GPIO22
+						"GPIO23", // GPIO23
+						"GPIO24", // GPIO24
+						"GPIO25", // GPIO25
+						"GPIO26", // GPIO26
+						"GPIO27", // GPIO27
+						"PCIE_RP1_WAKE", // GPIO28
+						"FAN_TACH", // GPIO29
+						"HOST_SDA", // GPIO30
+						"HOST_SCL", // GPIO31
+						"ETH_RST_N", // GPIO32
+						"", // GPIO33
+						"CD0_IO0_MICCLK", // GPIO34
+						"CD0_IO0_MICDAT0", // GPIO35
+						"RP1_PCIE_CLKREQ_N", // GPIO36
+						"", // GPIO37
+						"CD0_SDA", // GPIO38
+						"CD0_SCL", // GPIO39
+						"CD1_SDA", // GPIO40
+						"CD1_SCL", // GPIO41
+						"USB_VBUS_EN", // GPIO42
+						"USB_OC_N", // GPIO43
+						"RP1_STAT_LED", // GPIO44
+						"FAN_PWM", // GPIO45
+						"CD1_IO0_MICCLK", // GPIO46
+						"2712_WAKE", // GPIO47
+						"CD1_IO1_MICDAT1", // GPIO48
+						"EN_MAX_USB_CUR", // GPIO49
+						"", // GPIO50
+						"", // GPIO51
+						"", // GPIO52
+						""; // GPIO53
+				};
+			};
+		};
+	};
+};
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 41c3d2821a78..02405209e6c4 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -618,4 +618,5 @@ source "drivers/misc/uacce/Kconfig"
 source "drivers/misc/pvpanic/Kconfig"
 source "drivers/misc/mchp_pci1xxxx/Kconfig"
 source "drivers/misc/keba/Kconfig"
+source "drivers/misc/rp1/Kconfig"
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index c2f990862d2b..84bfa866fbee 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -71,3 +71,4 @@ obj-$(CONFIG_TPS6594_PFSM)	+= tps6594-pfsm.o
 obj-$(CONFIG_NSM)		+= nsm.o
 obj-$(CONFIG_MARVELL_CN10K_DPI)	+= mrvl_cn10k_dpi.o
 obj-y				+= keba/
+obj-$(CONFIG_MISC_RP1)		+= rp1/
diff --git a/drivers/misc/rp1/Kconfig b/drivers/misc/rp1/Kconfig
new file mode 100644
index 000000000000..050417ee09ae
--- /dev/null
+++ b/drivers/misc/rp1/Kconfig
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# RaspberryPi RP1 misc device
+#
+
+config MISC_RP1
+        tristate "RaspberryPi RP1 PCIe support"
+        depends on PCI && PCI_QUIRKS
+        select OF
+        select OF_OVERLAY
+        select IRQ_DOMAIN
+        select PCI_DYNAMIC_OF_NODES
+        help
+          Support for the RP1 peripheral chip found on Raspberry Pi 5 board.
+          This device supports several sub-devices including e.g. Ethernet controller,
+          USB controller, I2C, SPI and UART.
+          The driver is responsible for enabling the DT node once the PCIe endpoint
+          has been configured, and handling interrupts.
+          This driver uses an overlay to load other drivers to support for RP1
+          internal sub-devices.
diff --git a/drivers/misc/rp1/Makefile b/drivers/misc/rp1/Makefile
new file mode 100644
index 000000000000..e83854b4ed2c
--- /dev/null
+++ b/drivers/misc/rp1/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+rp1-pci-objs			:= rp1-pci.o rp1-pci.dtbo.o
+obj-$(CONFIG_MISC_RP1)		+= rp1-pci.o
diff --git a/drivers/misc/rp1/rp1-pci.c b/drivers/misc/rp1/rp1-pci.c
new file mode 100644
index 000000000000..a6093ba7e19a
--- /dev/null
+++ b/drivers/misc/rp1/rp1-pci.c
@@ -0,0 +1,333 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018-22 Raspberry Pi Ltd.
+ * All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/of_platform.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+#include <dt-bindings/misc/rp1.h>
+
+#define RP1_B0_CHIP_ID		0x10001927
+#define RP1_C0_CHIP_ID		0x20001927
+
+#define RP1_PLATFORM_ASIC	BIT(1)
+#define RP1_PLATFORM_FPGA	BIT(0)
+
+#define RP1_DRIVER_NAME		"rp1"
+
+#define RP1_ACTUAL_IRQS		RP1_INT_END
+#define RP1_IRQS		RP1_ACTUAL_IRQS
+#define RP1_HW_IRQ_MASK		GENMASK(5, 0)
+
+#define RP1_SYSCLK_RATE		200000000
+#define RP1_SYSCLK_FPGA_RATE	60000000
+
+enum {
+	SYSINFO_CHIP_ID_OFFSET	= 0,
+	SYSINFO_PLATFORM_OFFSET	= 4,
+};
+
+#define REG_SET			0x800
+#define REG_CLR			0xc00
+
+/* MSIX CFG registers start at 0x8 */
+#define MSIX_CFG(x) (0x8 + (4 * (x)))
+
+#define MSIX_CFG_IACK_EN        BIT(3)
+#define MSIX_CFG_IACK           BIT(2)
+#define MSIX_CFG_TEST           BIT(1)
+#define MSIX_CFG_ENABLE         BIT(0)
+
+#define INTSTATL		0x108
+#define INTSTATH		0x10c
+
+extern char __dtbo_rp1_pci_begin[];
+extern char __dtbo_rp1_pci_end[];
+
+struct rp1_dev {
+	struct pci_dev *pdev;
+	struct device *dev;
+	struct clk *sys_clk;
+	struct irq_domain *domain;
+	struct irq_data *pcie_irqds[64];
+	void __iomem *bar1;
+	int ovcs_id;
+	bool level_triggered_irq[RP1_ACTUAL_IRQS];
+};
+
+static void dump_bar(struct pci_dev *pdev, unsigned int bar)
+{
+	dev_info(&pdev->dev,
+		 "bar%d len 0x%llx, start 0x%llx, end 0x%llx, flags, 0x%lx\n",
+		 bar,
+		 pci_resource_len(pdev, bar),
+		 pci_resource_start(pdev, bar),
+		 pci_resource_end(pdev, bar),
+		 pci_resource_flags(pdev, bar));
+}
+
+static void msix_cfg_set(struct rp1_dev *rp1, unsigned int hwirq, u32 value)
+{
+	iowrite32(value, rp1->bar1 + RP1_PCIE_APBS_BASE + REG_SET + MSIX_CFG(hwirq));
+}
+
+static void msix_cfg_clr(struct rp1_dev *rp1, unsigned int hwirq, u32 value)
+{
+	iowrite32(value, rp1->bar1 + RP1_PCIE_APBS_BASE + REG_CLR + MSIX_CFG(hwirq));
+}
+
+static void rp1_mask_irq(struct irq_data *irqd)
+{
+	struct rp1_dev *rp1 = irqd->domain->host_data;
+	struct irq_data *pcie_irqd = rp1->pcie_irqds[irqd->hwirq];
+
+	pci_msi_mask_irq(pcie_irqd);
+}
+
+static void rp1_unmask_irq(struct irq_data *irqd)
+{
+	struct rp1_dev *rp1 = irqd->domain->host_data;
+	struct irq_data *pcie_irqd = rp1->pcie_irqds[irqd->hwirq];
+
+	pci_msi_unmask_irq(pcie_irqd);
+}
+
+static int rp1_irq_set_type(struct irq_data *irqd, unsigned int type)
+{
+	struct rp1_dev *rp1 = irqd->domain->host_data;
+	unsigned int hwirq = (unsigned int)irqd->hwirq;
+	int ret = 0;
+
+	switch (type) {
+	case IRQ_TYPE_LEVEL_HIGH:
+		dev_dbg(rp1->dev, "MSIX IACK EN for irq %d\n", hwirq);
+		msix_cfg_set(rp1, hwirq, MSIX_CFG_IACK_EN);
+		rp1->level_triggered_irq[hwirq] = true;
+	break;
+	case IRQ_TYPE_EDGE_RISING:
+		msix_cfg_clr(rp1, hwirq, MSIX_CFG_IACK_EN);
+		rp1->level_triggered_irq[hwirq] = false;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static struct irq_chip rp1_irq_chip = {
+	.name            = "rp1_irq_chip",
+	.irq_mask        = rp1_mask_irq,
+	.irq_unmask      = rp1_unmask_irq,
+	.irq_set_type    = rp1_irq_set_type,
+};
+
+static void rp1_chained_handle_irq(struct irq_desc *desc)
+{
+	unsigned int hwirq = desc->irq_data.hwirq & RP1_HW_IRQ_MASK;
+	struct rp1_dev *rp1 = irq_desc_get_handler_data(desc);
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	int virq;
+
+	chained_irq_enter(chip, desc);
+
+	virq = irq_find_mapping(rp1->domain, hwirq);
+	generic_handle_irq(virq);
+	if (rp1->level_triggered_irq[hwirq])
+		msix_cfg_set(rp1, hwirq, MSIX_CFG_IACK);
+
+	chained_irq_exit(chip, desc);
+}
+
+static int rp1_irq_xlate(struct irq_domain *d, struct device_node *node,
+			 const u32 *intspec, unsigned int intsize,
+			 unsigned long *out_hwirq, unsigned int *out_type)
+{
+	struct rp1_dev *rp1 = d->host_data;
+	struct irq_data *pcie_irqd;
+	unsigned long hwirq;
+	int pcie_irq;
+	int ret;
+
+	ret = irq_domain_xlate_twocell(d, node, intspec, intsize,
+				       &hwirq, out_type);
+	if (!ret) {
+		pcie_irq = pci_irq_vector(rp1->pdev, hwirq);
+		pcie_irqd = irq_get_irq_data(pcie_irq);
+		rp1->pcie_irqds[hwirq] = pcie_irqd;
+		*out_hwirq = hwirq;
+	}
+
+	return ret;
+}
+
+static int rp1_irq_activate(struct irq_domain *d, struct irq_data *irqd,
+			    bool reserve)
+{
+	struct rp1_dev *rp1 = d->host_data;
+	struct irq_data *pcie_irqd;
+
+	pcie_irqd = rp1->pcie_irqds[irqd->hwirq];
+	msix_cfg_set(rp1, (unsigned int)irqd->hwirq, MSIX_CFG_ENABLE);
+
+	return irq_domain_activate_irq(pcie_irqd, reserve);
+}
+
+static void rp1_irq_deactivate(struct irq_domain *d, struct irq_data *irqd)
+{
+	struct rp1_dev *rp1 = d->host_data;
+	struct irq_data *pcie_irqd;
+
+	pcie_irqd = rp1->pcie_irqds[irqd->hwirq];
+	msix_cfg_clr(rp1, (unsigned int)irqd->hwirq, MSIX_CFG_ENABLE);
+
+	return irq_domain_deactivate_irq(pcie_irqd);
+}
+
+static const struct irq_domain_ops rp1_domain_ops = {
+	.xlate      = rp1_irq_xlate,
+	.activate   = rp1_irq_activate,
+	.deactivate = rp1_irq_deactivate,
+};
+
+static int rp1_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *rp1_node;
+	struct reset_control *reset;
+	struct rp1_dev *rp1;
+	int err  = 0;
+	int i;
+
+	rp1_node = dev_of_node(dev);
+	if (!rp1_node) {
+		dev_err(dev, "Missing of_node for device\n");
+		return -EINVAL;
+	}
+
+	rp1 = devm_kzalloc(&pdev->dev, sizeof(*rp1), GFP_KERNEL);
+	if (!rp1)
+		return -ENOMEM;
+
+	rp1->pdev = pdev;
+	rp1->dev = &pdev->dev;
+
+	reset = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
+	if (IS_ERR(reset))
+		return PTR_ERR(reset);
+	reset_control_reset(reset);
+
+	dump_bar(pdev, 0);
+	dump_bar(pdev, 1);
+
+	if (pci_resource_len(pdev, 1) <= 0x10000) {
+		dev_err(&pdev->dev,
+			"Not initialised - is the firmware running?\n");
+		return -EINVAL;
+	}
+
+	err = pcim_enable_device(pdev);
+	if (err < 0) {
+		dev_err(&pdev->dev, "Enabling PCI device has failed: %d",
+			err);
+		return err;
+	}
+
+	rp1->bar1 = pci_iomap(pdev, 1, 0);
+	if (!rp1->bar1) {
+		dev_err(&pdev->dev, "Cannot map PCI bar\n");
+		return -EIO;
+	}
+
+	u32 dtbo_size = __dtbo_rp1_pci_end - __dtbo_rp1_pci_begin;
+	void *dtbo_start = __dtbo_rp1_pci_begin;
+
+	err = of_overlay_fdt_apply(dtbo_start, dtbo_size, &rp1->ovcs_id, rp1_node);
+	if (err)
+		goto err_unmap_bar;
+
+	pci_set_master(pdev);
+
+	err = pci_alloc_irq_vectors(pdev, RP1_IRQS, RP1_IRQS,
+				    PCI_IRQ_MSIX);
+	if (err != RP1_IRQS) {
+		dev_err(&pdev->dev, "pci_alloc_irq_vectors failed - %d\n", err);
+		goto err_unload_overlay;
+	}
+
+	pci_set_drvdata(pdev, rp1);
+	rp1->domain = irq_domain_add_linear(of_find_node_by_name(NULL, "rp1"), RP1_IRQS,
+					    &rp1_domain_ops, rp1);
+
+	for (i = 0; i < RP1_IRQS; i++) {
+		int irq = irq_create_mapping(rp1->domain, i);
+
+		if (irq < 0) {
+			dev_err(&pdev->dev, "failed to create irq mapping\n");
+			err = irq;
+			goto err_unload_overlay;
+		}
+		irq_set_chip_and_handler(irq, &rp1_irq_chip, handle_level_irq);
+		irq_set_probe(irq);
+		irq_set_chained_handler_and_data(pci_irq_vector(pdev, i),
+						 rp1_chained_handle_irq, rp1);
+	}
+
+	err = of_platform_default_populate(rp1_node, NULL, dev);
+	if (err)
+		goto err_unload_overlay;
+
+	return 0;
+
+err_unload_overlay:
+	of_overlay_remove(&rp1->ovcs_id);
+err_unmap_bar:
+	pci_iounmap(pdev, rp1->bar1);
+
+	return err;
+}
+
+static void rp1_remove(struct pci_dev *pdev)
+{
+	struct rp1_dev *rp1 = pci_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+
+	of_platform_depopulate(dev);
+	pci_iounmap(pdev, rp1->bar1);
+	of_overlay_remove(&rp1->ovcs_id);
+
+	clk_unregister(rp1->sys_clk);
+}
+
+static const struct pci_device_id dev_id_table[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_RPI, PCI_DEVICE_ID_RP1_C0), },
+	{ 0, }
+};
+
+static struct pci_driver rp1_driver = {
+	.name		= RP1_DRIVER_NAME,
+	.id_table	= dev_id_table,
+	.probe		= rp1_probe,
+	.remove		= rp1_remove,
+};
+
+module_pci_driver(rp1_driver);
+
+MODULE_AUTHOR("Phil Elwell <phil@raspberrypi.com>");
+MODULE_DESCRIPTION("RP1 wrapper");
+MODULE_LICENSE("GPL");
diff --git a/drivers/misc/rp1/rp1-pci.dtso b/drivers/misc/rp1/rp1-pci.dtso
new file mode 100644
index 000000000000..0bf2f4bb18e6
--- /dev/null
+++ b/drivers/misc/rp1/rp1-pci.dtso
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+/* the dts overlay is included from the dts directory so
+ * it can be possible to check it with CHECK_DTBS while
+ * also compile it from the driver source directory.
+ */
+
+#include "arm64/broadcom/rp1.dtso"
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index a2ce4e08edf5..8c2e6238535e 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -6245,6 +6245,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0xa76e, dpc_log_size);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_XILINX, 0x5020, of_pci_make_dev_node);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_XILINX, 0x5021, of_pci_make_dev_node);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REDHAT, 0x0005, of_pci_make_dev_node);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_RPI, PCI_DEVICE_ID_RP1_C0, of_pci_make_dev_node);
 
 /*
  * Devices known to require a longer delay before first config space access
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index e388c8b1cbc2..2120f2895bb8 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2610,6 +2610,9 @@
 #define PCI_VENDOR_ID_TEKRAM		0x1de1
 #define PCI_DEVICE_ID_TEKRAM_DC290	0xdc29
 
+#define PCI_VENDOR_ID_RPI		0x1de4
+#define PCI_DEVICE_ID_RP1_C0		0x0001
+
 #define PCI_VENDOR_ID_ALIBABA		0x1ded
 
 #define PCI_VENDOR_ID_CXL		0x1e98
-- 
2.35.3


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

* [PATCH 09/11] arm64: defconfig: Enable RP1 misc/clock/gpio drivers as built-in
  2024-08-20 14:36 [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay Andrea della Porta
                   ` (7 preceding siblings ...)
  2024-08-20 14:36 ` [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver Andrea della Porta
@ 2024-08-20 14:36 ` Andrea della Porta
  2024-08-21  8:47   ` Krzysztof Kozlowski
  2024-08-20 14:36 ` [PATCH 10/11] net: macb: Add support for RP1's MACB variant Andrea della Porta
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-20 14:36 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Select the RP1 drivers needed to operate the PCI endpoint containing
several peripherals such as Ethernet and USB Controller. This chip is
present on RaspberryPi 5.

Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
---
 arch/arm64/configs/defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 7d32fca64996..e7615c464680 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -606,6 +606,7 @@ CONFIG_PINCTRL_QCM2290=y
 CONFIG_PINCTRL_QCS404=y
 CONFIG_PINCTRL_QDF2XXX=y
 CONFIG_PINCTRL_QDU1000=y
+CONFIG_PINCTRL_RP1=y
 CONFIG_PINCTRL_SA8775P=y
 CONFIG_PINCTRL_SC7180=y
 CONFIG_PINCTRL_SC7280=y
@@ -685,6 +686,7 @@ CONFIG_SENSORS_RASPBERRYPI_HWMON=m
 CONFIG_SENSORS_SL28CPLD=m
 CONFIG_SENSORS_INA2XX=m
 CONFIG_SENSORS_INA3221=m
+CONFIG_MISC_RP1=y
 CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
 CONFIG_CPU_THERMAL=y
 CONFIG_DEVFREQ_THERMAL=y
@@ -1259,6 +1261,7 @@ CONFIG_COMMON_CLK_CS2000_CP=y
 CONFIG_COMMON_CLK_FSL_SAI=y
 CONFIG_COMMON_CLK_S2MPS11=y
 CONFIG_COMMON_CLK_PWM=y
+CONFIG_COMMON_CLK_RP1=y
 CONFIG_COMMON_CLK_RS9_PCIE=y
 CONFIG_COMMON_CLK_VC3=y
 CONFIG_COMMON_CLK_VC5=y
-- 
2.35.3


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

* [PATCH 10/11] net: macb: Add support for RP1's MACB variant
  2024-08-20 14:36 [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay Andrea della Porta
                   ` (8 preceding siblings ...)
  2024-08-20 14:36 ` [PATCH 09/11] arm64: defconfig: Enable RP1 misc/clock/gpio drivers as built-in Andrea della Porta
@ 2024-08-20 14:36 ` Andrea della Porta
  2024-08-20 15:13   ` Andrew Lunn
                     ` (2 more replies)
  2024-08-20 14:36 ` [PATCH 11/11] arm64: dts: rp1: Add support for MACB contained in RP1 Andrea della Porta
  2024-08-21 13:42 ` [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay Krzysztof Kozlowski
  11 siblings, 3 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-08-20 14:36 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

RaspberryPi RP1 contains Cadence's MACB core. Implement the
changes to be able to operate the customization in the RP1.

Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
---
 drivers/net/ethernet/cadence/macb.h      |  25 ++++
 drivers/net/ethernet/cadence/macb_main.c | 152 ++++++++++++++++++++++-
 2 files changed, 175 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index ea71612f6b36..1d298f0cf685 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -85,6 +85,8 @@
 #define GEM_PBUFRXCUT		0x0044 /* RX Partial Store and Forward */
 #define GEM_JML			0x0048 /* Jumbo Max Length */
 #define GEM_HS_MAC_CONFIG	0x0050 /* GEM high speed config */
+#define GEM_AMP			0x0054 /* AXI Max Pipeline */
+#define GEM_INTMOD		0x005c /* Interrupt moderation */
 #define GEM_HRB			0x0080 /* Hash Bottom */
 #define GEM_HRT			0x0084 /* Hash Top */
 #define GEM_SA1B		0x0088 /* Specific1 Bottom */
@@ -347,6 +349,21 @@
 #define GEM_ADDR64_OFFSET	30 /* Address bus width - 64b or 32b */
 #define GEM_ADDR64_SIZE		1
 
+/* Bitfields in AMP */
+#define GEM_AR2R_MAX_PIPE_OFFSET	0  /* Maximum number of outstanding AXI read requests */
+#define GEM_AR2R_MAX_PIPE_SIZE		8
+#define GEM_AW2W_MAX_PIPE_OFFSET	8  /* Maximum number of outstanding AXI write requests */
+#define GEM_AW2W_MAX_PIPE_SIZE		8
+#define GEM_AW2B_FILL_OFFSET		16 /* Select wether the max AW2W transactions operates between: */
+#define GEM_AW2B_FILL_AW2W		0  /*   0: the AW to W AXI channel */
+#define GEM_AW2B_FILL_AW2B		1  /*   1: AW to B channel */
+#define GEM_AW2B_FILL_SIZE              1
+
+/* Bitfields in INTMOD */
+#define GEM_RX_MODERATION_OFFSET	0  /* RX interrupt moderation */
+#define GEM_RX_MODERATION_SIZE		8
+#define GEM_TX_MODERATION_OFFSET	16 /* TX interrupt moderation */
+#define GEM_TX_MODERATION_SIZE		8
 
 /* Bitfields in PBUFRXCUT */
 #define GEM_ENCUTTHRU_OFFSET	31 /* Enable RX partial store and forward */
@@ -812,6 +829,7 @@
 	})
 
 #define MACB_READ_NSR(bp)	macb_readl(bp, NSR)
+#define MACB_READ_TSR(bp)	macb_readl(bp, TSR)
 
 /* struct macb_dma_desc - Hardware DMA descriptor
  * @addr: DMA address of data buffer
@@ -1228,6 +1246,7 @@ struct macb_queue {
 	dma_addr_t		tx_ring_dma;
 	struct work_struct	tx_error_task;
 	bool			txubr_pending;
+	bool			tx_pending;
 	struct napi_struct	napi_tx;
 
 	dma_addr_t		rx_ring_dma;
@@ -1293,9 +1312,15 @@ struct macb {
 
 	u32			caps;
 	unsigned int		dma_burst_length;
+	u8			aw2w_max_pipe;
+	u8			ar2r_max_pipe;
+	bool			use_aw2b_fill;
 
 	phy_interface_t		phy_interface;
 
+	struct gpio_desc	*phy_reset_gpio;
+	int			phy_reset_ms;
+
 	/* AT91RM9200 transmit queue (1 on wire + 1 queued) */
 	struct macb_tx_skb	rm9200_txq[2];
 	unsigned int		max_tx_length;
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 11665be3a22c..5eb5be6c96fc 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -41,6 +41,9 @@
 #include <linux/inetdevice.h>
 #include "macb.h"
 
+static unsigned int txdelay = 35;
+module_param(txdelay, uint, 0644);
+
 /* This structure is only used for MACB on SiFive FU540 devices */
 struct sifive_fu540_macb_mgmt {
 	void __iomem *reg;
@@ -334,7 +337,7 @@ static int macb_mdio_wait_for_idle(struct macb *bp)
 	u32 val;
 
 	return readx_poll_timeout(MACB_READ_NSR, bp, val, val & MACB_BIT(IDLE),
-				  1, MACB_MDIO_TIMEOUT);
+				  100, MACB_MDIO_TIMEOUT);
 }
 
 static int macb_mdio_read_c22(struct mii_bus *bus, int mii_id, int regnum)
@@ -493,6 +496,19 @@ static int macb_mdio_write_c45(struct mii_bus *bus, int mii_id,
 	return status;
 }
 
+static int macb_mdio_reset(struct mii_bus *bus)
+{
+	struct macb *bp = bus->priv;
+
+	if (bp->phy_reset_gpio) {
+		gpiod_set_value_cansleep(bp->phy_reset_gpio, 1);
+		msleep(bp->phy_reset_ms);
+		gpiod_set_value_cansleep(bp->phy_reset_gpio, 0);
+	}
+
+	return 0;
+}
+
 static void macb_init_buffers(struct macb *bp)
 {
 	struct macb_queue *queue;
@@ -969,6 +985,7 @@ static int macb_mii_init(struct macb *bp)
 	bp->mii_bus->write = &macb_mdio_write_c22;
 	bp->mii_bus->read_c45 = &macb_mdio_read_c45;
 	bp->mii_bus->write_c45 = &macb_mdio_write_c45;
+	bp->mii_bus->reset = &macb_mdio_reset;
 	snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
 		 bp->pdev->name, bp->pdev->id);
 	bp->mii_bus->priv = bp;
@@ -1640,6 +1657,11 @@ static int macb_rx(struct macb_queue *queue, struct napi_struct *napi,
 
 		macb_init_rx_ring(queue);
 		queue_writel(queue, RBQP, queue->rx_ring_dma);
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+		if (bp->hw_dma_cap & HW_DMA_CAP_64B)
+			macb_writel(bp, RBQPH,
+				    upper_32_bits(queue->rx_ring_dma));
+#endif
 
 		macb_writel(bp, NCR, ctrl | MACB_BIT(RE));
 
@@ -1940,8 +1962,9 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
 				queue_writel(queue, ISR, MACB_BIT(TCOMP) |
 							 MACB_BIT(TXUBR));
 
-			if (status & MACB_BIT(TXUBR)) {
+			if (status & MACB_BIT(TXUBR) || queue->tx_pending) {
 				queue->txubr_pending = true;
+				queue->tx_pending = 0;
 				wmb(); // ensure softirq can see update
 			}
 
@@ -2394,6 +2417,11 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	skb_tx_timestamp(skb);
 
 	spin_lock_irq(&bp->lock);
+
+	/* TSTART write might get dropped, so make the IRQ retrigger a buffer read */
+	if (macb_readl(bp, TSR) & MACB_BIT(TGO))
+		queue->tx_pending = 1;
+
 	macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
 	spin_unlock_irq(&bp->lock);
 
@@ -2800,6 +2828,37 @@ static void macb_configure_dma(struct macb *bp)
 	}
 }
 
+static void gem_init_axi(struct macb *bp)
+{
+	u32 amp;
+
+	/* AXI pipeline setup - don't touch values unless specified in device
+	 * tree. Some hardware could have reset values > 1.
+	 */
+	amp = gem_readl(bp, AMP);
+
+	if (bp->use_aw2b_fill)
+		amp = GEM_BFINS(AW2B_FILL, bp->use_aw2b_fill, amp);
+	if (bp->aw2w_max_pipe)
+		amp = GEM_BFINS(AW2W_MAX_PIPE, bp->aw2w_max_pipe, amp);
+	if (bp->ar2r_max_pipe)
+		amp = GEM_BFINS(AR2R_MAX_PIPE, bp->ar2r_max_pipe, amp);
+
+	gem_writel(bp, AMP, amp);
+}
+
+static void gem_init_intmod(struct macb *bp)
+{
+	unsigned int throttle;
+	u32 intmod = 0;
+
+	/* Use sensible interrupt moderation thresholds (50us rx and tx) */
+	throttle = (1000 * 50) / 800;
+	intmod = GEM_BFINS(TX_MODERATION, throttle, intmod);
+	intmod = GEM_BFINS(RX_MODERATION, throttle, intmod);
+	gem_writel(bp, INTMOD, intmod);
+}
+
 static void macb_init_hw(struct macb *bp)
 {
 	u32 config;
@@ -2828,6 +2887,11 @@ static void macb_init_hw(struct macb *bp)
 	if (bp->caps & MACB_CAPS_JUMBO)
 		bp->rx_frm_len_mask = MACB_RX_JFRMLEN_MASK;
 
+	if (macb_is_gem(bp)) {
+		gem_init_axi(bp);
+		gem_init_intmod(bp);
+	}
+
 	macb_configure_dma(bp);
 
 	/* Enable RX partial store and forward and set watermark */
@@ -3189,6 +3253,52 @@ static void gem_get_ethtool_strings(struct net_device *dev, u32 sset, u8 *p)
 	}
 }
 
+static int gem_set_coalesce(struct net_device *dev,
+			    struct ethtool_coalesce *ec,
+			    struct kernel_ethtool_coalesce *kernel_coal,
+			    struct netlink_ext_ack *extack)
+{
+	struct macb *bp = netdev_priv(dev);
+	unsigned int tx_throttle;
+	unsigned int rx_throttle;
+	u32 intmod = 0;
+
+	/* GEM has simple IRQ throttling support. RX and TX interrupts
+	 * are separately moderated on 800ns quantums, with no support
+	 * for frame coalescing.
+	 */
+
+	/* Max is 255 * 0.8us = 204us. Zero implies no moderation. */
+	if (ec->rx_coalesce_usecs > 204 || ec->tx_coalesce_usecs > 204)
+		return -EINVAL;
+
+	tx_throttle = (1000 * ec->tx_coalesce_usecs) / 800;
+	rx_throttle = (1000 * ec->rx_coalesce_usecs) / 800;
+
+	intmod = GEM_BFINS(TX_MODERATION, tx_throttle, intmod);
+	intmod = GEM_BFINS(RX_MODERATION, rx_throttle, intmod);
+
+	gem_writel(bp, INTMOD, intmod);
+
+	return 0;
+}
+
+static int gem_get_coalesce(struct net_device *dev,
+			    struct ethtool_coalesce *ec,
+			    struct kernel_ethtool_coalesce *kernel_coal,
+			    struct netlink_ext_ack *extack)
+{
+	struct macb *bp = netdev_priv(dev);
+	u32 intmod;
+
+	intmod = gem_readl(bp, INTMOD);
+
+	ec->tx_coalesce_usecs = (GEM_BFEXT(TX_MODERATION, intmod) * 800) / 1000;
+	ec->rx_coalesce_usecs = (GEM_BFEXT(RX_MODERATION, intmod) * 800) / 1000;
+
+	return 0;
+}
+
 static struct net_device_stats *macb_get_stats(struct net_device *dev)
 {
 	struct macb *bp = netdev_priv(dev);
@@ -3772,6 +3882,8 @@ static const struct ethtool_ops macb_ethtool_ops = {
 };
 
 static const struct ethtool_ops gem_ethtool_ops = {
+	.supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS |
+				     ETHTOOL_COALESCE_TX_USECS,
 	.get_regs_len		= macb_get_regs_len,
 	.get_regs		= macb_get_regs,
 	.get_wol		= macb_get_wol,
@@ -3781,6 +3893,8 @@ static const struct ethtool_ops gem_ethtool_ops = {
 	.get_ethtool_stats	= gem_get_ethtool_stats,
 	.get_strings		= gem_get_ethtool_strings,
 	.get_sset_count		= gem_get_sset_count,
+	.get_coalesce		= gem_get_coalesce,
+	.set_coalesce		= gem_set_coalesce,
 	.get_link_ksettings     = macb_get_link_ksettings,
 	.set_link_ksettings     = macb_set_link_ksettings,
 	.get_ringparam		= macb_get_ringparam,
@@ -5100,6 +5214,11 @@ static int macb_probe(struct platform_device *pdev)
 			}
 		}
 	}
+
+	device_property_read_u8(&pdev->dev, "cdns,aw2w-max-pipe", &bp->aw2w_max_pipe);
+	device_property_read_u8(&pdev->dev, "cdns,ar2r-max-pipe", &bp->ar2r_max_pipe);
+	bp->use_aw2b_fill = device_property_read_bool(&pdev->dev, "cdns,use-aw2b-fill");
+
 	spin_lock_init(&bp->lock);
 
 	/* setup capabilities */
@@ -5155,6 +5274,21 @@ static int macb_probe(struct platform_device *pdev)
 	else
 		bp->phy_interface = interface;
 
+	/* optional PHY reset-related properties */
+	bp->phy_reset_gpio = devm_gpiod_get_optional(&pdev->dev, "phy-reset",
+						     GPIOD_OUT_LOW);
+	if (IS_ERR(bp->phy_reset_gpio)) {
+		dev_err(&pdev->dev, "Failed to obtain phy-reset gpio\n");
+		err = PTR_ERR(bp->phy_reset_gpio);
+		goto err_out_free_netdev;
+	}
+
+	bp->phy_reset_ms = 10;
+	of_property_read_u32(np, "phy-reset-duration", &bp->phy_reset_ms);
+	/* A sane reset duration should not be longer than 1s */
+	if (bp->phy_reset_ms > 1000)
+		bp->phy_reset_ms = 1000;
+
 	/* IP specific init */
 	err = init(pdev);
 	if (err)
@@ -5229,6 +5363,19 @@ static void macb_remove(struct platform_device *pdev)
 	}
 }
 
+static void macb_shutdown(struct platform_device *pdev)
+{
+	struct net_device *dev;
+
+	dev = platform_get_drvdata(pdev);
+
+	rtnl_lock();
+	netif_device_detach(dev);
+	if (netif_running(dev))
+		dev_close(dev);
+	rtnl_unlock();
+}
+
 static int __maybe_unused macb_suspend(struct device *dev)
 {
 	struct net_device *netdev = dev_get_drvdata(dev);
@@ -5482,6 +5629,7 @@ static const struct dev_pm_ops macb_pm_ops = {
 static struct platform_driver macb_driver = {
 	.probe		= macb_probe,
 	.remove_new	= macb_remove,
+	.shutdown	= macb_shutdown,
 	.driver		= {
 		.name		= "macb",
 		.of_match_table	= of_match_ptr(macb_dt_ids),
-- 
2.35.3


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

* [PATCH 11/11] arm64: dts: rp1: Add support for MACB contained in RP1
  2024-08-20 14:36 [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay Andrea della Porta
                   ` (9 preceding siblings ...)
  2024-08-20 14:36 ` [PATCH 10/11] net: macb: Add support for RP1's MACB variant Andrea della Porta
@ 2024-08-20 14:36 ` Andrea della Porta
  2024-08-21  8:43   ` Krzysztof Kozlowski
  2024-08-21 17:02   ` Florian Fainelli
  2024-08-21 13:42 ` [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay Krzysztof Kozlowski
  11 siblings, 2 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-08-20 14:36 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

RaspberryPi RP1 is multi function PCI endpoint device that
exposes several subperipherals via PCI BAR.
Add an ethernet node for Cadence MACB to the RP1 dtso

Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
---
 arch/arm64/boot/dts/broadcom/rp1.dtso | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm64/boot/dts/broadcom/rp1.dtso b/arch/arm64/boot/dts/broadcom/rp1.dtso
index d80178a278ee..b40e203c28d5 100644
--- a/arch/arm64/boot/dts/broadcom/rp1.dtso
+++ b/arch/arm64/boot/dts/broadcom/rp1.dtso
@@ -78,6 +78,29 @@ rp1_clocks: clocks@c040018000 {
 							       <50000000>;   // RP1_CLK_ETH_TSU
 				};
 
+				rp1_eth: ethernet@c040100000 {
+					reg = <0xc0 0x40100000  0x0 0x4000>;
+					compatible = "cdns,macb";
+					#address-cells = <1>;
+					#size-cells = <0>;
+					interrupts = <RP1_INT_ETH IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&macb_pclk &macb_hclk &rp1_clocks RP1_CLK_ETH_TSU>;
+					clock-names = "pclk", "hclk", "tsu_clk";
+					phy-mode = "rgmii-id";
+					cdns,aw2w-max-pipe = /bits/ 8 <8>;
+					cdns,ar2r-max-pipe = /bits/ 8 <8>;
+					cdns,use-aw2b-fill;
+					local-mac-address = [00 00 00 00 00 00];
+					phy-handle = <&phy1>;
+					phy-reset-gpios = <&rp1_gpio 32 GPIO_ACTIVE_LOW>;
+					phy-reset-duration = <5>;
+
+					phy1: ethernet-phy@1 {
+						reg = <0x1>;
+						brcm,powerdown-enable;
+					};
+				};
+
 				rp1_gpio: pinctrl@c0400d0000 {
 					reg = <0xc0 0x400d0000  0x0 0xc000>,
 					      <0xc0 0x400e0000  0x0 0xc000>,
-- 
2.35.3


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

* Re: [PATCH 10/11] net: macb: Add support for RP1's MACB variant
  2024-08-20 14:36 ` [PATCH 10/11] net: macb: Add support for RP1's MACB variant Andrea della Porta
@ 2024-08-20 15:13   ` Andrew Lunn
  2024-08-20 18:31     ` Andrea della Porta
  2024-08-21  8:49   ` Krzysztof Kozlowski
  2024-08-21 17:01   ` Florian Fainelli
  2 siblings, 1 reply; 117+ messages in thread
From: Andrew Lunn @ 2024-08-20 15:13 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Stefan Wahren

> +static unsigned int txdelay = 35;
> +module_param(txdelay, uint, 0644);

Networking does not like module parameters.

This is also unused in this patch! So i suggest you just delete it.

> +
>  /* This structure is only used for MACB on SiFive FU540 devices */
>  struct sifive_fu540_macb_mgmt {
>  	void __iomem *reg;
> @@ -334,7 +337,7 @@ static int macb_mdio_wait_for_idle(struct macb *bp)
>  	u32 val;
>  
>  	return readx_poll_timeout(MACB_READ_NSR, bp, val, val & MACB_BIT(IDLE),
> -				  1, MACB_MDIO_TIMEOUT);
> +				  100, MACB_MDIO_TIMEOUT);
>  }
  
Please take this patch out of the series, and break it up. This is one
patch, with a good explanation why you need 1->100.

>  static int macb_mdio_read_c22(struct mii_bus *bus, int mii_id, int regnum)
> @@ -493,6 +496,19 @@ static int macb_mdio_write_c45(struct mii_bus *bus, int mii_id,
>  	return status;
>  }
>  
> +static int macb_mdio_reset(struct mii_bus *bus)
> +{
> +	struct macb *bp = bus->priv;
> +
> +	if (bp->phy_reset_gpio) {
> +		gpiod_set_value_cansleep(bp->phy_reset_gpio, 1);
> +		msleep(bp->phy_reset_ms);
> +		gpiod_set_value_cansleep(bp->phy_reset_gpio, 0);
> +	}
> +
> +	return 0;
> +}
> +
>  static void macb_init_buffers(struct macb *bp)
>  {
>  	struct macb_queue *queue;
> @@ -969,6 +985,7 @@ static int macb_mii_init(struct macb *bp)
>  	bp->mii_bus->write = &macb_mdio_write_c22;
>  	bp->mii_bus->read_c45 = &macb_mdio_read_c45;
>  	bp->mii_bus->write_c45 = &macb_mdio_write_c45;
> +	bp->mii_bus->reset = &macb_mdio_reset;

This is one patch.

>  	snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
>  		 bp->pdev->name, bp->pdev->id);
>  	bp->mii_bus->priv = bp;
> @@ -1640,6 +1657,11 @@ static int macb_rx(struct macb_queue *queue, struct napi_struct *napi,
>  
>  		macb_init_rx_ring(queue);
>  		queue_writel(queue, RBQP, queue->rx_ring_dma);
> +#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
> +		if (bp->hw_dma_cap & HW_DMA_CAP_64B)
> +			macb_writel(bp, RBQPH,
> +				    upper_32_bits(queue->rx_ring_dma));
> +#endif

How does this affect a disto kernel? Do you actually need the #ifdef?
What does bp->hw_dma_cap contain when CONFIG_ARCH_DMA_ADDR_T_64BIT is
not defined?

Again, this should be a patch of its own, with a good commit message.

Interrupt coalescing should be a patch of its own, etc.

    Andrew

---
pw-bot: cr

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

* Re: [PATCH 01/11] dt-bindings: clock: Add RaspberryPi RP1 clock bindings
  2024-08-20 14:36 ` [PATCH 01/11] dt-bindings: clock: Add RaspberryPi RP1 clock bindings Andrea della Porta
@ 2024-08-20 16:19   ` Conor Dooley
  2024-08-20 18:25     ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Conor Dooley @ 2024-08-20 16:19 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

[-- Attachment #1: Type: text/plain, Size: 7556 bytes --]

On Tue, Aug 20, 2024 at 04:36:03PM +0200, Andrea della Porta wrote:
> Add device tree bindings for the clock generator found in RP1 multi
> function device, and relative entries in MAINTAINERS file.
> 
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> ---
>  .../clock/raspberrypi,rp1-clocks.yaml         | 87 +++++++++++++++++++
>  MAINTAINERS                                   |  6 ++
>  include/dt-bindings/clock/rp1.h               | 56 ++++++++++++
>  3 files changed, 149 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
>  create mode 100644 include/dt-bindings/clock/rp1.h
> 
> diff --git a/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml b/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> new file mode 100644
> index 000000000000..b27db86d0572
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> @@ -0,0 +1,87 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/raspberrypi,rp1-clocks.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: RaspberryPi RP1 clock generator
> +
> +maintainers:
> +  - Andrea della Porta <andrea.porta@suse.com>
> +
> +description: |
> +  The RP1 contains a clock generator designed as three PLLs (CORE, AUDIO,
> +  VIDEO), and each PLL output can be programmed though dividers to generate
> +  the clocks to drive the sub-peripherals embedded inside the chipset.
> +
> +  Link to datasheet:
> +  https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
> +
> +properties:
> +  compatible:
> +    const: raspberrypi,rp1-clocks
> +
> +  reg:
> +    maxItems: 1
> +
> +  '#clock-cells':
> +    description:
> +      The index in the assigned-clocks is mapped to the output clock as per
> +      definitions in dt-bindings/clock/rp1.h.
> +    const: 1
> +
> +  clocks:
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - '#clock-cells'
> +  - clocks
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/rp1.h>
> +
> +    rp1 {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        rp1_clocks: clocks@18000 {

The unit address does not match the reg property. I'm surprised that
dtc doesn't complain about that.

> +            compatible = "raspberrypi,rp1-clocks";
> +            reg = <0xc0 0x40018000 0x0 0x10038>;

This is a rather oddly specific size. It leads me to wonder if this
region is inside some sort of syscon area?

> +            #clock-cells = <1>;
> +            clocks = <&clk_xosc>;
> +
> +            assigned-clocks = <&rp1_clocks RP1_PLL_SYS_CORE>,

FWIW, I don't think any of these assigned clocks are helpful for the
example. That said, why do you need to configure all of these assigned
clocks via devicetree when this node is the provider of them?

> +                              <&rp1_clocks RP1_PLL_AUDIO_CORE>,
> +                              /* RP1_PLL_VIDEO_CORE and dividers are now managed by VEC,DPI drivers */

Comments like this also do not seem relevant to the binding.


Cheers,
Conor.


> +                              <&rp1_clocks RP1_PLL_SYS>,
> +                              <&rp1_clocks RP1_PLL_SYS_SEC>,
> +                              <&rp1_clocks RP1_PLL_AUDIO>,
> +                              <&rp1_clocks RP1_PLL_AUDIO_SEC>,
> +                              <&rp1_clocks RP1_CLK_SYS>,
> +                              <&rp1_clocks RP1_PLL_SYS_PRI_PH>,
> +                              /* RP1_CLK_SLOW_SYS is used for the frequency counter (FC0) */
> +                              <&rp1_clocks RP1_CLK_SLOW_SYS>,
> +                              <&rp1_clocks RP1_CLK_SDIO_TIMER>,
> +                              <&rp1_clocks RP1_CLK_SDIO_ALT_SRC>,
> +                              <&rp1_clocks RP1_CLK_ETH_TSU>;
> +
> +            assigned-clock-rates = <1000000000>, // RP1_PLL_SYS_CORE
> +                                   <1536000000>, // RP1_PLL_AUDIO_CORE
> +                                   <200000000>,  // RP1_PLL_SYS
> +                                   <125000000>,  // RP1_PLL_SYS_SEC
> +                                   <61440000>,   // RP1_PLL_AUDIO
> +                                   <192000000>,  // RP1_PLL_AUDIO_SEC
> +                                   <200000000>,  // RP1_CLK_SYS
> +                                   <100000000>,  // RP1_PLL_SYS_PRI_PH
> +                                   /* Must match the XOSC frequency */
> +                                   <50000000>, // RP1_CLK_SLOW_SYS
> +                                   <1000000>, // RP1_CLK_SDIO_TIMER
> +                                   <200000000>, // RP1_CLK_SDIO_ALT_SRC
> +                                   <50000000>; // RP1_CLK_ETH_TSU
> +        };
> +    };
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 42decde38320..6e7db9bce278 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -19116,6 +19116,12 @@ F:	Documentation/devicetree/bindings/media/raspberrypi,pispbe.yaml
>  F:	drivers/media/platform/raspberrypi/pisp_be/
>  F:	include/uapi/linux/media/raspberrypi/
>  
> +RASPBERRY PI RP1 PCI DRIVER
> +M:	Andrea della Porta <andrea.porta@suse.com>
> +S:	Maintained
> +F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> +F:	include/dt-bindings/clock/rp1.h
> +
>  RC-CORE / LIRC FRAMEWORK
>  M:	Sean Young <sean@mess.org>
>  L:	linux-media@vger.kernel.org
> diff --git a/include/dt-bindings/clock/rp1.h b/include/dt-bindings/clock/rp1.h
> new file mode 100644
> index 000000000000..1ed67b8a5229
> --- /dev/null
> +++ b/include/dt-bindings/clock/rp1.h
> @@ -0,0 +1,56 @@
> +/* SPDX-License-Identifier: GPL-2.0 OR MIT */
> +/*
> + * Copyright (C) 2021 Raspberry Pi Ltd.
> + */
> +
> +#define RP1_PLL_SYS_CORE		0
> +#define RP1_PLL_AUDIO_CORE		1
> +#define RP1_PLL_VIDEO_CORE		2
> +
> +#define RP1_PLL_SYS			3
> +#define RP1_PLL_AUDIO			4
> +#define RP1_PLL_VIDEO			5
> +
> +#define RP1_PLL_SYS_PRI_PH		6
> +#define RP1_PLL_SYS_SEC_PH		7
> +#define RP1_PLL_AUDIO_PRI_PH		8
> +
> +#define RP1_PLL_SYS_SEC			9
> +#define RP1_PLL_AUDIO_SEC		10
> +#define RP1_PLL_VIDEO_SEC		11
> +
> +#define RP1_CLK_SYS			12
> +#define RP1_CLK_SLOW_SYS		13
> +#define RP1_CLK_DMA			14
> +#define RP1_CLK_UART			15
> +#define RP1_CLK_ETH			16
> +#define RP1_CLK_PWM0			17
> +#define RP1_CLK_PWM1			18
> +#define RP1_CLK_AUDIO_IN		19
> +#define RP1_CLK_AUDIO_OUT		20
> +#define RP1_CLK_I2S			21
> +#define RP1_CLK_MIPI0_CFG		22
> +#define RP1_CLK_MIPI1_CFG		23
> +#define RP1_CLK_PCIE_AUX		24
> +#define RP1_CLK_USBH0_MICROFRAME	25
> +#define RP1_CLK_USBH1_MICROFRAME	26
> +#define RP1_CLK_USBH0_SUSPEND		27
> +#define RP1_CLK_USBH1_SUSPEND		28
> +#define RP1_CLK_ETH_TSU			29
> +#define RP1_CLK_ADC			30
> +#define RP1_CLK_SDIO_TIMER		31
> +#define RP1_CLK_SDIO_ALT_SRC		32
> +#define RP1_CLK_GP0			33
> +#define RP1_CLK_GP1			34
> +#define RP1_CLK_GP2			35
> +#define RP1_CLK_GP3			36
> +#define RP1_CLK_GP4			37
> +#define RP1_CLK_GP5			38
> +#define RP1_CLK_VEC			39
> +#define RP1_CLK_DPI			40
> +#define RP1_CLK_MIPI0_DPI		41
> +#define RP1_CLK_MIPI1_DPI		42
> +
> +/* Extra PLL output channels - RP1B0 only */
> +#define RP1_PLL_VIDEO_PRI_PH		43
> +#define RP1_PLL_AUDIO_TERN		44
> -- 
> 2.35.3
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 01/11] dt-bindings: clock: Add RaspberryPi RP1 clock bindings
  2024-08-20 16:19   ` Conor Dooley
@ 2024-08-20 18:25     ` Andrea della Porta
  2024-08-21 11:46       ` Conor Dooley
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-20 18:25 UTC (permalink / raw)
  To: Conor Dooley
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Conor,

On 17:19 Tue 20 Aug     , Conor Dooley wrote:
> On Tue, Aug 20, 2024 at 04:36:03PM +0200, Andrea della Porta wrote:
> > Add device tree bindings for the clock generator found in RP1 multi
> > function device, and relative entries in MAINTAINERS file.
> > 
> > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> > ---
> >  .../clock/raspberrypi,rp1-clocks.yaml         | 87 +++++++++++++++++++
> >  MAINTAINERS                                   |  6 ++
> >  include/dt-bindings/clock/rp1.h               | 56 ++++++++++++
> >  3 files changed, 149 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> >  create mode 100644 include/dt-bindings/clock/rp1.h
> > 
> > diff --git a/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml b/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> > new file mode 100644
> > index 000000000000..b27db86d0572
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> > @@ -0,0 +1,87 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/clock/raspberrypi,rp1-clocks.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: RaspberryPi RP1 clock generator
> > +
> > +maintainers:
> > +  - Andrea della Porta <andrea.porta@suse.com>
> > +
> > +description: |
> > +  The RP1 contains a clock generator designed as three PLLs (CORE, AUDIO,
> > +  VIDEO), and each PLL output can be programmed though dividers to generate
> > +  the clocks to drive the sub-peripherals embedded inside the chipset.
> > +
> > +  Link to datasheet:
> > +  https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
> > +
> > +properties:
> > +  compatible:
> > +    const: raspberrypi,rp1-clocks
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  '#clock-cells':
> > +    description:
> > +      The index in the assigned-clocks is mapped to the output clock as per
> > +      definitions in dt-bindings/clock/rp1.h.
> > +    const: 1
> > +
> > +  clocks:
> > +    maxItems: 1
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - '#clock-cells'
> > +  - clocks
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/clock/rp1.h>
> > +
> > +    rp1 {
> > +        #address-cells = <2>;
> > +        #size-cells = <2>;
> > +
> > +        rp1_clocks: clocks@18000 {
> 
> The unit address does not match the reg property. I'm surprised that
> dtc doesn't complain about that.

Agreed. I'll update the address with the reg value in the next release

> 
> > +            compatible = "raspberrypi,rp1-clocks";
> > +            reg = <0xc0 0x40018000 0x0 0x10038>;
> 
> This is a rather oddly specific size. It leads me to wonder if this
> region is inside some sort of syscon area?

From downstream source code and RP1 datasheet it seems that the last addressable
register is at 0xc040028014 while the range exposed through teh devicetree ends
up at 0xc040028038, so it seems more of a little safe margin. I wouldn't say it
is a syscon area since those register are quite specific for video clock
generation and not to be intended to be shared among different peripherals.
Anyway, the next register aperture is at 0xc040030000 so I would say we can 
extend the clock mapped register like the following:

reg = <0xc0 0x40018000 0x0 0x18000>;

if you think it is more readable.

> 
> > +            #clock-cells = <1>;
> > +            clocks = <&clk_xosc>;
> > +
> > +            assigned-clocks = <&rp1_clocks RP1_PLL_SYS_CORE>,

> FWIW, I don't think any of these assigned clocks are helpful for the
> example. That said, why do you need to configure all of these assigned
> clocks via devicetree when this node is the provider of them?

Not sure to understand what you mean here, the example is there just to
show how to compile the dt node, maybe you're referring to the fact that
the consumer should setup the clock freq? Consider that the rp1-clocks
is coupled to the peripherals contained in the same RP1 chip so there is
not much point in letting the peripherals set the clock to their leisure.

> 
> > +                              <&rp1_clocks RP1_PLL_AUDIO_CORE>,
> > +                              /* RP1_PLL_VIDEO_CORE and dividers are now managed by VEC,DPI drivers */
> 
> Comments like this also do not seem relevant to the binding.

Agreed, will drop in the next release.

> 
> 
> Cheers,
> Conor.
>

Many thanks,
Andrea
 
> 
> > +                              <&rp1_clocks RP1_PLL_SYS>,
> > +                              <&rp1_clocks RP1_PLL_SYS_SEC>,
> > +                              <&rp1_clocks RP1_PLL_AUDIO>,
> > +                              <&rp1_clocks RP1_PLL_AUDIO_SEC>,
> > +                              <&rp1_clocks RP1_CLK_SYS>,
> > +                              <&rp1_clocks RP1_PLL_SYS_PRI_PH>,
> > +                              /* RP1_CLK_SLOW_SYS is used for the frequency counter (FC0) */
> > +                              <&rp1_clocks RP1_CLK_SLOW_SYS>,
> > +                              <&rp1_clocks RP1_CLK_SDIO_TIMER>,
> > +                              <&rp1_clocks RP1_CLK_SDIO_ALT_SRC>,
> > +                              <&rp1_clocks RP1_CLK_ETH_TSU>;
> > +
> > +            assigned-clock-rates = <1000000000>, // RP1_PLL_SYS_CORE
> > +                                   <1536000000>, // RP1_PLL_AUDIO_CORE
> > +                                   <200000000>,  // RP1_PLL_SYS
> > +                                   <125000000>,  // RP1_PLL_SYS_SEC
> > +                                   <61440000>,   // RP1_PLL_AUDIO
> > +                                   <192000000>,  // RP1_PLL_AUDIO_SEC
> > +                                   <200000000>,  // RP1_CLK_SYS
> > +                                   <100000000>,  // RP1_PLL_SYS_PRI_PH
> > +                                   /* Must match the XOSC frequency */
> > +                                   <50000000>, // RP1_CLK_SLOW_SYS
> > +                                   <1000000>, // RP1_CLK_SDIO_TIMER
> > +                                   <200000000>, // RP1_CLK_SDIO_ALT_SRC
> > +                                   <50000000>; // RP1_CLK_ETH_TSU
> > +        };
> > +    };
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 42decde38320..6e7db9bce278 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -19116,6 +19116,12 @@ F:	Documentation/devicetree/bindings/media/raspberrypi,pispbe.yaml
> >  F:	drivers/media/platform/raspberrypi/pisp_be/
> >  F:	include/uapi/linux/media/raspberrypi/
> >  
> > +RASPBERRY PI RP1 PCI DRIVER
> > +M:	Andrea della Porta <andrea.porta@suse.com>
> > +S:	Maintained
> > +F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> > +F:	include/dt-bindings/clock/rp1.h
> > +
> >  RC-CORE / LIRC FRAMEWORK
> >  M:	Sean Young <sean@mess.org>
> >  L:	linux-media@vger.kernel.org
> > diff --git a/include/dt-bindings/clock/rp1.h b/include/dt-bindings/clock/rp1.h
> > new file mode 100644
> > index 000000000000..1ed67b8a5229
> > --- /dev/null
> > +++ b/include/dt-bindings/clock/rp1.h
> > @@ -0,0 +1,56 @@
> > +/* SPDX-License-Identifier: GPL-2.0 OR MIT */
> > +/*
> > + * Copyright (C) 2021 Raspberry Pi Ltd.
> > + */
> > +
> > +#define RP1_PLL_SYS_CORE		0
> > +#define RP1_PLL_AUDIO_CORE		1
> > +#define RP1_PLL_VIDEO_CORE		2
> > +
> > +#define RP1_PLL_SYS			3
> > +#define RP1_PLL_AUDIO			4
> > +#define RP1_PLL_VIDEO			5
> > +
> > +#define RP1_PLL_SYS_PRI_PH		6
> > +#define RP1_PLL_SYS_SEC_PH		7
> > +#define RP1_PLL_AUDIO_PRI_PH		8
> > +
> > +#define RP1_PLL_SYS_SEC			9
> > +#define RP1_PLL_AUDIO_SEC		10
> > +#define RP1_PLL_VIDEO_SEC		11
> > +
> > +#define RP1_CLK_SYS			12
> > +#define RP1_CLK_SLOW_SYS		13
> > +#define RP1_CLK_DMA			14
> > +#define RP1_CLK_UART			15
> > +#define RP1_CLK_ETH			16
> > +#define RP1_CLK_PWM0			17
> > +#define RP1_CLK_PWM1			18
> > +#define RP1_CLK_AUDIO_IN		19
> > +#define RP1_CLK_AUDIO_OUT		20
> > +#define RP1_CLK_I2S			21
> > +#define RP1_CLK_MIPI0_CFG		22
> > +#define RP1_CLK_MIPI1_CFG		23
> > +#define RP1_CLK_PCIE_AUX		24
> > +#define RP1_CLK_USBH0_MICROFRAME	25
> > +#define RP1_CLK_USBH1_MICROFRAME	26
> > +#define RP1_CLK_USBH0_SUSPEND		27
> > +#define RP1_CLK_USBH1_SUSPEND		28
> > +#define RP1_CLK_ETH_TSU			29
> > +#define RP1_CLK_ADC			30
> > +#define RP1_CLK_SDIO_TIMER		31
> > +#define RP1_CLK_SDIO_ALT_SRC		32
> > +#define RP1_CLK_GP0			33
> > +#define RP1_CLK_GP1			34
> > +#define RP1_CLK_GP2			35
> > +#define RP1_CLK_GP3			36
> > +#define RP1_CLK_GP4			37
> > +#define RP1_CLK_GP5			38
> > +#define RP1_CLK_VEC			39
> > +#define RP1_CLK_DPI			40
> > +#define RP1_CLK_MIPI0_DPI		41
> > +#define RP1_CLK_MIPI1_DPI		42
> > +
> > +/* Extra PLL output channels - RP1B0 only */
> > +#define RP1_PLL_VIDEO_PRI_PH		43
> > +#define RP1_PLL_AUDIO_TERN		44
> > -- 
> > 2.35.3
> > 



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

* Re: [PATCH 10/11] net: macb: Add support for RP1's MACB variant
  2024-08-20 15:13   ` Andrew Lunn
@ 2024-08-20 18:31     ` Andrea della Porta
  0 siblings, 0 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-08-20 18:31 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Stefan Wahren

Hi Andrew,

On 17:13 Tue 20 Aug     , Andrew Lunn wrote:
> > +static unsigned int txdelay = 35;
> > +module_param(txdelay, uint, 0644);
> 
> Networking does not like module parameters.
> 
> This is also unused in this patch! So i suggest you just delete it.
> 
> > +
> >  /* This structure is only used for MACB on SiFive FU540 devices */
> >  struct sifive_fu540_macb_mgmt {
> >  	void __iomem *reg;
> > @@ -334,7 +337,7 @@ static int macb_mdio_wait_for_idle(struct macb *bp)
> >  	u32 val;
> >  
> >  	return readx_poll_timeout(MACB_READ_NSR, bp, val, val & MACB_BIT(IDLE),
> > -				  1, MACB_MDIO_TIMEOUT);
> > +				  100, MACB_MDIO_TIMEOUT);
> >  }
>   
> Please take this patch out of the series, and break it up. This is one
> patch, with a good explanation why you need 1->100.
> 
> >  static int macb_mdio_read_c22(struct mii_bus *bus, int mii_id, int regnum)
> > @@ -493,6 +496,19 @@ static int macb_mdio_write_c45(struct mii_bus *bus, int mii_id,
> >  	return status;
> >  }
> >  
> > +static int macb_mdio_reset(struct mii_bus *bus)
> > +{
> > +	struct macb *bp = bus->priv;
> > +
> > +	if (bp->phy_reset_gpio) {
> > +		gpiod_set_value_cansleep(bp->phy_reset_gpio, 1);
> > +		msleep(bp->phy_reset_ms);
> > +		gpiod_set_value_cansleep(bp->phy_reset_gpio, 0);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  static void macb_init_buffers(struct macb *bp)
> >  {
> >  	struct macb_queue *queue;
> > @@ -969,6 +985,7 @@ static int macb_mii_init(struct macb *bp)
> >  	bp->mii_bus->write = &macb_mdio_write_c22;
> >  	bp->mii_bus->read_c45 = &macb_mdio_read_c45;
> >  	bp->mii_bus->write_c45 = &macb_mdio_write_c45;
> > +	bp->mii_bus->reset = &macb_mdio_reset;
> 
> This is one patch.
> 
> >  	snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
> >  		 bp->pdev->name, bp->pdev->id);
> >  	bp->mii_bus->priv = bp;
> > @@ -1640,6 +1657,11 @@ static int macb_rx(struct macb_queue *queue, struct napi_struct *napi,
> >  
> >  		macb_init_rx_ring(queue);
> >  		queue_writel(queue, RBQP, queue->rx_ring_dma);
> > +#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
> > +		if (bp->hw_dma_cap & HW_DMA_CAP_64B)
> > +			macb_writel(bp, RBQPH,
> > +				    upper_32_bits(queue->rx_ring_dma));
> > +#endif
> 
> How does this affect a disto kernel? Do you actually need the #ifdef?
> What does bp->hw_dma_cap contain when CONFIG_ARCH_DMA_ADDR_T_64BIT is
> not defined?
> 
> Again, this should be a patch of its own, with a good commit message.
> 
> Interrupt coalescing should be a patch of its own, etc.
> 
>     Andrew
>

Thanks for the feedback, I agree on all the observations. Please do note
however that, as mentioned in the cover letter, this patch is not intended
to be included upstream and is provided just as a quick way for anyone
interested in testing the RP1 functionality using the Ethernet MAC. 
As such, this patch has not been polished nor splitted into manageable bits.
Ii'm taknge note of your comments however and will come back to them in a
future patch that deals specifically with macb.

Many thanks,
Andrea
 
> ---
> pw-bot: cr

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

* Re: [PATCH 04/11] of: address: Preserve the flags portion on 1:1 dma-ranges mapping
  2024-08-20 14:36 ` [PATCH 04/11] of: address: Preserve the flags portion on 1:1 dma-ranges mapping Andrea della Porta
@ 2024-08-21  0:16   ` Rob Herring
  2024-08-21  8:18     ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Rob Herring @ 2024-08-21  0:16 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On Tue, Aug 20, 2024 at 04:36:06PM +0200, Andrea della Porta wrote:
> A missing or empty dma-ranges in a DT node implies a 1:1 mapping for dma
> translations. In this specific case, rhe current behaviour is to zero out

typo

> the entire specifier so that the translation could be carried on as an
> offset from zero.  This includes address specifier that has flags (e.g.
> PCI ranges).
> Once the flags portion has been zeroed, the translation chain is broken
> since the mapping functions will check the upcoming address specifier

What does "upcoming address" mean?

> against mismatching flags, always failing the 1:1 mapping and its entire
> purpose of always succeeding.
> Set to zero only the address portion while passing the flags through.

Can you point me to what the failing DT looks like. I'm puzzled how 
things would have worked for anyone.


> 
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> ---
>  drivers/of/address.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/of/address.c b/drivers/of/address.c
> index d669ce25b5f9..5a6d55a67aa8 100644
> --- a/drivers/of/address.c
> +++ b/drivers/of/address.c
> @@ -443,7 +443,8 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
>  	}
>  	if (ranges == NULL || rlen == 0) {
>  		offset = of_read_number(addr, na);
> -		memset(addr, 0, pna * 4);
> +		/* copy the address while preserving the flags */
> +		memset(addr + pbus->flag_cells, 0, (pna - pbus->flag_cells) * 4);
>  		pr_debug("empty ranges; 1:1 translation\n");
>  		goto finish;
>  	}
> -- 
> 2.35.3
> 

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

* Re: [PATCH 04/11] of: address: Preserve the flags portion on 1:1 dma-ranges mapping
  2024-08-21  0:16   ` Rob Herring
@ 2024-08-21  8:18     ` Andrea della Porta
  2024-08-26 21:29       ` Rob Herring
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-21  8:18 UTC (permalink / raw)
  To: Rob Herring
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Rob,

On 19:16 Tue 20 Aug     , Rob Herring wrote:
> On Tue, Aug 20, 2024 at 04:36:06PM +0200, Andrea della Porta wrote:
> > A missing or empty dma-ranges in a DT node implies a 1:1 mapping for dma
> > translations. In this specific case, rhe current behaviour is to zero out
> 
> typo

Fixed, thanks!

> 
> > the entire specifier so that the translation could be carried on as an
> > offset from zero.  This includes address specifier that has flags (e.g.
> > PCI ranges).
> > Once the flags portion has been zeroed, the translation chain is broken
> > since the mapping functions will check the upcoming address specifier
> 
> What does "upcoming address" mean?

Sorry for the confusion, this means "address specifier (with valid flags) fed
to the translating functions and for which we are looking for a translation".
While this address has some valid flags set, it will fail the translation step
since the ranges it is matched against have flags zeroed out by the 1:1 mapping
condition.

> 
> > against mismatching flags, always failing the 1:1 mapping and its entire
> > purpose of always succeeding.
> > Set to zero only the address portion while passing the flags through.
> 
> Can you point me to what the failing DT looks like. I'm puzzled how 
> things would have worked for anyone.
> 

The following is a simplified and lightly edited) version of the resulting DT
from RPi5:

 pci@0,0 {
	#address-cells = <0x03>;
	#size-cells = <0x02>;
	......
	device_type = "pci";
	compatible = "pci14e4,2712\0pciclass,060400\0pciclass,0604";
	ranges = <0x82000000 0x00 0x00   0x82000000 0x00 0x00   0x00 0x600000>;
	reg = <0x00 0x00 0x00   0x00 0x00>;

	......

	rp1@0 {
		#address-cells = <0x02>;
		#size-cells = <0x02>;
		compatible = "simple-bus";
		ranges = <0xc0 0x40000000   0x01 0x00 0x00   0x00 0x400000>;
		dma-ranges = <0x10 0x00   0x43000000 0x10 0x00   0x10 0x00>;
		......
	};
 };

The pci@0,0 bridge node is automatically created by virtue of
CONFIG_PCI_DYNAMIC_OF_NODES, and has no dma-ranges, hence it implies 1:1 dma
mappings (flags for this mapping are set to zero).  The rp1@0 node has
dma-ranges with flags set (0x43000000). Since 0x43000000 != 0x00 any translation
will fail.
Regarding why no one has really complained about that: AFAIK this could
very well be an unusual scenario that is arising now that we have real use
case for platform devices behind a PCI endpoint and devices populated
dynamically from dtb overlay.

Many thanks,
Andrea

> 
> > 
> > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> > ---
> >  drivers/of/address.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/of/address.c b/drivers/of/address.c
> > index d669ce25b5f9..5a6d55a67aa8 100644
> > --- a/drivers/of/address.c
> > +++ b/drivers/of/address.c
> > @@ -443,7 +443,8 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
> >  	}
> >  	if (ranges == NULL || rlen == 0) {
> >  		offset = of_read_number(addr, na);
> > -		memset(addr, 0, pna * 4);
> > +		/* copy the address while preserving the flags */
> > +		memset(addr + pbus->flag_cells, 0, (pna - pbus->flag_cells) * 4);
> >  		pr_debug("empty ranges; 1:1 translation\n");
> >  		goto finish;
> >  	}
> > -- 
> > 2.35.3
> > 

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-20 14:36 ` [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver Andrea della Porta
@ 2024-08-21  8:38   ` Krzysztof Kozlowski
  2024-08-21 14:20     ` Krzysztof Kozlowski
  2024-08-30 13:49     ` Andrea della Porta
  2024-08-21 13:07   ` kernel test robot
                     ` (5 subsequent siblings)
  6 siblings, 2 replies; 117+ messages in thread
From: Krzysztof Kozlowski @ 2024-08-21  8:38 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On Tue, Aug 20, 2024 at 04:36:10PM +0200, Andrea della Porta wrote:
> The RaspberryPi RP1 is ia PCI multi function device containing
> peripherals ranging from Ethernet to USB controller, I2C, SPI
> and others.
> Implement a bare minimum driver to operate the RP1, leveraging
> actual OF based driver implementations for the on-borad peripherals
> by loading a devicetree overlay during driver probe.
> The peripherals are accessed by mapping MMIO registers starting
> from PCI BAR1 region.
> As a minimum driver, the peripherals will not be added to the
> dtbo here, but in following patches.
> 
> Link: https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> ---
>  MAINTAINERS                           |   2 +
>  arch/arm64/boot/dts/broadcom/rp1.dtso | 152 ++++++++++++

Do not mix DTS with drivers.

These MUST be separate.

>  drivers/misc/Kconfig                  |   1 +
>  drivers/misc/Makefile                 |   1 +
>  drivers/misc/rp1/Kconfig              |  20 ++
>  drivers/misc/rp1/Makefile             |   3 +
>  drivers/misc/rp1/rp1-pci.c            | 333 ++++++++++++++++++++++++++
>  drivers/misc/rp1/rp1-pci.dtso         |   8 +
>  drivers/pci/quirks.c                  |   1 +
>  include/linux/pci_ids.h               |   3 +
>  10 files changed, 524 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/broadcom/rp1.dtso
>  create mode 100644 drivers/misc/rp1/Kconfig
>  create mode 100644 drivers/misc/rp1/Makefile
>  create mode 100644 drivers/misc/rp1/rp1-pci.c
>  create mode 100644 drivers/misc/rp1/rp1-pci.dtso
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 67f460c36ea1..1359538b76e8 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -19119,9 +19119,11 @@ F:	include/uapi/linux/media/raspberrypi/
>  RASPBERRY PI RP1 PCI DRIVER
>  M:	Andrea della Porta <andrea.porta@suse.com>
>  S:	Maintained
> +F:	arch/arm64/boot/dts/broadcom/rp1.dtso
>  F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
>  F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
>  F:	drivers/clk/clk-rp1.c
> +F:	drivers/misc/rp1/
>  F:	drivers/pinctrl/pinctrl-rp1.c
>  F:	include/dt-bindings/clock/rp1.h
>  F:	include/dt-bindings/misc/rp1.h
> diff --git a/arch/arm64/boot/dts/broadcom/rp1.dtso b/arch/arm64/boot/dts/broadcom/rp1.dtso
> new file mode 100644
> index 000000000000..d80178a278ee
> --- /dev/null
> +++ b/arch/arm64/boot/dts/broadcom/rp1.dtso
> @@ -0,0 +1,152 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/interrupt-controller/irq.h>
> +#include <dt-bindings/clock/rp1.h>
> +#include <dt-bindings/misc/rp1.h>
> +
> +/dts-v1/;
> +/plugin/;
> +
> +/ {
> +	fragment@0 {
> +		target-path="";
> +		__overlay__ {
> +			#address-cells = <3>;
> +			#size-cells = <2>;
> +
> +			rp1: rp1@0 {
> +				compatible = "simple-bus";
> +				#address-cells = <2>;
> +				#size-cells = <2>;
> +				interrupt-controller;
> +				interrupt-parent = <&rp1>;
> +				#interrupt-cells = <2>;
> +
> +				// ranges and dma-ranges must be provided by the includer
> +				ranges = <0xc0 0x40000000
> +					  0x01/*0x02000000*/ 0x00 0x00000000
> +					  0x00 0x00400000>;

Are you 100% sure you do not have here dtc W=1 warnings?

> +
> +				dma-ranges =
> +				// inbound RP1 1x_xxxxxxxx -> PCIe 1x_xxxxxxxx
> +					     <0x10 0x00000000
> +					      0x43000000 0x10 0x00000000
> +					      0x10 0x00000000>;
> +
> +				clk_xosc: clk_xosc {

Nope, switch to DTS coding style.

> +					compatible = "fixed-clock";
> +					#clock-cells = <0>;
> +					clock-output-names = "xosc";
> +					clock-frequency = <50000000>;
> +				};
> +
> +				macb_pclk: macb_pclk {
> +					compatible = "fixed-clock";
> +					#clock-cells = <0>;
> +					clock-output-names = "pclk";
> +					clock-frequency = <200000000>;
> +				};
> +
> +				macb_hclk: macb_hclk {
> +					compatible = "fixed-clock";
> +					#clock-cells = <0>;
> +					clock-output-names = "hclk";
> +					clock-frequency = <200000000>;
> +				};
> +
> +				rp1_clocks: clocks@c040018000 {

Why do you mix MMIO with non-MMIO nodes? This really does not look
correct.

> +					compatible = "raspberrypi,rp1-clocks";
> +					#clock-cells = <1>;
> +					reg = <0xc0 0x40018000 0x0 0x10038>;

Wrong order of properties - see DTS coding style.

> +					clocks = <&clk_xosc>;
> +					clock-names = "xosc";

Best regards,
Krzysztof


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

* Re: [PATCH 02/11] dt-bindings: pinctrl: Add RaspberryPi RP1 gpio/pinctrl/pinmux bindings
  2024-08-20 14:36 ` [PATCH 02/11] dt-bindings: pinctrl: Add RaspberryPi RP1 gpio/pinctrl/pinmux bindings Andrea della Porta
@ 2024-08-21  8:42   ` Krzysztof Kozlowski
  2024-08-30 10:22     ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Krzysztof Kozlowski @ 2024-08-21  8:42 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On Tue, Aug 20, 2024 at 04:36:04PM +0200, Andrea della Porta wrote:
> Add device tree bindings for the gpio/pin/mux controller that is part of
> the RP1 multi function device, and relative entries in MAINTAINERS file.
> 
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> ---
>  .../pinctrl/raspberrypi,rp1-gpio.yaml         | 177 +++++++++++++
>  MAINTAINERS                                   |   2 +
>  include/dt-bindings/misc/rp1.h                | 235 ++++++++++++++++++
>  3 files changed, 414 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
>  create mode 100644 include/dt-bindings/misc/rp1.h
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml b/Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
> new file mode 100644
> index 000000000000..7011fa258363
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
> @@ -0,0 +1,177 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pinctrl/raspberrypi,rp1-gpio.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: RaspberryPi RP1 GPIO/Pinconf/Pinmux Controller submodule
> +
> +maintainers:
> +  - Andrea della Porta <andrea.porta@suse.com>
> +
> +description:
> +  The RP1 chipset is a Multi Function Device containing, among other sub-peripherals,
> +  a gpio/pinconf/mux controller whose 54 pins are grouped into 3 banks. It works also
> +  as an interrupt controller for those gpios.
> +
> +  Each pin configuration node lists the pin(s) to which it applies, and one or
> +  more of the mux function to select on those pin(s), and their configuration.
> +  The pin configuration and multiplexing supports the generic bindings.
> +  For details on each properties (including the meaning of "pin configuration node"),
> +  you can refer to ./pinctrl-bindings.txt.
> +
> +properties:
> +  compatible:
> +    const: raspberrypi,rp1-gpio
> +
> +  reg:
> +    minItems: 3

You can drop minItems.

> +    maxItems: 3
> +    description: One reg specifier for each one of the 3 pin banks.
> +
> +  '#gpio-cells':
> +    description: The first cell is the pin number and the second cell is used
> +      to specify the flags (see include/dt-bindings/gpio/gpio.h).
> +    const: 2
> +
> +  gpio-controller: true
> +
> +  gpio-ranges:
> +    maxItems: 1
> +
> +  gpio-line-names:
> +    maxItems: 54
> +
> +  interrupts:
> +    minItems: 3

Ditto

> +    maxItems: 3
> +    description: One interrupt specifier for each one of the 3 pin banks.
> +
> +  '#interrupt-cells':
> +    description:
> +      Specifies the Bank number (as specified in include/dt-bindings/misc/rp1.h)
> +      and Flags (as defined in (include/dt-bindings/interrupt-controller/irq.h).
> +      Possible values for the Bank number are
> +          RP1_INT_IO_BANK0
> +          RP1_INT_IO_BANK1
> +          RP1_INT_IO_BANK2
> +    const: 2
> +
> +  interrupt-controller: true
> +
> +additionalProperties:
> +  anyOf:
> +    - type: object
> +      additionalProperties: false
> +      allOf:
> +        - $ref: pincfg-node.yaml#
> +        - $ref: pinmux-node.yaml#
> +
> +      description:
> +        Pin controller client devices use pin configuration subnodes (children
> +        and grandchildren) for desired pin configuration.
> +        Client device subnodes use below standard properties.
> +
> +      properties:
> +        pins:
> +          description:
> +            A string (or list of strings) adhering to the pattern "gpio[0-5][0-9]"
> +        function: true
> +        bias-disable: true
> +        bias-pull-down: true
> +        bias-pull-up: true
> +        slew-rate:
> +          description: 0 is slow slew rate, 1 is fast slew rate
> +          enum: [ 0, 1 ]
> +        drive-strength:
> +          description: 0 -> 2mA, 1 -> 4mA, 2 -> 8mA, 3 -> 12mA
> +          enum: [ 0, 1, 2, 3 ]

No, that's [ 2, 4, 8 and 12 ]

Read description of the field - it is in specific units.

> +
> +    - type: object
> +      additionalProperties:
> +        $ref: "#/additionalProperties/anyOf/0"
> +
> +allOf:
> +  - $ref: pinctrl.yaml#
> +
> +required:
> +  - reg
> +  - compatible
> +  - "#gpio-cells"
> +  - gpio-controller
> +  - interrupts
> +  - "#interrupt-cells"
> +  - interrupt-controller
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/misc/rp1.h>
> +
> +    rp1 {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        rp1_gpio: pinctrl@c0400d0000 {
> +            reg = <0xc0 0x400d0000  0x0 0xc000>,
> +                  <0xc0 0x400e0000  0x0 0xc000>,
> +                  <0xc0 0x400f0000  0x0 0xc000>;
> +            compatible = "raspberrypi,rp1-gpio";
> +            gpio-controller;
> +            #gpio-cells = <2>;
> +            interrupt-controller;
> +            #interrupt-cells = <2>;
> +            interrupts = <RP1_INT_IO_BANK0 IRQ_TYPE_LEVEL_HIGH>,
> +                         <RP1_INT_IO_BANK1 IRQ_TYPE_LEVEL_HIGH>,
> +                         <RP1_INT_IO_BANK2 IRQ_TYPE_LEVEL_HIGH>;
> +            gpio-line-names =
> +                   "ID_SDA", // GPIO0
> +                   "ID_SCL", // GPIO1
> +                   "GPIO2", "GPIO3", "GPIO4", "GPIO5", "GPIO6",
> +                   "GPIO7", "GPIO8", "GPIO9", "GPIO10", "GPIO11",
> +                   "GPIO12", "GPIO13", "GPIO14", "GPIO15", "GPIO16",
> +                   "GPIO17", "GPIO18", "GPIO19", "GPIO20", "GPIO21",
> +                   "GPIO22", "GPIO23", "GPIO24", "GPIO25", "GPIO26",
> +                   "GPIO27",
> +                   "PCIE_RP1_WAKE", // GPIO28
> +                   "FAN_TACH", // GPIO29
> +                   "HOST_SDA", // GPIO30
> +                   "HOST_SCL", // GPIO31
> +                   "ETH_RST_N", // GPIO32
> +                   "", // GPIO33
> +                   "CD0_IO0_MICCLK", // GPIO34
> +                   "CD0_IO0_MICDAT0", // GPIO35
> +                   "RP1_PCIE_CLKREQ_N", // GPIO36
> +                   "", // GPIO37
> +                   "CD0_SDA", // GPIO38
> +                   "CD0_SCL", // GPIO39
> +                   "CD1_SDA", // GPIO40
> +                   "CD1_SCL", // GPIO41
> +                   "USB_VBUS_EN", // GPIO42
> +                   "USB_OC_N", // GPIO43
> +                   "RP1_STAT_LED", // GPIO44
> +                   "FAN_PWM", // GPIO45
> +                   "CD1_IO0_MICCLK", // GPIO46
> +                   "2712_WAKE", // GPIO47
> +                   "CD1_IO1_MICDAT1", // GPIO48
> +                   "EN_MAX_USB_CUR", // GPIO49
> +                   "", // GPIO50
> +                   "", // GPIO51
> +                   "", // GPIO52
> +                   ""; // GPIO53
> +
> +            rp1_uart0_14_15: rp1_uart0_14_15 {
> +                pin_txd {
> +                    function = "uart0";
> +                    pins = "gpio14";
> +                    bias-disable;
> +                };
> +
> +                pin_rxd {
> +                    function = "uart0";
> +                    pins = "gpio15";
> +                    bias-pull-up;
> +                };
> +            };
> +        };
> +    };
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 6e7db9bce278..c5018232c251 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -19120,7 +19120,9 @@ RASPBERRY PI RP1 PCI DRIVER
>  M:	Andrea della Porta <andrea.porta@suse.com>
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> +F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
>  F:	include/dt-bindings/clock/rp1.h
> +F:	include/dt-bindings/misc/rp1.h
>  
>  RC-CORE / LIRC FRAMEWORK
>  M:	Sean Young <sean@mess.org>
> diff --git a/include/dt-bindings/misc/rp1.h b/include/dt-bindings/misc/rp1.h

Filename should base on the compatible.

The same applies to clocks bindings.

> new file mode 100644
> index 000000000000..6dd5e23870c2
> --- /dev/null
> +++ b/include/dt-bindings/misc/rp1.h
> @@ -0,0 +1,235 @@
> +/* SPDX-License-Identifier: GPL-2.0 OR MIT */
> +/*
> + * This header provides constants for the PY MFD.
> + */
> +
> +#ifndef _RP1_H
> +#define _RP1_H

That's very poor header guard...

> +
> +/* Address map */
> +#define RP1_SYSINFO_BASE 0x000000
> +#define RP1_TBMAN_BASE 0x004000

Nope, addresses are not bindings. Drop entire header.


> +#define RP1_SYSCFG_BASE 0x008000
> +#define RP1_OTP_BASE 0x00c000
> +#define RP1_POWER_BASE 0x010000
> +#define RP1_RESETS_BASE 0x014000
> +#define RP1_CLOCKS_BANK_DEFAULT_BASE 0x018000
> +#define RP1_CLOCKS_BANK_VIDEO_BASE 0x01c000
> +#define RP1_PLL_SYS_BASE 0x020000
> +#define RP1_PLL_AUDIO_BASE 0x024000
> +#define RP1_PLL_VIDEO_BASE 0x028000
> +#define RP1_UART0_BASE 0x030000
> +#define RP1_UART1_BASE 0x034000
> +#define RP1_UART2_BASE 0x038000
> +#define RP1_UART3_BASE 0x03c000
> +#define RP1_UART4_BASE 0x040000
> +#define RP1_UART5_BASE 0x044000
> +#define RP1_SPI8_BASE 0x04c000
> +#define RP1_SPI0_BASE 0x050000
> +#define RP1_SPI1_BASE 0x054000
> +#define RP1_SPI2_BASE 0x058000
> +#define RP1_SPI3_BASE 0x05c000
> +#define RP1_SPI4_BASE 0x060000
> +#define RP1_SPI5_BASE 0x064000
> +#define RP1_SPI6_BASE 0x068000
> +#define RP1_SPI7_BASE 0x06c000
> +#define RP1_I2C0_BASE 0x070000
> +#define RP1_I2C1_BASE 0x074000
> +#define RP1_I2C2_BASE 0x078000
> +#define RP1_I2C3_BASE 0x07c000
> +#define RP1_I2C4_BASE 0x080000
> +#define RP1_I2C5_BASE 0x084000
> +#define RP1_I2C6_BASE 0x088000
> +#define RP1_AUDIO_IN_BASE 0x090000
> +#define RP1_AUDIO_OUT_BASE 0x094000
> +#define RP1_PWM0_BASE 0x098000
> +#define RP1_PWM1_BASE 0x09c000
> +#define RP1_I2S0_BASE 0x0a0000
> +#define RP1_I2S1_BASE 0x0a4000
> +#define RP1_I2S2_BASE 0x0a8000
> +#define RP1_TIMER_BASE 0x0ac000
> +#define RP1_SDIO0_APBS_BASE 0x0b0000
> +#define RP1_SDIO1_APBS_BASE 0x0b4000
> +#define RP1_BUSFABRIC_MONITOR_BASE 0x0c0000
> +#define RP1_BUSFABRIC_AXISHIM_BASE 0x0c4000
> +#define RP1_ADC_BASE 0x0c8000
> +#define RP1_IO_BANK0_BASE 0x0d0000
> +#define RP1_IO_BANK1_BASE 0x0d4000
> +#define RP1_IO_BANK2_BASE 0x0d8000
> +#define RP1_SYS_RIO0_BASE 0x0e0000
> +#define RP1_SYS_RIO1_BASE 0x0e4000
> +#define RP1_SYS_RIO2_BASE 0x0e8000
> +#define RP1_PADS_BANK0_BASE 0x0f0000
> +#define RP1_PADS_BANK1_BASE 0x0f4000
> +#define RP1_PADS_BANK2_BASE 0x0f8000
> +#define RP1_PADS_ETH_BASE 0x0fc000
> +#define RP1_ETH_IP_BASE 0x100000
> +#define RP1_ETH_CFG_BASE 0x104000
> +#define RP1_PCIE_APBS_BASE 0x108000
> +#define RP1_MIPI0_CSIDMA_BASE 0x110000
> +#define RP1_MIPI0_CSIHOST_BASE 0x114000
> +#define RP1_MIPI0_DSIDMA_BASE 0x118000
> +#define RP1_MIPI0_DSIHOST_BASE 0x11c000
> +#define RP1_MIPI0_MIPICFG_BASE 0x120000
> +#define RP1_MIPI0_ISP_BASE 0x124000
> +#define RP1_MIPI1_CSIDMA_BASE 0x128000
> +#define RP1_MIPI1_CSIHOST_BASE 0x12c000
> +#define RP1_MIPI1_DSIDMA_BASE 0x130000
> +#define RP1_MIPI1_DSIHOST_BASE 0x134000
> +#define RP1_MIPI1_MIPICFG_BASE 0x138000
> +#define RP1_MIPI1_ISP_BASE 0x13c000
> +#define RP1_VIDEO_OUT_CFG_BASE 0x140000
> +#define RP1_VIDEO_OUT_VEC_BASE 0x144000
> +#define RP1_VIDEO_OUT_DPI_BASE 0x148000
> +#define RP1_XOSC_BASE 0x150000
> +#define RP1_WATCHDOG_BASE 0x154000
> +#define RP1_DMA_TICK_BASE 0x158000
> +#define RP1_SDIO_CLOCKS_BASE 0x15c000
> +#define RP1_USBHOST0_APBS_BASE 0x160000
> +#define RP1_USBHOST1_APBS_BASE 0x164000
> +#define RP1_ROSC0_BASE 0x168000
> +#define RP1_ROSC1_BASE 0x16c000
> +#define RP1_VBUSCTRL_BASE 0x170000
> +#define RP1_TICKS_BASE 0x174000
> +#define RP1_PIO_APBS_BASE 0x178000
> +#define RP1_SDIO0_AHBLS_BASE 0x180000
> +#define RP1_SDIO1_AHBLS_BASE 0x184000
> +#define RP1_DMA_BASE 0x188000
> +#define RP1_RAM_BASE 0x1c0000
> +#define RP1_RAM_SIZE 0x020000
> +#define RP1_USBHOST0_AXIS_BASE 0x200000
> +#define RP1_USBHOST1_AXIS_BASE 0x300000
> +#define RP1_EXAC_BASE 0x400000
> +
> +/* Interrupts */
> +
> +#define RP1_INT_IO_BANK0 0
> +#define RP1_INT_IO_BANK1 1

Also no, interrupt numbers are not considered bindings. That's too much
churn. Otherwise, please point me to driver code using the define
(directly! that's the requirement).

Best regards,
Krzysztof


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

* Re: [PATCH 11/11] arm64: dts: rp1: Add support for MACB contained in RP1
  2024-08-20 14:36 ` [PATCH 11/11] arm64: dts: rp1: Add support for MACB contained in RP1 Andrea della Porta
@ 2024-08-21  8:43   ` Krzysztof Kozlowski
  2024-08-30 22:33     ` Andrea della Porta
  2024-08-21 17:02   ` Florian Fainelli
  1 sibling, 1 reply; 117+ messages in thread
From: Krzysztof Kozlowski @ 2024-08-21  8:43 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On Tue, Aug 20, 2024 at 04:36:13PM +0200, Andrea della Porta wrote:
> RaspberryPi RP1 is multi function PCI endpoint device that
> exposes several subperipherals via PCI BAR.
> Add an ethernet node for Cadence MACB to the RP1 dtso
> 
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> ---
>  arch/arm64/boot/dts/broadcom/rp1.dtso | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/broadcom/rp1.dtso b/arch/arm64/boot/dts/broadcom/rp1.dtso
> index d80178a278ee..b40e203c28d5 100644
> --- a/arch/arm64/boot/dts/broadcom/rp1.dtso
> +++ b/arch/arm64/boot/dts/broadcom/rp1.dtso
> @@ -78,6 +78,29 @@ rp1_clocks: clocks@c040018000 {
>  							       <50000000>;   // RP1_CLK_ETH_TSU
>  				};
>  
> +				rp1_eth: ethernet@c040100000 {
> +					reg = <0xc0 0x40100000  0x0 0x4000>;
> +					compatible = "cdns,macb";

Please start using DTS coding style...

Best regards,
Krzysztof


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

* Re: [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support
  2024-08-20 14:36 ` [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support Andrea della Porta
@ 2024-08-21  8:45   ` Krzysztof Kozlowski
  2024-08-30 10:39     ` Andrea della Porta
  2024-08-21  9:22   ` kernel test robot
                     ` (4 subsequent siblings)
  5 siblings, 1 reply; 117+ messages in thread
From: Krzysztof Kozlowski @ 2024-08-21  8:45 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On Tue, Aug 20, 2024 at 04:36:09PM +0200, Andrea della Porta wrote:
> The RP1 is an MFD supporting a gpio controller and /pinmux/pinctrl.
> Add minimum support for the gpio only portion. The driver is in
> pinctrl folder since upcoming patches will add the pinmux/pinctrl
> support where the gpio part can be seen as an addition.
> 
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> ---
>  MAINTAINERS                   |   1 +
>  drivers/pinctrl/Kconfig       |  10 +
>  drivers/pinctrl/Makefile      |   1 +
>  drivers/pinctrl/pinctrl-rp1.c | 719 ++++++++++++++++++++++++++++++++++
>  4 files changed, 731 insertions(+)
>  create mode 100644 drivers/pinctrl/pinctrl-rp1.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 4ce7b049d67e..67f460c36ea1 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -19122,6 +19122,7 @@ S:	Maintained
>  F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
>  F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
>  F:	drivers/clk/clk-rp1.c
> +F:	drivers/pinctrl/pinctrl-rp1.c
>  F:	include/dt-bindings/clock/rp1.h
>  F:	include/dt-bindings/misc/rp1.h
>  
> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
> index 7e4f93a3bc7a..18bb1a8bd102 100644
> --- a/drivers/pinctrl/Kconfig
> +++ b/drivers/pinctrl/Kconfig
> @@ -565,6 +565,16 @@ config PINCTRL_MLXBF3
>  	  each pin. This driver can also be built as a module called
>  	  pinctrl-mlxbf3.
>  
> +config PINCTRL_RP1
> +	bool "Pinctrl driver for RP1"
> +	select PINMUX
> +	select PINCONF
> +	select GENERIC_PINCONF
> +	select GPIOLIB_IRQCHIP
> +	help
> +	  Enable the gpio and pinctrl/mux  driver for RaspberryPi RP1
> +	  multi function device. 
> +
>  source "drivers/pinctrl/actions/Kconfig"
>  source "drivers/pinctrl/aspeed/Kconfig"
>  source "drivers/pinctrl/bcm/Kconfig"
> diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
> index cc809669405a..f1ca23b563f6 100644
> --- a/drivers/pinctrl/Makefile
> +++ b/drivers/pinctrl/Makefile
> @@ -45,6 +45,7 @@ obj-$(CONFIG_PINCTRL_PIC32)	+= pinctrl-pic32.o
>  obj-$(CONFIG_PINCTRL_PISTACHIO)	+= pinctrl-pistachio.o
>  obj-$(CONFIG_PINCTRL_RK805)	+= pinctrl-rk805.o
>  obj-$(CONFIG_PINCTRL_ROCKCHIP)	+= pinctrl-rockchip.o
> +obj-$(CONFIG_PINCTRL_RP1)       += pinctrl-rp1.o
>  obj-$(CONFIG_PINCTRL_SCMI)	+= pinctrl-scmi.o
>  obj-$(CONFIG_PINCTRL_SINGLE)	+= pinctrl-single.o
>  obj-$(CONFIG_PINCTRL_ST) 	+= pinctrl-st.o
> diff --git a/drivers/pinctrl/pinctrl-rp1.c b/drivers/pinctrl/pinctrl-rp1.c
> new file mode 100644
> index 000000000000..c035d2014505
> --- /dev/null
> +++ b/drivers/pinctrl/pinctrl-rp1.c
> @@ -0,0 +1,719 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Driver for Raspberry Pi RP1 GPIO unit
> + *
> + * Copyright (C) 2023 Raspberry Pi Ltd.
> + *
> + * This driver is inspired by:
> + * pinctrl-bcm2835.c, please see original file for copyright information
> + */
> +
> +#include <linux/bitmap.h>
> +#include <linux/bitops.h>
> +#include <linux/bug.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/gpio/driver.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/irqdesc.h>
> +#include <linux/init.h>
> +#include <linux/of_address.h>
> +#include <linux/of.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/seq_file.h>
> +#include <linux/spinlock.h>
> +#include <linux/types.h>

Half of these headers are not used. Drop them.

Best regards,
Krzysztof


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

* Re: [PATCH 09/11] arm64: defconfig: Enable RP1 misc/clock/gpio drivers as built-in
  2024-08-20 14:36 ` [PATCH 09/11] arm64: defconfig: Enable RP1 misc/clock/gpio drivers as built-in Andrea della Porta
@ 2024-08-21  8:47   ` Krzysztof Kozlowski
  2024-08-30 22:24     ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Krzysztof Kozlowski @ 2024-08-21  8:47 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On Tue, Aug 20, 2024 at 04:36:11PM +0200, Andrea della Porta wrote:
> Select the RP1 drivers needed to operate the PCI endpoint containing
> several peripherals such as Ethernet and USB Controller. This chip is
> present on RaspberryPi 5.
> 
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> ---
>  arch/arm64/configs/defconfig | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index 7d32fca64996..e7615c464680 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -606,6 +606,7 @@ CONFIG_PINCTRL_QCM2290=y
>  CONFIG_PINCTRL_QCS404=y
>  CONFIG_PINCTRL_QDF2XXX=y
>  CONFIG_PINCTRL_QDU1000=y
> +CONFIG_PINCTRL_RP1=y
>  CONFIG_PINCTRL_SA8775P=y
>  CONFIG_PINCTRL_SC7180=y
>  CONFIG_PINCTRL_SC7280=y
> @@ -685,6 +686,7 @@ CONFIG_SENSORS_RASPBERRYPI_HWMON=m
>  CONFIG_SENSORS_SL28CPLD=m
>  CONFIG_SENSORS_INA2XX=m
>  CONFIG_SENSORS_INA3221=m
> +CONFIG_MISC_RP1=y

Module?

>  CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
>  CONFIG_CPU_THERMAL=y
>  CONFIG_DEVFREQ_THERMAL=y
> @@ -1259,6 +1261,7 @@ CONFIG_COMMON_CLK_CS2000_CP=y
>  CONFIG_COMMON_CLK_FSL_SAI=y
>  CONFIG_COMMON_CLK_S2MPS11=y
>  CONFIG_COMMON_CLK_PWM=y
> +CONFIG_COMMON_CLK_RP1=y

Module?

>  CONFIG_COMMON_CLK_RS9_PCIE=y
>  CONFIG_COMMON_CLK_VC3=y
>  CONFIG_COMMON_CLK_VC5=y
> -- 
> 2.35.3
> 

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

* Re: [PATCH 10/11] net: macb: Add support for RP1's MACB variant
  2024-08-20 14:36 ` [PATCH 10/11] net: macb: Add support for RP1's MACB variant Andrea della Porta
  2024-08-20 15:13   ` Andrew Lunn
@ 2024-08-21  8:49   ` Krzysztof Kozlowski
  2024-08-30 22:32     ` Andrea della Porta
  2024-08-21 17:01   ` Florian Fainelli
  2 siblings, 1 reply; 117+ messages in thread
From: Krzysztof Kozlowski @ 2024-08-21  8:49 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On Tue, Aug 20, 2024 at 04:36:12PM +0200, Andrea della Porta wrote:
> RaspberryPi RP1 contains Cadence's MACB core. Implement the
> changes to be able to operate the customization in the RP1.
> 
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>


> @@ -5100,6 +5214,11 @@ static int macb_probe(struct platform_device *pdev)
>  			}
>  		}
>  	}
> +
> +	device_property_read_u8(&pdev->dev, "cdns,aw2w-max-pipe", &bp->aw2w_max_pipe);
> +	device_property_read_u8(&pdev->dev, "cdns,ar2r-max-pipe", &bp->ar2r_max_pipe);

Where are the bindings?

> +	bp->use_aw2b_fill = device_property_read_bool(&pdev->dev, "cdns,use-aw2b-fill");
> +
>  	spin_lock_init(&bp->lock);
>  
>  	/* setup capabilities */
> @@ -5155,6 +5274,21 @@ static int macb_probe(struct platform_device *pdev)
>  	else
>  		bp->phy_interface = interface;
>  
> +	/* optional PHY reset-related properties */
> +	bp->phy_reset_gpio = devm_gpiod_get_optional(&pdev->dev, "phy-reset",

Where is the binding?

> +						     GPIOD_OUT_LOW);
> +	if (IS_ERR(bp->phy_reset_gpio)) {
> +		dev_err(&pdev->dev, "Failed to obtain phy-reset gpio\n");
> +		err = PTR_ERR(bp->phy_reset_gpio);
> +		goto err_out_free_netdev;
> +	}
> +
> +	bp->phy_reset_ms = 10;
> +	of_property_read_u32(np, "phy-reset-duration", &bp->phy_reset_ms);

Where is the binding?

> +	/* A sane reset duration should not be longer than 1s */
> +	if (bp->phy_reset_ms > 1000)
> +		bp->phy_reset_ms = 1000;
> +
>  	/* IP specific init */
>  	err = init(pdev);

Best regards,
Krzysztof


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

* Re: [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support
  2024-08-20 14:36 ` [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support Andrea della Porta
  2024-08-21  8:45   ` Krzysztof Kozlowski
@ 2024-08-21  9:22   ` kernel test robot
  2024-08-21 12:06   ` kernel test robot
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 117+ messages in thread
From: kernel test robot @ 2024-08-21  9:22 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio
  Cc: Paul Gazzillo, Necip Fazil Yildiran, oe-kbuild-all, netdev

Hi Andrea,

kernel test robot noticed the following build warnings:

[auto build test WARNING on clk/clk-next]
[also build test WARNING on robh/for-next char-misc/char-misc-testing char-misc/char-misc-next char-misc/char-misc-linus linus/master v6.11-rc4 next-20240821]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Andrea-della-Porta/dt-bindings-clock-Add-RaspberryPi-RP1-clock-bindings/20240821-023901
base:   https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
patch link:    https://lore.kernel.org/r/eb39a5f3cefff2a1240a18a255dac090af16f223.1724159867.git.andrea.porta%40suse.com
patch subject: [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support
config: nios2-kismet-CONFIG_GPIOLIB_IRQCHIP-CONFIG_PINCTRL_RP1-0-0 (https://download.01.org/0day-ci/archive/20240821/202408211702.1WVqlgTb-lkp@intel.com/config)
reproduce: (https://download.01.org/0day-ci/archive/20240821/202408211702.1WVqlgTb-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408211702.1WVqlgTb-lkp@intel.com/

kismet warnings: (new ones prefixed by >>)
>> kismet: WARNING: unmet direct dependencies detected for GPIOLIB_IRQCHIP when selected by PINCTRL_RP1
   WARNING: unmet direct dependencies detected for GPIOLIB_IRQCHIP
     Depends on [n]: GPIOLIB [=n]
     Selected by [y]:
     - PINCTRL_RP1 [=y] && PINCTRL [=y]

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH 01/11] dt-bindings: clock: Add RaspberryPi RP1 clock bindings
  2024-08-20 18:25     ` Andrea della Porta
@ 2024-08-21 11:46       ` Conor Dooley
  2024-08-22  9:35         ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Conor Dooley @ 2024-08-21 11:46 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

[-- Attachment #1: Type: text/plain, Size: 10025 bytes --]

On Tue, Aug 20, 2024 at 08:25:36PM +0200, Andrea della Porta wrote:
> Hi Conor,
> 
> On 17:19 Tue 20 Aug     , Conor Dooley wrote:
> > On Tue, Aug 20, 2024 at 04:36:03PM +0200, Andrea della Porta wrote:
> > > Add device tree bindings for the clock generator found in RP1 multi
> > > function device, and relative entries in MAINTAINERS file.
> > > 
> > > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> > > ---
> > >  .../clock/raspberrypi,rp1-clocks.yaml         | 87 +++++++++++++++++++
> > >  MAINTAINERS                                   |  6 ++
> > >  include/dt-bindings/clock/rp1.h               | 56 ++++++++++++
> > >  3 files changed, 149 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> > >  create mode 100644 include/dt-bindings/clock/rp1.h
> > > 
> > > diff --git a/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml b/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> > > new file mode 100644
> > > index 000000000000..b27db86d0572
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> > > @@ -0,0 +1,87 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/clock/raspberrypi,rp1-clocks.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: RaspberryPi RP1 clock generator
> > > +
> > > +maintainers:
> > > +  - Andrea della Porta <andrea.porta@suse.com>
> > > +
> > > +description: |
> > > +  The RP1 contains a clock generator designed as three PLLs (CORE, AUDIO,
> > > +  VIDEO), and each PLL output can be programmed though dividers to generate
> > > +  the clocks to drive the sub-peripherals embedded inside the chipset.
> > > +
> > > +  Link to datasheet:
> > > +  https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
> > > +
> > > +properties:
> > > +  compatible:
> > > +    const: raspberrypi,rp1-clocks
> > > +
> > > +  reg:
> > > +    maxItems: 1
> > > +
> > > +  '#clock-cells':
> > > +    description:
> > > +      The index in the assigned-clocks is mapped to the output clock as per
> > > +      definitions in dt-bindings/clock/rp1.h.
> > > +    const: 1
> > > +
> > > +  clocks:
> > > +    maxItems: 1
> > > +
> > > +required:
> > > +  - compatible
> > > +  - reg
> > > +  - '#clock-cells'
> > > +  - clocks
> > > +
> > > +additionalProperties: false
> > > +
> > > +examples:
> > > +  - |
> > > +    #include <dt-bindings/clock/rp1.h>
> > > +
> > > +    rp1 {
> > > +        #address-cells = <2>;
> > > +        #size-cells = <2>;
> > > +
> > > +        rp1_clocks: clocks@18000 {
> > 
> > The unit address does not match the reg property. I'm surprised that
> > dtc doesn't complain about that.
> 
> Agreed. I'll update the address with the reg value in the next release
> 
> > 
> > > +            compatible = "raspberrypi,rp1-clocks";
> > > +            reg = <0xc0 0x40018000 0x0 0x10038>;
> > 
> > This is a rather oddly specific size. It leads me to wonder if this
> > region is inside some sort of syscon area?
> 
> >From downstream source code and RP1 datasheet it seems that the last addressable
> register is at 0xc040028014 while the range exposed through teh devicetree ends
> up at 0xc040028038, so it seems more of a little safe margin. I wouldn't say it
> is a syscon area since those register are quite specific for video clock
> generation and not to be intended to be shared among different peripherals.
> Anyway, the next register aperture is at 0xc040030000 so I would say we can 
> extend the clock mapped register like the following:
> 
> reg = <0xc0 0x40018000 0x0 0x18000>;
> 
> if you think it is more readable.

I don't care 
> > > +            #clock-cells = <1>;
> > > +            clocks = <&clk_xosc>;
> > > +
> > > +            assigned-clocks = <&rp1_clocks RP1_PLL_SYS_CORE>,
> 
> > FWIW, I don't think any of these assigned clocks are helpful for the
> > example. That said, why do you need to configure all of these assigned
> > clocks via devicetree when this node is the provider of them?
> 
> Not sure to understand what you mean here, the example is there just to
> show how to compile the dt node, maybe you're referring to the fact that
> the consumer should setup the clock freq?

I suppose, yeah. I don't think a particular configuration is relevant
for the example binding, but simultaneously don't get why you are
assigning the rate for clocks used by audio devices or ethernet in the
clock provider node.

> Consider that the rp1-clocks
> is coupled to the peripherals contained in the same RP1 chip so there is
> not much point in letting the peripherals set the clock to their leisure.

How is that any different to the many other SoCs in the kernel?

> > > +                              <&rp1_clocks RP1_PLL_AUDIO_CORE>,
> > > +                              /* RP1_PLL_VIDEO_CORE and dividers are now managed by VEC,DPI drivers */
> > 
> > Comments like this also do not seem relevant to the binding.
> 
> Agreed, will drop in the next release.
> 
> > 
> > 
> > Cheers,
> > Conor.
> >
> 
> Many thanks,
> Andrea
>  
> > 
> > > +                              <&rp1_clocks RP1_PLL_SYS>,
> > > +                              <&rp1_clocks RP1_PLL_SYS_SEC>,
> > > +                              <&rp1_clocks RP1_PLL_AUDIO>,
> > > +                              <&rp1_clocks RP1_PLL_AUDIO_SEC>,
> > > +                              <&rp1_clocks RP1_CLK_SYS>,
> > > +                              <&rp1_clocks RP1_PLL_SYS_PRI_PH>,
> > > +                              /* RP1_CLK_SLOW_SYS is used for the frequency counter (FC0) */
> > > +                              <&rp1_clocks RP1_CLK_SLOW_SYS>,
> > > +                              <&rp1_clocks RP1_CLK_SDIO_TIMER>,
> > > +                              <&rp1_clocks RP1_CLK_SDIO_ALT_SRC>,
> > > +                              <&rp1_clocks RP1_CLK_ETH_TSU>;
> > > +
> > > +            assigned-clock-rates = <1000000000>, // RP1_PLL_SYS_CORE
> > > +                                   <1536000000>, // RP1_PLL_AUDIO_CORE
> > > +                                   <200000000>,  // RP1_PLL_SYS
> > > +                                   <125000000>,  // RP1_PLL_SYS_SEC
> > > +                                   <61440000>,   // RP1_PLL_AUDIO
> > > +                                   <192000000>,  // RP1_PLL_AUDIO_SEC
> > > +                                   <200000000>,  // RP1_CLK_SYS
> > > +                                   <100000000>,  // RP1_PLL_SYS_PRI_PH
> > > +                                   /* Must match the XOSC frequency */
> > > +                                   <50000000>, // RP1_CLK_SLOW_SYS
> > > +                                   <1000000>, // RP1_CLK_SDIO_TIMER
> > > +                                   <200000000>, // RP1_CLK_SDIO_ALT_SRC
> > > +                                   <50000000>; // RP1_CLK_ETH_TSU
> > > +        };
> > > +    };
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index 42decde38320..6e7db9bce278 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -19116,6 +19116,12 @@ F:	Documentation/devicetree/bindings/media/raspberrypi,pispbe.yaml
> > >  F:	drivers/media/platform/raspberrypi/pisp_be/
> > >  F:	include/uapi/linux/media/raspberrypi/
> > >  
> > > +RASPBERRY PI RP1 PCI DRIVER
> > > +M:	Andrea della Porta <andrea.porta@suse.com>
> > > +S:	Maintained
> > > +F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> > > +F:	include/dt-bindings/clock/rp1.h
> > > +
> > >  RC-CORE / LIRC FRAMEWORK
> > >  M:	Sean Young <sean@mess.org>
> > >  L:	linux-media@vger.kernel.org
> > > diff --git a/include/dt-bindings/clock/rp1.h b/include/dt-bindings/clock/rp1.h
> > > new file mode 100644
> > > index 000000000000..1ed67b8a5229
> > > --- /dev/null
> > > +++ b/include/dt-bindings/clock/rp1.h
> > > @@ -0,0 +1,56 @@
> > > +/* SPDX-License-Identifier: GPL-2.0 OR MIT */
> > > +/*
> > > + * Copyright (C) 2021 Raspberry Pi Ltd.
> > > + */
> > > +
> > > +#define RP1_PLL_SYS_CORE		0
> > > +#define RP1_PLL_AUDIO_CORE		1
> > > +#define RP1_PLL_VIDEO_CORE		2
> > > +
> > > +#define RP1_PLL_SYS			3
> > > +#define RP1_PLL_AUDIO			4
> > > +#define RP1_PLL_VIDEO			5
> > > +
> > > +#define RP1_PLL_SYS_PRI_PH		6
> > > +#define RP1_PLL_SYS_SEC_PH		7
> > > +#define RP1_PLL_AUDIO_PRI_PH		8
> > > +
> > > +#define RP1_PLL_SYS_SEC			9
> > > +#define RP1_PLL_AUDIO_SEC		10
> > > +#define RP1_PLL_VIDEO_SEC		11
> > > +
> > > +#define RP1_CLK_SYS			12
> > > +#define RP1_CLK_SLOW_SYS		13
> > > +#define RP1_CLK_DMA			14
> > > +#define RP1_CLK_UART			15
> > > +#define RP1_CLK_ETH			16
> > > +#define RP1_CLK_PWM0			17
> > > +#define RP1_CLK_PWM1			18
> > > +#define RP1_CLK_AUDIO_IN		19
> > > +#define RP1_CLK_AUDIO_OUT		20
> > > +#define RP1_CLK_I2S			21
> > > +#define RP1_CLK_MIPI0_CFG		22
> > > +#define RP1_CLK_MIPI1_CFG		23
> > > +#define RP1_CLK_PCIE_AUX		24
> > > +#define RP1_CLK_USBH0_MICROFRAME	25
> > > +#define RP1_CLK_USBH1_MICROFRAME	26
> > > +#define RP1_CLK_USBH0_SUSPEND		27
> > > +#define RP1_CLK_USBH1_SUSPEND		28
> > > +#define RP1_CLK_ETH_TSU			29
> > > +#define RP1_CLK_ADC			30
> > > +#define RP1_CLK_SDIO_TIMER		31
> > > +#define RP1_CLK_SDIO_ALT_SRC		32
> > > +#define RP1_CLK_GP0			33
> > > +#define RP1_CLK_GP1			34
> > > +#define RP1_CLK_GP2			35
> > > +#define RP1_CLK_GP3			36
> > > +#define RP1_CLK_GP4			37
> > > +#define RP1_CLK_GP5			38
> > > +#define RP1_CLK_VEC			39
> > > +#define RP1_CLK_DPI			40
> > > +#define RP1_CLK_MIPI0_DPI		41
> > > +#define RP1_CLK_MIPI1_DPI		42
> > > +
> > > +/* Extra PLL output channels - RP1B0 only */
> > > +#define RP1_PLL_VIDEO_PRI_PH		43
> > > +#define RP1_PLL_AUDIO_TERN		44
> > > -- 
> > > 2.35.3
> > > 
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support
  2024-08-20 14:36 ` [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support Andrea della Porta
  2024-08-21  8:45   ` Krzysztof Kozlowski
  2024-08-21  9:22   ` kernel test robot
@ 2024-08-21 12:06   ` kernel test robot
  2024-08-21 13:27   ` Simon Horman
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 117+ messages in thread
From: kernel test robot @ 2024-08-21 12:06 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio
  Cc: oe-kbuild-all, netdev

Hi Andrea,

kernel test robot noticed the following build errors:

[auto build test ERROR on clk/clk-next]
[also build test ERROR on robh/for-next char-misc/char-misc-testing char-misc/char-misc-next char-misc/char-misc-linus linus/master v6.11-rc4 next-20240821]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Andrea-della-Porta/dt-bindings-clock-Add-RaspberryPi-RP1-clock-bindings/20240821-023901
base:   https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
patch link:    https://lore.kernel.org/r/eb39a5f3cefff2a1240a18a255dac090af16f223.1724159867.git.andrea.porta%40suse.com
patch subject: [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support
config: alpha-allyesconfig (https://download.01.org/0day-ci/archive/20240821/202408211907.cUrf3RpN-lkp@intel.com/config)
compiler: alpha-linux-gcc (GCC) 13.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240821/202408211907.cUrf3RpN-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408211907.cUrf3RpN-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/pinctrl/pinctrl-rp1.c: In function 'rp1_get_fsel':
>> drivers/pinctrl/pinctrl-rp1.c:237:22: error: implicit declaration of function 'FIELD_GET'; did you mean 'FIELD_SET'? [-Werror=implicit-function-declaration]
     237 |         u32 oeover = FIELD_GET(RP1_GPIO_CTRL_OEOVER_MASK, ctrl);
         |                      ^~~~~~~~~
         |                      FIELD_SET
   drivers/pinctrl/pinctrl-rp1.c: In function 'rp1_set_fsel':
>> drivers/pinctrl/pinctrl-rp1.c:146:25: error: implicit declaration of function 'FIELD_PREP'; did you mean 'FIELD_SET'? [-Werror=implicit-function-declaration]
     146 |                 _reg |= FIELD_PREP((_mask), (_val));    \
         |                         ^~~~~~~~~~
   drivers/pinctrl/pinctrl-rp1.c:257:17: note: in expansion of macro 'FIELD_SET'
     257 |                 FIELD_SET(ctrl, RP1_GPIO_CTRL_OEOVER_MASK, RP1_OEOVER_DISABLE);
         |                 ^~~~~~~~~
   cc1: some warnings being treated as errors


vim +237 drivers/pinctrl/pinctrl-rp1.c

   136	
   137	#define RP1_PAD_DRIVE_2MA		0x00000000
   138	#define RP1_PAD_DRIVE_4MA		BIT(4)
   139	#define RP1_PAD_DRIVE_8MA		BIT(5)
   140	#define RP1_PAD_DRIVE_12MA		(RP1_PAD_DRIVE_4MA | \
   141						RP1_PAD_DRIVE_8MA)
   142	
   143	#define FIELD_SET(_reg, _mask, _val)			\
   144		({						\
   145			_reg &= ~(_mask);				\
 > 146			_reg |= FIELD_PREP((_mask), (_val));	\
   147		})
   148	
   149	#define FUNC(f) \
   150		[func_##f] = #f
   151	
   152	struct rp1_iobank_desc {
   153		int min_gpio;
   154		int num_gpios;
   155		int gpio_offset;
   156		int inte_offset;
   157		int ints_offset;
   158		int rio_offset;
   159		int pads_offset;
   160	};
   161	
   162	struct rp1_pin_info {
   163		u8 num;
   164		u8 bank;
   165		u8 offset;
   166		u8 fsel;
   167		u8 irq_type;
   168	
   169		void __iomem *gpio;
   170		void __iomem *rio;
   171		void __iomem *inte;
   172		void __iomem *ints;
   173		void __iomem *pad;
   174	};
   175	
   176	struct rp1_pinctrl {
   177		struct device *dev;
   178		void __iomem *gpio_base;
   179		void __iomem *rio_base;
   180		void __iomem *pads_base;
   181		int irq[RP1_NUM_BANKS];
   182		struct rp1_pin_info pins[RP1_NUM_GPIOS];
   183	
   184		struct pinctrl_dev *pctl_dev;
   185		struct gpio_chip gpio_chip;
   186		struct pinctrl_gpio_range gpio_range;
   187	
   188		raw_spinlock_t irq_lock[RP1_NUM_BANKS];
   189	};
   190	
   191	const struct rp1_iobank_desc rp1_iobanks[RP1_NUM_BANKS] = {
   192		/*         gpio   inte    ints     rio    pads */
   193		{  0, 28, 0x0000, 0x011c, 0x0124, 0x0000, 0x0004 },
   194		{ 28,  6, 0x4000, 0x411c, 0x4124, 0x4000, 0x4004 },
   195		{ 34, 20, 0x8000, 0x811c, 0x8124, 0x8000, 0x8004 },
   196	};
   197	
   198	static int rp1_pinconf_set(struct rp1_pin_info *pin,
   199				   unsigned int offset, unsigned long *configs,
   200				   unsigned int num_configs);
   201	
   202	static struct rp1_pin_info *rp1_get_pin(struct gpio_chip *chip,
   203						unsigned int offset)
   204	{
   205		struct rp1_pinctrl *pc = gpiochip_get_data(chip);
   206	
   207		if (pc && offset < RP1_NUM_GPIOS)
   208			return &pc->pins[offset];
   209		return NULL;
   210	}
   211	
   212	static void rp1_pad_update(struct rp1_pin_info *pin, u32 clr, u32 set)
   213	{
   214		u32 padctrl = readl(pin->pad);
   215	
   216		padctrl &= ~clr;
   217		padctrl |= set;
   218	
   219		writel(padctrl, pin->pad);
   220	}
   221	
   222	static void rp1_input_enable(struct rp1_pin_info *pin, int value)
   223	{
   224		rp1_pad_update(pin, RP1_PAD_IN_ENABLE_MASK,
   225			       value ? RP1_PAD_IN_ENABLE_MASK : 0);
   226	}
   227	
   228	static void rp1_output_enable(struct rp1_pin_info *pin, int value)
   229	{
   230		rp1_pad_update(pin, RP1_PAD_OUT_DISABLE_MASK,
   231			       value ? 0 : RP1_PAD_OUT_DISABLE_MASK);
   232	}
   233	
   234	static u32 rp1_get_fsel(struct rp1_pin_info *pin)
   235	{
   236		u32 ctrl = readl(pin->gpio + RP1_GPIO_CTRL);
 > 237		u32 oeover = FIELD_GET(RP1_GPIO_CTRL_OEOVER_MASK, ctrl);
   238		u32 fsel = FIELD_GET(RP1_GPIO_CTRL_FUNCSEL_MASK, ctrl);
   239	
   240		if (oeover != RP1_OEOVER_PERI || fsel >= RP1_FSEL_COUNT)
   241			fsel = RP1_FSEL_NONE;
   242	
   243		return fsel;
   244	}
   245	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-20 14:36 ` [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver Andrea della Porta
  2024-08-21  8:38   ` Krzysztof Kozlowski
@ 2024-08-21 13:07   ` kernel test robot
  2024-08-21 13:49   ` kernel test robot
                     ` (4 subsequent siblings)
  6 siblings, 0 replies; 117+ messages in thread
From: kernel test robot @ 2024-08-21 13:07 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio
  Cc: Paul Gazzillo, Necip Fazil Yildiran, oe-kbuild-all, netdev

Hi Andrea,

kernel test robot noticed the following build warnings:

[auto build test WARNING on clk/clk-next]
[also build test WARNING on robh/for-next char-misc/char-misc-testing char-misc/char-misc-next char-misc/char-misc-linus linus/master v6.11-rc4 next-20240821]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Andrea-della-Porta/dt-bindings-clock-Add-RaspberryPi-RP1-clock-bindings/20240821-023901
base:   https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
patch link:    https://lore.kernel.org/r/5954e4dccc0e158cf434d2c281ad57120538409b.1724159867.git.andrea.porta%40suse.com
patch subject: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
config: sparc-kismet-CONFIG_PCI_DYNAMIC_OF_NODES-CONFIG_MISC_RP1-0-0 (https://download.01.org/0day-ci/archive/20240821/202408212017.eN5JVu0P-lkp@intel.com/config)
reproduce: (https://download.01.org/0day-ci/archive/20240821/202408212017.eN5JVu0P-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408212017.eN5JVu0P-lkp@intel.com/

kismet warnings: (new ones prefixed by >>)
>> kismet: WARNING: unmet direct dependencies detected for PCI_DYNAMIC_OF_NODES when selected by MISC_RP1
   WARNING: unmet direct dependencies detected for PCI_DYNAMIC_OF_NODES
     Depends on [n]: PCI [=y] && OF_IRQ [=n]
     Selected by [y]:
     - MISC_RP1 [=y] && PCI [=y] && PCI_QUIRKS [=y]

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH 06/11] clk: rp1: Add support for clocks provided by RP1
  2024-08-20 14:36 ` [PATCH 06/11] clk: rp1: Add support for clocks provided by RP1 Andrea della Porta
@ 2024-08-21 13:17   ` Simon Horman
  2024-08-22 10:04     ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Simon Horman @ 2024-08-21 13:17 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On Tue, Aug 20, 2024 at 04:36:08PM +0200, Andrea della Porta wrote:
> RaspberryPi RP1 is an MFD providing, among other peripherals, several
> clock generators and PLLs that drives the sub-peripherals.
> Add the driver to support the clock providers.
> 
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>

...

> diff --git a/drivers/clk/clk-rp1.c b/drivers/clk/clk-rp1.c
> new file mode 100644
> index 000000000000..d18e711c0623
> --- /dev/null
> +++ b/drivers/clk/clk-rp1.c
> @@ -0,0 +1,1655 @@
> +// SPDX-License-Identifier: GPL

checkpatch says:

WARNING: 'SPDX-License-Identifier: GPL' is not supported in LICENSES/...

...

> +static int rp1_clock_set_parent(struct clk_hw *hw, u8 index)
> +{
> +	struct rp1_clock *clock = container_of(hw, struct rp1_clock, hw);
> +	struct rp1_clockman *clockman = clock->clockman;
> +	const struct rp1_clock_data *data = clock->data;
> +	u32 ctrl, sel;
> +
> +	spin_lock(&clockman->regs_lock);
> +	ctrl = clockman_read(clockman, data->ctrl_reg);
> +
> +	if (index >= data->num_std_parents) {
> +		/* This is an aux source request */
> +		if (index >= data->num_std_parents + data->num_aux_parents)

It looks like &clockman->regs_lock needs to be unlocked here.

Flagged by Smatch, Sparse. and Coccinelle.

> +			return -EINVAL;
> +
> +		/* Select parent from aux list */
> +		ctrl = set_register_field(ctrl, index - data->num_std_parents,
> +					  CLK_CTRL_AUXSRC_MASK,
> +					  CLK_CTRL_AUXSRC_SHIFT);
> +		/* Set src to aux list */
> +		ctrl = set_register_field(ctrl, AUX_SEL, data->clk_src_mask,
> +					  CLK_CTRL_SRC_SHIFT);
> +	} else {
> +		ctrl = set_register_field(ctrl, index, data->clk_src_mask,
> +					  CLK_CTRL_SRC_SHIFT);
> +	}
> +
> +	clockman_write(clockman, data->ctrl_reg, ctrl);
> +	spin_unlock(&clockman->regs_lock);
> +
> +	sel = rp1_clock_get_parent(hw);
> +	WARN(sel != index, "(%s): Parent index req %u returned back %u\n",
> +	     data->name, index, sel);
> +
> +	return 0;
> +}

...

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

* Re: [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support
  2024-08-20 14:36 ` [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support Andrea della Porta
                     ` (2 preceding siblings ...)
  2024-08-21 12:06   ` kernel test robot
@ 2024-08-21 13:27   ` Simon Horman
  2024-08-23 17:16     ` Andrea della Porta
  2024-08-21 20:51   ` kernel test robot
  2024-08-26  8:59   ` Linus Walleij
  5 siblings, 1 reply; 117+ messages in thread
From: Simon Horman @ 2024-08-21 13:27 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On Tue, Aug 20, 2024 at 04:36:09PM +0200, Andrea della Porta wrote:
> The RP1 is an MFD supporting a gpio controller and /pinmux/pinctrl.
> Add minimum support for the gpio only portion. The driver is in
> pinctrl folder since upcoming patches will add the pinmux/pinctrl
> support where the gpio part can be seen as an addition.
> 
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>

...

> diff --git a/drivers/pinctrl/pinctrl-rp1.c b/drivers/pinctrl/pinctrl-rp1.c

...

> +const struct rp1_iobank_desc rp1_iobanks[RP1_NUM_BANKS] = {
> +	/*         gpio   inte    ints     rio    pads */
> +	{  0, 28, 0x0000, 0x011c, 0x0124, 0x0000, 0x0004 },
> +	{ 28,  6, 0x4000, 0x411c, 0x4124, 0x4000, 0x4004 },
> +	{ 34, 20, 0x8000, 0x811c, 0x8124, 0x8000, 0x8004 },
> +};

rp1_iobanks seems to only be used in this file.
If so, it should be static.

Flagged by Sparse.

...

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

* Re: [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay
  2024-08-20 14:36 [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay Andrea della Porta
                   ` (10 preceding siblings ...)
  2024-08-20 14:36 ` [PATCH 11/11] arm64: dts: rp1: Add support for MACB contained in RP1 Andrea della Porta
@ 2024-08-21 13:42 ` Krzysztof Kozlowski
  2024-08-22  9:05   ` Andrea della Porta
  11 siblings, 1 reply; 117+ messages in thread
From: Krzysztof Kozlowski @ 2024-08-21 13:42 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On 20/08/2024 16:36, Andrea della Porta wrote:
> RP1 is an MFD chipset that acts as a south-bridge PCIe endpoint sporting
> a pletora of subdevices (i.e.  Ethernet, USB host controller, I2C, PWM, 
> etc.) whose registers are all reachable starting from an offset from the
> BAR address.  The main point here is that while the RP1 as an endpoint
> itself is discoverable via usual PCI enumeraiton, the devices it contains
> are not discoverable and must be declared e.g. via the devicetree.
> 
> This patchset is an attempt to provide a minimum infrastructure to allow
> the RP1 chipset to be discovered and perpherals it contains to be added
> from a devictree overlay loaded during RP1 PCI endpoint enumeration.
> Followup patches should add support for the several peripherals contained
> in RP1.
> 
> This work is based upon dowstream drivers code and the proposal from RH
> et al. (see [1] and [2]). A similar approach is also pursued in [3].

Looking briefly at findings it seems this was not really tested by
automation and you expect reviewers to find issues which are pointed out
by tools. That's not nice approach. Reviewer's time is limited, while
tools do it for free. And the tools are free - you can use them without
any effort.

It does not look like you tested the DTS against bindings. Please run
`make dtbs_check W=1` (see
Documentation/devicetree/bindings/writing-schema.rst or
https://www.linaro.org/blog/tips-and-tricks-for-validating-devicetree-sources-with-the-devicetree-schema/
for instructions).

Please run standard kernel tools for static analysis, like coccinelle,
smatch and sparse, and fix reported warnings. Also please check for
warnings when building with W=1. Most of these commands (checks or W=1
build) can build specific targets, like some directory, to narrow the
scope to only your code. The code here looks like it needs a fix. Feel
free to get in touch if the warning is not clear.

Please run scripts/checkpatch.pl and fix reported warnings. Then please
run `scripts/checkpatch.pl --strict` and (probably) fix more warnings.
Some warnings can be ignored, especially from --strict run, but the code
here looks like it needs a fix. Feel free to get in touch if the warning
is not clear.


Best regards,
Krzysztof


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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-20 14:36 ` [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver Andrea della Porta
  2024-08-21  8:38   ` Krzysztof Kozlowski
  2024-08-21 13:07   ` kernel test robot
@ 2024-08-21 13:49   ` kernel test robot
  2024-08-21 16:20   ` Stefan Wahren
                     ` (3 subsequent siblings)
  6 siblings, 0 replies; 117+ messages in thread
From: kernel test robot @ 2024-08-21 13:49 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio
  Cc: oe-kbuild-all, netdev

Hi Andrea,

kernel test robot noticed the following build errors:

[auto build test ERROR on clk/clk-next]
[also build test ERROR on robh/for-next char-misc/char-misc-testing char-misc/char-misc-next char-misc/char-misc-linus linus/master v6.11-rc4 next-20240821]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Andrea-della-Porta/dt-bindings-clock-Add-RaspberryPi-RP1-clock-bindings/20240821-023901
base:   https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
patch link:    https://lore.kernel.org/r/5954e4dccc0e158cf434d2c281ad57120538409b.1724159867.git.andrea.porta%40suse.com
patch subject: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
config: x86_64-randconfig-r133-20240821 (https://download.01.org/0day-ci/archive/20240821/202408212114.i6MFeKR1-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240821/202408212114.i6MFeKR1-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408212114.i6MFeKR1-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/misc/rp1/rp1-pci.c: In function 'rp1_mask_irq':
>> drivers/misc/rp1/rp1-pci.c:98:9: error: implicit declaration of function 'pci_msi_mask_irq'; did you mean 'pci_msix_free_irq'? [-Werror=implicit-function-declaration]
      98 |         pci_msi_mask_irq(pcie_irqd);
         |         ^~~~~~~~~~~~~~~~
         |         pci_msix_free_irq
   drivers/misc/rp1/rp1-pci.c: In function 'rp1_unmask_irq':
>> drivers/misc/rp1/rp1-pci.c:106:9: error: implicit declaration of function 'pci_msi_unmask_irq' [-Werror=implicit-function-declaration]
     106 |         pci_msi_unmask_irq(pcie_irqd);
         |         ^~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors


vim +98 drivers/misc/rp1/rp1-pci.c

    92	
    93	static void rp1_mask_irq(struct irq_data *irqd)
    94	{
    95		struct rp1_dev *rp1 = irqd->domain->host_data;
    96		struct irq_data *pcie_irqd = rp1->pcie_irqds[irqd->hwirq];
    97	
  > 98		pci_msi_mask_irq(pcie_irqd);
    99	}
   100	
   101	static void rp1_unmask_irq(struct irq_data *irqd)
   102	{
   103		struct rp1_dev *rp1 = irqd->domain->host_data;
   104		struct irq_data *pcie_irqd = rp1->pcie_irqds[irqd->hwirq];
   105	
 > 106		pci_msi_unmask_irq(pcie_irqd);
   107	}
   108	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-21  8:38   ` Krzysztof Kozlowski
@ 2024-08-21 14:20     ` Krzysztof Kozlowski
  2024-08-22 14:33       ` Andrea della Porta
  2024-08-30 13:49     ` Andrea della Porta
  1 sibling, 1 reply; 117+ messages in thread
From: Krzysztof Kozlowski @ 2024-08-21 14:20 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On 21/08/2024 10:38, Krzysztof Kozlowski wrote:
> On Tue, Aug 20, 2024 at 04:36:10PM +0200, Andrea della Porta wrote:

...

>>  drivers/misc/Kconfig                  |   1 +
>>  drivers/misc/Makefile                 |   1 +
>>  drivers/misc/rp1/Kconfig              |  20 ++
>>  drivers/misc/rp1/Makefile             |   3 +
>>  drivers/misc/rp1/rp1-pci.c            | 333 ++++++++++++++++++++++++++
>>  drivers/misc/rp1/rp1-pci.dtso         |   8 +
>>  drivers/pci/quirks.c                  |   1 +
>>  include/linux/pci_ids.h               |   3 +
>>  10 files changed, 524 insertions(+)
>>  create mode 100644 arch/arm64/boot/dts/broadcom/rp1.dtso
>>  create mode 100644 drivers/misc/rp1/Kconfig
>>  create mode 100644 drivers/misc/rp1/Makefile
>>  create mode 100644 drivers/misc/rp1/rp1-pci.c
>>  create mode 100644 drivers/misc/rp1/rp1-pci.dtso
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 67f460c36ea1..1359538b76e8 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -19119,9 +19119,11 @@ F:	include/uapi/linux/media/raspberrypi/
>>  RASPBERRY PI RP1 PCI DRIVER
>>  M:	Andrea della Porta <andrea.porta@suse.com>
>>  S:	Maintained
>> +F:	arch/arm64/boot/dts/broadcom/rp1.dtso
>>  F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
>>  F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
>>  F:	drivers/clk/clk-rp1.c
>> +F:	drivers/misc/rp1/
>>  F:	drivers/pinctrl/pinctrl-rp1.c
>>  F:	include/dt-bindings/clock/rp1.h
>>  F:	include/dt-bindings/misc/rp1.h
>> diff --git a/arch/arm64/boot/dts/broadcom/rp1.dtso b/arch/arm64/boot/dts/broadcom/rp1.dtso
>> new file mode 100644
>> index 000000000000..d80178a278ee
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/broadcom/rp1.dtso
>> @@ -0,0 +1,152 @@
>> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
>> +
>> +#include <dt-bindings/gpio/gpio.h>
>> +#include <dt-bindings/interrupt-controller/irq.h>
>> +#include <dt-bindings/clock/rp1.h>
>> +#include <dt-bindings/misc/rp1.h>
>> +
>> +/dts-v1/;
>> +/plugin/;
>> +
>> +/ {
>> +	fragment@0 {
>> +		target-path="";
>> +		__overlay__ {
>> +			#address-cells = <3>;
>> +			#size-cells = <2>;
>> +
>> +			rp1: rp1@0 {
>> +				compatible = "simple-bus";
>> +				#address-cells = <2>;
>> +				#size-cells = <2>;
>> +				interrupt-controller;
>> +				interrupt-parent = <&rp1>;
>> +				#interrupt-cells = <2>;
>> +
>> +				// ranges and dma-ranges must be provided by the includer
>> +				ranges = <0xc0 0x40000000
>> +					  0x01/*0x02000000*/ 0x00 0x00000000
>> +					  0x00 0x00400000>;
> 
> Are you 100% sure you do not have here dtc W=1 warnings?

One more thing, I do not see this overlay applied to any target, which
means it cannot be tested. You miss entry in Makefile.

Best regards,
Krzysztof


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

* Re: [PATCH 03/11] PCI: of_property: Sanitize 32 bit PCI address parsed from DT
  2024-08-20 14:36 ` [PATCH 03/11] PCI: of_property: Sanitize 32 bit PCI address parsed from DT Andrea della Porta
@ 2024-08-21 15:24   ` Bjorn Helgaas
  2024-08-26 19:51     ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Bjorn Helgaas @ 2024-08-21 15:24 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On Tue, Aug 20, 2024 at 04:36:05PM +0200, Andrea della Porta wrote:
> The of_pci_set_address() function parse devicetree PCI range specifier

s/parse/parses/ ? 

> assuming the address is 'sanitized' at the origin, i.e. without checking
> whether the incoming address is 32 or 64 bit has specified in the flags.
> In this way an address with no OF_PCI_ADDR_SPACE_MEM64 set in the flagss

s/flagss/flags/

> could leak through and the upper 32 bits of the address will be set too,
> and this violates the PCI specs stating that ion 32 bit address the upper

s/ion/in/

> bit should be zero.

I don't understand this code, so I'm probably missing something.  It
looks like the interesting path here is:

  of_pci_prop_ranges
    res = &pdev->resource[...];
    for (j = 0; j < num; j++) {
      val64 = res[j].start;
      of_pci_set_address(..., val64, 0, flags, false);
 +      if (OF_PCI_ADDR_SPACE_MEM64)
 +        prop[1] = upper_32_bits(val64);
 +      else
 +        prop[1] = 0;

OF_PCI_ADDR_SPACE_MEM64 tells us about the size of the PCI bus
address, but the address (val64) is a CPU physical address, not a PCI
bus address, so I don't understand why of_pci_set_address() should use
OF_PCI_ADDR_SPACE_MEM64 to clear part of the CPU address.

Add blank lines between paragraphs.

> This could cause mapping translation mismatch on PCI devices (e.g. RP1)
> that are expected to be addressed with a 64 bit address while advertising
> a 32 bit address in the PCI config region.
> Add a check in of_pci_set_address() to set upper 32 bits to zero in case
> the address has no 64 bit flag set.

Is this an indication of a DT error?  Have you seen this cause a
problem?  If so, what does it look like to a user?  I.e., how could a
user find this patch if they saw a problem?

> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> ---
>  drivers/pci/of_property.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/of_property.c b/drivers/pci/of_property.c
> index 5a0b98e69795..77865facdb4a 100644
> --- a/drivers/pci/of_property.c
> +++ b/drivers/pci/of_property.c
> @@ -60,7 +60,10 @@ static void of_pci_set_address(struct pci_dev *pdev, u32 *prop, u64 addr,
>  	prop[0] |= flags | reg_num;
>  	if (!reloc) {
>  		prop[0] |= OF_PCI_ADDR_FIELD_NONRELOC;
> -		prop[1] = upper_32_bits(addr);
> +		if (FIELD_GET(OF_PCI_ADDR_FIELD_SS, flags) == OF_PCI_ADDR_SPACE_MEM64)
> +			prop[1] = upper_32_bits(addr);
> +		else
> +			prop[1] = 0;
>  		prop[2] = lower_32_bits(addr);
>  	}
>  }
> -- 
> 2.35.3
> 

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-20 14:36 ` [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver Andrea della Porta
                     ` (2 preceding siblings ...)
  2024-08-21 13:49   ` kernel test robot
@ 2024-08-21 16:20   ` Stefan Wahren
  2024-08-23  9:44     ` Andrea della Porta
  2024-08-21 16:55   ` Bjorn Helgaas
                     ` (2 subsequent siblings)
  6 siblings, 1 reply; 117+ messages in thread
From: Stefan Wahren @ 2024-08-21 16:20 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn

Hi Andrea,

Am 20.08.24 um 16:36 schrieb Andrea della Porta:
> The RaspberryPi RP1 is ia PCI multi function device containing
> peripherals ranging from Ethernet to USB controller, I2C, SPI
> and others.
sorry, i cannot provide you a code review, but just some comments. multi
function device suggests "mfd" subsystem or at least "soc" . I won't
recommend misc driver here.
> Implement a bare minimum driver to operate the RP1, leveraging
> actual OF based driver implementations for the on-borad peripherals
> by loading a devicetree overlay during driver probe.
Can you please explain why this should be a DT overlay? The RP1 is
assembled on the Raspberry Pi 5 PCB. DT overlays are typically for loose
connections like displays or HATs. I think a DTSI just for the RP1 would
fit better and is easier to read.
> The peripherals are accessed by mapping MMIO registers starting
> from PCI BAR1 region.
> As a minimum driver, the peripherals will not be added to the
> dtbo here, but in following patches.
>
> Link: https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> ---
>   MAINTAINERS                           |   2 +
>   arch/arm64/boot/dts/broadcom/rp1.dtso | 152 ++++++++++++
>   drivers/misc/Kconfig                  |   1 +
>   drivers/misc/Makefile                 |   1 +
>   drivers/misc/rp1/Kconfig              |  20 ++
>   drivers/misc/rp1/Makefile             |   3 +
>   drivers/misc/rp1/rp1-pci.c            | 333 ++++++++++++++++++++++++++
>   drivers/misc/rp1/rp1-pci.dtso         |   8 +
>   drivers/pci/quirks.c                  |   1 +
>   include/linux/pci_ids.h               |   3 +
>   10 files changed, 524 insertions(+)
>   create mode 100644 arch/arm64/boot/dts/broadcom/rp1.dtso
>   create mode 100644 drivers/misc/rp1/Kconfig
>   create mode 100644 drivers/misc/rp1/Makefile
>   create mode 100644 drivers/misc/rp1/rp1-pci.c
>   create mode 100644 drivers/misc/rp1/rp1-pci.dtso
>
...
> +
> +				rp1_clocks: clocks@c040018000 {
> +					compatible = "raspberrypi,rp1-clocks";
> +					#clock-cells = <1>;
> +					reg = <0xc0 0x40018000 0x0 0x10038>;
> +					clocks = <&clk_xosc>;
> +					clock-names = "xosc";
> +
> +					assigned-clocks = <&rp1_clocks RP1_PLL_SYS_CORE>,
> +							  <&rp1_clocks RP1_PLL_AUDIO_CORE>,
> +							  // RP1_PLL_VIDEO_CORE and dividers are now managed by VEC,DPI drivers
> +							  <&rp1_clocks RP1_PLL_SYS>,
> +							  <&rp1_clocks RP1_PLL_SYS_SEC>,
> +							  <&rp1_clocks RP1_PLL_SYS_PRI_PH>,
> +							  <&rp1_clocks RP1_CLK_ETH_TSU>;
> +
> +					assigned-clock-rates = <1000000000>, // RP1_PLL_SYS_CORE
> +							       <1536000000>, // RP1_PLL_AUDIO_CORE
> +							       <200000000>,  // RP1_PLL_SYS
> +							       <125000000>,  // RP1_PLL_SYS_SEC
> +							       <100000000>,  // RP1_PLL_SYS_PRI_PH
> +							       <50000000>;   // RP1_CLK_ETH_TSU
> +				};
> +
> +				rp1_gpio: pinctrl@c0400d0000 {
> +					reg = <0xc0 0x400d0000  0x0 0xc000>,
> +					      <0xc0 0x400e0000  0x0 0xc000>,
> +					      <0xc0 0x400f0000  0x0 0xc000>;
> +					compatible = "raspberrypi,rp1-gpio";
> +					gpio-controller;
> +					#gpio-cells = <2>;
> +					interrupt-controller;
> +					#interrupt-cells = <2>;
> +					interrupts = <RP1_INT_IO_BANK0 IRQ_TYPE_LEVEL_HIGH>,
> +						     <RP1_INT_IO_BANK1 IRQ_TYPE_LEVEL_HIGH>,
> +						     <RP1_INT_IO_BANK2 IRQ_TYPE_LEVEL_HIGH>;
> +					gpio-line-names =
> +						"ID_SDA", // GPIO0
> +						"ID_SCL", // GPIO1
> +						"GPIO2", // GPIO2
> +						"GPIO3", // GPIO3
> +						"GPIO4", // GPIO4
> +						"GPIO5", // GPIO5
> +						"GPIO6", // GPIO6
> +						"GPIO7", // GPIO7
> +						"GPIO8", // GPIO8
> +						"GPIO9", // GPIO9
> +						"GPIO10", // GPIO10
> +						"GPIO11", // GPIO11
> +						"GPIO12", // GPIO12
> +						"GPIO13", // GPIO13
> +						"GPIO14", // GPIO14
> +						"GPIO15", // GPIO15
> +						"GPIO16", // GPIO16
> +						"GPIO17", // GPIO17
> +						"GPIO18", // GPIO18
> +						"GPIO19", // GPIO19
> +						"GPIO20", // GPIO20
> +						"GPIO21", // GPIO21
> +						"GPIO22", // GPIO22
> +						"GPIO23", // GPIO23
> +						"GPIO24", // GPIO24
> +						"GPIO25", // GPIO25
> +						"GPIO26", // GPIO26
> +						"GPIO27", // GPIO27
> +						"PCIE_RP1_WAKE", // GPIO28
> +						"FAN_TACH", // GPIO29
> +						"HOST_SDA", // GPIO30
> +						"HOST_SCL", // GPIO31
> +						"ETH_RST_N", // GPIO32
> +						"", // GPIO33
> +						"CD0_IO0_MICCLK", // GPIO34
> +						"CD0_IO0_MICDAT0", // GPIO35
> +						"RP1_PCIE_CLKREQ_N", // GPIO36
> +						"", // GPIO37
> +						"CD0_SDA", // GPIO38
> +						"CD0_SCL", // GPIO39
> +						"CD1_SDA", // GPIO40
> +						"CD1_SCL", // GPIO41
> +						"USB_VBUS_EN", // GPIO42
> +						"USB_OC_N", // GPIO43
> +						"RP1_STAT_LED", // GPIO44
> +						"FAN_PWM", // GPIO45
> +						"CD1_IO0_MICCLK", // GPIO46
> +						"2712_WAKE", // GPIO47
> +						"CD1_IO1_MICDAT1", // GPIO48
> +						"EN_MAX_USB_CUR", // GPIO49
> +						"", // GPIO50
> +						"", // GPIO51
> +						"", // GPIO52
> +						""; // GPIO53
GPIO line names are board specific, so this should go to the Raspberry
Pi 5 file.
> +				};
> +			};
> +		};
> +	};
> +};
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index 41c3d2821a78..02405209e6c4 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -618,4 +618,5 @@ source "drivers/misc/uacce/Kconfig"
>   source "drivers/misc/pvpanic/Kconfig"
>   source "drivers/misc/mchp_pci1xxxx/Kconfig"
>   source "drivers/misc/keba/Kconfig"
> +source "drivers/misc/rp1/Kconfig"
>   endmenu
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index c2f990862d2b..84bfa866fbee 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -71,3 +71,4 @@ obj-$(CONFIG_TPS6594_PFSM)	+= tps6594-pfsm.o
>   obj-$(CONFIG_NSM)		+= nsm.o
>   obj-$(CONFIG_MARVELL_CN10K_DPI)	+= mrvl_cn10k_dpi.o
>   obj-y				+= keba/
> +obj-$(CONFIG_MISC_RP1)		+= rp1/
> diff --git a/drivers/misc/rp1/Kconfig b/drivers/misc/rp1/Kconfig
> new file mode 100644
> index 000000000000..050417ee09ae
> --- /dev/null
> +++ b/drivers/misc/rp1/Kconfig
> @@ -0,0 +1,20 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# RaspberryPi RP1 misc device
> +#
> +
> +config MISC_RP1
> +        tristate "RaspberryPi RP1 PCIe support"
> +        depends on PCI && PCI_QUIRKS
> +        select OF
> +        select OF_OVERLAY
> +        select IRQ_DOMAIN
> +        select PCI_DYNAMIC_OF_NODES
> +        help
> +          Support for the RP1 peripheral chip found on Raspberry Pi 5 board.
> +          This device supports several sub-devices including e.g. Ethernet controller,
> +          USB controller, I2C, SPI and UART.
> +          The driver is responsible for enabling the DT node once the PCIe endpoint
> +          has been configured, and handling interrupts.
> +          This driver uses an overlay to load other drivers to support for RP1
> +          internal sub-devices.
> diff --git a/drivers/misc/rp1/Makefile b/drivers/misc/rp1/Makefile
> new file mode 100644
> index 000000000000..e83854b4ed2c
> --- /dev/null
> +++ b/drivers/misc/rp1/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +rp1-pci-objs			:= rp1-pci.o rp1-pci.dtbo.o
> +obj-$(CONFIG_MISC_RP1)		+= rp1-pci.o
> diff --git a/drivers/misc/rp1/rp1-pci.c b/drivers/misc/rp1/rp1-pci.c
> new file mode 100644
> index 000000000000..a6093ba7e19a
> --- /dev/null
> +++ b/drivers/misc/rp1/rp1-pci.c
> @@ -0,0 +1,333 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2018-22 Raspberry Pi Ltd.
> + * All rights reserved.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clkdev.h>
> +#include <linux/clk-provider.h>
> +#include <linux/err.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/irqchip/chained_irq.h>
> +#include <linux/irqdomain.h>
> +#include <linux/module.h>
> +#include <linux/msi.h>
> +#include <linux/of_platform.h>
> +#include <linux/pci.h>
> +#include <linux/platform_device.h>
> +#include <linux/reset.h>
> +
> +#include <dt-bindings/misc/rp1.h>
> +
> +#define RP1_B0_CHIP_ID		0x10001927
> +#define RP1_C0_CHIP_ID		0x20001927
> +
> +#define RP1_PLATFORM_ASIC	BIT(1)
> +#define RP1_PLATFORM_FPGA	BIT(0)
> +
> +#define RP1_DRIVER_NAME		"rp1"
> +
> +#define RP1_ACTUAL_IRQS		RP1_INT_END
> +#define RP1_IRQS		RP1_ACTUAL_IRQS
> +#define RP1_HW_IRQ_MASK		GENMASK(5, 0)
> +
> +#define RP1_SYSCLK_RATE		200000000
> +#define RP1_SYSCLK_FPGA_RATE	60000000
> +
> +enum {
> +	SYSINFO_CHIP_ID_OFFSET	= 0,
> +	SYSINFO_PLATFORM_OFFSET	= 4,
> +};
> +
> +#define REG_SET			0x800
> +#define REG_CLR			0xc00
> +
> +/* MSIX CFG registers start at 0x8 */
> +#define MSIX_CFG(x) (0x8 + (4 * (x)))
> +
> +#define MSIX_CFG_IACK_EN        BIT(3)
> +#define MSIX_CFG_IACK           BIT(2)
> +#define MSIX_CFG_TEST           BIT(1)
> +#define MSIX_CFG_ENABLE         BIT(0)
> +
> +#define INTSTATL		0x108
> +#define INTSTATH		0x10c
> +
> +extern char __dtbo_rp1_pci_begin[];
> +extern char __dtbo_rp1_pci_end[];
> +
> +struct rp1_dev {
> +	struct pci_dev *pdev;
> +	struct device *dev;
> +	struct clk *sys_clk;
> +	struct irq_domain *domain;
> +	struct irq_data *pcie_irqds[64];
> +	void __iomem *bar1;
> +	int ovcs_id;
> +	bool level_triggered_irq[RP1_ACTUAL_IRQS];
> +};
> +
> +
...
> +
> +static const struct pci_device_id dev_id_table[] = {
> +	{ PCI_DEVICE(PCI_VENDOR_ID_RPI, PCI_DEVICE_ID_RP1_C0), },
> +	{ 0, }
> +};
> +
> +static struct pci_driver rp1_driver = {
> +	.name		= RP1_DRIVER_NAME,
> +	.id_table	= dev_id_table,
> +	.probe		= rp1_probe,
> +	.remove		= rp1_remove,
> +};
> +
> +module_pci_driver(rp1_driver);
> +
> +MODULE_AUTHOR("Phil Elwell <phil@raspberrypi.com>");
Module author & Copyright doesn't seem to match with this patch author.
Please clarify/fix

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-20 14:36 ` [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver Andrea della Porta
                     ` (3 preceding siblings ...)
  2024-08-21 16:20   ` Stefan Wahren
@ 2024-08-21 16:55   ` Bjorn Helgaas
  2024-08-23 10:21     ` Andrea della Porta
  2024-08-21 17:56   ` kernel test robot
  2024-08-24  1:53   ` Greg Kroah-Hartman
  6 siblings, 1 reply; 117+ messages in thread
From: Bjorn Helgaas @ 2024-08-21 16:55 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On Tue, Aug 20, 2024 at 04:36:10PM +0200, Andrea della Porta wrote:
> The RaspberryPi RP1 is ia PCI multi function device containing

s/ia/a/

> peripherals ranging from Ethernet to USB controller, I2C, SPI
> and others.

Add blank lines between paragraphs.

> Implement a bare minimum driver to operate the RP1, leveraging
> actual OF based driver implementations for the on-borad peripherals

s/on-borad/on-board/

> by loading a devicetree overlay during driver probe.
> The peripherals are accessed by mapping MMIO registers starting
> from PCI BAR1 region.
> As a minimum driver, the peripherals will not be added to the
> dtbo here, but in following patches.

> +config MISC_RP1
> +        tristate "RaspberryPi RP1 PCIe support"
> +        depends on PCI && PCI_QUIRKS
> +        select OF
> +        select OF_OVERLAY
> +        select IRQ_DOMAIN
> +        select PCI_DYNAMIC_OF_NODES
> +        help
> +          Support for the RP1 peripheral chip found on Raspberry Pi 5 board.
> +          This device supports several sub-devices including e.g. Ethernet controller,
> +          USB controller, I2C, SPI and UART.
> +          The driver is responsible for enabling the DT node once the PCIe endpoint
> +          has been configured, and handling interrupts.
> +          This driver uses an overlay to load other drivers to support for RP1
> +          internal sub-devices.

s/support for/support/

Add blank lines between paragraphs.  Consider wrapping to fit in 80
columns.  Current width of 86 seems random.

> diff --git a/drivers/misc/rp1/Makefile b/drivers/misc/rp1/Makefile
> new file mode 100644
> index 000000000000..e83854b4ed2c
> --- /dev/null
> +++ b/drivers/misc/rp1/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +rp1-pci-objs			:= rp1-pci.o rp1-pci.dtbo.o
> +obj-$(CONFIG_MISC_RP1)		+= rp1-pci.o
> diff --git a/drivers/misc/rp1/rp1-pci.c b/drivers/misc/rp1/rp1-pci.c
> new file mode 100644
> index 000000000000..a6093ba7e19a
> --- /dev/null
> +++ b/drivers/misc/rp1/rp1-pci.c
> @@ -0,0 +1,333 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2018-22 Raspberry Pi Ltd.

s/22/24/ ?

> +#define RP1_B0_CHIP_ID		0x10001927
> +#define RP1_C0_CHIP_ID		0x20001927

Drop; both unused.

> +#define RP1_PLATFORM_ASIC	BIT(1)
> +#define RP1_PLATFORM_FPGA	BIT(0)

Drop; both unused.

> +#define RP1_SYSCLK_RATE		200000000
> +#define RP1_SYSCLK_FPGA_RATE	60000000

Drop; both unused.

> +enum {
> +	SYSINFO_CHIP_ID_OFFSET	= 0,
> +	SYSINFO_PLATFORM_OFFSET	= 4,
> +};

Drop; unused.

> +/* MSIX CFG registers start at 0x8 */

s/MSIX/MSI-X/

> +#define MSIX_CFG_TEST           BIT(1)

Unused.

> +#define INTSTATL		0x108
> +#define INTSTATH		0x10c

Drop; both unused.

> +static void dump_bar(struct pci_dev *pdev, unsigned int bar)
> +{
> +	dev_info(&pdev->dev,
> +		 "bar%d len 0x%llx, start 0x%llx, end 0x%llx, flags, 0x%lx\n",

%pR does most of this for you.

> +static int rp1_irq_set_type(struct irq_data *irqd, unsigned int type)
> +{
> +	struct rp1_dev *rp1 = irqd->domain->host_data;
> +	unsigned int hwirq = (unsigned int)irqd->hwirq;
> +	int ret = 0;
> +
> +	switch (type) {
> +	case IRQ_TYPE_LEVEL_HIGH:
> +		dev_dbg(rp1->dev, "MSIX IACK EN for irq %d\n", hwirq);
> +		msix_cfg_set(rp1, hwirq, MSIX_CFG_IACK_EN);
> +		rp1->level_triggered_irq[hwirq] = true;
> +	break;
> +	case IRQ_TYPE_EDGE_RISING:
> +		msix_cfg_clr(rp1, hwirq, MSIX_CFG_IACK_EN);
> +		rp1->level_triggered_irq[hwirq] = false;
> +		break;
> +	default:
> +		ret = -EINVAL;

If you "return -EINVAL" directly here, I think you can drop "ret" and
just "return 0" below.

> +		break;
> +	}
> +
> +	return ret;
> +}

> +static int rp1_irq_xlate(struct irq_domain *d, struct device_node *node,
> +			 const u32 *intspec, unsigned int intsize,
> +			 unsigned long *out_hwirq, unsigned int *out_type)
> +{
> +	struct rp1_dev *rp1 = d->host_data;
> +	struct irq_data *pcie_irqd;
> +	unsigned long hwirq;
> +	int pcie_irq;
> +	int ret;
> +
> +	ret = irq_domain_xlate_twocell(d, node, intspec, intsize,
> +				       &hwirq, out_type);
> +	if (!ret) {
> +		pcie_irq = pci_irq_vector(rp1->pdev, hwirq);
> +		pcie_irqd = irq_get_irq_data(pcie_irq);
> +		rp1->pcie_irqds[hwirq] = pcie_irqd;
> +		*out_hwirq = hwirq;
> +	}
> +
> +	return ret;

  if (ret)
    return ret;

  ...
  return 0;

would make this easier to read and unindent the normal path.

> +	rp1->bar1 = pci_iomap(pdev, 1, 0);

pcim_iomap()

> +	if (!rp1->bar1) {
> +		dev_err(&pdev->dev, "Cannot map PCI bar\n");

s/bar/BAR/

> +#define PCI_VENDOR_ID_RPI		0x1de4
> +#define PCI_DEVICE_ID_RP1_C0		0x0001

Device ID should include "RPI" as well.

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

* Re: [PATCH 10/11] net: macb: Add support for RP1's MACB variant
  2024-08-20 14:36 ` [PATCH 10/11] net: macb: Add support for RP1's MACB variant Andrea della Porta
  2024-08-20 15:13   ` Andrew Lunn
  2024-08-21  8:49   ` Krzysztof Kozlowski
@ 2024-08-21 17:01   ` Florian Fainelli
  2024-08-26 20:03     ` Andrea della Porta
  2 siblings, 1 reply; 117+ messages in thread
From: Florian Fainelli @ 2024-08-21 17:01 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On 8/20/24 07:36, Andrea della Porta wrote:
> RaspberryPi RP1 contains Cadence's MACB core. Implement the
> changes to be able to operate the customization in the RP1.
> 
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>

You are doing a lot of things, all at once, and you should consider 
extracting your change into a smaller subset with bug fixes first:

- one commit which writes to the RBQPH the upper 32-bits of the RX ring 
DMA address, that looks like a bug fix

- one commit which retriggers a buffer read, even though that appears to 
be RP1 specific maybe, if not, then this is also a bug fix

- one commit that adds support for macb_shutdown() to kill DMA operations

- one commit which adds support for a configurable PHY reset line + 
delay specified in milli seconds

- one commit which adds support for controling the interrupt coalescing 
settings

And then you can add all of the RP1 specific bits like the AXI bridge 
configuration.

[snip]

> @@ -1228,6 +1246,7 @@ struct macb_queue {
>   	dma_addr_t		tx_ring_dma;
>   	struct work_struct	tx_error_task;
>   	bool			txubr_pending;
> +	bool			tx_pending;
>   	struct napi_struct	napi_tx;
>   
>   	dma_addr_t		rx_ring_dma;
> @@ -1293,9 +1312,15 @@ struct macb {
>   
>   	u32			caps;
>   	unsigned int		dma_burst_length;
> +	u8			aw2w_max_pipe;
> +	u8			ar2r_max_pipe;
> +	bool			use_aw2b_fill;
>   
>   	phy_interface_t		phy_interface;
>   
> +	struct gpio_desc	*phy_reset_gpio;
> +	int			phy_reset_ms;

The delay cannot be negative, so this needs to be unsigned int.

> +
>   	/* AT91RM9200 transmit queue (1 on wire + 1 queued) */
>   	struct macb_tx_skb	rm9200_txq[2];
>   	unsigned int		max_tx_length;
> diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
> index 11665be3a22c..5eb5be6c96fc 100644
> --- a/drivers/net/ethernet/cadence/macb_main.c
> +++ b/drivers/net/ethernet/cadence/macb_main.c
> @@ -41,6 +41,9 @@
>   #include <linux/inetdevice.h>
>   #include "macb.h"
>   
> +static unsigned int txdelay = 35;
> +module_param(txdelay, uint, 0644);
> +
>   /* This structure is only used for MACB on SiFive FU540 devices */
>   struct sifive_fu540_macb_mgmt {
>   	void __iomem *reg;
> @@ -334,7 +337,7 @@ static int macb_mdio_wait_for_idle(struct macb *bp)
>   	u32 val;
>   
>   	return readx_poll_timeout(MACB_READ_NSR, bp, val, val & MACB_BIT(IDLE),
> -				  1, MACB_MDIO_TIMEOUT);
> +				  100, MACB_MDIO_TIMEOUT);

Why do we need to increase how frequently we poll?
-- 
Florian


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

* Re: [PATCH 11/11] arm64: dts: rp1: Add support for MACB contained in RP1
  2024-08-20 14:36 ` [PATCH 11/11] arm64: dts: rp1: Add support for MACB contained in RP1 Andrea della Porta
  2024-08-21  8:43   ` Krzysztof Kozlowski
@ 2024-08-21 17:02   ` Florian Fainelli
  2024-08-26 20:18     ` Andrea della Porta
  1 sibling, 1 reply; 117+ messages in thread
From: Florian Fainelli @ 2024-08-21 17:02 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On 8/20/24 07:36, Andrea della Porta wrote:
> RaspberryPi RP1 is multi function PCI endpoint device that
> exposes several subperipherals via PCI BAR.
> Add an ethernet node for Cadence MACB to the RP1 dtso
> 
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> ---
>   arch/arm64/boot/dts/broadcom/rp1.dtso | 23 +++++++++++++++++++++++
>   1 file changed, 23 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/broadcom/rp1.dtso b/arch/arm64/boot/dts/broadcom/rp1.dtso
> index d80178a278ee..b40e203c28d5 100644
> --- a/arch/arm64/boot/dts/broadcom/rp1.dtso
> +++ b/arch/arm64/boot/dts/broadcom/rp1.dtso
> @@ -78,6 +78,29 @@ rp1_clocks: clocks@c040018000 {
>   							       <50000000>;   // RP1_CLK_ETH_TSU
>   				};
>   
> +				rp1_eth: ethernet@c040100000 {
> +					reg = <0xc0 0x40100000  0x0 0x4000>;
> +					compatible = "cdns,macb";
> +					#address-cells = <1>;
> +					#size-cells = <0>;
> +					interrupts = <RP1_INT_ETH IRQ_TYPE_LEVEL_HIGH>;
> +					clocks = <&macb_pclk &macb_hclk &rp1_clocks RP1_CLK_ETH_TSU>;
> +					clock-names = "pclk", "hclk", "tsu_clk";
> +					phy-mode = "rgmii-id";
> +					cdns,aw2w-max-pipe = /bits/ 8 <8>;
> +					cdns,ar2r-max-pipe = /bits/ 8 <8>;
> +					cdns,use-aw2b-fill;
> +					local-mac-address = [00 00 00 00 00 00];
> +					phy-handle = <&phy1>;
> +					phy-reset-gpios = <&rp1_gpio 32 GPIO_ACTIVE_LOW>;
> +					phy-reset-duration = <5>;
> +
> +					phy1: ethernet-phy@1 {
> +						reg = <0x1>;
> +						brcm,powerdown-enable;

Undocumented property, and I would like to understand why this needs to 
be specified in the Device Tree? What model of Broadcom Ethernet PHY is 
being used here?
-- 
Florian


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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-20 14:36 ` [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver Andrea della Porta
                     ` (4 preceding siblings ...)
  2024-08-21 16:55   ` Bjorn Helgaas
@ 2024-08-21 17:56   ` kernel test robot
  2024-08-24  1:53   ` Greg Kroah-Hartman
  6 siblings, 0 replies; 117+ messages in thread
From: kernel test robot @ 2024-08-21 17:56 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio
  Cc: oe-kbuild-all, netdev

Hi Andrea,

kernel test robot noticed the following build warnings:

[auto build test WARNING on clk/clk-next]
[also build test WARNING on robh/for-next char-misc/char-misc-testing char-misc/char-misc-next char-misc/char-misc-linus linus/master v6.11-rc4 next-20240821]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Andrea-della-Porta/dt-bindings-clock-Add-RaspberryPi-RP1-clock-bindings/20240821-023901
base:   https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
patch link:    https://lore.kernel.org/r/5954e4dccc0e158cf434d2c281ad57120538409b.1724159867.git.andrea.porta%40suse.com
patch subject: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
config: mips-allyesconfig (https://download.01.org/0day-ci/archive/20240822/202408220150.bmFMT5Bk-lkp@intel.com/config)
compiler: mips-linux-gcc (GCC) 14.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240822/202408220150.bmFMT5Bk-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408220150.bmFMT5Bk-lkp@intel.com/

All warnings (new ones prefixed by >>):

   In file included from include/linux/device.h:15,
                    from include/linux/pci.h:37,
                    from drivers/misc/rp1/rp1-pci.c:18:
   drivers/misc/rp1/rp1-pci.c: In function 'dump_bar':
>> drivers/misc/rp1/rp1-pci.c:75:18: warning: format '%llx' expects argument of type 'long long unsigned int', but argument 4 has type 'resource_size_t' {aka 'unsigned int'} [-Wformat=]
      75 |                  "bar%d len 0x%llx, start 0x%llx, end 0x%llx, flags, 0x%lx\n",
         |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/dev_printk.h:110:30: note: in definition of macro 'dev_printk_index_wrap'
     110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
         |                              ^~~
   include/linux/dev_printk.h:160:58: note: in expansion of macro 'dev_fmt'
     160 |         dev_printk_index_wrap(_dev_info, KERN_INFO, dev, dev_fmt(fmt), ##__VA_ARGS__)
         |                                                          ^~~~~~~
   drivers/misc/rp1/rp1-pci.c:74:9: note: in expansion of macro 'dev_info'
      74 |         dev_info(&pdev->dev,
         |         ^~~~~~~~
   drivers/misc/rp1/rp1-pci.c:75:34: note: format string is defined here
      75 |                  "bar%d len 0x%llx, start 0x%llx, end 0x%llx, flags, 0x%lx\n",
         |                               ~~~^
         |                                  |
         |                                  long long unsigned int
         |                               %x
   drivers/misc/rp1/rp1-pci.c:75:18: warning: format '%llx' expects argument of type 'long long unsigned int', but argument 5 has type 'resource_size_t' {aka 'unsigned int'} [-Wformat=]
      75 |                  "bar%d len 0x%llx, start 0x%llx, end 0x%llx, flags, 0x%lx\n",
         |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/dev_printk.h:110:30: note: in definition of macro 'dev_printk_index_wrap'
     110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
         |                              ^~~
   include/linux/dev_printk.h:160:58: note: in expansion of macro 'dev_fmt'
     160 |         dev_printk_index_wrap(_dev_info, KERN_INFO, dev, dev_fmt(fmt), ##__VA_ARGS__)
         |                                                          ^~~~~~~
   drivers/misc/rp1/rp1-pci.c:74:9: note: in expansion of macro 'dev_info'
      74 |         dev_info(&pdev->dev,
         |         ^~~~~~~~
   drivers/misc/rp1/rp1-pci.c:75:48: note: format string is defined here
      75 |                  "bar%d len 0x%llx, start 0x%llx, end 0x%llx, flags, 0x%lx\n",
         |                                             ~~~^
         |                                                |
         |                                                long long unsigned int
         |                                             %x
   drivers/misc/rp1/rp1-pci.c:75:18: warning: format '%llx' expects argument of type 'long long unsigned int', but argument 6 has type 'resource_size_t' {aka 'unsigned int'} [-Wformat=]
      75 |                  "bar%d len 0x%llx, start 0x%llx, end 0x%llx, flags, 0x%lx\n",
         |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/dev_printk.h:110:30: note: in definition of macro 'dev_printk_index_wrap'
     110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
         |                              ^~~
   include/linux/dev_printk.h:160:58: note: in expansion of macro 'dev_fmt'
     160 |         dev_printk_index_wrap(_dev_info, KERN_INFO, dev, dev_fmt(fmt), ##__VA_ARGS__)
         |                                                          ^~~~~~~
   drivers/misc/rp1/rp1-pci.c:74:9: note: in expansion of macro 'dev_info'
      74 |         dev_info(&pdev->dev,
         |         ^~~~~~~~
   drivers/misc/rp1/rp1-pci.c:75:60: note: format string is defined here
      75 |                  "bar%d len 0x%llx, start 0x%llx, end 0x%llx, flags, 0x%lx\n",
         |                                                         ~~~^
         |                                                            |
         |                                                            long long unsigned int
         |                                                         %x


vim +75 drivers/misc/rp1/rp1-pci.c

  > 18	#include <linux/pci.h>
    19	#include <linux/platform_device.h>
    20	#include <linux/reset.h>
    21	
    22	#include <dt-bindings/misc/rp1.h>
    23	
    24	#define RP1_B0_CHIP_ID		0x10001927
    25	#define RP1_C0_CHIP_ID		0x20001927
    26	
    27	#define RP1_PLATFORM_ASIC	BIT(1)
    28	#define RP1_PLATFORM_FPGA	BIT(0)
    29	
    30	#define RP1_DRIVER_NAME		"rp1"
    31	
    32	#define RP1_ACTUAL_IRQS		RP1_INT_END
    33	#define RP1_IRQS		RP1_ACTUAL_IRQS
    34	#define RP1_HW_IRQ_MASK		GENMASK(5, 0)
    35	
    36	#define RP1_SYSCLK_RATE		200000000
    37	#define RP1_SYSCLK_FPGA_RATE	60000000
    38	
    39	enum {
    40		SYSINFO_CHIP_ID_OFFSET	= 0,
    41		SYSINFO_PLATFORM_OFFSET	= 4,
    42	};
    43	
    44	#define REG_SET			0x800
    45	#define REG_CLR			0xc00
    46	
    47	/* MSIX CFG registers start at 0x8 */
    48	#define MSIX_CFG(x) (0x8 + (4 * (x)))
    49	
    50	#define MSIX_CFG_IACK_EN        BIT(3)
    51	#define MSIX_CFG_IACK           BIT(2)
    52	#define MSIX_CFG_TEST           BIT(1)
    53	#define MSIX_CFG_ENABLE         BIT(0)
    54	
    55	#define INTSTATL		0x108
    56	#define INTSTATH		0x10c
    57	
    58	extern char __dtbo_rp1_pci_begin[];
    59	extern char __dtbo_rp1_pci_end[];
    60	
    61	struct rp1_dev {
    62		struct pci_dev *pdev;
    63		struct device *dev;
    64		struct clk *sys_clk;
    65		struct irq_domain *domain;
    66		struct irq_data *pcie_irqds[64];
    67		void __iomem *bar1;
    68		int ovcs_id;
    69		bool level_triggered_irq[RP1_ACTUAL_IRQS];
    70	};
    71	
    72	static void dump_bar(struct pci_dev *pdev, unsigned int bar)
    73	{
    74		dev_info(&pdev->dev,
  > 75			 "bar%d len 0x%llx, start 0x%llx, end 0x%llx, flags, 0x%lx\n",
    76			 bar,
    77			 pci_resource_len(pdev, bar),
    78			 pci_resource_start(pdev, bar),
    79			 pci_resource_end(pdev, bar),
    80			 pci_resource_flags(pdev, bar));
    81	}
    82	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support
  2024-08-20 14:36 ` [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support Andrea della Porta
                     ` (3 preceding siblings ...)
  2024-08-21 13:27   ` Simon Horman
@ 2024-08-21 20:51   ` kernel test robot
  2024-08-26  8:59   ` Linus Walleij
  5 siblings, 0 replies; 117+ messages in thread
From: kernel test robot @ 2024-08-21 20:51 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio
  Cc: oe-kbuild-all, netdev

Hi Andrea,

kernel test robot noticed the following build warnings:

[auto build test WARNING on clk/clk-next]
[also build test WARNING on robh/for-next char-misc/char-misc-testing char-misc/char-misc-next char-misc/char-misc-linus linus/master v6.11-rc4 next-20240821]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Andrea-della-Porta/dt-bindings-clock-Add-RaspberryPi-RP1-clock-bindings/20240821-023901
base:   https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
patch link:    https://lore.kernel.org/r/eb39a5f3cefff2a1240a18a255dac090af16f223.1724159867.git.andrea.porta%40suse.com
patch subject: [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support
config: powerpc64-randconfig-r123-20240821 (https://download.01.org/0day-ci/archive/20240822/202408220406.czlwSpkP-lkp@intel.com/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce: (https://download.01.org/0day-ci/archive/20240822/202408220406.czlwSpkP-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408220406.czlwSpkP-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/pinctrl/pinctrl-rp1.c:191:30: sparse: sparse: symbol 'rp1_iobanks' was not declared. Should it be static?

vim +/rp1_iobanks +191 drivers/pinctrl/pinctrl-rp1.c

   190	
 > 191	const struct rp1_iobank_desc rp1_iobanks[RP1_NUM_BANKS] = {
   192		/*         gpio   inte    ints     rio    pads */
   193		{  0, 28, 0x0000, 0x011c, 0x0124, 0x0000, 0x0004 },
   194		{ 28,  6, 0x4000, 0x411c, 0x4124, 0x4000, 0x4004 },
   195		{ 34, 20, 0x8000, 0x811c, 0x8124, 0x8000, 0x8004 },
   196	};
   197	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay
  2024-08-21 13:42 ` [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay Krzysztof Kozlowski
@ 2024-08-22  9:05   ` Andrea della Porta
  2024-08-22  9:50     ` Krzysztof Kozlowski
  2024-08-22 13:04     ` Andrew Lunn
  0 siblings, 2 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-08-22  9:05 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Krzysztof,

On 15:42 Wed 21 Aug     , Krzysztof Kozlowski wrote:
> On 20/08/2024 16:36, Andrea della Porta wrote:
> > RP1 is an MFD chipset that acts as a south-bridge PCIe endpoint sporting
> > a pletora of subdevices (i.e.  Ethernet, USB host controller, I2C, PWM, 
> > etc.) whose registers are all reachable starting from an offset from the
> > BAR address.  The main point here is that while the RP1 as an endpoint
> > itself is discoverable via usual PCI enumeraiton, the devices it contains
> > are not discoverable and must be declared e.g. via the devicetree.
> > 
> > This patchset is an attempt to provide a minimum infrastructure to allow
> > the RP1 chipset to be discovered and perpherals it contains to be added
> > from a devictree overlay loaded during RP1 PCI endpoint enumeration.
> > Followup patches should add support for the several peripherals contained
> > in RP1.
> > 
> > This work is based upon dowstream drivers code and the proposal from RH
> > et al. (see [1] and [2]). A similar approach is also pursued in [3].
> 
> Looking briefly at findings it seems this was not really tested by
> automation and you expect reviewers to find issues which are pointed out
> by tools. That's not nice approach. Reviewer's time is limited, while
> tools do it for free. And the tools are free - you can use them without
> any effort.

Sorry if I gave you that impression, but this is not obviously the case.
I've spent quite a bit of time in trying to deliver a patchset that ease
your and others work, at least to the best I can. In fact, I've used many
of the checking facilities you mentioned before sending it, solving all
of the reported issues, except the ones for which there are strong reasons
to leave untouched, as explained below.

> 
> It does not look like you tested the DTS against bindings. Please run
> `make dtbs_check W=1` (see
> Documentation/devicetree/bindings/writing-schema.rst or
> https://www.linaro.org/blog/tips-and-tricks-for-validating-devicetree-sources-with-the-devicetree-schema/
> for instructions).

#> make W=1 dt_binding_check DT_SCHEMA_FILES=raspberrypi,rp1-gpio.yaml
   CHKDT   Documentation/devicetree/bindings
   LINT    Documentation/devicetree/bindings
   DTEX    Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.example.dts
   DTC_CHK Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.example.dtb

#> make W=1 dt_binding_check DT_SCHEMA_FILES=raspberrypi,rp1-clocks.yaml
   CHKDT   Documentation/devicetree/bindings
   LINT    Documentation/devicetree/bindings
   DTEX    Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.example.dts
   DTC_CHK Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.example.dtb

I see no issues here, in case you've found something different, I kindly ask you to post
the results.

#> make W=1 CHECK_DTBS=y broadcom/rp1.dtbo
   DTC     arch/arm64/boot/dts/broadcom/rp1.dtbo
   arch/arm64/boot/dts/broadcom/rp1.dtso:37.24-42.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/clk_xosc: missing or empty reg/ranges property
   arch/arm64/boot/dts/broadcom/rp1.dtso:44.26-49.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/macb_pclk: missing or empty reg/ranges property
   arch/arm64/boot/dts/broadcom/rp1.dtso:51.26-56.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/macb_hclk: missing or empty reg/ranges property
   arch/arm64/boot/dts/broadcom/rp1.dtso:14.15-173.5: Warning (avoid_unnecessary_addr_size): /fragment@0/__overlay__: unnecessary #address-cells/#size-cells without "ranges", "dma-ranges" or child "reg" property 

I believe that These warnings are unavoidable, and stem from the fact that this
is quite a peculiar setup (PCI endpoint which dynamically loads platform driver
addressable via BAR).
The missing reg/ranges in the threee clocks are due to the simple-bus of the
containing node to which I believe they should belong: I did a test to place
those clocks in the same dtso under root or /clocks node but AFAIK it doesn't
seems to work. I could move them in a separate dtso to be loaded before the main
one but this is IMHO even more cumbersome than having a couple of warnings in
CHECK_DTBS.
Of course, if you have any suggestion on how to improve it I would be glad to
discuss.
About the last warning about the address/size-cells, if I drop those two lines
in the _overlay_ node it generates even more warning, so again it's a "don't fix"
one.

> 
> Please run standard kernel tools for static analysis, like coccinelle,
> smatch and sparse, and fix reported warnings. Also please check for
> warnings when building with W=1. Most of these commands (checks or W=1
> build) can build specific targets, like some directory, to narrow the
> scope to only your code. The code here looks like it needs a fix. Feel
> free to get in touch if the warning is not clear.

I didn't run those static analyzers since I've preferred a more "manual" aproach
by carfeully checking the code, but I agree that something can escape even the
more carefully executed code inspection so I will add them to my arsenal from
now on. Thanks for the heads up.

> 
> Please run scripts/checkpatch.pl and fix reported warnings. Then please
> run `scripts/checkpatch.pl --strict` and (probably) fix more warnings.
> Some warnings can be ignored, especially from --strict run, but the code
> here looks like it needs a fix. Feel free to get in touch if the warning
> is not clear.
>

Again, most of checkpatch's complaints have been addressed, the remaining
ones I deemed as not worth fixing, for example:

#> scripts/checkpatch.pl --strict --codespell tmp/*.patch

WARNING: please write a help paragraph that fully describes the config symbol
#42: FILE: drivers/clk/Kconfig:91:
+config COMMON_CLK_RP1
+       tristate "Raspberry Pi RP1-based clock support"
+       depends on PCI || COMPILE_TEST
+       depends on COMMON_CLK
+       help
+         Enable common clock framework support for Raspberry Pi RP1.
+         This mutli-function device has 3 main PLLs and several clock
+         generators to drive the internal sub-peripherals.
+

I don't understand this warning, the paragraph is there and is more or less similar
to many in the same file that are already upstream. Checkpatch bug?


CHECK: Alignment should match open parenthesis
#1541: FILE: drivers/clk/clk-rp1.c:1470:
+       if (WARN_ON_ONCE(clock_data->num_std_parents > AUX_SEL &&
+           strcmp("-", clock_data->parents[AUX_SEL])))

This would have worsen the code readability.


WARNING: ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP
#673: FILE: drivers/pinctrl/pinctrl-rp1.c:600:
+                               return -ENOTSUPP;

This I must investigate: I've already tried to fix it before sending the patchset
but for some reason it wouldn't work, so I planned to fix it in the upcoming 
releases.


WARNING: externs should be avoided in .c files
#331: FILE: drivers/misc/rp1/rp1-pci.c:58:
+extern char __dtbo_rp1_pci_begin[];

True, but in this case we don't have a symbol that should be exported to other
translation units, it just needs to be referenced inside the driver and
consumed locally. Hence it would be better to place the extern in .c file.


Apologies for a couple of other warnings that I could have seen in the first
place, but honestly they don't seems to be a big deal (one typo and on over
100 chars comment, that will be fixed in next patch version). 
 
> 
> Best regards,
> Krzysztof
>

Many thanks,
Andrea 

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

* Re: [PATCH 01/11] dt-bindings: clock: Add RaspberryPi RP1 clock bindings
  2024-08-21 11:46       ` Conor Dooley
@ 2024-08-22  9:35         ` Andrea della Porta
  2024-08-22  9:52           ` Krzysztof Kozlowski
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-22  9:35 UTC (permalink / raw)
  To: Conor Dooley
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Conor,

On 12:46 Wed 21 Aug     , Conor Dooley wrote:
> On Tue, Aug 20, 2024 at 08:25:36PM +0200, Andrea della Porta wrote:
> > Hi Conor,
> > 
> > On 17:19 Tue 20 Aug     , Conor Dooley wrote:
> > > On Tue, Aug 20, 2024 at 04:36:03PM +0200, Andrea della Porta wrote:
> > > > Add device tree bindings for the clock generator found in RP1 multi
> > > > function device, and relative entries in MAINTAINERS file.
> > > > 
> > > > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> > > > ---
> > > >  .../clock/raspberrypi,rp1-clocks.yaml         | 87 +++++++++++++++++++
> > > >  MAINTAINERS                                   |  6 ++
> > > >  include/dt-bindings/clock/rp1.h               | 56 ++++++++++++
> > > >  3 files changed, 149 insertions(+)
> > > >  create mode 100644 Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> > > >  create mode 100644 include/dt-bindings/clock/rp1.h
> > > > 
> > > > diff --git a/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml b/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> > > > new file mode 100644
> > > > index 000000000000..b27db86d0572
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> > > > @@ -0,0 +1,87 @@
> > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > +%YAML 1.2
> > > > +---
> > > > +$id: http://devicetree.org/schemas/clock/raspberrypi,rp1-clocks.yaml#
> > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > +
> > > > +title: RaspberryPi RP1 clock generator
> > > > +
> > > > +maintainers:
> > > > +  - Andrea della Porta <andrea.porta@suse.com>
> > > > +
> > > > +description: |
> > > > +  The RP1 contains a clock generator designed as three PLLs (CORE, AUDIO,
> > > > +  VIDEO), and each PLL output can be programmed though dividers to generate
> > > > +  the clocks to drive the sub-peripherals embedded inside the chipset.
> > > > +
> > > > +  Link to datasheet:
> > > > +  https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
> > > > +
> > > > +properties:
> > > > +  compatible:
> > > > +    const: raspberrypi,rp1-clocks
> > > > +
> > > > +  reg:
> > > > +    maxItems: 1
> > > > +
> > > > +  '#clock-cells':
> > > > +    description:
> > > > +      The index in the assigned-clocks is mapped to the output clock as per
> > > > +      definitions in dt-bindings/clock/rp1.h.
> > > > +    const: 1
> > > > +
> > > > +  clocks:
> > > > +    maxItems: 1
> > > > +
> > > > +required:
> > > > +  - compatible
> > > > +  - reg
> > > > +  - '#clock-cells'
> > > > +  - clocks
> > > > +
> > > > +additionalProperties: false
> > > > +
> > > > +examples:
> > > > +  - |
> > > > +    #include <dt-bindings/clock/rp1.h>
> > > > +
> > > > +    rp1 {
> > > > +        #address-cells = <2>;
> > > > +        #size-cells = <2>;
> > > > +
> > > > +        rp1_clocks: clocks@18000 {
> > > 
> > > The unit address does not match the reg property. I'm surprised that
> > > dtc doesn't complain about that.
> > 
> > Agreed. I'll update the address with the reg value in the next release
> > 
> > > 
> > > > +            compatible = "raspberrypi,rp1-clocks";
> > > > +            reg = <0xc0 0x40018000 0x0 0x10038>;
> > > 
> > > This is a rather oddly specific size. It leads me to wonder if this
> > > region is inside some sort of syscon area?
> > 
> > >From downstream source code and RP1 datasheet it seems that the last addressable
> > register is at 0xc040028014 while the range exposed through teh devicetree ends
> > up at 0xc040028038, so it seems more of a little safe margin. I wouldn't say it
> > is a syscon area since those register are quite specific for video clock
> > generation and not to be intended to be shared among different peripherals.
> > Anyway, the next register aperture is at 0xc040030000 so I would say we can 
> > extend the clock mapped register like the following:
> > 
> > reg = <0xc0 0x40018000 0x0 0x18000>;
> > 
> > if you think it is more readable.
> 
> I don't care

Ack.

> > > > +            #clock-cells = <1>;
> > > > +            clocks = <&clk_xosc>;
> > > > +
> > > > +            assigned-clocks = <&rp1_clocks RP1_PLL_SYS_CORE>,
> > 
> > > FWIW, I don't think any of these assigned clocks are helpful for the
> > > example. That said, why do you need to configure all of these assigned
> > > clocks via devicetree when this node is the provider of them?
> > 
> > Not sure to understand what you mean here, the example is there just to
> > show how to compile the dt node, maybe you're referring to the fact that
> > the consumer should setup the clock freq?
> 
> I suppose, yeah. I don't think a particular configuration is relevant
> for the example binding, but simultaneously don't get why you are
> assigning the rate for clocks used by audio devices or ethernet in the
> clock provider node.
>

Honestly I don't have a strong preference here, I can manage to do some tests
moving the clock rate settings inside the consumer nodes but I kinda like
the curernt idea of a centralized node where clocks are setup beforehand.
In RP1 the clock generator and peripherals such as ethernet are all on-board
and cannot be rewired in any other way so the devices are not standalone
consumer in their own right (such it would be an ethernet chip wired to an
external CPU). But of course this is debatable, on the other hand the current
approach of provider/consumer is of course very clean. I'm just wondering
wthether you think I should take action on this or we can leave it as it is.
Please see also below.

> > Consider that the rp1-clocks
> > is coupled to the peripherals contained in the same RP1 chip so there is
> > not much point in letting the peripherals set the clock to their leisure.
> 
> How is that any different to the many other SoCs in the kernel?

In fact, it isn't. Please take a look at:
 
arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi
arch/arm/boot/dts/ti/omap/omap44xx-clocks.dtsi
arch/arm/boot/dts/ti/omap/dra7xx-clocks.dtsi
arch/arm/boot/dts/nxp/imx/imx7d-zii-rpu2.dts

and probably many others... they use the same approach, so I assumed it is at
least reasonable to assign the clock rate this way.


Many thanks,
Andrea

> 
> > > > +                              <&rp1_clocks RP1_PLL_AUDIO_CORE>,
> > > > +                              /* RP1_PLL_VIDEO_CORE and dividers are now managed by VEC,DPI drivers */
> > > 
> > > Comments like this also do not seem relevant to the binding.
> > 
> > Agreed, will drop in the next release.
> > 
> > > 
> > > 
> > > Cheers,
> > > Conor.
> > >
> > 
> > Many thanks,
> > Andrea
> >  
> > > 
> > > > +                              <&rp1_clocks RP1_PLL_SYS>,
> > > > +                              <&rp1_clocks RP1_PLL_SYS_SEC>,
> > > > +                              <&rp1_clocks RP1_PLL_AUDIO>,
> > > > +                              <&rp1_clocks RP1_PLL_AUDIO_SEC>,
> > > > +                              <&rp1_clocks RP1_CLK_SYS>,
> > > > +                              <&rp1_clocks RP1_PLL_SYS_PRI_PH>,
> > > > +                              /* RP1_CLK_SLOW_SYS is used for the frequency counter (FC0) */
> > > > +                              <&rp1_clocks RP1_CLK_SLOW_SYS>,
> > > > +                              <&rp1_clocks RP1_CLK_SDIO_TIMER>,
> > > > +                              <&rp1_clocks RP1_CLK_SDIO_ALT_SRC>,
> > > > +                              <&rp1_clocks RP1_CLK_ETH_TSU>;
> > > > +
> > > > +            assigned-clock-rates = <1000000000>, // RP1_PLL_SYS_CORE
> > > > +                                   <1536000000>, // RP1_PLL_AUDIO_CORE
> > > > +                                   <200000000>,  // RP1_PLL_SYS
> > > > +                                   <125000000>,  // RP1_PLL_SYS_SEC
> > > > +                                   <61440000>,   // RP1_PLL_AUDIO
> > > > +                                   <192000000>,  // RP1_PLL_AUDIO_SEC
> > > > +                                   <200000000>,  // RP1_CLK_SYS
> > > > +                                   <100000000>,  // RP1_PLL_SYS_PRI_PH
> > > > +                                   /* Must match the XOSC frequency */
> > > > +                                   <50000000>, // RP1_CLK_SLOW_SYS
> > > > +                                   <1000000>, // RP1_CLK_SDIO_TIMER
> > > > +                                   <200000000>, // RP1_CLK_SDIO_ALT_SRC
> > > > +                                   <50000000>; // RP1_CLK_ETH_TSU
> > > > +        };
> > > > +    };
> > > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > > index 42decde38320..6e7db9bce278 100644
> > > > --- a/MAINTAINERS
> > > > +++ b/MAINTAINERS
> > > > @@ -19116,6 +19116,12 @@ F:	Documentation/devicetree/bindings/media/raspberrypi,pispbe.yaml
> > > >  F:	drivers/media/platform/raspberrypi/pisp_be/
> > > >  F:	include/uapi/linux/media/raspberrypi/
> > > >  
> > > > +RASPBERRY PI RP1 PCI DRIVER
> > > > +M:	Andrea della Porta <andrea.porta@suse.com>
> > > > +S:	Maintained
> > > > +F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> > > > +F:	include/dt-bindings/clock/rp1.h
> > > > +
> > > >  RC-CORE / LIRC FRAMEWORK
> > > >  M:	Sean Young <sean@mess.org>
> > > >  L:	linux-media@vger.kernel.org
> > > > diff --git a/include/dt-bindings/clock/rp1.h b/include/dt-bindings/clock/rp1.h
> > > > new file mode 100644
> > > > index 000000000000..1ed67b8a5229
> > > > --- /dev/null
> > > > +++ b/include/dt-bindings/clock/rp1.h
> > > > @@ -0,0 +1,56 @@
> > > > +/* SPDX-License-Identifier: GPL-2.0 OR MIT */
> > > > +/*
> > > > + * Copyright (C) 2021 Raspberry Pi Ltd.
> > > > + */
> > > > +
> > > > +#define RP1_PLL_SYS_CORE		0
> > > > +#define RP1_PLL_AUDIO_CORE		1
> > > > +#define RP1_PLL_VIDEO_CORE		2
> > > > +
> > > > +#define RP1_PLL_SYS			3
> > > > +#define RP1_PLL_AUDIO			4
> > > > +#define RP1_PLL_VIDEO			5
> > > > +
> > > > +#define RP1_PLL_SYS_PRI_PH		6
> > > > +#define RP1_PLL_SYS_SEC_PH		7
> > > > +#define RP1_PLL_AUDIO_PRI_PH		8
> > > > +
> > > > +#define RP1_PLL_SYS_SEC			9
> > > > +#define RP1_PLL_AUDIO_SEC		10
> > > > +#define RP1_PLL_VIDEO_SEC		11
> > > > +
> > > > +#define RP1_CLK_SYS			12
> > > > +#define RP1_CLK_SLOW_SYS		13
> > > > +#define RP1_CLK_DMA			14
> > > > +#define RP1_CLK_UART			15
> > > > +#define RP1_CLK_ETH			16
> > > > +#define RP1_CLK_PWM0			17
> > > > +#define RP1_CLK_PWM1			18
> > > > +#define RP1_CLK_AUDIO_IN		19
> > > > +#define RP1_CLK_AUDIO_OUT		20
> > > > +#define RP1_CLK_I2S			21
> > > > +#define RP1_CLK_MIPI0_CFG		22
> > > > +#define RP1_CLK_MIPI1_CFG		23
> > > > +#define RP1_CLK_PCIE_AUX		24
> > > > +#define RP1_CLK_USBH0_MICROFRAME	25
> > > > +#define RP1_CLK_USBH1_MICROFRAME	26
> > > > +#define RP1_CLK_USBH0_SUSPEND		27
> > > > +#define RP1_CLK_USBH1_SUSPEND		28
> > > > +#define RP1_CLK_ETH_TSU			29
> > > > +#define RP1_CLK_ADC			30
> > > > +#define RP1_CLK_SDIO_TIMER		31
> > > > +#define RP1_CLK_SDIO_ALT_SRC		32
> > > > +#define RP1_CLK_GP0			33
> > > > +#define RP1_CLK_GP1			34
> > > > +#define RP1_CLK_GP2			35
> > > > +#define RP1_CLK_GP3			36
> > > > +#define RP1_CLK_GP4			37
> > > > +#define RP1_CLK_GP5			38
> > > > +#define RP1_CLK_VEC			39
> > > > +#define RP1_CLK_DPI			40
> > > > +#define RP1_CLK_MIPI0_DPI		41
> > > > +#define RP1_CLK_MIPI1_DPI		42
> > > > +
> > > > +/* Extra PLL output channels - RP1B0 only */
> > > > +#define RP1_PLL_VIDEO_PRI_PH		43
> > > > +#define RP1_PLL_AUDIO_TERN		44
> > > > -- 
> > > > 2.35.3
> > > > 
> > 
> > 



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

* Re: [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay
  2024-08-22  9:05   ` Andrea della Porta
@ 2024-08-22  9:50     ` Krzysztof Kozlowski
  2024-08-29 13:11       ` Andrea della Porta
  2024-08-22 13:04     ` Andrew Lunn
  1 sibling, 1 reply; 117+ messages in thread
From: Krzysztof Kozlowski @ 2024-08-22  9:50 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On 22/08/2024 11:05, Andrea della Porta wrote:
> Hi Krzysztof,
> 
> On 15:42 Wed 21 Aug     , Krzysztof Kozlowski wrote:
>> On 20/08/2024 16:36, Andrea della Porta wrote:
>>> RP1 is an MFD chipset that acts as a south-bridge PCIe endpoint sporting
>>> a pletora of subdevices (i.e.  Ethernet, USB host controller, I2C, PWM, 
>>> etc.) whose registers are all reachable starting from an offset from the
>>> BAR address.  The main point here is that while the RP1 as an endpoint
>>> itself is discoverable via usual PCI enumeraiton, the devices it contains
>>> are not discoverable and must be declared e.g. via the devicetree.
>>>
>>> This patchset is an attempt to provide a minimum infrastructure to allow
>>> the RP1 chipset to be discovered and perpherals it contains to be added
>>> from a devictree overlay loaded during RP1 PCI endpoint enumeration.
>>> Followup patches should add support for the several peripherals contained
>>> in RP1.
>>>
>>> This work is based upon dowstream drivers code and the proposal from RH
>>> et al. (see [1] and [2]). A similar approach is also pursued in [3].
>>
>> Looking briefly at findings it seems this was not really tested by
>> automation and you expect reviewers to find issues which are pointed out
>> by tools. That's not nice approach. Reviewer's time is limited, while
>> tools do it for free. And the tools are free - you can use them without
>> any effort.
> 
> Sorry if I gave you that impression, but this is not obviously the case.

Just look at number of reports... so many sparse reports that I wonder
how it is not the case.

And many kbuild reports.

> I've spent quite a bit of time in trying to deliver a patchset that ease
> your and others work, at least to the best I can. In fact, I've used many
> of the checking facilities you mentioned before sending it, solving all
> of the reported issues, except the ones for which there are strong reasons
> to leave untouched, as explained below.
> 
>>
>> It does not look like you tested the DTS against bindings. Please run
>> `make dtbs_check W=1` (see
>> Documentation/devicetree/bindings/writing-schema.rst or
>> https://www.linaro.org/blog/tips-and-tricks-for-validating-devicetree-sources-with-the-devicetree-schema/
>> for instructions).
> 
> #> make W=1 dt_binding_check DT_SCHEMA_FILES=raspberrypi,rp1-gpio.yaml
>    CHKDT   Documentation/devicetree/bindings
>    LINT    Documentation/devicetree/bindings
>    DTEX    Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.example.dts
>    DTC_CHK Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.example.dtb
> 
> #> make W=1 dt_binding_check DT_SCHEMA_FILES=raspberrypi,rp1-clocks.yaml
>    CHKDT   Documentation/devicetree/bindings
>    LINT    Documentation/devicetree/bindings
>    DTEX    Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.example.dts
>    DTC_CHK Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.example.dtb
> 
> I see no issues here, in case you've found something different, I kindly ask you to post
> the results.
> 
> #> make W=1 CHECK_DTBS=y broadcom/rp1.dtbo
>    DTC     arch/arm64/boot/dts/broadcom/rp1.dtbo
>    arch/arm64/boot/dts/broadcom/rp1.dtso:37.24-42.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/clk_xosc: missing or empty reg/ranges property
>    arch/arm64/boot/dts/broadcom/rp1.dtso:44.26-49.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/macb_pclk: missing or empty reg/ranges property
>    arch/arm64/boot/dts/broadcom/rp1.dtso:51.26-56.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/macb_hclk: missing or empty reg/ranges property
>    arch/arm64/boot/dts/broadcom/rp1.dtso:14.15-173.5: Warning (avoid_unnecessary_addr_size): /fragment@0/__overlay__: unnecessary #address-cells/#size-cells without "ranges", "dma-ranges" or child "reg" property 
> 
> I believe that These warnings are unavoidable, and stem from the fact that this
> is quite a peculiar setup (PCI endpoint which dynamically loads platform driver
> addressable via BAR).
> The missing reg/ranges in the threee clocks are due to the simple-bus of the
> containing node to which I believe they should belong: I did a test to place

This is not the place where they belong. non-MMIO nodes should not be
under simple-bus.

> those clocks in the same dtso under root or /clocks node but AFAIK it doesn't
> seems to work. I could move them in a separate dtso to be loaded before the main

Well... who instantiates them? If they are in top-level, then
CLK_OF_DECLARE which is not called at your point?

You must instantiate clocks different way, since they are not part of
"rp1". That's another bogus DT description... external oscilator is not
part of RP1.


> one but this is IMHO even more cumbersome than having a couple of warnings in
> CHECK_DTBS.
> Of course, if you have any suggestion on how to improve it I would be glad to
> discuss.
> About the last warning about the address/size-cells, if I drop those two lines
> in the _overlay_ node it generates even more warning, so again it's a "don't fix"
> one.
> 
>>
>> Please run standard kernel tools for static analysis, like coccinelle,
>> smatch and sparse, and fix reported warnings. Also please check for
>> warnings when building with W=1. Most of these commands (checks or W=1
>> build) can build specific targets, like some directory, to narrow the
>> scope to only your code. The code here looks like it needs a fix. Feel
>> free to get in touch if the warning is not clear.
> 
> I didn't run those static analyzers since I've preferred a more "manual" aproach
> by carfeully checking the code, but I agree that something can escape even the
> more carefully executed code inspection so I will add them to my arsenal from
> now on. Thanks for the heads up.

I don't care if you do not run static analyzers if you produce good
code. But if you produce bugs which could have been easily spotted with
sparser, than it is different thing.

Start running static checkers instead of asking reviewers to do that.

> 
>>
>> Please run scripts/checkpatch.pl and fix reported warnings. Then please
>> run `scripts/checkpatch.pl --strict` and (probably) fix more warnings.
>> Some warnings can be ignored, especially from --strict run, but the code
>> here looks like it needs a fix. Feel free to get in touch if the warning
>> is not clear.
>>
> 
> Again, most of checkpatch's complaints have been addressed, the remaining
> ones I deemed as not worth fixing, for example:>
> #> scripts/checkpatch.pl --strict --codespell tmp/*.patch
> 
> WARNING: please write a help paragraph that fully describes the config symbol
> #42: FILE: drivers/clk/Kconfig:91:
> +config COMMON_CLK_RP1
> +       tristate "Raspberry Pi RP1-based clock support"
> +       depends on PCI || COMPILE_TEST
> +       depends on COMMON_CLK
> +       help
> +         Enable common clock framework support for Raspberry Pi RP1.
> +         This mutli-function device has 3 main PLLs and several clock
> +         generators to drive the internal sub-peripherals.
> +
> 
> I don't understand this warning, the paragraph is there and is more or less similar
> to many in the same file that are already upstream. Checkpatch bug?
> 
> 
> CHECK: Alignment should match open parenthesis
> #1541: FILE: drivers/clk/clk-rp1.c:1470:
> +       if (WARN_ON_ONCE(clock_data->num_std_parents > AUX_SEL &&
> +           strcmp("-", clock_data->parents[AUX_SEL])))
> 
> This would have worsen the code readability.
> 
> 
> WARNING: ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP
> #673: FILE: drivers/pinctrl/pinctrl-rp1.c:600:
> +                               return -ENOTSUPP;
> 
> This I must investigate: I've already tried to fix it before sending the patchset
> but for some reason it wouldn't work, so I planned to fix it in the upcoming 
> releases.
> 
> 
> WARNING: externs should be avoided in .c files
> #331: FILE: drivers/misc/rp1/rp1-pci.c:58:
> +extern char __dtbo_rp1_pci_begin[];
> 
> True, but in this case we don't have a symbol that should be exported to other
> translation units, it just needs to be referenced inside the driver and
> consumed locally. Hence it would be better to place the extern in .c file.
> 
> 
> Apologies for a couple of other warnings that I could have seen in the first
> place, but honestly they don't seems to be a big deal (one typo and on over
> 100 chars comment, that will be fixed in next patch version). 

Again, judging by number of reports from checkers that is a big deal,
because it is your task to run the tools.

Best regards,
Krzysztof


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

* Re: [PATCH 01/11] dt-bindings: clock: Add RaspberryPi RP1 clock bindings
  2024-08-22  9:35         ` Andrea della Porta
@ 2024-08-22  9:52           ` Krzysztof Kozlowski
  2024-08-22 16:23             ` Conor Dooley
  0 siblings, 1 reply; 117+ messages in thread
From: Krzysztof Kozlowski @ 2024-08-22  9:52 UTC (permalink / raw)
  To: Conor Dooley, Andrea della Porta, Michael Turquette, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On 22/08/2024 11:35, Andrea della Porta wrote:
> Hi Conor,
> 
> On 12:46 Wed 21 Aug     , Conor Dooley wrote:
>> On Tue, Aug 20, 2024 at 08:25:36PM +0200, Andrea della Porta wrote:
>>> Hi Conor,
>>>
>>> On 17:19 Tue 20 Aug     , Conor Dooley wrote:
>>>> On Tue, Aug 20, 2024 at 04:36:03PM +0200, Andrea della Porta wrote:
>>>>> Add device tree bindings for the clock generator found in RP1 multi
>>>>> function device, and relative entries in MAINTAINERS file.
>>>>>
>>>>> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
>>>>> ---
>>>>>  .../clock/raspberrypi,rp1-clocks.yaml         | 87 +++++++++++++++++++
>>>>>  MAINTAINERS                                   |  6 ++
>>>>>  include/dt-bindings/clock/rp1.h               | 56 ++++++++++++
>>>>>  3 files changed, 149 insertions(+)
>>>>>  create mode 100644 Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
>>>>>  create mode 100644 include/dt-bindings/clock/rp1.h
>>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml b/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
>>>>> new file mode 100644
>>>>> index 000000000000..b27db86d0572
>>>>> --- /dev/null
>>>>> +++ b/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
>>>>> @@ -0,0 +1,87 @@
>>>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>>>> +%YAML 1.2
>>>>> +---
>>>>> +$id: http://devicetree.org/schemas/clock/raspberrypi,rp1-clocks.yaml#
>>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>>> +
>>>>> +title: RaspberryPi RP1 clock generator
>>>>> +
>>>>> +maintainers:
>>>>> +  - Andrea della Porta <andrea.porta@suse.com>
>>>>> +
>>>>> +description: |
>>>>> +  The RP1 contains a clock generator designed as three PLLs (CORE, AUDIO,
>>>>> +  VIDEO), and each PLL output can be programmed though dividers to generate
>>>>> +  the clocks to drive the sub-peripherals embedded inside the chipset.
>>>>> +
>>>>> +  Link to datasheet:
>>>>> +  https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
>>>>> +
>>>>> +properties:
>>>>> +  compatible:
>>>>> +    const: raspberrypi,rp1-clocks
>>>>> +
>>>>> +  reg:
>>>>> +    maxItems: 1
>>>>> +
>>>>> +  '#clock-cells':
>>>>> +    description:
>>>>> +      The index in the assigned-clocks is mapped to the output clock as per
>>>>> +      definitions in dt-bindings/clock/rp1.h.
>>>>> +    const: 1
>>>>> +
>>>>> +  clocks:
>>>>> +    maxItems: 1
>>>>> +
>>>>> +required:
>>>>> +  - compatible
>>>>> +  - reg
>>>>> +  - '#clock-cells'
>>>>> +  - clocks
>>>>> +
>>>>> +additionalProperties: false
>>>>> +
>>>>> +examples:
>>>>> +  - |
>>>>> +    #include <dt-bindings/clock/rp1.h>
>>>>> +
>>>>> +    rp1 {
>>>>> +        #address-cells = <2>;
>>>>> +        #size-cells = <2>;
>>>>> +
>>>>> +        rp1_clocks: clocks@18000 {
>>>>
>>>> The unit address does not match the reg property. I'm surprised that
>>>> dtc doesn't complain about that.
>>>
>>> Agreed. I'll update the address with the reg value in the next release
>>>
>>>>
>>>>> +            compatible = "raspberrypi,rp1-clocks";
>>>>> +            reg = <0xc0 0x40018000 0x0 0x10038>;
>>>>
>>>> This is a rather oddly specific size. It leads me to wonder if this
>>>> region is inside some sort of syscon area?
>>>
>>> >From downstream source code and RP1 datasheet it seems that the last addressable
>>> register is at 0xc040028014 while the range exposed through teh devicetree ends
>>> up at 0xc040028038, so it seems more of a little safe margin. I wouldn't say it
>>> is a syscon area since those register are quite specific for video clock
>>> generation and not to be intended to be shared among different peripherals.
>>> Anyway, the next register aperture is at 0xc040030000 so I would say we can 
>>> extend the clock mapped register like the following:
>>>
>>> reg = <0xc0 0x40018000 0x0 0x18000>;
>>>
>>> if you think it is more readable.
>>
>> I don't care
> 
> Ack.
> 
>>>>> +            #clock-cells = <1>;
>>>>> +            clocks = <&clk_xosc>;
>>>>> +
>>>>> +            assigned-clocks = <&rp1_clocks RP1_PLL_SYS_CORE>,
>>>
>>>> FWIW, I don't think any of these assigned clocks are helpful for the
>>>> example. That said, why do you need to configure all of these assigned
>>>> clocks via devicetree when this node is the provider of them?
>>>
>>> Not sure to understand what you mean here, the example is there just to
>>> show how to compile the dt node, maybe you're referring to the fact that
>>> the consumer should setup the clock freq?
>>
>> I suppose, yeah. I don't think a particular configuration is relevant
>> for the example binding, but simultaneously don't get why you are
>> assigning the rate for clocks used by audio devices or ethernet in the
>> clock provider node.
>>
> 
> Honestly I don't have a strong preference here, I can manage to do some tests
> moving the clock rate settings inside the consumer nodes but I kinda like
> the curernt idea of a centralized node where clocks are setup beforehand.
> In RP1 the clock generator and peripherals such as ethernet are all on-board
> and cannot be rewired in any other way so the devices are not standalone
> consumer in their own right (such it would be an ethernet chip wired to an
> external CPU). But of course this is debatable, on the other hand the current
> approach of provider/consumer is of course very clean. I'm just wondering
> wthether you think I should take action on this or we can leave it as it is.
> Please see also below.
> 
>>> Consider that the rp1-clocks
>>> is coupled to the peripherals contained in the same RP1 chip so there is
>>> not much point in letting the peripherals set the clock to their leisure.
>>
>> How is that any different to the many other SoCs in the kernel?
> 
> In fact, it isn't. Please take a look at:
>  
> arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi
> arch/arm/boot/dts/ti/omap/omap44xx-clocks.dtsi
> arch/arm/boot/dts/ti/omap/dra7xx-clocks.dtsi
> arch/arm/boot/dts/nxp/imx/imx7d-zii-rpu2.dts
> 
> and probably many others... they use the same approach, so I assumed it is at
> least reasonable to assign the clock rate this way.

Please do not bring some ancient DTS, not really worked on, as example.
stm32 could is moderately recent but dra and omap are not.

Best regards,
Krzysztof


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

* Re: [PATCH 06/11] clk: rp1: Add support for clocks provided by RP1
  2024-08-21 13:17   ` Simon Horman
@ 2024-08-22 10:04     ` Andrea della Porta
  0 siblings, 0 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-08-22 10:04 UTC (permalink / raw)
  To: Simon Horman
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Simon,

On 14:17 Wed 21 Aug     , Simon Horman wrote:
> On Tue, Aug 20, 2024 at 04:36:08PM +0200, Andrea della Porta wrote:
> > RaspberryPi RP1 is an MFD providing, among other peripherals, several
> > clock generators and PLLs that drives the sub-peripherals.
> > Add the driver to support the clock providers.
> > 
> > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> 
> ...
> 
> > diff --git a/drivers/clk/clk-rp1.c b/drivers/clk/clk-rp1.c
> > new file mode 100644
> > index 000000000000..d18e711c0623
> > --- /dev/null
> > +++ b/drivers/clk/clk-rp1.c
> > @@ -0,0 +1,1655 @@
> > +// SPDX-License-Identifier: GPL
> 
> checkpatch says:
> 
> WARNING: 'SPDX-License-Identifier: GPL' is not supported in LICENSES/...
>

Alas, the system on which I executed checkpatch was missing git python module,
so spdxcheck.py wasn't working properly, sorry about that. Fixed in the next
release.

> ...
> 
> > +static int rp1_clock_set_parent(struct clk_hw *hw, u8 index)
> > +{
> > +	struct rp1_clock *clock = container_of(hw, struct rp1_clock, hw);
> > +	struct rp1_clockman *clockman = clock->clockman;
> > +	const struct rp1_clock_data *data = clock->data;
> > +	u32 ctrl, sel;
> > +
> > +	spin_lock(&clockman->regs_lock);
> > +	ctrl = clockman_read(clockman, data->ctrl_reg);
> > +
> > +	if (index >= data->num_std_parents) {
> > +		/* This is an aux source request */
> > +		if (index >= data->num_std_parents + data->num_aux_parents)
> 
> It looks like &clockman->regs_lock needs to be unlocked here.
> 
> Flagged by Smatch, Sparse. and Coccinelle.

Ack.

Many thanks,
Andrea

> 
> > +			return -EINVAL;
> > +
> > +		/* Select parent from aux list */
> > +		ctrl = set_register_field(ctrl, index - data->num_std_parents,
> > +					  CLK_CTRL_AUXSRC_MASK,
> > +					  CLK_CTRL_AUXSRC_SHIFT);
> > +		/* Set src to aux list */
> > +		ctrl = set_register_field(ctrl, AUX_SEL, data->clk_src_mask,
> > +					  CLK_CTRL_SRC_SHIFT);
> > +	} else {
> > +		ctrl = set_register_field(ctrl, index, data->clk_src_mask,
> > +					  CLK_CTRL_SRC_SHIFT);
> > +	}
> > +
> > +	clockman_write(clockman, data->ctrl_reg, ctrl);
> > +	spin_unlock(&clockman->regs_lock);
> > +
> > +	sel = rp1_clock_get_parent(hw);
> > +	WARN(sel != index, "(%s): Parent index req %u returned back %u\n",
> > +	     data->name, index, sel);
> > +
> > +	return 0;
> > +}
> 
> ...

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

* Re: [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay
  2024-08-22  9:05   ` Andrea della Porta
  2024-08-22  9:50     ` Krzysztof Kozlowski
@ 2024-08-22 13:04     ` Andrew Lunn
  2024-08-29 12:01       ` Andrea della Porta
  1 sibling, 1 reply; 117+ messages in thread
From: Andrew Lunn @ 2024-08-22 13:04 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Andrea della Porta, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Florian Fainelli, Broadcom internal kernel review list,
	Linus Walleij, Catalin Marinas, Will Deacon, Derek Kiernan,
	Dragan Cvetic, Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre,
	Claudiu Beznea, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Saravana Kannan, Bjorn Helgaas, linux-clk,
	devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
	linux-gpio, netdev, linux-pci, linux-arch, Lee Jones,
	Stefan Wahren

> WARNING: ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP
> #673: FILE: drivers/pinctrl/pinctrl-rp1.c:600:
> +                               return -ENOTSUPP;
> 
> This I must investigate: I've already tried to fix it before sending the patchset
> but for some reason it wouldn't work, so I planned to fix it in the upcoming 
> releases.

ENOTSUPP is an NFS error. It should not be used outside for NFS. You
want EOPNOTSUPP.

 
> WARNING: externs should be avoided in .c files
> #331: FILE: drivers/misc/rp1/rp1-pci.c:58:
> +extern char __dtbo_rp1_pci_begin[];
> 
> True, but in this case we don't have a symbol that should be exported to other
> translation units, it just needs to be referenced inside the driver and
> consumed locally. Hence it would be better to place the extern in .c file.
 
Did you try making it static.

	Andrew

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-21 14:20     ` Krzysztof Kozlowski
@ 2024-08-22 14:33       ` Andrea della Porta
  2024-08-22 14:46         ` Krzysztof Kozlowski
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-22 14:33 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Krzysztof,

On 16:20 Wed 21 Aug     , Krzysztof Kozlowski wrote:
> On 21/08/2024 10:38, Krzysztof Kozlowski wrote:
> > On Tue, Aug 20, 2024 at 04:36:10PM +0200, Andrea della Porta wrote:
> 
> ...
> 
> >>  drivers/misc/Kconfig                  |   1 +
> >>  drivers/misc/Makefile                 |   1 +
> >>  drivers/misc/rp1/Kconfig              |  20 ++
> >>  drivers/misc/rp1/Makefile             |   3 +
> >>  drivers/misc/rp1/rp1-pci.c            | 333 ++++++++++++++++++++++++++
> >>  drivers/misc/rp1/rp1-pci.dtso         |   8 +
> >>  drivers/pci/quirks.c                  |   1 +
> >>  include/linux/pci_ids.h               |   3 +
> >>  10 files changed, 524 insertions(+)
> >>  create mode 100644 arch/arm64/boot/dts/broadcom/rp1.dtso
> >>  create mode 100644 drivers/misc/rp1/Kconfig
> >>  create mode 100644 drivers/misc/rp1/Makefile
> >>  create mode 100644 drivers/misc/rp1/rp1-pci.c
> >>  create mode 100644 drivers/misc/rp1/rp1-pci.dtso
> >>
> >> diff --git a/MAINTAINERS b/MAINTAINERS
> >> index 67f460c36ea1..1359538b76e8 100644
> >> --- a/MAINTAINERS
> >> +++ b/MAINTAINERS
> >> @@ -19119,9 +19119,11 @@ F:	include/uapi/linux/media/raspberrypi/
> >>  RASPBERRY PI RP1 PCI DRIVER
> >>  M:	Andrea della Porta <andrea.porta@suse.com>
> >>  S:	Maintained
> >> +F:	arch/arm64/boot/dts/broadcom/rp1.dtso
> >>  F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> >>  F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
> >>  F:	drivers/clk/clk-rp1.c
> >> +F:	drivers/misc/rp1/
> >>  F:	drivers/pinctrl/pinctrl-rp1.c
> >>  F:	include/dt-bindings/clock/rp1.h
> >>  F:	include/dt-bindings/misc/rp1.h
> >> diff --git a/arch/arm64/boot/dts/broadcom/rp1.dtso b/arch/arm64/boot/dts/broadcom/rp1.dtso
> >> new file mode 100644
> >> index 000000000000..d80178a278ee
> >> --- /dev/null
> >> +++ b/arch/arm64/boot/dts/broadcom/rp1.dtso
> >> @@ -0,0 +1,152 @@
> >> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> >> +
> >> +#include <dt-bindings/gpio/gpio.h>
> >> +#include <dt-bindings/interrupt-controller/irq.h>
> >> +#include <dt-bindings/clock/rp1.h>
> >> +#include <dt-bindings/misc/rp1.h>
> >> +
> >> +/dts-v1/;
> >> +/plugin/;
> >> +
> >> +/ {
> >> +	fragment@0 {
> >> +		target-path="";
> >> +		__overlay__ {
> >> +			#address-cells = <3>;
> >> +			#size-cells = <2>;
> >> +
> >> +			rp1: rp1@0 {
> >> +				compatible = "simple-bus";
> >> +				#address-cells = <2>;
> >> +				#size-cells = <2>;
> >> +				interrupt-controller;
> >> +				interrupt-parent = <&rp1>;
> >> +				#interrupt-cells = <2>;
> >> +
> >> +				// ranges and dma-ranges must be provided by the includer
> >> +				ranges = <0xc0 0x40000000
> >> +					  0x01/*0x02000000*/ 0x00 0x00000000
> >> +					  0x00 0x00400000>;
> > 
> > Are you 100% sure you do not have here dtc W=1 warnings?
> 
> One more thing, I do not see this overlay applied to any target, which
> means it cannot be tested. You miss entry in Makefile.
>

The dtso is intended to be built from driver/misc/rp1/Makefile as it will
be included in the driver obj:

--- /dev/null
+++ b/drivers/misc/rp1/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+rp1-pci-objs                   := rp1-pci.o rp1-pci.dtbo.o
+obj-$(CONFIG_MISC_RP1)         += rp1-pci.o

and not as part of the dtb system, hence it's m issing in
arch/arm64/boot/dts/broadcom/Makefile.

On the other hand:

#> make W=1 CHECK_DTBS=y broadcom/rp1.dtbo
  DTC     arch/arm64/boot/dts/broadcom/rp1.dtbo
arch/arm64/boot/dts/broadcom/rp1.dtso:37.24-42.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/clk_xosc: missing or empty reg/ranges property
arch/arm64/boot/dts/broadcom/rp1.dtso:44.26-49.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/macb_pclk: missing or empty reg/ranges property
arch/arm64/boot/dts/broadcom/rp1.dtso:51.26-56.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/macb_hclk: missing or empty reg/ranges property
arch/arm64/boot/dts/broadcom/rp1.dtso:14.15-173.5: Warning (avoid_unnecessary_addr_size): /fragment@0/__overlay__: unnecessary #address-cells/#size-cells without "ranges", "dma-ranges" or child "reg" property

seems to do the checks, unless I'm missing something.

Thanks,
Andrea

> Best regards,
> Krzysztof
> 

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-22 14:33       ` Andrea della Porta
@ 2024-08-22 14:46         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 117+ messages in thread
From: Krzysztof Kozlowski @ 2024-08-22 14:46 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On 22/08/2024 16:33, Andrea della Porta wrote:
> Hi Krzysztof,
> 
> On 16:20 Wed 21 Aug     , Krzysztof Kozlowski wrote:
>> On 21/08/2024 10:38, Krzysztof Kozlowski wrote:
>>> On Tue, Aug 20, 2024 at 04:36:10PM +0200, Andrea della Porta wrote:
>>
>> ...
>>
>>>>  drivers/misc/Kconfig                  |   1 +
>>>>  drivers/misc/Makefile                 |   1 +
>>>>  drivers/misc/rp1/Kconfig              |  20 ++
>>>>  drivers/misc/rp1/Makefile             |   3 +
>>>>  drivers/misc/rp1/rp1-pci.c            | 333 ++++++++++++++++++++++++++
>>>>  drivers/misc/rp1/rp1-pci.dtso         |   8 +
>>>>  drivers/pci/quirks.c                  |   1 +
>>>>  include/linux/pci_ids.h               |   3 +
>>>>  10 files changed, 524 insertions(+)
>>>>  create mode 100644 arch/arm64/boot/dts/broadcom/rp1.dtso
>>>>  create mode 100644 drivers/misc/rp1/Kconfig
>>>>  create mode 100644 drivers/misc/rp1/Makefile
>>>>  create mode 100644 drivers/misc/rp1/rp1-pci.c
>>>>  create mode 100644 drivers/misc/rp1/rp1-pci.dtso
>>>>
>>>> diff --git a/MAINTAINERS b/MAINTAINERS
>>>> index 67f460c36ea1..1359538b76e8 100644
>>>> --- a/MAINTAINERS
>>>> +++ b/MAINTAINERS
>>>> @@ -19119,9 +19119,11 @@ F:	include/uapi/linux/media/raspberrypi/
>>>>  RASPBERRY PI RP1 PCI DRIVER
>>>>  M:	Andrea della Porta <andrea.porta@suse.com>
>>>>  S:	Maintained
>>>> +F:	arch/arm64/boot/dts/broadcom/rp1.dtso
>>>>  F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
>>>>  F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
>>>>  F:	drivers/clk/clk-rp1.c
>>>> +F:	drivers/misc/rp1/
>>>>  F:	drivers/pinctrl/pinctrl-rp1.c
>>>>  F:	include/dt-bindings/clock/rp1.h
>>>>  F:	include/dt-bindings/misc/rp1.h
>>>> diff --git a/arch/arm64/boot/dts/broadcom/rp1.dtso b/arch/arm64/boot/dts/broadcom/rp1.dtso
>>>> new file mode 100644
>>>> index 000000000000..d80178a278ee
>>>> --- /dev/null
>>>> +++ b/arch/arm64/boot/dts/broadcom/rp1.dtso
>>>> @@ -0,0 +1,152 @@
>>>> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
>>>> +
>>>> +#include <dt-bindings/gpio/gpio.h>
>>>> +#include <dt-bindings/interrupt-controller/irq.h>
>>>> +#include <dt-bindings/clock/rp1.h>
>>>> +#include <dt-bindings/misc/rp1.h>
>>>> +
>>>> +/dts-v1/;
>>>> +/plugin/;
>>>> +
>>>> +/ {
>>>> +	fragment@0 {
>>>> +		target-path="";
>>>> +		__overlay__ {
>>>> +			#address-cells = <3>;
>>>> +			#size-cells = <2>;
>>>> +
>>>> +			rp1: rp1@0 {
>>>> +				compatible = "simple-bus";
>>>> +				#address-cells = <2>;
>>>> +				#size-cells = <2>;
>>>> +				interrupt-controller;
>>>> +				interrupt-parent = <&rp1>;
>>>> +				#interrupt-cells = <2>;
>>>> +
>>>> +				// ranges and dma-ranges must be provided by the includer
>>>> +				ranges = <0xc0 0x40000000
>>>> +					  0x01/*0x02000000*/ 0x00 0x00000000
>>>> +					  0x00 0x00400000>;
>>>
>>> Are you 100% sure you do not have here dtc W=1 warnings?
>>
>> One more thing, I do not see this overlay applied to any target, which
>> means it cannot be tested. You miss entry in Makefile.
>>
> 
> The dtso is intended to be built from driver/misc/rp1/Makefile as it will
> be included in the driver obj:
> 
> --- /dev/null
> +++ b/drivers/misc/rp1/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +rp1-pci-objs                   := rp1-pci.o rp1-pci.dtbo.o
> +obj-$(CONFIG_MISC_RP1)         += rp1-pci.o
> 
> and not as part of the dtb system, hence it's m issing in
> arch/arm64/boot/dts/broadcom/Makefile.
> 
> On the other hand:
> 
> #> make W=1 CHECK_DTBS=y broadcom/rp1.dtbo
>   DTC     arch/arm64/boot/dts/broadcom/rp1.dtbo
> arch/arm64/boot/dts/broadcom/rp1.dtso:37.24-42.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/clk_xosc: missing or empty reg/ranges property
> arch/arm64/boot/dts/broadcom/rp1.dtso:44.26-49.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/macb_pclk: missing or empty reg/ranges property
> arch/arm64/boot/dts/broadcom/rp1.dtso:51.26-56.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/macb_hclk: missing or empty reg/ranges property
> arch/arm64/boot/dts/broadcom/rp1.dtso:14.15-173.5: Warning (avoid_unnecessary_addr_size): /fragment@0/__overlay__: unnecessary #address-cells/#size-cells without "ranges", "dma-ranges" or child "reg" property
> 
> seems to do the checks, unless I'm missing something.

Yeah, there is still no target which applies the overlay, so no one can
tell whether it applies cleanly or not. You can only test single
overlay, but it is expected to test each overlay being applied to chosen
DTB.

Best regards,
Krzysztof


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

* Re: [PATCH 01/11] dt-bindings: clock: Add RaspberryPi RP1 clock bindings
  2024-08-22  9:52           ` Krzysztof Kozlowski
@ 2024-08-22 16:23             ` Conor Dooley
  2024-08-23 18:21               ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Conor Dooley @ 2024-08-22 16:23 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

[-- Attachment #1: Type: text/plain, Size: 4500 bytes --]

On Thu, Aug 22, 2024 at 11:52:27AM +0200, Krzysztof Kozlowski wrote:

> >>>>> +examples:
> >>>>> +  - |
> >>>>> +    #include <dt-bindings/clock/rp1.h>
> >>>>> +
> >>>>> +    rp1 {
> >>>>> +        #address-cells = <2>;
> >>>>> +        #size-cells = <2>;
> >>>>> +
> >>>>> +        rp1_clocks: clocks@18000 {
> >>>>
> >>>> The unit address does not match the reg property. I'm surprised that
> >>>> dtc doesn't complain about that.
> >>>
> >>> Agreed. I'll update the address with the reg value in the next release
> >>>
> >>>>
> >>>>> +            compatible = "raspberrypi,rp1-clocks";
> >>>>> +            reg = <0xc0 0x40018000 0x0 0x10038>;
> >>>>
> >>>> This is a rather oddly specific size. It leads me to wonder if this
> >>>> region is inside some sort of syscon area?
> >>>
> >>> >From downstream source code and RP1 datasheet it seems that the last addressable
> >>> register is at 0xc040028014 while the range exposed through teh devicetree ends
> >>> up at 0xc040028038, so it seems more of a little safe margin. I wouldn't say it
> >>> is a syscon area since those register are quite specific for video clock
> >>> generation and not to be intended to be shared among different peripherals.
> >>> Anyway, the next register aperture is at 0xc040030000 so I would say we can 
> >>> extend the clock mapped register like the following:
> >>>
> >>> reg = <0xc0 0x40018000 0x0 0x18000>;
> >>>
> >>> if you think it is more readable.
> >>
> >> I don't care
> > 
> > Ack.
> > 
> >>>>> +            #clock-cells = <1>;
> >>>>> +            clocks = <&clk_xosc>;
> >>>>> +
> >>>>> +            assigned-clocks = <&rp1_clocks RP1_PLL_SYS_CORE>,
> >>>
> >>>> FWIW, I don't think any of these assigned clocks are helpful for the
> >>>> example. That said, why do you need to configure all of these assigned
> >>>> clocks via devicetree when this node is the provider of them?
> >>>
> >>> Not sure to understand what you mean here, the example is there just to
> >>> show how to compile the dt node, maybe you're referring to the fact that
> >>> the consumer should setup the clock freq?
> >>
> >> I suppose, yeah. I don't think a particular configuration is relevant
> >> for the example binding, but simultaneously don't get why you are
> >> assigning the rate for clocks used by audio devices or ethernet in the
> >> clock provider node.
> >>
> > 
> > Honestly I don't have a strong preference here, I can manage to do some tests
> > moving the clock rate settings inside the consumer nodes but I kinda like
> > the curernt idea of a centralized node where clocks are setup beforehand.
> > In RP1 the clock generator and peripherals such as ethernet are all on-board
> > and cannot be rewired in any other way so the devices are not standalone
> > consumer in their own right (such it would be an ethernet chip wired to an
> > external CPU). But of course this is debatable, on the other hand the current
> > approach of provider/consumer is of course very clean. I'm just wondering
> > wthether you think I should take action on this or we can leave it as it is.
> > Please see also below.
> > 
> >>> Consider that the rp1-clocks
> >>> is coupled to the peripherals contained in the same RP1 chip so there is
> >>> not much point in letting the peripherals set the clock to their leisure.
> >>
> >> How is that any different to the many other SoCs in the kernel?
> > 
> > In fact, it isn't. Please take a look at:
> >  
> > arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi
> > arch/arm/boot/dts/ti/omap/omap44xx-clocks.dtsi
> > arch/arm/boot/dts/ti/omap/dra7xx-clocks.dtsi
> > arch/arm/boot/dts/nxp/imx/imx7d-zii-rpu2.dts
> > 
> > and probably many others... they use the same approach, so I assumed it is at
> > least reasonable to assign the clock rate this way.
> 
> Please do not bring some ancient DTS, not really worked on, as example.
> stm32 could is moderately recent but dra and omap are not.

Right, there may be some examples like this, but there are many many
other SoCs where clocks are also not re-wireable, that do not. To me
this line of argument is akin to the clock driver calling enable on all
of the clocks because "all of the peripherals are always on the SoC".
The peripheral is the actual consumer of the clock that quote-unquote
wants the particular rate, not the clock provider, so having the rate
assignments in the consumers is the only thing that makes sense to me.



[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-21 16:20   ` Stefan Wahren
@ 2024-08-23  9:44     ` Andrea della Porta
  2024-08-23 10:23       ` Stefan Wahren
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-23  9:44 UTC (permalink / raw)
  To: Stefan Wahren
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn

Hi Stefan,

On 18:20 Wed 21 Aug     , Stefan Wahren wrote:
> Hi Andrea,
> 
> Am 20.08.24 um 16:36 schrieb Andrea della Porta:
> > The RaspberryPi RP1 is ia PCI multi function device containing
> > peripherals ranging from Ethernet to USB controller, I2C, SPI
> > and others.
> sorry, i cannot provide you a code review, but just some comments. multi
> function device suggests "mfd" subsystem or at least "soc" . I won't
> recommend misc driver here.

It's true that RP1 can be called an MFD but the reason for not placing
it in mfd subsystem are twofold:

- these discussions are quite clear about this matter: please see [1]
  and [2]
- the current driver use no mfd API at all

This RP1 driver is not currently addressing any aspect of ARM core in the
SoC so I would say it should not stay in drivers/soc / either, as also
condifirmed by [2] again and [3] (note that Microchip LAN966x is a very
close fit to what we have here on RP1).

> > Implement a bare minimum driver to operate the RP1, leveraging
> > actual OF based driver implementations for the on-borad peripherals
> > by loading a devicetree overlay during driver probe.
> Can you please explain why this should be a DT overlay? The RP1 is
> assembled on the Raspberry Pi 5 PCB. DT overlays are typically for loose
> connections like displays or HATs. I think a DTSI just for the RP1 would
> fit better and is easier to read.

The dtsi solution you proposed is the one adopted downstream. It has its
benefits of course, but there's more.
With the overlay approach we can achieve more generic and agnostic approach
to managing this chipset, being that it is a PCI endpoint and could be
possibly be reused in other hw implementations. I believe a similar
reasoning could be applied to Bootlin's Microchip LAN966x patchset as
well, and they also choose to approach the dtb overlay.
Plus, a solution that can (althoguh proabbly in teh long run) cope
with both DT or ACPI based system has been kindly requested, plase see [4]
for details.
IMHO the approach proposed from RH et al. of using dtbo for this 'special'
kind of drivers makes a lot of sense (see [5]).

> > The peripherals are accessed by mapping MMIO registers starting
> > from PCI BAR1 region.
> > As a minimum driver, the peripherals will not be added to the
> > dtbo here, but in following patches.
> > 
> > Link: https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
> > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> > ---
> >   MAINTAINERS                           |   2 +
> >   arch/arm64/boot/dts/broadcom/rp1.dtso | 152 ++++++++++++
> >   drivers/misc/Kconfig                  |   1 +
> >   drivers/misc/Makefile                 |   1 +
> >   drivers/misc/rp1/Kconfig              |  20 ++
> >   drivers/misc/rp1/Makefile             |   3 +
> >   drivers/misc/rp1/rp1-pci.c            | 333 ++++++++++++++++++++++++++
> >   drivers/misc/rp1/rp1-pci.dtso         |   8 +
> >   drivers/pci/quirks.c                  |   1 +
> >   include/linux/pci_ids.h               |   3 +
> >   10 files changed, 524 insertions(+)
> >   create mode 100644 arch/arm64/boot/dts/broadcom/rp1.dtso
> >   create mode 100644 drivers/misc/rp1/Kconfig
> >   create mode 100644 drivers/misc/rp1/Makefile
> >   create mode 100644 drivers/misc/rp1/rp1-pci.c
> >   create mode 100644 drivers/misc/rp1/rp1-pci.dtso
> > 
> ...
> > +
> > +				rp1_clocks: clocks@c040018000 {
> > +					compatible = "raspberrypi,rp1-clocks";
> > +					#clock-cells = <1>;
> > +					reg = <0xc0 0x40018000 0x0 0x10038>;
> > +					clocks = <&clk_xosc>;
> > +					clock-names = "xosc";
> > +
> > +					assigned-clocks = <&rp1_clocks RP1_PLL_SYS_CORE>,
> > +							  <&rp1_clocks RP1_PLL_AUDIO_CORE>,
> > +							  // RP1_PLL_VIDEO_CORE and dividers are now managed by VEC,DPI drivers
> > +							  <&rp1_clocks RP1_PLL_SYS>,
> > +							  <&rp1_clocks RP1_PLL_SYS_SEC>,
> > +							  <&rp1_clocks RP1_PLL_SYS_PRI_PH>,
> > +							  <&rp1_clocks RP1_CLK_ETH_TSU>;
> > +
> > +					assigned-clock-rates = <1000000000>, // RP1_PLL_SYS_CORE
> > +							       <1536000000>, // RP1_PLL_AUDIO_CORE
> > +							       <200000000>,  // RP1_PLL_SYS
> > +							       <125000000>,  // RP1_PLL_SYS_SEC
> > +							       <100000000>,  // RP1_PLL_SYS_PRI_PH
> > +							       <50000000>;   // RP1_CLK_ETH_TSU
> > +				};
> > +
> > +				rp1_gpio: pinctrl@c0400d0000 {
> > +					reg = <0xc0 0x400d0000  0x0 0xc000>,
> > +					      <0xc0 0x400e0000  0x0 0xc000>,
> > +					      <0xc0 0x400f0000  0x0 0xc000>;
> > +					compatible = "raspberrypi,rp1-gpio";
> > +					gpio-controller;
> > +					#gpio-cells = <2>;
> > +					interrupt-controller;
> > +					#interrupt-cells = <2>;
> > +					interrupts = <RP1_INT_IO_BANK0 IRQ_TYPE_LEVEL_HIGH>,
> > +						     <RP1_INT_IO_BANK1 IRQ_TYPE_LEVEL_HIGH>,
> > +						     <RP1_INT_IO_BANK2 IRQ_TYPE_LEVEL_HIGH>;
> > +					gpio-line-names =
> > +						"ID_SDA", // GPIO0
> > +						"ID_SCL", // GPIO1
> > +						"GPIO2", // GPIO2
> > +						"GPIO3", // GPIO3
> > +						"GPIO4", // GPIO4
> > +						"GPIO5", // GPIO5
> > +						"GPIO6", // GPIO6
> > +						"GPIO7", // GPIO7
> > +						"GPIO8", // GPIO8
> > +						"GPIO9", // GPIO9
> > +						"GPIO10", // GPIO10
> > +						"GPIO11", // GPIO11
> > +						"GPIO12", // GPIO12
> > +						"GPIO13", // GPIO13
> > +						"GPIO14", // GPIO14
> > +						"GPIO15", // GPIO15
> > +						"GPIO16", // GPIO16
> > +						"GPIO17", // GPIO17
> > +						"GPIO18", // GPIO18
> > +						"GPIO19", // GPIO19
> > +						"GPIO20", // GPIO20
> > +						"GPIO21", // GPIO21
> > +						"GPIO22", // GPIO22
> > +						"GPIO23", // GPIO23
> > +						"GPIO24", // GPIO24
> > +						"GPIO25", // GPIO25
> > +						"GPIO26", // GPIO26
> > +						"GPIO27", // GPIO27
> > +						"PCIE_RP1_WAKE", // GPIO28
> > +						"FAN_TACH", // GPIO29
> > +						"HOST_SDA", // GPIO30
> > +						"HOST_SCL", // GPIO31
> > +						"ETH_RST_N", // GPIO32
> > +						"", // GPIO33
> > +						"CD0_IO0_MICCLK", // GPIO34
> > +						"CD0_IO0_MICDAT0", // GPIO35
> > +						"RP1_PCIE_CLKREQ_N", // GPIO36
> > +						"", // GPIO37
> > +						"CD0_SDA", // GPIO38
> > +						"CD0_SCL", // GPIO39
> > +						"CD1_SDA", // GPIO40
> > +						"CD1_SCL", // GPIO41
> > +						"USB_VBUS_EN", // GPIO42
> > +						"USB_OC_N", // GPIO43
> > +						"RP1_STAT_LED", // GPIO44
> > +						"FAN_PWM", // GPIO45
> > +						"CD1_IO0_MICCLK", // GPIO46
> > +						"2712_WAKE", // GPIO47
> > +						"CD1_IO1_MICDAT1", // GPIO48
> > +						"EN_MAX_USB_CUR", // GPIO49
> > +						"", // GPIO50
> > +						"", // GPIO51
> > +						"", // GPIO52
> > +						""; // GPIO53
> GPIO line names are board specific, so this should go to the Raspberry
> Pi 5 file.

Could we instead just name them with generic GPIO'N' where N is the number
of the gpio? Much like many of that pins already are... in this way we
don't add a dependency in the board dts to the rp1_gpio node, which is not
even there when the main dts is parsed at boot, since the dtbo will be
added only on PCI enumeration of the RP1 device.
Or even better: since we don't explicitly use the gpio names to address
them (e.g. phy-reset-gpios in rp1_eth node is addressing the ETH_RST_N
gpio by number), can we just get rid of the gpio-line-names property?
Also Bootlin's Microchip gpio node seems to avoid naming them...

> > +				};
> > +			};
> > +		};
> > +	};
> > +};
> > diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> > index 41c3d2821a78..02405209e6c4 100644
> > --- a/drivers/misc/Kconfig
> > +++ b/drivers/misc/Kconfig
> > @@ -618,4 +618,5 @@ source "drivers/misc/uacce/Kconfig"
> >   source "drivers/misc/pvpanic/Kconfig"
> >   source "drivers/misc/mchp_pci1xxxx/Kconfig"
> >   source "drivers/misc/keba/Kconfig"
> > +source "drivers/misc/rp1/Kconfig"
> >   endmenu
> > diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> > index c2f990862d2b..84bfa866fbee 100644
> > --- a/drivers/misc/Makefile
> > +++ b/drivers/misc/Makefile
> > @@ -71,3 +71,4 @@ obj-$(CONFIG_TPS6594_PFSM)	+= tps6594-pfsm.o
> >   obj-$(CONFIG_NSM)		+= nsm.o
> >   obj-$(CONFIG_MARVELL_CN10K_DPI)	+= mrvl_cn10k_dpi.o
> >   obj-y				+= keba/
> > +obj-$(CONFIG_MISC_RP1)		+= rp1/
> > diff --git a/drivers/misc/rp1/Kconfig b/drivers/misc/rp1/Kconfig
> > new file mode 100644
> > index 000000000000..050417ee09ae
> > --- /dev/null
> > +++ b/drivers/misc/rp1/Kconfig
> > @@ -0,0 +1,20 @@
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +#
> > +# RaspberryPi RP1 misc device
> > +#
> > +
> > +config MISC_RP1
> > +        tristate "RaspberryPi RP1 PCIe support"
> > +        depends on PCI && PCI_QUIRKS
> > +        select OF
> > +        select OF_OVERLAY
> > +        select IRQ_DOMAIN
> > +        select PCI_DYNAMIC_OF_NODES
> > +        help
> > +          Support for the RP1 peripheral chip found on Raspberry Pi 5 board.
> > +          This device supports several sub-devices including e.g. Ethernet controller,
> > +          USB controller, I2C, SPI and UART.
> > +          The driver is responsible for enabling the DT node once the PCIe endpoint
> > +          has been configured, and handling interrupts.
> > +          This driver uses an overlay to load other drivers to support for RP1
> > +          internal sub-devices.
> > diff --git a/drivers/misc/rp1/Makefile b/drivers/misc/rp1/Makefile
> > new file mode 100644
> > index 000000000000..e83854b4ed2c
> > --- /dev/null
> > +++ b/drivers/misc/rp1/Makefile
> > @@ -0,0 +1,3 @@
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +rp1-pci-objs			:= rp1-pci.o rp1-pci.dtbo.o
> > +obj-$(CONFIG_MISC_RP1)		+= rp1-pci.o
> > diff --git a/drivers/misc/rp1/rp1-pci.c b/drivers/misc/rp1/rp1-pci.c
> > new file mode 100644
> > index 000000000000..a6093ba7e19a
> > --- /dev/null
> > +++ b/drivers/misc/rp1/rp1-pci.c
> > @@ -0,0 +1,333 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2018-22 Raspberry Pi Ltd.
> > + * All rights reserved.
> > + */
> > +
> > +#include <linux/clk.h>
> > +#include <linux/clkdev.h>
> > +#include <linux/clk-provider.h>
> > +#include <linux/err.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/irq.h>
> > +#include <linux/irqchip/chained_irq.h>
> > +#include <linux/irqdomain.h>
> > +#include <linux/module.h>
> > +#include <linux/msi.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/pci.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/reset.h>
> > +
> > +#include <dt-bindings/misc/rp1.h>
> > +
> > +#define RP1_B0_CHIP_ID		0x10001927
> > +#define RP1_C0_CHIP_ID		0x20001927
> > +
> > +#define RP1_PLATFORM_ASIC	BIT(1)
> > +#define RP1_PLATFORM_FPGA	BIT(0)
> > +
> > +#define RP1_DRIVER_NAME		"rp1"
> > +
> > +#define RP1_ACTUAL_IRQS		RP1_INT_END
> > +#define RP1_IRQS		RP1_ACTUAL_IRQS
> > +#define RP1_HW_IRQ_MASK		GENMASK(5, 0)
> > +
> > +#define RP1_SYSCLK_RATE		200000000
> > +#define RP1_SYSCLK_FPGA_RATE	60000000
> > +
> > +enum {
> > +	SYSINFO_CHIP_ID_OFFSET	= 0,
> > +	SYSINFO_PLATFORM_OFFSET	= 4,
> > +};
> > +
> > +#define REG_SET			0x800
> > +#define REG_CLR			0xc00
> > +
> > +/* MSIX CFG registers start at 0x8 */
> > +#define MSIX_CFG(x) (0x8 + (4 * (x)))
> > +
> > +#define MSIX_CFG_IACK_EN        BIT(3)
> > +#define MSIX_CFG_IACK           BIT(2)
> > +#define MSIX_CFG_TEST           BIT(1)
> > +#define MSIX_CFG_ENABLE         BIT(0)
> > +
> > +#define INTSTATL		0x108
> > +#define INTSTATH		0x10c
> > +
> > +extern char __dtbo_rp1_pci_begin[];
> > +extern char __dtbo_rp1_pci_end[];
> > +
> > +struct rp1_dev {
> > +	struct pci_dev *pdev;
> > +	struct device *dev;
> > +	struct clk *sys_clk;
> > +	struct irq_domain *domain;
> > +	struct irq_data *pcie_irqds[64];
> > +	void __iomem *bar1;
> > +	int ovcs_id;
> > +	bool level_triggered_irq[RP1_ACTUAL_IRQS];
> > +};
> > +
> > +
> ...
> > +
> > +static const struct pci_device_id dev_id_table[] = {
> > +	{ PCI_DEVICE(PCI_VENDOR_ID_RPI, PCI_DEVICE_ID_RP1_C0), },
> > +	{ 0, }
> > +};
> > +
> > +static struct pci_driver rp1_driver = {
> > +	.name		= RP1_DRIVER_NAME,
> > +	.id_table	= dev_id_table,
> > +	.probe		= rp1_probe,
> > +	.remove		= rp1_remove,
> > +};
> > +
> > +module_pci_driver(rp1_driver);
> > +
> > +MODULE_AUTHOR("Phil Elwell <phil@raspberrypi.com>");
> Module author & Copyright doesn't seem to match with this patch author.
> Please clarify/fix

My intention here is that, even if the code has been heavily modified by me,
the core original code is still there so I just wanted to tribute it to the
original author. 
I'll synchronize this with RaspberryPi guys and coem up with a unified solution.
Just in case: would multiple MODULE_AUTHOR entries (one with my name and one
with original authors name) be accepetd?

Many thanks,
Andrea

References:

- [1]: https://lore.kernel.org/all/20240612140208.GC1504919@google.com/
- [2]: https://lore.kernel.org/all/83f7fa09-d0e6-4f36-a27d-cee08979be2a@app.fastmail.com/
- [3]: https://lore.kernel.org/all/2024081356-mutable-everyday-6f9d@gregkh/
- [4]: https://lore.kernel.org/all/ba8cdf39-3ba3-4abc-98f5-d394d6867f95@gmx.net/
- [5]: https://lpc.events/event/17/contributions/1421/attachments/1337/2680/LPC2023%20Non-discoverable%20devices%20in%20PCI.pdf

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-21 16:55   ` Bjorn Helgaas
@ 2024-08-23 10:21     ` Andrea della Porta
  0 siblings, 0 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-08-23 10:21 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On 11:55 Wed 21 Aug     , Bjorn Helgaas wrote:
> On Tue, Aug 20, 2024 at 04:36:10PM +0200, Andrea della Porta wrote:
> > The RaspberryPi RP1 is ia PCI multi function device containing
> 
> s/ia/a/
> 
> > peripherals ranging from Ethernet to USB controller, I2C, SPI
> > and others.
> 
> Add blank lines between paragraphs.
> 
> > Implement a bare minimum driver to operate the RP1, leveraging
> > actual OF based driver implementations for the on-borad peripherals
> 
> s/on-borad/on-board/
> 
> > by loading a devicetree overlay during driver probe.
> > The peripherals are accessed by mapping MMIO registers starting
> > from PCI BAR1 region.
> > As a minimum driver, the peripherals will not be added to the
> > dtbo here, but in following patches.
> 
> > +config MISC_RP1
> > +        tristate "RaspberryPi RP1 PCIe support"
> > +        depends on PCI && PCI_QUIRKS
> > +        select OF
> > +        select OF_OVERLAY
> > +        select IRQ_DOMAIN
> > +        select PCI_DYNAMIC_OF_NODES
> > +        help
> > +          Support for the RP1 peripheral chip found on Raspberry Pi 5 board.
> > +          This device supports several sub-devices including e.g. Ethernet controller,
> > +          USB controller, I2C, SPI and UART.
> > +          The driver is responsible for enabling the DT node once the PCIe endpoint
> > +          has been configured, and handling interrupts.
> > +          This driver uses an overlay to load other drivers to support for RP1
> > +          internal sub-devices.
> 
> s/support for/support/
> 
> Add blank lines between paragraphs.  Consider wrapping to fit in 80
> columns.  Current width of 86 seems random.
> 
> > diff --git a/drivers/misc/rp1/Makefile b/drivers/misc/rp1/Makefile
> > new file mode 100644
> > index 000000000000..e83854b4ed2c
> > --- /dev/null
> > +++ b/drivers/misc/rp1/Makefile
> > @@ -0,0 +1,3 @@
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +rp1-pci-objs			:= rp1-pci.o rp1-pci.dtbo.o
> > +obj-$(CONFIG_MISC_RP1)		+= rp1-pci.o
> > diff --git a/drivers/misc/rp1/rp1-pci.c b/drivers/misc/rp1/rp1-pci.c
> > new file mode 100644
> > index 000000000000..a6093ba7e19a
> > --- /dev/null
> > +++ b/drivers/misc/rp1/rp1-pci.c
> > @@ -0,0 +1,333 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2018-22 Raspberry Pi Ltd.
> 
> s/22/24/ ?
> 
> > +#define RP1_B0_CHIP_ID		0x10001927
> > +#define RP1_C0_CHIP_ID		0x20001927
> 
> Drop; both unused.
> 
> > +#define RP1_PLATFORM_ASIC	BIT(1)
> > +#define RP1_PLATFORM_FPGA	BIT(0)
> 
> Drop; both unused.
> 
> > +#define RP1_SYSCLK_RATE		200000000
> > +#define RP1_SYSCLK_FPGA_RATE	60000000
> 
> Drop; both unused.
> 
> > +enum {
> > +	SYSINFO_CHIP_ID_OFFSET	= 0,
> > +	SYSINFO_PLATFORM_OFFSET	= 4,
> > +};
> 
> Drop; unused.
> 
> > +/* MSIX CFG registers start at 0x8 */
> 
> s/MSIX/MSI-X/
> 
> > +#define MSIX_CFG_TEST           BIT(1)
> 
> Unused.
> 
> > +#define INTSTATL		0x108
> > +#define INTSTATH		0x10c
> 
> Drop; both unused.
> 
> > +static void dump_bar(struct pci_dev *pdev, unsigned int bar)
> > +{
> > +	dev_info(&pdev->dev,
> > +		 "bar%d len 0x%llx, start 0x%llx, end 0x%llx, flags, 0x%lx\n",
> 
> %pR does most of this for you.
> 
> > +static int rp1_irq_set_type(struct irq_data *irqd, unsigned int type)
> > +{
> > +	struct rp1_dev *rp1 = irqd->domain->host_data;
> > +	unsigned int hwirq = (unsigned int)irqd->hwirq;
> > +	int ret = 0;
> > +
> > +	switch (type) {
> > +	case IRQ_TYPE_LEVEL_HIGH:
> > +		dev_dbg(rp1->dev, "MSIX IACK EN for irq %d\n", hwirq);
> > +		msix_cfg_set(rp1, hwirq, MSIX_CFG_IACK_EN);
> > +		rp1->level_triggered_irq[hwirq] = true;
> > +	break;
> > +	case IRQ_TYPE_EDGE_RISING:
> > +		msix_cfg_clr(rp1, hwirq, MSIX_CFG_IACK_EN);
> > +		rp1->level_triggered_irq[hwirq] = false;
> > +		break;
> > +	default:
> > +		ret = -EINVAL;
> 
> If you "return -EINVAL" directly here, I think you can drop "ret" and
> just "return 0" below.
> 
> > +		break;
> > +	}
> > +
> > +	return ret;
> > +}
> 
> > +static int rp1_irq_xlate(struct irq_domain *d, struct device_node *node,
> > +			 const u32 *intspec, unsigned int intsize,
> > +			 unsigned long *out_hwirq, unsigned int *out_type)
> > +{
> > +	struct rp1_dev *rp1 = d->host_data;
> > +	struct irq_data *pcie_irqd;
> > +	unsigned long hwirq;
> > +	int pcie_irq;
> > +	int ret;
> > +
> > +	ret = irq_domain_xlate_twocell(d, node, intspec, intsize,
> > +				       &hwirq, out_type);
> > +	if (!ret) {
> > +		pcie_irq = pci_irq_vector(rp1->pdev, hwirq);
> > +		pcie_irqd = irq_get_irq_data(pcie_irq);
> > +		rp1->pcie_irqds[hwirq] = pcie_irqd;
> > +		*out_hwirq = hwirq;
> > +	}
> > +
> > +	return ret;
> 
>   if (ret)
>     return ret;
> 
>   ...
>   return 0;
> 
> would make this easier to read and unindent the normal path.
> 
> > +	rp1->bar1 = pci_iomap(pdev, 1, 0);
> 
> pcim_iomap()
> 
> > +	if (!rp1->bar1) {
> > +		dev_err(&pdev->dev, "Cannot map PCI bar\n");
> 
> s/bar/BAR/
> 
> > +#define PCI_VENDOR_ID_RPI		0x1de4
> > +#define PCI_DEVICE_ID_RP1_C0		0x0001
> 
> Device ID should include "RPI" as well.

Ack to all suggestions. Fixed in the next release, thanks.

Andrea

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-23  9:44     ` Andrea della Porta
@ 2024-08-23 10:23       ` Stefan Wahren
  2024-08-23 16:31         ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Stefan Wahren @ 2024-08-23 10:23 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn

Hi Andrea,

Am 23.08.24 um 11:44 schrieb Andrea della Porta:
> Hi Stefan,
>
> On 18:20 Wed 21 Aug     , Stefan Wahren wrote:
>> Hi Andrea,
>>
>> Am 20.08.24 um 16:36 schrieb Andrea della Porta:
>>> The RaspberryPi RP1 is ia PCI multi function device containing
>>> peripherals ranging from Ethernet to USB controller, I2C, SPI
>>> and others.
>> sorry, i cannot provide you a code review, but just some comments. multi
>> function device suggests "mfd" subsystem or at least "soc" . I won't
>> recommend misc driver here.
> It's true that RP1 can be called an MFD but the reason for not placing
> it in mfd subsystem are twofold:
>
> - these discussions are quite clear about this matter: please see [1]
>    and [2]
> - the current driver use no mfd API at all
>
> This RP1 driver is not currently addressing any aspect of ARM core in the
> SoC so I would say it should not stay in drivers/soc / either, as also
> condifirmed by [2] again and [3] (note that Microchip LAN966x is a very
> close fit to what we have here on RP1).
thanks i was aware of these discussions. A pointer to them or at least a
short statement in the cover letter would be great.
>
>>> Implement a bare minimum driver to operate the RP1, leveraging
>>> actual OF based driver implementations for the on-borad peripherals
>>> by loading a devicetree overlay during driver probe.
>> Can you please explain why this should be a DT overlay? The RP1 is
>> assembled on the Raspberry Pi 5 PCB. DT overlays are typically for loose
>> connections like displays or HATs. I think a DTSI just for the RP1 would
>> fit better and is easier to read.
> The dtsi solution you proposed is the one adopted downstream. It has its
> benefits of course, but there's more.
> With the overlay approach we can achieve more generic and agnostic approach
> to managing this chipset, being that it is a PCI endpoint and could be
> possibly be reused in other hw implementations. I believe a similar
> reasoning could be applied to Bootlin's Microchip LAN966x patchset as
> well, and they also choose to approach the dtb overlay.
Could please add this point in the commit message. Doesn't introduce
(maintainence) issues in case U-Boot needs a RP1 driver, too?
> Plus, a solution that can (althoguh proabbly in teh long run) cope
> with both DT or ACPI based system has been kindly requested, plase see [4]
> for details.
> IMHO the approach proposed from RH et al. of using dtbo for this 'special'
> kind of drivers makes a lot of sense (see [5]).
>
>>> The peripherals are accessed by mapping MMIO registers starting
>>> from PCI BAR1 region.
>>> As a minimum driver, the peripherals will not be added to the
>>> dtbo here, but in following patches.
>>>
>>> Link: https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
>>> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
>>> ---
>>>    MAINTAINERS                           |   2 +
>>>    arch/arm64/boot/dts/broadcom/rp1.dtso | 152 ++++++++++++
>>>    drivers/misc/Kconfig                  |   1 +
>>>    drivers/misc/Makefile                 |   1 +
>>>    drivers/misc/rp1/Kconfig              |  20 ++
>>>    drivers/misc/rp1/Makefile             |   3 +
>>>    drivers/misc/rp1/rp1-pci.c            | 333 ++++++++++++++++++++++++++
>>>    drivers/misc/rp1/rp1-pci.dtso         |   8 +
>>>    drivers/pci/quirks.c                  |   1 +
>>>    include/linux/pci_ids.h               |   3 +
>>>    10 files changed, 524 insertions(+)
>>>    create mode 100644 arch/arm64/boot/dts/broadcom/rp1.dtso
>>>    create mode 100644 drivers/misc/rp1/Kconfig
>>>    create mode 100644 drivers/misc/rp1/Makefile
>>>    create mode 100644 drivers/misc/rp1/rp1-pci.c
>>>    create mode 100644 drivers/misc/rp1/rp1-pci.dtso
>>>
>> ...
>>> +
>>> +				rp1_clocks: clocks@c040018000 {
>>> +					compatible = "raspberrypi,rp1-clocks";
>>> +					#clock-cells = <1>;
>>> +					reg = <0xc0 0x40018000 0x0 0x10038>;
>>> +					clocks = <&clk_xosc>;
>>> +					clock-names = "xosc";
>>> +
>>> +					assigned-clocks = <&rp1_clocks RP1_PLL_SYS_CORE>,
>>> +							  <&rp1_clocks RP1_PLL_AUDIO_CORE>,
>>> +							  // RP1_PLL_VIDEO_CORE and dividers are now managed by VEC,DPI drivers
>>> +							  <&rp1_clocks RP1_PLL_SYS>,
>>> +							  <&rp1_clocks RP1_PLL_SYS_SEC>,
>>> +							  <&rp1_clocks RP1_PLL_SYS_PRI_PH>,
>>> +							  <&rp1_clocks RP1_CLK_ETH_TSU>;
>>> +
>>> +					assigned-clock-rates = <1000000000>, // RP1_PLL_SYS_CORE
>>> +							       <1536000000>, // RP1_PLL_AUDIO_CORE
>>> +							       <200000000>,  // RP1_PLL_SYS
>>> +							       <125000000>,  // RP1_PLL_SYS_SEC
>>> +							       <100000000>,  // RP1_PLL_SYS_PRI_PH
>>> +							       <50000000>;   // RP1_CLK_ETH_TSU
>>> +				};
>>> +
>>> +				rp1_gpio: pinctrl@c0400d0000 {
>>> +					reg = <0xc0 0x400d0000  0x0 0xc000>,
>>> +					      <0xc0 0x400e0000  0x0 0xc000>,
>>> +					      <0xc0 0x400f0000  0x0 0xc000>;
>>> +					compatible = "raspberrypi,rp1-gpio";
>>> +					gpio-controller;
>>> +					#gpio-cells = <2>;
>>> +					interrupt-controller;
>>> +					#interrupt-cells = <2>;
>>> +					interrupts = <RP1_INT_IO_BANK0 IRQ_TYPE_LEVEL_HIGH>,
>>> +						     <RP1_INT_IO_BANK1 IRQ_TYPE_LEVEL_HIGH>,
>>> +						     <RP1_INT_IO_BANK2 IRQ_TYPE_LEVEL_HIGH>;
>>> +					gpio-line-names =
>>> +						"ID_SDA", // GPIO0
>>> +						"ID_SCL", // GPIO1
>>> +						"GPIO2", // GPIO2
>>> +						"GPIO3", // GPIO3
>>> +						"GPIO4", // GPIO4
>>> +						"GPIO5", // GPIO5
>>> +						"GPIO6", // GPIO6
>>> +						"GPIO7", // GPIO7
>>> +						"GPIO8", // GPIO8
>>> +						"GPIO9", // GPIO9
>>> +						"GPIO10", // GPIO10
>>> +						"GPIO11", // GPIO11
>>> +						"GPIO12", // GPIO12
>>> +						"GPIO13", // GPIO13
>>> +						"GPIO14", // GPIO14
>>> +						"GPIO15", // GPIO15
>>> +						"GPIO16", // GPIO16
>>> +						"GPIO17", // GPIO17
>>> +						"GPIO18", // GPIO18
>>> +						"GPIO19", // GPIO19
>>> +						"GPIO20", // GPIO20
>>> +						"GPIO21", // GPIO21
>>> +						"GPIO22", // GPIO22
>>> +						"GPIO23", // GPIO23
>>> +						"GPIO24", // GPIO24
>>> +						"GPIO25", // GPIO25
>>> +						"GPIO26", // GPIO26
>>> +						"GPIO27", // GPIO27
>>> +						"PCIE_RP1_WAKE", // GPIO28
>>> +						"FAN_TACH", // GPIO29
>>> +						"HOST_SDA", // GPIO30
>>> +						"HOST_SCL", // GPIO31
>>> +						"ETH_RST_N", // GPIO32
>>> +						"", // GPIO33
>>> +						"CD0_IO0_MICCLK", // GPIO34
>>> +						"CD0_IO0_MICDAT0", // GPIO35
>>> +						"RP1_PCIE_CLKREQ_N", // GPIO36
>>> +						"", // GPIO37
>>> +						"CD0_SDA", // GPIO38
>>> +						"CD0_SCL", // GPIO39
>>> +						"CD1_SDA", // GPIO40
>>> +						"CD1_SCL", // GPIO41
>>> +						"USB_VBUS_EN", // GPIO42
>>> +						"USB_OC_N", // GPIO43
>>> +						"RP1_STAT_LED", // GPIO44
>>> +						"FAN_PWM", // GPIO45
>>> +						"CD1_IO0_MICCLK", // GPIO46
>>> +						"2712_WAKE", // GPIO47
>>> +						"CD1_IO1_MICDAT1", // GPIO48
>>> +						"EN_MAX_USB_CUR", // GPIO49
>>> +						"", // GPIO50
>>> +						"", // GPIO51
>>> +						"", // GPIO52
>>> +						""; // GPIO53
>> GPIO line names are board specific, so this should go to the Raspberry
>> Pi 5 file.
> Could we instead just name them with generic GPIO'N' where N is the number
> of the gpio? Much like many of that pins already are... in this way we
> don't add a dependency in the board dts to the rp1_gpio node, which is not
> even there when the main dts is parsed at boot, since the dtbo will be
> added only on PCI enumeration of the RP1 device.
I think we should avoid user space incompatibilities with the vendor tree.
> Or even better: since we don't explicitly use the gpio names to address
> them (e.g. phy-reset-gpios in rp1_eth node is addressing the ETH_RST_N
> gpio by number), can we just get rid of the gpio-line-names property?
> Also Bootlin's Microchip gpio node seems to avoid naming them...
As i said above the gpio lines are for user space, honestly nobody likes
to go to cryptic interfaces of gpiochips and gpio numbers.

Maybe ETH_RST_N isn't good example because this not interesting from
user space. For example RP1_STAT_LED is a better one. Nobody can predict
the future use cases of the RP1 and its pins. So i think we should have
the flexibilty to specify the GPIOs on the board level for user
friendliness.

Isn't it possible to specify almost empty rp1 node with the gpio line
names for the RPi 5 and apply the rp1 overlay on top?
>
>>> +				};
>>> +			};
>>> +		};
>>> +	};
>>> +};
>>> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
>>> index 41c3d2821a78..02405209e6c4 100644
>>> --- a/drivers/misc/Kconfig
>>> +++ b/drivers/misc/Kconfig
>>> @@ -618,4 +618,5 @@ source "drivers/misc/uacce/Kconfig"
>>>    source "drivers/misc/pvpanic/Kconfig"
>>>    source "drivers/misc/mchp_pci1xxxx/Kconfig"
>>>    source "drivers/misc/keba/Kconfig"
>>> +source "drivers/misc/rp1/Kconfig"
>>>    endmenu
>>> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
>>> index c2f990862d2b..84bfa866fbee 100644
>>> --- a/drivers/misc/Makefile
>>> +++ b/drivers/misc/Makefile
>>> @@ -71,3 +71,4 @@ obj-$(CONFIG_TPS6594_PFSM)	+= tps6594-pfsm.o
>>>    obj-$(CONFIG_NSM)		+= nsm.o
>>>    obj-$(CONFIG_MARVELL_CN10K_DPI)	+= mrvl_cn10k_dpi.o
>>>    obj-y				+= keba/
>>> +obj-$(CONFIG_MISC_RP1)		+= rp1/
>>> diff --git a/drivers/misc/rp1/Kconfig b/drivers/misc/rp1/Kconfig
>>> new file mode 100644
>>> index 000000000000..050417ee09ae
>>> --- /dev/null
>>> +++ b/drivers/misc/rp1/Kconfig
>>> @@ -0,0 +1,20 @@
>>> +# SPDX-License-Identifier: GPL-2.0-only
>>> +#
>>> +# RaspberryPi RP1 misc device
>>> +#
>>> +
>>> +config MISC_RP1
>>> +        tristate "RaspberryPi RP1 PCIe support"
>>> +        depends on PCI && PCI_QUIRKS
>>> +        select OF
>>> +        select OF_OVERLAY
>>> +        select IRQ_DOMAIN
>>> +        select PCI_DYNAMIC_OF_NODES
>>> +        help
>>> +          Support for the RP1 peripheral chip found on Raspberry Pi 5 board.
>>> +          This device supports several sub-devices including e.g. Ethernet controller,
>>> +          USB controller, I2C, SPI and UART.
>>> +          The driver is responsible for enabling the DT node once the PCIe endpoint
>>> +          has been configured, and handling interrupts.
>>> +          This driver uses an overlay to load other drivers to support for RP1
>>> +          internal sub-devices.
>>> diff --git a/drivers/misc/rp1/Makefile b/drivers/misc/rp1/Makefile
>>> new file mode 100644
>>> index 000000000000..e83854b4ed2c
>>> --- /dev/null
>>> +++ b/drivers/misc/rp1/Makefile
>>> @@ -0,0 +1,3 @@
>>> +# SPDX-License-Identifier: GPL-2.0-only
>>> +rp1-pci-objs			:= rp1-pci.o rp1-pci.dtbo.o
>>> +obj-$(CONFIG_MISC_RP1)		+= rp1-pci.o
>>> diff --git a/drivers/misc/rp1/rp1-pci.c b/drivers/misc/rp1/rp1-pci.c
>>> new file mode 100644
>>> index 000000000000..a6093ba7e19a
>>> --- /dev/null
>>> +++ b/drivers/misc/rp1/rp1-pci.c
>>> @@ -0,0 +1,333 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + * Copyright (c) 2018-22 Raspberry Pi Ltd.
>>> + * All rights reserved.
>>> + */
>>> +
>>> +#include <linux/clk.h>
>>> +#include <linux/clkdev.h>
>>> +#include <linux/clk-provider.h>
>>> +#include <linux/err.h>
>>> +#include <linux/interrupt.h>
>>> +#include <linux/irq.h>
>>> +#include <linux/irqchip/chained_irq.h>
>>> +#include <linux/irqdomain.h>
>>> +#include <linux/module.h>
>>> +#include <linux/msi.h>
>>> +#include <linux/of_platform.h>
>>> +#include <linux/pci.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/reset.h>
>>> +
>>> +#include <dt-bindings/misc/rp1.h>
>>> +
>>> +#define RP1_B0_CHIP_ID		0x10001927
>>> +#define RP1_C0_CHIP_ID		0x20001927
>>> +
>>> +#define RP1_PLATFORM_ASIC	BIT(1)
>>> +#define RP1_PLATFORM_FPGA	BIT(0)
>>> +
>>> +#define RP1_DRIVER_NAME		"rp1"
>>> +
>>> +#define RP1_ACTUAL_IRQS		RP1_INT_END
>>> +#define RP1_IRQS		RP1_ACTUAL_IRQS
>>> +#define RP1_HW_IRQ_MASK		GENMASK(5, 0)
>>> +
>>> +#define RP1_SYSCLK_RATE		200000000
>>> +#define RP1_SYSCLK_FPGA_RATE	60000000
>>> +
>>> +enum {
>>> +	SYSINFO_CHIP_ID_OFFSET	= 0,
>>> +	SYSINFO_PLATFORM_OFFSET	= 4,
>>> +};
>>> +
>>> +#define REG_SET			0x800
>>> +#define REG_CLR			0xc00
>>> +
>>> +/* MSIX CFG registers start at 0x8 */
>>> +#define MSIX_CFG(x) (0x8 + (4 * (x)))
>>> +
>>> +#define MSIX_CFG_IACK_EN        BIT(3)
>>> +#define MSIX_CFG_IACK           BIT(2)
>>> +#define MSIX_CFG_TEST           BIT(1)
>>> +#define MSIX_CFG_ENABLE         BIT(0)
>>> +
>>> +#define INTSTATL		0x108
>>> +#define INTSTATH		0x10c
>>> +
>>> +extern char __dtbo_rp1_pci_begin[];
>>> +extern char __dtbo_rp1_pci_end[];
>>> +
>>> +struct rp1_dev {
>>> +	struct pci_dev *pdev;
>>> +	struct device *dev;
>>> +	struct clk *sys_clk;
>>> +	struct irq_domain *domain;
>>> +	struct irq_data *pcie_irqds[64];
>>> +	void __iomem *bar1;
>>> +	int ovcs_id;
>>> +	bool level_triggered_irq[RP1_ACTUAL_IRQS];
>>> +};
>>> +
>>> +
>> ...
>>> +
>>> +static const struct pci_device_id dev_id_table[] = {
>>> +	{ PCI_DEVICE(PCI_VENDOR_ID_RPI, PCI_DEVICE_ID_RP1_C0), },
>>> +	{ 0, }
>>> +};
>>> +
>>> +static struct pci_driver rp1_driver = {
>>> +	.name		= RP1_DRIVER_NAME,
>>> +	.id_table	= dev_id_table,
>>> +	.probe		= rp1_probe,
>>> +	.remove		= rp1_remove,
>>> +};
>>> +
>>> +module_pci_driver(rp1_driver);
>>> +
>>> +MODULE_AUTHOR("Phil Elwell <phil@raspberrypi.com>");
>> Module author & Copyright doesn't seem to match with this patch author.
>> Please clarify/fix
> My intention here is that, even if the code has been heavily modified by me,
> the core original code is still there so I just wanted to tribute it to the
> original author.
> I'll synchronize this with RaspberryPi guys and coem up with a unified solution.
That would be nice to mention in the commit message and add your copyright.
> Just in case: would multiple MODULE_AUTHOR entries (one with my name and one
> with original authors name) be accepetd?
Sure

Best regards
>
> Many thanks,
> Andrea
>
> References:
>
> - [1]: https://lore.kernel.org/all/20240612140208.GC1504919@google.com/
> - [2]: https://lore.kernel.org/all/83f7fa09-d0e6-4f36-a27d-cee08979be2a@app.fastmail.com/
> - [3]: https://lore.kernel.org/all/2024081356-mutable-everyday-6f9d@gregkh/
> - [4]: https://lore.kernel.org/all/ba8cdf39-3ba3-4abc-98f5-d394d6867f95@gmx.net/
> - [5]: https://lpc.events/event/17/contributions/1421/attachments/1337/2680/LPC2023%20Non-discoverable%20devices%20in%20PCI.pdf


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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-23 10:23       ` Stefan Wahren
@ 2024-08-23 16:31         ` Andrea della Porta
  2024-08-30 18:27           ` Rob Herring
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-23 16:31 UTC (permalink / raw)
  To: Stefan Wahren
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn

Hi Stefan,

On 12:23 Fri 23 Aug     , Stefan Wahren wrote:
> Hi Andrea,
> 
> Am 23.08.24 um 11:44 schrieb Andrea della Porta:
> > Hi Stefan,
> > 
> > On 18:20 Wed 21 Aug     , Stefan Wahren wrote:
> > > Hi Andrea,
> > > 
> > > Am 20.08.24 um 16:36 schrieb Andrea della Porta:
> > > > The RaspberryPi RP1 is ia PCI multi function device containing
> > > > peripherals ranging from Ethernet to USB controller, I2C, SPI
> > > > and others.
> > > sorry, i cannot provide you a code review, but just some comments. multi
> > > function device suggests "mfd" subsystem or at least "soc" . I won't
> > > recommend misc driver here.
> > It's true that RP1 can be called an MFD but the reason for not placing
> > it in mfd subsystem are twofold:
> > 
> > - these discussions are quite clear about this matter: please see [1]
> >    and [2]
> > - the current driver use no mfd API at all
> > 
> > This RP1 driver is not currently addressing any aspect of ARM core in the
> > SoC so I would say it should not stay in drivers/soc / either, as also
> > condifirmed by [2] again and [3] (note that Microchip LAN966x is a very
> > close fit to what we have here on RP1).
> thanks i was aware of these discussions. A pointer to them or at least a
> short statement in the cover letter would be great.

Sure, consider it done.

> > 
> > > > Implement a bare minimum driver to operate the RP1, leveraging
> > > > actual OF based driver implementations for the on-borad peripherals
> > > > by loading a devicetree overlay during driver probe.
> > > Can you please explain why this should be a DT overlay? The RP1 is
> > > assembled on the Raspberry Pi 5 PCB. DT overlays are typically for loose
> > > connections like displays or HATs. I think a DTSI just for the RP1 would
> > > fit better and is easier to read.
> > The dtsi solution you proposed is the one adopted downstream. It has its
> > benefits of course, but there's more.
> > With the overlay approach we can achieve more generic and agnostic approach
> > to managing this chipset, being that it is a PCI endpoint and could be
> > possibly be reused in other hw implementations. I believe a similar
> > reasoning could be applied to Bootlin's Microchip LAN966x patchset as
> > well, and they also choose to approach the dtb overlay.
> Could please add this point in the commit message. Doesn't introduce

Ack.

> (maintainence) issues in case U-Boot needs a RP1 driver, too?

Good point. Right now u-boot does not support RP1 nor PCIe (which is a
prerequisite for RP1 to work) on Rpi5 and I'm quite sure that it will be
so in the near future. Of course I cannot guarantee this will be the case
far away in time.

Since u-boot is lacking support for RP1 we cannot really produce some test
results to check the compatibility versus kernel dtb overlay but we can
speculate a little bit about it. AFAIK u-boot would probably place the rp1
node directly under its pcie@12000 node in DT while the dtb overlay will use
dynamically created PCI endpoint node (dev@0) as parent for rp1 node.

I would say it should work out of the box, the only minor drawback here should
be the redundant rp1 node left from u-boot. And maybe some added checks to
make sure the driver will be loaded only once from the dtb overlay and not
from the u-boot node, but this change is locally to the RP1 linux driver code
so it should not impact u-boot in any way.  I'm inclined to consider the last
one a minor issue. 
Please do keep in mind that, of course, this is just brainstorming and I cannot
give 100% guarantee about that.

> > Plus, a solution that can (althoguh proabbly in teh long run) cope
> > with both DT or ACPI based system has been kindly requested, plase see [4]
> > for details.
> > IMHO the approach proposed from RH et al. of using dtbo for this 'special'
> > kind of drivers makes a lot of sense (see [5]).
> > 
> > > > The peripherals are accessed by mapping MMIO registers starting
> > > > from PCI BAR1 region.
> > > > As a minimum driver, the peripherals will not be added to the
> > > > dtbo here, but in following patches.
> > > > 
> > > > Link: https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
> > > > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> > > > ---
> > > >    MAINTAINERS                           |   2 +
> > > >    arch/arm64/boot/dts/broadcom/rp1.dtso | 152 ++++++++++++
> > > >    drivers/misc/Kconfig                  |   1 +
> > > >    drivers/misc/Makefile                 |   1 +
> > > >    drivers/misc/rp1/Kconfig              |  20 ++
> > > >    drivers/misc/rp1/Makefile             |   3 +
> > > >    drivers/misc/rp1/rp1-pci.c            | 333 ++++++++++++++++++++++++++
> > > >    drivers/misc/rp1/rp1-pci.dtso         |   8 +
> > > >    drivers/pci/quirks.c                  |   1 +
> > > >    include/linux/pci_ids.h               |   3 +
> > > >    10 files changed, 524 insertions(+)
> > > >    create mode 100644 arch/arm64/boot/dts/broadcom/rp1.dtso
> > > >    create mode 100644 drivers/misc/rp1/Kconfig
> > > >    create mode 100644 drivers/misc/rp1/Makefile
> > > >    create mode 100644 drivers/misc/rp1/rp1-pci.c
> > > >    create mode 100644 drivers/misc/rp1/rp1-pci.dtso
> > > > 
> > > ...
> > > > +
> > > > +				rp1_clocks: clocks@c040018000 {
> > > > +					compatible = "raspberrypi,rp1-clocks";
> > > > +					#clock-cells = <1>;
> > > > +					reg = <0xc0 0x40018000 0x0 0x10038>;
> > > > +					clocks = <&clk_xosc>;
> > > > +					clock-names = "xosc";
> > > > +
> > > > +					assigned-clocks = <&rp1_clocks RP1_PLL_SYS_CORE>,
> > > > +							  <&rp1_clocks RP1_PLL_AUDIO_CORE>,
> > > > +							  // RP1_PLL_VIDEO_CORE and dividers are now managed by VEC,DPI drivers
> > > > +							  <&rp1_clocks RP1_PLL_SYS>,
> > > > +							  <&rp1_clocks RP1_PLL_SYS_SEC>,
> > > > +							  <&rp1_clocks RP1_PLL_SYS_PRI_PH>,
> > > > +							  <&rp1_clocks RP1_CLK_ETH_TSU>;
> > > > +
> > > > +					assigned-clock-rates = <1000000000>, // RP1_PLL_SYS_CORE
> > > > +							       <1536000000>, // RP1_PLL_AUDIO_CORE
> > > > +							       <200000000>,  // RP1_PLL_SYS
> > > > +							       <125000000>,  // RP1_PLL_SYS_SEC
> > > > +							       <100000000>,  // RP1_PLL_SYS_PRI_PH
> > > > +							       <50000000>;   // RP1_CLK_ETH_TSU
> > > > +				};
> > > > +
> > > > +				rp1_gpio: pinctrl@c0400d0000 {
> > > > +					reg = <0xc0 0x400d0000  0x0 0xc000>,
> > > > +					      <0xc0 0x400e0000  0x0 0xc000>,
> > > > +					      <0xc0 0x400f0000  0x0 0xc000>;
> > > > +					compatible = "raspberrypi,rp1-gpio";
> > > > +					gpio-controller;
> > > > +					#gpio-cells = <2>;
> > > > +					interrupt-controller;
> > > > +					#interrupt-cells = <2>;
> > > > +					interrupts = <RP1_INT_IO_BANK0 IRQ_TYPE_LEVEL_HIGH>,
> > > > +						     <RP1_INT_IO_BANK1 IRQ_TYPE_LEVEL_HIGH>,
> > > > +						     <RP1_INT_IO_BANK2 IRQ_TYPE_LEVEL_HIGH>;
> > > > +					gpio-line-names =
> > > > +						"ID_SDA", // GPIO0
> > > > +						"ID_SCL", // GPIO1
> > > > +						"GPIO2", // GPIO2
> > > > +						"GPIO3", // GPIO3
> > > > +						"GPIO4", // GPIO4
> > > > +						"GPIO5", // GPIO5
> > > > +						"GPIO6", // GPIO6
> > > > +						"GPIO7", // GPIO7
> > > > +						"GPIO8", // GPIO8
> > > > +						"GPIO9", // GPIO9
> > > > +						"GPIO10", // GPIO10
> > > > +						"GPIO11", // GPIO11
> > > > +						"GPIO12", // GPIO12
> > > > +						"GPIO13", // GPIO13
> > > > +						"GPIO14", // GPIO14
> > > > +						"GPIO15", // GPIO15
> > > > +						"GPIO16", // GPIO16
> > > > +						"GPIO17", // GPIO17
> > > > +						"GPIO18", // GPIO18
> > > > +						"GPIO19", // GPIO19
> > > > +						"GPIO20", // GPIO20
> > > > +						"GPIO21", // GPIO21
> > > > +						"GPIO22", // GPIO22
> > > > +						"GPIO23", // GPIO23
> > > > +						"GPIO24", // GPIO24
> > > > +						"GPIO25", // GPIO25
> > > > +						"GPIO26", // GPIO26
> > > > +						"GPIO27", // GPIO27
> > > > +						"PCIE_RP1_WAKE", // GPIO28
> > > > +						"FAN_TACH", // GPIO29
> > > > +						"HOST_SDA", // GPIO30
> > > > +						"HOST_SCL", // GPIO31
> > > > +						"ETH_RST_N", // GPIO32
> > > > +						"", // GPIO33
> > > > +						"CD0_IO0_MICCLK", // GPIO34
> > > > +						"CD0_IO0_MICDAT0", // GPIO35
> > > > +						"RP1_PCIE_CLKREQ_N", // GPIO36
> > > > +						"", // GPIO37
> > > > +						"CD0_SDA", // GPIO38
> > > > +						"CD0_SCL", // GPIO39
> > > > +						"CD1_SDA", // GPIO40
> > > > +						"CD1_SCL", // GPIO41
> > > > +						"USB_VBUS_EN", // GPIO42
> > > > +						"USB_OC_N", // GPIO43
> > > > +						"RP1_STAT_LED", // GPIO44
> > > > +						"FAN_PWM", // GPIO45
> > > > +						"CD1_IO0_MICCLK", // GPIO46
> > > > +						"2712_WAKE", // GPIO47
> > > > +						"CD1_IO1_MICDAT1", // GPIO48
> > > > +						"EN_MAX_USB_CUR", // GPIO49
> > > > +						"", // GPIO50
> > > > +						"", // GPIO51
> > > > +						"", // GPIO52
> > > > +						""; // GPIO53
> > > GPIO line names are board specific, so this should go to the Raspberry
> > > Pi 5 file.
> > Could we instead just name them with generic GPIO'N' where N is the number
> > of the gpio? Much like many of that pins already are... in this way we
> > don't add a dependency in the board dts to the rp1_gpio node, which is not
> > even there when the main dts is parsed at boot, since the dtbo will be
> > added only on PCI enumeration of the RP1 device.
> I think we should avoid user space incompatibilities with the vendor tree.
> > Or even better: since we don't explicitly use the gpio names to address
> > them (e.g. phy-reset-gpios in rp1_eth node is addressing the ETH_RST_N
> > gpio by number), can we just get rid of the gpio-line-names property?
> > Also Bootlin's Microchip gpio node seems to avoid naming them...
> As i said above the gpio lines are for user space, honestly nobody likes
> to go to cryptic interfaces of gpiochips and gpio numbers.
>

You're right.
 
> Maybe ETH_RST_N isn't good example because this not interesting from
> user space. For example RP1_STAT_LED is a better one. Nobody can predict
> the future use cases of the RP1 and its pins. So i think we should have
> the flexibilty to specify the GPIOs on the board level for user
> friendliness.
>

Agreed.
 
> Isn't it possible to specify almost empty rp1 node with the gpio line
> names for the RPi 5 and apply the rp1 overlay on top?

Uhm, we can think of something like that, i.e. a secondary dtbo (populated
with the gpio-line-names property only) to be added after the PCI enumeration
has added the primary dtbo (i.e. the proposed rp1.dtso with gpio-line-names
dropped) into devicetree. This implies loading this second dtbo from either:

- the RP1 driver itself, since it's the one that is dynamically adding
the RP1 node. I would say this is not the cleanest way unless we provide
an elegant way to fed the customized dtbo to teh driver itself, but has
the advantage that it would surely work and has no side effects that
come to mind.

- late at boot, directly from userspace. I see 2 problems here:
1) the gpio driver is already probed by the first dtbo so we should have
   a way to just add teh gpio names to the alredy existing one. Not sure
   how to accomplish that right now.
2) not sure whether how to prepare the dtbo, it should probably have an
   empty target-path since the dt parent tree is created dynamically and
   can be different for each system.

This could be also helpful to customize things like the phy, that is
external to teh ethernet MAC.
I need to do some investigation, but would be helpful if you or others
have some preference/objection on the two approaches above.

> > 
> > > > +				};
> > > > +			};
> > > > +		};
> > > > +	};
> > > > +};
> > > > diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> > > > index 41c3d2821a78..02405209e6c4 100644
> > > > --- a/drivers/misc/Kconfig
> > > > +++ b/drivers/misc/Kconfig
> > > > @@ -618,4 +618,5 @@ source "drivers/misc/uacce/Kconfig"
> > > >    source "drivers/misc/pvpanic/Kconfig"
> > > >    source "drivers/misc/mchp_pci1xxxx/Kconfig"
> > > >    source "drivers/misc/keba/Kconfig"
> > > > +source "drivers/misc/rp1/Kconfig"
> > > >    endmenu
> > > > diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> > > > index c2f990862d2b..84bfa866fbee 100644
> > > > --- a/drivers/misc/Makefile
> > > > +++ b/drivers/misc/Makefile
> > > > @@ -71,3 +71,4 @@ obj-$(CONFIG_TPS6594_PFSM)	+= tps6594-pfsm.o
> > > >    obj-$(CONFIG_NSM)		+= nsm.o
> > > >    obj-$(CONFIG_MARVELL_CN10K_DPI)	+= mrvl_cn10k_dpi.o
> > > >    obj-y				+= keba/
> > > > +obj-$(CONFIG_MISC_RP1)		+= rp1/
> > > > diff --git a/drivers/misc/rp1/Kconfig b/drivers/misc/rp1/Kconfig
> > > > new file mode 100644
> > > > index 000000000000..050417ee09ae
> > > > --- /dev/null
> > > > +++ b/drivers/misc/rp1/Kconfig
> > > > @@ -0,0 +1,20 @@
> > > > +# SPDX-License-Identifier: GPL-2.0-only
> > > > +#
> > > > +# RaspberryPi RP1 misc device
> > > > +#
> > > > +
> > > > +config MISC_RP1
> > > > +        tristate "RaspberryPi RP1 PCIe support"
> > > > +        depends on PCI && PCI_QUIRKS
> > > > +        select OF
> > > > +        select OF_OVERLAY
> > > > +        select IRQ_DOMAIN
> > > > +        select PCI_DYNAMIC_OF_NODES
> > > > +        help
> > > > +          Support for the RP1 peripheral chip found on Raspberry Pi 5 board.
> > > > +          This device supports several sub-devices including e.g. Ethernet controller,
> > > > +          USB controller, I2C, SPI and UART.
> > > > +          The driver is responsible for enabling the DT node once the PCIe endpoint
> > > > +          has been configured, and handling interrupts.
> > > > +          This driver uses an overlay to load other drivers to support for RP1
> > > > +          internal sub-devices.
> > > > diff --git a/drivers/misc/rp1/Makefile b/drivers/misc/rp1/Makefile
> > > > new file mode 100644
> > > > index 000000000000..e83854b4ed2c
> > > > --- /dev/null
> > > > +++ b/drivers/misc/rp1/Makefile
> > > > @@ -0,0 +1,3 @@
> > > > +# SPDX-License-Identifier: GPL-2.0-only
> > > > +rp1-pci-objs			:= rp1-pci.o rp1-pci.dtbo.o
> > > > +obj-$(CONFIG_MISC_RP1)		+= rp1-pci.o
> > > > diff --git a/drivers/misc/rp1/rp1-pci.c b/drivers/misc/rp1/rp1-pci.c
> > > > new file mode 100644
> > > > index 000000000000..a6093ba7e19a
> > > > --- /dev/null
> > > > +++ b/drivers/misc/rp1/rp1-pci.c
> > > > @@ -0,0 +1,333 @@
> > > > +// SPDX-License-Identifier: GPL-2.0
> > > > +/*
> > > > + * Copyright (c) 2018-22 Raspberry Pi Ltd.
> > > > + * All rights reserved.
> > > > + */
> > > > +
> > > > +#include <linux/clk.h>
> > > > +#include <linux/clkdev.h>
> > > > +#include <linux/clk-provider.h>
> > > > +#include <linux/err.h>
> > > > +#include <linux/interrupt.h>
> > > > +#include <linux/irq.h>
> > > > +#include <linux/irqchip/chained_irq.h>
> > > > +#include <linux/irqdomain.h>
> > > > +#include <linux/module.h>
> > > > +#include <linux/msi.h>
> > > > +#include <linux/of_platform.h>
> > > > +#include <linux/pci.h>
> > > > +#include <linux/platform_device.h>
> > > > +#include <linux/reset.h>
> > > > +
> > > > +#include <dt-bindings/misc/rp1.h>
> > > > +
> > > > +#define RP1_B0_CHIP_ID		0x10001927
> > > > +#define RP1_C0_CHIP_ID		0x20001927
> > > > +
> > > > +#define RP1_PLATFORM_ASIC	BIT(1)
> > > > +#define RP1_PLATFORM_FPGA	BIT(0)
> > > > +
> > > > +#define RP1_DRIVER_NAME		"rp1"
> > > > +
> > > > +#define RP1_ACTUAL_IRQS		RP1_INT_END
> > > > +#define RP1_IRQS		RP1_ACTUAL_IRQS
> > > > +#define RP1_HW_IRQ_MASK		GENMASK(5, 0)
> > > > +
> > > > +#define RP1_SYSCLK_RATE		200000000
> > > > +#define RP1_SYSCLK_FPGA_RATE	60000000
> > > > +
> > > > +enum {
> > > > +	SYSINFO_CHIP_ID_OFFSET	= 0,
> > > > +	SYSINFO_PLATFORM_OFFSET	= 4,
> > > > +};
> > > > +
> > > > +#define REG_SET			0x800
> > > > +#define REG_CLR			0xc00
> > > > +
> > > > +/* MSIX CFG registers start at 0x8 */
> > > > +#define MSIX_CFG(x) (0x8 + (4 * (x)))
> > > > +
> > > > +#define MSIX_CFG_IACK_EN        BIT(3)
> > > > +#define MSIX_CFG_IACK           BIT(2)
> > > > +#define MSIX_CFG_TEST           BIT(1)
> > > > +#define MSIX_CFG_ENABLE         BIT(0)
> > > > +
> > > > +#define INTSTATL		0x108
> > > > +#define INTSTATH		0x10c
> > > > +
> > > > +extern char __dtbo_rp1_pci_begin[];
> > > > +extern char __dtbo_rp1_pci_end[];
> > > > +
> > > > +struct rp1_dev {
> > > > +	struct pci_dev *pdev;
> > > > +	struct device *dev;
> > > > +	struct clk *sys_clk;
> > > > +	struct irq_domain *domain;
> > > > +	struct irq_data *pcie_irqds[64];
> > > > +	void __iomem *bar1;
> > > > +	int ovcs_id;
> > > > +	bool level_triggered_irq[RP1_ACTUAL_IRQS];
> > > > +};
> > > > +
> > > > +
> > > ...
> > > > +
> > > > +static const struct pci_device_id dev_id_table[] = {
> > > > +	{ PCI_DEVICE(PCI_VENDOR_ID_RPI, PCI_DEVICE_ID_RP1_C0), },
> > > > +	{ 0, }
> > > > +};
> > > > +
> > > > +static struct pci_driver rp1_driver = {
> > > > +	.name		= RP1_DRIVER_NAME,
> > > > +	.id_table	= dev_id_table,
> > > > +	.probe		= rp1_probe,
> > > > +	.remove		= rp1_remove,
> > > > +};
> > > > +
> > > > +module_pci_driver(rp1_driver);
> > > > +
> > > > +MODULE_AUTHOR("Phil Elwell <phil@raspberrypi.com>");
> > > Module author & Copyright doesn't seem to match with this patch author.
> > > Please clarify/fix
> > My intention here is that, even if the code has been heavily modified by me,
> > the core original code is still there so I just wanted to tribute it to the
> > original author.
> > I'll synchronize this with RaspberryPi guys and coem up with a unified solution.
> That would be nice to mention in the commit message and add your copyright.

Ack.

> > Just in case: would multiple MODULE_AUTHOR entries (one with my name and one
> > with original authors name) be accepetd?
> Sure

Many thanks,

Andrea

> 
> Best regards
> > 
> > Many thanks,
> > Andrea
> > 
> > References:
> > 
> > - [1]: https://lore.kernel.org/all/20240612140208.GC1504919@google.com/
> > - [2]: https://lore.kernel.org/all/83f7fa09-d0e6-4f36-a27d-cee08979be2a@app.fastmail.com/
> > - [3]: https://lore.kernel.org/all/2024081356-mutable-everyday-6f9d@gregkh/
> > - [4]: https://lore.kernel.org/all/ba8cdf39-3ba3-4abc-98f5-d394d6867f95@gmx.net/
> > - [5]: https://lpc.events/event/17/contributions/1421/attachments/1337/2680/LPC2023%20Non-discoverable%20devices%20in%20PCI.pdf
> 

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

* Re: [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support
  2024-08-21 13:27   ` Simon Horman
@ 2024-08-23 17:16     ` Andrea della Porta
  0 siblings, 0 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-08-23 17:16 UTC (permalink / raw)
  To: Simon Horman
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On 14:27 Wed 21 Aug     , Simon Horman wrote:
> On Tue, Aug 20, 2024 at 04:36:09PM +0200, Andrea della Porta wrote:
> > The RP1 is an MFD supporting a gpio controller and /pinmux/pinctrl.
> > Add minimum support for the gpio only portion. The driver is in
> > pinctrl folder since upcoming patches will add the pinmux/pinctrl
> > support where the gpio part can be seen as an addition.
> > 
> > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> 
> ...
> 
> > diff --git a/drivers/pinctrl/pinctrl-rp1.c b/drivers/pinctrl/pinctrl-rp1.c
> 
> ...
> 
> > +const struct rp1_iobank_desc rp1_iobanks[RP1_NUM_BANKS] = {
> > +	/*         gpio   inte    ints     rio    pads */
> > +	{  0, 28, 0x0000, 0x011c, 0x0124, 0x0000, 0x0004 },
> > +	{ 28,  6, 0x4000, 0x411c, 0x4124, 0x4000, 0x4004 },
> > +	{ 34, 20, 0x8000, 0x811c, 0x8124, 0x8000, 0x8004 },
> > +};
> 
> rp1_iobanks seems to only be used in this file.
> If so, it should be static.

Fixed, thanks.

> 
> Flagged by Sparse.
> 
> ...

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

* Re: [PATCH 01/11] dt-bindings: clock: Add RaspberryPi RP1 clock bindings
  2024-08-22 16:23             ` Conor Dooley
@ 2024-08-23 18:21               ` Andrea della Porta
  0 siblings, 0 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-08-23 18:21 UTC (permalink / raw)
  To: Conor Dooley
  Cc: Krzysztof Kozlowski, Andrea della Porta, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Florian Fainelli, Broadcom internal kernel review list,
	Linus Walleij, Catalin Marinas, Will Deacon, Derek Kiernan,
	Dragan Cvetic, Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre,
	Claudiu Beznea, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Saravana Kannan, Bjorn Helgaas, linux-clk,
	devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
	linux-gpio, netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Conor and Krzysztof,

On 17:23 Thu 22 Aug     , Conor Dooley wrote:
> On Thu, Aug 22, 2024 at 11:52:27AM +0200, Krzysztof Kozlowski wrote:
> 
> > >>>>> +examples:
> > >>>>> +  - |
> > >>>>> +    #include <dt-bindings/clock/rp1.h>
> > >>>>> +
> > >>>>> +    rp1 {
> > >>>>> +        #address-cells = <2>;
> > >>>>> +        #size-cells = <2>;
> > >>>>> +
> > >>>>> +        rp1_clocks: clocks@18000 {
> > >>>>
> > >>>> The unit address does not match the reg property. I'm surprised that
> > >>>> dtc doesn't complain about that.
> > >>>
> > >>> Agreed. I'll update the address with the reg value in the next release
> > >>>
> > >>>>
> > >>>>> +            compatible = "raspberrypi,rp1-clocks";
> > >>>>> +            reg = <0xc0 0x40018000 0x0 0x10038>;
> > >>>>
> > >>>> This is a rather oddly specific size. It leads me to wonder if this
> > >>>> region is inside some sort of syscon area?
> > >>>
> > >>> >From downstream source code and RP1 datasheet it seems that the last addressable
> > >>> register is at 0xc040028014 while the range exposed through teh devicetree ends
> > >>> up at 0xc040028038, so it seems more of a little safe margin. I wouldn't say it
> > >>> is a syscon area since those register are quite specific for video clock
> > >>> generation and not to be intended to be shared among different peripherals.
> > >>> Anyway, the next register aperture is at 0xc040030000 so I would say we can 
> > >>> extend the clock mapped register like the following:
> > >>>
> > >>> reg = <0xc0 0x40018000 0x0 0x18000>;
> > >>>
> > >>> if you think it is more readable.
> > >>
> > >> I don't care
> > > 
> > > Ack.
> > > 
> > >>>>> +            #clock-cells = <1>;
> > >>>>> +            clocks = <&clk_xosc>;
> > >>>>> +
> > >>>>> +            assigned-clocks = <&rp1_clocks RP1_PLL_SYS_CORE>,
> > >>>
> > >>>> FWIW, I don't think any of these assigned clocks are helpful for the
> > >>>> example. That said, why do you need to configure all of these assigned
> > >>>> clocks via devicetree when this node is the provider of them?
> > >>>
> > >>> Not sure to understand what you mean here, the example is there just to
> > >>> show how to compile the dt node, maybe you're referring to the fact that
> > >>> the consumer should setup the clock freq?
> > >>
> > >> I suppose, yeah. I don't think a particular configuration is relevant
> > >> for the example binding, but simultaneously don't get why you are
> > >> assigning the rate for clocks used by audio devices or ethernet in the
> > >> clock provider node.
> > >>
> > > 
> > > Honestly I don't have a strong preference here, I can manage to do some tests
> > > moving the clock rate settings inside the consumer nodes but I kinda like
> > > the curernt idea of a centralized node where clocks are setup beforehand.
> > > In RP1 the clock generator and peripherals such as ethernet are all on-board
> > > and cannot be rewired in any other way so the devices are not standalone
> > > consumer in their own right (such it would be an ethernet chip wired to an
> > > external CPU). But of course this is debatable, on the other hand the current
> > > approach of provider/consumer is of course very clean. I'm just wondering
> > > wthether you think I should take action on this or we can leave it as it is.
> > > Please see also below.
> > > 
> > >>> Consider that the rp1-clocks
> > >>> is coupled to the peripherals contained in the same RP1 chip so there is
> > >>> not much point in letting the peripherals set the clock to their leisure.
> > >>
> > >> How is that any different to the many other SoCs in the kernel?
> > > 
> > > In fact, it isn't. Please take a look at:
> > >  
> > > arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi
> > > arch/arm/boot/dts/ti/omap/omap44xx-clocks.dtsi
> > > arch/arm/boot/dts/ti/omap/dra7xx-clocks.dtsi
> > > arch/arm/boot/dts/nxp/imx/imx7d-zii-rpu2.dts
> > > 
> > > and probably many others... they use the same approach, so I assumed it is at
> > > least reasonable to assign the clock rate this way.
> > 
> > Please do not bring some ancient DTS, not really worked on, as example.
> > stm32 could is moderately recent but dra and omap are not.
> 
> Right, there may be some examples like this, but there are many many
> other SoCs where clocks are also not re-wireable, that do not. To me
> this line of argument is akin to the clock driver calling enable on all
> of the clocks because "all of the peripherals are always on the SoC".
> The peripheral is the actual consumer of the clock that quote-unquote
> wants the particular rate, not the clock provider, so having the rate
> assignments in the consumers is the only thing that makes sense to me.
> 
> 

I'll try to cook something that move the rate definition to the consumer
side, then.

Many thanks,
Andrea

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-20 14:36 ` [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver Andrea della Porta
                     ` (5 preceding siblings ...)
  2024-08-21 17:56   ` kernel test robot
@ 2024-08-24  1:53   ` Greg Kroah-Hartman
  2024-08-26  9:07     ` Andrea della Porta
  6 siblings, 1 reply; 117+ messages in thread
From: Greg Kroah-Hartman @ 2024-08-24  1:53 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Nicolas Ferre, Claudiu Beznea, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Saravana Kannan,
	Bjorn Helgaas, linux-clk, devicetree, linux-rpi-kernel,
	linux-arm-kernel, linux-kernel, linux-gpio, netdev, linux-pci,
	linux-arch, Lee Jones, Andrew Lunn, Stefan Wahren

On Tue, Aug 20, 2024 at 04:36:10PM +0200, Andrea della Porta wrote:
> --- a/include/linux/pci_ids.h
> +++ b/include/linux/pci_ids.h
> @@ -2610,6 +2610,9 @@
>  #define PCI_VENDOR_ID_TEKRAM		0x1de1
>  #define PCI_DEVICE_ID_TEKRAM_DC290	0xdc29
>  
> +#define PCI_VENDOR_ID_RPI		0x1de4
> +#define PCI_DEVICE_ID_RP1_C0		0x0001

Minor thing, but please read the top of this file.  As you aren't using
these values anywhere outside of this one driver, there's no need to add
these values to pci_ids.h.  Just keep them local to the .c file itself.

thanks,

greg k-h

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

* Re: [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support
  2024-08-20 14:36 ` [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support Andrea della Porta
                     ` (4 preceding siblings ...)
  2024-08-21 20:51   ` kernel test robot
@ 2024-08-26  8:59   ` Linus Walleij
  2024-08-28 15:24     ` Andrea della Porta
  5 siblings, 1 reply; 117+ messages in thread
From: Linus Walleij @ 2024-08-26  8:59 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Catalin Marinas,
	Will Deacon, Derek Kiernan, Dragan Cvetic, Arnd Bergmann,
	Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Andrea,

thanks for your patch!

On Tue, Aug 20, 2024 at 4:36 PM Andrea della Porta
<andrea.porta@suse.com> wrote:

> The RP1 is an MFD supporting a gpio controller and /pinmux/pinctrl.
> Add minimum support for the gpio only portion. The driver is in
> pinctrl folder since upcoming patches will add the pinmux/pinctrl
> support where the gpio part can be seen as an addition.
>
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
(...)

> +#include <linux/bitmap.h>
> +#include <linux/bitops.h>
(...)

> +static void rp1_pad_update(struct rp1_pin_info *pin, u32 clr, u32 set)
> +{
> +       u32 padctrl = readl(pin->pad);
> +
> +       padctrl &= ~clr;
> +       padctrl |= set;
> +
> +       writel(padctrl, pin->pad);
> +}

Looks a bit like a reimplementation of regmap-mmio? If you want to do
this why not use regmap-mmio?

> +static void rp1_set_dir(struct rp1_pin_info *pin, bool is_input)
> +{
> +       int offset = is_input ? RP1_CLR_OFFSET : RP1_SET_OFFSET;
> +
> +       writel(1 << pin->offset, pin->rio + RP1_RIO_OE + offset);

If you include bitops.h what about:

writel(BIT(pin->offset), pin->rio + RP1_RIO_OE + offset);

> +static int rp1_get_value(struct rp1_pin_info *pin)
> +{
> +       return !!(readl(pin->rio + RP1_RIO_IN) & (1 << pin->offset));
> +}

Also here

> +
> +static void rp1_set_value(struct rp1_pin_info *pin, int value)
> +{
> +       /* Assume the pin is already an output */
> +       writel(1 << pin->offset,
> +              pin->rio + RP1_RIO_OUT + (value ? RP1_SET_OFFSET : RP1_CLR_OFFSET));
> +}

And here

> +static int rp1_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
> +                              unsigned long config)
> +{
> +       struct rp1_pin_info *pin = rp1_get_pin(chip, offset);
> +       unsigned long configs[] = { config };
> +
> +       return rp1_pinconf_set(pin, offset, configs,
> +                              ARRAY_SIZE(configs));
> +}

Nice that you implement this!

> +static void rp1_gpio_irq_config(struct rp1_pin_info *pin, bool enable)
> +{
> +       writel(1 << pin->offset,
> +              pin->inte + (enable ? RP1_SET_OFFSET : RP1_CLR_OFFSET));

BIT()

Yours,
Linus Walleij

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-24  1:53   ` Greg Kroah-Hartman
@ 2024-08-26  9:07     ` Andrea della Porta
  2024-08-26  9:18       ` Greg Kroah-Hartman
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-26  9:07 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Nicolas Ferre, Claudiu Beznea, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Saravana Kannan,
	Bjorn Helgaas, linux-clk, devicetree, linux-rpi-kernel,
	linux-arm-kernel, linux-kernel, linux-gpio, netdev, linux-pci,
	linux-arch, Lee Jones, Andrew Lunn, Stefan Wahren

Hi Greg,

On 09:53 Sat 24 Aug     , Greg Kroah-Hartman wrote:
> On Tue, Aug 20, 2024 at 04:36:10PM +0200, Andrea della Porta wrote:
> > --- a/include/linux/pci_ids.h
> > +++ b/include/linux/pci_ids.h
> > @@ -2610,6 +2610,9 @@
> >  #define PCI_VENDOR_ID_TEKRAM		0x1de1
> >  #define PCI_DEVICE_ID_TEKRAM_DC290	0xdc29
> >  
> > +#define PCI_VENDOR_ID_RPI		0x1de4
> > +#define PCI_DEVICE_ID_RP1_C0		0x0001
> 
> Minor thing, but please read the top of this file.  As you aren't using
> these values anywhere outside of this one driver, there's no need to add
> these values to pci_ids.h.  Just keep them local to the .c file itself.
>

Thanks, I've read the top part of that file. The reason I've declared those
two macroes in pci_ids.h is that I'm using them both in the
main driver (rp1-pci.c) and in drivers/pci/quirks.c.

I suppose I could move DECLARE_PCI_FIXUP_FINAL() inside rp1-pci.c to keep
those two defines local, but judging from the number of entries of
DECLARE_PCI_FIXP_FINAL found in quirks.c versus the occurences found in
respective driver, I assumed the preferred way was to place it in quirks.c.

Many thanks,
Andrea

 
> thanks,
> 
> greg k-h

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-26  9:07     ` Andrea della Porta
@ 2024-08-26  9:18       ` Greg Kroah-Hartman
  0 siblings, 0 replies; 117+ messages in thread
From: Greg Kroah-Hartman @ 2024-08-26  9:18 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Nicolas Ferre, Claudiu Beznea, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Saravana Kannan,
	Bjorn Helgaas, linux-clk, devicetree, linux-rpi-kernel,
	linux-arm-kernel, linux-kernel, linux-gpio, netdev, linux-pci,
	linux-arch, Lee Jones, Andrew Lunn, Stefan Wahren

On Mon, Aug 26, 2024 at 11:07:33AM +0200, Andrea della Porta wrote:
> Hi Greg,
> 
> On 09:53 Sat 24 Aug     , Greg Kroah-Hartman wrote:
> > On Tue, Aug 20, 2024 at 04:36:10PM +0200, Andrea della Porta wrote:
> > > --- a/include/linux/pci_ids.h
> > > +++ b/include/linux/pci_ids.h
> > > @@ -2610,6 +2610,9 @@
> > >  #define PCI_VENDOR_ID_TEKRAM		0x1de1
> > >  #define PCI_DEVICE_ID_TEKRAM_DC290	0xdc29
> > >  
> > > +#define PCI_VENDOR_ID_RPI		0x1de4
> > > +#define PCI_DEVICE_ID_RP1_C0		0x0001
> > 
> > Minor thing, but please read the top of this file.  As you aren't using
> > these values anywhere outside of this one driver, there's no need to add
> > these values to pci_ids.h.  Just keep them local to the .c file itself.
> >
> 
> Thanks, I've read the top part of that file. The reason I've declared those
> two macroes in pci_ids.h is that I'm using them both in the
> main driver (rp1-pci.c) and in drivers/pci/quirks.c.

Ah, missed that, sorry, nevermind.

greg k-h

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

* Re: [PATCH 03/11] PCI: of_property: Sanitize 32 bit PCI address parsed from DT
  2024-08-21 15:24   ` Bjorn Helgaas
@ 2024-08-26 19:51     ` Andrea della Porta
  2024-09-03 22:26       ` Bjorn Helgaas
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-26 19:51 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Bjorn,

On 10:24 Wed 21 Aug     , Bjorn Helgaas wrote:
> On Tue, Aug 20, 2024 at 04:36:05PM +0200, Andrea della Porta wrote:
> > The of_pci_set_address() function parse devicetree PCI range specifier
> 
> s/parse/parses/ ? 

Ack.

> 
> > assuming the address is 'sanitized' at the origin, i.e. without checking
> > whether the incoming address is 32 or 64 bit has specified in the flags.
> > In this way an address with no OF_PCI_ADDR_SPACE_MEM64 set in the flagss
> 
> s/flagss/flags/

Ack.

> 
> > could leak through and the upper 32 bits of the address will be set too,
> > and this violates the PCI specs stating that ion 32 bit address the upper
> 
> s/ion/in/

Ack.

> 
> > bit should be zero.
> 
> I don't understand this code, so I'm probably missing something.  It
> looks like the interesting path here is:
> 
>   of_pci_prop_ranges
>     res = &pdev->resource[...];
>     for (j = 0; j < num; j++) {
>       val64 = res[j].start;
>       of_pci_set_address(..., val64, 0, flags, false);
>  +      if (OF_PCI_ADDR_SPACE_MEM64)
>  +        prop[1] = upper_32_bits(val64);
>  +      else
>  +        prop[1] = 0;
> 
> OF_PCI_ADDR_SPACE_MEM64 tells us about the size of the PCI bus
> address, but the address (val64) is a CPU physical address, not a PCI
> bus address, so I don't understand why of_pci_set_address() should use
> OF_PCI_ADDR_SPACE_MEM64 to clear part of the CPU address.
>

It all starts from of_pci_prop_ranges(), that is the caller of of_pci_set_address().
val64 (i.e. res[j].start) is the address part of a struct resource that has
its own flags.  Those flags are directly translated to of_pci_range flags by
of_pci_get_addr_flags(), so any IORESOURCE_MEM_64 / IORESOURCE_MEM in the
resource flag will respectively become OF_PCI_ADDR_SPACE_MEM64 / OF_PCI_ADDR_SPACE_MEM32
in pci range.
What is advertised as 32 bit at the origin (val64) should not become a 64
bit PCI address at the output of of_pci_set_address(), so the upper 32 bit
portion should be dropped. 
This is explicitly stated in [1] (see page 5), where a space code of 0b10
implies that the upper 32 bit of the address must be zeroed out.
Please note that of_pci_prop_ranges() will be called only in case 
CONFIG_PCI_DYNAMIC_OF_NODES is enabled to populate ranges for pci bridges and
pci endpoint for which a quirk is declared, so I would say not a very
often recurring use case.
 
[1] - https://www.devicetree.org/open-firmware/bindings/pci/pci2_1.pdf

> Add blank lines between paragraphs.

Ack.

> 
> > This could cause mapping translation mismatch on PCI devices (e.g. RP1)
> > that are expected to be addressed with a 64 bit address while advertising
> > a 32 bit address in the PCI config region.
> > Add a check in of_pci_set_address() to set upper 32 bits to zero in case
> > the address has no 64 bit flag set.
> 
> Is this an indication of a DT error?  Have you seen this cause a
> problem?  If so, what does it look like to a user?  I.e., how could a
> user find this patch if they saw a problem?

Not neccessarily a DT error, but an inconsistent representation of addresses
wrt the specs. I incidentally encountered this on RaspberryPi 5, where
the PCI config space for the RP1 endpoint shows 32 bit BARs (basically an
offset from zero) but the effective address to which the CPU can access the
device is 64 bit nonetheless (0x1f_00000000).  I believe this is backed by
some non standard hw wiring.

Without this patch the range translation chain is broken, like this:

pcie@120000: <0x2000000 0x00 0x00    0x1f 0x00                0x00 0xfffffffc>;
~~~ chain breaks here ~~~
pci@0      : <0x82000000 0x1f 0x00   0x82000000 0x1f 0x00     0x00 0x600000>;
dev@0,0    : <0x01 0x00 0x00         0x82010000 0x1f 0x00     0x00 0x400000>;
rp1@0      : <0xc0 0x40000000        0x01 0x00 0x00           0x00 0x400000>;

while with the patch applied the chain correctly become:

pcie@120000: <0x2000000 0x00 0x00    0x1f 0x00                0x00 0xfffffffc>;
pci@0      : <0x82000000 0x00 0x00   0x82000000 0x00 0x00     0x00 0x600000>;
dev@0,0    : <0x01 0x00 0x00         0x82010000 0x00 0x00     0x00 0x400000>;
rp1@0      : <0xc0 0x40000000        0x01 0x00 0x00           0x00 0x400000>;

I'm not advocating here that this patch is fixing the behaviour on Rpi5, this
is just a nice side effect of the correct address representation. I think we can
also probably fix it by patching the pcie node in the devicetree like this:

pcie@120000: <0x2000000 0xi1f 0x00    0x1f 0x00                0x00 0xfffffffc>;

but this is of course just a 1:1 mapping, while the address will still be at
least 'virtually' unconsistent, showing 64 bit address wihile the 32 bit flag is
set.
The net symptoms to the user would be, in the case of the RP1, a platform driver
of one of its sub-peripheral that fails to be probed.

Many thanks,
Andrea

> 
> > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> > ---
> >  drivers/pci/of_property.c | 5 ++++-
> >  1 file changed, 4 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/pci/of_property.c b/drivers/pci/of_property.c
> > index 5a0b98e69795..77865facdb4a 100644
> > --- a/drivers/pci/of_property.c
> > +++ b/drivers/pci/of_property.c
> > @@ -60,7 +60,10 @@ static void of_pci_set_address(struct pci_dev *pdev, u32 *prop, u64 addr,
> >  	prop[0] |= flags | reg_num;
> >  	if (!reloc) {
> >  		prop[0] |= OF_PCI_ADDR_FIELD_NONRELOC;
> > -		prop[1] = upper_32_bits(addr);
> > +		if (FIELD_GET(OF_PCI_ADDR_FIELD_SS, flags) == OF_PCI_ADDR_SPACE_MEM64)
> > +			prop[1] = upper_32_bits(addr);
> > +		else
> > +			prop[1] = 0;
> >  		prop[2] = lower_32_bits(addr);
> >  	}
> >  }
> > -- 
> > 2.35.3
> > 

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

* Re: [PATCH 10/11] net: macb: Add support for RP1's MACB variant
  2024-08-21 17:01   ` Florian Fainelli
@ 2024-08-26 20:03     ` Andrea della Porta
  0 siblings, 0 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-08-26 20:03 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Florian,

On 10:01 Wed 21 Aug     , Florian Fainelli wrote:
> On 8/20/24 07:36, Andrea della Porta wrote:
> > RaspberryPi RP1 contains Cadence's MACB core. Implement the
> > changes to be able to operate the customization in the RP1.
> > 
> > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> 
> You are doing a lot of things, all at once, and you should consider
> extracting your change into a smaller subset with bug fixes first:
> 
> - one commit which writes to the RBQPH the upper 32-bits of the RX ring DMA
> address, that looks like a bug fix
> 
> - one commit which retriggers a buffer read, even though that appears to be
> RP1 specific maybe, if not, then this is also a bug fix
> 
> - one commit that adds support for macb_shutdown() to kill DMA operations
> 
> - one commit which adds support for a configurable PHY reset line + delay
> specified in milli seconds
> 
> - one commit which adds support for controling the interrupt coalescing
> settings
> 
> And then you can add all of the RP1 specific bits like the AXI bridge
> configuration.
> 
> [snip]
> 
> > @@ -1228,6 +1246,7 @@ struct macb_queue {
> >   	dma_addr_t		tx_ring_dma;
> >   	struct work_struct	tx_error_task;
> >   	bool			txubr_pending;
> > +	bool			tx_pending;
> >   	struct napi_struct	napi_tx;
> >   	dma_addr_t		rx_ring_dma;
> > @@ -1293,9 +1312,15 @@ struct macb {
> >   	u32			caps;
> >   	unsigned int		dma_burst_length;
> > +	u8			aw2w_max_pipe;
> > +	u8			ar2r_max_pipe;
> > +	bool			use_aw2b_fill;
> >   	phy_interface_t		phy_interface;
> > +	struct gpio_desc	*phy_reset_gpio;
> > +	int			phy_reset_ms;
> 
> The delay cannot be negative, so this needs to be unsigned int.
> 
> > +
> >   	/* AT91RM9200 transmit queue (1 on wire + 1 queued) */
> >   	struct macb_tx_skb	rm9200_txq[2];
> >   	unsigned int		max_tx_length;
> > diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
> > index 11665be3a22c..5eb5be6c96fc 100644
> > --- a/drivers/net/ethernet/cadence/macb_main.c
> > +++ b/drivers/net/ethernet/cadence/macb_main.c
> > @@ -41,6 +41,9 @@
> >   #include <linux/inetdevice.h>
> >   #include "macb.h"
> > +static unsigned int txdelay = 35;
> > +module_param(txdelay, uint, 0644);
> > +
> >   /* This structure is only used for MACB on SiFive FU540 devices */
> >   struct sifive_fu540_macb_mgmt {
> >   	void __iomem *reg;
> > @@ -334,7 +337,7 @@ static int macb_mdio_wait_for_idle(struct macb *bp)
> >   	u32 val;
> >   	return readx_poll_timeout(MACB_READ_NSR, bp, val, val & MACB_BIT(IDLE),
> > -				  1, MACB_MDIO_TIMEOUT);
> > +				  100, MACB_MDIO_TIMEOUT);
> 
> Why do we need to increase how frequently we poll?

Thanks for your feedback, I will save all your precious suggestions for a future patch that
will enable the macb ethernet.
As stated in the cover letter, right now this specific patch is not intended to be upstreamed
as is but it's just here for testing purposes, hence its 'raw' state.
For sure the ethernet contained in RP1 will be one of the first device I will try to bring
upstream, so I'll apply your comments there. Maybe the next time I will also add a better
explanation about the state of a specific patch in the commit comment itself, and not only
in the cover letter, just to be more explicit.

Many thanks,
Andrea 

> -- 
> Florian
> 

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

* Re: [PATCH 11/11] arm64: dts: rp1: Add support for MACB contained in RP1
  2024-08-21 17:02   ` Florian Fainelli
@ 2024-08-26 20:18     ` Andrea della Porta
  0 siblings, 0 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-08-26 20:18 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Florian,

On 10:02 Wed 21 Aug     , Florian Fainelli wrote:
> On 8/20/24 07:36, Andrea della Porta wrote:
> > RaspberryPi RP1 is multi function PCI endpoint device that
> > exposes several subperipherals via PCI BAR.
> > Add an ethernet node for Cadence MACB to the RP1 dtso
> > 
> > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> > ---
> >   arch/arm64/boot/dts/broadcom/rp1.dtso | 23 +++++++++++++++++++++++
> >   1 file changed, 23 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/broadcom/rp1.dtso b/arch/arm64/boot/dts/broadcom/rp1.dtso
> > index d80178a278ee..b40e203c28d5 100644
> > --- a/arch/arm64/boot/dts/broadcom/rp1.dtso
> > +++ b/arch/arm64/boot/dts/broadcom/rp1.dtso
> > @@ -78,6 +78,29 @@ rp1_clocks: clocks@c040018000 {
> >   							       <50000000>;   // RP1_CLK_ETH_TSU
> >   				};
> > +				rp1_eth: ethernet@c040100000 {
> > +					reg = <0xc0 0x40100000  0x0 0x4000>;
> > +					compatible = "cdns,macb";
> > +					#address-cells = <1>;
> > +					#size-cells = <0>;
> > +					interrupts = <RP1_INT_ETH IRQ_TYPE_LEVEL_HIGH>;
> > +					clocks = <&macb_pclk &macb_hclk &rp1_clocks RP1_CLK_ETH_TSU>;
> > +					clock-names = "pclk", "hclk", "tsu_clk";
> > +					phy-mode = "rgmii-id";
> > +					cdns,aw2w-max-pipe = /bits/ 8 <8>;
> > +					cdns,ar2r-max-pipe = /bits/ 8 <8>;
> > +					cdns,use-aw2b-fill;
> > +					local-mac-address = [00 00 00 00 00 00];
> > +					phy-handle = <&phy1>;
> > +					phy-reset-gpios = <&rp1_gpio 32 GPIO_ACTIVE_LOW>;
> > +					phy-reset-duration = <5>;
> > +
> > +					phy1: ethernet-phy@1 {
> > +						reg = <0x1>;
> > +						brcm,powerdown-enable;
> 
> Undocumented property, and I would like to understand why this needs to be
> specified in the Device Tree? What model of Broadcom Ethernet PHY is being
> used here?

It's a Broadcom BCM5421 transceiver, and that property is intended to support
the optional link-down powersave from DT. It will require slight changes in
drivers/net/phy/broadcom.c too and is not really necessary for minimal support,
so I will drop it in the next iteration.

Many thanks,
Andrea

> -- 
> Florian
> 

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

* Re: [PATCH 04/11] of: address: Preserve the flags portion on 1:1 dma-ranges mapping
  2024-08-21  8:18     ` Andrea della Porta
@ 2024-08-26 21:29       ` Rob Herring
  2024-08-29 10:13         ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Rob Herring @ 2024-08-26 21:29 UTC (permalink / raw)
  To: Rob Herring, Andrea della Porta, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On Wed, Aug 21, 2024 at 3:19 AM Andrea della Porta
<andrea.porta@suse.com> wrote:
>
> Hi Rob,
>
> On 19:16 Tue 20 Aug     , Rob Herring wrote:
> > On Tue, Aug 20, 2024 at 04:36:06PM +0200, Andrea della Porta wrote:
> > > A missing or empty dma-ranges in a DT node implies a 1:1 mapping for dma
> > > translations. In this specific case, rhe current behaviour is to zero out
> >
> > typo
>
> Fixed, thanks!
>
> >
> > > the entire specifier so that the translation could be carried on as an
> > > offset from zero.  This includes address specifier that has flags (e.g.
> > > PCI ranges).
> > > Once the flags portion has been zeroed, the translation chain is broken
> > > since the mapping functions will check the upcoming address specifier
> >
> > What does "upcoming address" mean?
>
> Sorry for the confusion, this means "address specifier (with valid flags) fed
> to the translating functions and for which we are looking for a translation".
> While this address has some valid flags set, it will fail the translation step
> since the ranges it is matched against have flags zeroed out by the 1:1 mapping
> condition.
>
> >
> > > against mismatching flags, always failing the 1:1 mapping and its entire
> > > purpose of always succeeding.
> > > Set to zero only the address portion while passing the flags through.
> >
> > Can you point me to what the failing DT looks like. I'm puzzled how
> > things would have worked for anyone.
> >
>
> The following is a simplified and lightly edited) version of the resulting DT
> from RPi5:
>
>  pci@0,0 {
>         #address-cells = <0x03>;
>         #size-cells = <0x02>;
>         ......
>         device_type = "pci";
>         compatible = "pci14e4,2712\0pciclass,060400\0pciclass,0604";
>         ranges = <0x82000000 0x00 0x00   0x82000000 0x00 0x00   0x00 0x600000>;
>         reg = <0x00 0x00 0x00   0x00 0x00>;
>
>         ......
>
>         rp1@0 {

What does 0 represent here? There's no 0 address in 'ranges' below.
Since you said the parent is a PCI-PCI bridge, then the unit-address
would have to be the PCI devfn and you are missing 'reg' (or omitted
it).

>                 #address-cells = <0x02>;
>                 #size-cells = <0x02>;
>                 compatible = "simple-bus";

The parent is a PCI-PCI bridge. Child nodes have to be PCI devices and
"simple-bus" is not a PCI device.

The assumption so far with all of this is that you have some specific
PCI device (and therefore a driver). The simple-buses under it are
defined per BAR. Not really certain if that makes sense in all cases,
but since the address assignment is dynamic, it may have to. I'm also
not completely convinced we should reuse 'simple-bus' here or define
something specific like 'pci-bar-bus' or something.

>                 ranges = <0xc0 0x40000000   0x01 0x00 0x00   0x00 0x400000>;
>                 dma-ranges = <0x10 0x00   0x43000000 0x10 0x00   0x10 0x00>;
>                 ......
>         };
>  };
>
> The pci@0,0 bridge node is automatically created by virtue of
> CONFIG_PCI_DYNAMIC_OF_NODES, and has no dma-ranges, hence it implies 1:1 dma
> mappings (flags for this mapping are set to zero).  The rp1@0 node has
> dma-ranges with flags set (0x43000000). Since 0x43000000 != 0x00 any translation
> will fail.

It's possible that we should fill in 'dma-ranges' when making these
nodes rather than supporting missing dma-ranges here.

Rob

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

* Re: [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support
  2024-08-26  8:59   ` Linus Walleij
@ 2024-08-28 15:24     ` Andrea della Porta
  2024-09-02  8:31       ` Linus Walleij
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-28 15:24 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Catalin Marinas,
	Will Deacon, Derek Kiernan, Dragan Cvetic, Arnd Bergmann,
	Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Linus,

On 10:59 Mon 26 Aug     , Linus Walleij wrote:
> Hi Andrea,
> 
> thanks for your patch!

Thanks for your review!

> 
> On Tue, Aug 20, 2024 at 4:36 PM Andrea della Porta
> <andrea.porta@suse.com> wrote:
> 
> > The RP1 is an MFD supporting a gpio controller and /pinmux/pinctrl.
> > Add minimum support for the gpio only portion. The driver is in
> > pinctrl folder since upcoming patches will add the pinmux/pinctrl
> > support where the gpio part can be seen as an addition.
> >
> > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> (...)
> 
> > +#include <linux/bitmap.h>
> > +#include <linux/bitops.h>
> (...)
> 
> > +static void rp1_pad_update(struct rp1_pin_info *pin, u32 clr, u32 set)
> > +{
> > +       u32 padctrl = readl(pin->pad);
> > +
> > +       padctrl &= ~clr;
> > +       padctrl |= set;
> > +
> > +       writel(padctrl, pin->pad);
> > +}
> 
> Looks a bit like a reimplementation of regmap-mmio? If you want to do
> this why not use regmap-mmio?

Agreed. I can leverage regmail_field to get rid of the reimplemented code
for the pin->pad register region. Do you think it could be worth using
regmap-mmio also on pin->gpio, pin->inte, pin->ints and pin->rio even
though they are not doing any special field manipulation as the pin->pad
case? 

> 
> > +static void rp1_set_dir(struct rp1_pin_info *pin, bool is_input)
> > +{
> > +       int offset = is_input ? RP1_CLR_OFFSET : RP1_SET_OFFSET;
> > +
> > +       writel(1 << pin->offset, pin->rio + RP1_RIO_OE + offset);
> 
> If you include bitops.h what about:
> 
> writel(BIT(pin->offset), pin->rio + RP1_RIO_OE + offset);

Ack.

> 
> > +static int rp1_get_value(struct rp1_pin_info *pin)
> > +{
> > +       return !!(readl(pin->rio + RP1_RIO_IN) & (1 << pin->offset));
> > +}
> 
> Also here

Ack.

> 
> > +
> > +static void rp1_set_value(struct rp1_pin_info *pin, int value)
> > +{
> > +       /* Assume the pin is already an output */
> > +       writel(1 << pin->offset,
> > +              pin->rio + RP1_RIO_OUT + (value ? RP1_SET_OFFSET : RP1_CLR_OFFSET));
> > +}
> 
> And here

Ack.

> 
> > +static int rp1_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
> > +                              unsigned long config)
> > +{
> > +       struct rp1_pin_info *pin = rp1_get_pin(chip, offset);
> > +       unsigned long configs[] = { config };
> > +
> > +       return rp1_pinconf_set(pin, offset, configs,
> > +                              ARRAY_SIZE(configs));
> > +}
> 
> Nice that you implement this!

Thanks :)

> 
> > +static void rp1_gpio_irq_config(struct rp1_pin_info *pin, bool enable)
> > +{
> > +       writel(1 << pin->offset,
> > +              pin->inte + (enable ? RP1_SET_OFFSET : RP1_CLR_OFFSET));
> 
> BIT()

Ack.

Many thanks,
Andrea

> 
> Yours,
> Linus Walleij

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

* Re: [PATCH 04/11] of: address: Preserve the flags portion on 1:1 dma-ranges mapping
  2024-08-26 21:29       ` Rob Herring
@ 2024-08-29 10:13         ` Andrea della Porta
  2024-08-29 13:18           ` Rob Herring
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-29 10:13 UTC (permalink / raw)
  To: Rob Herring
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Rob,

On 16:29 Mon 26 Aug     , Rob Herring wrote:
> On Wed, Aug 21, 2024 at 3:19 AM Andrea della Porta
> <andrea.porta@suse.com> wrote:
> >
> > Hi Rob,
> >
> > On 19:16 Tue 20 Aug     , Rob Herring wrote:
> > > On Tue, Aug 20, 2024 at 04:36:06PM +0200, Andrea della Porta wrote:
> > > > A missing or empty dma-ranges in a DT node implies a 1:1 mapping for dma
> > > > translations. In this specific case, rhe current behaviour is to zero out
> > >
> > > typo
> >
> > Fixed, thanks!
> >
> > >
> > > > the entire specifier so that the translation could be carried on as an
> > > > offset from zero.  This includes address specifier that has flags (e.g.
> > > > PCI ranges).
> > > > Once the flags portion has been zeroed, the translation chain is broken
> > > > since the mapping functions will check the upcoming address specifier
> > >
> > > What does "upcoming address" mean?
> >
> > Sorry for the confusion, this means "address specifier (with valid flags) fed
> > to the translating functions and for which we are looking for a translation".
> > While this address has some valid flags set, it will fail the translation step
> > since the ranges it is matched against have flags zeroed out by the 1:1 mapping
> > condition.
> >
> > >
> > > > against mismatching flags, always failing the 1:1 mapping and its entire
> > > > purpose of always succeeding.
> > > > Set to zero only the address portion while passing the flags through.
> > >
> > > Can you point me to what the failing DT looks like. I'm puzzled how
> > > things would have worked for anyone.
> > >
> >
> > The following is a simplified and lightly edited) version of the resulting DT
> > from RPi5:
> >
> >  pci@0,0 {
> >         #address-cells = <0x03>;
> >         #size-cells = <0x02>;
> >         ......
> >         device_type = "pci";
> >         compatible = "pci14e4,2712\0pciclass,060400\0pciclass,0604";
> >         ranges = <0x82000000 0x00 0x00   0x82000000 0x00 0x00   0x00 0x600000>;
> >         reg = <0x00 0x00 0x00   0x00 0x00>;
> >
> >         ......
> >
> >         rp1@0 {
> 
> What does 0 represent here? There's no 0 address in 'ranges' below.
> Since you said the parent is a PCI-PCI bridge, then the unit-address
> would have to be the PCI devfn and you are missing 'reg' (or omitted
> it).

There's no reg property because the registers for RP1 are addressed
starting at 0x40108000 offset from BAR1. The devicetree specs says
that a missing reg node should not have any unit address specified
(and AFAIK there's no other special directives for simple-bus specified
in dt-bindings). 
I've added @0 just to get rid of the following warning:

 Warning (unit_address_vs_reg): /fragment@0/__overlay__/rp1: node has
 a reg or ranges property, but no unit name 

coming from make W=1 CHECK_DTBS=y broadcom/rp1.dtbo.
This is the exact same approach used by Bootlin patchset from:

https://lore.kernel.org/all/20240808154658.247873-2-herve.codina@bootlin.com/

replied here below for convenience:

+	pci-ep-bus@0 {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		/*
+		 * map @0xe2000000 (32MB) to BAR0 (CPU)
+		 * map @0xe0000000 (16MB) to BAR1 (AMBA)
+		 */
+		ranges = <0xe2000000 0x00 0x00 0x00 0x2000000
+		          0xe0000000 0x01 0x00 0x00 0x1000000>;

Also, I think it's not possible to know the devfn in advance, since the
DT part is pre-compiled as an overlay while the devfn number is coming from
bus enumeration.
Since the registers for sub-peripherals will start (as stated in ranges
property) from 0xc040000000, I'd be inclined to use rp1@c040000000 as the
node name and address unit. Is it feasible?

> 
> >                 #address-cells = <0x02>;
> >                 #size-cells = <0x02>;
> >                 compatible = "simple-bus";
> 
> The parent is a PCI-PCI bridge. Child nodes have to be PCI devices and
> "simple-bus" is not a PCI device.

The simple-bus is needed to automatically traverse and create platform
devices in of_platform_populate(). It's true that RP1 is a PCI device,
but sub-peripherals of RP1 are platform devices so I guess this is
unavoidable right now.

> 
> The assumption so far with all of this is that you have some specific
> PCI device (and therefore a driver). The simple-buses under it are
> defined per BAR. Not really certain if that makes sense in all cases,
> but since the address assignment is dynamic, it may have to. I'm also
> not completely convinced we should reuse 'simple-bus' here or define
> something specific like 'pci-bar-bus' or something.

Good point. Labeling a new bus for this kind of 'appliance' could be
beneficial to unify the dt overlay approach, and I guess it could be
adopted by the aforementioned Bootlin's Microchip patchset too.
However, since the difference with simple-bus would be basically non
existent, I believe that this could be done in a future patch due to
the fact that the dtbo is contained into the driver itself, so we do
not suffer from the proliferation that happens when dtb are managed
outside.

> 
> >                 ranges = <0xc0 0x40000000   0x01 0x00 0x00   0x00 0x400000>;
> >                 dma-ranges = <0x10 0x00   0x43000000 0x10 0x00   0x10 0x00>;
> >                 ......
> >         };
> >  };
> >
> > The pci@0,0 bridge node is automatically created by virtue of
> > CONFIG_PCI_DYNAMIC_OF_NODES, and has no dma-ranges, hence it implies 1:1 dma
> > mappings (flags for this mapping are set to zero).  The rp1@0 node has
> > dma-ranges with flags set (0x43000000). Since 0x43000000 != 0x00 any translation
> > will fail.
> 
> It's possible that we should fill in 'dma-ranges' when making these
> nodes rather than supporting missing dma-ranges here.

I really think that filling dma-ranges for dynamically created pci
nodes would be the correct approach.
However, IMHO this does not imply that we could let inconsistent
address (64 bit addr with 32 flag bit set) laying around the 
translation chain, and fixing that is currently working fine. I'd
be then inclined to say the proposed change is outside the scope
of the present patchset and to postpone it to a future patch.

Many thanks,
Andrea

> 
> Rob

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

* Re: [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay
  2024-08-22 13:04     ` Andrew Lunn
@ 2024-08-29 12:01       ` Andrea della Porta
  2024-08-29 13:04         ` Andrew Lunn
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-29 12:01 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Krzysztof Kozlowski, Andrea della Porta, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Florian Fainelli, Broadcom internal kernel review list,
	Linus Walleij, Catalin Marinas, Will Deacon, Derek Kiernan,
	Dragan Cvetic, Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre,
	Claudiu Beznea, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Saravana Kannan, Bjorn Helgaas, linux-clk,
	devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
	linux-gpio, netdev, linux-pci, linux-arch, Lee Jones,
	Stefan Wahren

Hi Andrew,

On 15:04 Thu 22 Aug     , Andrew Lunn wrote:
> > WARNING: ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP
> > #673: FILE: drivers/pinctrl/pinctrl-rp1.c:600:
> > +                               return -ENOTSUPP;
> > 
> > This I must investigate: I've already tried to fix it before sending the patchset
> > but for some reason it wouldn't work, so I planned to fix it in the upcoming 
> > releases.
> 
> ENOTSUPP is an NFS error. It should not be used outside for NFS. You
> want EOPNOTSUPP.

Ack.

> 
>  
> > WARNING: externs should be avoided in .c files
> > #331: FILE: drivers/misc/rp1/rp1-pci.c:58:
> > +extern char __dtbo_rp1_pci_begin[];
> > 
> > True, but in this case we don't have a symbol that should be exported to other
> > translation units, it just needs to be referenced inside the driver and
> > consumed locally. Hence it would be better to place the extern in .c file.
>  
> Did you try making it static.

The dtso is compiled into an obj and linked with the driver which is in
a different transaltion unit. I'm not aware on other ways to include that
symbol without declaring it extern (the exception being some hackery 
trick that compile the dtso into a .c file to be included into the driver
main source file). 
Or probably I'm not seeing what you are proposing, could you please elaborate
on that?

Many thanks,
Andrea

> 
> 	Andrew

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

* Re: [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay
  2024-08-29 12:01       ` Andrea della Porta
@ 2024-08-29 13:04         ` Andrew Lunn
  2024-08-29 13:13           ` Andrea della Porta
  2024-08-30  5:21           ` Andrea della Porta
  0 siblings, 2 replies; 117+ messages in thread
From: Andrew Lunn @ 2024-08-29 13:04 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Andrea della Porta, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Florian Fainelli, Broadcom internal kernel review list,
	Linus Walleij, Catalin Marinas, Will Deacon, Derek Kiernan,
	Dragan Cvetic, Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre,
	Claudiu Beznea, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Saravana Kannan, Bjorn Helgaas, linux-clk,
	devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
	linux-gpio, netdev, linux-pci, linux-arch, Lee Jones,
	Stefan Wahren

> > > WARNING: externs should be avoided in .c files
> > > #331: FILE: drivers/misc/rp1/rp1-pci.c:58:
> > > +extern char __dtbo_rp1_pci_begin[];
> > > 
> > > True, but in this case we don't have a symbol that should be exported to other
> > > translation units, it just needs to be referenced inside the driver and
> > > consumed locally. Hence it would be better to place the extern in .c file.
> >  
> > Did you try making it static.
> 
> The dtso is compiled into an obj and linked with the driver which is in
> a different transaltion unit. I'm not aware on other ways to include that
> symbol without declaring it extern (the exception being some hackery 
> trick that compile the dtso into a .c file to be included into the driver
> main source file). 
> Or probably I'm not seeing what you are proposing, could you please elaborate
> on that?

Sorry, i jumped to the wrong conclusion. Often it is missing static
keyword which causes warnings. However, you say it needs to be global
scope.

Reading the warning again:

> > > WARNING: externs should be avoided in .c files

It is wanting you to put it in a .h file, which then gets
included by the two users.

	Andrew

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

* Re: [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay
  2024-08-22  9:50     ` Krzysztof Kozlowski
@ 2024-08-29 13:11       ` Andrea della Porta
  0 siblings, 0 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-08-29 13:11 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Krzysztof,

On 11:50 Thu 22 Aug     , Krzysztof Kozlowski wrote:
> On 22/08/2024 11:05, Andrea della Porta wrote:
> > Hi Krzysztof,
> > 
> > On 15:42 Wed 21 Aug     , Krzysztof Kozlowski wrote:
> >> On 20/08/2024 16:36, Andrea della Porta wrote:
> >>> RP1 is an MFD chipset that acts as a south-bridge PCIe endpoint sporting
> >>> a pletora of subdevices (i.e.  Ethernet, USB host controller, I2C, PWM, 
> >>> etc.) whose registers are all reachable starting from an offset from the
> >>> BAR address.  The main point here is that while the RP1 as an endpoint
> >>> itself is discoverable via usual PCI enumeraiton, the devices it contains
> >>> are not discoverable and must be declared e.g. via the devicetree.
> >>>
> >>> This patchset is an attempt to provide a minimum infrastructure to allow
> >>> the RP1 chipset to be discovered and perpherals it contains to be added
> >>> from a devictree overlay loaded during RP1 PCI endpoint enumeration.
> >>> Followup patches should add support for the several peripherals contained
> >>> in RP1.
> >>>
> >>> This work is based upon dowstream drivers code and the proposal from RH
> >>> et al. (see [1] and [2]). A similar approach is also pursued in [3].
> >>
> >> Looking briefly at findings it seems this was not really tested by
> >> automation and you expect reviewers to find issues which are pointed out
> >> by tools. That's not nice approach. Reviewer's time is limited, while
> >> tools do it for free. And the tools are free - you can use them without
> >> any effort.
> > 
> > Sorry if I gave you that impression, but this is not obviously the case.
> 
> Just look at number of reports... so many sparse reports that I wonder
> how it is not the case.
> 
> And many kbuild reports.

Ack.

> 
> > I've spent quite a bit of time in trying to deliver a patchset that ease
> > your and others work, at least to the best I can. In fact, I've used many
> > of the checking facilities you mentioned before sending it, solving all
> > of the reported issues, except the ones for which there are strong reasons
> > to leave untouched, as explained below.
> > 
> >>
> >> It does not look like you tested the DTS against bindings. Please run
> >> `make dtbs_check W=1` (see
> >> Documentation/devicetree/bindings/writing-schema.rst or
> >> https://www.linaro.org/blog/tips-and-tricks-for-validating-devicetree-sources-with-the-devicetree-schema/
> >> for instructions).
> > 
> > #> make W=1 dt_binding_check DT_SCHEMA_FILES=raspberrypi,rp1-gpio.yaml
> >    CHKDT   Documentation/devicetree/bindings
> >    LINT    Documentation/devicetree/bindings
> >    DTEX    Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.example.dts
> >    DTC_CHK Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.example.dtb
> > 
> > #> make W=1 dt_binding_check DT_SCHEMA_FILES=raspberrypi,rp1-clocks.yaml
> >    CHKDT   Documentation/devicetree/bindings
> >    LINT    Documentation/devicetree/bindings
> >    DTEX    Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.example.dts
> >    DTC_CHK Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.example.dtb
> > 
> > I see no issues here, in case you've found something different, I kindly ask you to post
> > the results.
> > 
> > #> make W=1 CHECK_DTBS=y broadcom/rp1.dtbo
> >    DTC     arch/arm64/boot/dts/broadcom/rp1.dtbo
> >    arch/arm64/boot/dts/broadcom/rp1.dtso:37.24-42.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/clk_xosc: missing or empty reg/ranges property
> >    arch/arm64/boot/dts/broadcom/rp1.dtso:44.26-49.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/macb_pclk: missing or empty reg/ranges property
> >    arch/arm64/boot/dts/broadcom/rp1.dtso:51.26-56.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/macb_hclk: missing or empty reg/ranges property
> >    arch/arm64/boot/dts/broadcom/rp1.dtso:14.15-173.5: Warning (avoid_unnecessary_addr_size): /fragment@0/__overlay__: unnecessary #address-cells/#size-cells without "ranges", "dma-ranges" or child "reg" property 
> > 
> > I believe that These warnings are unavoidable, and stem from the fact that this
> > is quite a peculiar setup (PCI endpoint which dynamically loads platform driver
> > addressable via BAR).
> > The missing reg/ranges in the threee clocks are due to the simple-bus of the
> > containing node to which I believe they should belong: I did a test to place
> 
> This is not the place where they belong. non-MMIO nodes should not be
> under simple-bus.

Ack.

> 
> > those clocks in the same dtso under root or /clocks node but AFAIK it doesn't
> > seems to work. I could move them in a separate dtso to be loaded before the main
> 
> Well... who instantiates them? If they are in top-level, then
> CLK_OF_DECLARE which is not called at your point?
> 
> You must instantiate clocks different way, since they are not part of
> "rp1". That's another bogus DT description... external oscilator is not
> part of RP1.
>

Ok, I'll dive into that and see what I can come up with. Many thanks for
this feedback.
 
> 
> > one but this is IMHO even more cumbersome than having a couple of warnings in
> > CHECK_DTBS.
> > Of course, if you have any suggestion on how to improve it I would be glad to
> > discuss.
> > About the last warning about the address/size-cells, if I drop those two lines
> > in the _overlay_ node it generates even more warning, so again it's a "don't fix"
> > one.
> > 
> >>
> >> Please run standard kernel tools for static analysis, like coccinelle,
> >> smatch and sparse, and fix reported warnings. Also please check for
> >> warnings when building with W=1. Most of these commands (checks or W=1
> >> build) can build specific targets, like some directory, to narrow the
> >> scope to only your code. The code here looks like it needs a fix. Feel
> >> free to get in touch if the warning is not clear.
> > 
> > I didn't run those static analyzers since I've preferred a more "manual" aproach
> > by carfeully checking the code, but I agree that something can escape even the
> > more carefully executed code inspection so I will add them to my arsenal from
> > now on. Thanks for the heads up.
> 
> I don't care if you do not run static analyzers if you produce good
> code. But if you produce bugs which could have been easily spotted with
> sparser, than it is different thing.
> 
> Start running static checkers instead of asking reviewers to do that.

Ack.

> 
> > 
> >>
> >> Please run scripts/checkpatch.pl and fix reported warnings. Then please
> >> run `scripts/checkpatch.pl --strict` and (probably) fix more warnings.
> >> Some warnings can be ignored, especially from --strict run, but the code
> >> here looks like it needs a fix. Feel free to get in touch if the warning
> >> is not clear.
> >>
> > 
> > Again, most of checkpatch's complaints have been addressed, the remaining
> > ones I deemed as not worth fixing, for example:>
> > #> scripts/checkpatch.pl --strict --codespell tmp/*.patch
> > 
> > WARNING: please write a help paragraph that fully describes the config symbol
> > #42: FILE: drivers/clk/Kconfig:91:
> > +config COMMON_CLK_RP1
> > +       tristate "Raspberry Pi RP1-based clock support"
> > +       depends on PCI || COMPILE_TEST
> > +       depends on COMMON_CLK
> > +       help
> > +         Enable common clock framework support for Raspberry Pi RP1.
> > +         This mutli-function device has 3 main PLLs and several clock
> > +         generators to drive the internal sub-peripherals.
> > +
> > 
> > I don't understand this warning, the paragraph is there and is more or less similar
> > to many in the same file that are already upstream. Checkpatch bug?
> > 
> > 
> > CHECK: Alignment should match open parenthesis
> > #1541: FILE: drivers/clk/clk-rp1.c:1470:
> > +       if (WARN_ON_ONCE(clock_data->num_std_parents > AUX_SEL &&
> > +           strcmp("-", clock_data->parents[AUX_SEL])))
> > 
> > This would have worsen the code readability.
> > 
> > 
> > WARNING: ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP
> > #673: FILE: drivers/pinctrl/pinctrl-rp1.c:600:
> > +                               return -ENOTSUPP;
> > 
> > This I must investigate: I've already tried to fix it before sending the patchset
> > but for some reason it wouldn't work, so I planned to fix it in the upcoming 
> > releases.
> > 
> > 
> > WARNING: externs should be avoided in .c files
> > #331: FILE: drivers/misc/rp1/rp1-pci.c:58:
> > +extern char __dtbo_rp1_pci_begin[];
> > 
> > True, but in this case we don't have a symbol that should be exported to other
> > translation units, it just needs to be referenced inside the driver and
> > consumed locally. Hence it would be better to place the extern in .c file.
> > 
> > 
> > Apologies for a couple of other warnings that I could have seen in the first
> > place, but honestly they don't seems to be a big deal (one typo and on over
> > 100 chars comment, that will be fixed in next patch version). 
> 
> Again, judging by number of reports from checkers that is a big deal,
> because it is your task to run the tools.

Ack.

Many thanks,
Andrea

> 
> Best regards,
> Krzysztof
> 

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

* Re: [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay
  2024-08-29 13:04         ` Andrew Lunn
@ 2024-08-29 13:13           ` Andrea della Porta
  2024-08-30  5:21           ` Andrea della Porta
  1 sibling, 0 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-08-29 13:13 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Krzysztof Kozlowski, Andrea della Porta, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Florian Fainelli, Broadcom internal kernel review list,
	Linus Walleij, Catalin Marinas, Will Deacon, Derek Kiernan,
	Dragan Cvetic, Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre,
	Claudiu Beznea, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Saravana Kannan, Bjorn Helgaas, linux-clk,
	devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
	linux-gpio, netdev, linux-pci, linux-arch, Lee Jones,
	Stefan Wahren

Hi Andrew,

On 15:04 Thu 29 Aug     , Andrew Lunn wrote:
> > > > WARNING: externs should be avoided in .c files
> > > > #331: FILE: drivers/misc/rp1/rp1-pci.c:58:
> > > > +extern char __dtbo_rp1_pci_begin[];
> > > > 
> > > > True, but in this case we don't have a symbol that should be exported to other
> > > > translation units, it just needs to be referenced inside the driver and
> > > > consumed locally. Hence it would be better to place the extern in .c file.
> > >  
> > > Did you try making it static.
> > 
> > The dtso is compiled into an obj and linked with the driver which is in
> > a different transaltion unit. I'm not aware on other ways to include that
> > symbol without declaring it extern (the exception being some hackery 
> > trick that compile the dtso into a .c file to be included into the driver
> > main source file). 
> > Or probably I'm not seeing what you are proposing, could you please elaborate
> > on that?
> 
> Sorry, i jumped to the wrong conclusion. Often it is missing static
> keyword which causes warnings. However, you say it needs to be global
> scope.
> 
> Reading the warning again:
> 
> > > > WARNING: externs should be avoided in .c files
> 
> It is wanting you to put it in a .h file, which then gets
> included by the two users.

Ah I see now what you were referring to, thanks.
I'll put the extern into an header file, although there are no two users
of that, the only one being rp1-pci.c.

Many thanks,
Andrea

> 
> 	Andrew

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

* Re: [PATCH 04/11] of: address: Preserve the flags portion on 1:1 dma-ranges mapping
  2024-08-29 10:13         ` Andrea della Porta
@ 2024-08-29 13:18           ` Rob Herring
  2024-08-29 16:26             ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Rob Herring @ 2024-08-29 13:18 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On Thu, Aug 29, 2024 at 5:13 AM Andrea della Porta
<andrea.porta@suse.com> wrote:
>
> Hi Rob,

BTW, I noticed your email replies set "reply-to" to everyone in To and
Cc. The result (with Gmail) is my reply lists everyone twice (in both
To and Cc). "reply-to" is just supposed to be the 1 address you want
replies sent to instead of the "from" address.

> On 16:29 Mon 26 Aug     , Rob Herring wrote:
> > On Wed, Aug 21, 2024 at 3:19 AM Andrea della Porta
> > <andrea.porta@suse.com> wrote:
> > >
> > > Hi Rob,
> > >
> > > On 19:16 Tue 20 Aug     , Rob Herring wrote:
> > > > On Tue, Aug 20, 2024 at 04:36:06PM +0200, Andrea della Porta wrote:
> > > > > A missing or empty dma-ranges in a DT node implies a 1:1 mapping for dma
> > > > > translations. In this specific case, rhe current behaviour is to zero out
> > > >
> > > > typo
> > >
> > > Fixed, thanks!
> > >
> > > >
> > > > > the entire specifier so that the translation could be carried on as an
> > > > > offset from zero.  This includes address specifier that has flags (e.g.
> > > > > PCI ranges).
> > > > > Once the flags portion has been zeroed, the translation chain is broken
> > > > > since the mapping functions will check the upcoming address specifier
> > > >
> > > > What does "upcoming address" mean?
> > >
> > > Sorry for the confusion, this means "address specifier (with valid flags) fed
> > > to the translating functions and for which we are looking for a translation".
> > > While this address has some valid flags set, it will fail the translation step
> > > since the ranges it is matched against have flags zeroed out by the 1:1 mapping
> > > condition.
> > >
> > > >
> > > > > against mismatching flags, always failing the 1:1 mapping and its entire
> > > > > purpose of always succeeding.
> > > > > Set to zero only the address portion while passing the flags through.
> > > >
> > > > Can you point me to what the failing DT looks like. I'm puzzled how
> > > > things would have worked for anyone.
> > > >
> > >
> > > The following is a simplified and lightly edited) version of the resulting DT
> > > from RPi5:
> > >
> > >  pci@0,0 {
> > >         #address-cells = <0x03>;
> > >         #size-cells = <0x02>;
> > >         ......
> > >         device_type = "pci";
> > >         compatible = "pci14e4,2712\0pciclass,060400\0pciclass,0604";
> > >         ranges = <0x82000000 0x00 0x00   0x82000000 0x00 0x00   0x00 0x600000>;
> > >         reg = <0x00 0x00 0x00   0x00 0x00>;
> > >
> > >         ......
> > >
> > >         rp1@0 {
> >
> > What does 0 represent here? There's no 0 address in 'ranges' below.
> > Since you said the parent is a PCI-PCI bridge, then the unit-address
> > would have to be the PCI devfn and you are missing 'reg' (or omitted
> > it).
>
> There's no reg property because the registers for RP1 are addressed
> starting at 0x40108000 offset from BAR1. The devicetree specs says
> that a missing reg node should not have any unit address specified
> (and AFAIK there's no other special directives for simple-bus specified
> in dt-bindings).
> I've added @0 just to get rid of the following warning:
>
>  Warning (unit_address_vs_reg): /fragment@0/__overlay__/rp1: node has
>  a reg or ranges property, but no unit name

It's still wrong as dtc only checks the unit-address is correct in a
few cases with known bus types.

> coming from make W=1 CHECK_DTBS=y broadcom/rp1.dtbo.
> This is the exact same approach used by Bootlin patchset from:
>
> https://lore.kernel.org/all/20240808154658.247873-2-herve.codina@bootlin.com/

It is not. First, that has a node for the PCI device (i.e. the
LAN966x). You do not. You only have a PCI-PCI bridge and that is
wrong.

BTW, you should Cc Herve and others that are working on this feature.
It is by no means fully sorted as you have found.

> replied here below for convenience:
>
> +       pci-ep-bus@0 {
> +               compatible = "simple-bus";
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +
> +               /*
> +                * map @0xe2000000 (32MB) to BAR0 (CPU)
> +                * map @0xe0000000 (16MB) to BAR1 (AMBA)
> +                */
> +               ranges = <0xe2000000 0x00 0x00 0x00 0x2000000

The 0 parent address here matches the unit-address, so all good in this case.

> +                         0xe0000000 0x01 0x00 0x00 0x1000000>;
>
> Also, I think it's not possible to know the devfn in advance, since the
> DT part is pre-compiled as an overlay while the devfn number is coming from
> bus enumeration.

No. devfn is fixed unless you are plugging in a card in different
slots. The bus number is the part that is not known and assigned by
the OS, but you'll notice that is omitted.

In any case, the RP1 node should be generated, so its devfn is irrelevant.

> Since the registers for sub-peripherals will start (as stated in ranges
> property) from 0xc040000000, I'd be inclined to use rp1@c040000000 as the
> node name and address unit. Is it feasible?

Yes, but that would be in nodes underneath ranges. Above, it is the
parent bus we are talking about.

> > >                 #address-cells = <0x02>;
> > >                 #size-cells = <0x02>;
> > >                 compatible = "simple-bus";
> >
> > The parent is a PCI-PCI bridge. Child nodes have to be PCI devices and
> > "simple-bus" is not a PCI device.
>
> The simple-bus is needed to automatically traverse and create platform
> devices in of_platform_populate(). It's true that RP1 is a PCI device,
> but sub-peripherals of RP1 are platform devices so I guess this is
> unavoidable right now.

You are missing the point. A PCI-PCI bridge does not have a
simple-bus. However, I think it's just what you pasted here that's
wrong. From the looks of the RP1 driver and the overlay, it should be
correct.

It would also help if you dumped out what "lspci -tvnn" prints.

> > The assumption so far with all of this is that you have some specific
> > PCI device (and therefore a driver). The simple-buses under it are
> > defined per BAR. Not really certain if that makes sense in all cases,
> > but since the address assignment is dynamic, it may have to. I'm also
> > not completely convinced we should reuse 'simple-bus' here or define
> > something specific like 'pci-bar-bus' or something.
>
> Good point. Labeling a new bus for this kind of 'appliance' could be
> beneficial to unify the dt overlay approach, and I guess it could be
> adopted by the aforementioned Bootlin's Microchip patchset too.
> However, since the difference with simple-bus would be basically non
> existent, I believe that this could be done in a future patch due to
> the fact that the dtbo is contained into the driver itself, so we do
> not suffer from the proliferation that happens when dtb are managed
> outside.

It's an ABI, so we really need to decide first.

> > >                 ranges = <0xc0 0x40000000   0x01 0x00 0x00   0x00 0x400000>;
> > >                 dma-ranges = <0x10 0x00   0x43000000 0x10 0x00   0x10 0x00>;
> > >                 ......
> > >         };
> > >  };
> > >
> > > The pci@0,0 bridge node is automatically created by virtue of
> > > CONFIG_PCI_DYNAMIC_OF_NODES, and has no dma-ranges, hence it implies 1:1 dma
> > > mappings (flags for this mapping are set to zero).  The rp1@0 node has
> > > dma-ranges with flags set (0x43000000). Since 0x43000000 != 0x00 any translation
> > > will fail.
> >
> > It's possible that we should fill in 'dma-ranges' when making these
> > nodes rather than supporting missing dma-ranges here.
>
> I really think that filling dma-ranges for dynamically created pci
> nodes would be the correct approach.
> However, IMHO this does not imply that we could let inconsistent
> address (64 bit addr with 32 flag bit set) laying around the
> translation chain, and fixing that is currently working fine. I'd
> be then inclined to say the proposed change is outside the scope
> of the present patchset and to postpone it to a future patch.

Okay, but let's fix it with a test case. There's already a test case
for all this in the DT unittest which can be extended.

Rob

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

* Re: [PATCH 04/11] of: address: Preserve the flags portion on 1:1 dma-ranges mapping
  2024-08-29 13:18           ` Rob Herring
@ 2024-08-29 16:26             ` Andrea della Porta
  2024-08-30 19:37               ` Rob Herring
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-29 16:26 UTC (permalink / raw)
  To: Rob Herring
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren, Herve Codina, Luca Ceresoli, Thomas Petazzoni

Hi Rob,

On 08:18 Thu 29 Aug     , Rob Herring wrote:
> On Thu, Aug 29, 2024 at 5:13 AM Andrea della Porta
> <andrea.porta@suse.com> wrote:
> >
> > Hi Rob,
> 
> BTW, I noticed your email replies set "reply-to" to everyone in To and
> Cc. The result (with Gmail) is my reply lists everyone twice (in both
> To and Cc). "reply-to" is just supposed to be the 1 address you want
> replies sent to instead of the "from" address.

IIUC you're probably referring to Mail-Reply-To, that address only one recipient
at a time (i.e. you want to reply only to the author). Reply-To is a catch-all
that will work as a fallback when you hit either reply or reply-all in your client.
In fact, neither Reply-To nor Mail-Reply-To are included in my emails, the
interesting one being Mail-Followup-To, that should override any of the above
mentioned headers (including To: and Cc:) for the reply all function. How these
headers are interpreted depends solely on the mail client, I'm afraid.
Is it possible that your client is mistakenly merging both Mail-Followup-To 
plus To and Cc lists?
Anyway, I've disabled Mail-followup-To as it's added by mutt, can you please
confirm that this mail now works for you? Hopefully it will not clobber the
recipent list too much, since AFAIK that header was purposely invented to avoid
such inconsistencies.

> 
> > On 16:29 Mon 26 Aug     , Rob Herring wrote:
> > > On Wed, Aug 21, 2024 at 3:19 AM Andrea della Porta
> > > <andrea.porta@suse.com> wrote:
> > > >
> > > > Hi Rob,
> > > >
> > > > On 19:16 Tue 20 Aug     , Rob Herring wrote:
> > > > > On Tue, Aug 20, 2024 at 04:36:06PM +0200, Andrea della Porta wrote:
> > > > > > A missing or empty dma-ranges in a DT node implies a 1:1 mapping for dma
> > > > > > translations. In this specific case, rhe current behaviour is to zero out
> > > > >
> > > > > typo
> > > >
> > > > Fixed, thanks!
> > > >
> > > > >
> > > > > > the entire specifier so that the translation could be carried on as an
> > > > > > offset from zero.  This includes address specifier that has flags (e.g.
> > > > > > PCI ranges).
> > > > > > Once the flags portion has been zeroed, the translation chain is broken
> > > > > > since the mapping functions will check the upcoming address specifier
> > > > >
> > > > > What does "upcoming address" mean?
> > > >
> > > > Sorry for the confusion, this means "address specifier (with valid flags) fed
> > > > to the translating functions and for which we are looking for a translation".
> > > > While this address has some valid flags set, it will fail the translation step
> > > > since the ranges it is matched against have flags zeroed out by the 1:1 mapping
> > > > condition.
> > > >
> > > > >
> > > > > > against mismatching flags, always failing the 1:1 mapping and its entire
> > > > > > purpose of always succeeding.
> > > > > > Set to zero only the address portion while passing the flags through.
> > > > >
> > > > > Can you point me to what the failing DT looks like. I'm puzzled how
> > > > > things would have worked for anyone.
> > > > >
> > > >
> > > > The following is a simplified and lightly edited) version of the resulting DT
> > > > from RPi5:
> > > >
> > > >  pci@0,0 {
> > > >         #address-cells = <0x03>;
> > > >         #size-cells = <0x02>;
> > > >         ......
> > > >         device_type = "pci";
> > > >         compatible = "pci14e4,2712\0pciclass,060400\0pciclass,0604";
> > > >         ranges = <0x82000000 0x00 0x00   0x82000000 0x00 0x00   0x00 0x600000>;
> > > >         reg = <0x00 0x00 0x00   0x00 0x00>;
> > > >
> > > >         ......
> > > >
> > > >         rp1@0 {
> > >
> > > What does 0 represent here? There's no 0 address in 'ranges' below.
> > > Since you said the parent is a PCI-PCI bridge, then the unit-address
> > > would have to be the PCI devfn and you are missing 'reg' (or omitted
> > > it).
> >
> > There's no reg property because the registers for RP1 are addressed
> > starting at 0x40108000 offset from BAR1. The devicetree specs says
> > that a missing reg node should not have any unit address specified
> > (and AFAIK there's no other special directives for simple-bus specified
> > in dt-bindings).
> > I've added @0 just to get rid of the following warning:
> >
> >  Warning (unit_address_vs_reg): /fragment@0/__overlay__/rp1: node has
> >  a reg or ranges property, but no unit name
> 
> It's still wrong as dtc only checks the unit-address is correct in a
> few cases with known bus types.

Sorry, I don't follow you on this, I'm probably missing something. Could
you please add some details?

> 
> > coming from make W=1 CHECK_DTBS=y broadcom/rp1.dtbo.
> > This is the exact same approach used by Bootlin patchset from:
> >
> > https://lore.kernel.org/all/20240808154658.247873-2-herve.codina@bootlin.com/
> 
> It is not. First, that has a node for the PCI device (i.e. the
> LAN966x). You do not. You only have a PCI-PCI bridge and that is
> wrong.

I'm a little confused now, but I think the confusion is generated by
the label node names I've chosen that are, admittedly, a bit sloppy.
I'll try to make some clarity, please see below.

> 
> BTW, you should Cc Herve and others that are working on this feature.
> It is by no means fully sorted as you have found.

Sure, just added, thanks for the heads up.

> 
> > replied here below for convenience:
> >
> > +       pci-ep-bus@0 {
> > +               compatible = "simple-bus";
> > +               #address-cells = <1>;
> > +               #size-cells = <1>;
> > +
> > +               /*
> > +                * map @0xe2000000 (32MB) to BAR0 (CPU)
> > +                * map @0xe0000000 (16MB) to BAR1 (AMBA)
> > +                */
> > +               ranges = <0xe2000000 0x00 0x00 0x00 0x2000000
> 
> The 0 parent address here matches the unit-address, so all good in this case.

Just to be sure, the parent address being the triple zeros in the ranges property,
right?

> 
> > +                         0xe0000000 0x01 0x00 0x00 0x1000000>;
> >
> > Also, I think it's not possible to know the devfn in advance, since the
> > DT part is pre-compiled as an overlay while the devfn number is coming from
> > bus enumeration.
> 
> No. devfn is fixed unless you are plugging in a card in different
> slots. The bus number is the part that is not known and assigned by
> the OS, but you'll notice that is omitted.
> 
> In any case, the RP1 node should be generated, so its devfn is irrelevant.

Which is a possibility, since the driver should possibly work also with RP1
mounted on a PCI card, one day. But as you pointed out, since this is automatically
generated, should not be a concern.

> 
> > Since the registers for sub-peripherals will start (as stated in ranges
> > property) from 0xc040000000, I'd be inclined to use rp1@c040000000 as the
> > node name and address unit. Is it feasible?
> 
> Yes, but that would be in nodes underneath ranges. Above, it is the
> parent bus we are talking about.

Right.

> 
> > > >                 #address-cells = <0x02>;
> > > >                 #size-cells = <0x02>;
> > > >                 compatible = "simple-bus";
> > >
> > > The parent is a PCI-PCI bridge. Child nodes have to be PCI devices and
> > > "simple-bus" is not a PCI device.
> >
> > The simple-bus is needed to automatically traverse and create platform
> > devices in of_platform_populate(). It's true that RP1 is a PCI device,
> > but sub-peripherals of RP1 are platform devices so I guess this is
> > unavoidable right now.
> 
> You are missing the point. A PCI-PCI bridge does not have a
> simple-bus. However, I think it's just what you pasted here that's
> wrong. From the looks of the RP1 driver and the overlay, it should be
> correct.

Trying to clarify: at first I thought of my rp1 node (in the dtso) as the pci
endpoint device, but I now see that it should be intended as just the bus 
attached to the real endpoint device (which is the dynamically generated dev@0,0).
In this sense, rp1 is probably a really wrong name, let's say we use the same 
name from Bootlin, i.e. pci-ep-bus. The DT tree would then be:

pci@0,0         <- auto generated, this represent the pci bridge
  dev@0,0       <- auto generated, this represent the pci ednpoint device, a.k.a. the RP1
    pci-ep-bus  <- added from dtbo, this is the simple-bus to which peripherals are attached

this view is much like Bootlin's approach, also my pci-ep-bus node now would look
like this:
 ...
 pci-ep-bus@0 {
	ranges = <0xc0 0x40000000
                  0x01 0x00 0x00000000
                  0x00 0x00400000>;
	...
 };

and also the correct unit address here is 0 again, since the parent address in
ranges is 0x01 0x00 0x00000000 (0x01 is the flags and in this case represent
BAR1, I assume that for the unit address I should use only the address part that
is 0, right?).

> 
> It would also help if you dumped out what "lspci -tvnn" prints.
> 

Here it is:

localhost:~ # lspci -tvnn
-[0002:00]---00.0-[01]----00.0  Raspberry Pi Ltd RP1 PCIe 2.0 South Bridge [1de4:0001]

> > > The assumption so far with all of this is that you have some specific
> > > PCI device (and therefore a driver). The simple-buses under it are
> > > defined per BAR. Not really certain if that makes sense in all cases,
> > > but since the address assignment is dynamic, it may have to. I'm also
> > > not completely convinced we should reuse 'simple-bus' here or define
> > > something specific like 'pci-bar-bus' or something.
> >
> > Good point. Labeling a new bus for this kind of 'appliance' could be
> > beneficial to unify the dt overlay approach, and I guess it could be
> > adopted by the aforementioned Bootlin's Microchip patchset too.
> > However, since the difference with simple-bus would be basically non
> > existent, I believe that this could be done in a future patch due to
> > the fact that the dtbo is contained into the driver itself, so we do
> > not suffer from the proliferation that happens when dtb are managed
> > outside.
> 
> It's an ABI, so we really need to decide first.

Okay. How should we proceed?

> 
> > > >                 ranges = <0xc0 0x40000000   0x01 0x00 0x00   0x00 0x400000>;
> > > >                 dma-ranges = <0x10 0x00   0x43000000 0x10 0x00   0x10 0x00>;
> > > >                 ......
> > > >         };
> > > >  };
> > > >
> > > > The pci@0,0 bridge node is automatically created by virtue of
> > > > CONFIG_PCI_DYNAMIC_OF_NODES, and has no dma-ranges, hence it implies 1:1 dma
> > > > mappings (flags for this mapping are set to zero).  The rp1@0 node has
> > > > dma-ranges with flags set (0x43000000). Since 0x43000000 != 0x00 any translation
> > > > will fail.
> > >
> > > It's possible that we should fill in 'dma-ranges' when making these
> > > nodes rather than supporting missing dma-ranges here.
> >
> > I really think that filling dma-ranges for dynamically created pci
> > nodes would be the correct approach.
> > However, IMHO this does not imply that we could let inconsistent
> > address (64 bit addr with 32 flag bit set) laying around the
> > translation chain, and fixing that is currently working fine. I'd
> > be then inclined to say the proposed change is outside the scope
> > of the present patchset and to postpone it to a future patch.
> 
> Okay, but let's fix it with a test case. There's already a test case
> for all this in the DT unittest which can be extended.

I'm taking a look at the unittest framework right now.

Many thanks,
Andrea

> 
> Rob

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

* Re: [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay
  2024-08-29 13:04         ` Andrew Lunn
  2024-08-29 13:13           ` Andrea della Porta
@ 2024-08-30  5:21           ` Andrea della Porta
  2024-08-30 14:10             ` Andrew Lunn
  1 sibling, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-30  5:21 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Krzysztof Kozlowski, Andrea della Porta, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Florian Fainelli, Broadcom internal kernel review list,
	Linus Walleij, Catalin Marinas, Will Deacon, Derek Kiernan,
	Dragan Cvetic, Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre,
	Claudiu Beznea, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Saravana Kannan, Bjorn Helgaas, linux-clk,
	devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
	linux-gpio, netdev, linux-pci, linux-arch, Lee Jones,
	Stefan Wahren

Hi Andrew,

On 15:04 Thu 29 Aug     , Andrew Lunn wrote:
> > > > WARNING: externs should be avoided in .c files
> > > > #331: FILE: drivers/misc/rp1/rp1-pci.c:58:
> > > > +extern char __dtbo_rp1_pci_begin[];
> > > > 
> > > > True, but in this case we don't have a symbol that should be exported to other
> > > > translation units, it just needs to be referenced inside the driver and
> > > > consumed locally. Hence it would be better to place the extern in .c file.
> > >  
> > > Did you try making it static.
> > 
> > The dtso is compiled into an obj and linked with the driver which is in
> > a different transaltion unit. I'm not aware on other ways to include that
> > symbol without declaring it extern (the exception being some hackery 
> > trick that compile the dtso into a .c file to be included into the driver
> > main source file). 
> > Or probably I'm not seeing what you are proposing, could you please elaborate
> > on that?
> 
> Sorry, i jumped to the wrong conclusion. Often it is missing static
> keyword which causes warnings. However, you say it needs to be global
> scope.
> 
> Reading the warning again:
> 
> > > > WARNING: externs should be avoided in .c files
> 
> It is wanting you to put it in a .h file, which then gets
> included by the two users.

On a second thought, are you really sure we want to proceed with the header file?
After all the only line in it would be the extern declaration and the only one to
include it would be rp1-dev.c. Moreover, an header file would convey the false
premise that you can include it and use that symbol while in fact it should be
only used inside the driver.
OTOH, not creating that header file will continue to trigger the warning...

Many thanks,
Andrea

> 
> 	Andrew

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

* Re: [PATCH 02/11] dt-bindings: pinctrl: Add RaspberryPi RP1 gpio/pinctrl/pinmux bindings
  2024-08-21  8:42   ` Krzysztof Kozlowski
@ 2024-08-30 10:22     ` Andrea della Porta
  2024-08-30 11:46       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-08-30 10:22 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Krzysztof,

On 10:42 Wed 21 Aug     , Krzysztof Kozlowski wrote:
> On Tue, Aug 20, 2024 at 04:36:04PM +0200, Andrea della Porta wrote:
> > Add device tree bindings for the gpio/pin/mux controller that is part of
> > the RP1 multi function device, and relative entries in MAINTAINERS file.
> > 
> > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> > ---
> >  .../pinctrl/raspberrypi,rp1-gpio.yaml         | 177 +++++++++++++
> >  MAINTAINERS                                   |   2 +
> >  include/dt-bindings/misc/rp1.h                | 235 ++++++++++++++++++
> >  3 files changed, 414 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
> >  create mode 100644 include/dt-bindings/misc/rp1.h
> > 
> > diff --git a/Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml b/Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
> > new file mode 100644
> > index 000000000000..7011fa258363
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
> > @@ -0,0 +1,177 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/pinctrl/raspberrypi,rp1-gpio.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: RaspberryPi RP1 GPIO/Pinconf/Pinmux Controller submodule
> > +
> > +maintainers:
> > +  - Andrea della Porta <andrea.porta@suse.com>
> > +
> > +description:
> > +  The RP1 chipset is a Multi Function Device containing, among other sub-peripherals,
> > +  a gpio/pinconf/mux controller whose 54 pins are grouped into 3 banks. It works also
> > +  as an interrupt controller for those gpios.
> > +
> > +  Each pin configuration node lists the pin(s) to which it applies, and one or
> > +  more of the mux function to select on those pin(s), and their configuration.
> > +  The pin configuration and multiplexing supports the generic bindings.
> > +  For details on each properties (including the meaning of "pin configuration node"),
> > +  you can refer to ./pinctrl-bindings.txt.
> > +
> > +properties:
> > +  compatible:
> > +    const: raspberrypi,rp1-gpio
> > +
> > +  reg:
> > +    minItems: 3
> 
> You can drop minItems.

Ack.

> 
> > +    maxItems: 3
> > +    description: One reg specifier for each one of the 3 pin banks.
> > +
> > +  '#gpio-cells':
> > +    description: The first cell is the pin number and the second cell is used
> > +      to specify the flags (see include/dt-bindings/gpio/gpio.h).
> > +    const: 2
> > +
> > +  gpio-controller: true
> > +
> > +  gpio-ranges:
> > +    maxItems: 1
> > +
> > +  gpio-line-names:
> > +    maxItems: 54
> > +
> > +  interrupts:
> > +    minItems: 3
> 
> Ditto

Ack.

> 
> > +    maxItems: 3
> > +    description: One interrupt specifier for each one of the 3 pin banks.
> > +
> > +  '#interrupt-cells':
> > +    description:
> > +      Specifies the Bank number (as specified in include/dt-bindings/misc/rp1.h)
> > +      and Flags (as defined in (include/dt-bindings/interrupt-controller/irq.h).
> > +      Possible values for the Bank number are
> > +          RP1_INT_IO_BANK0
> > +          RP1_INT_IO_BANK1
> > +          RP1_INT_IO_BANK2
> > +    const: 2
> > +
> > +  interrupt-controller: true
> > +
> > +additionalProperties:
> > +  anyOf:
> > +    - type: object
> > +      additionalProperties: false
> > +      allOf:
> > +        - $ref: pincfg-node.yaml#
> > +        - $ref: pinmux-node.yaml#
> > +
> > +      description:
> > +        Pin controller client devices use pin configuration subnodes (children
> > +        and grandchildren) for desired pin configuration.
> > +        Client device subnodes use below standard properties.
> > +
> > +      properties:
> > +        pins:
> > +          description:
> > +            A string (or list of strings) adhering to the pattern "gpio[0-5][0-9]"
> > +        function: true
> > +        bias-disable: true
> > +        bias-pull-down: true
> > +        bias-pull-up: true
> > +        slew-rate:
> > +          description: 0 is slow slew rate, 1 is fast slew rate
> > +          enum: [ 0, 1 ]
> > +        drive-strength:
> > +          description: 0 -> 2mA, 1 -> 4mA, 2 -> 8mA, 3 -> 12mA
> > +          enum: [ 0, 1, 2, 3 ]
> 
> No, that's [ 2, 4, 8 and 12 ]
> 
> Read description of the field - it is in specific units.

Ack. Thanks, this would have been a bug, since the driver was already using
the current value instead of the positional.

> 
> > +
> > +    - type: object
> > +      additionalProperties:
> > +        $ref: "#/additionalProperties/anyOf/0"
> > +
> > +allOf:
> > +  - $ref: pinctrl.yaml#
> > +
> > +required:
> > +  - reg
> > +  - compatible
> > +  - "#gpio-cells"
> > +  - gpio-controller
> > +  - interrupts
> > +  - "#interrupt-cells"
> > +  - interrupt-controller
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/irq.h>
> > +    #include <dt-bindings/misc/rp1.h>
> > +
> > +    rp1 {
> > +        #address-cells = <2>;
> > +        #size-cells = <2>;
> > +
> > +        rp1_gpio: pinctrl@c0400d0000 {
> > +            reg = <0xc0 0x400d0000  0x0 0xc000>,
> > +                  <0xc0 0x400e0000  0x0 0xc000>,
> > +                  <0xc0 0x400f0000  0x0 0xc000>;
> > +            compatible = "raspberrypi,rp1-gpio";
> > +            gpio-controller;
> > +            #gpio-cells = <2>;
> > +            interrupt-controller;
> > +            #interrupt-cells = <2>;
> > +            interrupts = <RP1_INT_IO_BANK0 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <RP1_INT_IO_BANK1 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <RP1_INT_IO_BANK2 IRQ_TYPE_LEVEL_HIGH>;
> > +            gpio-line-names =
> > +                   "ID_SDA", // GPIO0
> > +                   "ID_SCL", // GPIO1
> > +                   "GPIO2", "GPIO3", "GPIO4", "GPIO5", "GPIO6",
> > +                   "GPIO7", "GPIO8", "GPIO9", "GPIO10", "GPIO11",
> > +                   "GPIO12", "GPIO13", "GPIO14", "GPIO15", "GPIO16",
> > +                   "GPIO17", "GPIO18", "GPIO19", "GPIO20", "GPIO21",
> > +                   "GPIO22", "GPIO23", "GPIO24", "GPIO25", "GPIO26",
> > +                   "GPIO27",
> > +                   "PCIE_RP1_WAKE", // GPIO28
> > +                   "FAN_TACH", // GPIO29
> > +                   "HOST_SDA", // GPIO30
> > +                   "HOST_SCL", // GPIO31
> > +                   "ETH_RST_N", // GPIO32
> > +                   "", // GPIO33
> > +                   "CD0_IO0_MICCLK", // GPIO34
> > +                   "CD0_IO0_MICDAT0", // GPIO35
> > +                   "RP1_PCIE_CLKREQ_N", // GPIO36
> > +                   "", // GPIO37
> > +                   "CD0_SDA", // GPIO38
> > +                   "CD0_SCL", // GPIO39
> > +                   "CD1_SDA", // GPIO40
> > +                   "CD1_SCL", // GPIO41
> > +                   "USB_VBUS_EN", // GPIO42
> > +                   "USB_OC_N", // GPIO43
> > +                   "RP1_STAT_LED", // GPIO44
> > +                   "FAN_PWM", // GPIO45
> > +                   "CD1_IO0_MICCLK", // GPIO46
> > +                   "2712_WAKE", // GPIO47
> > +                   "CD1_IO1_MICDAT1", // GPIO48
> > +                   "EN_MAX_USB_CUR", // GPIO49
> > +                   "", // GPIO50
> > +                   "", // GPIO51
> > +                   "", // GPIO52
> > +                   ""; // GPIO53
> > +
> > +            rp1_uart0_14_15: rp1_uart0_14_15 {
> > +                pin_txd {
> > +                    function = "uart0";
> > +                    pins = "gpio14";
> > +                    bias-disable;
> > +                };
> > +
> > +                pin_rxd {
> > +                    function = "uart0";
> > +                    pins = "gpio15";
> > +                    bias-pull-up;
> > +                };
> > +            };
> > +        };
> > +    };
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 6e7db9bce278..c5018232c251 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -19120,7 +19120,9 @@ RASPBERRY PI RP1 PCI DRIVER
> >  M:	Andrea della Porta <andrea.porta@suse.com>
> >  S:	Maintained
> >  F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> > +F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
> >  F:	include/dt-bindings/clock/rp1.h
> > +F:	include/dt-bindings/misc/rp1.h
> >  
> >  RC-CORE / LIRC FRAMEWORK
> >  M:	Sean Young <sean@mess.org>
> > diff --git a/include/dt-bindings/misc/rp1.h b/include/dt-bindings/misc/rp1.h
> 
> Filename should base on the compatible.

include/dt-bindings/misc/rp1.h is just a shared header currently included from:

- arch/arm64/boot/dts/broadcom/rp1.dtso (use RP1_INT_IO_BANKx)
- drivers/misc/rp1/rp1-pci.c		(use RP1_INT_END)
- Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml (use RP1_INT_IO_BANKx)

and the driver it is logically bound to (misc/rp1-pci.c) has no compatible, since it is a
PCI driver.
If you consider feasible to drop those interrupt defines in yaml bindings (please, see below), 
then I can just drop the entire header placing those defines inside rp1-pci.c, otherwise
we should come up with a new filename. If this is the case, I kindly ask for a suggestion.

> 
> The same applies to clocks bindings.

Ack.

> 
> > new file mode 100644
> > index 000000000000..6dd5e23870c2
> > --- /dev/null
> > +++ b/include/dt-bindings/misc/rp1.h
> > @@ -0,0 +1,235 @@
> > +/* SPDX-License-Identifier: GPL-2.0 OR MIT */
> > +/*
> > + * This header provides constants for the PY MFD.
> > + */
> > +
> > +#ifndef _RP1_H
> > +#define _RP1_H
> 
> That's very poor header guard...

Ack.

> 
> > +
> > +/* Address map */
> > +#define RP1_SYSINFO_BASE 0x000000
> > +#define RP1_TBMAN_BASE 0x004000
> 
> Nope, addresses are not bindings. Drop entire header.

I've dropped the address part.

> 
> 
> > +#define RP1_SYSCFG_BASE 0x008000
> > +#define RP1_OTP_BASE 0x00c000
> > +#define RP1_POWER_BASE 0x010000
> > +#define RP1_RESETS_BASE 0x014000
> > +#define RP1_CLOCKS_BANK_DEFAULT_BASE 0x018000
> > +#define RP1_CLOCKS_BANK_VIDEO_BASE 0x01c000
> > +#define RP1_PLL_SYS_BASE 0x020000
> > +#define RP1_PLL_AUDIO_BASE 0x024000
> > +#define RP1_PLL_VIDEO_BASE 0x028000
> > +#define RP1_UART0_BASE 0x030000
> > +#define RP1_UART1_BASE 0x034000
> > +#define RP1_UART2_BASE 0x038000
> > +#define RP1_UART3_BASE 0x03c000
> > +#define RP1_UART4_BASE 0x040000
> > +#define RP1_UART5_BASE 0x044000
> > +#define RP1_SPI8_BASE 0x04c000
> > +#define RP1_SPI0_BASE 0x050000
> > +#define RP1_SPI1_BASE 0x054000
> > +#define RP1_SPI2_BASE 0x058000
> > +#define RP1_SPI3_BASE 0x05c000
> > +#define RP1_SPI4_BASE 0x060000
> > +#define RP1_SPI5_BASE 0x064000
> > +#define RP1_SPI6_BASE 0x068000
> > +#define RP1_SPI7_BASE 0x06c000
> > +#define RP1_I2C0_BASE 0x070000
> > +#define RP1_I2C1_BASE 0x074000
> > +#define RP1_I2C2_BASE 0x078000
> > +#define RP1_I2C3_BASE 0x07c000
> > +#define RP1_I2C4_BASE 0x080000
> > +#define RP1_I2C5_BASE 0x084000
> > +#define RP1_I2C6_BASE 0x088000
> > +#define RP1_AUDIO_IN_BASE 0x090000
> > +#define RP1_AUDIO_OUT_BASE 0x094000
> > +#define RP1_PWM0_BASE 0x098000
> > +#define RP1_PWM1_BASE 0x09c000
> > +#define RP1_I2S0_BASE 0x0a0000
> > +#define RP1_I2S1_BASE 0x0a4000
> > +#define RP1_I2S2_BASE 0x0a8000
> > +#define RP1_TIMER_BASE 0x0ac000
> > +#define RP1_SDIO0_APBS_BASE 0x0b0000
> > +#define RP1_SDIO1_APBS_BASE 0x0b4000
> > +#define RP1_BUSFABRIC_MONITOR_BASE 0x0c0000
> > +#define RP1_BUSFABRIC_AXISHIM_BASE 0x0c4000
> > +#define RP1_ADC_BASE 0x0c8000
> > +#define RP1_IO_BANK0_BASE 0x0d0000
> > +#define RP1_IO_BANK1_BASE 0x0d4000
> > +#define RP1_IO_BANK2_BASE 0x0d8000
> > +#define RP1_SYS_RIO0_BASE 0x0e0000
> > +#define RP1_SYS_RIO1_BASE 0x0e4000
> > +#define RP1_SYS_RIO2_BASE 0x0e8000
> > +#define RP1_PADS_BANK0_BASE 0x0f0000
> > +#define RP1_PADS_BANK1_BASE 0x0f4000
> > +#define RP1_PADS_BANK2_BASE 0x0f8000
> > +#define RP1_PADS_ETH_BASE 0x0fc000
> > +#define RP1_ETH_IP_BASE 0x100000
> > +#define RP1_ETH_CFG_BASE 0x104000
> > +#define RP1_PCIE_APBS_BASE 0x108000
> > +#define RP1_MIPI0_CSIDMA_BASE 0x110000
> > +#define RP1_MIPI0_CSIHOST_BASE 0x114000
> > +#define RP1_MIPI0_DSIDMA_BASE 0x118000
> > +#define RP1_MIPI0_DSIHOST_BASE 0x11c000
> > +#define RP1_MIPI0_MIPICFG_BASE 0x120000
> > +#define RP1_MIPI0_ISP_BASE 0x124000
> > +#define RP1_MIPI1_CSIDMA_BASE 0x128000
> > +#define RP1_MIPI1_CSIHOST_BASE 0x12c000
> > +#define RP1_MIPI1_DSIDMA_BASE 0x130000
> > +#define RP1_MIPI1_DSIHOST_BASE 0x134000
> > +#define RP1_MIPI1_MIPICFG_BASE 0x138000
> > +#define RP1_MIPI1_ISP_BASE 0x13c000
> > +#define RP1_VIDEO_OUT_CFG_BASE 0x140000
> > +#define RP1_VIDEO_OUT_VEC_BASE 0x144000
> > +#define RP1_VIDEO_OUT_DPI_BASE 0x148000
> > +#define RP1_XOSC_BASE 0x150000
> > +#define RP1_WATCHDOG_BASE 0x154000
> > +#define RP1_DMA_TICK_BASE 0x158000
> > +#define RP1_SDIO_CLOCKS_BASE 0x15c000
> > +#define RP1_USBHOST0_APBS_BASE 0x160000
> > +#define RP1_USBHOST1_APBS_BASE 0x164000
> > +#define RP1_ROSC0_BASE 0x168000
> > +#define RP1_ROSC1_BASE 0x16c000
> > +#define RP1_VBUSCTRL_BASE 0x170000
> > +#define RP1_TICKS_BASE 0x174000
> > +#define RP1_PIO_APBS_BASE 0x178000
> > +#define RP1_SDIO0_AHBLS_BASE 0x180000
> > +#define RP1_SDIO1_AHBLS_BASE 0x184000
> > +#define RP1_DMA_BASE 0x188000
> > +#define RP1_RAM_BASE 0x1c0000
> > +#define RP1_RAM_SIZE 0x020000
> > +#define RP1_USBHOST0_AXIS_BASE 0x200000
> > +#define RP1_USBHOST1_AXIS_BASE 0x300000
> > +#define RP1_EXAC_BASE 0x400000
> > +
> > +/* Interrupts */
> > +
> > +#define RP1_INT_IO_BANK0 0
> > +#define RP1_INT_IO_BANK1 1
> 
> Also no, interrupt numbers are not considered bindings. That's too much
> churn. Otherwise, please point me to driver code using the define
> (directly! that's the requirement).

As mentioned above, RP1_INT_END is used in rp1-pci.c. To get rid of all those
macroes from dt-binding would mean to hardcode the interrupt number in both
the binding example and in dtso, from this:

interrupts = <RP1_INT_IO_BANK0 IRQ_TYPE_LEVEL_HIGH>,
             <RP1_INT_IO_BANK1 IRQ_TYPE_LEVEL_HIGH>,
             <RP1_INT_IO_BANK2 IRQ_TYPE_LEVEL_HIGH>;

to this:

interrupts = <0 IRQ_TYPE_LEVEL_HIGH>,
	     <1 IRQ_TYPE_LEVEL_HIGH>,
             <2 IRQ_TYPE_LEVEL_HIGH>;

is this what you are proposing?

Many thanks,
Andrea

> 
> Best regards,
> Krzysztof
> 

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

* Re: [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support
  2024-08-21  8:45   ` Krzysztof Kozlowski
@ 2024-08-30 10:39     ` Andrea della Porta
  0 siblings, 0 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-08-30 10:39 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Krzysztof,

On 10:45 Wed 21 Aug     , Krzysztof Kozlowski wrote:
> On Tue, Aug 20, 2024 at 04:36:09PM +0200, Andrea della Porta wrote:
> > The RP1 is an MFD supporting a gpio controller and /pinmux/pinctrl.
> > Add minimum support for the gpio only portion. The driver is in
> > pinctrl folder since upcoming patches will add the pinmux/pinctrl
> > support where the gpio part can be seen as an addition.
> > 
> > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> > ---
> >  MAINTAINERS                   |   1 +
> >  drivers/pinctrl/Kconfig       |  10 +
> >  drivers/pinctrl/Makefile      |   1 +
> >  drivers/pinctrl/pinctrl-rp1.c | 719 ++++++++++++++++++++++++++++++++++
> >  4 files changed, 731 insertions(+)
> >  create mode 100644 drivers/pinctrl/pinctrl-rp1.c
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 4ce7b049d67e..67f460c36ea1 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -19122,6 +19122,7 @@ S:	Maintained
> >  F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> >  F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
> >  F:	drivers/clk/clk-rp1.c
> > +F:	drivers/pinctrl/pinctrl-rp1.c
> >  F:	include/dt-bindings/clock/rp1.h
> >  F:	include/dt-bindings/misc/rp1.h
> >  
> > diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
> > index 7e4f93a3bc7a..18bb1a8bd102 100644
> > --- a/drivers/pinctrl/Kconfig
> > +++ b/drivers/pinctrl/Kconfig
> > @@ -565,6 +565,16 @@ config PINCTRL_MLXBF3
> >  	  each pin. This driver can also be built as a module called
> >  	  pinctrl-mlxbf3.
> >  
> > +config PINCTRL_RP1
> > +	bool "Pinctrl driver for RP1"
> > +	select PINMUX
> > +	select PINCONF
> > +	select GENERIC_PINCONF
> > +	select GPIOLIB_IRQCHIP
> > +	help
> > +	  Enable the gpio and pinctrl/mux  driver for RaspberryPi RP1
> > +	  multi function device. 
> > +
> >  source "drivers/pinctrl/actions/Kconfig"
> >  source "drivers/pinctrl/aspeed/Kconfig"
> >  source "drivers/pinctrl/bcm/Kconfig"
> > diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
> > index cc809669405a..f1ca23b563f6 100644
> > --- a/drivers/pinctrl/Makefile
> > +++ b/drivers/pinctrl/Makefile
> > @@ -45,6 +45,7 @@ obj-$(CONFIG_PINCTRL_PIC32)	+= pinctrl-pic32.o
> >  obj-$(CONFIG_PINCTRL_PISTACHIO)	+= pinctrl-pistachio.o
> >  obj-$(CONFIG_PINCTRL_RK805)	+= pinctrl-rk805.o
> >  obj-$(CONFIG_PINCTRL_ROCKCHIP)	+= pinctrl-rockchip.o
> > +obj-$(CONFIG_PINCTRL_RP1)       += pinctrl-rp1.o
> >  obj-$(CONFIG_PINCTRL_SCMI)	+= pinctrl-scmi.o
> >  obj-$(CONFIG_PINCTRL_SINGLE)	+= pinctrl-single.o
> >  obj-$(CONFIG_PINCTRL_ST) 	+= pinctrl-st.o
> > diff --git a/drivers/pinctrl/pinctrl-rp1.c b/drivers/pinctrl/pinctrl-rp1.c
> > new file mode 100644
> > index 000000000000..c035d2014505
> > --- /dev/null
> > +++ b/drivers/pinctrl/pinctrl-rp1.c
> > @@ -0,0 +1,719 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Driver for Raspberry Pi RP1 GPIO unit
> > + *
> > + * Copyright (C) 2023 Raspberry Pi Ltd.
> > + *
> > + * This driver is inspired by:
> > + * pinctrl-bcm2835.c, please see original file for copyright information
> > + */
> > +
> > +#include <linux/bitmap.h>
> > +#include <linux/bitops.h>
> > +#include <linux/bug.h>
> > +#include <linux/delay.h>
> > +#include <linux/device.h>
> > +#include <linux/err.h>
> > +#include <linux/gpio/driver.h>
> > +#include <linux/io.h>
> > +#include <linux/irq.h>
> > +#include <linux/irqdesc.h>
> > +#include <linux/init.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/seq_file.h>
> > +#include <linux/spinlock.h>
> > +#include <linux/types.h>
> 
> Half of these headers are not used. Drop them.

Ack.

Many thanks,
Andrea

> 
> Best regards,
> Krzysztof
> 

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

* Re: [PATCH 02/11] dt-bindings: pinctrl: Add RaspberryPi RP1 gpio/pinctrl/pinmux bindings
  2024-08-30 10:22     ` Andrea della Porta
@ 2024-08-30 11:46       ` Krzysztof Kozlowski
  2024-09-02  8:44         ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Krzysztof Kozlowski @ 2024-08-30 11:46 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On 30/08/2024 12:22, Andrea della Porta wrote:
> Hi Krzysztof,
> 

...

>>> +#define RP1_USBHOST0_AXIS_BASE 0x200000
>>> +#define RP1_USBHOST1_AXIS_BASE 0x300000
>>> +#define RP1_EXAC_BASE 0x400000
>>> +
>>> +/* Interrupts */
>>> +
>>> +#define RP1_INT_IO_BANK0 0
>>> +#define RP1_INT_IO_BANK1 1
>>
>> Also no, interrupt numbers are not considered bindings. That's too much
>> churn. Otherwise, please point me to driver code using the define
>> (directly! that's the requirement).
> 
> As mentioned above, RP1_INT_END is used in rp1-pci.c. To get rid of all those

Number of interrupts is not a binding, either. Does not appear in the DTS.

> macroes from dt-binding would mean to hardcode the interrupt number in both
> the binding example and in dtso, from this:
> 
> interrupts = <RP1_INT_IO_BANK0 IRQ_TYPE_LEVEL_HIGH>,
>              <RP1_INT_IO_BANK1 IRQ_TYPE_LEVEL_HIGH>,
>              <RP1_INT_IO_BANK2 IRQ_TYPE_LEVEL_HIGH>;
> 
> to this:
> 
> interrupts = <0 IRQ_TYPE_LEVEL_HIGH>,
> 	     <1 IRQ_TYPE_LEVEL_HIGH>,
>              <2 IRQ_TYPE_LEVEL_HIGH>;
> 
> is this what you are proposing?

Yes, just like every DTS does. I think the hard-coding of numbers is not
a problem.

Best regards,
Krzysztof


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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-21  8:38   ` Krzysztof Kozlowski
  2024-08-21 14:20     ` Krzysztof Kozlowski
@ 2024-08-30 13:49     ` Andrea della Porta
  2024-08-30 14:21       ` Andrew Lunn
  2024-08-30 16:52       ` Krzysztof Kozlowski
  1 sibling, 2 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-08-30 13:49 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Krzysztof,

On 10:38 Wed 21 Aug     , Krzysztof Kozlowski wrote:
> On Tue, Aug 20, 2024 at 04:36:10PM +0200, Andrea della Porta wrote:
> > The RaspberryPi RP1 is ia PCI multi function device containing
> > peripherals ranging from Ethernet to USB controller, I2C, SPI
> > and others.
> > Implement a bare minimum driver to operate the RP1, leveraging
> > actual OF based driver implementations for the on-borad peripherals
> > by loading a devicetree overlay during driver probe.
> > The peripherals are accessed by mapping MMIO registers starting
> > from PCI BAR1 region.
> > As a minimum driver, the peripherals will not be added to the
> > dtbo here, but in following patches.
> > 
> > Link: https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
> > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> > ---
> >  MAINTAINERS                           |   2 +
> >  arch/arm64/boot/dts/broadcom/rp1.dtso | 152 ++++++++++++
> 
> Do not mix DTS with drivers.
> 
> These MUST be separate.

Separating the dtso from the driver in two different patches would mean
that the dtso patch would be ordered before the driver one. This is because
the driver embeds the dtbo binary blob inside itself, at build time. So
in order to build the driver, the dtso needs to be there also. This is not
the standard approach used with 'normal' dtb/dtbo, where the dtb patch is
ordered last wrt the driver it refers to.
Are you sure you want to proceed in this way?

> 
> >  drivers/misc/Kconfig                  |   1 +
> >  drivers/misc/Makefile                 |   1 +
> >  drivers/misc/rp1/Kconfig              |  20 ++
> >  drivers/misc/rp1/Makefile             |   3 +
> >  drivers/misc/rp1/rp1-pci.c            | 333 ++++++++++++++++++++++++++
> >  drivers/misc/rp1/rp1-pci.dtso         |   8 +
> >  drivers/pci/quirks.c                  |   1 +
> >  include/linux/pci_ids.h               |   3 +
> >  10 files changed, 524 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/broadcom/rp1.dtso
> >  create mode 100644 drivers/misc/rp1/Kconfig
> >  create mode 100644 drivers/misc/rp1/Makefile
> >  create mode 100644 drivers/misc/rp1/rp1-pci.c
> >  create mode 100644 drivers/misc/rp1/rp1-pci.dtso
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 67f460c36ea1..1359538b76e8 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -19119,9 +19119,11 @@ F:	include/uapi/linux/media/raspberrypi/
> >  RASPBERRY PI RP1 PCI DRIVER
> >  M:	Andrea della Porta <andrea.porta@suse.com>
> >  S:	Maintained
> > +F:	arch/arm64/boot/dts/broadcom/rp1.dtso
> >  F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> >  F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
> >  F:	drivers/clk/clk-rp1.c
> > +F:	drivers/misc/rp1/
> >  F:	drivers/pinctrl/pinctrl-rp1.c
> >  F:	include/dt-bindings/clock/rp1.h
> >  F:	include/dt-bindings/misc/rp1.h
> > diff --git a/arch/arm64/boot/dts/broadcom/rp1.dtso b/arch/arm64/boot/dts/broadcom/rp1.dtso
> > new file mode 100644
> > index 000000000000..d80178a278ee
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/broadcom/rp1.dtso
> > @@ -0,0 +1,152 @@
> > +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> > +
> > +#include <dt-bindings/gpio/gpio.h>
> > +#include <dt-bindings/interrupt-controller/irq.h>
> > +#include <dt-bindings/clock/rp1.h>
> > +#include <dt-bindings/misc/rp1.h>
> > +
> > +/dts-v1/;
> > +/plugin/;
> > +
> > +/ {
> > +	fragment@0 {
> > +		target-path="";
> > +		__overlay__ {
> > +			#address-cells = <3>;
> > +			#size-cells = <2>;
> > +
> > +			rp1: rp1@0 {
> > +				compatible = "simple-bus";
> > +				#address-cells = <2>;
> > +				#size-cells = <2>;
> > +				interrupt-controller;
> > +				interrupt-parent = <&rp1>;
> > +				#interrupt-cells = <2>;
> > +
> > +				// ranges and dma-ranges must be provided by the includer
> > +				ranges = <0xc0 0x40000000
> > +					  0x01/*0x02000000*/ 0x00 0x00000000
> > +					  0x00 0x00400000>;
> 
> Are you 100% sure you do not have here dtc W=1 warnings?

the W=1 warnings are:

arch/arm64/boot/dts/broadcom/rp1.dtso:37.24-42.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/clk_xosc: missing or empty reg/ranges property
arch/arm64/boot/dts/broadcom/rp1.dtso:44.26-49.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/macb_pclk: missing or empty reg/ranges property
arch/arm64/boot/dts/broadcom/rp1.dtso:51.26-56.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/macb_hclk: missing or empty reg/ranges property
arch/arm64/boot/dts/broadcom/rp1.dtso:14.15-173.5: Warning (avoid_unnecessary_addr_size): /fragment@0/__overlay__: unnecessary #address-cells/#size-cells without "ranges", "dma-ranges" or child "reg" property

I don't see anything related to the ranges line you mentioned.

> 
> > +
> > +				dma-ranges =
> > +				// inbound RP1 1x_xxxxxxxx -> PCIe 1x_xxxxxxxx
> > +					     <0x10 0x00000000
> > +					      0x43000000 0x10 0x00000000
> > +					      0x10 0x00000000>;
> > +
> > +				clk_xosc: clk_xosc {
> 
> Nope, switch to DTS coding style.

Ack.

> 
> > +					compatible = "fixed-clock";
> > +					#clock-cells = <0>;
> > +					clock-output-names = "xosc";
> > +					clock-frequency = <50000000>;
> > +				};
> > +
> > +				macb_pclk: macb_pclk {
> > +					compatible = "fixed-clock";
> > +					#clock-cells = <0>;
> > +					clock-output-names = "pclk";
> > +					clock-frequency = <200000000>;
> > +				};
> > +
> > +				macb_hclk: macb_hclk {
> > +					compatible = "fixed-clock";
> > +					#clock-cells = <0>;
> > +					clock-output-names = "hclk";
> > +					clock-frequency = <200000000>;
> > +				};
> > +
> > +				rp1_clocks: clocks@c040018000 {
> 
> Why do you mix MMIO with non-MMIO nodes? This really does not look
> correct.
>

Right. This is already under discussion here:
https://lore.kernel.org/all/ZtBzis5CzQMm8loh@apocalypse/

IIUC you proposed to instantiate the non-MMIO nodes (the three clocks) by
using CLK_OF_DECLARE.
 
> > +					compatible = "raspberrypi,rp1-clocks";
> > +					#clock-cells = <1>;
> > +					reg = <0xc0 0x40018000 0x0 0x10038>;
> 
> Wrong order of properties - see DTS coding style.

Ack.

Many thanks,
Andrea

> 
> > +					clocks = <&clk_xosc>;
> > +					clock-names = "xosc";
> 
> Best regards,
> Krzysztof
> 

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

* Re: [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay
  2024-08-30  5:21           ` Andrea della Porta
@ 2024-08-30 14:10             ` Andrew Lunn
  2024-09-02  9:21               ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Andrew Lunn @ 2024-08-30 14:10 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Krzysztof Kozlowski, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Stefan Wahren

> On a second thought, are you really sure we want to proceed with the header file?
> After all the only line in it would be the extern declaration and the only one to
> include it would be rp1-dev.c. Moreover, an header file would convey the false
> premise that you can include it and use that symbol while in fact it should be
> only used inside the driver.
> OTOH, not creating that header file will continue to trigger the warning...

The header file does not need to be in global scope. It could be in
the driver source directory. As such, nothing outside of the driver
can use it.

Headers like this have multiple proposes. One is they make a symbol
visible to the linker. But having two different .c files include the
header enables type checking, which for long term maintenance is just
as important. So a one line header is fine.

	Andrew


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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-30 13:49     ` Andrea della Porta
@ 2024-08-30 14:21       ` Andrew Lunn
  2024-09-03 14:56         ` Andrea della Porta
  2024-08-30 16:52       ` Krzysztof Kozlowski
  1 sibling, 1 reply; 117+ messages in thread
From: Andrew Lunn @ 2024-08-30 14:21 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Krzysztof Kozlowski, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Stefan Wahren

On Fri, Aug 30, 2024 at 03:49:04PM +0200, Andrea della Porta wrote:
> Hi Krzysztof,
> 
> On 10:38 Wed 21 Aug     , Krzysztof Kozlowski wrote:
> > On Tue, Aug 20, 2024 at 04:36:10PM +0200, Andrea della Porta wrote:
> > > The RaspberryPi RP1 is ia PCI multi function device containing
> > > peripherals ranging from Ethernet to USB controller, I2C, SPI
> > > and others.
> > > Implement a bare minimum driver to operate the RP1, leveraging
> > > actual OF based driver implementations for the on-borad peripherals
> > > by loading a devicetree overlay during driver probe.
> > > The peripherals are accessed by mapping MMIO registers starting
> > > from PCI BAR1 region.
> > > As a minimum driver, the peripherals will not be added to the
> > > dtbo here, but in following patches.
> > > 
> > > Link: https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
> > > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> > > ---
> > >  MAINTAINERS                           |   2 +
> > >  arch/arm64/boot/dts/broadcom/rp1.dtso | 152 ++++++++++++
> > 
> > Do not mix DTS with drivers.
> > 
> > These MUST be separate.
> 
> Separating the dtso from the driver in two different patches would mean
> that the dtso patch would be ordered before the driver one. This is because
> the driver embeds the dtbo binary blob inside itself, at build time. So
> in order to build the driver, the dtso needs to be there also. This is not
> the standard approach used with 'normal' dtb/dtbo, where the dtb patch is
> ordered last wrt the driver it refers to.
> Are you sure you want to proceed in this way?

It is more about they are logically separate things. The .dtb/dtbo
describes the hardware. It should be possible to review that as a
standalone thing. The code them implements the binding. It makes no
sense to review the code until the binding is correct, because changes
to the binding will need changes to the code. Hence, we want the
binding first, then the code which implements it.

	Andrew

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-30 13:49     ` Andrea della Porta
  2024-08-30 14:21       ` Andrew Lunn
@ 2024-08-30 16:52       ` Krzysztof Kozlowski
  2024-09-03 15:15         ` Andrea della Porta
  1 sibling, 1 reply; 117+ messages in thread
From: Krzysztof Kozlowski @ 2024-08-30 16:52 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On 30/08/2024 15:49, Andrea della Porta wrote:
> Hi Krzysztof,
> 
> On 10:38 Wed 21 Aug     , Krzysztof Kozlowski wrote:
>> On Tue, Aug 20, 2024 at 04:36:10PM +0200, Andrea della Porta wrote:
>>> The RaspberryPi RP1 is ia PCI multi function device containing
>>> peripherals ranging from Ethernet to USB controller, I2C, SPI
>>> and others.
>>> Implement a bare minimum driver to operate the RP1, leveraging
>>> actual OF based driver implementations for the on-borad peripherals
>>> by loading a devicetree overlay during driver probe.
>>> The peripherals are accessed by mapping MMIO registers starting
>>> from PCI BAR1 region.
>>> As a minimum driver, the peripherals will not be added to the
>>> dtbo here, but in following patches.
>>>
>>> Link: https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
>>> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
>>> ---
>>>  MAINTAINERS                           |   2 +
>>>  arch/arm64/boot/dts/broadcom/rp1.dtso | 152 ++++++++++++
>>
>> Do not mix DTS with drivers.
>>
>> These MUST be separate.
> 
> Separating the dtso from the driver in two different patches would mean
> that the dtso patch would be ordered before the driver one. This is because
> the driver embeds the dtbo binary blob inside itself, at build time. So
> in order to build the driver, the dtso needs to be there also. This is not

Sure, in such case DTS will have to go through the same tree as driver
as an exception. Please document it in patch changelog (---).

> the standard approach used with 'normal' dtb/dtbo, where the dtb patch is
> ordered last wrt the driver it refers to.

It's not exactly the "ordered last" that matters, but lack of dependency
and going through separate tree and branch - arm-soc/dts. Here there
will be an exception how we handle patch, but still DTS is hardware
description so should not be combined with driver code.

> Are you sure you want to proceed in this way?


> 
>>
>>>  drivers/misc/Kconfig                  |   1 +
>>>  drivers/misc/Makefile                 |   1 +
>>>  drivers/misc/rp1/Kconfig              |  20 ++
>>>  drivers/misc/rp1/Makefile             |   3 +
>>>  drivers/misc/rp1/rp1-pci.c            | 333 ++++++++++++++++++++++++++
>>>  drivers/misc/rp1/rp1-pci.dtso         |   8 +
>>>  drivers/pci/quirks.c                  |   1 +
>>>  include/linux/pci_ids.h               |   3 +
>>>  10 files changed, 524 insertions(+)
>>>  create mode 100644 arch/arm64/boot/dts/broadcom/rp1.dtso
>>>  create mode 100644 drivers/misc/rp1/Kconfig
>>>  create mode 100644 drivers/misc/rp1/Makefile
>>>  create mode 100644 drivers/misc/rp1/rp1-pci.c
>>>  create mode 100644 drivers/misc/rp1/rp1-pci.dtso
>>>
>>> diff --git a/MAINTAINERS b/MAINTAINERS
>>> index 67f460c36ea1..1359538b76e8 100644
>>> --- a/MAINTAINERS
>>> +++ b/MAINTAINERS
>>> @@ -19119,9 +19119,11 @@ F:	include/uapi/linux/media/raspberrypi/
>>>  RASPBERRY PI RP1 PCI DRIVER
>>>  M:	Andrea della Porta <andrea.porta@suse.com>
>>>  S:	Maintained
>>> +F:	arch/arm64/boot/dts/broadcom/rp1.dtso
>>>  F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
>>>  F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
>>>  F:	drivers/clk/clk-rp1.c
>>> +F:	drivers/misc/rp1/
>>>  F:	drivers/pinctrl/pinctrl-rp1.c
>>>  F:	include/dt-bindings/clock/rp1.h
>>>  F:	include/dt-bindings/misc/rp1.h
>>> diff --git a/arch/arm64/boot/dts/broadcom/rp1.dtso b/arch/arm64/boot/dts/broadcom/rp1.dtso
>>> new file mode 100644
>>> index 000000000000..d80178a278ee
>>> --- /dev/null
>>> +++ b/arch/arm64/boot/dts/broadcom/rp1.dtso
>>> @@ -0,0 +1,152 @@
>>> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
>>> +
>>> +#include <dt-bindings/gpio/gpio.h>
>>> +#include <dt-bindings/interrupt-controller/irq.h>
>>> +#include <dt-bindings/clock/rp1.h>
>>> +#include <dt-bindings/misc/rp1.h>
>>> +
>>> +/dts-v1/;
>>> +/plugin/;
>>> +
>>> +/ {
>>> +	fragment@0 {
>>> +		target-path="";
>>> +		__overlay__ {
>>> +			#address-cells = <3>;
>>> +			#size-cells = <2>;
>>> +
>>> +			rp1: rp1@0 {
>>> +				compatible = "simple-bus";
>>> +				#address-cells = <2>;
>>> +				#size-cells = <2>;
>>> +				interrupt-controller;
>>> +				interrupt-parent = <&rp1>;
>>> +				#interrupt-cells = <2>;
>>> +
>>> +				// ranges and dma-ranges must be provided by the includer
>>> +				ranges = <0xc0 0x40000000
>>> +					  0x01/*0x02000000*/ 0x00 0x00000000
>>> +					  0x00 0x00400000>;
>>
>> Are you 100% sure you do not have here dtc W=1 warnings?
> 
> the W=1 warnings are:
> 
> arch/arm64/boot/dts/broadcom/rp1.dtso:37.24-42.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/clk_xosc: missing or empty reg/ranges property
> arch/arm64/boot/dts/broadcom/rp1.dtso:44.26-49.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/macb_pclk: missing or empty reg/ranges property
> arch/arm64/boot/dts/broadcom/rp1.dtso:51.26-56.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/macb_hclk: missing or empty reg/ranges property
> arch/arm64/boot/dts/broadcom/rp1.dtso:14.15-173.5: Warning (avoid_unnecessary_addr_size): /fragment@0/__overlay__: unnecessary #address-cells/#size-cells without "ranges", "dma-ranges" or child "reg" property
> 
> I don't see anything related to the ranges line you mentioned.

Hm, indeed, but I would expect warning about unit address not matching
ranges/reg.

> 
>>
>>> +
>>> +				dma-ranges =
>>> +				// inbound RP1 1x_xxxxxxxx -> PCIe 1x_xxxxxxxx
>>> +					     <0x10 0x00000000
>>> +					      0x43000000 0x10 0x00000000
>>> +					      0x10 0x00000000>;
>>> +
>>> +				clk_xosc: clk_xosc {
>>
>> Nope, switch to DTS coding style.
> 
> Ack.
> 
>>
>>> +					compatible = "fixed-clock";
>>> +					#clock-cells = <0>;
>>> +					clock-output-names = "xosc";
>>> +					clock-frequency = <50000000>;
>>> +				};
>>> +
>>> +				macb_pclk: macb_pclk {
>>> +					compatible = "fixed-clock";
>>> +					#clock-cells = <0>;
>>> +					clock-output-names = "pclk";
>>> +					clock-frequency = <200000000>;
>>> +				};
>>> +
>>> +				macb_hclk: macb_hclk {
>>> +					compatible = "fixed-clock";
>>> +					#clock-cells = <0>;
>>> +					clock-output-names = "hclk";
>>> +					clock-frequency = <200000000>;
>>> +				};
>>> +
>>> +				rp1_clocks: clocks@c040018000 {
>>
>> Why do you mix MMIO with non-MMIO nodes? This really does not look
>> correct.
>>
> 
> Right. This is already under discussion here:
> https://lore.kernel.org/all/ZtBzis5CzQMm8loh@apocalypse/
> 
> IIUC you proposed to instantiate the non-MMIO nodes (the three clocks) by
> using CLK_OF_DECLARE.

Depends. Where are these clocks? Naming suggests they might not be even
part of this device. But if these are part of the device, then why this
is not a clock controller (if they are controllable) or even removed
(because we do not represent internal clock tree in DTS).

Best regards,
Krzysztof


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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-23 16:31         ` Andrea della Porta
@ 2024-08-30 18:27           ` Rob Herring
  2024-09-02  9:34             ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Rob Herring @ 2024-08-30 18:27 UTC (permalink / raw)
  To: Stefan Wahren, Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn

On Fri, Aug 23, 2024 at 11:31 AM Andrea della Porta
<andrea.porta@suse.com> wrote:
>
> Hi Stefan,
>
> On 12:23 Fri 23 Aug     , Stefan Wahren wrote:
> > Hi Andrea,
> >
> > Am 23.08.24 um 11:44 schrieb Andrea della Porta:
> > > Hi Stefan,
> > >
> > > On 18:20 Wed 21 Aug     , Stefan Wahren wrote:
> > > > Hi Andrea,
> > > >
> > > > Am 20.08.24 um 16:36 schrieb Andrea della Porta:
> > > > > The RaspberryPi RP1 is ia PCI multi function device containing
> > > > > peripherals ranging from Ethernet to USB controller, I2C, SPI
> > > > > and others.
> > > > sorry, i cannot provide you a code review, but just some comments. multi
> > > > function device suggests "mfd" subsystem or at least "soc" . I won't
> > > > recommend misc driver here.
> > > It's true that RP1 can be called an MFD but the reason for not placing
> > > it in mfd subsystem are twofold:
> > >
> > > - these discussions are quite clear about this matter: please see [1]
> > >    and [2]
> > > - the current driver use no mfd API at all
> > >
> > > This RP1 driver is not currently addressing any aspect of ARM core in the
> > > SoC so I would say it should not stay in drivers/soc / either, as also
> > > condifirmed by [2] again and [3] (note that Microchip LAN966x is a very
> > > close fit to what we have here on RP1).
> > thanks i was aware of these discussions. A pointer to them or at least a
> > short statement in the cover letter would be great.
>
> Sure, consider it done.
>
> > >
> > > > > Implement a bare minimum driver to operate the RP1, leveraging
> > > > > actual OF based driver implementations for the on-borad peripherals
> > > > > by loading a devicetree overlay during driver probe.
> > > > Can you please explain why this should be a DT overlay? The RP1 is
> > > > assembled on the Raspberry Pi 5 PCB. DT overlays are typically for loose
> > > > connections like displays or HATs. I think a DTSI just for the RP1 would
> > > > fit better and is easier to read.
> > > The dtsi solution you proposed is the one adopted downstream. It has its
> > > benefits of course, but there's more.
> > > With the overlay approach we can achieve more generic and agnostic approach
> > > to managing this chipset, being that it is a PCI endpoint and could be
> > > possibly be reused in other hw implementations. I believe a similar
> > > reasoning could be applied to Bootlin's Microchip LAN966x patchset as
> > > well, and they also choose to approach the dtb overlay.
> > Could please add this point in the commit message. Doesn't introduce
>
> Ack.
>
> > (maintainence) issues in case U-Boot needs a RP1 driver, too?
>
> Good point. Right now u-boot does not support RP1 nor PCIe (which is a
> prerequisite for RP1 to work) on Rpi5 and I'm quite sure that it will be
> so in the near future. Of course I cannot guarantee this will be the case
> far away in time.
>
> Since u-boot is lacking support for RP1 we cannot really produce some test
> results to check the compatibility versus kernel dtb overlay but we can
> speculate a little bit about it. AFAIK u-boot would probably place the rp1
> node directly under its pcie@12000 node in DT while the dtb overlay will use
> dynamically created PCI endpoint node (dev@0) as parent for rp1 node.

u-boot could do that and it would not be following the 25+ year old
PCI bus bindings. Some things may be argued about as "Linux bindings",
but that isn't one of them.

Rob

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

* Re: [PATCH 04/11] of: address: Preserve the flags portion on 1:1 dma-ranges mapping
  2024-08-29 16:26             ` Andrea della Porta
@ 2024-08-30 19:37               ` Rob Herring
  2024-09-03  9:09                 ` Herve Codina
  2024-09-03 16:15                 ` Andrea della Porta
  0 siblings, 2 replies; 117+ messages in thread
From: Rob Herring @ 2024-08-30 19:37 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren, Herve Codina, Luca Ceresoli, Thomas Petazzoni

On Thu, Aug 29, 2024 at 11:26 AM Andrea della Porta
<andrea.porta@suse.com> wrote:
>
> Hi Rob,
>
> On 08:18 Thu 29 Aug     , Rob Herring wrote:
> > On Thu, Aug 29, 2024 at 5:13 AM Andrea della Porta
> > <andrea.porta@suse.com> wrote:
> > >
> > > Hi Rob,
> >
> > BTW, I noticed your email replies set "reply-to" to everyone in To and
> > Cc. The result (with Gmail) is my reply lists everyone twice (in both
> > To and Cc). "reply-to" is just supposed to be the 1 address you want
> > replies sent to instead of the "from" address.
>
> IIUC you're probably referring to Mail-Reply-To, that address only one recipient
> at a time (i.e. you want to reply only to the author). Reply-To is a catch-all
> that will work as a fallback when you hit either reply or reply-all in your client.
> In fact, neither Reply-To nor Mail-Reply-To are included in my emails, the
> interesting one being Mail-Followup-To, that should override any of the above
> mentioned headers (including To: and Cc:) for the reply all function. How these
> headers are interpreted depends solely on the mail client, I'm afraid.
> Is it possible that your client is mistakenly merging both Mail-Followup-To
> plus To and Cc lists?

Indeed, the UI displays 'reply-to' but the source shows
Mail-Followup-To which I'd never heard of. From reading up on it, I
agree the client, Gmail web interface, handles it incorrectly. Not
really anything I can do to fix Gmail though...

> Anyway, I've disabled Mail-followup-To as it's added by mutt, can you please
> confirm that this mail now works for you? Hopefully it will not clobber the
> recipent list too much, since AFAIK that header was purposely invented to avoid
> such inconsistencies.

Seems fine now.

My brief read of the header is it is to avoid receiving multiple
copies depending if you are subscribed to a list or not. But listing
out every other address except your own seems like an odd way to
implement "omit From" in replies. You're still going to get N copies
from N lists as well. I guess it made some sense to some people...

> > > On 16:29 Mon 26 Aug     , Rob Herring wrote:
> > > > On Wed, Aug 21, 2024 at 3:19 AM Andrea della Porta
> > > > <andrea.porta@suse.com> wrote:
> > > > >
> > > > > Hi Rob,
> > > > >
> > > > > On 19:16 Tue 20 Aug     , Rob Herring wrote:
> > > > > > On Tue, Aug 20, 2024 at 04:36:06PM +0200, Andrea della Porta wrote:
> > > > > > > A missing or empty dma-ranges in a DT node implies a 1:1 mapping for dma
> > > > > > > translations. In this specific case, rhe current behaviour is to zero out
> > > > > >
> > > > > > typo
> > > > >
> > > > > Fixed, thanks!
> > > > >
> > > > > >
> > > > > > > the entire specifier so that the translation could be carried on as an
> > > > > > > offset from zero.  This includes address specifier that has flags (e.g.
> > > > > > > PCI ranges).
> > > > > > > Once the flags portion has been zeroed, the translation chain is broken
> > > > > > > since the mapping functions will check the upcoming address specifier
> > > > > >
> > > > > > What does "upcoming address" mean?
> > > > >
> > > > > Sorry for the confusion, this means "address specifier (with valid flags) fed
> > > > > to the translating functions and for which we are looking for a translation".
> > > > > While this address has some valid flags set, it will fail the translation step
> > > > > since the ranges it is matched against have flags zeroed out by the 1:1 mapping
> > > > > condition.
> > > > >
> > > > > >
> > > > > > > against mismatching flags, always failing the 1:1 mapping and its entire
> > > > > > > purpose of always succeeding.
> > > > > > > Set to zero only the address portion while passing the flags through.
> > > > > >
> > > > > > Can you point me to what the failing DT looks like. I'm puzzled how
> > > > > > things would have worked for anyone.
> > > > > >
> > > > >
> > > > > The following is a simplified and lightly edited) version of the resulting DT
> > > > > from RPi5:
> > > > >
> > > > >  pci@0,0 {
> > > > >         #address-cells = <0x03>;
> > > > >         #size-cells = <0x02>;
> > > > >         ......
> > > > >         device_type = "pci";
> > > > >         compatible = "pci14e4,2712\0pciclass,060400\0pciclass,0604";
> > > > >         ranges = <0x82000000 0x00 0x00   0x82000000 0x00 0x00   0x00 0x600000>;
> > > > >         reg = <0x00 0x00 0x00   0x00 0x00>;
> > > > >
> > > > >         ......
> > > > >
> > > > >         rp1@0 {
> > > >
> > > > What does 0 represent here? There's no 0 address in 'ranges' below.
> > > > Since you said the parent is a PCI-PCI bridge, then the unit-address
> > > > would have to be the PCI devfn and you are missing 'reg' (or omitted
> > > > it).
> > >
> > > There's no reg property because the registers for RP1 are addressed
> > > starting at 0x40108000 offset from BAR1. The devicetree specs says
> > > that a missing reg node should not have any unit address specified
> > > (and AFAIK there's no other special directives for simple-bus specified
> > > in dt-bindings).
> > > I've added @0 just to get rid of the following warning:
> > >
> > >  Warning (unit_address_vs_reg): /fragment@0/__overlay__/rp1: node has
> > >  a reg or ranges property, but no unit name
> >
> > It's still wrong as dtc only checks the unit-address is correct in a
> > few cases with known bus types.
>
> Sorry, I don't follow you on this, I'm probably missing something. Could
> you please add some details?

dtc only checks unit-address matches reg/ranges for simple-bus, pci,
i2c, and spi. Since this case is none of them, there is no warning and
it is left to reviewers to check. The warnings are often a clue
something is wrong and the easy fix is often not the right one. This
is still an area the tooling needs improvements on.

> >
> > > coming from make W=1 CHECK_DTBS=y broadcom/rp1.dtbo.
> > > This is the exact same approach used by Bootlin patchset from:
> > >
> > > https://lore.kernel.org/all/20240808154658.247873-2-herve.codina@bootlin.com/
> >
> > It is not. First, that has a node for the PCI device (i.e. the
> > LAN966x). You do not. You only have a PCI-PCI bridge and that is
> > wrong.
>
> I'm a little confused now, but I think the confusion is generated by
> the label node names I've chosen that are, admittedly, a bit sloppy.
> I'll try to make some clarity, please see below.
>
> >
> > BTW, you should Cc Herve and others that are working on this feature.
> > It is by no means fully sorted as you have found.
>
> Sure, just added, thanks for the heads up.
>
> >
> > > replied here below for convenience:
> > >
> > > +       pci-ep-bus@0 {
> > > +               compatible = "simple-bus";
> > > +               #address-cells = <1>;
> > > +               #size-cells = <1>;
> > > +
> > > +               /*
> > > +                * map @0xe2000000 (32MB) to BAR0 (CPU)
> > > +                * map @0xe0000000 (16MB) to BAR1 (AMBA)
> > > +                */
> > > +               ranges = <0xe2000000 0x00 0x00 0x00 0x2000000
> >
> > The 0 parent address here matches the unit-address, so all good in this case.
>
> Just to be sure, the parent address being the triple zeros in the ranges property,
> right?

Yes.

>
> >
> > > +                         0xe0000000 0x01 0x00 0x00 0x1000000>;
> > >
> > > Also, I think it's not possible to know the devfn in advance, since the
> > > DT part is pre-compiled as an overlay while the devfn number is coming from
> > > bus enumeration.
> >
> > No. devfn is fixed unless you are plugging in a card in different
> > slots. The bus number is the part that is not known and assigned by
> > the OS, but you'll notice that is omitted.
> >
> > In any case, the RP1 node should be generated, so its devfn is irrelevant.
>
> Which is a possibility, since the driver should possibly work also with RP1
> mounted on a PCI card, one day. But as you pointed out, since this is automatically
> generated, should not be a concern.
>
> >
> > > Since the registers for sub-peripherals will start (as stated in ranges
> > > property) from 0xc040000000, I'd be inclined to use rp1@c040000000 as the
> > > node name and address unit. Is it feasible?
> >
> > Yes, but that would be in nodes underneath ranges. Above, it is the
> > parent bus we are talking about.
>
> Right.
>
> >
> > > > >                 #address-cells = <0x02>;
> > > > >                 #size-cells = <0x02>;
> > > > >                 compatible = "simple-bus";
> > > >
> > > > The parent is a PCI-PCI bridge. Child nodes have to be PCI devices and
> > > > "simple-bus" is not a PCI device.
> > >
> > > The simple-bus is needed to automatically traverse and create platform
> > > devices in of_platform_populate(). It's true that RP1 is a PCI device,
> > > but sub-peripherals of RP1 are platform devices so I guess this is
> > > unavoidable right now.
> >
> > You are missing the point. A PCI-PCI bridge does not have a
> > simple-bus. However, I think it's just what you pasted here that's
> > wrong. From the looks of the RP1 driver and the overlay, it should be
> > correct.
>
> Trying to clarify: at first I thought of my rp1 node (in the dtso) as the pci
> endpoint device, but I now see that it should be intended as just the bus
> attached to the real endpoint device (which is the dynamically generated dev@0,0).
> In this sense, rp1 is probably a really wrong name, let's say we use the same
> name from Bootlin, i.e. pci-ep-bus. The DT tree would then be:
>
> pci@0,0         <- auto generated, this represent the pci bridge

Or root port specifically.

>   dev@0,0       <- auto generated, this represent the pci ednpoint device, a.k.a. the RP1
>     pci-ep-bus  <- added from dtbo, this is the simple-bus to which peripherals are attached
>
> this view is much like Bootlin's approach, also my pci-ep-bus node now would look
> like this:
>  ...
>  pci-ep-bus@0 {
>         ranges = <0xc0 0x40000000
>                   0x01 0x00 0x00000000
>                   0x00 0x00400000>;
>         ...
>  };
>
> and also the correct unit address here is 0 again, since the parent address in
> ranges is 0x01 0x00 0x00000000 (0x01 is the flags and in this case represent
> BAR1, I assume that for the unit address I should use only the address part that
> is 0, right?).

No, it should be 1 for BAR1. It's 1 node per BAR.

>
> >
> > It would also help if you dumped out what "lspci -tvnn" prints.
> >
>
> Here it is:
>
> localhost:~ # lspci -tvnn
> -[0002:00]---00.0-[01]----00.0  Raspberry Pi Ltd RP1 PCIe 2.0 South Bridge [1de4:0001]

Right, so that matches what you now have above.

> > > > The assumption so far with all of this is that you have some specific
> > > > PCI device (and therefore a driver). The simple-buses under it are
> > > > defined per BAR. Not really certain if that makes sense in all cases,
> > > > but since the address assignment is dynamic, it may have to. I'm also
> > > > not completely convinced we should reuse 'simple-bus' here or define
> > > > something specific like 'pci-bar-bus' or something.
> > >
> > > Good point. Labeling a new bus for this kind of 'appliance' could be
> > > beneficial to unify the dt overlay approach, and I guess it could be
> > > adopted by the aforementioned Bootlin's Microchip patchset too.
> > > However, since the difference with simple-bus would be basically non
> > > existent, I believe that this could be done in a future patch due to
> > > the fact that the dtbo is contained into the driver itself, so we do
> > > not suffer from the proliferation that happens when dtb are managed
> > > outside.
> >
> > It's an ABI, so we really need to decide first.
>
> Okay. How should we proceed?

I think simple-bus where you have it is fine. It is really 1 level up
that needs to be specified. Basically something that's referenced from
the specific PCI device's schema (e.g. the RP1 schema (which you are
missing)).

That schema needs to roughly look like this:

properties:
  "#address-cells":
    const: 3
  "#size-cells":
    const: 2
  ranges:
    minItems: 1
    maxItems: 6
    items:
      additionalItems: true
      items:
        - maximum: 5  # The BAR number
        - const: 0
        - const: 0
        - # TODO: valid PCI memory flags

patternProperties:
  "^bar-bus@[0-5]$":
    type: object
    additionalProperties: true
    properties:
      compatible:
        const: simple-bus
      ranges: true

There were some discussions around interrupt handling that might also
factor into this.

Rob

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

* Re: [PATCH 05/11] vmlinux.lds.h: Preserve DTB sections from being discarded after init
  2024-08-20 14:36 ` [PATCH 05/11] vmlinux.lds.h: Preserve DTB sections from being discarded after init Andrea della Porta
@ 2024-08-30 19:46   ` Stephen Boyd
  2024-09-03 12:29     ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Stephen Boyd @ 2024-08-30 19:46 UTC (permalink / raw)
  To: Andrea della Porta, Andrew Lunn, Arnd Bergmann, Bjorn Helgaas,
	Broadcom internal kernel review list, Catalin Marinas,
	Claudiu Beznea, Conor Dooley, David S. Miller, Derek Kiernan,
	Dragan Cvetic, Eric Dumazet, Florian Fainelli, Greg Kroah-Hartman,
	Jakub Kicinski, Krzysztof Kozlowski, Lee Jones, Linus Walleij,
	Michael Turquette, Nicolas Ferre, Paolo Abeni, Rob Herring,
	Saravana Kannan, Stefan Wahren, Will Deacon, devicetree,
	linux-arch, linux-arm-kernel, linux-clk, linux-gpio, linux-kernel,
	linux-pci, linux-rpi-kernel, netdev

Quoting Andrea della Porta (2024-08-20 07:36:07)
> The special section .dtb.init.rodata contains dtb and dtbo compiled
> as objects inside the kernel and ends up in .init.data sectiion that
> will be discarded early after the init phase. This is a problem for
> builtin drivers that apply dtb overlay at runtime since this happens
> later (e.g. during bus enumeration) and also for modules that should
> be able to do it dynamically during runtime.
> Move the dtb section to .data.
> 
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> ---
>  include/asm-generic/vmlinux.lds.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> index ad6afc5c4918..3ae9097774b0 100644
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -365,6 +365,7 @@
>         TRACE_PRINTKS()                                                 \
>         BPF_RAW_TP()                                                    \
>         TRACEPOINT_STR()                                                \
> +       KERNEL_DTB()                                                    \

The KERNEL_DTB() macro shows the section name is dtb.init.rodata. Can
you remove the ".init." part if this isn't initdata anymore? And
shouldn't it be in the RO_DATA() macro?

It would be nice to keep the initdata properties when this isn't used
after init as well. Perhaps we need another macro and/or filename to
indicate that the DTB{O} can be thrown away after init/module init.

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

* Re: [PATCH 09/11] arm64: defconfig: Enable RP1 misc/clock/gpio drivers as built-in
  2024-08-21  8:47   ` Krzysztof Kozlowski
@ 2024-08-30 22:24     ` Andrea della Porta
  0 siblings, 0 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-08-30 22:24 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Krzysztof,

On 10:47 Wed 21 Aug     , Krzysztof Kozlowski wrote:
> On Tue, Aug 20, 2024 at 04:36:11PM +0200, Andrea della Porta wrote:
> > Select the RP1 drivers needed to operate the PCI endpoint containing
> > several peripherals such as Ethernet and USB Controller. This chip is
> > present on RaspberryPi 5.
> > 
> > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> > ---
> >  arch/arm64/configs/defconfig | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> > index 7d32fca64996..e7615c464680 100644
> > --- a/arch/arm64/configs/defconfig
> > +++ b/arch/arm64/configs/defconfig
> > @@ -606,6 +606,7 @@ CONFIG_PINCTRL_QCM2290=y
> >  CONFIG_PINCTRL_QCS404=y
> >  CONFIG_PINCTRL_QDF2XXX=y
> >  CONFIG_PINCTRL_QDU1000=y
> > +CONFIG_PINCTRL_RP1=y
> >  CONFIG_PINCTRL_SA8775P=y
> >  CONFIG_PINCTRL_SC7180=y
> >  CONFIG_PINCTRL_SC7280=y
> > @@ -685,6 +686,7 @@ CONFIG_SENSORS_RASPBERRYPI_HWMON=m
> >  CONFIG_SENSORS_SL28CPLD=m
> >  CONFIG_SENSORS_INA2XX=m
> >  CONFIG_SENSORS_INA3221=m
> > +CONFIG_MISC_RP1=y
> 
> Module?

Ack.

> 
> >  CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
> >  CONFIG_CPU_THERMAL=y
> >  CONFIG_DEVFREQ_THERMAL=y
> > @@ -1259,6 +1261,7 @@ CONFIG_COMMON_CLK_CS2000_CP=y
> >  CONFIG_COMMON_CLK_FSL_SAI=y
> >  CONFIG_COMMON_CLK_S2MPS11=y
> >  CONFIG_COMMON_CLK_PWM=y
> > +CONFIG_COMMON_CLK_RP1=y
> 
> Module?

Ack.

Many thanks,
Andrea

> 
> >  CONFIG_COMMON_CLK_RS9_PCIE=y
> >  CONFIG_COMMON_CLK_VC3=y
> >  CONFIG_COMMON_CLK_VC5=y
> > -- 
> > 2.35.3
> > 

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

* Re: [PATCH 10/11] net: macb: Add support for RP1's MACB variant
  2024-08-21  8:49   ` Krzysztof Kozlowski
@ 2024-08-30 22:32     ` Andrea della Porta
  0 siblings, 0 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-08-30 22:32 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Krzysztof,

On 10:49 Wed 21 Aug     , Krzysztof Kozlowski wrote:
> On Tue, Aug 20, 2024 at 04:36:12PM +0200, Andrea della Porta wrote:
> > RaspberryPi RP1 contains Cadence's MACB core. Implement the
> > changes to be able to operate the customization in the RP1.
> > 
> > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> 
> 
> > @@ -5100,6 +5214,11 @@ static int macb_probe(struct platform_device *pdev)
> >  			}
> >  		}
> >  	}
> > +
> > +	device_property_read_u8(&pdev->dev, "cdns,aw2w-max-pipe", &bp->aw2w_max_pipe);
> > +	device_property_read_u8(&pdev->dev, "cdns,ar2r-max-pipe", &bp->ar2r_max_pipe);
> 
> Where are the bindings?

As stated in the cover letter, this patch (and the dtb patch #11 for macb) is completely
unpolished and intended only for a quick test of the ethernet peripheral underneath
the RP1.  As such, it's not intended to be upstreamed yet.
However, your feedback is really appreaciated and will be used in a future patch that
will deal with ethernet mac support.

> 
> > +	bp->use_aw2b_fill = device_property_read_bool(&pdev->dev, "cdns,use-aw2b-fill");
> > +
> >  	spin_lock_init(&bp->lock);
> >  
> >  	/* setup capabilities */
> > @@ -5155,6 +5274,21 @@ static int macb_probe(struct platform_device *pdev)
> >  	else
> >  		bp->phy_interface = interface;
> >  
> > +	/* optional PHY reset-related properties */
> > +	bp->phy_reset_gpio = devm_gpiod_get_optional(&pdev->dev, "phy-reset",
> 
> Where is the binding?

Ditto.

> 
> > +						     GPIOD_OUT_LOW);
> > +	if (IS_ERR(bp->phy_reset_gpio)) {
> > +		dev_err(&pdev->dev, "Failed to obtain phy-reset gpio\n");
> > +		err = PTR_ERR(bp->phy_reset_gpio);
> > +		goto err_out_free_netdev;
> > +	}
> > +
> > +	bp->phy_reset_ms = 10;
> > +	of_property_read_u32(np, "phy-reset-duration", &bp->phy_reset_ms);
> 
> Where is the binding?

Ditto.

Cheers,
Andrea

> 
> > +	/* A sane reset duration should not be longer than 1s */
> > +	if (bp->phy_reset_ms > 1000)
> > +		bp->phy_reset_ms = 1000;
> > +
> >  	/* IP specific init */
> >  	err = init(pdev);
> 
> Best regards,
> Krzysztof
> 

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

* Re: [PATCH 11/11] arm64: dts: rp1: Add support for MACB contained in RP1
  2024-08-21  8:43   ` Krzysztof Kozlowski
@ 2024-08-30 22:33     ` Andrea della Porta
  0 siblings, 0 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-08-30 22:33 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Krzysztof,

On 10:43 Wed 21 Aug     , Krzysztof Kozlowski wrote:
> On Tue, Aug 20, 2024 at 04:36:13PM +0200, Andrea della Porta wrote:
> > RaspberryPi RP1 is multi function PCI endpoint device that
> > exposes several subperipherals via PCI BAR.
> > Add an ethernet node for Cadence MACB to the RP1 dtso
> > 
> > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> > ---
> >  arch/arm64/boot/dts/broadcom/rp1.dtso | 23 +++++++++++++++++++++++
> >  1 file changed, 23 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/broadcom/rp1.dtso b/arch/arm64/boot/dts/broadcom/rp1.dtso
> > index d80178a278ee..b40e203c28d5 100644
> > --- a/arch/arm64/boot/dts/broadcom/rp1.dtso
> > +++ b/arch/arm64/boot/dts/broadcom/rp1.dtso
> > @@ -78,6 +78,29 @@ rp1_clocks: clocks@c040018000 {
> >  							       <50000000>;   // RP1_CLK_ETH_TSU
> >  				};
> >  
> > +				rp1_eth: ethernet@c040100000 {
> > +					reg = <0xc0 0x40100000  0x0 0x4000>;
> > +					compatible = "cdns,macb";
> 
> Please start using DTS coding style...

Ack.

Regards,
Andrea

> 
> Best regards,
> Krzysztof
> 

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

* Re: [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support
  2024-08-28 15:24     ` Andrea della Porta
@ 2024-09-02  8:31       ` Linus Walleij
  0 siblings, 0 replies; 117+ messages in thread
From: Linus Walleij @ 2024-09-02  8:31 UTC (permalink / raw)
  To: Linus Walleij, Andrea della Porta, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Florian Fainelli, Broadcom internal kernel review list,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On Wed, Aug 28, 2024 at 5:24 PM Andrea della Porta
<andrea.porta@suse.com> wrote:

> > Looks a bit like a reimplementation of regmap-mmio? If you want to do
> > this why not use regmap-mmio?
>
> Agreed. I can leverage regmail_field to get rid of the reimplemented code
> for the pin->pad register region. Do you think it could be worth using
> regmap-mmio also on pin->gpio, pin->inte, pin->ints and pin->rio even
> though they are not doing any special field manipulation as the pin->pad
> case?

Don't know without looking at the result, I bet you will see what
looks best when you edit the patch, let's see what you come
up with, I trust you on this.

Yours,
Linus Walleij

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

* Re: [PATCH 02/11] dt-bindings: pinctrl: Add RaspberryPi RP1 gpio/pinctrl/pinmux bindings
  2024-08-30 11:46       ` Krzysztof Kozlowski
@ 2024-09-02  8:44         ` Andrea della Porta
  0 siblings, 0 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-09-02  8:44 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Krzysztof,

On 13:46 Fri 30 Aug     , Krzysztof Kozlowski wrote:
> On 30/08/2024 12:22, Andrea della Porta wrote:
> > Hi Krzysztof,
> > 
> 
> ...
> 
> >>> +#define RP1_USBHOST0_AXIS_BASE 0x200000
> >>> +#define RP1_USBHOST1_AXIS_BASE 0x300000
> >>> +#define RP1_EXAC_BASE 0x400000
> >>> +
> >>> +/* Interrupts */
> >>> +
> >>> +#define RP1_INT_IO_BANK0 0
> >>> +#define RP1_INT_IO_BANK1 1
> >>
> >> Also no, interrupt numbers are not considered bindings. That's too much
> >> churn. Otherwise, please point me to driver code using the define
> >> (directly! that's the requirement).
> > 
> > As mentioned above, RP1_INT_END is used in rp1-pci.c. To get rid of all those
> 
> Number of interrupts is not a binding, either. Does not appear in the DTS.

Ack.

> 
> > macroes from dt-binding would mean to hardcode the interrupt number in both
> > the binding example and in dtso, from this:
> > 
> > interrupts = <RP1_INT_IO_BANK0 IRQ_TYPE_LEVEL_HIGH>,
> >              <RP1_INT_IO_BANK1 IRQ_TYPE_LEVEL_HIGH>,
> >              <RP1_INT_IO_BANK2 IRQ_TYPE_LEVEL_HIGH>;
> > 
> > to this:
> > 
> > interrupts = <0 IRQ_TYPE_LEVEL_HIGH>,
> > 	     <1 IRQ_TYPE_LEVEL_HIGH>,
> >              <2 IRQ_TYPE_LEVEL_HIGH>;
> > 
> > is this what you are proposing?
> 
> Yes, just like every DTS does. I think the hard-coding of numbers is not
> a problem.

Ack.

Regards,
Andrea

> 
> Best regards,
> Krzysztof
> 

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

* Re: [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay
  2024-08-30 14:10             ` Andrew Lunn
@ 2024-09-02  9:21               ` Andrea della Porta
  0 siblings, 0 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-09-02  9:21 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Andrea della Porta, Krzysztof Kozlowski, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Florian Fainelli, Broadcom internal kernel review list,
	Linus Walleij, Catalin Marinas, Will Deacon, Derek Kiernan,
	Dragan Cvetic, Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre,
	Claudiu Beznea, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Saravana Kannan, Bjorn Helgaas, linux-clk,
	devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
	linux-gpio, netdev, linux-pci, linux-arch, Lee Jones,
	Stefan Wahren

Hi Andrew,

On 16:10 Fri 30 Aug     , Andrew Lunn wrote:
> > On a second thought, are you really sure we want to proceed with the header file?
> > After all the only line in it would be the extern declaration and the only one to
> > include it would be rp1-dev.c. Moreover, an header file would convey the false
> > premise that you can include it and use that symbol while in fact it should be
> > only used inside the driver.
> > OTOH, not creating that header file will continue to trigger the warning...
> 
> The header file does not need to be in global scope. It could be in
> the driver source directory. As such, nothing outside of the driver
> can use it.

Ack.

> 
> Headers like this have multiple proposes. One is they make a symbol
> visible to the linker. But having two different .c files include the

Hmm... not sure what second file is including it, since only rp1_pci.c needs it.

> header enables type checking, which for long term maintenance is just
> as important. So a one line header is fine.

Done.

Cheers,
Andrea

> 
> 	Andrew
> 

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-30 18:27           ` Rob Herring
@ 2024-09-02  9:34             ` Andrea della Porta
  0 siblings, 0 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-09-02  9:34 UTC (permalink / raw)
  To: Rob Herring
  Cc: Stefan Wahren, Andrea della Porta, Michael Turquette,
	Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn

Hi Rob,

On 13:27 Fri 30 Aug     , Rob Herring wrote:
> On Fri, Aug 23, 2024 at 11:31 AM Andrea della Porta
> <andrea.porta@suse.com> wrote:
> >
...
> >
> > Since u-boot is lacking support for RP1 we cannot really produce some test
> > results to check the compatibility versus kernel dtb overlay but we can
> > speculate a little bit about it. AFAIK u-boot would probably place the rp1
> > node directly under its pcie@12000 node in DT while the dtb overlay will use
> > dynamically created PCI endpoint node (dev@0) as parent for rp1 node.
> 
> u-boot could do that and it would not be following the 25+ year old
> PCI bus bindings. Some things may be argued about as "Linux bindings",
> but that isn't one of them.

Indeed. It was just speculation, not something I would bet on.

Regards,
Andrea

> 
> Rob

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

* Re: [PATCH 04/11] of: address: Preserve the flags portion on 1:1 dma-ranges mapping
  2024-08-30 19:37               ` Rob Herring
@ 2024-09-03  9:09                 ` Herve Codina
  2024-09-03  9:33                   ` Andrea della Porta
  2024-09-03 16:15                 ` Andrea della Porta
  1 sibling, 1 reply; 117+ messages in thread
From: Herve Codina @ 2024-09-03  9:09 UTC (permalink / raw)
  To: Rob Herring
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren, Luca Ceresoli, Thomas Petazzoni

Hi,

On Fri, 30 Aug 2024 14:37:54 -0500
Rob Herring <robh@kernel.org> wrote:

...

> > this view is much like Bootlin's approach, also my pci-ep-bus node now would look
> > like this:
> >  ...
> >  pci-ep-bus@0 {
> >         ranges = <0xc0 0x40000000
> >                   0x01 0x00 0x00000000
> >                   0x00 0x00400000>;
> >         ...
> >  };
> >
> > and also the correct unit address here is 0 again, since the parent address in
> > ranges is 0x01 0x00 0x00000000 (0x01 is the flags and in this case represent
> > BAR1, I assume that for the unit address I should use only the address part that
> > is 0, right?).  
> 
> No, it should be 1 for BAR1. It's 1 node per BAR.

It should be 1 node per BAR but in some cases it is not.

Indeed, in the LAN966x case, the pci-ep-bus need to have access to several
BARs and we have:
	...
	pci-ep-bus@0 {
		compatible = "simple-bus";
		#address-cells = <1>;
		#size-cells = <1>;

		/*
		 * map @0xe2000000 (32MB) to BAR0 (CPU)
		 * map @0xe0000000 (16MB) to BAR1 (AMBA)
		 */
		ranges = <0xe2000000 0x00 0x00 0x00 0x2000000
		          0xe0000000 0x01 0x00 0x00 0x1000000>;
	...

Some devices under this bus need to use both BARs and use two regs values
in their reg properties to access BAR0 and BAR1.


> > > > > The assumption so far with all of this is that you have some specific
> > > > > PCI device (and therefore a driver). The simple-buses under it are
> > > > > defined per BAR. Not really certain if that makes sense in all cases,
> > > > > but since the address assignment is dynamic, it may have to. I'm also
> > > > > not completely convinced we should reuse 'simple-bus' here or define
> > > > > something specific like 'pci-bar-bus' or something.  
> > > >
> > > > Good point. Labeling a new bus for this kind of 'appliance' could be
> > > > beneficial to unify the dt overlay approach, and I guess it could be
> > > > adopted by the aforementioned Bootlin's Microchip patchset too.
> > > > However, since the difference with simple-bus would be basically non
> > > > existent, I believe that this could be done in a future patch due to
> > > > the fact that the dtbo is contained into the driver itself, so we do
> > > > not suffer from the proliferation that happens when dtb are managed
> > > > outside.  
> > >
> > > It's an ABI, so we really need to decide first.  
> >
> > Okay. How should we proceed?  
> 
> I think simple-bus where you have it is fine. It is really 1 level up
> that needs to be specified. Basically something that's referenced from
> the specific PCI device's schema (e.g. the RP1 schema (which you are
> missing)).
> 
> That schema needs to roughly look like this:
> 
> properties:
>   "#address-cells":
>     const: 3
>   "#size-cells":
>     const: 2
>   ranges:
>     minItems: 1
>     maxItems: 6
>     items:
>       additionalItems: true
>       items:
>         - maximum: 5  # The BAR number
>         - const: 0
>         - const: 0
>         - # TODO: valid PCI memory flags
> 
> patternProperties:
>   "^bar-bus@[0-5]$":
>     type: object
>     additionalProperties: true
>     properties:
>       compatible:
>         const: simple-bus
>       ranges: true
> 

IMHO, the node should not have 'bar' in the name.
In the LAN966x PCI use case, multiple BARs have to be accessed by devices
under this simple-bus. That's why I choose pci-ep-bus for this node name.

Best regards,
Hervé

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

* Re: [PATCH 04/11] of: address: Preserve the flags portion on 1:1 dma-ranges mapping
  2024-09-03  9:09                 ` Herve Codina
@ 2024-09-03  9:33                   ` Andrea della Porta
  2024-09-03 18:55                     ` Rob Herring
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-09-03  9:33 UTC (permalink / raw)
  To: Herve Codina
  Cc: Rob Herring, Andrea della Porta, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren, Luca Ceresoli, Thomas Petazzoni

Hi Herve,

On 11:09 Tue 03 Sep     , Herve Codina wrote:
> Hi,
> 
> On Fri, 30 Aug 2024 14:37:54 -0500
> Rob Herring <robh@kernel.org> wrote:
> 
> ...
> 
> > > this view is much like Bootlin's approach, also my pci-ep-bus node now would look
> > > like this:
> > >  ...
> > >  pci-ep-bus@0 {
> > >         ranges = <0xc0 0x40000000
> > >                   0x01 0x00 0x00000000
> > >                   0x00 0x00400000>;
> > >         ...
> > >  };
> > >
> > > and also the correct unit address here is 0 again, since the parent address in
> > > ranges is 0x01 0x00 0x00000000 (0x01 is the flags and in this case represent
> > > BAR1, I assume that for the unit address I should use only the address part that
> > > is 0, right?).  
> > 
> > No, it should be 1 for BAR1. It's 1 node per BAR.
> 
> It should be 1 node per BAR but in some cases it is not.
> 
> Indeed, in the LAN966x case, the pci-ep-bus need to have access to several
> BARs and we have:

I second this, on RP1 there are multiple BARs too, but for this minimal
implementation we need only one. Splitting them in one bus per BAR or
merging them with multiple ranges entries depend on whether the peripherals
can access different BARs simultaneously. Besides this contraint, I would
say both approach are viable.

> 	...
> 	pci-ep-bus@0 {
> 		compatible = "simple-bus";
> 		#address-cells = <1>;
> 		#size-cells = <1>;
> 
> 		/*
> 		 * map @0xe2000000 (32MB) to BAR0 (CPU)
> 		 * map @0xe0000000 (16MB) to BAR1 (AMBA)
> 		 */
> 		ranges = <0xe2000000 0x00 0x00 0x00 0x2000000
> 		          0xe0000000 0x01 0x00 0x00 0x1000000>;
> 	...
> 
> Some devices under this bus need to use both BARs and use two regs values
> in their reg properties to access BAR0 and BAR1.
> 
> 
> > > > > > The assumption so far with all of this is that you have some specific
> > > > > > PCI device (and therefore a driver). The simple-buses under it are
> > > > > > defined per BAR. Not really certain if that makes sense in all cases,
> > > > > > but since the address assignment is dynamic, it may have to. I'm also
> > > > > > not completely convinced we should reuse 'simple-bus' here or define
> > > > > > something specific like 'pci-bar-bus' or something.  
> > > > >
> > > > > Good point. Labeling a new bus for this kind of 'appliance' could be
> > > > > beneficial to unify the dt overlay approach, and I guess it could be
> > > > > adopted by the aforementioned Bootlin's Microchip patchset too.
> > > > > However, since the difference with simple-bus would be basically non
> > > > > existent, I believe that this could be done in a future patch due to
> > > > > the fact that the dtbo is contained into the driver itself, so we do
> > > > > not suffer from the proliferation that happens when dtb are managed
> > > > > outside.  
> > > >
> > > > It's an ABI, so we really need to decide first.  
> > >
> > > Okay. How should we proceed?  
> > 
> > I think simple-bus where you have it is fine. It is really 1 level up
> > that needs to be specified. Basically something that's referenced from
> > the specific PCI device's schema (e.g. the RP1 schema (which you are
> > missing)).
> > 
> > That schema needs to roughly look like this:
> > 
> > properties:
> >   "#address-cells":
> >     const: 3
> >   "#size-cells":
> >     const: 2
> >   ranges:
> >     minItems: 1
> >     maxItems: 6
> >     items:
> >       additionalItems: true
> >       items:
> >         - maximum: 5  # The BAR number
> >         - const: 0
> >         - const: 0
> >         - # TODO: valid PCI memory flags
> > 
> > patternProperties:
> >   "^bar-bus@[0-5]$":
> >     type: object
> >     additionalProperties: true
> >     properties:
> >       compatible:
> >         const: simple-bus
> >       ranges: true
> > 
> 
> IMHO, the node should not have 'bar' in the name.
> In the LAN966x PCI use case, multiple BARs have to be accessed by devices
> under this simple-bus. That's why I choose pci-ep-bus for this node name.
>

Agreed for your scenario. Anyway, since the dtbo and driver are shipped together,
we are free to change the name anytime without impacting anything.

Many thanks,
Andrea
 
> Best regards,
> Hervé

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

* Re: [PATCH 05/11] vmlinux.lds.h: Preserve DTB sections from being discarded after init
  2024-08-30 19:46   ` Stephen Boyd
@ 2024-09-03 12:29     ` Andrea della Porta
  2024-09-21 20:47       ` Stephen Boyd
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-09-03 12:29 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Andrea della Porta, Andrew Lunn, Arnd Bergmann, Bjorn Helgaas,
	Broadcom internal kernel review list, Catalin Marinas,
	Claudiu Beznea, Conor Dooley, David S. Miller, Derek Kiernan,
	Dragan Cvetic, Eric Dumazet, Florian Fainelli, Greg Kroah-Hartman,
	Jakub Kicinski, Krzysztof Kozlowski, Lee Jones, Linus Walleij,
	Michael Turquette, Nicolas Ferre, Paolo Abeni, Rob Herring,
	Saravana Kannan, Stefan Wahren, Will Deacon, devicetree,
	linux-arch, linux-arm-kernel, linux-clk, linux-gpio, linux-kernel,
	linux-pci, linux-rpi-kernel, netdev

Hi Stephen,

On 12:46 Fri 30 Aug     , Stephen Boyd wrote:
> Quoting Andrea della Porta (2024-08-20 07:36:07)
> > The special section .dtb.init.rodata contains dtb and dtbo compiled
> > as objects inside the kernel and ends up in .init.data sectiion that
> > will be discarded early after the init phase. This is a problem for
> > builtin drivers that apply dtb overlay at runtime since this happens
> > later (e.g. during bus enumeration) and also for modules that should
> > be able to do it dynamically during runtime.
> > Move the dtb section to .data.
> > 
> > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> > ---
> >  include/asm-generic/vmlinux.lds.h | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> > index ad6afc5c4918..3ae9097774b0 100644
> > --- a/include/asm-generic/vmlinux.lds.h
> > +++ b/include/asm-generic/vmlinux.lds.h
> > @@ -365,6 +365,7 @@
> >         TRACE_PRINTKS()                                                 \
> >         BPF_RAW_TP()                                                    \
> >         TRACEPOINT_STR()                                                \
> > +       KERNEL_DTB()                                                    \
> 
> The KERNEL_DTB() macro shows the section name is dtb.init.rodata. Can
> you remove the ".init." part if this isn't initdata anymore? And
> shouldn't it be in the RO_DATA() macro?

Ack.

> 
> It would be nice to keep the initdata properties when this isn't used
> after init as well. Perhaps we need another macro and/or filename to
> indicate that the DTB{O} can be thrown away after init/module init.

We can certainly add some more filename extension that would place the
relevant data in a droppable section. 
Throwing away the dtb/o after init is like the actual KERNEL_DTB macro that
is adding teh data to section .init.data, but this would mean t would be
useful only at very early init stage, just like for CONFIG_OF_UNITTEST.
Throwing after module init could be more difficult though, I think,
for example we're not sure when to discard the section in case of deferred
modules probe.

Many thanks,
Andrea

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-30 14:21       ` Andrew Lunn
@ 2024-09-03 14:56         ` Andrea della Porta
  0 siblings, 0 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-09-03 14:56 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Andrea della Porta, Krzysztof Kozlowski, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Florian Fainelli, Broadcom internal kernel review list,
	Linus Walleij, Catalin Marinas, Will Deacon, Derek Kiernan,
	Dragan Cvetic, Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre,
	Claudiu Beznea, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Saravana Kannan, Bjorn Helgaas, linux-clk,
	devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
	linux-gpio, netdev, linux-pci, linux-arch, Lee Jones,
	Stefan Wahren

Hi Andrew,

On 16:21 Fri 30 Aug     , Andrew Lunn wrote:
> On Fri, Aug 30, 2024 at 03:49:04PM +0200, Andrea della Porta wrote:
> > Hi Krzysztof,
> > 
> > On 10:38 Wed 21 Aug     , Krzysztof Kozlowski wrote:
> > > On Tue, Aug 20, 2024 at 04:36:10PM +0200, Andrea della Porta wrote:
> > > > The RaspberryPi RP1 is ia PCI multi function device containing
> > > > peripherals ranging from Ethernet to USB controller, I2C, SPI
> > > > and others.
> > > > Implement a bare minimum driver to operate the RP1, leveraging
> > > > actual OF based driver implementations for the on-borad peripherals
> > > > by loading a devicetree overlay during driver probe.
> > > > The peripherals are accessed by mapping MMIO registers starting
> > > > from PCI BAR1 region.
> > > > As a minimum driver, the peripherals will not be added to the
> > > > dtbo here, but in following patches.
> > > > 
> > > > Link: https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
> > > > Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> > > > ---
> > > >  MAINTAINERS                           |   2 +
> > > >  arch/arm64/boot/dts/broadcom/rp1.dtso | 152 ++++++++++++
> > > 
> > > Do not mix DTS with drivers.
> > > 
> > > These MUST be separate.
> > 
> > Separating the dtso from the driver in two different patches would mean
> > that the dtso patch would be ordered before the driver one. This is because
> > the driver embeds the dtbo binary blob inside itself, at build time. So
> > in order to build the driver, the dtso needs to be there also. This is not
> > the standard approach used with 'normal' dtb/dtbo, where the dtb patch is
> > ordered last wrt the driver it refers to.
> > Are you sure you want to proceed in this way?
> 
> It is more about they are logically separate things. The .dtb/dtbo
> describes the hardware. It should be possible to review that as a
> standalone thing. The code them implements the binding. It makes no
> sense to review the code until the binding is correct, because changes
> to the binding will need changes to the code. Hence, we want the
> binding first, then the code which implements it.

Ack.

Cheers,
Andrea

> 
> 	Andrew

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-08-30 16:52       ` Krzysztof Kozlowski
@ 2024-09-03 15:15         ` Andrea della Porta
  2024-09-03 18:27           ` Krzysztof Kozlowski
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-09-03 15:15 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Krzysztof,

On 18:52 Fri 30 Aug     , Krzysztof Kozlowski wrote:
> On 30/08/2024 15:49, Andrea della Porta wrote:
> > Hi Krzysztof,
> > 
> > On 10:38 Wed 21 Aug     , Krzysztof Kozlowski wrote:
> >> On Tue, Aug 20, 2024 at 04:36:10PM +0200, Andrea della Porta wrote:
> >>> The RaspberryPi RP1 is ia PCI multi function device containing
> >>> peripherals ranging from Ethernet to USB controller, I2C, SPI
> >>> and others.
> >>> Implement a bare minimum driver to operate the RP1, leveraging
> >>> actual OF based driver implementations for the on-borad peripherals
> >>> by loading a devicetree overlay during driver probe.
> >>> The peripherals are accessed by mapping MMIO registers starting
> >>> from PCI BAR1 region.
> >>> As a minimum driver, the peripherals will not be added to the
> >>> dtbo here, but in following patches.
> >>>
> >>> Link: https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
> >>> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> >>> ---
> >>>  MAINTAINERS                           |   2 +
> >>>  arch/arm64/boot/dts/broadcom/rp1.dtso | 152 ++++++++++++
> >>
> >> Do not mix DTS with drivers.
> >>
> >> These MUST be separate.
> > 
> > Separating the dtso from the driver in two different patches would mean
> > that the dtso patch would be ordered before the driver one. This is because
> > the driver embeds the dtbo binary blob inside itself, at build time. So
> > in order to build the driver, the dtso needs to be there also. This is not
> 
> Sure, in such case DTS will have to go through the same tree as driver
> as an exception. Please document it in patch changelog (---).

Ack.

> 
> > the standard approach used with 'normal' dtb/dtbo, where the dtb patch is
> > ordered last wrt the driver it refers to.
> 
> It's not exactly the "ordered last" that matters, but lack of dependency
> and going through separate tree and branch - arm-soc/dts. Here there
> will be an exception how we handle patch, but still DTS is hardware
> description so should not be combined with driver code.

Ack.

> 
> > Are you sure you want to proceed in this way?
> 
> 
> > 
> >>
> >>>  drivers/misc/Kconfig                  |   1 +
> >>>  drivers/misc/Makefile                 |   1 +
> >>>  drivers/misc/rp1/Kconfig              |  20 ++
> >>>  drivers/misc/rp1/Makefile             |   3 +
> >>>  drivers/misc/rp1/rp1-pci.c            | 333 ++++++++++++++++++++++++++
> >>>  drivers/misc/rp1/rp1-pci.dtso         |   8 +
> >>>  drivers/pci/quirks.c                  |   1 +
> >>>  include/linux/pci_ids.h               |   3 +
> >>>  10 files changed, 524 insertions(+)
> >>>  create mode 100644 arch/arm64/boot/dts/broadcom/rp1.dtso
> >>>  create mode 100644 drivers/misc/rp1/Kconfig
> >>>  create mode 100644 drivers/misc/rp1/Makefile
> >>>  create mode 100644 drivers/misc/rp1/rp1-pci.c
> >>>  create mode 100644 drivers/misc/rp1/rp1-pci.dtso
> >>>
> >>> diff --git a/MAINTAINERS b/MAINTAINERS
> >>> index 67f460c36ea1..1359538b76e8 100644
> >>> --- a/MAINTAINERS
> >>> +++ b/MAINTAINERS
> >>> @@ -19119,9 +19119,11 @@ F:	include/uapi/linux/media/raspberrypi/
> >>>  RASPBERRY PI RP1 PCI DRIVER
> >>>  M:	Andrea della Porta <andrea.porta@suse.com>
> >>>  S:	Maintained
> >>> +F:	arch/arm64/boot/dts/broadcom/rp1.dtso
> >>>  F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
> >>>  F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
> >>>  F:	drivers/clk/clk-rp1.c
> >>> +F:	drivers/misc/rp1/
> >>>  F:	drivers/pinctrl/pinctrl-rp1.c
> >>>  F:	include/dt-bindings/clock/rp1.h
> >>>  F:	include/dt-bindings/misc/rp1.h
> >>> diff --git a/arch/arm64/boot/dts/broadcom/rp1.dtso b/arch/arm64/boot/dts/broadcom/rp1.dtso
> >>> new file mode 100644
> >>> index 000000000000..d80178a278ee
> >>> --- /dev/null
> >>> +++ b/arch/arm64/boot/dts/broadcom/rp1.dtso
> >>> @@ -0,0 +1,152 @@
> >>> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> >>> +
> >>> +#include <dt-bindings/gpio/gpio.h>
> >>> +#include <dt-bindings/interrupt-controller/irq.h>
> >>> +#include <dt-bindings/clock/rp1.h>
> >>> +#include <dt-bindings/misc/rp1.h>
> >>> +
> >>> +/dts-v1/;
> >>> +/plugin/;
> >>> +
> >>> +/ {
> >>> +	fragment@0 {
> >>> +		target-path="";
> >>> +		__overlay__ {
> >>> +			#address-cells = <3>;
> >>> +			#size-cells = <2>;
> >>> +
> >>> +			rp1: rp1@0 {
> >>> +				compatible = "simple-bus";
> >>> +				#address-cells = <2>;
> >>> +				#size-cells = <2>;
> >>> +				interrupt-controller;
> >>> +				interrupt-parent = <&rp1>;
> >>> +				#interrupt-cells = <2>;
> >>> +
> >>> +				// ranges and dma-ranges must be provided by the includer
> >>> +				ranges = <0xc0 0x40000000
> >>> +					  0x01/*0x02000000*/ 0x00 0x00000000
> >>> +					  0x00 0x00400000>;
> >>
> >> Are you 100% sure you do not have here dtc W=1 warnings?
> > 
> > the W=1 warnings are:
> > 
> > arch/arm64/boot/dts/broadcom/rp1.dtso:37.24-42.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/clk_xosc: missing or empty reg/ranges property
> > arch/arm64/boot/dts/broadcom/rp1.dtso:44.26-49.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/macb_pclk: missing or empty reg/ranges property
> > arch/arm64/boot/dts/broadcom/rp1.dtso:51.26-56.7: Warning (simple_bus_reg): /fragment@0/__overlay__/rp1@0/macb_hclk: missing or empty reg/ranges property
> > arch/arm64/boot/dts/broadcom/rp1.dtso:14.15-173.5: Warning (avoid_unnecessary_addr_size): /fragment@0/__overlay__: unnecessary #address-cells/#size-cells without "ranges", "dma-ranges" or child "reg" property
> > 
> > I don't see anything related to the ranges line you mentioned.
> 
> Hm, indeed, but I would expect warning about unit address not matching
> ranges/reg.
> 
> > 
> >>
> >>> +
> >>> +				dma-ranges =
> >>> +				// inbound RP1 1x_xxxxxxxx -> PCIe 1x_xxxxxxxx
> >>> +					     <0x10 0x00000000
> >>> +					      0x43000000 0x10 0x00000000
> >>> +					      0x10 0x00000000>;
> >>> +
> >>> +				clk_xosc: clk_xosc {
> >>
> >> Nope, switch to DTS coding style.
> > 
> > Ack.
> > 
> >>
> >>> +					compatible = "fixed-clock";
> >>> +					#clock-cells = <0>;
> >>> +					clock-output-names = "xosc";
> >>> +					clock-frequency = <50000000>;
> >>> +				};
> >>> +
> >>> +				macb_pclk: macb_pclk {
> >>> +					compatible = "fixed-clock";
> >>> +					#clock-cells = <0>;
> >>> +					clock-output-names = "pclk";
> >>> +					clock-frequency = <200000000>;
> >>> +				};
> >>> +
> >>> +				macb_hclk: macb_hclk {
> >>> +					compatible = "fixed-clock";
> >>> +					#clock-cells = <0>;
> >>> +					clock-output-names = "hclk";
> >>> +					clock-frequency = <200000000>;
> >>> +				};
> >>> +
> >>> +				rp1_clocks: clocks@c040018000 {
> >>
> >> Why do you mix MMIO with non-MMIO nodes? This really does not look
> >> correct.
> >>
> > 
> > Right. This is already under discussion here:
> > https://lore.kernel.org/all/ZtBzis5CzQMm8loh@apocalypse/
> > 
> > IIUC you proposed to instantiate the non-MMIO nodes (the three clocks) by
> > using CLK_OF_DECLARE.
> 
> Depends. Where are these clocks? Naming suggests they might not be even
> part of this device. But if these are part of the device, then why this
> is not a clock controller (if they are controllable) or even removed
> (because we do not represent internal clock tree in DTS).

xosc is a crystal connected to the oscillator input of the RP1, so I would
consider it an external fixed-clock. If we were in the entire dts, I would have
put it in root under /clocks node, but here we're in the dtbo so I'm not sure
where else should I put it.

Regarding pclk and hclk, I'm still trying to understand where they come from.
If they are external clocks (since they are fixed-clock too), they should be
in the same node as xosc. CLK_OF_DECLARE does not seem to fit here because
there's no special management of these clocks, so no new clock definition is
needed.
If they are internal tree, I cannot simply get rid of them because rp1_eth node
references these two clocks (see clocks property), so they must be decalred 
somewhere. Any hint about this?.

Many thanks,
Andrea

> 
> Best regards,
> Krzysztof
> 

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

* Re: [PATCH 04/11] of: address: Preserve the flags portion on 1:1 dma-ranges mapping
  2024-08-30 19:37               ` Rob Herring
  2024-09-03  9:09                 ` Herve Codina
@ 2024-09-03 16:15                 ` Andrea della Porta
  2024-09-03 18:46                   ` Rob Herring
  1 sibling, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-09-03 16:15 UTC (permalink / raw)
  To: Rob Herring
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren, Herve Codina, Luca Ceresoli, Thomas Petazzoni

Hi Rob,

On 14:37 Fri 30 Aug     , Rob Herring wrote:
> On Thu, Aug 29, 2024 at 11:26 AM Andrea della Porta
> <andrea.porta@suse.com> wrote:
> >
> > Hi Rob,
> >

...

> 
> I think simple-bus where you have it is fine. It is really 1 level up
> that needs to be specified. Basically something that's referenced from
> the specific PCI device's schema (e.g. the RP1 schema (which you are
> missing)).
> 
> That schema needs to roughly look like this:
> 
> properties:
>   "#address-cells":
>     const: 3
>   "#size-cells":
>     const: 2
>   ranges:
>     minItems: 1
>     maxItems: 6
>     items:
>       additionalItems: true
>       items:
>         - maximum: 5  # The BAR number
>         - const: 0
>         - const: 0
>         - # TODO: valid PCI memory flags
> 
> patternProperties:
>   "^bar-bus@[0-5]$":
>     type: object
>     additionalProperties: true
>     properties:
>       compatible:
>         const: simple-bus
>       ranges: true
>

Hmmm.. not sure how this is going to work. The PCI device (RP1) will
havei, at runtime, a compatible like this:

compatible = "pci1de4,1\0pciclass,0200000\0pciclass,0200";

that is basically generated automatically by the OF framework. So, in the
schema you proposed above, I can put something like:

properties:
  compatible:
    contains:
      pattern: '^pci1de4,1'

or maybe I could omit the compatible entirely, like in:

https://github.com/devicetree-org/dt-schema/blob/main/dtschema/schemas/pci/pci-iommu.yaml

that seems to refer to generic compatible values.
In both cases though, I don't see how these binding could work with
make dt_binding_check, since there's no compatible known at compile
time (for the first approach), or no compatible at all (the second
approach).
Is it intended only as a loose documentation?
Or are you proposing that for a future new bus (hence with a new, specific,
compatible) that could be described by the schema above?

Many thanks,
Andrea
 
> There were some discussions around interrupt handling that might also
> factor into this.
> 
> Rob

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-09-03 15:15         ` Andrea della Porta
@ 2024-09-03 18:27           ` Krzysztof Kozlowski
  2024-09-05 16:33             ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Krzysztof Kozlowski @ 2024-09-03 18:27 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On 03/09/2024 17:15, Andrea della Porta wrote:
>>>>> +
>>>>> +				rp1_clocks: clocks@c040018000 {
>>>>
>>>> Why do you mix MMIO with non-MMIO nodes? This really does not look
>>>> correct.
>>>>
>>>
>>> Right. This is already under discussion here:
>>> https://lore.kernel.org/all/ZtBzis5CzQMm8loh@apocalypse/
>>>
>>> IIUC you proposed to instantiate the non-MMIO nodes (the three clocks) by
>>> using CLK_OF_DECLARE.
>>
>> Depends. Where are these clocks? Naming suggests they might not be even
>> part of this device. But if these are part of the device, then why this
>> is not a clock controller (if they are controllable) or even removed
>> (because we do not represent internal clock tree in DTS).
> 
> xosc is a crystal connected to the oscillator input of the RP1, so I would
> consider it an external fixed-clock. If we were in the entire dts, I would have
> put it in root under /clocks node, but here we're in the dtbo so I'm not sure
> where else should I put it.

But physically, on which PCB, where is this clock located?

> 
> Regarding pclk and hclk, I'm still trying to understand where they come from.
> If they are external clocks (since they are fixed-clock too), they should be
> in the same node as xosc. CLK_OF_DECLARE does not seem to fit here because

There is no such node as "/clocks" so do not focus on that. That's just
placeholder but useless and it is inconsistent with other cases (e.g.
regulators).

If this is external oscillator then it is not part of RP1 and you cannot
put it inside just to satisfy your drivers.

> there's no special management of these clocks, so no new clock definition is
> needed.

> If they are internal tree, I cannot simply get rid of them because rp1_eth node
> references these two clocks (see clocks property), so they must be decalred 
> somewhere. Any hint about this?.
> 

Describe the hardware. Show the diagram or schematics where is which device.

Best regards,
Krzysztof


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

* Re: [PATCH 04/11] of: address: Preserve the flags portion on 1:1 dma-ranges mapping
  2024-09-03 16:15                 ` Andrea della Porta
@ 2024-09-03 18:46                   ` Rob Herring
  2024-09-04  8:33                     ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Rob Herring @ 2024-09-03 18:46 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren, Herve Codina, Luca Ceresoli, Thomas Petazzoni

On Tue, Sep 3, 2024 at 11:15 AM Andrea della Porta
<andrea.porta@suse.com> wrote:
>
> Hi Rob,
>
> On 14:37 Fri 30 Aug     , Rob Herring wrote:
> > On Thu, Aug 29, 2024 at 11:26 AM Andrea della Porta
> > <andrea.porta@suse.com> wrote:
> > >
> > > Hi Rob,
> > >
>
> ...
>
> >
> > I think simple-bus where you have it is fine. It is really 1 level up
> > that needs to be specified. Basically something that's referenced from
> > the specific PCI device's schema (e.g. the RP1 schema (which you are
> > missing)).
> >
> > That schema needs to roughly look like this:
> >
> > properties:
> >   "#address-cells":
> >     const: 3
> >   "#size-cells":
> >     const: 2
> >   ranges:
> >     minItems: 1
> >     maxItems: 6
> >     items:
> >       additionalItems: true
> >       items:
> >         - maximum: 5  # The BAR number
> >         - const: 0
> >         - const: 0
> >         - # TODO: valid PCI memory flags
> >
> > patternProperties:
> >   "^bar-bus@[0-5]$":
> >     type: object
> >     additionalProperties: true
> >     properties:
> >       compatible:
> >         const: simple-bus
> >       ranges: true
> >
>
> Hmmm.. not sure how this is going to work. The PCI device (RP1) will
> havei, at runtime, a compatible like this:
>
> compatible = "pci1de4,1\0pciclass,0200000\0pciclass,0200";
>
> that is basically generated automatically by the OF framework. So, in the
> schema you proposed above, I can put something like:
>
> properties:
>   compatible:
>     contains:
>       pattern: '^pci1de4,1'

No, it should be like this:

compatible:
  items:
    - const: pci1de4,1
    - const: pciclass,0200000
    - const: pciclass,0200

or

compatible:
  addtionalItems: true
  maxItems: 3
  items:
    - const: pci1de4,1


Alternatively, we could instead only generate 'pciclass' compatibles
for bridge nodes. The reason being that being an ethernet controller
doesn't really tell us anything. There's no standard interface
associated with that class.

> or maybe I could omit the compatible entirely, like in:

No.

> https://github.com/devicetree-org/dt-schema/blob/main/dtschema/schemas/pci/pci-iommu.yaml

That's not a device node, but just part of pci-host-bridge.yaml.

> that seems to refer to generic compatible values.
> In both cases though, I don't see how these binding could work with
> make dt_binding_check, since there's no compatible known at compile
> time (for the first approach), or no compatible at all (the second
> approach).
> Is it intended only as a loose documentation?

No, schemas define exactly what a binding can and can't contain. But
they are divided into device schemas and common schemas. The latter
are incomplete and are included by the former. Generally, "compatible"
goes in device schemas.

> Or are you proposing that for a future new bus (hence with a new, specific,
> compatible) that could be described by the schema above?

The above schema would be the common schema included by a RP1 schema,
LAN966x schema, or any other device doing the same thing.
Rob

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

* Re: [PATCH 04/11] of: address: Preserve the flags portion on 1:1 dma-ranges mapping
  2024-09-03  9:33                   ` Andrea della Porta
@ 2024-09-03 18:55                     ` Rob Herring
  0 siblings, 0 replies; 117+ messages in thread
From: Rob Herring @ 2024-09-03 18:55 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Herve Codina, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren, Luca Ceresoli, Thomas Petazzoni

On Tue, Sep 3, 2024 at 4:33 AM Andrea della Porta <andrea.porta@suse.com> wrote:
>
> Hi Herve,
>
> On 11:09 Tue 03 Sep     , Herve Codina wrote:
> > Hi,
> >
> > On Fri, 30 Aug 2024 14:37:54 -0500
> > Rob Herring <robh@kernel.org> wrote:
> >
> > ...
> >
> > > > this view is much like Bootlin's approach, also my pci-ep-bus node now would look
> > > > like this:
> > > >  ...
> > > >  pci-ep-bus@0 {
> > > >         ranges = <0xc0 0x40000000
> > > >                   0x01 0x00 0x00000000
> > > >                   0x00 0x00400000>;
> > > >         ...
> > > >  };
> > > >
> > > > and also the correct unit address here is 0 again, since the parent address in
> > > > ranges is 0x01 0x00 0x00000000 (0x01 is the flags and in this case represent
> > > > BAR1, I assume that for the unit address I should use only the address part that
> > > > is 0, right?).
> > >
> > > No, it should be 1 for BAR1. It's 1 node per BAR.
> >
> > It should be 1 node per BAR but in some cases it is not.
> >
> > Indeed, in the LAN966x case, the pci-ep-bus need to have access to several
> > BARs and we have:

Might not be the last time I forget this...

> I second this, on RP1 there are multiple BARs too, but for this minimal
> implementation we need only one. Splitting them in one bus per BAR or
> merging them with multiple ranges entries depend on whether the peripherals
> can access different BARs simultaneously. Besides this contraint, I would
> say both approach are viable.

Okay. You all define what you need as you understand the devices better than me.


> >       ...
> >       pci-ep-bus@0 {
> >               compatible = "simple-bus";
> >               #address-cells = <1>;
> >               #size-cells = <1>;
> >
> >               /*
> >                * map @0xe2000000 (32MB) to BAR0 (CPU)
> >                * map @0xe0000000 (16MB) to BAR1 (AMBA)
> >                */
> >               ranges = <0xe2000000 0x00 0x00 0x00 0x2000000
> >                         0xe0000000 0x01 0x00 0x00 0x1000000>;
> >       ...
> >
> > Some devices under this bus need to use both BARs and use two regs values
> > in their reg properties to access BAR0 and BAR1.
> >
> >
> > > > > > > The assumption so far with all of this is that you have some specific
> > > > > > > PCI device (and therefore a driver). The simple-buses under it are
> > > > > > > defined per BAR. Not really certain if that makes sense in all cases,
> > > > > > > but since the address assignment is dynamic, it may have to. I'm also
> > > > > > > not completely convinced we should reuse 'simple-bus' here or define
> > > > > > > something specific like 'pci-bar-bus' or something.
> > > > > >
> > > > > > Good point. Labeling a new bus for this kind of 'appliance' could be
> > > > > > beneficial to unify the dt overlay approach, and I guess it could be
> > > > > > adopted by the aforementioned Bootlin's Microchip patchset too.
> > > > > > However, since the difference with simple-bus would be basically non
> > > > > > existent, I believe that this could be done in a future patch due to
> > > > > > the fact that the dtbo is contained into the driver itself, so we do
> > > > > > not suffer from the proliferation that happens when dtb are managed
> > > > > > outside.
> > > > >
> > > > > It's an ABI, so we really need to decide first.
> > > >
> > > > Okay. How should we proceed?
> > >
> > > I think simple-bus where you have it is fine. It is really 1 level up
> > > that needs to be specified. Basically something that's referenced from
> > > the specific PCI device's schema (e.g. the RP1 schema (which you are
> > > missing)).
> > >
> > > That schema needs to roughly look like this:
> > >
> > > properties:
> > >   "#address-cells":
> > >     const: 3
> > >   "#size-cells":
> > >     const: 2
> > >   ranges:
> > >     minItems: 1
> > >     maxItems: 6
> > >     items:
> > >       additionalItems: true
> > >       items:
> > >         - maximum: 5  # The BAR number
> > >         - const: 0
> > >         - const: 0
> > >         - # TODO: valid PCI memory flags
> > >
> > > patternProperties:
> > >   "^bar-bus@[0-5]$":
> > >     type: object
> > >     additionalProperties: true
> > >     properties:
> > >       compatible:
> > >         const: simple-bus
> > >       ranges: true
> > >
> >
> > IMHO, the node should not have 'bar' in the name.
> > In the LAN966x PCI use case, multiple BARs have to be accessed by devices
> > under this simple-bus. That's why I choose pci-ep-bus for this node name.
> >
>
> Agreed for your scenario. Anyway, since the dtbo and driver are shipped together,
> we are free to change the name anytime without impacting anything.

Indeed, no one should care what the nodename is. However, that doesn't
mean you don't have to define something. Really, just 'bus' should be
enough as node names should only be what class a node is. If it is not
enough, then really you need some sort of compatible to identify the
kind of 'bus'. If you want 'pci-ep-bus', then that's fine.


Rob

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

* Re: [PATCH 03/11] PCI: of_property: Sanitize 32 bit PCI address parsed from DT
  2024-08-26 19:51     ` Andrea della Porta
@ 2024-09-03 22:26       ` Bjorn Helgaas
  2024-09-05 16:43         ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Bjorn Helgaas @ 2024-09-03 22:26 UTC (permalink / raw)
  To: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On Mon, Aug 26, 2024 at 09:51:02PM +0200, Andrea della Porta wrote:
> On 10:24 Wed 21 Aug     , Bjorn Helgaas wrote:
> > On Tue, Aug 20, 2024 at 04:36:05PM +0200, Andrea della Porta wrote:
> > > The of_pci_set_address() function parses devicetree PCI range
> > > specifier assuming the address is 'sanitized' at the origin,
> > > i.e. without checking whether the incoming address is 32 or 64
> > > bit has specified in the flags.  In this way an address with no
> > > OF_PCI_ADDR_SPACE_MEM64 set in the flags could leak through and
> > > the upper 32 bits of the address will be set too, and this
> > > violates the PCI specs stating that in 32 bit address the upper
> > > bit should be zero.

> > I don't understand this code, so I'm probably missing something.  It
> > looks like the interesting path here is:
> > 
> >   of_pci_prop_ranges
> >     res = &pdev->resource[...];
> >     for (j = 0; j < num; j++) {
> >       val64 = res[j].start;
> >       of_pci_set_address(..., val64, 0, flags, false);
> >  +      if (OF_PCI_ADDR_SPACE_MEM64)
> >  +        prop[1] = upper_32_bits(val64);
> >  +      else
> >  +        prop[1] = 0;
> > 
> > OF_PCI_ADDR_SPACE_MEM64 tells us about the size of the PCI bus
> > address, but the address (val64) is a CPU physical address, not a PCI
> > bus address, so I don't understand why of_pci_set_address() should use
> > OF_PCI_ADDR_SPACE_MEM64 to clear part of the CPU address.
> 
> It all starts from of_pci_prop_ranges(), that is the caller of
> of_pci_set_address().

> val64 (i.e. res[j].start) is the address part of a struct resource
> that has its own flags.  Those flags are directly translated to
> of_pci_range flags by of_pci_get_addr_flags(), so any
> IORESOURCE_MEM_64 / IORESOURCE_MEM in the resource flag will
> respectively become OF_PCI_ADDR_SPACE_MEM64 /
> OF_PCI_ADDR_SPACE_MEM32 in pci range.

> What is advertised as 32 bit at the origin (val64) should not become
> a 64 bit PCI address at the output of of_pci_set_address(), so the
> upper 32 bit portion should be dropped. 

> This is explicitly stated in [1] (see page 5), where a space code of 0b10
> implies that the upper 32 bit of the address must be zeroed out.

OK, I was confused and thought IORESOURCE_MEM_64 was telling us
something about the *CPU* address, but it's actually telling us
something about what *PCI bus* addresses are possible, i.e., whether
it's a 32-bit BAR or a 64-bit BAR.

However, the CPU physical address space and the PCI bus address are
not the same.  Generic code paths should account for that different by
applying an offset (the offset will be zero on many platforms where
CPU and PCI bus addresses *look* the same).

So a generic code path like of_pci_prop_ranges() that basically copies
a CPU physical address to a PCI bus address looks broken to me.

Maybe my expectation of this being described in DT is mistaken.

Bjorn

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

* Re: [PATCH 04/11] of: address: Preserve the flags portion on 1:1 dma-ranges mapping
  2024-09-03 18:46                   ` Rob Herring
@ 2024-09-04  8:33                     ` Andrea della Porta
  0 siblings, 0 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-09-04  8:33 UTC (permalink / raw)
  To: Rob Herring
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren, Herve Codina, Luca Ceresoli, Thomas Petazzoni

Hi Rob,

On 13:46 Tue 03 Sep     , Rob Herring wrote:
> On Tue, Sep 3, 2024 at 11:15 AM Andrea della Porta
> <andrea.porta@suse.com> wrote:
> >
> > Hi Rob,
> >
> > On 14:37 Fri 30 Aug     , Rob Herring wrote:
> > > On Thu, Aug 29, 2024 at 11:26 AM Andrea della Porta
> > > <andrea.porta@suse.com> wrote:
> > > >
> > > > Hi Rob,
> > > >
> >
> > ...
> >
> > >
> > > I think simple-bus where you have it is fine. It is really 1 level up
> > > that needs to be specified. Basically something that's referenced from
> > > the specific PCI device's schema (e.g. the RP1 schema (which you are
> > > missing)).
> > >
> > > That schema needs to roughly look like this:
> > >
> > > properties:
> > >   "#address-cells":
> > >     const: 3
> > >   "#size-cells":
> > >     const: 2
> > >   ranges:
> > >     minItems: 1
> > >     maxItems: 6
> > >     items:
> > >       additionalItems: true
> > >       items:
> > >         - maximum: 5  # The BAR number
> > >         - const: 0
> > >         - const: 0
> > >         - # TODO: valid PCI memory flags
> > >
> > > patternProperties:
> > >   "^bar-bus@[0-5]$":
> > >     type: object
> > >     additionalProperties: true
> > >     properties:
> > >       compatible:
> > >         const: simple-bus
> > >       ranges: true
> > >
> >
> > Hmmm.. not sure how this is going to work. The PCI device (RP1) will
> > havei, at runtime, a compatible like this:
> >
> > compatible = "pci1de4,1\0pciclass,0200000\0pciclass,0200";
> >
> > that is basically generated automatically by the OF framework. So, in the
> > schema you proposed above, I can put something like:
> >
> > properties:
> >   compatible:
> >     contains:
> >       pattern: '^pci1de4,1'
> 
> No, it should be like this:
> 
> compatible:
>   items:
>     - const: pci1de4,1
>     - const: pciclass,0200000
>     - const: pciclass,0200
> 
> or
> 
> compatible:
>   addtionalItems: true
>   maxItems: 3
>   items:
>     - const: pci1de4,1
>

Ack.
 
> 
> Alternatively, we could instead only generate 'pciclass' compatibles
> for bridge nodes. The reason being that being an ethernet controller
> doesn't really tell us anything. There's no standard interface
> associated with that class.

I'd avoid this one, since the class is not representative in this case. RP1
is an MFD and not an Ethernet controller. Also, it would prevent other similar
PCI devices with differnt class from using this schema.

> 
> > or maybe I could omit the compatible entirely, like in:
> 
> No.
> 
> > https://github.com/devicetree-org/dt-schema/blob/main/dtschema/schemas/pci/pci-iommu.yaml
> 
> That's not a device node, but just part of pci-host-bridge.yaml.
> 
> > that seems to refer to generic compatible values.
> > In both cases though, I don't see how these binding could work with
> > make dt_binding_check, since there's no compatible known at compile
> > time (for the first approach), or no compatible at all (the second
> > approach).
> > Is it intended only as a loose documentation?
> 
> No, schemas define exactly what a binding can and can't contain. But
> they are divided into device schemas and common schemas. The latter
> are incomplete and are included by the former. Generally, "compatible"
> goes in device schemas.

Ack.

> 
> > Or are you proposing that for a future new bus (hence with a new, specific,
> > compatible) that could be described by the schema above?
> 
> The above schema would be the common schema included by a RP1 schema,
> LAN966x schema, or any other device doing the same thing.

Many thanks, I believe I've got it now :)

Cheers,
Andrea

> Rob

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-09-03 18:27           ` Krzysztof Kozlowski
@ 2024-09-05 16:33             ` Andrea della Porta
  2024-09-05 16:52               ` Krzysztof Kozlowski
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-09-05 16:33 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Krzysztof,

On 20:27 Tue 03 Sep     , Krzysztof Kozlowski wrote:
> On 03/09/2024 17:15, Andrea della Porta wrote:
> >>>>> +
> >>>>> +				rp1_clocks: clocks@c040018000 {
> >>>>
> >>>> Why do you mix MMIO with non-MMIO nodes? This really does not look
> >>>> correct.
> >>>>
> >>>
> >>> Right. This is already under discussion here:
> >>> https://lore.kernel.org/all/ZtBzis5CzQMm8loh@apocalypse/
> >>>
> >>> IIUC you proposed to instantiate the non-MMIO nodes (the three clocks) by
> >>> using CLK_OF_DECLARE.
> >>
> >> Depends. Where are these clocks? Naming suggests they might not be even
> >> part of this device. But if these are part of the device, then why this
> >> is not a clock controller (if they are controllable) or even removed
> >> (because we do not represent internal clock tree in DTS).
> > 
> > xosc is a crystal connected to the oscillator input of the RP1, so I would
> > consider it an external fixed-clock. If we were in the entire dts, I would have
> > put it in root under /clocks node, but here we're in the dtbo so I'm not sure
> > where else should I put it.
> 
> But physically, on which PCB, where is this clock located?

xosc is a crystal, feeding the reference clock oscillator input pins of the RP1,
please see page 12 of the following document:
https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
On Rpi5, the PCB is the very same as the one on which the BCM2712 (SoC) and RP1
are soldered. Would you consider it external (since the crystal is outside the RP1)
or internal (since the oscillator feeded by the crystal is inside the RP1)?

> 
> > 
> > Regarding pclk and hclk, I'm still trying to understand where they come from.
> > If they are external clocks (since they are fixed-clock too), they should be
> > in the same node as xosc. CLK_OF_DECLARE does not seem to fit here because
> 
> There is no such node as "/clocks" so do not focus on that. That's just
> placeholder but useless and it is inconsistent with other cases (e.g.
> regulators).

Fine, I beleve that the root node would be okay then, or some other carefully named
node in root, if the clock is not internal to any chip.

> 
> If this is external oscillator then it is not part of RP1 and you cannot
> put it inside just to satisfy your drivers.

Ack.

> 
> > there's no special management of these clocks, so no new clock definition is
> > needed.
> 
> > If they are internal tree, I cannot simply get rid of them because rp1_eth node
> > references these two clocks (see clocks property), so they must be decalred 
> > somewhere. Any hint about this?.
> > 
> 
> Describe the hardware. Show the diagram or schematics where is which device.

Unfortunately I don't have the documentation (schematics or other info) about
how these two clocks (pclk and hclk) are arranged, but I'm trying to get
some insight about that from various sources. While we're waiting for some
(hopefully) more certain info, I'd like to speculate a bit. I would say that
they both probably be either external (just like xosc), or generated internally
to the RP1:

If externals, I would place them in the same position as xosc, so root node
or some other node under root (eg.: /rp1-clocks)

If internals, I would leave them just where they are, i.e. inside the rp1 node

Does it make sense?

Many thnaks,
Andrea

> 
> Best regards,
> Krzysztof
> 

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

* Re: [PATCH 03/11] PCI: of_property: Sanitize 32 bit PCI address parsed from DT
  2024-09-03 22:26       ` Bjorn Helgaas
@ 2024-09-05 16:43         ` Andrea della Porta
  2024-09-05 20:16           ` Bjorn Helgaas
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-09-05 16:43 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Bjorn,

On 17:26 Tue 03 Sep     , Bjorn Helgaas wrote:
> On Mon, Aug 26, 2024 at 09:51:02PM +0200, Andrea della Porta wrote:
> > On 10:24 Wed 21 Aug     , Bjorn Helgaas wrote:
> > > On Tue, Aug 20, 2024 at 04:36:05PM +0200, Andrea della Porta wrote:
> > > > The of_pci_set_address() function parses devicetree PCI range
> > > > specifier assuming the address is 'sanitized' at the origin,
> > > > i.e. without checking whether the incoming address is 32 or 64
> > > > bit has specified in the flags.  In this way an address with no
> > > > OF_PCI_ADDR_SPACE_MEM64 set in the flags could leak through and
> > > > the upper 32 bits of the address will be set too, and this
> > > > violates the PCI specs stating that in 32 bit address the upper
> > > > bit should be zero.
> 
> > > I don't understand this code, so I'm probably missing something.  It
> > > looks like the interesting path here is:
> > > 
> > >   of_pci_prop_ranges
> > >     res = &pdev->resource[...];
> > >     for (j = 0; j < num; j++) {
> > >       val64 = res[j].start;
> > >       of_pci_set_address(..., val64, 0, flags, false);
> > >  +      if (OF_PCI_ADDR_SPACE_MEM64)
> > >  +        prop[1] = upper_32_bits(val64);
> > >  +      else
> > >  +        prop[1] = 0;
> > > 
> > > OF_PCI_ADDR_SPACE_MEM64 tells us about the size of the PCI bus
> > > address, but the address (val64) is a CPU physical address, not a PCI
> > > bus address, so I don't understand why of_pci_set_address() should use
> > > OF_PCI_ADDR_SPACE_MEM64 to clear part of the CPU address.
> > 
> > It all starts from of_pci_prop_ranges(), that is the caller of
> > of_pci_set_address().
> 
> > val64 (i.e. res[j].start) is the address part of a struct resource
> > that has its own flags.  Those flags are directly translated to
> > of_pci_range flags by of_pci_get_addr_flags(), so any
> > IORESOURCE_MEM_64 / IORESOURCE_MEM in the resource flag will
> > respectively become OF_PCI_ADDR_SPACE_MEM64 /
> > OF_PCI_ADDR_SPACE_MEM32 in pci range.
> 
> > What is advertised as 32 bit at the origin (val64) should not become
> > a 64 bit PCI address at the output of of_pci_set_address(), so the
> > upper 32 bit portion should be dropped. 
> 
> > This is explicitly stated in [1] (see page 5), where a space code of 0b10
> > implies that the upper 32 bit of the address must be zeroed out.
> 
> OK, I was confused and thought IORESOURCE_MEM_64 was telling us
> something about the *CPU* address, but it's actually telling us
> something about what *PCI bus* addresses are possible, i.e., whether
> it's a 32-bit BAR or a 64-bit BAR.
> 
> However, the CPU physical address space and the PCI bus address are
> not the same.  Generic code paths should account for that different by
> applying an offset (the offset will be zero on many platforms where
> CPU and PCI bus addresses *look* the same).
> 
> So a generic code path like of_pci_prop_ranges() that basically copies
> a CPU physical address to a PCI bus address looks broken to me.

Hmmm, I'd say that a translation from one bus type to the other is
going on nonetheless, and this is done in the current upstream function
as well. This patch of course does not add the translation (which is
already in place), just to do it avoiding generating inconsistent address.


> 
> Maybe my expectation of this being described in DT is mistaken.

Not sure what you mean here, the address being translated are coming from
DT, in fact they are described by "ranges" properties.

Many thanks,
Andrea

> Bjorn

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-09-05 16:33             ` Andrea della Porta
@ 2024-09-05 16:52               ` Krzysztof Kozlowski
  2024-09-05 18:54                 ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Krzysztof Kozlowski @ 2024-09-05 16:52 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On 05/09/2024 18:33, Andrea della Porta wrote:
> Hi Krzysztof,
> 
> On 20:27 Tue 03 Sep     , Krzysztof Kozlowski wrote:
>> On 03/09/2024 17:15, Andrea della Porta wrote:
>>>>>>> +
>>>>>>> +				rp1_clocks: clocks@c040018000 {
>>>>>>
>>>>>> Why do you mix MMIO with non-MMIO nodes? This really does not look
>>>>>> correct.
>>>>>>
>>>>>
>>>>> Right. This is already under discussion here:
>>>>> https://lore.kernel.org/all/ZtBzis5CzQMm8loh@apocalypse/
>>>>>
>>>>> IIUC you proposed to instantiate the non-MMIO nodes (the three clocks) by
>>>>> using CLK_OF_DECLARE.
>>>>
>>>> Depends. Where are these clocks? Naming suggests they might not be even
>>>> part of this device. But if these are part of the device, then why this
>>>> is not a clock controller (if they are controllable) or even removed
>>>> (because we do not represent internal clock tree in DTS).
>>>
>>> xosc is a crystal connected to the oscillator input of the RP1, so I would
>>> consider it an external fixed-clock. If we were in the entire dts, I would have
>>> put it in root under /clocks node, but here we're in the dtbo so I'm not sure
>>> where else should I put it.
>>
>> But physically, on which PCB, where is this clock located?
> 
> xosc is a crystal, feeding the reference clock oscillator input pins of the RP1,
> please see page 12 of the following document:
> https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf

That's not the answer. Where is it physically located?

> On Rpi5, the PCB is the very same as the one on which the BCM2712 (SoC) and RP1
> are soldered. Would you consider it external (since the crystal is outside the RP1)
> or internal (since the oscillator feeded by the crystal is inside the RP1)?

So it is on RPi 5 board? Just like every other SoC and every other
vendor? Then just like every other SoC and every other vendor it is in
board DTS file.

> 
>>
>>>
>>> Regarding pclk and hclk, I'm still trying to understand where they come from.
>>> If they are external clocks (since they are fixed-clock too), they should be
>>> in the same node as xosc. CLK_OF_DECLARE does not seem to fit here because
>>
>> There is no such node as "/clocks" so do not focus on that. That's just
>> placeholder but useless and it is inconsistent with other cases (e.g.
>> regulators).
> 
> Fine, I beleve that the root node would be okay then, or some other carefully named
> node in root, if the clock is not internal to any chip.
> 
>>
>> If this is external oscillator then it is not part of RP1 and you cannot
>> put it inside just to satisfy your drivers.
> 
> Ack.
> 
>>
>>> there's no special management of these clocks, so no new clock definition is
>>> needed.
>>
>>> If they are internal tree, I cannot simply get rid of them because rp1_eth node
>>> references these two clocks (see clocks property), so they must be decalred 
>>> somewhere. Any hint about this?.
>>>
>>
>> Describe the hardware. Show the diagram or schematics where is which device.
> 
> Unfortunately I don't have the documentation (schematics or other info) about
> how these two clocks (pclk and hclk) are arranged, but I'm trying to get
> some insight about that from various sources. While we're waiting for some
> (hopefully) more certain info, I'd like to speculate a bit. I would say that
> they both probably be either external (just like xosc), or generated internally
> to the RP1:
> 
> If externals, I would place them in the same position as xosc, so root node
> or some other node under root (eg.: /rp1-clocks)

Just like /clocks, /rp1-clocks is not better. Neither /rp1-foo-clocks.

I think there is some sort of big misunderstanding here. Is this RP1
co-processor on the RP board, connected over PCI to Broadcom SoC?

> 
> If internals, I would leave them just where they are, i.e. inside the rp1 node
> 
> Does it make sense?

No, because you do not have xosc there, according to my knowledge.

Best regards,
Krzysztof


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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-09-05 16:52               ` Krzysztof Kozlowski
@ 2024-09-05 18:54                 ` Andrea della Porta
  2024-09-05 21:20                   ` Krzysztof Kozlowski
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-09-05 18:54 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

Hi Krzysztof,

On 18:52 Thu 05 Sep     , Krzysztof Kozlowski wrote:
> On 05/09/2024 18:33, Andrea della Porta wrote:
> > Hi Krzysztof,
> > 
> > On 20:27 Tue 03 Sep     , Krzysztof Kozlowski wrote:
> >> On 03/09/2024 17:15, Andrea della Porta wrote:
> >>>>>>> +
> >>>>>>> +				rp1_clocks: clocks@c040018000 {
> >>>>>>
> >>>>>> Why do you mix MMIO with non-MMIO nodes? This really does not look
> >>>>>> correct.
> >>>>>>
> >>>>>
> >>>>> Right. This is already under discussion here:
> >>>>> https://lore.kernel.org/all/ZtBzis5CzQMm8loh@apocalypse/
> >>>>>
> >>>>> IIUC you proposed to instantiate the non-MMIO nodes (the three clocks) by
> >>>>> using CLK_OF_DECLARE.
> >>>>
> >>>> Depends. Where are these clocks? Naming suggests they might not be even
> >>>> part of this device. But if these are part of the device, then why this
> >>>> is not a clock controller (if they are controllable) or even removed
> >>>> (because we do not represent internal clock tree in DTS).
> >>>
> >>> xosc is a crystal connected to the oscillator input of the RP1, so I would
> >>> consider it an external fixed-clock. If we were in the entire dts, I would have
> >>> put it in root under /clocks node, but here we're in the dtbo so I'm not sure
> >>> where else should I put it.
> >>
> >> But physically, on which PCB, where is this clock located?
> > 
> > xosc is a crystal, feeding the reference clock oscillator input pins of the RP1,
> > please see page 12 of the following document:
> > https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
> 
> That's not the answer. Where is it physically located?

Please see below.

> 
> > On Rpi5, the PCB is the very same as the one on which the BCM2712 (SoC) and RP1
> > are soldered. Would you consider it external (since the crystal is outside the RP1)
> > or internal (since the oscillator feeded by the crystal is inside the RP1)?
> 
> So it is on RPi 5 board? Just like every other SoC and every other
> vendor? Then just like every other SoC and every other vendor it is in
> board DTS file.

Yes it's on the Rpi5 board. These are two separate thing, though: one is where
to put it (DTS, DTSO) and another is in what target path relative to root. I
was trying to understand the latter.
The clock node should be put in the DTBO since we are loading this driver at
runtime and we probably don't want to depend on some specific node name to be
present in the DTS. This is also true because this driver should possibly work
also on ACPI system and on hypothetical PCI card on which the RP1 could be mounted
in the future, and in that case a DTS could be not even there. 
After all, those clocks must be in the immediate proximity to the RP1, and on the
same board, which may or may not be the main board as the Rpi5 case.
I think that, since this application is a little bit peculiar, maybe some
compromises could be legit.

> 
> > 
> >>
> >>>
> >>> Regarding pclk and hclk, I'm still trying to understand where they come from.
> >>> If they are external clocks (since they are fixed-clock too), they should be
> >>> in the same node as xosc. CLK_OF_DECLARE does not seem to fit here because
> >>
> >> There is no such node as "/clocks" so do not focus on that. That's just
> >> placeholder but useless and it is inconsistent with other cases (e.g.
> >> regulators).
> > 
> > Fine, I beleve that the root node would be okay then, or some other carefully named
> > node in root, if the clock is not internal to any chip.
> > 
> >>
> >> If this is external oscillator then it is not part of RP1 and you cannot
> >> put it inside just to satisfy your drivers.
> > 
> > Ack.
> > 
> >>
> >>> there's no special management of these clocks, so no new clock definition is
> >>> needed.
> >>
> >>> If they are internal tree, I cannot simply get rid of them because rp1_eth node
> >>> references these two clocks (see clocks property), so they must be decalred 
> >>> somewhere. Any hint about this?.
> >>>
> >>
> >> Describe the hardware. Show the diagram or schematics where is which device.
> > 
> > Unfortunately I don't have the documentation (schematics or other info) about
> > how these two clocks (pclk and hclk) are arranged, but I'm trying to get
> > some insight about that from various sources. While we're waiting for some
> > (hopefully) more certain info, I'd like to speculate a bit. I would say that
> > they both probably be either external (just like xosc), or generated internally
> > to the RP1:
> > 
> > If externals, I would place them in the same position as xosc, so root node
> > or some other node under root (eg.: /rp1-clocks)
> 
> Just like /clocks, /rp1-clocks is not better. Neither /rp1-foo-clocks.

Right. So in this case, since xosc seems to be on the same level and on the same
board of the RP1 and the SoC, and it's also external to the RP1, can I assume that
placing xosc node in root is ok?

> 
> I think there is some sort of big misunderstanding here. Is this RP1
> co-processor on the RP board, connected over PCI to Broadcom SoC?

Yes. 

 ---------------Rpi5 board---------------------
 |                                            |
 |    SoC ==pci bus==> RP1 <== xosc crystal   |
 |                                            |
 ----------------------------------------------

> 
> > 
> > If internals, I would leave them just where they are, i.e. inside the rp1 node
> > 
> > Does it make sense?
> 
> No, because you do not have xosc there, according to my knowledge.

Hmmm sorry, not sure what this negation was referring to... I was talking about
hclk and pclk, not xosc here. Could you please add some details?

Many thanks,
Andrea

> 
> Best regards,
> Krzysztof
> 

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

* Re: [PATCH 03/11] PCI: of_property: Sanitize 32 bit PCI address parsed from DT
  2024-09-05 16:43         ` Andrea della Porta
@ 2024-09-05 20:16           ` Bjorn Helgaas
  2024-09-27  6:48             ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Bjorn Helgaas @ 2024-09-05 20:16 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren, Lizhi Hou

[+cc Lizhi]

On Thu, Sep 05, 2024 at 06:43:35PM +0200, Andrea della Porta wrote:
> On 17:26 Tue 03 Sep     , Bjorn Helgaas wrote:
> > On Mon, Aug 26, 2024 at 09:51:02PM +0200, Andrea della Porta wrote:
> > > On 10:24 Wed 21 Aug     , Bjorn Helgaas wrote:
> > > > On Tue, Aug 20, 2024 at 04:36:05PM +0200, Andrea della Porta wrote:
> > > > > The of_pci_set_address() function parses devicetree PCI range
> > > > > specifier assuming the address is 'sanitized' at the origin,
> > > > > i.e. without checking whether the incoming address is 32 or 64
> > > > > bit has specified in the flags.  In this way an address with no
> > > > > OF_PCI_ADDR_SPACE_MEM64 set in the flags could leak through and
> > > > > the upper 32 bits of the address will be set too, and this
> > > > > violates the PCI specs stating that in 32 bit address the upper
> > > > > bit should be zero.
> > 
> > > > I don't understand this code, so I'm probably missing something.  It
> > > > looks like the interesting path here is:
> > > > 
> > > >   of_pci_prop_ranges
> > > >     res = &pdev->resource[...];
> > > >     for (j = 0; j < num; j++) {
> > > >       val64 = res[j].start;
> > > >       of_pci_set_address(..., val64, 0, flags, false);
> > > >  +      if (OF_PCI_ADDR_SPACE_MEM64)
> > > >  +        prop[1] = upper_32_bits(val64);
> > > >  +      else
> > > >  +        prop[1] = 0;
> ...
> > However, the CPU physical address space and the PCI bus address are
> > not the same.  Generic code paths should account for that different by
> > applying an offset (the offset will be zero on many platforms where
> > CPU and PCI bus addresses *look* the same).
> > 
> > So a generic code path like of_pci_prop_ranges() that basically copies
> > a CPU physical address to a PCI bus address looks broken to me.
> 
> Hmmm, I'd say that a translation from one bus type to the other is
> going on nonetheless, and this is done in the current upstream function
> as well. This patch of course does not add the translation (which is
> already in place), just to do it avoiding generating inconsistent address.

I think I was looking at this backwards.  I assumed we were *parsing"
a "ranges" property, but I think in fact we're *building* a "ranges"
property to describe an existing PCI device (either a PCI-to-PCI
bridge or an endpoint).  For such devices there is no address
translation.

Any address translation would only occur at a PCI host bridge that has
CPU address space on the upstream side and PCI address space on the
downstream side.

Since (IIUC), we're building "ranges" for a device in the interior of
a PCI hierarchy where address translation doesn't happen, I think both
the parent and child addresses in "ranges" should be in the PCI
address space.

But right now, I think they're both in the CPU address space, and we
basically do this:

  of_pci_prop_ranges(struct pci_dev *pdev, ...)
    res = &pdev->resource[...];
    for (j = 0; j < num; j++) {   # iterate through BARs or windows
      val64 = res[j].start;       # CPU physical address
      # <convert to PCI address space>
      of_pci_set_address(..., rp[i].parent_addr, val64, ...)
        rp[i].parent_addr = val64
      if (pci_is_bridge(pdev))
        memcpy(rp[i].child_addr, rp[i].parent_addr)
      else
        rp[i].child_addr[0] = j   # child addr unset/unused

Here "res" is a PCI BAR or bridge window, and it contains CPU physical
addresses, so "val64" is a CPU physical address.  It looks to me like
we should convert to a PCI bus address at the point noted above, based
on any translation described by the PCI host bridge.  That *should*
naturally result in a 32-bit value if OF_PCI_ADDR_SPACE_MEM64 is not
set.

> > Maybe my expectation of this being described in DT is mistaken.
> 
> Not sure what you mean here, the address being translated are coming from
> DT, in fact they are described by "ranges" properties.

Right, for my own future reference since I couldn't find a generic
description of "ranges" in Documentation/devicetree/:

[1] https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#ranges

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

* Re: [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver
  2024-09-05 18:54                 ` Andrea della Porta
@ 2024-09-05 21:20                   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 117+ messages in thread
From: Krzysztof Kozlowski @ 2024-09-05 21:20 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren

On 05/09/2024 20:54, Andrea della Porta wrote:
> Hi Krzysztof,
> 
> On 18:52 Thu 05 Sep     , Krzysztof Kozlowski wrote:
>> On 05/09/2024 18:33, Andrea della Porta wrote:
>>> Hi Krzysztof,
>>>
>>> On 20:27 Tue 03 Sep     , Krzysztof Kozlowski wrote:
>>>> On 03/09/2024 17:15, Andrea della Porta wrote:
>>>>>>>>> +
>>>>>>>>> +				rp1_clocks: clocks@c040018000 {
>>>>>>>>
>>>>>>>> Why do you mix MMIO with non-MMIO nodes? This really does not look
>>>>>>>> correct.
>>>>>>>>
>>>>>>>
>>>>>>> Right. This is already under discussion here:
>>>>>>> https://lore.kernel.org/all/ZtBzis5CzQMm8loh@apocalypse/
>>>>>>>
>>>>>>> IIUC you proposed to instantiate the non-MMIO nodes (the three clocks) by
>>>>>>> using CLK_OF_DECLARE.
>>>>>>
>>>>>> Depends. Where are these clocks? Naming suggests they might not be even
>>>>>> part of this device. But if these are part of the device, then why this
>>>>>> is not a clock controller (if they are controllable) or even removed
>>>>>> (because we do not represent internal clock tree in DTS).
>>>>>
>>>>> xosc is a crystal connected to the oscillator input of the RP1, so I would
>>>>> consider it an external fixed-clock. If we were in the entire dts, I would have
>>>>> put it in root under /clocks node, but here we're in the dtbo so I'm not sure
>>>>> where else should I put it.
>>>>
>>>> But physically, on which PCB, where is this clock located?
>>>
>>> xosc is a crystal, feeding the reference clock oscillator input pins of the RP1,
>>> please see page 12 of the following document:
>>> https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
>>
>> That's not the answer. Where is it physically located?
> 
> Please see below.
> 
>>
>>> On Rpi5, the PCB is the very same as the one on which the BCM2712 (SoC) and RP1
>>> are soldered. Would you consider it external (since the crystal is outside the RP1)
>>> or internal (since the oscillator feeded by the crystal is inside the RP1)?
>>
>> So it is on RPi 5 board? Just like every other SoC and every other
>> vendor? Then just like every other SoC and every other vendor it is in
>> board DTS file.
> 
> Yes it's on the Rpi5 board. These are two separate thing, though: one is where

Finally.

> to put it (DTS, DTSO) and another is in what target path relative to root. I
> was trying to understand the latter.

It is already or should be part of DTS, not DTSO. You are duplicating
device nodes.

> The clock node should be put in the DTBO since we are loading this driver at
> runtime and we probably don't want to depend on some specific node name to be
> present in the DTS. This is also true because this driver should possibly work
> also on ACPI system and on hypothetical PCI card on which the RP1 could be mounted

Not really. ACPI and thus DT in such case will take it as clock input.
Basically what you need here is to provide clock inputs to this device.
It's then firmware independent.

> in the future, and in that case a DTS could be not even there. 

No problem. Whatever firmware mechanism you have, it will provide you clock.

> After all, those clocks must be in the immediate proximity to the RP1, and on the
> same board, which may or may not be the main board as the Rpi5 case.
> I think that, since this application is a little bit peculiar, maybe some
> compromises could be legit.

Application is not peculiar but completely standard. You have standard
PCI device which has some inputs. One of these inputs, maybe on some
reserved M.2 pins or whatver connector you have there, is the clock.

...

>>>
>>> If externals, I would place them in the same position as xosc, so root node
>>> or some other node under root (eg.: /rp1-clocks)
>>
>> Just like /clocks, /rp1-clocks is not better. Neither /rp1-foo-clocks.
> 
> Right. So in this case, since xosc seems to be on the same level and on the same
> board of the RP1 and the SoC, and it's also external to the RP1, can I assume that
> placing xosc node in root is ok?

root node of the DTS yes. Root node of DTSO of course not, because it is
not part of DTSO and you are duplicating DTS. It would not even work.

That's why you need to apply the overlay to proper target as I asked
long time ago.

> 
>>
>> I think there is some sort of big misunderstanding here. Is this RP1
>> co-processor on the RP board, connected over PCI to Broadcom SoC?
> 
> Yes. 
> 
>  ---------------Rpi5 board---------------------
>  |                                            |
>  |    SoC ==pci bus==> RP1 <== xosc crystal   |
>  |                                            |
>  ----------------------------------------------
> 
>>
>>>
>>> If internals, I would leave them just where they are, i.e. inside the rp1 node
>>>
>>> Does it make sense?
>>
>> No, because you do not have xosc there, according to my knowledge.
> 
> Hmmm sorry, not sure what this negation was referring to... I was talking about
> hclk and pclk, not xosc here. Could you please add some details?

If considering hclk and pclk, then depends where are they. If they come
as inputs, then same as xosc. If they are not, then it is also obvious -
we do not represent internal device clocks as fixed clocks in DTS,
because it makes absolutely no sense at all. No benefits, no help,
nothing at all.

It's just device's internal clock.

This is again nothing peculiar. Many other devices have some internal
stuff. Do we add fixed clocks for these? Fixed regulators? No, of course
not.

Best regards,
Krzysztof


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

* Re: [PATCH 05/11] vmlinux.lds.h: Preserve DTB sections from being discarded after init
  2024-09-03 12:29     ` Andrea della Porta
@ 2024-09-21 20:47       ` Stephen Boyd
  2024-09-22  8:14         ` Masahiro Yamada
  0 siblings, 1 reply; 117+ messages in thread
From: Stephen Boyd @ 2024-09-21 20:47 UTC (permalink / raw)
  To: Andrea della Porta, Masahiro Yamada
  Cc: Andrea della Porta, Andrew Lunn, Arnd Bergmann, Bjorn Helgaas,
	Broadcom internal kernel review list, Catalin Marinas,
	Claudiu Beznea, Conor Dooley, David S. Miller, Derek Kiernan,
	Dragan Cvetic, Eric Dumazet, Florian Fainelli, Greg Kroah-Hartman,
	Jakub Kicinski, Krzysztof Kozlowski, Lee Jones, Linus Walleij,
	Michael Turquette, Nicolas Ferre, Paolo Abeni, Rob Herring,
	Saravana Kannan, Stefan Wahren, Will Deacon, devicetree,
	linux-arch, linux-arm-kernel, linux-clk, linux-gpio, linux-kernel,
	linux-pci, linux-rpi-kernel, netdev, linux-kbuild

Quoting Andrea della Porta (2024-09-03 05:29:18)
> On 12:46 Fri 30 Aug     , Stephen Boyd wrote:
> > Quoting Andrea della Porta (2024-08-20 07:36:07)
> > > diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> > > index ad6afc5c4918..3ae9097774b0 100644
> > > --- a/include/asm-generic/vmlinux.lds.h
> > > +++ b/include/asm-generic/vmlinux.lds.h
> > 
> > It would be nice to keep the initdata properties when this isn't used
> > after init as well. Perhaps we need another macro and/or filename to
> > indicate that the DTB{O} can be thrown away after init/module init.
> 
> We can certainly add some more filename extension that would place the
> relevant data in a droppable section. 
> Throwing away the dtb/o after init is like the actual KERNEL_DTB macro that
> is adding teh data to section .init.data, but this would mean t would be
> useful only at very early init stage, just like for CONFIG_OF_UNITTEST.
> Throwing after module init could be more difficult though, I think,
> for example we're not sure when to discard the section in case of deferred
> modules probe.
> 

This patch can fix a modpost warning seen in linux-next because I have
added DT overlays from KUnit tests while kbuild has properly marked the
overlay as initdata that is discarded. See [1] for details. In KUnit I
doubt this really matters because most everything runs from __init code
(even if it isn't marked that way).

I'm thinking that we need to make dtbo Makefile target put the blob in
the rodata section so it doesn't get thrown away and leave the builtin
DTB as part of init.rodata. Did you already do that? I see the kbuild
tree has removed the commit that caused the warning, but I suspect this
may still be a problem. See [2] for the next series where overlays
applied in the test happen from driver probe so __ref is added.

If we simply copy the wrap command and make it so that overlays always
go to the .rodata section we should be good. Maybe there's some way to
figure out what is being wrapped so we don't have to copy the whole
thing.

Finally, it's unfortunate that the DTBO is copied when an overlay is
applied. We'll waste memory after this patch, so of_overlay_fdt_apply()
could be taught to reuse the blob passed in instead of copying it.

-----8<----
diff --git a/scripts/Makefile.dtbs b/scripts/Makefile.dtbs
index 55998b878e54..070e08082cd3 100644
--- a/scripts/Makefile.dtbs
+++ b/scripts/Makefile.dtbs
@@ -51,11 +51,25 @@ quiet_cmd_wrap_S_dtb = WRAP    $@
 		echo '.balign STRUCT_ALIGNMENT';					\
 	} > $@
 
+quiet_cmd_wrap_S_dtbo = WRAP    $@
+      cmd_wrap_S_dtbo = {								\
+		symbase=__$(patsubst .%,%,$(suffix $<))_$(subst -,_,$(notdir $*));	\
+		echo '\#include <asm-generic/vmlinux.lds.h>';				\
+		echo '.section .rodata,"a"';						\
+		echo '.balign STRUCT_ALIGNMENT';					\
+		echo ".global $${symbase}_begin";					\
+		echo "$${symbase}_begin:";						\
+		echo '.incbin "$<" ';							\
+		echo ".global $${symbase}_end";						\
+		echo "$${symbase}_end:";						\
+		echo '.balign STRUCT_ALIGNMENT';					\
+	} > $@
+
 $(obj)/%.dtb.S: $(obj)/%.dtb FORCE
 	$(call if_changed,wrap_S_dtb)
 
 $(obj)/%.dtbo.S: $(obj)/%.dtbo FORCE
-	$(call if_changed,wrap_S_dtb)
+	$(call if_changed,wrap_S_dtbo)
 
 # Schema check
 # ---------------------------------------------------------------------------

[1] https://lore.kernel.org/all/20240909112728.30a9bd35@canb.auug.org.au/
[2] https://lore.kernel.org/all/20240910094459.352572-1-masahiroy@kernel.org/

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

* Re: [PATCH 05/11] vmlinux.lds.h: Preserve DTB sections from being discarded after init
  2024-09-21 20:47       ` Stephen Boyd
@ 2024-09-22  8:14         ` Masahiro Yamada
  2024-09-23 18:13           ` Stephen Boyd
  0 siblings, 1 reply; 117+ messages in thread
From: Masahiro Yamada @ 2024-09-22  8:14 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Andrea della Porta, Andrew Lunn, Arnd Bergmann, Bjorn Helgaas,
	Broadcom internal kernel review list, Catalin Marinas,
	Claudiu Beznea, Conor Dooley, David S. Miller, Derek Kiernan,
	Dragan Cvetic, Eric Dumazet, Florian Fainelli, Greg Kroah-Hartman,
	Jakub Kicinski, Krzysztof Kozlowski, Lee Jones, Linus Walleij,
	Michael Turquette, Nicolas Ferre, Paolo Abeni, Rob Herring,
	Saravana Kannan, Stefan Wahren, Will Deacon, devicetree,
	linux-arch, linux-arm-kernel, linux-clk, linux-gpio, linux-kernel,
	linux-pci, linux-rpi-kernel, netdev, linux-kbuild

On Sun, Sep 22, 2024 at 5:47 AM Stephen Boyd <sboyd@kernel.org> wrote:
>
> Quoting Andrea della Porta (2024-09-03 05:29:18)
> > On 12:46 Fri 30 Aug     , Stephen Boyd wrote:
> > > Quoting Andrea della Porta (2024-08-20 07:36:07)
> > > > diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> > > > index ad6afc5c4918..3ae9097774b0 100644
> > > > --- a/include/asm-generic/vmlinux.lds.h
> > > > +++ b/include/asm-generic/vmlinux.lds.h
> > >
> > > It would be nice to keep the initdata properties when this isn't used
> > > after init as well. Perhaps we need another macro and/or filename to
> > > indicate that the DTB{O} can be thrown away after init/module init.
> >
> > We can certainly add some more filename extension that would place the
> > relevant data in a droppable section.
> > Throwing away the dtb/o after init is like the actual KERNEL_DTB macro that
> > is adding teh data to section .init.data, but this would mean t would be
> > useful only at very early init stage, just like for CONFIG_OF_UNITTEST.
> > Throwing after module init could be more difficult though, I think,
> > for example we're not sure when to discard the section in case of deferred
> > modules probe.
> >
>
> This patch can fix a modpost warning seen in linux-next because I have
> added DT overlays from KUnit tests while kbuild has properly marked the
> overlay as initdata that is discarded. See [1] for details. In KUnit I
> doubt this really matters because most everything runs from __init code
> (even if it isn't marked that way).
>
> I'm thinking that we need to make dtbo Makefile target put the blob in
> the rodata section so it doesn't get thrown away and leave the builtin
> DTB as part of init.rodata. Did you already do that? I see the kbuild
> tree has removed the commit that caused the warning, but I suspect this
> may still be a problem. See [2] for the next series where overlays
> applied in the test happen from driver probe so __ref is added.
>
> If we simply copy the wrap command and make it so that overlays always
> go to the .rodata section we should be good. Maybe there's some way to
> figure out what is being wrapped so we don't have to copy the whole
> thing.
>
> Finally, it's unfortunate that the DTBO is copied when an overlay is
> applied. We'll waste memory after this patch, so of_overlay_fdt_apply()
> could be taught to reuse the blob passed in instead of copying it.
>
> -----8<----
> diff --git a/scripts/Makefile.dtbs b/scripts/Makefile.dtbs
> index 55998b878e54..070e08082cd3 100644
> --- a/scripts/Makefile.dtbs
> +++ b/scripts/Makefile.dtbs
> @@ -51,11 +51,25 @@ quiet_cmd_wrap_S_dtb = WRAP    $@
>                 echo '.balign STRUCT_ALIGNMENT';                                        \
>         } > $@
>
> +quiet_cmd_wrap_S_dtbo = WRAP    $@
> +      cmd_wrap_S_dtbo = {                                                              \
> +               symbase=__$(patsubst .%,%,$(suffix $<))_$(subst -,_,$(notdir $*));      \
> +               echo '\#include <asm-generic/vmlinux.lds.h>';                           \
> +               echo '.section .rodata,"a"';                                            \
> +               echo '.balign STRUCT_ALIGNMENT';                                        \
> +               echo ".global $${symbase}_begin";                                       \
> +               echo "$${symbase}_begin:";                                              \
> +               echo '.incbin "$<" ';                                                   \
> +               echo ".global $${symbase}_end";                                         \
> +               echo "$${symbase}_end:";                                                \
> +               echo '.balign STRUCT_ALIGNMENT';                                        \
> +       } > $@
> +
>  $(obj)/%.dtb.S: $(obj)/%.dtb FORCE
>         $(call if_changed,wrap_S_dtb)
>
>  $(obj)/%.dtbo.S: $(obj)/%.dtbo FORCE
> -       $(call if_changed,wrap_S_dtb)
> +       $(call if_changed,wrap_S_dtbo)
>
>  # Schema check
>  # ---------------------------------------------------------------------------
>
> [1] https://lore.kernel.org/all/20240909112728.30a9bd35@canb.auug.org.au/
> [2] https://lore.kernel.org/all/20240910094459.352572-1-masahiroy@kernel.org/







Rather, I'd modify my patch as follows:



--- a/scripts/Makefile.dtbs
+++ b/scripts/Makefile.dtbs
@@ -34,12 +34,14 @@ $(obj)/dtbs-list: $(dtb-y) FORCE
 # Assembly file to wrap dtb(o)
 # ---------------------------------------------------------------------------

+builtin-dtb-section = $(if $(filter arch/%, $(obj)),.dtb.init.rodata,.rodata)
+
 # Generate an assembly file to wrap the output of the device tree compiler
 quiet_cmd_wrap_S_dtb = WRAP    $@
       cmd_wrap_S_dtb = { \
  symbase=__$(patsubst .%,%,$(suffix $<))_$(subst -,_,$(notdir $*)); \
  echo '\#include <asm-generic/vmlinux.lds.h>'; \
- echo '.section .dtb.init.rodata,"a"'; \
+ echo '.section $(builtin-dtb-section),"a"'; \
  echo '.balign STRUCT_ALIGNMENT'; \
  echo ".global $${symbase}_begin"; \
  echo "$${symbase}_begin:"; \




-- 
Best Regards
Masahiro Yamada

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

* Re: [PATCH 05/11] vmlinux.lds.h: Preserve DTB sections from being discarded after init
  2024-09-22  8:14         ` Masahiro Yamada
@ 2024-09-23 18:13           ` Stephen Boyd
  2024-09-24  2:45             ` Masahiro Yamada
  0 siblings, 1 reply; 117+ messages in thread
From: Stephen Boyd @ 2024-09-23 18:13 UTC (permalink / raw)
  To: Masahiro Yamada
  Cc: Andrea della Porta, Andrew Lunn, Arnd Bergmann, Bjorn Helgaas,
	Broadcom internal kernel review list, Catalin Marinas,
	Claudiu Beznea, Conor Dooley, David S. Miller, Derek Kiernan,
	Dragan Cvetic, Eric Dumazet, Florian Fainelli, Greg Kroah-Hartman,
	Jakub Kicinski, Krzysztof Kozlowski, Lee Jones, Linus Walleij,
	Michael Turquette, Nicolas Ferre, Paolo Abeni, Rob Herring,
	Saravana Kannan, Stefan Wahren, Will Deacon, devicetree,
	linux-arch, linux-arm-kernel, linux-clk, linux-gpio, linux-kernel,
	linux-pci, linux-rpi-kernel, netdev, linux-kbuild

Quoting Masahiro Yamada (2024-09-22 01:14:12)
> 
> Rather, I'd modify my patch as follows:
> 
> --- a/scripts/Makefile.dtbs
> +++ b/scripts/Makefile.dtbs
> @@ -34,12 +34,14 @@ $(obj)/dtbs-list: $(dtb-y) FORCE
>  # Assembly file to wrap dtb(o)
>  # ---------------------------------------------------------------------------
> 
> +builtin-dtb-section = $(if $(filter arch/%, $(obj)),.dtb.init.rodata,.rodata)

I think we want to free the empty root dtb that's always builtin. That
is in drivers/of/ right? And I worry that an overlay could be in arch/
and then this breaks again. That's why it feels more correct to treat
dtbo.o vs. dtb.o differently. Perhaps we can check $(obj) for dtbo vs
dtb?

Also, modpost code looks for .init* named sections and treats them as
initdata already. Can we rename .dtb.init.rodata to .init.dtb.rodata so
that modpost can find that?

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

* Re: [PATCH 05/11] vmlinux.lds.h: Preserve DTB sections from being discarded after init
  2024-09-23 18:13           ` Stephen Boyd
@ 2024-09-24  2:45             ` Masahiro Yamada
  0 siblings, 0 replies; 117+ messages in thread
From: Masahiro Yamada @ 2024-09-24  2:45 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Andrea della Porta, Andrew Lunn, Arnd Bergmann, Bjorn Helgaas,
	Broadcom internal kernel review list, Catalin Marinas,
	Claudiu Beznea, Conor Dooley, David S. Miller, Derek Kiernan,
	Dragan Cvetic, Eric Dumazet, Florian Fainelli, Greg Kroah-Hartman,
	Jakub Kicinski, Krzysztof Kozlowski, Lee Jones, Linus Walleij,
	Michael Turquette, Nicolas Ferre, Paolo Abeni, Rob Herring,
	Saravana Kannan, Stefan Wahren, Will Deacon, devicetree,
	linux-arch, linux-arm-kernel, linux-clk, linux-gpio, linux-kernel,
	linux-pci, linux-rpi-kernel, netdev, linux-kbuild

On Tue, Sep 24, 2024 at 3:13 AM Stephen Boyd <sboyd@kernel.org> wrote:
>
> Quoting Masahiro Yamada (2024-09-22 01:14:12)
> >
> > Rather, I'd modify my patch as follows:
> >
> > --- a/scripts/Makefile.dtbs
> > +++ b/scripts/Makefile.dtbs
> > @@ -34,12 +34,14 @@ $(obj)/dtbs-list: $(dtb-y) FORCE
> >  # Assembly file to wrap dtb(o)
> >  # ---------------------------------------------------------------------------
> >
> > +builtin-dtb-section = $(if $(filter arch/%, $(obj)),.dtb.init.rodata,.rodata)
>
> I think we want to free the empty root dtb that's always builtin. That
> is in drivers/of/ right?


drivers/of/empty_root.dts is really small.

That is not a big deal even if empty_root.dtb
remains in the .rodata section.



> And I worry that an overlay could be in arch/
> and then this breaks again. That's why it feels more correct to treat
> dtbo.o vs. dtb.o differently. Perhaps we can check $(obj) for dtbo vs
> dtb?


This is not a problem either.


Checking $(obj)/ is temporary.

See this later patch:

https://lore.kernel.org/linux-kbuild/20240904234803.698424-16-masahiroy@kernel.org/T/#u

After my work is completed, DTB and DTBO will go
to the .rodata section unconditionally.



> Also, modpost code looks for .init* named sections and treats them as
> initdata already. Can we rename .dtb.init.rodata to .init.dtb.rodata so
> that modpost can find that?


My previous patch checked .dtb.init.rodata.

I do not mind renaming it to .init.dtb.rodata.







-- 
Best Regards
Masahiro Yamada

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

* Re: [PATCH 03/11] PCI: of_property: Sanitize 32 bit PCI address parsed from DT
  2024-09-05 20:16           ` Bjorn Helgaas
@ 2024-09-27  6:48             ` Andrea della Porta
  2024-09-28 20:17               ` Bjorn Helgaas
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-09-27  6:48 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren, Lizhi Hou

Hi Bjorn,

On 15:16 Thu 05 Sep     , Bjorn Helgaas wrote:
> [+cc Lizhi]
> 
> On Thu, Sep 05, 2024 at 06:43:35PM +0200, Andrea della Porta wrote:
> > On 17:26 Tue 03 Sep     , Bjorn Helgaas wrote:
> > > On Mon, Aug 26, 2024 at 09:51:02PM +0200, Andrea della Porta wrote:
> > > > On 10:24 Wed 21 Aug     , Bjorn Helgaas wrote:
> > > > > On Tue, Aug 20, 2024 at 04:36:05PM +0200, Andrea della Porta wrote:
> > > > > > The of_pci_set_address() function parses devicetree PCI range
> > > > > > specifier assuming the address is 'sanitized' at the origin,
> > > > > > i.e. without checking whether the incoming address is 32 or 64
> > > > > > bit has specified in the flags.  In this way an address with no
> > > > > > OF_PCI_ADDR_SPACE_MEM64 set in the flags could leak through and
> > > > > > the upper 32 bits of the address will be set too, and this
> > > > > > violates the PCI specs stating that in 32 bit address the upper
> > > > > > bit should be zero.
> > > 
> > > > > I don't understand this code, so I'm probably missing something.  It
> > > > > looks like the interesting path here is:
> > > > > 
> > > > >   of_pci_prop_ranges
> > > > >     res = &pdev->resource[...];
> > > > >     for (j = 0; j < num; j++) {
> > > > >       val64 = res[j].start;
> > > > >       of_pci_set_address(..., val64, 0, flags, false);
> > > > >  +      if (OF_PCI_ADDR_SPACE_MEM64)
> > > > >  +        prop[1] = upper_32_bits(val64);
> > > > >  +      else
> > > > >  +        prop[1] = 0;
> > ...
> > > However, the CPU physical address space and the PCI bus address are
> > > not the same.  Generic code paths should account for that different by
> > > applying an offset (the offset will be zero on many platforms where
> > > CPU and PCI bus addresses *look* the same).
> > > 
> > > So a generic code path like of_pci_prop_ranges() that basically copies
> > > a CPU physical address to a PCI bus address looks broken to me.
> > 
> > Hmmm, I'd say that a translation from one bus type to the other is
> > going on nonetheless, and this is done in the current upstream function
> > as well. This patch of course does not add the translation (which is
> > already in place), just to do it avoiding generating inconsistent address.
> 
> I think I was looking at this backwards.  I assumed we were *parsing"
> a "ranges" property, but I think in fact we're *building* a "ranges"
> property to describe an existing PCI device (either a PCI-to-PCI
> bridge or an endpoint).  For such devices there is no address
> translation.
> 
> Any address translation would only occur at a PCI host bridge that has
> CPU address space on the upstream side and PCI address space on the
> downstream side.
> 
> Since (IIUC), we're building "ranges" for a device in the interior of
> a PCI hierarchy where address translation doesn't happen, I think both
> the parent and child addresses in "ranges" should be in the PCI
> address space.
> 
> But right now, I think they're both in the CPU address space, and we
> basically do this:
> 
>   of_pci_prop_ranges(struct pci_dev *pdev, ...)
>     res = &pdev->resource[...];
>     for (j = 0; j < num; j++) {   # iterate through BARs or windows
>       val64 = res[j].start;       # CPU physical address
>       # <convert to PCI address space>
>       of_pci_set_address(..., rp[i].parent_addr, val64, ...)
>         rp[i].parent_addr = val64
>       if (pci_is_bridge(pdev))
>         memcpy(rp[i].child_addr, rp[i].parent_addr)
>       else
>         rp[i].child_addr[0] = j   # child addr unset/unused
> 
> Here "res" is a PCI BAR or bridge window, and it contains CPU physical
> addresses, so "val64" is a CPU physical address.  It looks to me like
> we should convert to a PCI bus address at the point noted above, based
> on any translation described by the PCI host bridge.  That *should*
> naturally result in a 32-bit value if OF_PCI_ADDR_SPACE_MEM64 is not
> set.

That's exactly the point, ecxept that right now a 64 bit address would
"unnaturally" pass through even if OF_PCI_ADDR_SPACE_MEM64 is not set.
Hence the purpose of this patch.

Many thanks,
Andrea

> 
> > > Maybe my expectation of this being described in DT is mistaken.
> > 
> > Not sure what you mean here, the address being translated are coming from
> > DT, in fact they are described by "ranges" properties.
> 
> Right, for my own future reference since I couldn't find a generic
> description of "ranges" in Documentation/devicetree/:
> 
> [1] https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#ranges

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

* Re: [PATCH 03/11] PCI: of_property: Sanitize 32 bit PCI address parsed from DT
  2024-09-27  6:48             ` Andrea della Porta
@ 2024-09-28 20:17               ` Bjorn Helgaas
  2024-10-06 11:20                 ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Bjorn Helgaas @ 2024-09-28 20:17 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren, Lizhi Hou

On Fri, Sep 27, 2024 at 08:48:28AM +0200, Andrea della Porta wrote:
> On 15:16 Thu 05 Sep     , Bjorn Helgaas wrote:
> > On Thu, Sep 05, 2024 at 06:43:35PM +0200, Andrea della Porta wrote:
> > > On 17:26 Tue 03 Sep     , Bjorn Helgaas wrote:
> > > > On Mon, Aug 26, 2024 at 09:51:02PM +0200, Andrea della Porta wrote:
> > > > > On 10:24 Wed 21 Aug     , Bjorn Helgaas wrote:
> > > > > > On Tue, Aug 20, 2024 at 04:36:05PM +0200, Andrea della Porta wrote:
> > > > > > > The of_pci_set_address() function parses devicetree PCI range
> > > > > > > specifier assuming the address is 'sanitized' at the origin,
> > > > > > > i.e. without checking whether the incoming address is 32 or 64
> > > > > > > bit has specified in the flags.  In this way an address with no
> > > > > > > OF_PCI_ADDR_SPACE_MEM64 set in the flags could leak through and
> > > > > > > the upper 32 bits of the address will be set too, and this
> > > > > > > violates the PCI specs stating that in 32 bit address the upper
> > > > > > > bit should be zero.
> > > > 
> > > > > > I don't understand this code, so I'm probably missing something.  It
> > > > > > looks like the interesting path here is:
> > > > > > 
> > > > > >   of_pci_prop_ranges
> > > > > >     res = &pdev->resource[...];
> > > > > >     for (j = 0; j < num; j++) {
> > > > > >       val64 = res[j].start;
> > > > > >       of_pci_set_address(..., val64, 0, flags, false);
> > > > > >  +      if (OF_PCI_ADDR_SPACE_MEM64)
> > > > > >  +        prop[1] = upper_32_bits(val64);
> > > > > >  +      else
> > > > > >  +        prop[1] = 0;
> > > ...
> > > > However, the CPU physical address space and the PCI bus address are
> > > > not the same.  Generic code paths should account for that different by
> > > > applying an offset (the offset will be zero on many platforms where
> > > > CPU and PCI bus addresses *look* the same).
> > > > 
> > > > So a generic code path like of_pci_prop_ranges() that basically copies
> > > > a CPU physical address to a PCI bus address looks broken to me.
> > > 
> > > Hmmm, I'd say that a translation from one bus type to the other is
> > > going on nonetheless, and this is done in the current upstream function
> > > as well. This patch of course does not add the translation (which is
> > > already in place), just to do it avoiding generating inconsistent address.
> > 
> > I think I was looking at this backwards.  I assumed we were *parsing"
> > a "ranges" property, but I think in fact we're *building* a "ranges"
> > property to describe an existing PCI device (either a PCI-to-PCI
> > bridge or an endpoint).  For such devices there is no address
> > translation.
> > 
> > Any address translation would only occur at a PCI host bridge that has
> > CPU address space on the upstream side and PCI address space on the
> > downstream side.
> > 
> > Since (IIUC), we're building "ranges" for a device in the interior of
> > a PCI hierarchy where address translation doesn't happen, I think both
> > the parent and child addresses in "ranges" should be in the PCI
> > address space.
> > 
> > But right now, I think they're both in the CPU address space, and we
> > basically do this:
> > 
> >   of_pci_prop_ranges(struct pci_dev *pdev, ...)
> >     res = &pdev->resource[...];
> >     for (j = 0; j < num; j++) {   # iterate through BARs or windows
> >       val64 = res[j].start;       # CPU physical address
> >       # <convert to PCI address space>
> >       of_pci_set_address(..., rp[i].parent_addr, val64, ...)
> >         rp[i].parent_addr = val64
> >       if (pci_is_bridge(pdev))
> >         memcpy(rp[i].child_addr, rp[i].parent_addr)
> >       else
> >         rp[i].child_addr[0] = j   # child addr unset/unused
> > 
> > Here "res" is a PCI BAR or bridge window, and it contains CPU physical
> > addresses, so "val64" is a CPU physical address.  It looks to me like
> > we should convert to a PCI bus address at the point noted above, based
> > on any translation described by the PCI host bridge.  That *should*
> > naturally result in a 32-bit value if OF_PCI_ADDR_SPACE_MEM64 is not
> > set.
> 
> That's exactly the point, except that right now a 64 bit address would
> "unnaturally" pass through even if OF_PCI_ADDR_SPACE_MEM64 is not set.
> Hence the purpose of this patch.

From your earlier email
(https://lore.kernel.org/r/Zszcps6bnCcdFa54@apocalypse):

> Without this patch the range translation chain is broken, like this:

> pcie@120000: <0x2000000 0x00 0x00    0x1f 0x00                0x00 0xfffffffc>;
> ~~~ chain breaks here ~~~
> pci@0      : <0x82000000 0x1f 0x00   0x82000000 0x1f 0x00     0x00 0x600000>;
> dev@0,0    : <0x01 0x00 0x00         0x82010000 0x1f 0x00     0x00 0x400000>;
> rp1@0      : <0xc0 0x40000000        0x01 0x00 0x00           0x00 0x400000>;

The cover letter said "RP1 is an MFD chipset that acts as a
south-bridge PCIe endpoint .. the RP1 as an endpoint itself is
discoverable via usual PCI enumeration".

I assume pcie@120000 is the PCI host bridge and is already in the
original DT describing the platform.  I assume pci@0 is a Root Port
and dev@0,0 is the RP1 Endpoint, and the existing code already adds
them as they are enumerated when pci_bus_add_device() calls
of_pci_make_dev_node(), and I think this series adds the rp1@0
description.

And the "ranges" properties are built when of_pci_make_dev_node()
eventually calls of_pci_prop_ranges().  With reference to sec 2.2.1.1
of https://www.devicetree.org/open-firmware/bindings/pci/pci2_1.pdf
and
https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#ranges,
I *think* your example says:

pcie@120000 has:
  child phys.hi	      0x02000000    n=0 p=0 t=0 ss=10b
  child phys.mid,lo   0x00000000_00000000
  parent phys.hi,lo   0x0000001f_00000000
  length hi,lo        0x00000000_fffffffc

which would make it a bridge where the child (PCI) address space is
relocatable non-prefetchable 32-bit memory space at
0x00000000-0xfffffffc, and the corresponding parent address space is
0x1f_00000000-0x1f_fffffffc.  That means the host bridge applies an
address translation of "child_addr = parent_addr - 0x1f_00000000".

pci@0 has:
  child phys.hi	      0x82000000    n=1 p=0 t=0 ss=10b
  child phys.mid,lo   0x0000001f_00000000
  parent phys.hi      0x82000000    n=1 p=0 t=0 ss=10b
  parent phys.mid,lo  0x0000001f_00000000
  length hi,lo        0x00000000_00600000

which would make it a PCI-to-PCI bridge (I assume a PCIe Root Port),
where the child (secondary bus) address space is the non-relocatable
non-prefetchable 32-bit memory space 0x1f_00000000-0x1f_005fffff and
the parent (primary bus) address space is also non-relocatable
non-prefetchable 32-bit memory space at 0x1f_00000000-0x1f_005fffff.

This looks wrong to me because the pci@0 parent address space
(0x1f_00000000-0x1f_005fffff) should be inside the pcie@120000 child
address space (0x00000000-0xfffffffc), but it's not.

IIUC, this patch clears the upper 32 bits in the pci@0 parent address
space.  That would make things work correctly in this case because
that happens to be the exact translation of pcie@120000, so it results
in pci@0 parent address space of 0x00000000-0x005fffff.

But I don't think it works in general because there's no requirement
that the host bridge address translation be that simple.  For example,
if we have two host bridges, and we want each to have 2GB of 32-bit
PCI address space starting at 0x0, it might look like this:

  0x00000002_00000000 -> PCI 0x00000000 (subtract 0x00000002_00000000)
  0x00000002_80000000 -> PCI 0x00000000 (subtract 0x00000002_80000000)

In this case simply ignoring the high 32 bits of the CPU address isn't
the correct translation for the second host bridge.  I think we should
look at each host bridge's "ranges", find the difference between its
parent and child addresses, and apply the same difference to
everything below that bridge.

> while with the patch applied the chain correctly become:

> pcie@120000: <0x2000000 0x00 0x00    0x1f 0x00                0x00 0xfffffffc>;
> pci@0      : <0x82000000 0x00 0x00   0x82000000 0x00 0x00     0x00 0x600000>;
> dev@0,0    : <0x01 0x00 0x00         0x82010000 0x00 0x00     0x00 0x400000>;
> rp1@0      : <0xc0 0x40000000        0x01 0x00 0x00           0x00 0x400000>;

> > > > Maybe my expectation of this being described in DT is mistaken.
> > > 
> > > Not sure what you mean here, the address being translated are coming from
> > > DT, in fact they are described by "ranges" properties.
> > 
> > Right, for my own future reference since I couldn't find a generic
> > description of "ranges" in Documentation/devicetree/:
> > 
> > [1] https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#ranges

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

* Re: [PATCH 03/11] PCI: of_property: Sanitize 32 bit PCI address parsed from DT
  2024-09-28 20:17               ` Bjorn Helgaas
@ 2024-10-06 11:20                 ` Andrea della Porta
  2024-10-08  1:08                   ` Bjorn Helgaas
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-10-06 11:20 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren, Lizhi Hou

Hi Bjorn,

On 15:17 Sat 28 Sep     , Bjorn Helgaas wrote:
...
> From your earlier email
> (https://lore.kernel.org/r/Zszcps6bnCcdFa54@apocalypse):
> 
> > Without this patch the range translation chain is broken, like this:
> 
> > pcie@120000: <0x2000000 0x00 0x00    0x1f 0x00                0x00 0xfffffffc>;
> > ~~~ chain breaks here ~~~
> > pci@0      : <0x82000000 0x1f 0x00   0x82000000 0x1f 0x00     0x00 0x600000>;
> > dev@0,0    : <0x01 0x00 0x00         0x82010000 0x1f 0x00     0x00 0x400000>;
> > rp1@0      : <0xc0 0x40000000        0x01 0x00 0x00           0x00 0x400000>;
> 
> The cover letter said "RP1 is an MFD chipset that acts as a
> south-bridge PCIe endpoint .. the RP1 as an endpoint itself is
> discoverable via usual PCI enumeration".
> 
> I assume pcie@120000 is the PCI host bridge and is already in the
> original DT describing the platform.  I assume pci@0 is a Root Port
> and dev@0,0 is the RP1 Endpoint, and the existing code already adds
> them as they are enumerated when pci_bus_add_device() calls
> of_pci_make_dev_node(), and I think this series adds the rp1@0
> description.

Correct.

> 
> And the "ranges" properties are built when of_pci_make_dev_node()
> eventually calls of_pci_prop_ranges().  With reference to sec 2.2.1.1
> of https://www.devicetree.org/open-firmware/bindings/pci/pci2_1.pdf
> and
> https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#ranges,
> I *think* your example says:
> 
> pcie@120000 has:
>   child phys.hi	      0x02000000    n=0 p=0 t=0 ss=10b
>   child phys.mid,lo   0x00000000_00000000
>   parent phys.hi,lo   0x0000001f_00000000
>   length hi,lo        0x00000000_fffffffc
> 
> which would make it a bridge where the child (PCI) address space is
> relocatable non-prefetchable 32-bit memory space at
> 0x00000000-0xfffffffc, and the corresponding parent address space is
> 0x1f_00000000-0x1f_fffffffc.  That means the host bridge applies an
> address translation of "child_addr = parent_addr - 0x1f_00000000".
> 
> pci@0 has:
>   child phys.hi	      0x82000000    n=1 p=0 t=0 ss=10b
>   child phys.mid,lo   0x0000001f_00000000
>   parent phys.hi      0x82000000    n=1 p=0 t=0 ss=10b
>   parent phys.mid,lo  0x0000001f_00000000
>   length hi,lo        0x00000000_00600000
> 
> which would make it a PCI-to-PCI bridge (I assume a PCIe Root Port),
> where the child (secondary bus) address space is the non-relocatable
> non-prefetchable 32-bit memory space 0x1f_00000000-0x1f_005fffff and
> the parent (primary bus) address space is also non-relocatable
> non-prefetchable 32-bit memory space at 0x1f_00000000-0x1f_005fffff.
> 
> This looks wrong to me because the pci@0 parent address space
> (0x1f_00000000-0x1f_005fffff) should be inside the pcie@120000 child
> address space (0x00000000-0xfffffffc), but it's not.

Exactly, that example refers to the 'uncorrected' case, i.e. without the
patch applied.

> 
> IIUC, this patch clears the upper 32 bits in the pci@0 parent address
> space.  That would make things work correctly in this case because
> that happens to be the exact translation of pcie@120000, so it results
> in pci@0 parent address space of 0x00000000-0x005fffff.

Right. I think we sould split it into two issues:

[1] RP1 acknowledges a 32 bit BAR address from its config space while the
device must be accessed using a 64 bit address (that is cpu address
0x1f_00000000), which sounds strange to me but I guess that is how
the hw interconnect has been designed, so we need to cope with it.

[2] I still think that the of_pci_set_address() function should be amended
to avoid generating invalid 64 address when 32 bit flag is set.

As you noted, fixing [2] will incidentally also let [1] work: I think
we can try to solve [1] the proper way and maybe defer [2] for a separate
patch.
To solve [1] I've dropped this patch and tried to solve it from devicetree,
modifying the following mapping:

pcie@120000: <0x3000000 0x1f 0x00    0x1f 0x00                0x00 0xfffffffc>;

so we now have a 1:1 64 bit mapping from 0x1f_00000000 to 0x1f_00000000.
I thought it would result in something like this:

pcie@120000: <0x3000000 0x1f 0x00    0x1f 0x00                0x00 0xfffffffc>;
pci@0      : <0x82000000 0x1f 0x00   0x82000000 0x1f 0x00     0x00 0x600000>;
dev@0,0    : <0x01 0x00 0x00         0x82010000 0x1f 0x00     0x00 0x400000>;
rp1@0      : <0xc0 0x40000000        0x01 0x00 0x00           0x00 0x400000>;

but it fails instead (err: "can't assign; no space") in pci_assign_resource()
function trying to match the size using pci_clip_resource_to_region(). It turned
out that the clipping is done against 32 bit memory region 'pci_32_bit',and
this is failing because the original region addresses to be clipped wxxiereas 64
bit wide. The 'culprit' seems to be the function devm_of_pci_get_host_bridge_resources()
dropping IORESOURCE_MEM_64 on any memory resource, which seems to be a change
somewhat specific to a RK3399 case (see commit 3bd6b8271ee66), but I'm not sure
whether it can be considered generic.

So, I'm actually at an empasse here.

Also, while taking a look at the resulting devicetree, I'm a bit confused by the
fact that the parent address generated by of_pci_prop_ranges() for the pci@0,0
bridge seems to be taken from the parent address of the pcie@120000 node. Shouldn't
it be taken from the child address of pcie@120000, instead?

> 
> But I don't think it works in general because there's no requirement
> that the host bridge address translation be that simple.  For example,
> if we have two host bridges, and we want each to have 2GB of 32-bit
> PCI address space starting at 0x0, it might look like this:
> 
>   0x00000002_00000000 -> PCI 0x00000000 (subtract 0x00000002_00000000)
>   0x00000002_80000000 -> PCI 0x00000000 (subtract 0x00000002_80000000)
> 
> In this case simply ignoring the high 32 bits of the CPU address isn't
> the correct translation for the second host bridge.  I think we should
> look at each host bridge's "ranges", find the difference between its
> parent and child addresses, and apply the same difference to
> everything below that bridge.

Not sure I've got this scenario straight: can you please provide the topology
and the bit setting (32/64 bit) for those ranges? Also, is this scenario coming
from a real use case or is it hypothetical?

Many thanks,
Andrea

...

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

* Re: [PATCH 03/11] PCI: of_property: Sanitize 32 bit PCI address parsed from DT
  2024-10-06 11:20                 ` Andrea della Porta
@ 2024-10-08  1:08                   ` Bjorn Helgaas
  2024-10-18 12:41                     ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Bjorn Helgaas @ 2024-10-08  1:08 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren, Lizhi Hou

On Sun, Oct 06, 2024 at 01:20:51PM +0200, Andrea della Porta wrote:
> On 15:17 Sat 28 Sep, Bjorn Helgaas wrote:
> ...
> > From your earlier email
> > (https://lore.kernel.org/r/Zszcps6bnCcdFa54@apocalypse):
> > 
> > > Without this patch the range translation chain is broken, like this:
> > 
> > > pcie@120000: <0x2000000 0x00 0x00    0x1f 0x00                0x00 0xfffffffc>;
> > > ~~~ chain breaks here ~~~
> > > pci@0      : <0x82000000 0x1f 0x00   0x82000000 0x1f 0x00     0x00 0x600000>;
> > > dev@0,0    : <0x01 0x00 0x00         0x82010000 0x1f 0x00     0x00 0x400000>;
> > > rp1@0      : <0xc0 0x40000000        0x01 0x00 0x00           0x00 0x400000>;
> > 
> > The cover letter said "RP1 is an MFD chipset that acts as a
> > south-bridge PCIe endpoint .. the RP1 as an endpoint itself is
> > discoverable via usual PCI enumeration".
> > 
> > I assume pcie@120000 is the PCI host bridge and is already in the
> > original DT describing the platform.  I assume pci@0 is a Root Port
> > and dev@0,0 is the RP1 Endpoint, and the existing code already adds
> > them as they are enumerated when pci_bus_add_device() calls
> > of_pci_make_dev_node(), and I think this series adds the rp1@0
> > description.
> 
> Correct.
> 
> > And the "ranges" properties are built when of_pci_make_dev_node()
> > eventually calls of_pci_prop_ranges().  With reference to sec 2.2.1.1
> > of https://www.devicetree.org/open-firmware/bindings/pci/pci2_1.pdf
> > and
> > https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#ranges,
> > I *think* your example says:
> > 
> > pcie@120000 has:
> >   child phys.hi       0x02000000    n=0 p=0 t=0 ss=10b
> >   child phys.mid,lo   0x00000000_00000000
> >   parent phys.hi,lo   0x0000001f_00000000
> >   length hi,lo        0x00000000_fffffffc
> > 
> > which would make it a bridge where the child (PCI) address space is
> > relocatable non-prefetchable 32-bit memory space at
> > 0x00000000-0xfffffffc, and the corresponding parent address space is
> > 0x1f_00000000-0x1f_fffffffc.  That means the host bridge applies an
> > address translation of "child_addr = parent_addr - 0x1f_00000000".
> > 
> > pci@0 has:
> >   child phys.hi       0x82000000    n=1 p=0 t=0 ss=10b
> >   child phys.mid,lo   0x0000001f_00000000
> >   parent phys.hi      0x82000000    n=1 p=0 t=0 ss=10b
> >   parent phys.mid,lo  0x0000001f_00000000
> >   length hi,lo        0x00000000_00600000
> > 
> > which would make it a PCI-to-PCI bridge (I assume a PCIe Root Port),
> > where the child (secondary bus) address space is the non-relocatable
> > non-prefetchable 32-bit memory space 0x1f_00000000-0x1f_005fffff and
> > the parent (primary bus) address space is also non-relocatable
> > non-prefetchable 32-bit memory space at 0x1f_00000000-0x1f_005fffff.
> > 
> > This looks wrong to me because the pci@0 parent address space
> > (0x1f_00000000-0x1f_005fffff) should be inside the pcie@120000 child
> > address space (0x00000000-0xfffffffc), but it's not.
> 
> Exactly, that example refers to the 'uncorrected' case, i.e. without the
> patch applied.
> 
> > IIUC, this patch clears the upper 32 bits in the pci@0 parent address
> > space.  That would make things work correctly in this case because
> > that happens to be the exact translation of pcie@120000, so it results
> > in pci@0 parent address space of 0x00000000-0x005fffff.
> 
> Right. I think we should split it into two issues:
> 
> [1] RP1 acknowledges a 32 bit BAR address from its config space while the
> device must be accessed using a 64 bit address (that is cpu address
> 0x1f_00000000), which sounds strange to me but I guess that is how
> the hw interconnect has been designed, so we need to cope with it.

It's common that PCI bus addresses are identical to CPU physical
addresses, but by no means universal.  More details in
Documentation/core-api/dma-api-howto.rst

> [2] I still think that the of_pci_set_address() function should be amended
> to avoid generating invalid 64 address when 32 bit flag is set.
> 
> As you noted, fixing [2] will incidentally also let [1] work: I think
> we can try to solve [1] the proper way and maybe defer [2] for a separate
> patch.
> To solve [1] I've dropped this patch and tried to solve it from devicetree,
> modifying the following mapping:
> 
> pcie@120000: <0x3000000 0x1f 0x00    0x1f 0x00                0x00 0xfffffffc>;
> 
> so we now have a 1:1 64 bit mapping from 0x1f_00000000 to 0x1f_00000000.

That's the wrong thing to change.  pcie@120000 is fine; it's pci@0
that's incorrect.

pcie@120000 is the host bridge, and its "ranges" must describe the
address translation it performs between the primary (CPU) side and the
secondary (PCI) side.  Either this offset is built into the hardware
and can't be changed, or the offset is configured by firmware and the
DT has to match.

So I think this description is correct:

  pcie@120000: <0x2000000 0x0 0x00000000 0x1f 0x00000000 0x0 0xfffffffc>;

which means we have an aperture from CPU physical addresses to PCI bus
addresses like this:

  Host bridge: [mem 0x1f_00000000-0x1f_fffffffb window] (bus address 0x00000000-0xfffffffb)

> I thought it would result in something like this:
> 
> pcie@120000: <0x3000000 0x1f 0x00    0x1f 0x00                0x00 0xfffffffc>;
> pci@0      : <0x82000000 0x1f 0x00   0x82000000 0x1f 0x00     0x00 0x600000>;
> dev@0,0    : <0x01 0x00 0x00         0x82010000 0x1f 0x00     0x00 0x400000>;
> rp1@0      : <0xc0 0x40000000        0x01 0x00 0x00           0x00 0x400000>;
> 
> but it fails instead (err: "can't assign; no space") in pci_assign_resource()
> function trying to match the size using pci_clip_resource_to_region(). It turned
> out that the clipping is done against 32 bit memory region 'pci_32_bit',and
> this is failing because the original region addresses to be clipped wxxiereas 64
> bit wide. The 'culprit' seems to be the function devm_of_pci_get_host_bridge_resources()
> dropping IORESOURCE_MEM_64 on any memory resource, which seems to be a change
> somewhat specific to a RK3399 case (see commit 3bd6b8271ee66), but I'm not sure
> whether it can be considered generic.

I think the problem is that we're building the pci@0 (Root Port)
"ranges" incorrectly.  pci@0 is a PCI-PCI bridge, which cannot do any
address translation, so its parent and child address spaces must both
be inside the pcie@120000 *child* address space.

> Also, while taking a look at the resulting devicetree, I'm a bit confused by the
> fact that the parent address generated by of_pci_prop_ranges() for the pci@0,0
> bridge seems to be taken from the parent address of the pcie@120000 node. Shouldn't
> it be taken from the child address of pcie@120000, instead?

Yes, this is exactly the problem.  The pci@0 parent and child
addresses in "ranges" are both in the PCI address space.  But we
start with pdev->resource[N], which is a CPU address.  To get the PCI
address, we need to apply pci_bus_address().  If the host bridge
windows are set up correctly, the window->offset used in
pcibios_resource_to_bus() should yield the PCI bus address.

I think it should look like this:

  pci@0: <0x82000000 0x0 0x00000000 0x82000000 0x0 0x00000000 0x0 0x600000>;

By default lspci shows you the CPU addresses for BARs, so you should
see something like this:

  00:02.0 PCI bridge
    Memory behind bridge: 1f00000000-1ffffffffb
    Capabilities: [40] Express Root Port

If you run "lspci -b", it will show you PCI bus addresses instead,
which should look like this:

  00:02.0 PCI bridge
    Memory behind bridge: 00000000-fffffffb
    Capabilities: [40] Express Root Port

> > But I don't think it works in general because there's no requirement
> > that the host bridge address translation be that simple.  For example,
> > if we have two host bridges, and we want each to have 2GB of 32-bit
> > PCI address space starting at 0x0, it might look like this:
> > 
> >   0x00000002_00000000 -> PCI 0x00000000 (subtract 0x00000002_00000000)
> >   0x00000002_80000000 -> PCI 0x00000000 (subtract 0x00000002_80000000)
> > 
> > In this case simply ignoring the high 32 bits of the CPU address isn't
> > the correct translation for the second host bridge.  I think we should
> > look at each host bridge's "ranges", find the difference between its
> > parent and child addresses, and apply the same difference to
> > everything below that bridge.
> 
> Not sure I've got this scenario straight: can you please provide the topology
> and the bit setting (32/64 bit) for those ranges? Also, is this scenario coming
> from a real use case or is it hypothetical?

This scenario is purely hypothetical, but it's a legal topology that
we should handle correctly.  It's two host bridges, with independent
PCI hierarchies below them:

  Host bridge A: [mem 0x2_00000000-0x2_7fffffff window] (bus address 0x00000000-0x7fffffff)
  Host bridge B: [mem 0x2_80000000-0x2_ffffffff window] (bus address 0x00000000-0x7fffffff)

Bridge A has an MMIO aperture at CPU addresses
0x2_00000000-0x2_7fffffff, and when it initiates PCI transactions on
its secondary side, the PCI address is CPU_addr - 0x2_00000000.

Similarly, bridge B has an MMIO aperture at CPU addresses 
0x2_80000000-0x2_ffffffff, and when it initiates PCI transactions on 
its secondary side, the PCI address is CPU_addr - 0x2_80000000.

Both hierarchies use PCI bus addresses in the 0x00000000-0x7fffffff
range.  In a topology like this, you can't convert a bus address back
to a CPU address unless you know which hierarchy it's in.
pcibios_bus_to_resource() takes a pci_bus pointer, which tells you
which hierarchy (and which host bridge address translation) to use.

Bjorn

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

* Re: [PATCH 03/11] PCI: of_property: Sanitize 32 bit PCI address parsed from DT
  2024-10-08  1:08                   ` Bjorn Helgaas
@ 2024-10-18 12:41                     ` Andrea della Porta
  2024-10-18 22:28                       ` Bjorn Helgaas
  0 siblings, 1 reply; 117+ messages in thread
From: Andrea della Porta @ 2024-10-18 12:41 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren, Lizhi Hou

Hi Bjorn,

On 20:08 Mon 07 Oct     , Bjorn Helgaas wrote:
... 
> It's common that PCI bus addresses are identical to CPU physical
> addresses, but by no means universal.  More details in
> Documentation/core-api/dma-api-howto.rst
> 
> > [2] I still think that the of_pci_set_address() function should be amended
> > to avoid generating invalid 64 address when 32 bit flag is set.
> > 
> > As you noted, fixing [2] will incidentally also let [1] work: I think
> > we can try to solve [1] the proper way and maybe defer [2] for a separate
> > patch.
> > To solve [1] I've dropped this patch and tried to solve it from devicetree,
> > modifying the following mapping:
> > 
> > pcie@120000: <0x3000000 0x1f 0x00    0x1f 0x00                0x00 0xfffffffc>;
> > 
> > so we now have a 1:1 64 bit mapping from 0x1f_00000000 to 0x1f_00000000.
> 
> That's the wrong thing to change.  pcie@120000 is fine; it's pci@0
> that's incorrect.
> 
> pcie@120000 is the host bridge, and its "ranges" must describe the
> address translation it performs between the primary (CPU) side and the
> secondary (PCI) side.  Either this offset is built into the hardware
> and can't be changed, or the offset is configured by firmware and the
> DT has to match.
> 
> So I think this description is correct:
> 
>   pcie@120000: <0x2000000 0x0 0x00000000 0x1f 0x00000000 0x0 0xfffffffc>;
> 
> which means we have an aperture from CPU physical addresses to PCI bus
> addresses like this:
> 
>   Host bridge: [mem 0x1f_00000000-0x1f_fffffffb window] (bus address 0x00000000-0xfffffffb)
> 
> > I thought it would result in something like this:
> > 
> > pcie@120000: <0x3000000 0x1f 0x00    0x1f 0x00                0x00 0xfffffffc>;
> > pci@0      : <0x82000000 0x1f 0x00   0x82000000 0x1f 0x00     0x00 0x600000>;
> > dev@0,0    : <0x01 0x00 0x00         0x82010000 0x1f 0x00     0x00 0x400000>;
> > rp1@0      : <0xc0 0x40000000        0x01 0x00 0x00           0x00 0x400000>;
> > 
> > but it fails instead (err: "can't assign; no space") in pci_assign_resource()
> > function trying to match the size using pci_clip_resource_to_region(). It turned
> > out that the clipping is done against 32 bit memory region 'pci_32_bit',and
> > this is failing because the original region addresses to be clipped wxxiereas 64
> > bit wide. The 'culprit' seems to be the function devm_of_pci_get_host_bridge_resources()
> > dropping IORESOURCE_MEM_64 on any memory resource, which seems to be a change
> > somewhat specific to a RK3399 case (see commit 3bd6b8271ee66), but I'm not sure
> > whether it can be considered generic.
> 
> I think the problem is that we're building the pci@0 (Root Port)
> "ranges" incorrectly.  pci@0 is a PCI-PCI bridge, which cannot do any
> address translation, so its parent and child address spaces must both
> be inside the pcie@120000 *child* address space.
> 
> > Also, while taking a look at the resulting devicetree, I'm a bit confused by the
> > fact that the parent address generated by of_pci_prop_ranges() for the pci@0,0
> > bridge seems to be taken from the parent address of the pcie@120000 node. Shouldn't
> > it be taken from the child address of pcie@120000, instead?
> 
> Yes, this is exactly the problem.  The pci@0 parent and child
> addresses in "ranges" are both in the PCI address space.  But we
> start with pdev->resource[N], which is a CPU address.  To get the PCI
> address, we need to apply pci_bus_address().  If the host bridge
> windows are set up correctly, the window->offset used in
> pcibios_resource_to_bus() should yield the PCI bus address.

You mean something like this, I think:

@@ -129,7 +129,7 @@ static int of_pci_prop_ranges(struct pci_dev *pdev, struct of_changeset *ocs,
                if (of_pci_get_addr_flags(&res[j], &flags))
                        continue;
 
-               val64 = res[j].start;
+               val64 = pci_bus_address(pdev, &res[j] - pdev->resource);
                of_pci_set_address(pdev, rp[i].parent_addr, val64, 0, flags,
                                   false);
                if (pci_is_bridge(pdev)) {

> 
> I think it should look like this:
> 
>   pci@0: <0x82000000 0x0 0x00000000 0x82000000 0x0 0x00000000 0x0 0x600000>;

indeed, with the above patch applied, the result is exactly as you expected.

> 
> By default lspci shows you the CPU addresses for BARs, so you should
> see something like this:
> 
>   00:02.0 PCI bridge
>     Memory behind bridge: 1f00000000-1ffffffffb
>     Capabilities: [40] Express Root Port
> 
> If you run "lspci -b", it will show you PCI bus addresses instead,
> which should look like this:
> 
>   00:02.0 PCI bridge
>     Memory behind bridge: 00000000-fffffffb
>     Capabilities: [40] Express Root Port
> 
> > > But I don't think it works in general because there's no requirement
> > > that the host bridge address translation be that simple.  For example,
> > > if we have two host bridges, and we want each to have 2GB of 32-bit
> > > PCI address space starting at 0x0, it might look like this:
> > > 
> > >   0x00000002_00000000 -> PCI 0x00000000 (subtract 0x00000002_00000000)
> > >   0x00000002_80000000 -> PCI 0x00000000 (subtract 0x00000002_80000000)
> > > 
> > > In this case simply ignoring the high 32 bits of the CPU address isn't
> > > the correct translation for the second host bridge.  I think we should
> > > look at each host bridge's "ranges", find the difference between its
> > > parent and child addresses, and apply the same difference to
> > > everything below that bridge.
> > 
> > Not sure I've got this scenario straight: can you please provide the topology
> > and the bit setting (32/64 bit) for those ranges? Also, is this scenario coming
> > from a real use case or is it hypothetical?
> 
> This scenario is purely hypothetical, but it's a legal topology that
> we should handle correctly.  It's two host bridges, with independent
> PCI hierarchies below them:
> 
>   Host bridge A: [mem 0x2_00000000-0x2_7fffffff window] (bus address 0x00000000-0x7fffffff)
>   Host bridge B: [mem 0x2_80000000-0x2_ffffffff window] (bus address 0x00000000-0x7fffffff)
> 
> Bridge A has an MMIO aperture at CPU addresses
> 0x2_00000000-0x2_7fffffff, and when it initiates PCI transactions on
> its secondary side, the PCI address is CPU_addr - 0x2_00000000.
> 
> Similarly, bridge B has an MMIO aperture at CPU addresses 
> 0x2_80000000-0x2_ffffffff, and when it initiates PCI transactions on 
> its secondary side, the PCI address is CPU_addr - 0x2_80000000.
> 
> Both hierarchies use PCI bus addresses in the 0x00000000-0x7fffffff
> range.  In a topology like this, you can't convert a bus address back
> to a CPU address unless you know which hierarchy it's in.
> pcibios_bus_to_resource() takes a pci_bus pointer, which tells you
> which hierarchy (and which host bridge address translation) to use.

Agreed. While I think about how to adjust that specific patch,i let's drop it from
this patchset since the aforementioned change is properly fixing the translation
issue.

> 
> Bjora

Many thanks,
Andrea

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

* Re: [PATCH 03/11] PCI: of_property: Sanitize 32 bit PCI address parsed from DT
  2024-10-18 12:41                     ` Andrea della Porta
@ 2024-10-18 22:28                       ` Bjorn Helgaas
  2024-10-19  8:46                         ` Andrea della Porta
  0 siblings, 1 reply; 117+ messages in thread
From: Bjorn Helgaas @ 2024-10-18 22:28 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren, Lizhi Hou

On Fri, Oct 18, 2024 at 02:41:11PM +0200, Andrea della Porta wrote:
> On 20:08 Mon 07 Oct     , Bjorn Helgaas wrote:
> ... 

> > Yes, this is exactly the problem.  The pci@0 parent and child
> > addresses in "ranges" are both in the PCI address space.  But we
> > start with pdev->resource[N], which is a CPU address.  To get the PCI
> > address, we need to apply pci_bus_address().  If the host bridge
> > windows are set up correctly, the window->offset used in
> > pcibios_resource_to_bus() should yield the PCI bus address.
> 
> You mean something like this, I think:
> 
> @@ -129,7 +129,7 @@ static int of_pci_prop_ranges(struct pci_dev *pdev, struct of_changeset *ocs,
>                 if (of_pci_get_addr_flags(&res[j], &flags))
>                         continue;
>  
> -               val64 = res[j].start;
> +               val64 = pci_bus_address(pdev, &res[j] - pdev->resource);
>                 of_pci_set_address(pdev, rp[i].parent_addr, val64, 0, flags,
>                                    false);
>                 if (pci_is_bridge(pdev)) {

Yes.

> > I think it should look like this:
> > 
> >   pci@0: <0x82000000 0x0 0x00000000 0x82000000 0x0 0x00000000 0x0 0x600000>;
> 
> indeed, with the above patch applied, the result is exactly as you expected.
> ...

> > > > But I don't think it works in general because there's no
> > > > requirement that the host bridge address translation be that
> > > > simple.  For example, if we have two host bridges, and we want
> > > > each to have 2GB of 32-bit PCI address space starting at 0x0,
> > > > it might look like this:
> > > > 
> > > >   0x00000002_00000000 -> PCI 0x00000000 (subtract 0x00000002_00000000)
> > > >   0x00000002_80000000 -> PCI 0x00000000 (subtract 0x00000002_80000000)
> > > > 
> > > > In this case simply ignoring the high 32 bits of the CPU
> > > > address isn't the correct translation for the second host
> > > > bridge.  I think we should look at each host bridge's
> > > > "ranges", find the difference between its parent and child
> > > > addresses, and apply the same difference to everything below
> > > > that bridge.
> > > 
> > > Not sure I've got this scenario straight: can you please provide
> > > the topology and the bit setting (32/64 bit) for those ranges?
> > > Also, is this scenario coming from a real use case or is it
> > > hypothetical?
> > 
> > This scenario is purely hypothetical, but it's a legal topology
> > that we should handle correctly.  It's two host bridges, with
> > independent PCI hierarchies below them:
> > 
> >   Host bridge A: [mem 0x2_00000000-0x2_7fffffff window] (bus address 0x00000000-0x7fffffff)
> >   Host bridge B: [mem 0x2_80000000-0x2_ffffffff window] (bus address 0x00000000-0x7fffffff)
> > 
> > Bridge A has an MMIO aperture at CPU addresses
> > 0x2_00000000-0x2_7fffffff, and when it initiates PCI transactions on
> > its secondary side, the PCI address is CPU_addr - 0x2_00000000.
> > 
> > Similarly, bridge B has an MMIO aperture at CPU addresses 
> > 0x2_80000000-0x2_ffffffff, and when it initiates PCI transactions on 
> > its secondary side, the PCI address is CPU_addr - 0x2_80000000.
> > 
> > Both hierarchies use PCI bus addresses in the 0x00000000-0x7fffffff
> > range.  In a topology like this, you can't convert a bus address back
> > to a CPU address unless you know which hierarchy it's in.
> > pcibios_bus_to_resource() takes a pci_bus pointer, which tells you
> > which hierarchy (and which host bridge address translation) to use.
> 
> Agreed. While I think about how to adjust that specific patch,i
> let's drop it from this patchset since the aforementioned change is
> properly fixing the translation issue.

OK.  I assume you mean to drop the "PCI: of_property: Sanitize 32 bit
PCI address parsed from DT" patch?  Or replace it with the
pci_bus_address() addition above?

Bjorn

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

* Re: [PATCH 03/11] PCI: of_property: Sanitize 32 bit PCI address parsed from DT
  2024-10-18 22:28                       ` Bjorn Helgaas
@ 2024-10-19  8:46                         ` Andrea della Porta
  0 siblings, 0 replies; 117+ messages in thread
From: Andrea della Porta @ 2024-10-19  8:46 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Andrea della Porta, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Broadcom internal kernel review list, Linus Walleij,
	Catalin Marinas, Will Deacon, Derek Kiernan, Dragan Cvetic,
	Arnd Bergmann, Greg Kroah-Hartman, Nicolas Ferre, Claudiu Beznea,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Saravana Kannan, Bjorn Helgaas, linux-clk, devicetree,
	linux-rpi-kernel, linux-arm-kernel, linux-kernel, linux-gpio,
	netdev, linux-pci, linux-arch, Lee Jones, Andrew Lunn,
	Stefan Wahren, Lizhi Hou

Hi Bjorn,

On 17:28 Fri 18 Oct     , Bjorn Helgaas wrote:
> On Fri, Oct 18, 2024 at 02:41:11PM +0200, Andrea della Porta wrote:
> > On 20:08 Mon 07 Oct     , Bjorn Helgaas wrote:
> > ... 
> 
> > > Yes, this is exactly the problem.  The pci@0 parent and child
> > > addresses in "ranges" are both in the PCI address space.  But we
> > > start with pdev->resource[N], which is a CPU address.  To get the PCI
> > > address, we need to apply pci_bus_address().  If the host bridge
> > > windows are set up correctly, the window->offset used in
> > > pcibios_resource_to_bus() should yield the PCI bus address.
> > 
> > You mean something like this, I think:
> > 
> > @@ -129,7 +129,7 @@ static int of_pci_prop_ranges(struct pci_dev *pdev, struct of_changeset *ocs,
> >                 if (of_pci_get_addr_flags(&res[j], &flags))
> >                         continue;
> >  
> > -               val64 = res[j].start;
> > +               val64 = pci_bus_address(pdev, &res[j] - pdev->resource);
> >                 of_pci_set_address(pdev, rp[i].parent_addr, val64, 0, flags,
> >                                    false);
> >                 if (pci_is_bridge(pdev)) {
> 
> Yes.
> 
> > > I think it should look like this:
> > > 
> > >   pci@0: <0x82000000 0x0 0x00000000 0x82000000 0x0 0x00000000 0x0 0x600000>;
> > 
> > indeed, with the above patch applied, the result is exactly as you expected.
> > ...
> 
> > > > > But I don't think it works in general because there's no
> > > > > requirement that the host bridge address translation be that
> > > > > simple.  For example, if we have two host bridges, and we want
> > > > > each to have 2GB of 32-bit PCI address space starting at 0x0,
> > > > > it might look like this:
> > > > > 
> > > > >   0x00000002_00000000 -> PCI 0x00000000 (subtract 0x00000002_00000000)
> > > > >   0x00000002_80000000 -> PCI 0x00000000 (subtract 0x00000002_80000000)
> > > > > 
> > > > > In this case simply ignoring the high 32 bits of the CPU
> > > > > address isn't the correct translation for the second host
> > > > > bridge.  I think we should look at each host bridge's
> > > > > "ranges", find the difference between its parent and child
> > > > > addresses, and apply the same difference to everything below
> > > > > that bridge.
> > > > 
> > > > Not sure I've got this scenario straight: can you please provide
> > > > the topology and the bit setting (32/64 bit) for those ranges?
> > > > Also, is this scenario coming from a real use case or is it
> > > > hypothetical?
> > > 
> > > This scenario is purely hypothetical, but it's a legal topology
> > > that we should handle correctly.  It's two host bridges, with
> > > independent PCI hierarchies below them:
> > > 
> > >   Host bridge A: [mem 0x2_00000000-0x2_7fffffff window] (bus address 0x00000000-0x7fffffff)
> > >   Host bridge B: [mem 0x2_80000000-0x2_ffffffff window] (bus address 0x00000000-0x7fffffff)
> > > 
> > > Bridge A has an MMIO aperture at CPU addresses
> > > 0x2_00000000-0x2_7fffffff, and when it initiates PCI transactions on
> > > its secondary side, the PCI address is CPU_addr - 0x2_00000000.
> > > 
> > > Similarly, bridge B has an MMIO aperture at CPU addresses 
> > > 0x2_80000000-0x2_ffffffff, and when it initiates PCI transactions on 
> > > its secondary side, the PCI address is CPU_addr - 0x2_80000000.
> > > 
> > > Both hierarchies use PCI bus addresses in the 0x00000000-0x7fffffff
> > > range.  In a topology like this, you can't convert a bus address back
> > > to a CPU address unless you know which hierarchy it's in.
> > > pcibios_bus_to_resource() takes a pci_bus pointer, which tells you
> > > which hierarchy (and which host bridge address translation) to use.
> > 
> > Agreed. While I think about how to adjust that specific patch,i
> > let's drop it from this patchset since the aforementioned change is
> > properly fixing the translation issue.
> 
> OK.  I assume you mean to drop the "PCI: of_property: Sanitize 32 bit
> PCI address parsed from DT" patch?  Or replace it with the
> pci_bus_address() addition above?

I'm planning to replace that patch with the above mentioned pci_bus_address()
addition. However, I think the 32 bit sanitization is still useful to prevent
wrongly encoded address to linger around, but I defer it to a subsequent standalone
patch, after figuring out the dual bridge scenario that you proposed.

> 
> Bjorn

Many thanks,
Andrea

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

end of thread, other threads:[~2024-10-19  8:46 UTC | newest]

Thread overview: 117+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-20 14:36 [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay Andrea della Porta
2024-08-20 14:36 ` [PATCH 01/11] dt-bindings: clock: Add RaspberryPi RP1 clock bindings Andrea della Porta
2024-08-20 16:19   ` Conor Dooley
2024-08-20 18:25     ` Andrea della Porta
2024-08-21 11:46       ` Conor Dooley
2024-08-22  9:35         ` Andrea della Porta
2024-08-22  9:52           ` Krzysztof Kozlowski
2024-08-22 16:23             ` Conor Dooley
2024-08-23 18:21               ` Andrea della Porta
2024-08-20 14:36 ` [PATCH 02/11] dt-bindings: pinctrl: Add RaspberryPi RP1 gpio/pinctrl/pinmux bindings Andrea della Porta
2024-08-21  8:42   ` Krzysztof Kozlowski
2024-08-30 10:22     ` Andrea della Porta
2024-08-30 11:46       ` Krzysztof Kozlowski
2024-09-02  8:44         ` Andrea della Porta
2024-08-20 14:36 ` [PATCH 03/11] PCI: of_property: Sanitize 32 bit PCI address parsed from DT Andrea della Porta
2024-08-21 15:24   ` Bjorn Helgaas
2024-08-26 19:51     ` Andrea della Porta
2024-09-03 22:26       ` Bjorn Helgaas
2024-09-05 16:43         ` Andrea della Porta
2024-09-05 20:16           ` Bjorn Helgaas
2024-09-27  6:48             ` Andrea della Porta
2024-09-28 20:17               ` Bjorn Helgaas
2024-10-06 11:20                 ` Andrea della Porta
2024-10-08  1:08                   ` Bjorn Helgaas
2024-10-18 12:41                     ` Andrea della Porta
2024-10-18 22:28                       ` Bjorn Helgaas
2024-10-19  8:46                         ` Andrea della Porta
2024-08-20 14:36 ` [PATCH 04/11] of: address: Preserve the flags portion on 1:1 dma-ranges mapping Andrea della Porta
2024-08-21  0:16   ` Rob Herring
2024-08-21  8:18     ` Andrea della Porta
2024-08-26 21:29       ` Rob Herring
2024-08-29 10:13         ` Andrea della Porta
2024-08-29 13:18           ` Rob Herring
2024-08-29 16:26             ` Andrea della Porta
2024-08-30 19:37               ` Rob Herring
2024-09-03  9:09                 ` Herve Codina
2024-09-03  9:33                   ` Andrea della Porta
2024-09-03 18:55                     ` Rob Herring
2024-09-03 16:15                 ` Andrea della Porta
2024-09-03 18:46                   ` Rob Herring
2024-09-04  8:33                     ` Andrea della Porta
2024-08-20 14:36 ` [PATCH 05/11] vmlinux.lds.h: Preserve DTB sections from being discarded after init Andrea della Porta
2024-08-30 19:46   ` Stephen Boyd
2024-09-03 12:29     ` Andrea della Porta
2024-09-21 20:47       ` Stephen Boyd
2024-09-22  8:14         ` Masahiro Yamada
2024-09-23 18:13           ` Stephen Boyd
2024-09-24  2:45             ` Masahiro Yamada
2024-08-20 14:36 ` [PATCH 06/11] clk: rp1: Add support for clocks provided by RP1 Andrea della Porta
2024-08-21 13:17   ` Simon Horman
2024-08-22 10:04     ` Andrea della Porta
2024-08-20 14:36 ` [PATCH 07/11] pinctrl: rp1: Implement RaspberryPi RP1 gpio support Andrea della Porta
2024-08-21  8:45   ` Krzysztof Kozlowski
2024-08-30 10:39     ` Andrea della Porta
2024-08-21  9:22   ` kernel test robot
2024-08-21 12:06   ` kernel test robot
2024-08-21 13:27   ` Simon Horman
2024-08-23 17:16     ` Andrea della Porta
2024-08-21 20:51   ` kernel test robot
2024-08-26  8:59   ` Linus Walleij
2024-08-28 15:24     ` Andrea della Porta
2024-09-02  8:31       ` Linus Walleij
2024-08-20 14:36 ` [PATCH 08/11] misc: rp1: RaspberryPi RP1 misc driver Andrea della Porta
2024-08-21  8:38   ` Krzysztof Kozlowski
2024-08-21 14:20     ` Krzysztof Kozlowski
2024-08-22 14:33       ` Andrea della Porta
2024-08-22 14:46         ` Krzysztof Kozlowski
2024-08-30 13:49     ` Andrea della Porta
2024-08-30 14:21       ` Andrew Lunn
2024-09-03 14:56         ` Andrea della Porta
2024-08-30 16:52       ` Krzysztof Kozlowski
2024-09-03 15:15         ` Andrea della Porta
2024-09-03 18:27           ` Krzysztof Kozlowski
2024-09-05 16:33             ` Andrea della Porta
2024-09-05 16:52               ` Krzysztof Kozlowski
2024-09-05 18:54                 ` Andrea della Porta
2024-09-05 21:20                   ` Krzysztof Kozlowski
2024-08-21 13:07   ` kernel test robot
2024-08-21 13:49   ` kernel test robot
2024-08-21 16:20   ` Stefan Wahren
2024-08-23  9:44     ` Andrea della Porta
2024-08-23 10:23       ` Stefan Wahren
2024-08-23 16:31         ` Andrea della Porta
2024-08-30 18:27           ` Rob Herring
2024-09-02  9:34             ` Andrea della Porta
2024-08-21 16:55   ` Bjorn Helgaas
2024-08-23 10:21     ` Andrea della Porta
2024-08-21 17:56   ` kernel test robot
2024-08-24  1:53   ` Greg Kroah-Hartman
2024-08-26  9:07     ` Andrea della Porta
2024-08-26  9:18       ` Greg Kroah-Hartman
2024-08-20 14:36 ` [PATCH 09/11] arm64: defconfig: Enable RP1 misc/clock/gpio drivers as built-in Andrea della Porta
2024-08-21  8:47   ` Krzysztof Kozlowski
2024-08-30 22:24     ` Andrea della Porta
2024-08-20 14:36 ` [PATCH 10/11] net: macb: Add support for RP1's MACB variant Andrea della Porta
2024-08-20 15:13   ` Andrew Lunn
2024-08-20 18:31     ` Andrea della Porta
2024-08-21  8:49   ` Krzysztof Kozlowski
2024-08-30 22:32     ` Andrea della Porta
2024-08-21 17:01   ` Florian Fainelli
2024-08-26 20:03     ` Andrea della Porta
2024-08-20 14:36 ` [PATCH 11/11] arm64: dts: rp1: Add support for MACB contained in RP1 Andrea della Porta
2024-08-21  8:43   ` Krzysztof Kozlowski
2024-08-30 22:33     ` Andrea della Porta
2024-08-21 17:02   ` Florian Fainelli
2024-08-26 20:18     ` Andrea della Porta
2024-08-21 13:42 ` [PATCH 00/11] Add support for RaspberryPi RP1 PCI device using a DT overlay Krzysztof Kozlowski
2024-08-22  9:05   ` Andrea della Porta
2024-08-22  9:50     ` Krzysztof Kozlowski
2024-08-29 13:11       ` Andrea della Porta
2024-08-22 13:04     ` Andrew Lunn
2024-08-29 12:01       ` Andrea della Porta
2024-08-29 13:04         ` Andrew Lunn
2024-08-29 13:13           ` Andrea della Porta
2024-08-30  5:21           ` Andrea della Porta
2024-08-30 14:10             ` Andrew Lunn
2024-09-02  9:21               ` Andrea della Porta

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 read-only IMAP folder(s) and NNTP newsgroup(s).