linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/18] Apple M1 SoC platform bring-up
@ 2021-02-04 20:39 Hector Martin
  2021-02-04 20:39 ` [PATCH 01/18] dt-bindings: vendor-prefixes: add AAPL prefix Hector Martin
                   ` (18 more replies)
  0 siblings, 19 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-04 20:39 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

This series brings up initial support for the Apple M1 SoC, used in the
2020 Mac Mini, MacBook Pro, and MacBook Air models.

The following features are supported in this initial port:

- UART (samsung-style) with earlycon support
- Interrupts, including affinity and IPIs (Apple Interrupt Controller)
- SMP (through standard spin-table support)
- simplefb-based framebuffer
- Devicetree for the Mac Mini (should work for the others too at this
  stage)

The primary pain points of this port are:

- Apple SoCs require FIQs, as the timers and "fast" IPIs are hardwired
  to the FIQ interrupt line. This patchset introduces FIQ support through
  the alternatives mechanism, so as to not affect other platforms,
  implemented as simply merging IRQs and FIQs. The AIC driver takes care
  of discriminating and routing IRQs to the right users.

- These SoCs blackhole nGnRE writes to internal MMIO ranges, and require
  nGnRnE. There is no obvious right solution to solve this. I do not
  expect the two patches for that in this series to be merged as-is, but
  the commit messages describe the problem and potential solutions. I
  hope we can have a discussion and converge on the right approach to
  solve this problem in the sanest way.

These machines officially support booting unsigned/user-provided
XNU-like kernels, with a very different boot protocol and devicetree
format. We are developing an initial bootloader, m1n1 [1], to take care
of as many hardware peculiarities as possible and present a standard
Linux arm64 boot protocol and device tree. In the future, I expect that
production setups will add U-Boot and perhaps GRUB into the boot chain,
to make the boot process similar to other ARM64 platforms.

The machines expose their debug UART over USB Type C, triggered with
vendor-specific USB-PD commands. Currently, the easiest way to get a
serial console on these machines is to use a second M1 box and a simple
USB C cable [2]. You can also build a DIY interface using an Arduino, a
FUSB302 chip or board, and a 1.2V UART-TTL adapter [3]. In the coming
weeks we will be designing an open hardware project to provide
serial/debug connectivity to these machines (and, hopefully, also
support other UART-over-Type C setups from other vendors). Please
contact me privately if you are interested in getting an early prototype
version of one of these devices.

A quickstart guide to booting Linux kernels on these machines is
available at [4], and we are documenting the hardware at [5].

[1] https://github.com/AsahiLinux/m1n1/
[2] https://github.com/AsahiLinux/macvdmtool/
[3] https://github.com/AsahiLinux/vdmtool/
[4] https://github.com/AsahiLinux/docs/wiki/Developer-Quickstart
[5] https://github.com/AsahiLinux/docs/wiki

== Project Blurb ==

Asahi Linux is an open community project dedicated to developing and
maintaining mainline support for Apple Silicon on Linux. Feel free to
drop by #asahi on freenode to chat with us, or check our website for
more information on the project:

https://asahilinux.org/


Hector Martin (18):
  dt-bindings: vendor-prefixes: add AAPL prefix
  dt-bindings: arm: cpus: Add AAPL,firestorm & icestorm compatibles
  dt-bindings: arm: AAPL: Add bindings for Apple ARM platforms
  arm64: Kconfig: Introduce CONFIG_ARCH_APPLE
  tty: serial: samsung_tty: add support for Apple UARTs
  dt-bindings: serial: samsung: Add AAPL,s5l-uart compatible
  tty: serial: samsung_tty: enable for ARCH_APPLE
  arm64: cpufeature: Add a feature for FIQ support
  arm64: cputype: Add CPU types for the Apple M1 big/little cores
  arm64: Introduce FIQ support
  arm64: Kconfig: Require FIQ support for ARCH_APPLE
  arm64: setup: Use nGnRnE IO mappings for fixmap on Apple platforms
  arm64: ioremap: use nGnRnE mappings on platforms that require it
  dt-bindings: interrupt-controller: Add DT bindings for apple-aic
  irqchip/apple-aic: Add support for the Apple Interrupt Controller
  irqchip/apple-aic: Add SMP / IPI support
  dt-bindings: display: add AAPL,simple-framebuffer
  arm64: apple: Add initial Mac Mini 2020 (M1) devicetree

 .../devicetree/bindings/arm/AAPL.yaml         |  36 ++
 .../devicetree/bindings/arm/cpus.yaml         |   2 +
 .../bindings/display/simple-framebuffer.yaml  |   5 +
 .../interrupt-controller/AAPL,aic.yaml        |  88 +++
 .../bindings/serial/samsung_uart.yaml         |   4 +-
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 MAINTAINERS                                   |  14 +
 arch/arm64/Kconfig                            |  10 +
 arch/arm64/Kconfig.platforms                  |   8 +
 arch/arm64/boot/dts/Makefile                  |   1 +
 arch/arm64/boot/dts/apple/Makefile            |   2 +
 arch/arm64/boot/dts/apple/apple-j274.dts      | 143 +++++
 arch/arm64/include/asm/assembler.h            |   4 +
 arch/arm64/include/asm/cpucaps.h              |   3 +-
 arch/arm64/include/asm/cpufeature.h           |   6 +
 arch/arm64/include/asm/cputype.h              |   6 +
 arch/arm64/include/asm/daifflags.h            |   7 +
 arch/arm64/include/asm/fixmap.h               |  10 +-
 arch/arm64/include/asm/io.h                   |   9 +-
 arch/arm64/include/asm/irqflags.h             |  17 +-
 arch/arm64/kernel/cpufeature.c                |  32 ++
 arch/arm64/kernel/entry.S                     |  27 +-
 arch/arm64/kernel/setup.c                     |  12 +
 drivers/irqchip/Kconfig                       |  10 +
 drivers/irqchip/Makefile                      |   1 +
 drivers/irqchip/irq-apple-aic.c               | 501 ++++++++++++++++++
 drivers/tty/serial/Kconfig                    |   2 +-
 drivers/tty/serial/samsung_tty.c              | 297 +++++++++--
 .../interrupt-controller/apple-aic.h          |  14 +
 include/linux/serial_s3c.h                    |  16 +
 include/uapi/linux/serial_core.h              |   3 +
 31 files changed, 1243 insertions(+), 49 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/AAPL.yaml
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/AAPL,aic.yaml
 create mode 100644 arch/arm64/boot/dts/apple/Makefile
 create mode 100644 arch/arm64/boot/dts/apple/apple-j274.dts
 create mode 100644 drivers/irqchip/irq-apple-aic.c
 create mode 100644 include/dt-bindings/interrupt-controller/apple-aic.h

--
2.30.0


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

* [PATCH 01/18] dt-bindings: vendor-prefixes: add AAPL prefix
  2021-02-04 20:39 [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin
@ 2021-02-04 20:39 ` Hector Martin
  2021-02-08 10:27   ` Krzysztof Kozlowski
  2021-02-04 20:39 ` [PATCH 02/18] dt-bindings: arm: cpus: Add AAPL,firestorm & icestorm compatibles Hector Martin
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 82+ messages in thread
From: Hector Martin @ 2021-02-04 20:39 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

Amusingly, this wasn't yet documented, even though this vendor prefix
has been used since time immemorial on PPC.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 041ae90b0d8f..d7950c723472 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -25,6 +25,8 @@ patternProperties:
   # Keep list in alphabetical order.
   "^70mai,.*":
     description: 70mai Co., Ltd.
+  "^AAPL,.*":
+    description: Apple Inc.
   "^abb,.*":
     description: ABB
   "^abilis,.*":
-- 
2.30.0


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

* [PATCH 02/18] dt-bindings: arm: cpus: Add AAPL,firestorm & icestorm compatibles
  2021-02-04 20:39 [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin
  2021-02-04 20:39 ` [PATCH 01/18] dt-bindings: vendor-prefixes: add AAPL prefix Hector Martin
@ 2021-02-04 20:39 ` Hector Martin
  2021-02-04 20:39 ` [PATCH 03/18] dt-bindings: arm: AAPL: Add bindings for Apple ARM platforms Hector Martin
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-04 20:39 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

These are the CPU cores in the "Apple Silicon" M1 SoC.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 Documentation/devicetree/bindings/arm/cpus.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml b/Documentation/devicetree/bindings/arm/cpus.yaml
index f02fd10de604..52cb69fd78c5 100644
--- a/Documentation/devicetree/bindings/arm/cpus.yaml
+++ b/Documentation/devicetree/bindings/arm/cpus.yaml
@@ -85,6 +85,8 @@ properties:
 
   compatible:
     enum:
+      - AAPL,icestorm
+      - AAPL,firestorm
       - arm,arm710t
       - arm,arm720t
       - arm,arm740t
-- 
2.30.0


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

* [PATCH 03/18] dt-bindings: arm: AAPL: Add bindings for Apple ARM platforms
  2021-02-04 20:39 [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin
  2021-02-04 20:39 ` [PATCH 01/18] dt-bindings: vendor-prefixes: add AAPL prefix Hector Martin
  2021-02-04 20:39 ` [PATCH 02/18] dt-bindings: arm: cpus: Add AAPL,firestorm & icestorm compatibles Hector Martin
@ 2021-02-04 20:39 ` Hector Martin
  2021-02-04 20:39 ` [PATCH 04/18] arm64: Kconfig: Introduce CONFIG_ARCH_APPLE Hector Martin
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-04 20:39 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

This introduces bindings for all three 2020 Apple M1 devices:

* AAPL,j274 - Mac mini (M1, 2020)
* AAPL,j293 - MacBook Pro (13-inch, M1, 2020)
* AAPL,j313 - MacBook Air (M1, 2020)

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 .../devicetree/bindings/arm/AAPL.yaml         | 36 +++++++++++++++++++
 MAINTAINERS                                   | 10 ++++++
 2 files changed, 46 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/AAPL.yaml

diff --git a/Documentation/devicetree/bindings/arm/AAPL.yaml b/Documentation/devicetree/bindings/arm/AAPL.yaml
new file mode 100644
index 000000000000..145b184e4a24
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/AAPL.yaml
@@ -0,0 +1,36 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/AAPL.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple ARM Machine Device Tree Bindings
+
+maintainers:
+  - Hector Martin <marcan@marcan.st>
+
+description: |
+  Apple ARM ("Apple Silicon") platforms should contain compatible strings
+  in the following format:
+
+  - AAPL,j274 (board/device ID)
+  - AAPL,m1 (SoC name)
+  - AAPL,arm-platform (used for all Apple ARM devices)
+
+properties:
+  $nodename:
+    const: "/"
+  compatible:
+    oneOf:
+      - description: Apple M1 SoC based platforms
+        items:
+          - enum:
+              - AAPL,j274 # Mac mini (M1, 2020)
+              - AAPL,j293 # MacBook Pro (13-inch, M1, 2020)
+              - AAPL,j313 # MacBook Air (M1, 2020)
+          - const: AAPL,m1
+          - const: AAPL,arm-platform
+
+additionalProperties: true
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index d3e847f7f3dc..91a7b33834ac 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1625,6 +1625,16 @@ F:	arch/arm/mach-alpine/
 F:	arch/arm64/boot/dts/amazon/
 F:	drivers/*/*alpine*
 
+ARM/APPLE MACHINE SUPPORT
+M:	Hector Martin <marcan@marcan.st>
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+W:	https://asahilinux.org
+B:	https://github.com/AsahiLinux/linux/issues
+C:	irc://chat.freenode.net/asahi-dev
+T:	git https://github.com/AsahiLinux/linux.git
+F:	Documentation/devicetree/bindings/arm/AAPL.yaml
+
 ARM/ARTPEC MACHINE SUPPORT
 M:	Jesper Nilsson <jesper.nilsson@axis.com>
 M:	Lars Persson <lars.persson@axis.com>
-- 
2.30.0


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

* [PATCH 04/18] arm64: Kconfig: Introduce CONFIG_ARCH_APPLE
  2021-02-04 20:39 [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin
                   ` (2 preceding siblings ...)
  2021-02-04 20:39 ` [PATCH 03/18] dt-bindings: arm: AAPL: Add bindings for Apple ARM platforms Hector Martin
@ 2021-02-04 20:39 ` Hector Martin
       [not found]   ` <87k0rll4i8.wl-maz@kernel.org>
  2021-02-04 20:39 ` [PATCH 05/18] tty: serial: samsung_tty: add support for Apple UARTs Hector Martin
                   ` (14 subsequent siblings)
  18 siblings, 1 reply; 82+ messages in thread
From: Hector Martin @ 2021-02-04 20:39 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

This adds a Kconfig option to toggle support for Apple ARM SoCs.
At this time this targets the M1 and later "Apple Silicon" Mac SoCs.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 arch/arm64/Kconfig.platforms | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 6eecdef538bd..e3e3bd2c4374 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -29,6 +29,13 @@ config ARCH_ALPINE
 	  This enables support for the Annapurna Labs Alpine
 	  Soc family.
 
+config ARCH_APPLE
+	bool "Apple Silicon SoC family"
+	select GENERIC_IRQ_CHIP
+	help
+	  This enables support for Apple's in-house ARM SoC family, starting
+	  with the Apple M1.
+
 config ARCH_BCM2835
 	bool "Broadcom BCM2835 family"
 	select TIMER_OF
-- 
2.30.0


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

* [PATCH 05/18] tty: serial: samsung_tty: add support for Apple UARTs
  2021-02-04 20:39 [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin
                   ` (3 preceding siblings ...)
  2021-02-04 20:39 ` [PATCH 04/18] arm64: Kconfig: Introduce CONFIG_ARCH_APPLE Hector Martin
@ 2021-02-04 20:39 ` Hector Martin
  2021-02-04 23:55   ` kernel test robot
                     ` (3 more replies)
  2021-02-04 20:39 ` [PATCH 06/18] dt-bindings: serial: samsung: Add AAPL,s5l-uart compatible Hector Martin
                   ` (13 subsequent siblings)
  18 siblings, 4 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-04 20:39 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

Apple SoCs are a distant descendant of Samsung designs and use yet
another variant of their UART style, with different interrupt handling.

In particular, this variant has the following differences with existing
ones:

* It includes a built-in interrupt controller with different registers,
  using only a single platform IRQ

* Internal interrupt sources are treated as edge-triggered, even though
  the IRQ output is level-triggered. This chiefly affects the TX IRQ
  path: the driver can no longer rely on the TX buffer empty IRQ
  immediately firing after TX is enabled, but instead must prime the
  FIFO with data directly.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 drivers/tty/serial/samsung_tty.c | 297 +++++++++++++++++++++++++++----
 include/linux/serial_s3c.h       |  16 ++
 include/uapi/linux/serial_core.h |   3 +
 3 files changed, 280 insertions(+), 36 deletions(-)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index 8ae3e03fbd8c..6d812ba1b748 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -56,6 +56,9 @@
 /* flag to ignore all characters coming in */
 #define RXSTAT_DUMMY_READ (0x10000000)
 
+/* IRQ number used when the handler is called in non-IRQ context */
+#define NO_IRQ -1
+
 struct s3c24xx_uart_info {
 	char			*name;
 	unsigned int		type;
@@ -144,6 +147,14 @@ struct s3c24xx_uart_port {
 #endif
 };
 
+enum s3c24xx_irq_type {
+	IRQ_DISCRETE = 0,
+	IRQ_S3C6400 = 1,
+	IRQ_APPLE = 2,
+};
+
+static void s3c24xx_serial_start_next_tx(struct s3c24xx_uart_port *ourport);
+
 /* conversion functions */
 
 #define s3c24xx_dev_to_port(__dev) dev_get_drvdata(__dev)
@@ -231,11 +242,20 @@ static int s3c24xx_serial_txempty_nofifo(struct uart_port *port)
 /*
  * s3c64xx and later SoC's include the interrupt mask and status registers in
  * the controller itself, unlike the s3c24xx SoC's which have these registers
- * in the interrupt controller. Check if the port type is s3c64xx or higher.
+ * in the interrupt controller. Apple SoCs use a different flavor of mask
+ * and status registers. This function returns the IRQ style to use.
  */
-static int s3c24xx_serial_has_interrupt_mask(struct uart_port *port)
+static int s3c24xx_irq_type(struct uart_port *port)
 {
-	return to_ourport(port)->info->type == PORT_S3C6400;
+	switch (to_ourport(port)->info->type) {
+	case PORT_S3C6400:
+		return IRQ_S3C6400;
+	case PORT_APPLE:
+		return IRQ_APPLE;
+	default:
+		return IRQ_DISCRETE;
+	}
+
 }
 
 static void s3c24xx_serial_rx_enable(struct uart_port *port)
@@ -289,10 +309,17 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port)
 	if (!ourport->tx_enabled)
 		return;
 
-	if (s3c24xx_serial_has_interrupt_mask(port))
+	switch (s3c24xx_irq_type(port)) {
+	case IRQ_APPLE:
+		s3c24xx_clear_bit(port, APPLE_UCON_TXTHRESH_ENA, S3C2410_UCON);
+		break;
+	case IRQ_S3C6400:
 		s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
-	else
+		break;
+	default:
 		disable_irq_nosync(ourport->tx_irq);
+		break;
+	}
 
 	if (dma && dma->tx_chan && ourport->tx_in_progress == S3C24XX_TX_DMA) {
 		dmaengine_pause(dma->tx_chan);
@@ -315,8 +342,6 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port)
 	ourport->tx_mode = 0;
 }
 
-static void s3c24xx_serial_start_next_tx(struct s3c24xx_uart_port *ourport);
-
 static void s3c24xx_serial_tx_dma_complete(void *args)
 {
 	struct s3c24xx_uart_port *ourport = args;
@@ -353,10 +378,17 @@ static void enable_tx_dma(struct s3c24xx_uart_port *ourport)
 	u32 ucon;
 
 	/* Mask Tx interrupt */
-	if (s3c24xx_serial_has_interrupt_mask(port))
+	switch (s3c24xx_irq_type(port)) {
+	case IRQ_APPLE:
+		WARN_ON(1); // No DMA
+		break;
+	case IRQ_S3C6400:
 		s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
-	else
+		break;
+	default:
 		disable_irq_nosync(ourport->tx_irq);
+		break;
+	}
 
 	/* Enable tx dma mode */
 	ucon = rd_regl(port, S3C2410_UCON);
@@ -369,6 +401,8 @@ static void enable_tx_dma(struct s3c24xx_uart_port *ourport)
 	ourport->tx_mode = S3C24XX_TX_DMA;
 }
 
+static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id);
+
 static void enable_tx_pio(struct s3c24xx_uart_port *ourport)
 {
 	struct uart_port *port = &ourport->port;
@@ -383,16 +417,30 @@ static void enable_tx_pio(struct s3c24xx_uart_port *ourport)
 	ucon = rd_regl(port, S3C2410_UCON);
 	ucon &= ~(S3C64XX_UCON_TXMODE_MASK);
 	ucon |= S3C64XX_UCON_TXMODE_CPU;
-	wr_regl(port,  S3C2410_UCON, ucon);
 
 	/* Unmask Tx interrupt */
-	if (s3c24xx_serial_has_interrupt_mask(port))
-		s3c24xx_clear_bit(port, S3C64XX_UINTM_TXD,
-				  S3C64XX_UINTM);
-	else
+	switch (s3c24xx_irq_type(port)) {
+	case IRQ_APPLE:
+		ucon |= APPLE_UCON_TXTHRESH_ENA_MSK;
+		break;
+	case IRQ_S3C6400:
+		s3c24xx_clear_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
+		break;
+	default:
 		enable_irq(ourport->tx_irq);
+		break;
+	}
+
+	wr_regl(port,  S3C2410_UCON, ucon);
 
 	ourport->tx_mode = S3C24XX_TX_PIO;
+
+	/*
+	 * The Apple version only has edge triggered TX IRQs, so we need
+	 * to kick off the process by sending some characters here.
+	 */
+	if (s3c24xx_irq_type(port) == IRQ_APPLE)
+		s3c24xx_serial_tx_chars(NO_IRQ, ourport);
 }
 
 static void s3c24xx_serial_start_tx_pio(struct s3c24xx_uart_port *ourport)
@@ -513,11 +561,18 @@ static void s3c24xx_serial_stop_rx(struct uart_port *port)
 
 	if (ourport->rx_enabled) {
 		dev_dbg(port->dev, "stopping rx\n");
-		if (s3c24xx_serial_has_interrupt_mask(port))
-			s3c24xx_set_bit(port, S3C64XX_UINTM_RXD,
-					S3C64XX_UINTM);
-		else
-			disable_irq_nosync(ourport->rx_irq);
+		switch (s3c24xx_irq_type(port)) {
+		case IRQ_APPLE:
+			s3c24xx_clear_bit(port, APPLE_UCON_RXTHRESH_ENA, S3C2410_UCON);
+			s3c24xx_clear_bit(port, APPLE_UCON_RXTO_ENA, S3C2410_UCON);
+			break;
+		case IRQ_S3C6400:
+			s3c24xx_set_bit(port, S3C64XX_UINTM_RXD, S3C64XX_UINTM);
+			break;
+		default:
+			disable_irq_nosync(ourport->tx_irq);
+			break;
+		}
 		ourport->rx_enabled = 0;
 	}
 	if (dma && dma->rx_chan) {
@@ -651,14 +706,18 @@ static void enable_rx_pio(struct s3c24xx_uart_port *ourport)
 
 	/* set Rx mode to DMA mode */
 	ucon = rd_regl(port, S3C2410_UCON);
-	ucon &= ~(S3C64XX_UCON_TIMEOUT_MASK |
-			S3C64XX_UCON_EMPTYINT_EN |
-			S3C64XX_UCON_DMASUS_EN |
-			S3C64XX_UCON_TIMEOUT_EN |
-			S3C64XX_UCON_RXMODE_MASK);
-	ucon |= 0xf << S3C64XX_UCON_TIMEOUT_SHIFT |
-			S3C64XX_UCON_TIMEOUT_EN |
-			S3C64XX_UCON_RXMODE_CPU;
+	ucon &= ~S3C64XX_UCON_RXMODE_MASK;
+	ucon |= S3C64XX_UCON_RXMODE_CPU;
+
+	/* Apple types use these bits for IRQ masks */
+	if (s3c24xx_irq_type(port) != IRQ_APPLE) {
+		ucon &= ~(S3C64XX_UCON_TIMEOUT_MASK |
+				S3C64XX_UCON_EMPTYINT_EN |
+				S3C64XX_UCON_DMASUS_EN |
+				S3C64XX_UCON_TIMEOUT_EN);
+		ucon |= 0xf << S3C64XX_UCON_TIMEOUT_SHIFT |
+				S3C64XX_UCON_TIMEOUT_EN;
+	}
 	wr_regl(port, S3C2410_UCON, ucon);
 
 	ourport->rx_mode = S3C24XX_RX_PIO;
@@ -831,7 +890,9 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
 	unsigned long flags;
 	int count, dma_count = 0;
 
-	spin_lock_irqsave(&port->lock, flags);
+	/* Only lock if called from IRQ context */
+	if (irq != NO_IRQ)
+		spin_lock_irqsave(&port->lock, flags);
 
 	count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
 
@@ -893,7 +954,8 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
 		s3c24xx_serial_stop_tx(port);
 
 out:
-	spin_unlock_irqrestore(&port->lock, flags);
+	if (irq != NO_IRQ)
+		spin_unlock_irqrestore(&port->lock, flags);
 	return IRQ_HANDLED;
 }
 
@@ -916,6 +978,26 @@ static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id)
 	return ret;
 }
 
+/* interrupt handler for Apple SoC's.*/
+static irqreturn_t apple_serial_handle_irq(int irq, void *id)
+{
+	struct s3c24xx_uart_port *ourport = id;
+	struct uart_port *port = &ourport->port;
+	unsigned int pend = rd_regl(port, S3C2410_UTRSTAT);
+	irqreturn_t ret = IRQ_HANDLED;
+
+	if (pend & (APPLE_UTRSTAT_RXTHRESH | APPLE_UTRSTAT_RXTO)) {
+		wr_regl(port, S3C2410_UTRSTAT, APPLE_UTRSTAT_RXTHRESH | APPLE_UTRSTAT_RXTO);
+		ret = s3c24xx_serial_rx_chars(irq, id);
+	}
+	if (pend & APPLE_UTRSTAT_TXTHRESH) {
+		wr_regl(port, S3C2410_UTRSTAT, APPLE_UTRSTAT_TXTHRESH);
+		ret = s3c24xx_serial_tx_chars(irq, id);
+	}
+
+	return ret;
+}
+
 static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port)
 {
 	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
@@ -1098,7 +1180,7 @@ static void s3c24xx_serial_shutdown(struct uart_port *port)
 	struct s3c24xx_uart_port *ourport = to_ourport(port);
 
 	if (ourport->tx_claimed) {
-		if (!s3c24xx_serial_has_interrupt_mask(port))
+		if (s3c24xx_irq_type(port) == IRQ_DISCRETE)
 			free_irq(ourport->tx_irq, ourport);
 		ourport->tx_enabled = 0;
 		ourport->tx_claimed = 0;
@@ -1106,18 +1188,34 @@ static void s3c24xx_serial_shutdown(struct uart_port *port)
 	}
 
 	if (ourport->rx_claimed) {
-		if (!s3c24xx_serial_has_interrupt_mask(port))
+		if (s3c24xx_irq_type(port) == IRQ_DISCRETE)
 			free_irq(ourport->rx_irq, ourport);
 		ourport->rx_claimed = 0;
 		ourport->rx_enabled = 0;
 	}
 
 	/* Clear pending interrupts and mask all interrupts */
-	if (s3c24xx_serial_has_interrupt_mask(port)) {
+	switch (s3c24xx_irq_type(port)) {
+	case IRQ_APPLE: {
+		unsigned int ucon;
+
+		ucon = rd_regl(port, S3C2410_UCON);
+		ucon &= ~(APPLE_UCON_TXTHRESH_ENA_MSK |
+			APPLE_UCON_RXTHRESH_ENA_MSK |
+			APPLE_UCON_RXTO_ENA_MSK);
+		wr_regl(port, S3C2410_UCON, ucon);
+
+		wr_regl(port, S3C2410_UTRSTAT, APPLE_UTRSTAT_ALL_FLAGS);
+
+		free_irq(port->irq, ourport);
+		break;
+	}
+	case IRQ_S3C6400:
 		free_irq(port->irq, ourport);
 
 		wr_regl(port, S3C64XX_UINTP, 0xf);
 		wr_regl(port, S3C64XX_UINTM, 0xf);
+		break;
 	}
 
 	if (ourport->dma)
@@ -1215,6 +1313,47 @@ static int s3c64xx_serial_startup(struct uart_port *port)
 	return ret;
 }
 
+static int apple_serial_startup(struct uart_port *port)
+{
+	struct s3c24xx_uart_port *ourport = to_ourport(port);
+	unsigned long flags;
+	unsigned int ufcon;
+	int ret;
+
+	wr_regl(port, S3C2410_UTRSTAT, APPLE_UTRSTAT_ALL_FLAGS);
+
+	ret = request_irq(port->irq, apple_serial_handle_irq, IRQF_SHARED,
+			  s3c24xx_serial_portname(port), ourport);
+	if (ret) {
+		dev_err(port->dev, "cannot get irq %d\n", port->irq);
+		return ret;
+	}
+
+	/* For compatibility with s3c24xx Soc's */
+	ourport->rx_enabled = 1;
+	ourport->rx_claimed = 1;
+	ourport->tx_enabled = 0;
+	ourport->tx_claimed = 1;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	ufcon = rd_regl(port, S3C2410_UFCON);
+	ufcon |= S3C2410_UFCON_RESETRX | S5PV210_UFCON_RXTRIG8;
+	if (!uart_console(port))
+		ufcon |= S3C2410_UFCON_RESETTX;
+	wr_regl(port, S3C2410_UFCON, ufcon);
+
+	enable_rx_pio(ourport);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	/* Enable Rx Interrupt */
+	s3c24xx_set_bit(port, APPLE_UCON_RXTHRESH_ENA, S3C2410_UCON);
+	s3c24xx_set_bit(port, APPLE_UCON_RXTO_ENA, S3C2410_UCON);
+
+	return ret;
+}
+
 /* power power management control */
 
 static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
@@ -1544,6 +1683,8 @@ static const char *s3c24xx_serial_type(struct uart_port *port)
 		return "S3C2412";
 	case PORT_S3C6400:
 		return "S3C6400/10";
+	case PORT_APPLE:
+		return "APPLE";
 	default:
 		return NULL;
 	}
@@ -1868,9 +2009,16 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
 	/* setup info for port */
 	port->dev	= &platdev->dev;
 
+	switch (s3c24xx_irq_type(port)) {
+	/* Startup sequence is different for Apple SoC's */
+	case IRQ_APPLE:
+		s3c24xx_serial_ops.startup = apple_serial_startup;
+		break;
 	/* Startup sequence is different for s3c64xx and higher SoC's */
-	if (s3c24xx_serial_has_interrupt_mask(port))
+	case IRQ_S3C6400:
 		s3c24xx_serial_ops.startup = s3c64xx_serial_startup;
+		break;
+	}
 
 	port->uartclk = 1;
 
@@ -1905,7 +2053,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
 		ourport->tx_irq = ret + 1;
 	}
 
-	if (!s3c24xx_serial_has_interrupt_mask(port)) {
+	if (s3c24xx_irq_type(port) == IRQ_DISCRETE) {
 		ret = platform_get_irq(platdev, 1);
 		if (ret > 0)
 			ourport->tx_irq = ret;
@@ -1945,10 +2093,24 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
 		pr_warn("uart: failed to enable baudclk\n");
 
 	/* Keep all interrupts masked and cleared */
-	if (s3c24xx_serial_has_interrupt_mask(port)) {
+	switch (s3c24xx_irq_type(port)) {
+	case IRQ_APPLE: {
+		unsigned int ucon;
+
+		ucon = rd_regl(port, S3C2410_UCON);
+		ucon &= ~(APPLE_UCON_TXTHRESH_ENA_MSK |
+			APPLE_UCON_RXTHRESH_ENA_MSK |
+			APPLE_UCON_RXTO_ENA_MSK);
+		wr_regl(port, S3C2410_UCON, ucon);
+
+		wr_regl(port, S3C2410_UTRSTAT, APPLE_UTRSTAT_ALL_FLAGS);
+		break;
+	}
+	case IRQ_S3C6400:
 		wr_regl(port, S3C64XX_UINTM, 0xf);
 		wr_regl(port, S3C64XX_UINTP, 0xf);
 		wr_regl(port, S3C64XX_UINTSP, 0xf);
+		break;
 	}
 
 	dev_dbg(port->dev, "port: map=%pa, mem=%p, irq=%d (%d,%d), clock=%u\n",
@@ -2142,7 +2304,33 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)
 
 	if (port) {
 		/* restore IRQ mask */
-		if (s3c24xx_serial_has_interrupt_mask(port)) {
+		switch (s3c24xx_irq_type(port)) {
+		case IRQ_APPLE:
+			unsigned int ucon;
+
+			clk_prepare_enable(ourport->clk);
+			if (!IS_ERR(ourport->baudclk))
+				clk_prepare_enable(ourport->baudclk);
+
+			ucon = rd_regl(port, S3C2410_UCON);
+
+			ucon &= ~(APPLE_UCON_TXTHRESH_ENA_MSK |
+				APPLE_UCON_RXTHRESH_ENA_MSK |
+				APPLE_UCON_RXTO_ENA_MSK);
+
+			if (ourport->tx_enabled)
+				ucon |= APPLE_UCON_TXTHRESH_ENA_MSK;
+			if (ourport->rx_enabled)
+				ucon |= APPLE_UCON_RXTHRESH_ENA_MSK |
+					APPLE_UCON_RXTO_ENA_MSK;
+
+			wr_regl(port, S3C2410_UCON, ucon);
+
+			if (!IS_ERR(ourport->baudclk))
+				clk_disable_unprepare(ourport->baudclk);
+			clk_disable_unprepare(ourport->clk);
+			break;
+		case IRQ_S3C6400:
 			unsigned int uintm = 0xf;
 
 			if (ourport->tx_enabled)
@@ -2156,6 +2344,7 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)
 			if (!IS_ERR(ourport->baudclk))
 				clk_disable_unprepare(ourport->baudclk);
 			clk_disable_unprepare(ourport->clk);
+			break;
 		}
 	}
 
@@ -2556,6 +2745,34 @@ static struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = {
 #define EXYNOS5433_SERIAL_DRV_DATA (kernel_ulong_t)NULL
 #endif
 
+#if defined(CONFIG_ARCH_APPLE)
+static struct s3c24xx_serial_drv_data s5l_serial_drv_data = {
+	.info = &(struct s3c24xx_uart_info) {
+		.name		= "Apple S5L UART",
+		.type		= PORT_APPLE,
+		.fifosize	= 16,
+		.rx_fifomask	= S3C2410_UFSTAT_RXMASK,
+		.rx_fifoshift	= S3C2410_UFSTAT_RXSHIFT,
+		.rx_fifofull	= S3C2410_UFSTAT_RXFULL,
+		.tx_fifofull	= S3C2410_UFSTAT_TXFULL,
+		.tx_fifomask	= S3C2410_UFSTAT_TXMASK,
+		.tx_fifoshift	= S3C2410_UFSTAT_TXSHIFT,
+		.def_clk_sel	= S3C2410_UCON_CLKSEL0,
+		.num_clks	= 1,
+		.clksel_mask	= 0,
+		.clksel_shift	= 0,
+	},
+	.def_cfg = &(struct s3c2410_uartcfg) {
+		.ucon		= APPLE_UCON_DEFAULT,
+		.ufcon		= S3C2410_UFCON_DEFAULT,
+	},
+};
+#define S5L_SERIAL_DRV_DATA ((kernel_ulong_t)&s5l_serial_drv_data)
+#else
+#define S5L_SERIAL_DRV_DATA ((kernel_ulong_t)NULL)
+#endif
+
+
 static const struct platform_device_id s3c24xx_serial_driver_ids[] = {
 	{
 		.name		= "s3c2410-uart",
@@ -2578,6 +2795,9 @@ static const struct platform_device_id s3c24xx_serial_driver_ids[] = {
 	}, {
 		.name		= "exynos5433-uart",
 		.driver_data	= EXYNOS5433_SERIAL_DRV_DATA,
+	}, {
+		.name		= "s5l-uart",
+		.driver_data	= S5L_SERIAL_DRV_DATA,
 	},
 	{ },
 };
@@ -2599,6 +2819,8 @@ static const struct of_device_id s3c24xx_uart_dt_match[] = {
 		.data = (void *)EXYNOS4210_SERIAL_DRV_DATA },
 	{ .compatible = "samsung,exynos5433-uart",
 		.data = (void *)EXYNOS5433_SERIAL_DRV_DATA },
+	{ .compatible = "AAPL,s5l-uart",
+		.data = (void *)S5L_SERIAL_DRV_DATA },
 	{},
 };
 MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match);
@@ -2694,6 +2916,9 @@ static int __init s3c2410_early_console_setup(struct earlycon_device *device,
 
 OF_EARLYCON_DECLARE(s3c2410, "samsung,s3c2410-uart",
 			s3c2410_early_console_setup);
+/* Apple SoCs are close enough to s3c2410 for earlycon */
+OF_EARLYCON_DECLARE(s5l, "AAPL,s5l-uart",
+			s3c2410_early_console_setup);
 
 /* S3C2412, S3C2440, S3C64xx */
 static struct samsung_early_console_data s3c2440_early_console_data = {
diff --git a/include/linux/serial_s3c.h b/include/linux/serial_s3c.h
index ca2c5393dc6b..377c8c6e5b97 100644
--- a/include/linux/serial_s3c.h
+++ b/include/linux/serial_s3c.h
@@ -246,6 +246,22 @@
 				 S5PV210_UFCON_TXTRIG4 |	\
 				 S5PV210_UFCON_RXTRIG4)
 
+
+#define APPLE_UCON_RXTO_ENA	9
+#define APPLE_UCON_RXTHRESH_ENA	12
+#define APPLE_UCON_TXTHRESH_ENA	13
+#define APPLE_UCON_RXTO_ENA_MSK		(1 << APPLE_UCON_RXTO_ENA)
+#define APPLE_UCON_RXTHRESH_ENA_MSK	(1 << APPLE_UCON_RXTHRESH_ENA)
+#define APPLE_UCON_TXTHRESH_ENA_MSK	(1 << APPLE_UCON_TXTHRESH_ENA)
+
+#define APPLE_UCON_DEFAULT	  S3C2410_UCON_RXFIFO_TOI
+
+#define APPLE_UTRSTAT_RXTHRESH	(1<<4)
+#define APPLE_UTRSTAT_TXTHRESH	(1<<5)
+#define APPLE_UTRSTAT_RXTO	(1<<9)
+#define APPLE_UTRSTAT_ALL_FLAGS	(0x3f0)
+
+
 #ifndef __ASSEMBLY__
 
 #include <linux/serial_core.h>
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
index 62c22045fe65..59d102b674db 100644
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -277,4 +277,7 @@
 /* Freescale LINFlexD UART */
 #define PORT_LINFLEXUART	122
 
+/* Apple Silicon (M1/T8103) UART (Samsung variant) */
+#define PORT_APPLE	123
+
 #endif /* _UAPILINUX_SERIAL_CORE_H */
-- 
2.30.0


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

* [PATCH 06/18] dt-bindings: serial: samsung: Add AAPL,s5l-uart compatible
  2021-02-04 20:39 [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin
                   ` (4 preceding siblings ...)
  2021-02-04 20:39 ` [PATCH 05/18] tty: serial: samsung_tty: add support for Apple UARTs Hector Martin
@ 2021-02-04 20:39 ` Hector Martin
  2021-02-04 20:39 ` [PATCH 07/18] tty: serial: samsung_tty: enable for ARCH_APPLE Hector Martin
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-04 20:39 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

Apple mobile devices originally used Samsung SoCs (starting with the
S5L8900), and their current in-house SoCs continue to use compatible
UART peripherals. We'll call this UART variant AAPL,s5l-uart.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 Documentation/devicetree/bindings/serial/samsung_uart.yaml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/serial/samsung_uart.yaml b/Documentation/devicetree/bindings/serial/samsung_uart.yaml
index 21ee627b2ced..40409b31f4dc 100644
--- a/Documentation/devicetree/bindings/serial/samsung_uart.yaml
+++ b/Documentation/devicetree/bindings/serial/samsung_uart.yaml
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/serial/samsung_uart.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Samsung S3C, S5P and Exynos SoC UART Controller
+title: Samsung S3C, S5P, Exynos, and S5L (Apple SoC) SoC UART Controller
 
 maintainers:
   - Krzysztof Kozlowski <krzk@kernel.org>
@@ -19,6 +19,7 @@ properties:
   compatible:
     items:
       - enum:
+          - AAPL,s5l-uart
           - samsung,s3c2410-uart
           - samsung,s3c2412-uart
           - samsung,s3c2440-uart
@@ -96,6 +97,7 @@ allOf:
         compatible:
           contains:
             enum:
+              - AAPL,s5l-uart
               - samsung,exynos4210-uart
     then:
       properties:
-- 
2.30.0


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

* [PATCH 07/18] tty: serial: samsung_tty: enable for ARCH_APPLE
  2021-02-04 20:39 [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin
                   ` (5 preceding siblings ...)
  2021-02-04 20:39 ` [PATCH 06/18] dt-bindings: serial: samsung: Add AAPL,s5l-uart compatible Hector Martin
@ 2021-02-04 20:39 ` Hector Martin
       [not found]   ` <CAK8P3a1n+C5V5J24myy_h67DVp2YTN5Hd=tCWjPUYZcrAX4hCg@mail.gmail.com>
  2021-02-04 20:39 ` [PATCH 08/18] arm64: cpufeature: Add a feature for FIQ support Hector Martin
                   ` (11 subsequent siblings)
  18 siblings, 1 reply; 82+ messages in thread
From: Hector Martin @ 2021-02-04 20:39 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

Apple M1 SoCs are distant descendants of Samsung SoCs and use similar
UART blocks.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 drivers/tty/serial/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 34a2899e69c0..e239977e37f7 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -236,7 +236,7 @@ config SERIAL_CLPS711X_CONSOLE
 
 config SERIAL_SAMSUNG
 	tristate "Samsung SoC serial support"
-	depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
+	depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST || ARCH_APPLE
 	select SERIAL_CORE
 	help
 	  Support for the on-chip UARTs on the Samsung S3C24XX series CPUs,
-- 
2.30.0


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

* [PATCH 08/18] arm64: cpufeature: Add a feature for FIQ support
  2021-02-04 20:39 [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin
                   ` (6 preceding siblings ...)
  2021-02-04 20:39 ` [PATCH 07/18] tty: serial: samsung_tty: enable for ARCH_APPLE Hector Martin
@ 2021-02-04 20:39 ` Hector Martin
       [not found]   ` <87im75l2lp.wl-maz@kernel.org>
  2021-02-04 20:39 ` [PATCH 09/18] arm64: cputype: Add CPU types for the Apple M1 big/little cores Hector Martin
                   ` (10 subsequent siblings)
  18 siblings, 1 reply; 82+ messages in thread
From: Hector Martin @ 2021-02-04 20:39 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

Apple ARM SoCs (A11 and newer) have some interrupt sources hard-wired to
the FIQ line. Introduce a cpufeature that can be used to enable FIQ
unmasking and handling via alternatives.

This is currently enabled for all Apple CPUs. If/when support is
implemented for older (pre-A11) iPhone/iPad SoCs which do not need FIQs,
or if newer SoCs are released without the FIQ requirement, we can
revisit the condition.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 arch/arm64/Kconfig                  | 10 +++++++++
 arch/arm64/include/asm/cpucaps.h    |  3 ++-
 arch/arm64/include/asm/cpufeature.h |  6 ++++++
 arch/arm64/include/asm/cputype.h    |  1 +
 arch/arm64/kernel/cpufeature.c      | 32 +++++++++++++++++++++++++++++
 5 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index f39568b28ec1..11cfdc07404f 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1756,6 +1756,16 @@ config ARM64_DEBUG_PRIORITY_MASKING
 	  If unsure, say N
 endif
 
+config ARM64_FIQ_SUPPORT
+	bool "Support for FIQ interrupts"
+	help
+	  Adds support for handling FIQ interrupts as normal IRQs.
+	  This is required on Apple platforms where some IRQ sources are
+	  hardwired to the FIQ interrupt line.
+
+	  FIQs are only enabled at runtime on platforms that require them
+	  via the CPU feature framework.
+
 config RELOCATABLE
 	bool "Build a relocatable kernel image" if EXPERT
 	select ARCH_HAS_RELR
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index b77d997b173b..c36d926ad801 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -66,7 +66,8 @@
 #define ARM64_WORKAROUND_1508412		58
 #define ARM64_HAS_LDAPR				59
 #define ARM64_KVM_PROTECTED_MODE		60
+#define ARM64_NEEDS_FIQ				61
 
-#define ARM64_NCAPS				61
+#define ARM64_NCAPS				62
 
 #endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 9a555809b89c..3a00cfb347c9 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -716,6 +716,12 @@ static __always_inline bool system_uses_irq_prio_masking(void)
 	       cpus_have_const_cap(ARM64_HAS_IRQ_PRIO_MASKING);
 }
 
+static __always_inline bool system_uses_fiqs(void)
+{
+	return IS_ENABLED(CONFIG_ARM64_FIQ_SUPPORT) &&
+	       cpus_have_const_cap(ARM64_NEEDS_FIQ);
+}
+
 static inline bool system_supports_mte(void)
 {
 	return IS_ENABLED(CONFIG_ARM64_MTE) &&
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index ef5b040dee44..2084a0340d16 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -59,6 +59,7 @@
 #define ARM_CPU_IMP_NVIDIA		0x4E
 #define ARM_CPU_IMP_FUJITSU		0x46
 #define ARM_CPU_IMP_HISI		0x48
+#define ARM_CPU_IMP_APPLE		0x61
 
 #define ARM_CPU_PART_AEM_V8		0xD0F
 #define ARM_CPU_PART_FOUNDATION		0xD00
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index e99eddec0a46..0863cf7cf807 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1237,6 +1237,29 @@ static bool has_cache_idc(const struct arm64_cpu_capabilities *entry,
 	return ctr & BIT(CTR_IDC_SHIFT);
 }
 
+static void cpu_sync_irq_to_fiq(struct arm64_cpu_capabilities const *cap)
+{
+	u64 daif = read_sysreg(daif);
+
+	/*
+	 * By this point in the boot process IRQs are likely masked and FIOs
+	 * aren't, so we need to sync things to avoid spurious early FIQs.
+	 */
+
+	if (daif & PSR_I_BIT)
+		daif |= PSR_F_BIT;
+	else
+		daif &= ~PSR_F_BIT;
+
+	write_sysreg(daif, daif);
+}
+
+static bool needs_fiq(const struct arm64_cpu_capabilities *entry, int __unused)
+{
+	/* All supported Apple cores need this */
+	return read_cpuid_implementor() == ARM_CPU_IMP_APPLE;
+}
+
 static void cpu_emulate_effective_ctr(const struct arm64_cpu_capabilities *__unused)
 {
 	/*
@@ -2154,6 +2177,15 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.min_field_value = 1,
 	},
+#ifdef CONFIG_ARM64_FIQ_SUPPORT
+	{
+		.desc = "FIQs",
+		.capability = ARM64_NEEDS_FIQ,
+		.type = ARM64_CPUCAP_BOOT_CPU_FEATURE,
+		.matches = needs_fiq,
+		.cpu_enable = cpu_sync_irq_to_fiq,
+	},
+#endif
 	{},
 };
 
-- 
2.30.0


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

* [PATCH 09/18] arm64: cputype: Add CPU types for the Apple M1 big/little cores
  2021-02-04 20:39 [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin
                   ` (7 preceding siblings ...)
  2021-02-04 20:39 ` [PATCH 08/18] arm64: cpufeature: Add a feature for FIQ support Hector Martin
@ 2021-02-04 20:39 ` Hector Martin
  2021-02-04 20:39 ` [PATCH 10/18] arm64: Introduce FIQ support Hector Martin
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-04 20:39 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

These are not used at the moment, but let's add them for documentation
purposes.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 arch/arm64/include/asm/cputype.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 2084a0340d16..6231e1f0abe7 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -100,6 +100,9 @@
 
 #define HISI_CPU_PART_TSV110		0xD01
 
+#define APPLE_CPU_PART_M1_ICESTORM	0x022
+#define APPLE_CPU_PART_M1_FIRESTORM	0x023
+
 #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
 #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
 #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
@@ -128,6 +131,8 @@
 #define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL)
 #define MIDR_FUJITSU_A64FX MIDR_CPU_MODEL(ARM_CPU_IMP_FUJITSU, FUJITSU_CPU_PART_A64FX)
 #define MIDR_HISI_TSV110 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_TSV110)
+#define MIDR_APPLE_M1_ICESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM)
+#define MIDR_APPLE_M1_FIRESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM)
 
 /* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */
 #define MIDR_FUJITSU_ERRATUM_010001		MIDR_FUJITSU_A64FX
-- 
2.30.0


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

* [PATCH 10/18] arm64: Introduce FIQ support
  2021-02-04 20:39 [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin
                   ` (8 preceding siblings ...)
  2021-02-04 20:39 ` [PATCH 09/18] arm64: cputype: Add CPU types for the Apple M1 big/little cores Hector Martin
@ 2021-02-04 20:39 ` Hector Martin
       [not found]   ` <87h7mpky0f.wl-maz@kernel.org>
  2021-02-04 20:39 ` [PATCH 11/18] arm64: Kconfig: Require FIQ support for ARCH_APPLE Hector Martin
                   ` (8 subsequent siblings)
  18 siblings, 1 reply; 82+ messages in thread
From: Hector Martin @ 2021-02-04 20:39 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

Apple SoCs (A11 and newer) have some interrupt sources hardwired to the
FIQ line. Implement support for this by simply treating IRQs and FIQs
the same way in the interrupt vectors. This is conditional on the
ARM64_NEEDS_FIQ CPU feature flag, and thus will not affect other
systems.

Root irqchip drivers can discriminate between IRQs and FIQs by checking
the ISR_EL1 system register.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 arch/arm64/include/asm/assembler.h |  4 ++++
 arch/arm64/include/asm/daifflags.h |  7 +++++++
 arch/arm64/include/asm/irqflags.h  | 17 +++++++++++++----
 arch/arm64/kernel/entry.S          | 27 +++++++++++++++++++++++----
 4 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index bf125c591116..6acfc372dc76 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -42,7 +42,11 @@
 
 	/* IRQ is the lowest priority flag, unconditionally unmask the rest. */
 	.macro enable_da_f
+alternative_if ARM64_NEEDS_FIQ
+	msr	daifclr, #(8 | 4)
+alternative_else
 	msr	daifclr, #(8 | 4 | 1)
+alternative_endif
 	.endm
 
 /*
diff --git a/arch/arm64/include/asm/daifflags.h b/arch/arm64/include/asm/daifflags.h
index 1c26d7baa67f..228a6039c701 100644
--- a/arch/arm64/include/asm/daifflags.h
+++ b/arch/arm64/include/asm/daifflags.h
@@ -112,6 +112,13 @@ static inline void local_daif_restore(unsigned long flags)
 		 * So we don't need additional synchronization here.
 		 */
 		gic_write_pmr(pmr);
+	} else if (system_uses_fiqs()) {
+		/*
+		 * On systems that use FIQs, disable FIQs if IRQs are disabled.
+		 * This can happen if the DAIF_* flags at the top of this file
+		 * are used to set DAIF directly.
+		 */
+		flags |= PSR_F_BIT;
 	}
 
 	write_sysreg(flags, daif);
diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h
index ff328e5bbb75..689c573c4b47 100644
--- a/arch/arm64/include/asm/irqflags.h
+++ b/arch/arm64/include/asm/irqflags.h
@@ -19,8 +19,9 @@
  * side effects for other flags. Keeping to this order makes it easier for
  * entry.S to know which exceptions should be unmasked.
  *
- * FIQ is never expected, but we mask it when we disable debug exceptions, and
- * unmask it at all other times.
+ * FIQ is never expected on most platforms, but we mask it when we disable
+ * debug exceptions, and unmask it at all other times. On platforms that
+ * require FIQs, it tracks IRQ masking.
  */
 
 /*
@@ -34,8 +35,14 @@ static inline void arch_local_irq_enable(void)
 		WARN_ON_ONCE(pmr != GIC_PRIO_IRQON && pmr != GIC_PRIO_IRQOFF);
 	}
 
-	asm volatile(ALTERNATIVE(
+	/*
+	 * Yes, ALTERNATIVE() nests properly... only one of these should be
+	 * active on any given platform.
+	 */
+	asm volatile(ALTERNATIVE(ALTERNATIVE(
 		"msr	daifclr, #2		// arch_local_irq_enable",
+		"msr	daifclr, #3		// arch_local_irq_enable",
+		ARM64_NEEDS_FIQ),
 		__msr_s(SYS_ICC_PMR_EL1, "%0"),
 		ARM64_HAS_IRQ_PRIO_MASKING)
 		:
@@ -53,8 +60,10 @@ static inline void arch_local_irq_disable(void)
 		WARN_ON_ONCE(pmr != GIC_PRIO_IRQON && pmr != GIC_PRIO_IRQOFF);
 	}
 
-	asm volatile(ALTERNATIVE(
+	asm volatile(ALTERNATIVE(ALTERNATIVE(
 		"msr	daifset, #2		// arch_local_irq_disable",
+		"msr	daifset, #3		// arch_local_irq_disable",
+		ARM64_NEEDS_FIQ),
 		__msr_s(SYS_ICC_PMR_EL1, "%0"),
 		ARM64_HAS_IRQ_PRIO_MASKING)
 		:
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index c9bae73f2621..81ca04ebe37b 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -60,7 +60,7 @@
 #define BAD_FIQ		2
 #define BAD_ERROR	3
 
-	.macro kernel_ventry, el, label, regsize = 64
+	.macro kernel_ventry, el, label, regsize = 64, altlabel = 0, alt = 0
 	.align 7
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
 	.if	\el == 0
@@ -87,7 +87,15 @@ alternative_else_nop_endif
 	tbnz	x0, #THREAD_SHIFT, 0f
 	sub	x0, sp, x0			// x0'' = sp' - x0' = (sp + x0) - sp = x0
 	sub	sp, sp, x0			// sp'' = sp' - x0 = (sp + x0) - x0 = sp
+	.if	\altlabel != 0
+	alternative_if \alt
+	b	el\()\el\()_\altlabel
+	alternative_else
 	b	el\()\el\()_\label
+	alternative_endif
+	.else
+	b	el\()\el\()_\label
+	.endif
 
 0:
 	/*
@@ -119,7 +127,15 @@ alternative_else_nop_endif
 	sub	sp, sp, x0
 	mrs	x0, tpidrro_el0
 #endif
+	.if	\altlabel != 0
+	alternative_if \alt
+	b	el\()\el\()_\altlabel
+	alternative_else
 	b	el\()\el\()_\label
+	alternative_endif
+	.else
+	b	el\()\el\()_\label
+	.endif
 	.endm
 
 	.macro tramp_alias, dst, sym
@@ -547,18 +563,21 @@ SYM_CODE_START(vectors)
 
 	kernel_ventry	1, sync				// Synchronous EL1h
 	kernel_ventry	1, irq				// IRQ EL1h
-	kernel_ventry	1, fiq_invalid			// FIQ EL1h
+							// FIQ EL1h
+	kernel_ventry	1, fiq_invalid, 64, irq, ARM64_NEEDS_FIQ
 	kernel_ventry	1, error			// Error EL1h
 
 	kernel_ventry	0, sync				// Synchronous 64-bit EL0
 	kernel_ventry	0, irq				// IRQ 64-bit EL0
-	kernel_ventry	0, fiq_invalid			// FIQ 64-bit EL0
+							// FIQ 64-bit EL0
+	kernel_ventry	0, fiq_invalid, 64, irq, ARM64_NEEDS_FIQ
 	kernel_ventry	0, error			// Error 64-bit EL0
 
 #ifdef CONFIG_COMPAT
 	kernel_ventry	0, sync_compat, 32		// Synchronous 32-bit EL0
 	kernel_ventry	0, irq_compat, 32		// IRQ 32-bit EL0
-	kernel_ventry	0, fiq_invalid_compat, 32	// FIQ 32-bit EL0
+							// FIQ 32-bit EL0
+	kernel_ventry	0, fiq_invalid_compat, 32, irq_compat, ARM64_NEEDS_FIQ
 	kernel_ventry	0, error_compat, 32		// Error 32-bit EL0
 #else
 	kernel_ventry	0, sync_invalid, 32		// Synchronous 32-bit EL0
-- 
2.30.0


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

* [PATCH 11/18] arm64: Kconfig: Require FIQ support for ARCH_APPLE
  2021-02-04 20:39 [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin
                   ` (9 preceding siblings ...)
  2021-02-04 20:39 ` [PATCH 10/18] arm64: Introduce FIQ support Hector Martin
@ 2021-02-04 20:39 ` Hector Martin
       [not found]   ` <87ft29kxmp.wl-maz@kernel.org>
  2021-02-04 20:39 ` [PATCH 12/18] arm64: setup: Use nGnRnE IO mappings for fixmap on Apple platforms Hector Martin
                   ` (7 subsequent siblings)
  18 siblings, 1 reply; 82+ messages in thread
From: Hector Martin @ 2021-02-04 20:39 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

All currently supported Apple ARM SoCs (and possibly all future ones
too) require FIQs.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 arch/arm64/Kconfig.platforms | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index e3e3bd2c4374..8182d78e8e23 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -32,6 +32,7 @@ config ARCH_ALPINE
 config ARCH_APPLE
 	bool "Apple Silicon SoC family"
 	select GENERIC_IRQ_CHIP
+	select ARM64_FIQ_SUPPORT
 	help
 	  This enables support for Apple's in-house ARM SoC family, starting
 	  with the Apple M1.
-- 
2.30.0


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

* [PATCH 12/18] arm64: setup: Use nGnRnE IO mappings for fixmap on Apple platforms
  2021-02-04 20:39 [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin
                   ` (10 preceding siblings ...)
  2021-02-04 20:39 ` [PATCH 11/18] arm64: Kconfig: Require FIQ support for ARCH_APPLE Hector Martin
@ 2021-02-04 20:39 ` Hector Martin
  2021-02-04 20:39 ` [PATCH 13/18] arm64: ioremap: use nGnRnE mappings on platforms that require it Hector Martin
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-04 20:39 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

This is a hack. I do not expect this to be merged as-is.

The problem: on Apple ARM platforms, SoC MMIO needs to use nGnRnE
mappings: writes using nGnRE are blackholed. This seems to be by design,
and there doesn't seem to be any fabric configuration or other bit we
can flip to make the problem go away.

Particularly tricky is that this affects earlycon, which uses fixmap,
which all gets initialized before any of the usual cpufeatures /
alternatives stuff. So we need to take care of fixmap very early.

Options I can think of:

(1) Unconditionally use nGnRnE on all platforms for fixmap IO. Maybe
    this is actually fine? I suspect it might break some PCI-based
    earlycons?

(2) Deal with this special case in the earlycon code, since that seems
    to be the only user that matters on these platforms. Since the
    IO mapping is done in earlycon.c, this will require some cooperation
    with samsung_tty.c so earlycon knows when it needs to do this. Note
    that doing it with DT properties will break cmdline-only earlycon
    config (which otherwise works fine on this driver).

(3) This patch, but do something saner, like use a specific DT flag to
    trigger this mode instead of a platform match.

Any other ideas?

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 arch/arm64/include/asm/fixmap.h | 10 +++++++++-
 arch/arm64/kernel/setup.c       | 12 ++++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
index 4335800201c9..999351ce84df 100644
--- a/arch/arm64/include/asm/fixmap.h
+++ b/arch/arm64/include/asm/fixmap.h
@@ -94,7 +94,15 @@ enum fixed_addresses {
 #define FIXADDR_SIZE	(__end_of_permanent_fixed_addresses << PAGE_SHIFT)
 #define FIXADDR_START	(FIXADDR_TOP - FIXADDR_SIZE)
 
-#define FIXMAP_PAGE_IO     __pgprot(PROT_DEVICE_nGnRE)
+/*
+ * We use nGnRE by default, but some platforms require nGnRnE for MMIO.
+ */
+extern bool arm64_use_ne_io;
+
+#define FIXMAP_PAGE_IO_DEFAULT	__pgprot(PROT_DEVICE_nGnRE)
+#define FIXMAP_PAGE_IO_STRICT	__pgprot(PROT_DEVICE_nGnRnE)
+#define FIXMAP_PAGE_IO		(arm64_use_ne_io ? FIXMAP_PAGE_IO_STRICT \
+						 : FIXMAP_PAGE_IO_DEFAULT)
 
 void __init early_fixmap_init(void);
 
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index c18aacde8bb0..cd2dc3bdbae4 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -56,6 +56,8 @@ static struct resource *standard_resources;
 
 phys_addr_t __fdt_pointer __initdata;
 
+bool arm64_use_ne_io;
+
 /*
  * Standard memory resources
  */
@@ -197,6 +199,16 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
 
 	pr_info("Machine model: %s\n", name);
 	dump_stack_set_arch_desc("%s (DT)", name);
+
+#ifdef CONFIG_ARCH_APPLE
+	/*
+	 * Apple SoCs need to use nGnRnE mappings for MMIO, and this needs
+	 * to be detected before earlycon is initialized.
+	 */
+	if (of_flat_dt_is_compatible(of_get_flat_dt_root(),
+				     "AAPL,arm-platform"))
+		arm64_use_ne_io = true;
+#endif
 }
 
 static void __init request_standard_resources(void)
-- 
2.30.0


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

* [PATCH 13/18] arm64: ioremap: use nGnRnE mappings on platforms that require it
  2021-02-04 20:39 [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin
                   ` (11 preceding siblings ...)
  2021-02-04 20:39 ` [PATCH 12/18] arm64: setup: Use nGnRnE IO mappings for fixmap on Apple platforms Hector Martin
@ 2021-02-04 20:39 ` Hector Martin
       [not found]   ` <CAK8P3a2Ad+xmmMWgznOHPpxgCXKWFYfpHBqt_49_UuxrwFSq+A@mail.gmail.com>
  2021-02-04 20:39 ` [PATCH 14/18] dt-bindings: interrupt-controller: Add DT bindings for apple-aic Hector Martin
                   ` (5 subsequent siblings)
  18 siblings, 1 reply; 82+ messages in thread
From: Hector Martin @ 2021-02-04 20:39 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

This follows from the fixmap patch, but relates to the general case.
This is a hack, and incomplete. Read on for discussion.

The problem: on Apple ARM platforms, SoC MMIO needs to use nGnRnE
mappings: writes using nGnRE are blackholed. This seems to be by design,
and there doesn't seem to be any fabric configuration or other bit we
can flip to make the problem go away.

As an additional confounding factor, reportedly PCIe MMIO BAR mappings
conversely *do* need to use nGnRE to work properly. So we can't even get
away with a single ioremap setting, but need to discriminate based on
what bus the device is in. Since these devices have Thunderbolt, all PCI
devices in the tree are potentially in scope. Ugh.

Ideas:

(1) Set up some devicetree property to default to nGnRnE at the platform
    level, and then make PCI drivers use nGnRE.

    This will require changing the PCI code to make pci_ioremap_bar do
    something other than a plain ioremap().

    Unfortunately, of the ~630 PCI drivers in the tree, only ~90 use
    pci_ioremap_bar(). This would require a tree-wide cleanup to
    introduce something akin to pci_ioremap(), and make all PCI
    drivers use it instead of naked ioremap().

    Currently there are three ioremap variants:

    ioremap()
    ioremap_wc()
    ioremap_uc() (not normally used on arm64)

    None of these really capture the nGnRE vs nGnRnE distinction. If
    a new variant is introduced in common code, we'd have to provide
    a default implementation that falls back to regular ioremap() on
    other arches. Something like ioremap() vs. ioremap_np() (nonposted)?

(2) The converse of (1): keep the nGnRE default, but introduce special
    casing to the OF binding code to use nGnRnE when instructed to do so
    on these platforms. This means of_iomap() needs changing.

    The advantage of this approach is that the set of possible non-PCI
    drivers that are useful on these SoCs is bounded, so not all drivers
    that don't go through that path need to be fixed.

    Additionally, this could take advantage of the OF address
    translation stuff to be smarter about deciding to use nGnRnE, e.g.
    doing it based on a property of the parent bus node.

    Of note, some devices (like samsung_tty) go through the platform
    device framework, which eventually goes into devm code. So
    of_address_to_resource would need to set some flag on the struct
    resource, that can then be used by both of_iomap() and
    devm_ioremap_resource() and friends to eventually call the right
    ioremap variant.

    The ioremap considerations from (1) apply here too.

(3) Do it at a lower level, in ioremap() itself. This requires that
    ioremap() somehow discriminates based on address range to pick what
    kind of mapping to make.

    Declaring these address ranges would be an issue. Options:

    a) An out of band list in a DT node, a la /reserved-memory

    b) Something based on the existing DT hierarchy, where we can scan
       bus ranges and locate buses with a property that says "nGnRnE" or
       "nGnRE" and dynamically build the list based on that.

    The advantage of this option is that it doesn't touch non-arch code.
    The disadvantage is that it adds a complete new bespoke mechanism to
    the DT, and that it does not let device drivers actually select the
    IO mode, which might be desirable in the future anyway for some
    devices.

All discussion and additional ideas welcome.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 arch/arm64/include/asm/io.h | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 5ea8656a2030..f2609a4f5019 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -167,7 +167,14 @@ extern void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot
 extern void iounmap(volatile void __iomem *addr);
 extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
 
-#define ioremap(addr, size)		__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
+/*
+ * Some platforms require nGnRnE for MMIO.
+ */
+extern bool arm64_use_ne_io;
+
+#define ioremap(addr, size)		__ioremap((addr), (size), \
+						  arm64_use_ne_io ? __pgprot(PROT_DEVICE_nGnRnE) \
+								  : __pgprot(PROT_DEVICE_nGnRE))
 #define ioremap_wc(addr, size)		__ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
 
 /*
-- 
2.30.0


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

* [PATCH 14/18] dt-bindings: interrupt-controller: Add DT bindings for apple-aic
  2021-02-04 20:39 [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin
                   ` (12 preceding siblings ...)
  2021-02-04 20:39 ` [PATCH 13/18] arm64: ioremap: use nGnRnE mappings on platforms that require it Hector Martin
@ 2021-02-04 20:39 ` Hector Martin
  2021-02-09 23:07   ` Rob Herring
  2021-02-04 20:39 ` [PATCH 15/18] irqchip/apple-aic: Add support for the Apple Interrupt Controller Hector Martin
                   ` (4 subsequent siblings)
  18 siblings, 1 reply; 82+ messages in thread
From: Hector Martin @ 2021-02-04 20:39 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

AIC is the Apple Interrupt Controller found on Apple ARM SoCs, such as
the M1.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 .../interrupt-controller/AAPL,aic.yaml        | 88 +++++++++++++++++++
 MAINTAINERS                                   |  2 +
 .../interrupt-controller/apple-aic.h          | 14 +++
 3 files changed, 104 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/AAPL,aic.yaml
 create mode 100644 include/dt-bindings/interrupt-controller/apple-aic.h

diff --git a/Documentation/devicetree/bindings/interrupt-controller/AAPL,aic.yaml b/Documentation/devicetree/bindings/interrupt-controller/AAPL,aic.yaml
new file mode 100644
index 000000000000..7e119614275a
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/AAPL,aic.yaml
@@ -0,0 +1,88 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/AAPL,aic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple Interrupt Controller
+
+maintainers:
+  - Hector Martin <marcan@marcan.st>
+
+description: |
+  The Apple Interrupt Controller is a simple interrupt controller present on
+  Apple ARM SoC platforms, including various iPhone and iPad devices and the
+  "Apple Silicon" M1 Macs.
+
+  It provides the following features:
+
+  - Level-triggered hardware IRQs wired to SoC blocks
+    - Single mask bit per IRQ
+    - Per-IRQ affinity setting
+    - Automatic masking on event delivery (auto-ack)
+    - Software triggering (ORed with hw line)
+  - 2 per-CPU IPIs (meant as "self" and "other", but they are interchangeable
+    if not symmetric)
+  - Automatic prioritization (single event/ack register per CPU, lower IRQs =
+    higher priority)
+  - Automatic masking on ack
+  - Default "this CPU" register view and explicit per-CPU views
+
+allOf:
+  - $ref: /schemas/interrupt-controller.yaml#
+
+properties:
+  compatible:
+    contains:
+      enum:
+        - AAPL,aic
+        - AAPL,m1-aic
+
+  interrupt-controller: true
+
+  '#interrupt-cells':
+    const: 3
+    description: |
+      The 1st cell contains the interrupt type:
+        - 0: Hardware IRQ
+        - 1: FIQ
+        - 2: IPI
+
+      The 2nd cell contains the interrupt number.
+        - HW IRQs: interrupt number
+        - FIQs:
+          - 0: physical timer
+          - 1: virtual timer
+        - IPIs:
+          - 0: normal/"other" IPI (used interanlly for virtual IPIs)
+          - 1: self IPI (normally unused)
+
+      The 3rd cell contains the interrupt flags. This is normally
+      IRQ_TYPE_LEVEL_HIGH (4).
+
+  reg:
+    description: |
+      Specifies base physical address and size of the AIC registers.
+    maxItems: 1
+
+required:
+  - compatible
+  - '#interrupt-cells'
+  - interrupt-controller
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        aic: interrupt-controller@23b100000 {
+            compatible = "AAPL,m1-aic", "AAPL,aic";
+            #interrupt-cells = <3>;
+            interrupt-controller;
+            reg = <0x2 0x3b100000 0x0 0x8000>;
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 91a7b33834ac..f3d4661731c8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1634,6 +1634,8 @@ B:	https://github.com/AsahiLinux/linux/issues
 C:	irc://chat.freenode.net/asahi-dev
 T:	git https://github.com/AsahiLinux/linux.git
 F:	Documentation/devicetree/bindings/arm/AAPL.yaml
+F:	Documentation/devicetree/bindings/interrupt-controller/AAPL,aic.yaml
+F:	include/dt-bindings/interrupt-controller/apple-aic.h
 
 ARM/ARTPEC MACHINE SUPPORT
 M:	Jesper Nilsson <jesper.nilsson@axis.com>
diff --git a/include/dt-bindings/interrupt-controller/apple-aic.h b/include/dt-bindings/interrupt-controller/apple-aic.h
new file mode 100644
index 000000000000..f54dc0cd6e9a
--- /dev/null
+++ b/include/dt-bindings/interrupt-controller/apple-aic.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_APPLE_AIC_H
+#define _DT_BINDINGS_INTERRUPT_CONTROLLER_APPLE_AIC_H
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#define AIC_IRQ 0
+#define AIC_FIQ 1
+#define AIC_IPI 2
+
+#define AIC_TMR_PHYS 0
+#define AIC_TMR_VIRT 1
+
+#endif
-- 
2.30.0


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

* [PATCH 15/18] irqchip/apple-aic: Add support for the Apple Interrupt Controller
  2021-02-04 20:39 [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin
                   ` (13 preceding siblings ...)
  2021-02-04 20:39 ` [PATCH 14/18] dt-bindings: interrupt-controller: Add DT bindings for apple-aic Hector Martin
@ 2021-02-04 20:39 ` Hector Martin
       [not found]   ` <CAK8P3a1zbLM0s_GwkJ0AJQ8cocS-zcsWWKhOB7B99OtRYyDE7g@mail.gmail.com>
                     ` (2 more replies)
  2021-02-04 20:39 ` [PATCH 16/18] irqchip/apple-aic: Add SMP / IPI support Hector Martin
                   ` (3 subsequent siblings)
  18 siblings, 3 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-04 20:39 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

This is the root interrupt controller used on Apple ARM SoCs such as the
M1. This irqchip driver performs multiple functions:

* Discriminates between IRQs and FIQs

* Drives the AIC peripheral itself (which handles IRQs)

* Dispatches FIQs to downstream hard-wired clients (currently the ARM
  timer).

This patch introduces basic UP irqchip support, without SMP/IPI support.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 MAINTAINERS                     |   1 +
 drivers/irqchip/Kconfig         |  10 +
 drivers/irqchip/Makefile        |   1 +
 drivers/irqchip/irq-apple-aic.c | 316 ++++++++++++++++++++++++++++++++
 4 files changed, 328 insertions(+)
 create mode 100644 drivers/irqchip/irq-apple-aic.c

diff --git a/MAINTAINERS b/MAINTAINERS
index f3d4661731c8..3a54ee5747d3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1635,6 +1635,7 @@ C:	irc://chat.freenode.net/asahi-dev
 T:	git https://github.com/AsahiLinux/linux.git
 F:	Documentation/devicetree/bindings/arm/AAPL.yaml
 F:	Documentation/devicetree/bindings/interrupt-controller/AAPL,aic.yaml
+F:	drivers/irqchip/irq-apple-aic.c
 F:	include/dt-bindings/interrupt-controller/apple-aic.h
 
 ARM/ARTPEC MACHINE SUPPORT
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index b147f22a78f4..288c01a9abd4 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -590,4 +590,14 @@ config MST_IRQ
 	help
 	  Support MStar Interrupt Controller.
 
+config APPLE_AIC
+	bool "Apple Interrupt Controller (AIC)"
+	depends on ARCH_APPLE || COMPILE_TEST
+	default ARCH_APPLE
+	select IRQ_DOMAIN
+	select IRQ_DOMAIN_HIERARCHY
+	help
+	  Support for the Apple Interrupt Controller found on Apple Silicon SoCs,
+	  such as the M1.
+
 endmenu
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 0ac93bfaec61..0e2ba7c2dce7 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -113,3 +113,4 @@ obj-$(CONFIG_LOONGSON_PCH_PIC)		+= irq-loongson-pch-pic.o
 obj-$(CONFIG_LOONGSON_PCH_MSI)		+= irq-loongson-pch-msi.o
 obj-$(CONFIG_MST_IRQ)			+= irq-mst-intc.o
 obj-$(CONFIG_SL28CPLD_INTC)		+= irq-sl28cpld.o
+obj-$(CONFIG_APPLE_AIC)			+= irq-apple-aic.o
diff --git a/drivers/irqchip/irq-apple-aic.c b/drivers/irqchip/irq-apple-aic.c
new file mode 100644
index 000000000000..533e3ce9f432
--- /dev/null
+++ b/drivers/irqchip/irq-apple-aic.c
@@ -0,0 +1,316 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2021 Hector Martin <marcan@marcan.st>
+ *
+ * Based on irq-lpc32xx:
+ *   Copyright 2015-2016 Vladimir Zapolskiy <vz@mleia.com>
+ * Based on irq-bcm2836:
+ *   Copyright 2015 Broadcom
+ */
+
+/*
+ * AIC is a fairly simple interrupt controller with the following features:
+ *
+ * - 896 level-triggered hardware IRQs
+ *   - Single mask bit per IRQ
+ *   - Per-IRQ affinity setting
+ *   - Automatic masking on event delivery (auto-ack)
+ *   - Software triggering (ORed with hw line)
+ * - 2 per-CPU IPIs (meant as "self" and "other", but they are interchangeable if not symmetric)
+ * - Automatic prioritization (single event/ack register per CPU, lower IRQs = higher priority)
+ * - Automatic masking on ack
+ * - Default "this CPU" register view and explicit per-CPU views
+ *
+ * In addition, this driver also handles FIQs, as these are routed to the same IRQ vector. These
+ * are used for Fast IPIs (TODO) and the ARMv8 timer IRQs.
+ *
+ * Implementation notes:
+ *
+ * - This driver creates one IRQ domain for HW IRQs and the timer FIQs
+ * - FIQ hwirq numbers are assigned after true hwirqs, and are per-cpu
+ * - DT bindings use 3-cell form (like GIC):
+ *   - <0 nr flags> - hwirq #nr
+ *   - <1 nr flags> - FIQ #nr
+ *     - nr=0  physical timer
+ *     - nr=1  virtual timer
+ *   - <2 nr flags> - IPI #nr
+ *     - nr=0  other IPI
+ *     - nr=1  self IPI
+ *
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/io.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <asm/exception.h>
+
+#include <dt-bindings/interrupt-controller/apple-aic.h>
+
+#define AIC_INFO		0x0004
+#define AIC_INFO_NR_HW(i)	((i) & 0x0000ffff)
+
+#define AIC_CONFIG		0x0010
+
+#define AIC_WHOAMI		0x2000
+#define AIC_EVENT		0x2004
+
+#define AIC_EVENT_TYPE_HW	1
+#define AIC_EVENT_TYPE_IPI	4
+#define AIC_EVENT_IPI_OTHER	1
+#define AIC_EVENT_IPI_SELF	2
+
+#define AIC_IPI_SEND		0x2008
+#define AIC_IPI_ACK		0x200c
+#define AIC_IPI_MASK_SET	0x2024
+#define AIC_IPI_MASK_CLR	0x2028
+
+#define AIC_IPI_SEND_CPU(cpu)	BIT(cpu)
+
+#define AIC_IPI_OTHER		BIT(0)
+#define AIC_IPI_SELF		BIT(31)
+
+#define AIC_TARGET_CPU		0x3000
+#define AIC_SW_SET		0x4000
+#define AIC_SW_CLR		0x4080
+#define AIC_MASK_SET		0x4100
+#define AIC_MASK_CLR		0x4180
+
+#define AIC_CPU_IPI_SET(cpu)	(0x5008 + (cpu << 7))
+#define AIC_CPU_IPI_CLR(cpu)	(0x500c + (cpu << 7))
+#define AIC_CPU_IPI_MASK_SET(cpu) (0x5024 + (cpu << 7))
+#define AIC_CPU_IPI_MASK_CLR(cpu) (0x5028 + (cpu << 7))
+
+#define MASK_REG(x)		(4 * ((x) >> 5))
+#define MASK_BIT(x)		BIT((x) & 0x1f)
+
+#define AIC_NR_FIQ		2
+#define AIC_NR_IPI		2
+
+/*
+ * Max 31 bits in IPI SEND register (top bit is self).
+ * >=32-core chips will need code changes anyway.
+ */
+#define AIC_MAX_CPUS 31
+
+struct aic_irq_chip {
+	void __iomem *base;
+	struct irq_domain *hw_domain;
+	int nr_hw;
+};
+
+static struct aic_irq_chip *aic_irqc;
+
+static inline u32 aic_ic_read(struct aic_irq_chip *ic, u32 reg)
+{
+	return readl(ic->base + reg);
+}
+
+static inline void aic_ic_write(struct aic_irq_chip *ic, u32 reg, u32 val)
+{
+	writel(val, ic->base + reg);
+}
+
+/* These functions do nothing for FIQs, because they have no masks */
+static void aic_irq_mask(struct irq_data *d)
+{
+	struct aic_irq_chip *ic = irq_data_get_irq_chip_data(d);
+
+	if (d->hwirq < ic->nr_hw)
+		aic_ic_write(ic, AIC_MASK_SET + MASK_REG(d->hwirq),
+			     MASK_BIT(d->hwirq));
+}
+
+static void aic_irq_unmask(struct irq_data *d)
+{
+	struct aic_irq_chip *ic = irq_data_get_irq_chip_data(d);
+
+	if (d->hwirq < ic->nr_hw)
+		aic_ic_write(ic, AIC_MASK_CLR + MASK_REG(d->hwirq),
+			     MASK_BIT(d->hwirq));
+}
+
+static void aic_irq_eoi(struct irq_data *d)
+{
+	/*
+	 * Reading the interrupt reason automatically acknowledges and masks
+	 * the IRQ, so we just unmask it here if needed.
+	 */
+	if (!irqd_irq_disabled(d) && !irqd_irq_masked(d))
+		aic_irq_unmask(d);
+}
+
+static void aic_handle_irq(struct pt_regs *regs)
+{
+	struct aic_irq_chip *ic = aic_irqc;
+	u32 event = aic_ic_read(ic, AIC_EVENT);
+
+	while (event) {
+		u32 type = event >> 16, irq = event & 0xffff;
+
+		/* AIC_EVENT is read-sensitive, ensure it happens before we proceed */
+		isb();
+
+		if (type == AIC_EVENT_TYPE_HW) {
+			handle_domain_irq(aic_irqc->hw_domain, irq, regs);
+		} else if (type == AIC_EVENT_TYPE_IPI) {
+			handle_domain_irq(aic_irqc->hw_domain,
+					  ic->nr_hw + AIC_NR_FIQ + irq - 1, regs);
+		} else {
+			pr_err("spurious IRQ event %d, %d\n", type, irq);
+		}
+
+		event = aic_ic_read(ic, AIC_EVENT);
+	}
+}
+
+#define TIMER_FIRING(x)                                                        \
+	(((x) & (ARCH_TIMER_CTRL_ENABLE | ARCH_TIMER_CTRL_IT_MASK |            \
+		 ARCH_TIMER_CTRL_IT_STAT)) ==                                  \
+	 (ARCH_TIMER_CTRL_ENABLE | ARCH_TIMER_CTRL_IT_STAT))
+
+static void aic_handle_fiq(struct pt_regs *regs)
+{
+	/*
+	 * It would be really nice to find a system register that lets us get the FIQ source
+	 * state without having to peek down into clients...
+	 */
+	if (TIMER_FIRING(read_sysreg(cntp_ctl_el0))) {
+		handle_domain_irq(aic_irqc->hw_domain,
+				  aic_irqc->nr_hw + AIC_TMR_PHYS, regs);
+	}
+
+	if (TIMER_FIRING(read_sysreg(cntv_ctl_el0))) {
+		handle_domain_irq(aic_irqc->hw_domain,
+				  aic_irqc->nr_hw + AIC_TMR_VIRT, regs);
+	}
+}
+
+static void __exception_irq_entry aic_handle_irq_or_fiq(struct pt_regs *regs)
+{
+	u64 isr = read_sysreg(isr_el1);
+
+	if (isr & PSR_F_BIT)
+		aic_handle_fiq(regs);
+
+	if (isr & PSR_I_BIT)
+		aic_handle_irq(regs);
+}
+
+static struct irq_chip aic_chip = {
+	.name = "AIC",
+	.irq_mask = aic_irq_mask,
+	.irq_unmask = aic_irq_unmask,
+	.irq_eoi = aic_irq_eoi,
+};
+
+static int aic_irq_domain_map(struct irq_domain *id, unsigned int irq,
+			      irq_hw_number_t hw)
+{
+	struct aic_irq_chip *ic = id->host_data;
+
+	irq_set_chip_data(irq, ic);
+	if (hw < ic->nr_hw) {
+		irq_set_chip_and_handler(irq, &aic_chip, handle_fasteoi_irq);
+	} else {
+		irq_set_percpu_devid(irq);
+		irq_set_chip_and_handler(irq, &aic_chip,
+					 handle_percpu_devid_irq);
+	}
+	irq_set_status_flags(irq, IRQ_LEVEL);
+	irq_set_noprobe(irq);
+
+	return 0;
+}
+
+static void aic_irq_domain_unmap(struct irq_domain *id, unsigned int irq)
+{
+	irq_set_chip_and_handler(irq, NULL, NULL);
+}
+
+static int aic_irq_domain_xlate(struct irq_domain *id,
+				struct device_node *ctrlr, const u32 *intspec,
+				unsigned int intsize,
+				irq_hw_number_t *out_hwirq,
+				unsigned int *out_type)
+{
+	struct aic_irq_chip *ic = id->host_data;
+
+	if (intsize != 3)
+		return -EINVAL;
+
+	if (intspec[0] == AIC_IRQ && intspec[1] < ic->nr_hw)
+		*out_hwirq = intspec[1];
+	else if (intspec[0] == AIC_FIQ && intspec[1] < AIC_NR_FIQ)
+		*out_hwirq = ic->nr_hw + intspec[1];
+	else if (intspec[0] == AIC_IPI && intspec[1] < AIC_NR_IPI)
+		*out_hwirq = ic->nr_hw + AIC_NR_FIQ + intspec[1];
+	else
+		return -EINVAL;
+
+	*out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
+
+	return 0;
+}
+
+static const struct irq_domain_ops aic_irq_domain_ops = {
+	.map = aic_irq_domain_map,
+	.unmap = aic_irq_domain_unmap,
+	.xlate = aic_irq_domain_xlate,
+};
+
+static int __init aic_of_ic_init(struct device_node *node,
+				 struct device_node *parent)
+{
+	int i;
+	void __iomem *regs;
+	u32 info;
+	struct aic_irq_chip *irqc;
+
+	regs = of_iomap(node, 0);
+	if (WARN_ON(!regs))
+		return -EIO;
+
+	irqc = kzalloc(sizeof(*irqc), GFP_KERNEL);
+	if (!irqc)
+		return -ENOMEM;
+
+	aic_irqc = irqc;
+	irqc->base = regs;
+
+	info = aic_ic_read(irqc, AIC_INFO);
+	irqc->nr_hw = AIC_INFO_NR_HW(info);
+
+	irqc->hw_domain =
+		irq_domain_add_linear(node,
+				      irqc->nr_hw + AIC_NR_FIQ + AIC_NR_IPI,
+				      &aic_irq_domain_ops, irqc);
+	if (WARN_ON(!irqc->hw_domain)) {
+		iounmap(irqc->base);
+		kfree(irqc);
+		return -ENODEV;
+	}
+
+	irq_domain_update_bus_token(irqc->hw_domain, DOMAIN_BUS_WIRED);
+
+	set_handle_irq(aic_handle_irq_or_fiq);
+
+	for (i = 0; i < BITS_TO_LONGS(irqc->nr_hw); i++)
+		aic_ic_write(irqc, AIC_MASK_SET + i * 4, ~0);
+	for (i = 0; i < BITS_TO_LONGS(irqc->nr_hw); i++)
+		aic_ic_write(irqc, AIC_SW_CLR + i * 4, ~0);
+	for (i = 0; i < irqc->nr_hw; i++)
+		aic_ic_write(irqc, AIC_TARGET_CPU + i * 4, 1);
+
+	pr_info("AIC: initialized with %d IRQs, %d FIQs, %d IPIs\n",
+		irqc->nr_hw, AIC_NR_FIQ, AIC_NR_IPI);
+
+	return 0;
+}
+
+IRQCHIP_DECLARE(apple_m1_aic, "AAPL,aic", aic_of_ic_init);
-- 
2.30.0


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

* [PATCH 16/18] irqchip/apple-aic: Add SMP / IPI support
  2021-02-04 20:39 [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin
                   ` (14 preceding siblings ...)
  2021-02-04 20:39 ` [PATCH 15/18] irqchip/apple-aic: Add support for the Apple Interrupt Controller Hector Martin
@ 2021-02-04 20:39 ` Hector Martin
  2021-02-04 20:39 ` [PATCH 17/18] dt-bindings: display: add AAPL,simple-framebuffer Hector Martin
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-04 20:39 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

Since the hardware IRQ controller only supports two IPIs per CPU and
Linux needs more, we implement 32 virtual IPIs using software and funnel
them through a single hardware IPI.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 drivers/irqchip/irq-apple-aic.c | 195 +++++++++++++++++++++++++++++++-
 1 file changed, 190 insertions(+), 5 deletions(-)

diff --git a/drivers/irqchip/irq-apple-aic.c b/drivers/irqchip/irq-apple-aic.c
index 533e3ce9f432..daeffcca67ca 100644
--- a/drivers/irqchip/irq-apple-aic.c
+++ b/drivers/irqchip/irq-apple-aic.c
@@ -26,7 +26,9 @@
  *
  * Implementation notes:
  *
- * - This driver creates one IRQ domain for HW IRQs and the timer FIQs
+ * - This driver creates two IRQ domains, one for HW IRQs and the timer FIQs, and one for IPIs
+ * - Since Linux needs more than 2 IPIs, we implement a software IRQ controller and funnel all IPIs
+ *   into one per-CPU IPI (the second "self" IPI is unused).
  * - FIQ hwirq numbers are assigned after true hwirqs, and are per-cpu
  * - DT bindings use 3-cell form (like GIC):
  *   - <0 nr flags> - hwirq #nr
@@ -34,8 +36,8 @@
  *     - nr=0  physical timer
  *     - nr=1  virtual timer
  *   - <2 nr flags> - IPI #nr
- *     - nr=0  other IPI
- *     - nr=1  self IPI
+ *     - nr=0  other IPI (used internally for the virtual IPIs)
+ *     - nr=1  self IPI (unused)
  *
  */
 
@@ -91,6 +93,7 @@
 
 #define AIC_NR_FIQ		2
 #define AIC_NR_IPI		2
+#define AIC_NR_SWIPI		32
 
 /*
  * Max 31 bits in IPI SEND register (top bit is self).
@@ -101,9 +104,14 @@
 struct aic_irq_chip {
 	void __iomem *base;
 	struct irq_domain *hw_domain;
+	struct irq_domain *ipi_domain;
 	int nr_hw;
+	int ipi_hwirq;
 };
 
+atomic_t aic_vipi_flag[AIC_MAX_CPUS];
+atomic_t aic_vipi_mask[AIC_MAX_CPUS];
+
 static struct aic_irq_chip *aic_irqc;
 
 static inline u32 aic_ic_read(struct aic_irq_chip *ic, u32 reg)
@@ -159,6 +167,11 @@ static void aic_handle_irq(struct pt_regs *regs)
 		if (type == AIC_EVENT_TYPE_HW) {
 			handle_domain_irq(aic_irqc->hw_domain, irq, regs);
 		} else if (type == AIC_EVENT_TYPE_IPI) {
+			/*
+			 * Ensure loads from normal memory are ordered with respect to the wmb()
+			 * in aic_ipi_send_mask().
+			 */
+			rmb();
 			handle_domain_irq(aic_irqc->hw_domain,
 					  ic->nr_hw + AIC_NR_FIQ + irq - 1, regs);
 		} else {
@@ -202,11 +215,33 @@ static void __exception_irq_entry aic_handle_irq_or_fiq(struct pt_regs *regs)
 		aic_handle_irq(regs);
 }
 
+static int aic_irq_set_affinity(struct irq_data *d,
+				const struct cpumask *mask_val, bool force)
+{
+	irq_hw_number_t hwirq = irqd_to_hwirq(d);
+	struct aic_irq_chip *ic = irq_data_get_irq_chip_data(d);
+	int cpu;
+
+	if (hwirq > ic->nr_hw)
+		return -EINVAL;
+
+	if (force)
+		cpu = cpumask_first(mask_val);
+	else
+		cpu = cpumask_any_and(mask_val, cpu_online_mask);
+
+	aic_ic_write(ic, AIC_TARGET_CPU + hwirq * 4, BIT(cpu));
+	irq_data_update_effective_affinity(d, cpumask_of(cpu));
+
+	return IRQ_SET_MASK_OK;
+}
+
 static struct irq_chip aic_chip = {
 	.name = "AIC",
 	.irq_mask = aic_irq_mask,
 	.irq_unmask = aic_irq_unmask,
 	.irq_eoi = aic_irq_eoi,
+	.irq_set_affinity = aic_irq_set_affinity,
 };
 
 static int aic_irq_domain_map(struct irq_domain *id, unsigned int irq,
@@ -264,6 +299,149 @@ static const struct irq_domain_ops aic_irq_domain_ops = {
 	.xlate = aic_irq_domain_xlate,
 };
 
+static void aic_ipi_mask(struct irq_data *d)
+{
+	struct aic_irq_chip *ic = irq_data_get_irq_chip_data(d);
+	u32 irq_bit = BIT(irqd_to_hwirq(d));
+	int this_cpu = smp_processor_id();
+
+	atomic_and(~irq_bit, &aic_vipi_mask[this_cpu]);
+
+	if (!atomic_read(&aic_vipi_mask[this_cpu]))
+		aic_ic_write(ic, AIC_IPI_MASK_SET, AIC_IPI_OTHER);
+}
+
+static void aic_ipi_unmask(struct irq_data *d)
+{
+	struct aic_irq_chip *ic = irq_data_get_irq_chip_data(d);
+	u32 irq_bit = BIT(irqd_to_hwirq(d));
+	int this_cpu = smp_processor_id();
+
+	/* Make sure the kernel's idea of logical CPU order is the same as AIC's */
+	WARN_ON(aic_ic_read(ic, AIC_WHOAMI) != this_cpu);
+
+	atomic_or(irq_bit, &aic_vipi_mask[this_cpu]);
+
+	aic_ic_write(ic, AIC_IPI_MASK_CLR, AIC_IPI_OTHER);
+}
+
+static void aic_ipi_send_mask(struct irq_data *d, const struct cpumask *mask)
+{
+	struct aic_irq_chip *ic = irq_data_get_irq_chip_data(d);
+	u32 irq_bit = BIT(irqd_to_hwirq(d));
+	u32 send = 0;
+	int cpu;
+
+	for_each_cpu(cpu, mask) {
+		if (atomic_read(&aic_vipi_mask[cpu]) & irq_bit) {
+			atomic_or(irq_bit, &aic_vipi_flag[cpu]);
+			send |= AIC_IPI_SEND_CPU(cpu);
+		}
+	}
+
+	if (send) {
+		/*
+		 * Ensure that stores to Normal memory are visible to the
+		 * other CPUs before issuing the IPI.
+		 */
+		wmb();
+		aic_ic_write(ic, AIC_IPI_SEND, send);
+	}
+}
+
+static struct irq_chip ipi_chip = {
+	.name = "AIC-IPI",
+	.irq_mask = aic_ipi_mask,
+	.irq_unmask = aic_ipi_unmask,
+	.ipi_send_mask = aic_ipi_send_mask,
+};
+
+static void aic_handle_ipi(struct irq_desc *desc)
+{
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	int this_cpu = smp_processor_id();
+	int i;
+	unsigned long firing;
+
+	chained_irq_enter(chip, desc);
+	aic_ic_write(aic_irqc, AIC_IPI_ACK, AIC_IPI_OTHER);
+
+	firing = atomic_xchg(&aic_vipi_flag[this_cpu], 0);
+
+	for_each_set_bit(i, &firing, AIC_NR_SWIPI) {
+		generic_handle_irq(irq_find_mapping(aic_irqc->ipi_domain, i));
+	}
+
+	aic_ic_write(aic_irqc, AIC_IPI_MASK_CLR, AIC_IPI_OTHER);
+	chained_irq_exit(chip, desc);
+}
+
+static int aic_ipi_alloc(struct irq_domain *d, unsigned int virq,
+			 unsigned int nr_irqs, void *args)
+{
+	int i;
+
+	for (i = 0; i < nr_irqs; i++) {
+		irq_set_percpu_devid(virq + i);
+		irq_domain_set_info(d, virq + i, i, &ipi_chip, d->host_data,
+				    handle_percpu_devid_irq, NULL, NULL);
+	}
+
+	return 0;
+}
+
+static void aic_ipi_free(struct irq_domain *d, unsigned int virq,
+			 unsigned int nr_irqs)
+{
+	/* Not freeing IPIs */
+}
+
+static const struct irq_domain_ops aic_ipi_domain_ops = {
+	.alloc = aic_ipi_alloc,
+	.free = aic_ipi_free,
+};
+
+static int aic_init_smp(struct aic_irq_chip *irqc, struct device_node *node)
+{
+	struct irq_fwspec ipi_fwspec = {
+		.fwnode         = irqc->hw_domain->fwnode,
+		.param_count    = 3,
+		.param          = {
+			[0]     = AIC_IPI,
+			[1]     = 0,
+			[2]     = 0,
+		},
+	};
+	int base_ipi, mux_irq;
+
+	mux_irq = irq_create_fwspec_mapping(&ipi_fwspec);
+	if (WARN_ON(mux_irq <= 0))
+		return -ENODEV;
+
+	irqc->ipi_domain =
+		irq_domain_create_linear(irqc->hw_domain->fwnode, AIC_NR_SWIPI,
+					 &aic_ipi_domain_ops, irqc);
+	if (WARN_ON(!irqc->ipi_domain))
+		return -ENODEV;
+
+	irqc->ipi_domain->flags |= IRQ_DOMAIN_FLAG_IPI_SINGLE;
+	irq_domain_update_bus_token(irqc->ipi_domain, DOMAIN_BUS_IPI);
+
+	base_ipi = __irq_domain_alloc_irqs(irqc->ipi_domain, -1, AIC_NR_SWIPI,
+					   NUMA_NO_NODE, NULL, false, NULL);
+
+	if (WARN_ON(!base_ipi)) {
+		irq_domain_remove(irqc->ipi_domain);
+		return -ENODEV;
+	}
+
+	set_smp_ipi_range(base_ipi, AIC_NR_SWIPI);
+
+	irq_set_chained_handler_and_data(mux_irq, aic_handle_ipi, NULL);
+
+	return 0;
+}
+
 static int __init aic_of_ic_init(struct device_node *node,
 				 struct device_node *parent)
 {
@@ -298,6 +476,13 @@ static int __init aic_of_ic_init(struct device_node *node,
 
 	irq_domain_update_bus_token(irqc->hw_domain, DOMAIN_BUS_WIRED);
 
+	if (aic_init_smp(irqc, node)) {
+		irq_domain_remove(irqc->hw_domain);
+		iounmap(irqc->base);
+		kfree(irqc);
+		return -ENODEV;
+	}
+
 	set_handle_irq(aic_handle_irq_or_fiq);
 
 	for (i = 0; i < BITS_TO_LONGS(irqc->nr_hw); i++)
@@ -307,8 +492,8 @@ static int __init aic_of_ic_init(struct device_node *node,
 	for (i = 0; i < irqc->nr_hw; i++)
 		aic_ic_write(irqc, AIC_TARGET_CPU + i * 4, 1);
 
-	pr_info("AIC: initialized with %d IRQs, %d FIQs, %d IPIs\n",
-		irqc->nr_hw, AIC_NR_FIQ, AIC_NR_IPI);
+	pr_info("AIC: initialized with %d IRQs, %d FIQs, %d IPIs, %d vIPIs\n",
+		irqc->nr_hw, AIC_NR_FIQ, AIC_NR_IPI, AIC_NR_SWIPI);
 
 	return 0;
 }
-- 
2.30.0


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

* [PATCH 17/18] dt-bindings: display: add AAPL,simple-framebuffer
  2021-02-04 20:39 [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin
                   ` (15 preceding siblings ...)
  2021-02-04 20:39 ` [PATCH 16/18] irqchip/apple-aic: Add SMP / IPI support Hector Martin
@ 2021-02-04 20:39 ` Hector Martin
  2021-02-04 20:39 ` [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree Hector Martin
  2021-02-05 11:35 ` [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin 'marcan'
  18 siblings, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-04 20:39 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

Apple SoCs run firmware that sets up a simplefb-compatible framebuffer
for us. Add a compatible for it, and two missing supported formats.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 .../devicetree/bindings/display/simple-framebuffer.yaml      | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/simple-framebuffer.yaml b/Documentation/devicetree/bindings/display/simple-framebuffer.yaml
index eaf8c54fcf50..941c10f40ae5 100644
--- a/Documentation/devicetree/bindings/display/simple-framebuffer.yaml
+++ b/Documentation/devicetree/bindings/display/simple-framebuffer.yaml
@@ -54,6 +54,7 @@ properties:
   compatible:
     items:
       - enum:
+          - AAPL,simple-framebuffer
           - allwinner,simple-framebuffer
           - amlogic,simple-framebuffer
       - const: simple-framebuffer
@@ -84,9 +85,13 @@ properties:
       Format of the framebuffer:
         * `a8b8g8r8` - 32-bit pixels, d[31:24]=a, d[23:16]=b, d[15:8]=g, d[7:0]=r
         * `r5g6b5` - 16-bit pixels, d[15:11]=r, d[10:5]=g, d[4:0]=b
+        * `x8r8g8b8` - 32-bit pixels, d[23:16]=r, d[15:8]=g, d[7:0]=b
+        * `x2r10g10b10` - 32-bit pixels, d[29:20]=r, d[19:10]=g, d[9:0]=b
     enum:
       - a8b8g8r8
       - r5g6b5
+      - x8r8g8b8
+      - x2r10g10b10
 
   display:
     $ref: /schemas/types.yaml#/definitions/phandle
-- 
2.30.0


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

* [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
  2021-02-04 20:39 [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin
                   ` (16 preceding siblings ...)
  2021-02-04 20:39 ` [PATCH 17/18] dt-bindings: display: add AAPL,simple-framebuffer Hector Martin
@ 2021-02-04 20:39 ` Hector Martin
       [not found]   ` <CAK8P3a3v6emxavbyjFhY+WdvH1t4EPMZSjEsSx0M+cRqjRCO1g@mail.gmail.com>
                     ` (2 more replies)
  2021-02-05 11:35 ` [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin 'marcan'
  18 siblings, 3 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-04 20:39 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

This currently supports:

* SMP (via spin-tables)
* AIC IRQs
* Serial (with earlycon)
* Framebuffer

A number of properties are dynamic, and based on system firmware
decisions that vary from version to version. These are expected
to be filled in by the loader.

Signed-off-by: Hector Martin <marcan@marcan.st>
---
 MAINTAINERS                              |   1 +
 arch/arm64/boot/dts/Makefile             |   1 +
 arch/arm64/boot/dts/apple/Makefile       |   2 +
 arch/arm64/boot/dts/apple/apple-j274.dts | 143 +++++++++++++++++++++++
 4 files changed, 147 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/Makefile
 create mode 100644 arch/arm64/boot/dts/apple/apple-j274.dts

diff --git a/MAINTAINERS b/MAINTAINERS
index 3a54ee5747d3..5481b5bc2ef7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1635,6 +1635,7 @@ C:	irc://chat.freenode.net/asahi-dev
 T:	git https://github.com/AsahiLinux/linux.git
 F:	Documentation/devicetree/bindings/arm/AAPL.yaml
 F:	Documentation/devicetree/bindings/interrupt-controller/AAPL,aic.yaml
+F:	arch/arm64/boot/dts/AAPL/
 F:	drivers/irqchip/irq-apple-aic.c
 F:	include/dt-bindings/interrupt-controller/apple-aic.h
 
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index 9b1170658d60..64f055d94948 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -6,6 +6,7 @@ subdir-y += amazon
 subdir-y += amd
 subdir-y += amlogic
 subdir-y += apm
+subdir-y += apple
 subdir-y += arm
 subdir-y += bitmain
 subdir-y += broadcom
diff --git a/arch/arm64/boot/dts/apple/Makefile b/arch/arm64/boot/dts/apple/Makefile
new file mode 100644
index 000000000000..ec03c474efd4
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_APPLE) += apple-j274.dtb
diff --git a/arch/arm64/boot/dts/apple/apple-j274.dts b/arch/arm64/boot/dts/apple/apple-j274.dts
new file mode 100644
index 000000000000..238a1bcee066
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/apple-j274.dts
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 Hector Martin <marcan@marcan.st>
+ */
+
+/dts-v1/;
+#include <dt-bindings/interrupt-controller/apple-aic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+	model = "Apple Mac Mini M1 2020";
+	compatible = "AAPL,j274", "AAPL,m1", "AAPL,arm-platform";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	chosen {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		bootargs = "earlycon";
+		stdout-path = "serial0:1500000";
+
+		framebuffer0: framebuffer@0 {
+			compatible = "AAPL,simple-framebuffer", "simple-framebuffer";
+			reg = <0 0 0 0>; // To be filled by loader
+			// Format properties will be added by loader
+			status = "disabled";
+		};
+	};
+
+	memory@800000000 {
+		device_type = "memory";
+		reg = <0 0 0 0>; // To be filled by loader
+	};
+
+	aliases {
+		serial0 = &serial0;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			compatible = "AAPL,icestorm";
+			device_type = "cpu";
+			reg = <0x0 0x0>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0 0>; // To be filled by loader
+		};
+		cpu1: cpu@1 {
+			compatible = "AAPL,icestorm";
+			device_type = "cpu";
+			reg = <0x0 0x1>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0 0>; // To be filled by loader
+		};
+		cpu2: cpu@2 {
+			compatible = "AAPL,icestorm";
+			device_type = "cpu";
+			reg = <0x0 0x2>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0 0>; // To be filled by loader
+		};
+		cpu3: cpu@3 {
+			compatible = "AAPL,icestorm";
+			device_type = "cpu";
+			reg = <0x0 0x3>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0 0>; // To be filled by loader
+		};
+		cpu4: cpu@10100 {
+			compatible = "AAPL,firestorm";
+			device_type = "cpu";
+			reg = <0x0 0x10100>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0 0>; // To be filled by loader
+		};
+		cpu5: cpu@10101 {
+			compatible = "AAPL,firestorm";
+			device_type = "cpu";
+			reg = <0x0 0x10101>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0 0>; // To be filled by loader
+		};
+		cpu6: cpu@10102 {
+			compatible = "AAPL,firestorm";
+			device_type = "cpu";
+			reg = <0x0 0x10102>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0 0>; // To be filled by loader
+		};
+		cpu7: cpu@10103 {
+			compatible = "AAPL,firestorm";
+			device_type = "cpu";
+			reg = <0x0 0x10103>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0 0>; // To be filled by loader
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&aic>;
+		interrupts = <AIC_FIQ 0 IRQ_TYPE_LEVEL_HIGH>,
+				<AIC_FIQ 0 IRQ_TYPE_LEVEL_HIGH>,
+				<AIC_FIQ 1 IRQ_TYPE_LEVEL_HIGH>,
+				<AIC_FIQ 0 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	clk24: clk24 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "clk24";
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		aic: interrupt-controller@23b100000 {
+			compatible = "AAPL,m1-aic", "AAPL,aic";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg = <0x2 0x3b100000 0x0 0x8000>;
+		};
+
+		serial0: serial@235200000 {
+			compatible = "AAPL,s5l-uart";
+			reg = <0x2 0x35200000 0x0 0x1000>;
+			reg-io-width = <4>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 605 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk24>, <&clk24>;
+			clock-names = "uart", "clk_uart_baud0";
+		};
+
+	};
+};
-- 
2.30.0


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

* Re: [PATCH 07/18] tty: serial: samsung_tty: enable for ARCH_APPLE
       [not found]   ` <CAK8P3a1n+C5V5J24myy_h67DVp2YTN5Hd=tCWjPUYZcrAX4hCg@mail.gmail.com>
@ 2021-02-04 21:27     ` Hector Martin 'marcan'
  0 siblings, 0 replies; 82+ messages in thread
From: Hector Martin 'marcan' @ 2021-02-04 21:27 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: SoC Team, Linux ARM, Marc Zyngier, Rob Herring, linux-kernel,
	DTML, Olof Johansson

On 05/02/2021 06.16, Arnd Bergmann wrote:
> On Thu, Feb 4, 2021 at 9:39 PM Hector Martin <marcan@marcan.st> wrote:
> 
>>
>>   config SERIAL_SAMSUNG
>>          tristate "Samsung SoC serial support"
>> -       depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
>> +       depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST || ARCH_APPLE
> 
> By convention, please keep "|| COMPILE_TEST" last in the list.

Ack, good catch! Fixed for v2.

-- 
Hector Martin "marcan" (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
       [not found]   ` <CAK8P3a3v6emxavbyjFhY+WdvH1t4EPMZSjEsSx0M+cRqjRCO1g@mail.gmail.com>
@ 2021-02-04 21:44     ` Hector Martin 'marcan'
       [not found]       ` <CAK8P3a2DawQA-PD5aqbkVPB7UxuohN0oe9mJPe8488pUryotJQ@mail.gmail.com>
  0 siblings, 1 reply; 82+ messages in thread
From: Hector Martin 'marcan' @ 2021-02-04 21:44 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: SoC Team, Linux ARM, Marc Zyngier, Rob Herring, linux-kernel,
	DTML, Olof Johansson, Ard Biesheuvel

On 05/02/2021 06.29, Arnd Bergmann wrote:
> On Thu, Feb 4, 2021 at 9:39 PM Hector Martin <marcan@marcan.st> wrote:
> 
>> +/ {
>> +       model = "Apple Mac Mini M1 2020";
>> +       compatible = "AAPL,j274", "AAPL,m1", "AAPL,arm-platform";
>> +       #address-cells = <2>;
>> +       #size-cells = <2>;
>> +
>> +       chosen {
>> +               #address-cells = <2>;
>> +               #size-cells = <2>;
>> +               ranges;
>> +
>> +               bootargs = "earlycon";
>> +               stdout-path = "serial0:1500000";
>> +
>> +               framebuffer0: framebuffer@0 {
>> +                       compatible = "AAPL,simple-framebuffer", "simple-framebuffer";
>> +                       reg = <0 0 0 0>; // To be filled by loader
>> +                       // Format properties will be added by loader
>> +                       status = "disabled";
>> +               };
>> +       };
>> +
>> +       memory@800000000 {
>> +               device_type = "memory";
>> +               reg = <0 0 0 0>; // To be filled by loader
>> +       };
>> +
>> +       aliases {
>> +               serial0 = &serial0;
>> +       };
> 
> We tend to split the dts file into one file per SoC and one for the
> specific board. I guess in this case the split can be slightly different,
> but it does feel better to be prepared for sharing a lot of the contents
> between the different products.
> 
> In most cases, you'd want the 'aliases' and 'chosen' nodes to be
> in the board specific file.

I thought about that, but wasn't sure if splitting it up at this early 
stage made much sense since I'm not sure what the split should be, given 
all supported hardware is the same for all 3 released devices.

I'm happy to throw the aliases/chosen nodes into board specific files if 
you think that's a good starting point. Perhaps /memory too? Those 
properties are filled in/patched by the bootloader anyway...

There are also DT overlays; I was wondering if we could use those to 
keep the hierarchy and avoid having many duplicate trees in a 
hypothetical bootloader that embeds support for a large set of hardware, 
having it construct the final devicetree on the fly from SoC + a board 
overlay (and possibly further levels); but I'm not sure how that ties in 
with the device trees that live in the Linux tree. Do you have any 
pointers about this?

For reference, this is our current DT patching code in m1n1:

https://github.com/AsahiLinux/m1n1/blob/main/src/kboot.c

Eventually we're going to build some kind of tooling to automate diffing 
Apple device trees and importing changes/new devices into our own, 
though it will probably be quite a while until that is relevant; at this 
stage hand-maintaining them is perfectly fine (in any case this wouldn't 
be fully automated, so in the end our trees will still be organized 
however we want).

>> +       cpus {
>> +               #address-cells = <2>;
>> +               #size-cells = <0>;
>> +
>> +               cpu0: cpu@0 {
>> +                       compatible = "AAPL,icestorm";
>> +                       device_type = "cpu";
>> +                       reg = <0x0 0x0>;
>> +                       enable-method = "spin-table";
>> +                       cpu-release-addr = <0 0>; // To be filled by loader
>> +               };
> 
> Did you see the discussion on the #armlinux channel about the possibility
> of moving the cpu-enable method to PSCI based on a UEFI runtime
> interface?
> 
> There are a few open questions about what that would look like in the
> end, but Ard has come up with a prototype for the kernel side of it
> (obviously untested), which would interface either into the UEFI side
> of u-boot, or a simple already-instantiated version that could be
> kept inside of m1n1 and stay resident in memory.
> 
> I would like to see that model get adopted here eventually. If
> we manage to get the other patches ready for an initial merge in
> v5.12, we can probably start out with spin-table and move to that
> in a following release though.

I saw it go by but need to review it again; I've been missing too much 
sleep this week :) thanks for the reminder.

I think we might want to start with spin-table for now, given that there 
are no kernel changes needed anyway, but I'm happy to take the protoype 
for a spin (:)) and try implementing it in m1n1.

I do think it's valuable for whatever we do, at this stage, to not 
require u-boot; having that be an integral part of the boot chain is 
perfectly fine in the future but right now it helps to have a simple 
boot chain while we work out the early bring-up, and while u-boot grows 
the required support.

-- 
Hector Martin "marcan" (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 15/18] irqchip/apple-aic: Add support for the Apple Interrupt Controller
       [not found]   ` <CAK8P3a1zbLM0s_GwkJ0AJQ8cocS-zcsWWKhOB7B99OtRYyDE7g@mail.gmail.com>
@ 2021-02-04 22:04     ` Hector Martin 'marcan'
       [not found]       ` <CAK8P3a14vsLkCujd_XBAOAjL2h878gxkaoKPpaxL4jddZZcc-A@mail.gmail.com>
  0 siblings, 1 reply; 82+ messages in thread
From: Hector Martin 'marcan' @ 2021-02-04 22:04 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: SoC Team, Linux ARM, Marc Zyngier, Rob Herring, linux-kernel,
	DTML, Olof Johansson

On 05/02/2021 06.37, Arnd Bergmann wrote:
> On Thu, Feb 4, 2021 at 9:39 PM Hector Martin <marcan@marcan.st> wrote:
>> + * - This driver creates one IRQ domain for HW IRQs and the timer FIQs
>> + * - FIQ hwirq numbers are assigned after true hwirqs, and are per-cpu
>> + * - DT bindings use 3-cell form (like GIC):
>> + *   - <0 nr flags> - hwirq #nr
>> + *   - <1 nr flags> - FIQ #nr
>> + *     - nr=0  physical timer
>> + *     - nr=1  virtual timer
>> + *   - <2 nr flags> - IPI #nr
>> + *     - nr=0  other IPI
>> + *     - nr=1  self IPI
> 
> I think we should discuss the binding a bit here. My initial thinking was that
> it would be better to separate the AIC from the FIQ handling, as they don't
> seem to have any relation in hardware, and representing them as two
> separate nodes seems like a cleaner abstraction.

This was actually my original approach (I still have the FIQ irqchip 
patch lying around), but that idea somewhat broke when we decided to 
merge the vectors.

If we split it up again, one of the two still needs to be the root, 
decide whether what fired is an IRQ or FIQ, and dispatch accordingly. Or 
we could have three nodes and have one root handler dispatch to IRQ and 
FIQ nodes, but that sounds like overkill... (?)

Are you proposing just having different drivers/nodes in the same file, 
or implementing these as separate drivers in separate files?

>> +#define TIMER_FIRING(x)                                                        \
>> +       (((x) & (ARCH_TIMER_CTRL_ENABLE | ARCH_TIMER_CTRL_IT_MASK |            \
>> +                ARCH_TIMER_CTRL_IT_STAT)) ==                                  \
>> +        (ARCH_TIMER_CTRL_ENABLE | ARCH_TIMER_CTRL_IT_STAT))
>> +
>> +static void aic_handle_fiq(struct pt_regs *regs)
>> +{
>> +       /*
>> +        * It would be really nice to find a system register that lets us get the FIQ source
>> +        * state without having to peek down into clients...
>> +        */
>> +       if (TIMER_FIRING(read_sysreg(cntp_ctl_el0))) {
>> +               handle_domain_irq(aic_irqc->hw_domain,
>> +                                 aic_irqc->nr_hw + AIC_TMR_PHYS, regs);
>> +       }
>> +
>> +       if (TIMER_FIRING(read_sysreg(cntv_ctl_el0))) {
>> +               handle_domain_irq(aic_irqc->hw_domain,
>> +                                 aic_irqc->nr_hw + AIC_TMR_VIRT, regs);
>> +       }
>> +}
> 
> This seems to be a minor layering violation to me.

Absolutely. Under the assumption that these IRQ lines are ORed together 
into FIQ with no top-level dispatch though, there isn't a great solution 
here...

I think there is a chance FIQ interrupt child bits exist *somewhere*, so 
I actually plan on brute-forcing the list of implemented/valid CPU 
registers and trying to see if I can find some bits that do what I want. 
If it turns out they exist, this could alleviate some of the ugliness of 
the current approach.

> One idea I had was to just keep all the fiq handling in the timer driver
> itself, jumping there directly from the top-level fiq entry whenever
> we are on an Apple platform. At least as long as nothing else ever
> uses fiq.

In principle, as long as the timer handler only ever uses one IRQ (which 
I think is the case here, it just picks one of the 4, usually the 
physical timer, and it should only enable that one) it would work. But 
we still need *some* IRQ chip driver to deliver that, unless we want to 
throw a bunch of special-case code into the timer driver to hook 
directly into FIQs without an interrupt parent which... seems like it 
could get quite messy.

> When we discussed the earlier submission for the aic, I understood
> that FIQ is used for both timer and IPI, but the IPI actually has another
> method based on normal AIC interrupts that can be used as an
> alternative.

Correct, there are two parallel IPI implementations. It is my 
understanding that the CPU register based one, which ties into FIQ, is 
faster / more featureful (it has deferred IPIs, not sure if the plain 
AIC does those), as it is built into the core complexes instead of being 
part of the external AIC block. I could try benchmarking it within m1n1 
and see if I can find out how much faster it is.

I think it's worth thinking about supporting that IPI mechanism, which 
would necessitate dispatching FIQs too, so hard-coding it to route 
straight to the timer doesn't sound like a very future-proof plan... 
consider that Apple might put out a SoC in the future that rips out the 
AIC IPIs and leaves only the FIQ ones too.

>> +static void __exception_irq_entry aic_handle_irq_or_fiq(struct pt_regs *regs)
>> +{
>> +       u64 isr = read_sysreg(isr_el1);
>> +
>> +       if (isr & PSR_F_BIT)
>> +               aic_handle_fiq(regs);
>> +
>> +       if (isr & PSR_I_BIT)
>> +               aic_handle_irq(regs);
>> +}
> 
> Having the shared entry point here looks reasonable to me though, it
> does seem to make a few things easier.
> 
> I wonder if there is a possible race here: if we are ever in a situation
> where one of the two -- fiq or irq -- is disabled while the other one
> is enabled, we could get into a state where a handler is run while
> it should be masked.

That's a good point. We could filter with the SPSR_ELx mask bits here.

Though the FIQ support patch tries pretty hard to keep the mask bits in 
sync after early boot, so this concern might be somewhat academic. I'm 
happy to implement it if you think it might help though.

-- 
Hector Martin "marcan" (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 05/18] tty: serial: samsung_tty: add support for Apple UARTs
  2021-02-04 20:39 ` [PATCH 05/18] tty: serial: samsung_tty: add support for Apple UARTs Hector Martin
@ 2021-02-04 23:55   ` kernel test robot
  2021-02-05  9:44     ` Hector Martin 'marcan'
  2021-02-05  2:19   ` kernel test robot
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 82+ messages in thread
From: kernel test robot @ 2021-02-04 23:55 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: kbuild-all, linux-arm-kernel, Marc Zyngier, robh+dt,
	Arnd Bergmann, linux-kernel, devicetree, Olof Johansson

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

Hi Hector,

I love your patch! Perhaps something to improve:

[auto build test WARNING on arm64/for-next/core]
[also build test WARNING on robh/for-next linus/master v5.11-rc6 next-20210125]
[cannot apply to tip/irq/core]
[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]

url:    https://github.com/0day-ci/linux/commits/Hector-Martin/Apple-M1-SoC-platform-bring-up/20210205-045228
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
config: arm-defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/c3bf64138f141e20577083d30e0542004c194a20
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Hector-Martin/Apple-M1-SoC-platform-bring-up/20210205-045228
        git checkout c3bf64138f141e20577083d30e0542004c194a20
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/tty/serial/samsung_tty.c:60: warning: "NO_IRQ" redefined
      60 | #define NO_IRQ -1
         | 
   In file included from arch/arm/include/asm/hardirq.h:5,
                    from include/linux/hardirq.h:10,
                    from include/linux/interrupt.h:11,
                    from include/linux/serial_core.h:13,
                    from drivers/tty/serial/samsung_tty.c:36:
   arch/arm/include/asm/irq.h:22: note: this is the location of the previous definition
      22 | #define NO_IRQ ((unsigned int)(-1))
         | 
   drivers/tty/serial/samsung_tty.c: In function 's3c24xx_serial_resume_noirq':
   drivers/tty/serial/samsung_tty.c:2309:4: error: a label can only be part of a statement and a declaration is not a statement
    2309 |    unsigned int ucon;
         |    ^~~~~~~~
   drivers/tty/serial/samsung_tty.c:2334:4: error: a label can only be part of a statement and a declaration is not a statement
    2334 |    unsigned int uintm = 0xf;
         |    ^~~~~~~~


vim +/NO_IRQ +60 drivers/tty/serial/samsung_tty.c

    58	
    59	/* IRQ number used when the handler is called in non-IRQ context */
  > 60	#define NO_IRQ -1
    61	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 54180 bytes --]

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

* Re: [PATCH 05/18] tty: serial: samsung_tty: add support for Apple UARTs
  2021-02-04 20:39 ` [PATCH 05/18] tty: serial: samsung_tty: add support for Apple UARTs Hector Martin
  2021-02-04 23:55   ` kernel test robot
@ 2021-02-05  2:19   ` kernel test robot
       [not found]   ` <87lfc1l4lo.wl-maz@kernel.org>
  2021-02-08 10:54   ` Krzysztof Kozlowski
  3 siblings, 0 replies; 82+ messages in thread
From: kernel test robot @ 2021-02-05  2:19 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: kbuild-all, linux-arm-kernel, Marc Zyngier, robh+dt,
	Arnd Bergmann, linux-kernel, devicetree, Olof Johansson

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

Hi Hector,

I love your patch! Yet something to improve:

[auto build test ERROR on arm64/for-next/core]
[also build test ERROR on robh/for-next linus/master v5.11-rc6 next-20210125]
[cannot apply to tip/irq/core]
[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]

url:    https://github.com/0day-ci/linux/commits/Hector-Martin/Apple-M1-SoC-platform-bring-up/20210205-045228
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
config: arm-defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/c3bf64138f141e20577083d30e0542004c194a20
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Hector-Martin/Apple-M1-SoC-platform-bring-up/20210205-045228
        git checkout c3bf64138f141e20577083d30e0542004c194a20
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/tty/serial/samsung_tty.c:60: warning: "NO_IRQ" redefined
      60 | #define NO_IRQ -1
         | 
   In file included from arch/arm/include/asm/hardirq.h:5,
                    from include/linux/hardirq.h:10,
                    from include/linux/interrupt.h:11,
                    from include/linux/serial_core.h:13,
                    from drivers/tty/serial/samsung_tty.c:36:
   arch/arm/include/asm/irq.h:22: note: this is the location of the previous definition
      22 | #define NO_IRQ ((unsigned int)(-1))
         | 
   drivers/tty/serial/samsung_tty.c: In function 's3c24xx_serial_resume_noirq':
>> drivers/tty/serial/samsung_tty.c:2309:4: error: a label can only be part of a statement and a declaration is not a statement
    2309 |    unsigned int ucon;
         |    ^~~~~~~~
   drivers/tty/serial/samsung_tty.c:2334:4: error: a label can only be part of a statement and a declaration is not a statement
    2334 |    unsigned int uintm = 0xf;
         |    ^~~~~~~~


vim +2309 drivers/tty/serial/samsung_tty.c

  2299	
  2300	static int s3c24xx_serial_resume_noirq(struct device *dev)
  2301	{
  2302		struct uart_port *port = s3c24xx_dev_to_port(dev);
  2303		struct s3c24xx_uart_port *ourport = to_ourport(port);
  2304	
  2305		if (port) {
  2306			/* restore IRQ mask */
  2307			switch (s3c24xx_irq_type(port)) {
  2308			case IRQ_APPLE:
> 2309				unsigned int ucon;
  2310	
  2311				clk_prepare_enable(ourport->clk);
  2312				if (!IS_ERR(ourport->baudclk))
  2313					clk_prepare_enable(ourport->baudclk);
  2314	
  2315				ucon = rd_regl(port, S3C2410_UCON);
  2316	
  2317				ucon &= ~(APPLE_UCON_TXTHRESH_ENA_MSK |
  2318					APPLE_UCON_RXTHRESH_ENA_MSK |
  2319					APPLE_UCON_RXTO_ENA_MSK);
  2320	
  2321				if (ourport->tx_enabled)
  2322					ucon |= APPLE_UCON_TXTHRESH_ENA_MSK;
  2323				if (ourport->rx_enabled)
  2324					ucon |= APPLE_UCON_RXTHRESH_ENA_MSK |
  2325						APPLE_UCON_RXTO_ENA_MSK;
  2326	
  2327				wr_regl(port, S3C2410_UCON, ucon);
  2328	
  2329				if (!IS_ERR(ourport->baudclk))
  2330					clk_disable_unprepare(ourport->baudclk);
  2331				clk_disable_unprepare(ourport->clk);
  2332				break;
  2333			case IRQ_S3C6400:
  2334				unsigned int uintm = 0xf;
  2335	
  2336				if (ourport->tx_enabled)
  2337					uintm &= ~S3C64XX_UINTM_TXD_MSK;
  2338				if (ourport->rx_enabled)
  2339					uintm &= ~S3C64XX_UINTM_RXD_MSK;
  2340				clk_prepare_enable(ourport->clk);
  2341				if (!IS_ERR(ourport->baudclk))
  2342					clk_prepare_enable(ourport->baudclk);
  2343				wr_regl(port, S3C64XX_UINTM, uintm);
  2344				if (!IS_ERR(ourport->baudclk))
  2345					clk_disable_unprepare(ourport->baudclk);
  2346				clk_disable_unprepare(ourport->clk);
  2347				break;
  2348			}
  2349		}
  2350	
  2351		return 0;
  2352	}
  2353	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 54180 bytes --]

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

* Re: [PATCH 15/18] irqchip/apple-aic: Add support for the Apple Interrupt Controller
  2021-02-04 20:39 ` [PATCH 15/18] irqchip/apple-aic: Add support for the Apple Interrupt Controller Hector Martin
       [not found]   ` <CAK8P3a1zbLM0s_GwkJ0AJQ8cocS-zcsWWKhOB7B99OtRYyDE7g@mail.gmail.com>
@ 2021-02-05  2:27   ` kernel test robot
  2021-02-05  9:45     ` Hector Martin 'marcan'
       [not found]   ` <87eehqlxlr.wl-maz@kernel.org>
  2 siblings, 1 reply; 82+ messages in thread
From: kernel test robot @ 2021-02-05  2:27 UTC (permalink / raw)
  To: Hector Martin, soc
  Cc: kbuild-all, linux-arm-kernel, Marc Zyngier, robh+dt,
	Arnd Bergmann, linux-kernel, devicetree, Olof Johansson

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

Hi Hector,

I love your patch! Yet something to improve:

[auto build test ERROR on arm64/for-next/core]
[also build test ERROR on robh/for-next linus/master v5.11-rc6 next-20210125]
[cannot apply to tip/irq/core]
[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]

url:    https://github.com/0day-ci/linux/commits/Hector-Martin/Apple-M1-SoC-platform-bring-up/20210205-045228
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
config: arc-allyesconfig (attached as .config)
compiler: arceb-elf-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/01ec72727a358a6f4208bf56808f1ce57a251413
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Hector-Martin/Apple-M1-SoC-platform-bring-up/20210205-045228
        git checkout 01ec72727a358a6f4208bf56808f1ce57a251413
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/irqchip/irq-apple-aic.c:51:10: fatal error: asm/exception.h: No such file or directory
      51 | #include <asm/exception.h>
         |          ^~~~~~~~~~~~~~~~~
   compilation terminated.


vim +51 drivers/irqchip/irq-apple-aic.c

    43	
    44	#include <linux/io.h>
    45	#include <linux/irqchip.h>
    46	#include <linux/irqchip/chained_irq.h>
    47	#include <linux/of_address.h>
    48	#include <linux/of_irq.h>
    49	#include <linux/of_platform.h>
    50	#include <linux/slab.h>
  > 51	#include <asm/exception.h>
    52	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 67254 bytes --]

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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
       [not found]       ` <CAK8P3a2DawQA-PD5aqbkVPB7UxuohN0oe9mJPe8488pUryotJQ@mail.gmail.com>
@ 2021-02-05  7:11         ` Hector Martin 'marcan'
  0 siblings, 0 replies; 82+ messages in thread
From: Hector Martin 'marcan' @ 2021-02-05  7:11 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: SoC Team, Linux ARM, Marc Zyngier, Rob Herring, linux-kernel,
	DTML, Olof Johansson, Ard Biesheuvel

On 05/02/2021 08.08, Arnd Bergmann wrote:
> On Thu, Feb 4, 2021 at 10:44 PM Hector Martin 'marcan' <marcan@marcan.st> wrote:
>> On 05/02/2021 06.29, Arnd Bergmann wrote:
>>> On Thu, Feb 4, 2021 at 9:39 PM Hector Martin <marcan@marcan.st> wrote:
>>>
>>> We tend to split the dts file into one file per SoC and one for the
>>> specific board. I guess in this case the split can be slightly different,
>>> but it does feel better to be prepared for sharing a lot of the contents
>>> between the different products.
>>>
>>> In most cases, you'd want the 'aliases' and 'chosen' nodes to be
>>> in the board specific file.
>>
>> I thought about that, but wasn't sure if splitting it up at this early
>> stage made much sense since I'm not sure what the split should be, given
>> all supported hardware is the same for all 3 released devices.
>>
>> I'm happy to throw the aliases/chosen nodes into board specific files if
>> you think that's a good starting point. Perhaps /memory too? Those
>> properties are filled in/patched by the bootloader anyway...
> 
> Yes, I think that would help make it more consistent with other
> platforms even if we don't care too much here.

Ack, I'll split it up for v2.

> We don't really have overlays in the kernel sources (yet), though it
> is something that keeps coming up. For the moment, I'd just
> assume you can have one .dts file for each thing you want to
> support and keep the shared bits in .dtsi files.

No problem. We'll experiment with overlays in m1n1 and see how that goes.

One thing I wanted to ask: is there some kind of "experimental" policy 
for DT bindings? At early platform bring-up stages it seems like it 
could be valuable to allow for breaking DT changes while we flesh out 
the details (this is especially true of a reverse engineered platform 
like this, where we don't have knowledge of all the hardware details a 
priori). The dozen or so users we might have at this stage obviously 
won't complain too much :)

-- 
Hector Martin "marcan" (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 15/18] irqchip/apple-aic: Add support for the Apple Interrupt Controller
       [not found]       ` <CAK8P3a14vsLkCujd_XBAOAjL2h878gxkaoKPpaxL4jddZZcc-A@mail.gmail.com>
@ 2021-02-05  7:41         ` Hector Martin 'marcan'
  0 siblings, 0 replies; 82+ messages in thread
From: Hector Martin 'marcan' @ 2021-02-05  7:41 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: SoC Team, Linux ARM, Marc Zyngier, Rob Herring, linux-kernel,
	DTML, Olof Johansson

On 05/02/2021 08.04, Arnd Bergmann wrote:
> On Thu, Feb 4, 2021 at 11:06 PM Hector Martin 'marcan' <marcan@marcan.st> wrote:
>> If we split it up again, one of the two still needs to be the root,
>> decide whether what fired is an IRQ or FIQ, and dispatch accordingly. Or
>> we could have three nodes and have one root handler dispatch to IRQ and
>> FIQ nodes, but that sounds like overkill... (?)
> 
> Maybe I'm misreading the low-level entry code, but my impression
> was that the fiq and irq exception vectors could just be pointed to
> two different root drivers from the code in kernel_ventry

Certainly, but we'd have to introduce a fiq handler global and duplicate 
the handler code; this is what was done in the previous submission, but 
I seem to recall someone (Marc?) mentioned it would be cleaner to just 
merge them into the single IRQ path and discriminate in the irqchip, 
which is what I did here.

I can certainly go with either solution; I don't have a strong 
preference here.

Advantages of split path:

* More orthogonal

Advantages of merged path:

* Minimizes common vector changes needed for a single platform
* Keeps FIQ/IRQ code common, so FIQs are less likely to be accidentally 
broken by people not testing on Apple platforms.

Unclear:

* Performance. Split path runs less code, merged path has lower icache 
pressure.

>> Are you proposing just having different drivers/nodes in the same file,
>> or implementing these as separate drivers in separate files?
> 
> I was thinking of separate driver files.

That's what I previously had then :)

If this is the way to go I can certainly go back to that.

> I looked at other architectures, and found that at least powerpc
> and sparc64 have a really minimal timer tick, with their timer_interrupt()
> function getting called directly from the exception vector, and
> doing a minimum of accounting (irq_enter(), statistics, ...) manually.
> 
> It's a different question if we want to do that, or if there should always
> be an irqchip for consistency.

I think the issue here is that those platforms presumably have *one* 
timer hard wired to a specific exception vector (e.g. on PowerPC that's 
the decrementer). So, that setup is shared by all implementations in 
that platform.

But on ARM64, the architectural timer is supposed to go through an 
irqchip (GIC in normal platforms), it's just that here it ended up 
hard-wired to FIQ - though not alone, since fast IPIs are also there, so 
we can't treat it as a strict "timer vector" either.

So even if we could do this for Apple SoCs, it would be a non-standard 
setup, since every other ARM64 platform puts the timer behind an 
irqchip. Therefore, I think it makes sense to always go through an 
irqchip, rather than introduce a bypass for these SoCs.

Also worth noting that we have at least two functional hardware timers 
here (not sure if there are more, we run with HCR_EL2.E2H=1 in m1n1 
which maps the EL2 timer to be the EL1 timer; I'm not yet sure if 
setting that to 0 will expose extra HV timers or not) wired to the same 
FIQ. I confirmed that both the virtual and physical timers function 
independently in m1n1.

I did confirm there are no secure timers, which is expected given that 
there is no EL3 on these chips.

> Benchmarking would at least help understand why there are two.

Well, they call them "Fast IPIs" so *presumably* they are faster, but 
we'll see :)

> I don't think we have to pay too much attention to preparing the
> code design for it, we can always change it when needed. However,
> anything that impacts the DT binding here would have to be designed
> to not get in the way of adding it later.

I think this shouldn't pose much of a problem, since IPIs aren't exposed 
in the DT anyway. As long as we decide how we're handling IRQs vs FIQs 
(one or two nodes/drivers), then either of them could take 
responsibility for handling IPIs depending on the platform. We should 
probably just add a "fast-ipi" property to both nodes on platforms that 
support that, so that the drivers can make the decision based on it. Or 
perhaps that should be done with different compatibles?

-- 
Hector Martin "marcan" (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 05/18] tty: serial: samsung_tty: add support for Apple UARTs
  2021-02-04 23:55   ` kernel test robot
@ 2021-02-05  9:44     ` Hector Martin 'marcan'
  0 siblings, 0 replies; 82+ messages in thread
From: Hector Martin 'marcan' @ 2021-02-05  9:44 UTC (permalink / raw)
  To: soc
  Cc: kbuild-all, linux-arm-kernel, Marc Zyngier, robh+dt,
	Arnd Bergmann, linux-kernel, devicetree, Olof Johansson

On 05/02/2021 08.55, kernel test robot wrote:
>>> drivers/tty/serial/samsung_tty.c:60: warning: "NO_IRQ" redefined
>        60 | #define NO_IRQ -1

Turns out arm (32) defines NO_IRQ. Replaced with NOT_IN_IRQ for v2.

-- 
Hector Martin "marcan" (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 15/18] irqchip/apple-aic: Add support for the Apple Interrupt Controller
  2021-02-05  2:27   ` kernel test robot
@ 2021-02-05  9:45     ` Hector Martin 'marcan'
  0 siblings, 0 replies; 82+ messages in thread
From: Hector Martin 'marcan' @ 2021-02-05  9:45 UTC (permalink / raw)
  To: soc
  Cc: kbuild-all, linux-arm-kernel, Marc Zyngier, robh+dt,
	Arnd Bergmann, linux-kernel, devicetree, Olof Johansson

On 05/02/2021 11.27, kernel test robot wrote:
> config: arc-allyesconfig (attached as .config)

This is never going to build on !ARM64 since it uses ARM64 registers, so 
removing COMPILE_TEST for v2.

-- 
Hector Martin "marcan" (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 00/18] Apple M1 SoC platform bring-up
  2021-02-04 20:39 [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin
                   ` (17 preceding siblings ...)
  2021-02-04 20:39 ` [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree Hector Martin
@ 2021-02-05 11:35 ` Hector Martin 'marcan'
  18 siblings, 0 replies; 82+ messages in thread
From: Hector Martin 'marcan' @ 2021-02-05 11:35 UTC (permalink / raw)
  To: soc
  Cc: linux-arm-kernel, Marc Zyngier, robh, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson, Mohamed Mediouni,
	Stan Skowronek, Alexander Graf, Will Deacon, Linus Walleij,
	Mark Rutland

On 05/02/2021 05.39, Hector Martin wrote:
> This series brings up initial support for the Apple M1 SoC, used in the
> 2020 Mac Mini, MacBook Pro, and MacBook Air models.

Forgot to CC: a few folks involved in the previous related thread, 
sorry! Adding them here, hope everyone got the series via the MLs.

v2 will be CCed to everyone else too.

-- 
Hector Martin "marcan" (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 04/18] arm64: Kconfig: Introduce CONFIG_ARCH_APPLE
       [not found]   ` <87k0rll4i8.wl-maz@kernel.org>
@ 2021-02-07  8:05     ` Hector Martin 'marcan'
  0 siblings, 0 replies; 82+ messages in thread
From: Hector Martin 'marcan' @ 2021-02-07  8:05 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: soc, linux-arm-kernel, robh+dt, Arnd Bergmann, linux-kernel,
	devicetree, Olof Johansson

On 06/02/2021 22.17, Marc Zyngier wrote:
>> +config ARCH_APPLE
>> +	bool "Apple Silicon SoC family"
>> +	select GENERIC_IRQ_CHIP
> 
> nit: This is better selected by the interrupt controller that relies
> on the generic irqchip infrastructure.

Ack, changed for v2.

-- 
Hector Martin "marcan" (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 08/18] arm64: cpufeature: Add a feature for FIQ support
       [not found]   ` <87im75l2lp.wl-maz@kernel.org>
@ 2021-02-07  8:28     ` Hector Martin 'marcan'
       [not found]       ` <87czxalrwc.wl-maz@kernel.org>
  0 siblings, 1 reply; 82+ messages in thread
From: Hector Martin 'marcan' @ 2021-02-07  8:28 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: soc, linux-arm-kernel, robh+dt, Arnd Bergmann, linux-kernel,
	devicetree, Olof Johansson

On 06/02/2021 22.58, Marc Zyngier wrote:
> Hector Martin <marcan@marcan.st> wrote:
>> +static void cpu_sync_irq_to_fiq(struct arm64_cpu_capabilities const *cap)
>> +{
>> +	u64 daif = read_sysreg(daif);
>> +
>> +	/*
>> +	 * By this point in the boot process IRQs are likely masked and FIOs
>> +	 * aren't, so we need to sync things to avoid spurious early FIQs.
>> +	 */
>> +
>> +	if (daif & PSR_I_BIT)
>> +		daif |= PSR_F_BIT;
>> +	else
>> +		daif &= ~PSR_F_BIT;
>> +
>> +	write_sysreg(daif, daif);
> 
> Could this happen too late? If, as explained above, we can get a FIQ
> until we mask it here, what prevents something (a timer?) from kicking
> and creating havoc just before the sync?

Nothing, other than timers not being enabled this early (hopefully the 
bootloader doesn't leave a rogue timer running for us...)

> If the answer is "nothing", then it probably means that the default
> behaviour should be to treat PSTATE.I and PSTATE.F as containing the
> same value at all times, and not just as an afterthought when we
> detect that we're on a CPU type or another.

I thought of this too. Originally I thought PSTATE.F was always set on 
other systems, and thus unmasking FIQs could cause problems if there is 
a pending rogue FIQ for some reason. However, while writing this patch I 
realized that as part of normal process state changes we already unmask 
FIQs anyway (see DAIF_PROCCTX).

Thus, in fact, this patch actually changes things (when the cpufeature 
is set) to mask FIQs in some cases where they currently aren't, and 
conversely to unmask them in some cases where they currently are. But 
the fact that FIQ masking is somewhat inconsistent to begin with 
suggests that we should be able to mess with it without causing breakage 
for other systems.

So I guess in this case it would be legitimate to just make I==F on 
every system, and if something breaks it should be fixed by making 
whatever is causing a rogue FIQ not do that, right?

That would leave the vector switcheroo as the only thing the cpufeature 
does, which would certainly simplify a lot of the patch.

> This could expand into enabling Group-0 interrupts with GICv3 on
> systems that have a single security state (such as virtual machines),
> though I don't really see a good use case for it.

I could see having a separate vector path opening up the door for 
performance hacks for very specific use cases that want really low 
latency for *one* thing (e.g. the mess the Raspberry Pi folks do to work 
around that braindead USB controller's performance issues), though I 
imagine there would have to be very compelling reasons to develop a 
framework to do this sanely upstream.

Incidentally, I have a personal interest in real-time performance 
(especially audio); once the dust settles and we have a workable kernel 
for normal use I do hope to spend some time taking a deep dive into 
latencies and finding RT-unfriendly code, but that's pretty far off 
right now. Maybe PREEMPT_RT will even be merged by then :-) (I hope that 
without SMM to screw things up on these machines they might make very 
nice RT-capable boxes...)

-- 
Hector Martin "marcan" (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 10/18] arm64: Introduce FIQ support
       [not found]     ` <CAK8P3a0-Qk1WAUaCWeX8Zypphpadan3YAOES9t7LFYBOJkXKog@mail.gmail.com>
@ 2021-02-07  8:36       ` Hector Martin 'marcan'
       [not found]         ` <CAK8P3a1R51_nqfMWG7SxScJNJEQ3qvp-cynABKEDaQ4O9REM=Q@mail.gmail.com>
  0 siblings, 1 reply; 82+ messages in thread
From: Hector Martin 'marcan' @ 2021-02-07  8:36 UTC (permalink / raw)
  To: Arnd Bergmann, Marc Zyngier
  Cc: SoC Team, Linux ARM, Rob Herring, linux-kernel, DTML, Olof Johansson

On 07/02/2021 01.22, Arnd Bergmann wrote:
> * In the fiq handler code, check if normal interrupts were enabled
>    when the fiq hit. Normally they are enabled, so just proceed to
>    handle the timer and ipi directly
> 
> * if irq was disabled, defer the handling by doing a self-ipi
>    through the aic's ipi method, and handle it from there
>    when dealing with the next interrupt once interrupts get
>    enabled.
> 
> This would be similar to the soft-disable feature on powerpc, which
> never actually turns off interrupts from regular kernel code but
> just checks a flag in local_irq_enable that gets set when a
> hardirq happened.

Case #2 seems messy. In AIC, we'd have to either:

* Disable FIQs, and hope that doesn't confuse any save/restore code 
going on, then set a flag and check it in *both* the IRQ and FIQ path 
since either might trigger depending on what happens next, or
* Mask the relevant timer, which we'd then need to make sure does not 
confuse the timer code (Unmask it again when we fire the interrupt? But 
what if the timer code intended to mask it in the interim?)

Neither sounds particularly clean to me... if we had FIQ status masking 
registers this would be more reasonable, but I'm not sure I'd want the 
AIC driver to mess with neither DAIF nor the timer registers. It's bad 
enough that it has to read the latter already (and I hope I can find a 
better way of doing that...).

Plus I don't know if the vector entry code and other scaffolding between 
the vector and the AIC driver would be happy with, effectively, 
recursive interrupts. This could work with a carefully controlled path 
to make sure it doesn't break things, but I'm not so sure about the 
current "just point FIQ and IRQ to the same place" approach here.

-- 
Hector Martin "marcan" (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 10/18] arm64: Introduce FIQ support
       [not found]   ` <87h7mpky0f.wl-maz@kernel.org>
       [not found]     ` <CAK8P3a0-Qk1WAUaCWeX8Zypphpadan3YAOES9t7LFYBOJkXKog@mail.gmail.com>
@ 2021-02-07  8:47     ` Hector Martin 'marcan'
  1 sibling, 0 replies; 82+ messages in thread
From: Hector Martin 'marcan' @ 2021-02-07  8:47 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: soc, linux-arm-kernel, robh+dt, Arnd Bergmann, linux-kernel,
	devicetree, Olof Johansson, Mark Rutland, James Morse

On 07/02/2021 00.37, Marc Zyngier wrote:
> See my digression in patch 8. I really wonder what the benefit is to
> treat FIQ independently of IRQ, and we might as well generalise
> this. We could always panic on getting a FIQ on platforms that don't
> expect one.
> 
> It'd be good to rope in the other interested parties (Mark for the
> early entry code, James for RAS and SError handling).

CCing Mark and James: TL;DR what do you think about unconditionally 
keeping DAIF.I == DAIF.F, would this break other platforms with spurious 
FIQs or conversely mask FIQs when we don't want to in some cases? The 
FIQ vector would remain a panic except on platforms that require using 
it, via an alternatives patch.

>>   	kernel_ventry	1, sync				// Synchronous EL1h
>>   	kernel_ventry	1, irq				// IRQ EL1h
>> -	kernel_ventry	1, fiq_invalid			// FIQ EL1h
>> +							// FIQ EL1h
>> +	kernel_ventry	1, fiq_invalid, 64, irq, ARM64_NEEDS_FIQ
> 
> It could be better to create a set of first class FIQ handlers rather
> than this alternative target macro. I quickly hacked this instead,
> which I find more readable.

I think I ended up with the macro change to keep it 1:1 with IRQ, vs a 
separate branch... but I didn't think of the fallthrough-with-nop trick, 
neat. It is definitely is more readable. Are you OK with me pulling this 
patch in for v2, with your name on it?

> -	kernel_ventry	0, fiq_invalid_compat, 32	// FIQ 32-bit EL0
> +	kernel_ventry	0, fiq, 32			// FIQ 32-bit EL0

fiq_compat here, right?

-- 
Hector Martin "marcan" (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 05/18] tty: serial: samsung_tty: add support for Apple UARTs
       [not found]   ` <87lfc1l4lo.wl-maz@kernel.org>
@ 2021-02-07  9:12     ` Hector Martin 'marcan'
  2021-02-07  9:26       ` Hector Martin 'marcan'
       [not found]       ` <73116feaa00de9173d1f2c35ce16e08f@kernel.org>
  0 siblings, 2 replies; 82+ messages in thread
From: Hector Martin 'marcan' @ 2021-02-07  9:12 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: soc, linux-arm-kernel, robh+dt, Arnd Bergmann, linux-kernel,
	devicetree, Olof Johansson, Thomas Abraham

On 06/02/2021 22.15, Marc Zyngier wrote:
>> -static int s3c24xx_serial_has_interrupt_mask(struct uart_port *port)
>> +static int s3c24xx_irq_type(struct uart_port *port)
>>   {
>> -	return to_ourport(port)->info->type == PORT_S3C6400;
>> +	switch (to_ourport(port)->info->type) {
>> +	case PORT_S3C6400:
>> +		return IRQ_S3C6400;
>> +	case PORT_APPLE:
>> +		return IRQ_APPLE;
>> +	default:
>> +		return IRQ_DISCRETE;
>> +	}
>> +
> 
> nit: For ease of reviewing, it'd be good if you could split this patch
> with introducing the S3C6400 and "discrete" support initially, and
> only then add the new stuff.

Good idea, will do for v2.

>> +	if (s3c24xx_irq_type(port) == IRQ_APPLE)
>> +		s3c24xx_serial_tx_chars(NO_IRQ, ourport);
> 
> Instead of directly calling into the handler (which has its own
> problems, see below), could you just tickle the interrupt status
> register to make an interrupt pending and trigger an actual interrupt?
> I have no idea whether the HW supports this kind of trick though.

I thought of that, but I tried really hard to find such a feature with 
no success. The best I can do is unmask and trigger the *RX* timeout 
interrupt which will eventually fire but... this doesn't work so well in 
practice. There is no way to trigger IRQ flags directly (as those bits 
are write-1-to-clear).

>> -	spin_lock_irqsave(&port->lock, flags);
>> +	/* Only lock if called from IRQ context */
>> +	if (irq != NO_IRQ)
>> +		spin_lock_irqsave(&port->lock, flags);
> 
> Isn't that actually dangerous? What prevents the interrupt from firing
> right in the middle of this sequence and create havoc when called from
> enable_tx_pio()? I fail to see what you gain with sidestepping the
> locking.

The callpath here is:

uart_start -> __uart_start -> (uart_ops.start_tx) 
s3c24xx_serial_start_tx -> s3c24xx_serial_start_tx_pio -> enable_tx_pio 
-> s3c24xx_serial_tx_chars

And uart_start takes the uart_port lock. None of the serial functions 
take the lock because the serial core already does, but obviously the 
IRQ handler needs to, *if* it's called as an IRQ handler only.

> The default should be IRQ_NONE, otherwise the kernel cannot detect a
> screaming spurious interrupt.

Good point, and this needs fixing in s3c64xx_serial_handle_irq too then 
(which is what I based mine off of).

>> +	ret = request_irq(port->irq, apple_serial_handle_irq, IRQF_SHARED,
>> +			  s3c24xx_serial_portname(port), ourport);
> 
> Why IRQF_SHARED? Do you expect any other device sharing the same line
> with this UART?

This also came from s3c64xx_serial_startup and... now I wonder why that 
one needs it. Maybe on some SoCs it does get shared? Certainly not for 
discrete rx/tx irq chips (and indeed those don't set the flag)...

CCing Thomas, who added the S3C64xx support (and should probably review 
this patch); is there a reason for IRQF_SHARED there? NB: v1 breaks the 
build on arm or with CONFIG_PM_SLEEP, those will be fixed for v2.

Either way, certainly not for Apple SoCs; I'll get rid of IRQF_SHARED 
for v2.

>> diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
>> index 62c22045fe65..59d102b674db 100644
>> --- a/include/uapi/linux/serial_core.h
>> +++ b/include/uapi/linux/serial_core.h
>> @@ -277,4 +277,7 @@
>>   /* Freescale LINFlexD UART */
>>   #define PORT_LINFLEXUART	122
>>   
>> +/* Apple Silicon (M1/T8103) UART (Samsung variant) */
>> +#define PORT_APPLE	123
>> +
> 
> Do you actually need a new port type here? Looking at the driver
> itself, it is mainly used to work out the IRQ model. Maybe introducing
> a new irq_type field in the port structure would be better than
> exposing this to userspace (which should see something that is exactly
> the same as a S3C UART).

Well... every S3C variant already has its own port type here.

#define PORT_S3C2410    55
#define PORT_S3C2440    61
#define PORT_S3C2400    67
#define PORT_S3C2412    73
#define PORT_S3C6400    84

If we don't introduce a new one, which one should we pretend to be? :)

I agree that it might make sense to merge all of these into one, though; 
I don't know what the original reason for splitting them out is. But now 
that they're part of the userspace API, this might not be a good idea. 
Though, unsurprisingly, some googling suggests there are zero users of 
these defines in userspace.

-- 
Hector Martin "marcan" (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 11/18] arm64: Kconfig: Require FIQ support for ARCH_APPLE
       [not found]   ` <87ft29kxmp.wl-maz@kernel.org>
@ 2021-02-07  9:23     ` Hector Martin 'marcan'
       [not found]       ` <2a93bf0df74df8cb022e61d69d1de88e@kernel.org>
  0 siblings, 1 reply; 82+ messages in thread
From: Hector Martin 'marcan' @ 2021-02-07  9:23 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: soc, linux-arm-kernel, robh+dt, Arnd Bergmann, linux-kernel,
	devicetree, Olof Johansson

On 07/02/2021 00.46, Marc Zyngier wrote:
>>   config ARCH_APPLE
>>   	bool "Apple Silicon SoC family"
>>   	select GENERIC_IRQ_CHIP
>> +	select ARM64_FIQ_SUPPORT
> 
> Ah, this is what I was expecting in the previous patch. I guess the
> initial ARCH_APPLE patch could be moved down the line and add all the
> dependencies in one go.

I was trying to introduce the Kconfig before the code that depends on 
it; is it kosher to have it in the other order, looking for CONFIG_ 
defines that don't exist yet?

Though in this case the only user earlier in the series is the Samsung 
stuff, which doesn't care about FIQs, so I can just sort things as 
FIQ->ARCH_APPLE->samsung->AIC...

I'm not sure about AIC vs. ARCH_APPLE though. Right now the pattern is 
that AIC depends on ARCH_APPLE and also defaults to that. But then you 
can build with ARCH_APPLE and AIC disabled if you so choose, which does 
result in a broken system on these machines. AIC should build without 
ARCH_APPLE (as long as we're on ARM64), so we could reverse that.

-- 
Hector Martin "marcan" (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 05/18] tty: serial: samsung_tty: add support for Apple UARTs
  2021-02-07  9:12     ` Hector Martin 'marcan'
@ 2021-02-07  9:26       ` Hector Martin 'marcan'
  2021-02-08  9:36         ` Krzysztof Kozlowski
       [not found]       ` <73116feaa00de9173d1f2c35ce16e08f@kernel.org>
  1 sibling, 1 reply; 82+ messages in thread
From: Hector Martin 'marcan' @ 2021-02-07  9:26 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: soc, linux-arm-kernel, robh+dt, Arnd Bergmann, linux-kernel,
	devicetree, Olof Johansson, Krzysztof Kozlowski

On 07/02/2021 18.12, Hector Martin 'marcan' wrote:
> On 06/02/2021 22.15, Marc Zyngier wrote:
>> The default should be IRQ_NONE, otherwise the kernel cannot detect a
>> screaming spurious interrupt.
> 
> Good point, and this needs fixing in s3c64xx_serial_handle_irq too then
> (which is what I based mine off of).
> 
>>> +	ret = request_irq(port->irq, apple_serial_handle_irq, IRQF_SHARED,
>>> +			  s3c24xx_serial_portname(port), ourport);
>>
>> Why IRQF_SHARED? Do you expect any other device sharing the same line
>> with this UART?
> 
> This also came from s3c64xx_serial_startup and... now I wonder why that
> one needs it. Maybe on some SoCs it does get shared? Certainly not for
> discrete rx/tx irq chips (and indeed those don't set the flag)...
> 
> CCing Thomas, who added the S3C64xx support (and should probably review
> this patch); is there a reason for IRQF_SHARED there? NB: v1 breaks the
> build on arm or with CONFIG_PM_SLEEP, those will be fixed for v2.

Seems Thomas does not work for Linaro any more :)

CCing Krzysztof instead, who is the Samsung arch maintainer.

> 
> Either way, certainly not for Apple SoCs; I'll get rid of IRQF_SHARED
> for v2.

-- 
Hector Martin "marcan" (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 10/18] arm64: Introduce FIQ support
       [not found]         ` <CAK8P3a1R51_nqfMWG7SxScJNJEQ3qvp-cynABKEDaQ4O9REM=Q@mail.gmail.com>
@ 2021-02-07 15:38           ` Hector Martin 'marcan'
       [not found]             ` <CAK8P3a1vmUJ0EpzU2+u2gy8WHCVV5ur9u-oTzU2BP=ddbXQeLQ@mail.gmail.com>
  0 siblings, 1 reply; 82+ messages in thread
From: Hector Martin 'marcan' @ 2021-02-07 15:38 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Marc Zyngier, SoC Team, Linux ARM, Rob Herring, linux-kernel,
	DTML, Olof Johansson

On 07/02/2021 21.25, Arnd Bergmann wrote:
> On Sun, Feb 7, 2021 at 9:36 AM Hector Martin 'marcan' <marcan@marcan.st> wrote:
>> On 07/02/2021 01.22, Arnd Bergmann wrote:
>>> * In the fiq handler code, check if normal interrupts were enabled
>>>     when the fiq hit. Normally they are enabled, so just proceed to
>>>     handle the timer and ipi directly
>>>
>>> * if irq was disabled, defer the handling by doing a self-ipi
>>>     through the aic's ipi method, and handle it from there
>>>     when dealing with the next interrupt once interrupts get
>>>     enabled.
>>>
>>> This would be similar to the soft-disable feature on powerpc, which
>>> never actually turns off interrupts from regular kernel code but
>>> just checks a flag in local_irq_enable that gets set when a
>>> hardirq happened.
>>
>> Case #2 seems messy. In AIC, we'd have to either:
>>
>> * Disable FIQs, and hope that doesn't confuse any save/restore code
>> going on, then set a flag and check it in *both* the IRQ and FIQ path
>> since either might trigger depending on what happens next, or
>> * Mask the relevant timer, which we'd then need to make sure does not
>> confuse the timer code (Unmask it again when we fire the interrupt? But
>> what if the timer code intended to mask it in the interim?)
> 
> I'm not quite following here. The IRQ should be disabled the entire time
> while handling that self-IPI and the timer top half code, so if we get
> another FIQ while handling the timer from the IRQ path, it will lead
> either yet another self-IPI or it will be ignored in case the previous timer
> event has not been Acked yet. I would expect that both cases are
> race-free here, the only time that the FIQ needs to be disabled is
> while actually handling the FIQ. Did I miss something?

FIQs are level-triggered, and there are only two* ways of masking them 
(that we know of): in the timer, or DAIF. That means that if we get a 
FIQ, we *must* do one of two things: either mask it in the timer 
register, or mask FIQs entirely. If we do neither of these, we get a FIQ 
storm.

So if a timer FIQ fires while IRQs are disabled, and we can't call into 
the timer code (because IRQs were disabled, so we need to defer handling 
via the IPI), the only other options are to either poke the timer mask 
bit directly, or to mask FIQs. Neither seems particularly correct.

* An exception seems to be non-HV timer interrupts firing while we have 
a VM guest running (HCR_EL2.TGE=0). This causes a single FIQ, and no 
more, which suggests there is a mask bit for guest timer FIQs somewhere 
that gets automatically set when the FIQ is delivered to the CPU core. 
I've yet to find where this bit lives, I'll be doing a brute force sweep 
of system register space soon to see if I can find it, and if there is 
anything else useful near it.

>> Plus I don't know if the vector entry code and other scaffolding between
>> the vector and the AIC driver would be happy with, effectively,
>> recursive interrupts. This could work with a carefully controlled path
>> to make sure it doesn't break things, but I'm not so sure about the
>> current "just point FIQ and IRQ to the same place" approach here.
> 
> If we do what I described above, the FIQ and IRQ entry would have
> to be separate and only arrive in the same code path when calling
> into drivers/clocksource/arm_arch_timer.c. It's not recursive there
> because that part is only called when IRQ is disabled, and no IRQ
> is being executed while the FIQ hits.

Right, that's what i'm saying; we can't re-use the IRQ handler like Marc 
proposed, because I don't think that expects to be called reentrantly; 
we'd have to have a separate FIQ entry, but since it can be called with 
IRQs enabled and handle the FIQ in-line, it also needs to be able to 
*conditionally* behave like a normal IRQ handler. This level of 
complexity seems somewhat dubious, just to not maintain the FIQ mask bit 
synced. That's not just AIC code any more, it needs a bespoke FIQ vector 
and logic to decide whether IRQs are masked (call AIC to self-IPI 
without doing the usual IRQ processing) or unmasked (go through regular 
IRQ accounting and behave like an IRQ).

Perhaps I'm misunderstanding what you're proposing here or how this 
would work :)

-- 
Hector Martin "marcan" (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 05/18] tty: serial: samsung_tty: add support for Apple UARTs
  2021-02-07  9:26       ` Hector Martin 'marcan'
@ 2021-02-08  9:36         ` Krzysztof Kozlowski
  2021-02-08 16:14           ` Hector Martin
  0 siblings, 1 reply; 82+ messages in thread
From: Krzysztof Kozlowski @ 2021-02-08  9:36 UTC (permalink / raw)
  To: Hector Martin 'marcan'
  Cc: Marc Zyngier, soc, linux-arm-kernel, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

On Sun, Feb 07, 2021 at 06:26:43PM +0900, Hector Martin 'marcan' wrote:
> On 07/02/2021 18.12, Hector Martin 'marcan' wrote:
> > On 06/02/2021 22.15, Marc Zyngier wrote:
> > > The default should be IRQ_NONE, otherwise the kernel cannot detect a
> > > screaming spurious interrupt.
> > 
> > Good point, and this needs fixing in s3c64xx_serial_handle_irq too then
> > (which is what I based mine off of).
> > 
> > > > +	ret = request_irq(port->irq, apple_serial_handle_irq, IRQF_SHARED,
> > > > +			  s3c24xx_serial_portname(port), ourport);
> > > 
> > > Why IRQF_SHARED? Do you expect any other device sharing the same line
> > > with this UART?
> > 
> > This also came from s3c64xx_serial_startup and... now I wonder why that
> > one needs it. Maybe on some SoCs it does get shared? Certainly not for
> > discrete rx/tx irq chips (and indeed those don't set the flag)...
> > 
> > CCing Thomas, who added the S3C64xx support (and should probably review
> > this patch); is there a reason for IRQF_SHARED there? NB: v1 breaks the
> > build on arm or with CONFIG_PM_SLEEP, those will be fixed for v2.
> 
> Seems Thomas does not work for Linaro any more :)
> 
> CCing Krzysztof instead, who is the Samsung arch maintainer.

Please use the scripts/get_maintainers.pl to get the list of people to
Cc. The script would point necessary folks.

A different issue is that all your emails from this thread were marked
by Google as spam.  I don't see any particular warning signs in the
header so it looks more of content-based match for spam.

> > Either way, certainly not for Apple SoCs; I'll get rid of IRQF_SHARED
> > for v2.

Please send a v2 after fixing issues pointed out by kbuild.

Best regards,
Krzysztof


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

* Re: [PATCH 01/18] dt-bindings: vendor-prefixes: add AAPL prefix
  2021-02-04 20:39 ` [PATCH 01/18] dt-bindings: vendor-prefixes: add AAPL prefix Hector Martin
@ 2021-02-08 10:27   ` Krzysztof Kozlowski
  2021-02-08 17:32     ` Rob Herring
  0 siblings, 1 reply; 82+ messages in thread
From: Krzysztof Kozlowski @ 2021-02-08 10:27 UTC (permalink / raw)
  To: Hector Martin
  Cc: soc, linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

On Fri, Feb 05, 2021 at 05:39:34AM +0900, Hector Martin wrote:
> Amusingly, this wasn't yet documented, even though this vendor prefix
> has been used since time immemorial on PPC.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> index 041ae90b0d8f..d7950c723472 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> @@ -25,6 +25,8 @@ patternProperties:
>    # Keep list in alphabetical order.
>    "^70mai,.*":
>      description: 70mai Co., Ltd.
> +  "^AAPL,.*":

All prefixes are lower case... see ABB below (not mentioning that the
company name is not APPLE), so just "apple".

> +    description: Apple Inc.
>    "^abb,.*":
>      description: ABB

Best regards,
Krzysztof

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

* Re: [PATCH 05/18] tty: serial: samsung_tty: add support for Apple UARTs
  2021-02-04 20:39 ` [PATCH 05/18] tty: serial: samsung_tty: add support for Apple UARTs Hector Martin
                     ` (2 preceding siblings ...)
       [not found]   ` <87lfc1l4lo.wl-maz@kernel.org>
@ 2021-02-08 10:54   ` Krzysztof Kozlowski
  2021-02-08 16:10     ` Hector Martin
  3 siblings, 1 reply; 82+ messages in thread
From: Krzysztof Kozlowski @ 2021-02-08 10:54 UTC (permalink / raw)
  To: Hector Martin
  Cc: soc, linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

On Fri, Feb 05, 2021 at 05:39:38AM +0900, Hector Martin wrote:
> Apple SoCs are a distant descendant of Samsung designs and use yet
> another variant of their UART style, with different interrupt handling.
> 
> In particular, this variant has the following differences with existing
> ones:
> 
> * It includes a built-in interrupt controller with different registers,
>   using only a single platform IRQ
> 
> * Internal interrupt sources are treated as edge-triggered, even though
>   the IRQ output is level-triggered. This chiefly affects the TX IRQ
>   path: the driver can no longer rely on the TX buffer empty IRQ
>   immediately firing after TX is enabled, but instead must prime the
>   FIFO with data directly.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  drivers/tty/serial/samsung_tty.c | 297 +++++++++++++++++++++++++++----
>  include/linux/serial_s3c.h       |  16 ++
>  include/uapi/linux/serial_core.h |   3 +
>  3 files changed, 280 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
> index 8ae3e03fbd8c..6d812ba1b748 100644
> --- a/drivers/tty/serial/samsung_tty.c
> +++ b/drivers/tty/serial/samsung_tty.c
> @@ -56,6 +56,9 @@
>  /* flag to ignore all characters coming in */
>  #define RXSTAT_DUMMY_READ (0x10000000)
>  
> +/* IRQ number used when the handler is called in non-IRQ context */
> +#define NO_IRQ -1
> +
>  struct s3c24xx_uart_info {
>  	char			*name;
>  	unsigned int		type;
> @@ -144,6 +147,14 @@ struct s3c24xx_uart_port {
>  #endif
>  };
>  
> +enum s3c24xx_irq_type {
> +	IRQ_DISCRETE = 0,
> +	IRQ_S3C6400 = 1,
> +	IRQ_APPLE = 2,

It seems you add the third structure to differentiate type of UART.
There is already port type and s3c24xx_serial_drv_data, no need for
third structure (kind of similar to tries of Tamseel Shams in recent
patches). It's too much. Instead, differentiate by port type or prepare
own set of uart_ops if it's really different (like you did with startup
op).

> +};
> +
> +static void s3c24xx_serial_start_next_tx(struct s3c24xx_uart_port *ourport);
> +
>  /* conversion functions */
>  
>  #define s3c24xx_dev_to_port(__dev) dev_get_drvdata(__dev)
> @@ -231,11 +242,20 @@ static int s3c24xx_serial_txempty_nofifo(struct uart_port *port)
>  /*
>   * s3c64xx and later SoC's include the interrupt mask and status registers in
>   * the controller itself, unlike the s3c24xx SoC's which have these registers
> - * in the interrupt controller. Check if the port type is s3c64xx or higher.
> + * in the interrupt controller. Apple SoCs use a different flavor of mask
> + * and status registers. This function returns the IRQ style to use.
>   */
> -static int s3c24xx_serial_has_interrupt_mask(struct uart_port *port)
> +static int s3c24xx_irq_type(struct uart_port *port)
>  {
> -	return to_ourport(port)->info->type == PORT_S3C6400;
> +	switch (to_ourport(port)->info->type) {
> +	case PORT_S3C6400:
> +		return IRQ_S3C6400;
> +	case PORT_APPLE:
> +		return IRQ_APPLE;
> +	default:
> +		return IRQ_DISCRETE;
> +	}
> +

No empty lines at end of function.

>  }
>  
>  static void s3c24xx_serial_rx_enable(struct uart_port *port)
> @@ -289,10 +309,17 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port)
>  	if (!ourport->tx_enabled)
>  		return;
>  
> -	if (s3c24xx_serial_has_interrupt_mask(port))
> +	switch (s3c24xx_irq_type(port)) {
> +	case IRQ_APPLE:
> +		s3c24xx_clear_bit(port, APPLE_UCON_TXTHRESH_ENA, S3C2410_UCON);
> +		break;
> +	case IRQ_S3C6400:
>  		s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
> -	else
> +		break;
> +	default:
>  		disable_irq_nosync(ourport->tx_irq);
> +		break;
> +	}
>  
>  	if (dma && dma->tx_chan && ourport->tx_in_progress == S3C24XX_TX_DMA) {
>  		dmaengine_pause(dma->tx_chan);
> @@ -315,8 +342,6 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port)
>  	ourport->tx_mode = 0;
>  }
>  
> -static void s3c24xx_serial_start_next_tx(struct s3c24xx_uart_port *ourport);
> -
>  static void s3c24xx_serial_tx_dma_complete(void *args)
>  {
>  	struct s3c24xx_uart_port *ourport = args;
> @@ -353,10 +378,17 @@ static void enable_tx_dma(struct s3c24xx_uart_port *ourport)
>  	u32 ucon;
>  
>  	/* Mask Tx interrupt */
> -	if (s3c24xx_serial_has_interrupt_mask(port))
> +	switch (s3c24xx_irq_type(port)) {
> +	case IRQ_APPLE:
> +		WARN_ON(1); // No DMA
> +		break;
> +	case IRQ_S3C6400:
>  		s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
> -	else
> +		break;
> +	default:
>  		disable_irq_nosync(ourport->tx_irq);
> +		break;
> +	}
>  
>  	/* Enable tx dma mode */
>  	ucon = rd_regl(port, S3C2410_UCON);
> @@ -369,6 +401,8 @@ static void enable_tx_dma(struct s3c24xx_uart_port *ourport)
>  	ourport->tx_mode = S3C24XX_TX_DMA;
>  }
>  
> +static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id);
> +
>  static void enable_tx_pio(struct s3c24xx_uart_port *ourport)
>  {
>  	struct uart_port *port = &ourport->port;
> @@ -383,16 +417,30 @@ static void enable_tx_pio(struct s3c24xx_uart_port *ourport)
>  	ucon = rd_regl(port, S3C2410_UCON);
>  	ucon &= ~(S3C64XX_UCON_TXMODE_MASK);
>  	ucon |= S3C64XX_UCON_TXMODE_CPU;
> -	wr_regl(port,  S3C2410_UCON, ucon);
>  
>  	/* Unmask Tx interrupt */
> -	if (s3c24xx_serial_has_interrupt_mask(port))
> -		s3c24xx_clear_bit(port, S3C64XX_UINTM_TXD,
> -				  S3C64XX_UINTM);
> -	else
> +	switch (s3c24xx_irq_type(port)) {
> +	case IRQ_APPLE:
> +		ucon |= APPLE_UCON_TXTHRESH_ENA_MSK;
> +		break;
> +	case IRQ_S3C6400:
> +		s3c24xx_clear_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
> +		break;
> +	default:
>  		enable_irq(ourport->tx_irq);
> +		break;
> +	}
> +
> +	wr_regl(port,  S3C2410_UCON, ucon);
>  
>  	ourport->tx_mode = S3C24XX_TX_PIO;
> +
> +	/*
> +	 * The Apple version only has edge triggered TX IRQs, so we need
> +	 * to kick off the process by sending some characters here.
> +	 */
> +	if (s3c24xx_irq_type(port) == IRQ_APPLE)
> +		s3c24xx_serial_tx_chars(NO_IRQ, ourport);
>  }
>  
>  static void s3c24xx_serial_start_tx_pio(struct s3c24xx_uart_port *ourport)
> @@ -513,11 +561,18 @@ static void s3c24xx_serial_stop_rx(struct uart_port *port)
>  
>  	if (ourport->rx_enabled) {
>  		dev_dbg(port->dev, "stopping rx\n");
> -		if (s3c24xx_serial_has_interrupt_mask(port))
> -			s3c24xx_set_bit(port, S3C64XX_UINTM_RXD,
> -					S3C64XX_UINTM);
> -		else
> -			disable_irq_nosync(ourport->rx_irq);
> +		switch (s3c24xx_irq_type(port)) {
> +		case IRQ_APPLE:
> +			s3c24xx_clear_bit(port, APPLE_UCON_RXTHRESH_ENA, S3C2410_UCON);
> +			s3c24xx_clear_bit(port, APPLE_UCON_RXTO_ENA, S3C2410_UCON);
> +			break;
> +		case IRQ_S3C6400:
> +			s3c24xx_set_bit(port, S3C64XX_UINTM_RXD, S3C64XX_UINTM);
> +			break;
> +		default:
> +			disable_irq_nosync(ourport->tx_irq);
> +			break;
> +		}
>  		ourport->rx_enabled = 0;
>  	}
>  	if (dma && dma->rx_chan) {
> @@ -651,14 +706,18 @@ static void enable_rx_pio(struct s3c24xx_uart_port *ourport)
>  
>  	/* set Rx mode to DMA mode */
>  	ucon = rd_regl(port, S3C2410_UCON);
> -	ucon &= ~(S3C64XX_UCON_TIMEOUT_MASK |
> -			S3C64XX_UCON_EMPTYINT_EN |
> -			S3C64XX_UCON_DMASUS_EN |
> -			S3C64XX_UCON_TIMEOUT_EN |
> -			S3C64XX_UCON_RXMODE_MASK);
> -	ucon |= 0xf << S3C64XX_UCON_TIMEOUT_SHIFT |
> -			S3C64XX_UCON_TIMEOUT_EN |
> -			S3C64XX_UCON_RXMODE_CPU;
> +	ucon &= ~S3C64XX_UCON_RXMODE_MASK;
> +	ucon |= S3C64XX_UCON_RXMODE_CPU;
> +
> +	/* Apple types use these bits for IRQ masks */
> +	if (s3c24xx_irq_type(port) != IRQ_APPLE) {
> +		ucon &= ~(S3C64XX_UCON_TIMEOUT_MASK |
> +				S3C64XX_UCON_EMPTYINT_EN |
> +				S3C64XX_UCON_DMASUS_EN |
> +				S3C64XX_UCON_TIMEOUT_EN);
> +		ucon |= 0xf << S3C64XX_UCON_TIMEOUT_SHIFT |
> +				S3C64XX_UCON_TIMEOUT_EN;
> +	}
>  	wr_regl(port, S3C2410_UCON, ucon);
>  
>  	ourport->rx_mode = S3C24XX_RX_PIO;
> @@ -831,7 +890,9 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
>  	unsigned long flags;
>  	int count, dma_count = 0;
>  
> -	spin_lock_irqsave(&port->lock, flags);
> +	/* Only lock if called from IRQ context */
> +	if (irq != NO_IRQ)
> +		spin_lock_irqsave(&port->lock, flags);

I would prefer to have two functions - unlocked (doing actual stuff) and
a locking wrapper. Something like is done for regulator_is_enabled().
However the s3c24xx_serial_tx_chars() also unlocks-locks inside, so it
might be not easy to split common part Anyway hacking interrupt handler
to NO_IRQ is confusing and not readable.

>  
>  	count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
>  
> @@ -893,7 +954,8 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
>  		s3c24xx_serial_stop_tx(port);
>  
>  out:
> -	spin_unlock_irqrestore(&port->lock, flags);
> +	if (irq != NO_IRQ)
> +		spin_unlock_irqrestore(&port->lock, flags);
>  	return IRQ_HANDLED;
>  }
>  
> @@ -916,6 +978,26 @@ static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id)
>  	return ret;
>  }
>  
> +/* interrupt handler for Apple SoC's.*/
> +static irqreturn_t apple_serial_handle_irq(int irq, void *id)
> +{
> +	struct s3c24xx_uart_port *ourport = id;
> +	struct uart_port *port = &ourport->port;
> +	unsigned int pend = rd_regl(port, S3C2410_UTRSTAT);
> +	irqreturn_t ret = IRQ_HANDLED;
> +
> +	if (pend & (APPLE_UTRSTAT_RXTHRESH | APPLE_UTRSTAT_RXTO)) {
> +		wr_regl(port, S3C2410_UTRSTAT, APPLE_UTRSTAT_RXTHRESH | APPLE_UTRSTAT_RXTO);
> +		ret = s3c24xx_serial_rx_chars(irq, id);
> +	}
> +	if (pend & APPLE_UTRSTAT_TXTHRESH) {
> +		wr_regl(port, S3C2410_UTRSTAT, APPLE_UTRSTAT_TXTHRESH);
> +		ret = s3c24xx_serial_tx_chars(irq, id);
> +	}
> +
> +	return ret;
> +}
> +
>  static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port)
>  {
>  	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
> @@ -1098,7 +1180,7 @@ static void s3c24xx_serial_shutdown(struct uart_port *port)
>  	struct s3c24xx_uart_port *ourport = to_ourport(port);
>  
>  	if (ourport->tx_claimed) {
> -		if (!s3c24xx_serial_has_interrupt_mask(port))
> +		if (s3c24xx_irq_type(port) == IRQ_DISCRETE)
>  			free_irq(ourport->tx_irq, ourport);
>  		ourport->tx_enabled = 0;
>  		ourport->tx_claimed = 0;
> @@ -1106,18 +1188,34 @@ static void s3c24xx_serial_shutdown(struct uart_port *port)
>  	}
>  
>  	if (ourport->rx_claimed) {
> -		if (!s3c24xx_serial_has_interrupt_mask(port))
> +		if (s3c24xx_irq_type(port) == IRQ_DISCRETE)
>  			free_irq(ourport->rx_irq, ourport);
>  		ourport->rx_claimed = 0;
>  		ourport->rx_enabled = 0;
>  	}
>  
>  	/* Clear pending interrupts and mask all interrupts */
> -	if (s3c24xx_serial_has_interrupt_mask(port)) {
> +	switch (s3c24xx_irq_type(port)) {
> +	case IRQ_APPLE: {
> +		unsigned int ucon;
> +
> +		ucon = rd_regl(port, S3C2410_UCON);
> +		ucon &= ~(APPLE_UCON_TXTHRESH_ENA_MSK |
> +			APPLE_UCON_RXTHRESH_ENA_MSK |
> +			APPLE_UCON_RXTO_ENA_MSK);
> +		wr_regl(port, S3C2410_UCON, ucon);
> +
> +		wr_regl(port, S3C2410_UTRSTAT, APPLE_UTRSTAT_ALL_FLAGS);
> +
> +		free_irq(port->irq, ourport);
> +		break;
> +	}
> +	case IRQ_S3C6400:
>  		free_irq(port->irq, ourport);
>  
>  		wr_regl(port, S3C64XX_UINTP, 0xf);
>  		wr_regl(port, S3C64XX_UINTM, 0xf);
> +		break;
>  	}
>  
>  	if (ourport->dma)
> @@ -1215,6 +1313,47 @@ static int s3c64xx_serial_startup(struct uart_port *port)
>  	return ret;
>  }
>  
> +static int apple_serial_startup(struct uart_port *port)
> +{
> +	struct s3c24xx_uart_port *ourport = to_ourport(port);
> +	unsigned long flags;
> +	unsigned int ufcon;
> +	int ret;
> +
> +	wr_regl(port, S3C2410_UTRSTAT, APPLE_UTRSTAT_ALL_FLAGS);
> +
> +	ret = request_irq(port->irq, apple_serial_handle_irq, IRQF_SHARED,
> +			  s3c24xx_serial_portname(port), ourport);
> +	if (ret) {
> +		dev_err(port->dev, "cannot get irq %d\n", port->irq);
> +		return ret;
> +	}
> +
> +	/* For compatibility with s3c24xx Soc's */
> +	ourport->rx_enabled = 1;
> +	ourport->rx_claimed = 1;
> +	ourport->tx_enabled = 0;
> +	ourport->tx_claimed = 1;
> +
> +	spin_lock_irqsave(&port->lock, flags);
> +
> +	ufcon = rd_regl(port, S3C2410_UFCON);
> +	ufcon |= S3C2410_UFCON_RESETRX | S5PV210_UFCON_RXTRIG8;
> +	if (!uart_console(port))
> +		ufcon |= S3C2410_UFCON_RESETTX;
> +	wr_regl(port, S3C2410_UFCON, ufcon);
> +
> +	enable_rx_pio(ourport);
> +
> +	spin_unlock_irqrestore(&port->lock, flags);
> +
> +	/* Enable Rx Interrupt */
> +	s3c24xx_set_bit(port, APPLE_UCON_RXTHRESH_ENA, S3C2410_UCON);
> +	s3c24xx_set_bit(port, APPLE_UCON_RXTO_ENA, S3C2410_UCON);
> +
> +	return ret;
> +}
> +
>  /* power power management control */
>  
>  static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
> @@ -1544,6 +1683,8 @@ static const char *s3c24xx_serial_type(struct uart_port *port)
>  		return "S3C2412";
>  	case PORT_S3C6400:
>  		return "S3C6400/10";
> +	case PORT_APPLE:
> +		return "APPLE";

"Apple S5L"?

>  	default:
>  		return NULL;
>  	}
> @@ -1868,9 +2009,16 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
>  	/* setup info for port */
>  	port->dev	= &platdev->dev;
>  
> +	switch (s3c24xx_irq_type(port)) {
> +	/* Startup sequence is different for Apple SoC's */
> +	case IRQ_APPLE:
> +		s3c24xx_serial_ops.startup = apple_serial_startup;
> +		break;
>  	/* Startup sequence is different for s3c64xx and higher SoC's */
> -	if (s3c24xx_serial_has_interrupt_mask(port))
> +	case IRQ_S3C6400:
>  		s3c24xx_serial_ops.startup = s3c64xx_serial_startup;

Don't overwrite specific ops. It's difficult to see then which ops are
being used. Instead create a new set of uart_ops matching the needs.

Best regards,
Krzysztof

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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
  2021-02-04 20:39 ` [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree Hector Martin
       [not found]   ` <CAK8P3a3v6emxavbyjFhY+WdvH1t4EPMZSjEsSx0M+cRqjRCO1g@mail.gmail.com>
@ 2021-02-08 11:04   ` Krzysztof Kozlowski
  2021-02-08 11:56     ` Hector Martin 'marcan'
       [not found]   ` <a2825482e2f68c2f8cad7cb564414759@kernel.org>
  2 siblings, 1 reply; 82+ messages in thread
From: Krzysztof Kozlowski @ 2021-02-08 11:04 UTC (permalink / raw)
  To: Hector Martin
  Cc: soc, linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

On Fri, Feb 05, 2021 at 05:39:51AM +0900, Hector Martin wrote:
> This currently supports:
> 
> * SMP (via spin-tables)
> * AIC IRQs
> * Serial (with earlycon)
> * Framebuffer
> 
> A number of properties are dynamic, and based on system firmware
> decisions that vary from version to version. These are expected
> to be filled in by the loader.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  MAINTAINERS                              |   1 +
>  arch/arm64/boot/dts/Makefile             |   1 +
>  arch/arm64/boot/dts/apple/Makefile       |   2 +
>  arch/arm64/boot/dts/apple/apple-j274.dts | 143 +++++++++++++++++++++++
>  4 files changed, 147 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/apple/Makefile
>  create mode 100644 arch/arm64/boot/dts/apple/apple-j274.dts
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 3a54ee5747d3..5481b5bc2ef7 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1635,6 +1635,7 @@ C:	irc://chat.freenode.net/asahi-dev
>  T:	git https://github.com/AsahiLinux/linux.git
>  F:	Documentation/devicetree/bindings/arm/AAPL.yaml
>  F:	Documentation/devicetree/bindings/interrupt-controller/AAPL,aic.yaml
> +F:	arch/arm64/boot/dts/AAPL/

apple

Don't make things different for this one platform (comparing to all
other platforms). Apple is not that special. :)

>  F:	drivers/irqchip/irq-apple-aic.c
>  F:	include/dt-bindings/interrupt-controller/apple-aic.h
>  
> diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
> index 9b1170658d60..64f055d94948 100644
> --- a/arch/arm64/boot/dts/Makefile
> +++ b/arch/arm64/boot/dts/Makefile
> @@ -6,6 +6,7 @@ subdir-y += amazon
>  subdir-y += amd
>  subdir-y += amlogic
>  subdir-y += apm
> +subdir-y += apple
>  subdir-y += arm
>  subdir-y += bitmain
>  subdir-y += broadcom
> diff --git a/arch/arm64/boot/dts/apple/Makefile b/arch/arm64/boot/dts/apple/Makefile
> new file mode 100644
> index 000000000000..ec03c474efd4
> --- /dev/null
> +++ b/arch/arm64/boot/dts/apple/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0
> +dtb-$(CONFIG_ARCH_APPLE) += apple-j274.dtb
> diff --git a/arch/arm64/boot/dts/apple/apple-j274.dts b/arch/arm64/boot/dts/apple/apple-j274.dts
> new file mode 100644
> index 000000000000..238a1bcee066
> --- /dev/null
> +++ b/arch/arm64/boot/dts/apple/apple-j274.dts
> @@ -0,0 +1,143 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2021 Hector Martin <marcan@marcan.st>

A lot here might be difficult to reverse-egineer or figure out by
ourself, so usually people rely on vendor sources (the open source
compliance package). Didn't you receive such for the iOS (or whatever
was on your Mac)?

> + */
> +
> +/dts-v1/;
> +#include <dt-bindings/interrupt-controller/apple-aic.h>
> +#include <dt-bindings/interrupt-controller/irq.h>
> +
> +/ {
> +	model = "Apple Mac Mini M1 2020";
> +	compatible = "AAPL,j274", "AAPL,m1", "AAPL,arm-platform";

I guess Rob will comment on the dt-bindings more... but for me a generic
"arm-platform" is too generic. What's the point of it? I didn't see any
of such generic compatibles in other platforms.

> +	#address-cells = <2>;
> +	#size-cells = <2>;
> +
> +	chosen {
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		bootargs = "earlycon";

This should not be hard-coded in DTS. Pass it from bootloader.

> +		stdout-path = "serial0:1500000";

Use aliases.

> +
> +		framebuffer0: framebuffer@0 {
> +			compatible = "AAPL,simple-framebuffer", "simple-framebuffer";
> +			reg = <0 0 0 0>; // To be filled by loader
> +			// Format properties will be added by loader

Use /* style of comments

> +			status = "disabled";
> +		};
> +	};
> +
> +	memory@800000000 {
> +		device_type = "memory";
> +		reg = <0 0 0 0>; // To be filled by loader
> +	};
> +
> +	aliases {
> +		serial0 = &serial0;
> +	};
> +
> +	cpus {
> +		#address-cells = <2>;
> +		#size-cells = <0>;
> +
> +		cpu0: cpu@0 {
> +			compatible = "AAPL,icestorm";
> +			device_type = "cpu";
> +			reg = <0x0 0x0>;
> +			enable-method = "spin-table";
> +			cpu-release-addr = <0 0>; // To be filled by loader
> +		};
> +		cpu1: cpu@1 {
> +			compatible = "AAPL,icestorm";
> +			device_type = "cpu";
> +			reg = <0x0 0x1>;
> +			enable-method = "spin-table";
> +			cpu-release-addr = <0 0>; // To be filled by loader
> +		};
> +		cpu2: cpu@2 {
> +			compatible = "AAPL,icestorm";
> +			device_type = "cpu";
> +			reg = <0x0 0x2>;
> +			enable-method = "spin-table";
> +			cpu-release-addr = <0 0>; // To be filled by loader
> +		};
> +		cpu3: cpu@3 {
> +			compatible = "AAPL,icestorm";
> +			device_type = "cpu";
> +			reg = <0x0 0x3>;
> +			enable-method = "spin-table";
> +			cpu-release-addr = <0 0>; // To be filled by loader
> +		};
> +		cpu4: cpu@10100 {
> +			compatible = "AAPL,firestorm";
> +			device_type = "cpu";
> +			reg = <0x0 0x10100>;
> +			enable-method = "spin-table";
> +			cpu-release-addr = <0 0>; // To be filled by loader
> +		};
> +		cpu5: cpu@10101 {
> +			compatible = "AAPL,firestorm";
> +			device_type = "cpu";
> +			reg = <0x0 0x10101>;
> +			enable-method = "spin-table";
> +			cpu-release-addr = <0 0>; // To be filled by loader
> +		};
> +		cpu6: cpu@10102 {
> +			compatible = "AAPL,firestorm";
> +			device_type = "cpu";
> +			reg = <0x0 0x10102>;
> +			enable-method = "spin-table";
> +			cpu-release-addr = <0 0>; // To be filled by loader
> +		};
> +		cpu7: cpu@10103 {
> +			compatible = "AAPL,firestorm";
> +			device_type = "cpu";
> +			reg = <0x0 0x10103>;
> +			enable-method = "spin-table";
> +			cpu-release-addr = <0 0>; // To be filled by loader
> +		};
> +	};
> +
> +	timer {
> +		compatible = "arm,armv8-timer";
> +		interrupt-parent = <&aic>;
> +		interrupts = <AIC_FIQ 0 IRQ_TYPE_LEVEL_HIGH>,
> +				<AIC_FIQ 0 IRQ_TYPE_LEVEL_HIGH>,
> +				<AIC_FIQ 1 IRQ_TYPE_LEVEL_HIGH>,
> +				<AIC_FIQ 0 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	clk24: clk24 {

Just "clock". Node names should be generic.

> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <24000000>;
> +		clock-output-names = "clk24";

What clock is it? Part of board or SoC? Isn't it a work-around for
missing clock drivers?

> +	};
> +
> +	soc {
> +		compatible = "simple-bus";
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		aic: interrupt-controller@23b100000 {
> +			compatible = "AAPL,m1-aic", "AAPL,aic";
> +			#interrupt-cells = <3>;
> +			interrupt-controller;
> +			reg = <0x2 0x3b100000 0x0 0x8000>;
> +		};
> +
> +		serial0: serial@235200000 {
> +			compatible = "AAPL,s5l-uart";
> +			reg = <0x2 0x35200000 0x0 0x1000>;
> +			reg-io-width = <4>;
> +			interrupt-parent = <&aic>;
> +			interrupts = <AIC_IRQ 605 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clk24>, <&clk24>;
> +			clock-names = "uart", "clk_uart_baud0";
> +		};
> +

No blank lines at end of blocks.

Best regards,
Krzysztof

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

* Re: [PATCH 15/18] irqchip/apple-aic: Add support for the Apple Interrupt Controller
       [not found]     ` <CAK8P3a25eFFrMG-9QknFZ6Ckc3-gkiLK=jQdnyTMgn-z4X0RHQ@mail.gmail.com>
@ 2021-02-08 11:13       ` Hector Martin 'marcan'
       [not found]       ` <87a6selrkt.wl-maz@kernel.org>
  1 sibling, 0 replies; 82+ messages in thread
From: Hector Martin 'marcan' @ 2021-02-08 11:13 UTC (permalink / raw)
  To: Arnd Bergmann, Marc Zyngier
  Cc: SoC Team, Linux ARM, Rob Herring, linux-kernel, DTML, Olof Johansson

On 08/02/2021 19.29, Arnd Bergmann wrote:
> On Mon, Feb 8, 2021 at 10:25 AM Marc Zyngier <maz@kernel.org> wrote:
>> On Thu, 04 Feb 2021 20:39:48 +0000, Hector Martin <marcan@marcan.st> wrote:
> 
>>> +{
>>> +     return readl(ic->base + reg);
>>
>> Please consider using the _relaxed accessors, as I don't think any of
>> these interacts with memory (apart from IPIs, of course).
> 
> MSI interrupts require serializing with DMA, so at the minimum I think there
> needs to be something that ensures that DMA from device into memory
> has completed before delivering the completion interrupt to a driver. This
> may already be implied when the AIC is entered, but this is hard to know
> without actual hardware specs.
> 

I don't think this can be implied in any case, because if IRQ A fires 
and then the CPU speculates its way through AIC into the IRQ B handler, 
which reads DMA'd memory, then IRQ B fires and it has higher priority 
and *that* is what ends up getting returned from the event register 
first, the execution will commit with an ordering violation.

I'm pretty sure we need *some* level of explicit synchronization between 
reading the event register and actually delivering IRQs downstream. 
Using _relaxed might be okay, but we'd still need something where the 
isb() currently is in aic_handle_irq (though I admit I don't have a 
perfect picture of the memory ordering subtleties involved here yet).

Incidentally, just from the races and problems I've run into with 
trivial tests in m1n1, these CPUs seem to be *very* eager to speculate 
and I suspect they will help uncover race conditions in Linux...

-- 
Hector Martin "marcan" (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
  2021-02-08 11:04   ` Krzysztof Kozlowski
@ 2021-02-08 11:56     ` Hector Martin 'marcan'
  2021-02-08 12:13       ` Krzysztof Kozlowski
                         ` (2 more replies)
  0 siblings, 3 replies; 82+ messages in thread
From: Hector Martin 'marcan' @ 2021-02-08 11:56 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: soc, linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

On 08/02/2021 20.04, Krzysztof Kozlowski wrote:
> apple
> 
> Don't make things different for this one platform (comparing to all
> other platforms). Apple is not that special. :)

AAPL is the old vendor prefix used in the PowerPC era. I'm happy to use 
`apple`, as long as we're OK with having two different prefixes for the 
same vendor, one for PPC and one for ARM64. I've seen opinions go both 
ways on this one :)

>> + * Copyright 2021 Hector Martin <marcan@marcan.st>
> 
> A lot here might be difficult to reverse-egineer or figure out by
> ourself, so usually people rely on vendor sources (the open source
> compliance package). Didn't you receive such for the iOS (or whatever
> was on your Mac)?

Apple source drops are sparse (they don't even include things like the 
irqchip driver, only the very core OS code) and APSL licensed, which is 
a license incompatible with the GPL. Worse, they've moved to a 
partial-blob model with the M1; M1-compatible XNU source code drops now 
include a .a blob with startup and CPU-specific code, for which no 
source code is provided. (to be clear: Apple does not ship Linux for 
these machines)

Honestly, beyond what's in this patchset and a few more details about 
CPU registers like performance monitoring stuff that exist in public XNU 
drops but I haven't looked into yet, Apple's source code drops are going 
to be practically useless to us from here on out. It's all binaries 
after this.

Apple device trees are not open source at all; those are provided by 
iBoot and ship with device firmware, which is not openly licensed. Those 
device trees are OF-inspired, but otherwise in a different format and 
structure to Linux device trees.

Since there is zero Apple-published code or data with a license 
compatible with the Linux kernel to be used here, there can be zero 
copyright lines claiming any submissions are copyright Apple from us, 
because that would imply a license violation has occurred. I am treating 
this as I would any other no-source reverse engineering project, that 
is, ensuring that I only look at Apple code (binaries, source, 
devicetrees, whatever) to understand how the hardware functions, build 
documentation for it (at least in my head, but I am also trying to 
document things on our wiki as I go), and then write original code to 
drive it from Linux, unrelated to whatever Apple was doing.

We're also trying to avoid looking at any Apple stuff in general as much 
as possible, preferring black-box approaches where feasible, to minimize 
exposure. For example, I only looked at an (outdated, arm32 era) AIC 
register name list in XNU to write the AIC driver; there is no actual 
AIC driver code in the source, and instead of decompiling Apple's binary 
blob AIC driver module, I figured out how the hardware actually worked 
via probing and experimentation. The entire userspace GPU stack is being 
reverse engineered via a black-box approach, without any decompilation. 
I'm going to see what I can do about the kernel driver in the future, 
and prefer some kind of mmio tracing solution if I can get it all to 
work on macOS.

As for this file specifically: while I am obviously looking at Apple's 
DTs to figure out things like register offsets and what hardware exists, 
those are facts, and facts are not copyrightable, and thus Apple does 
not hold any copyright interest over this code as I submitted it. Short 
of verbatim copying and pasting of entire nodes with bespoke property 
names (which would never fly here anyway because Apple does things very 
differently from Linux DTs when you get down into the details), it would 
be extremely hard to argue that translating hardware information from 
decompiled Apple DTs to Linux DTs would constitute a copyright 
violation, since the entire purpose of DTs is to describe hardware facts.

You can read more about our reverse engineering and copyright policy at 
https://alx.sh/re - if you have any suggestions or spot anything 
problematic, please let me know.

(I'm actually probably going to change that copyright line to "The Asahi 
Linux Contributors" for v2, if that's okay with the kernel folks, to be 
in line with our other projects; I defaulted to my name since so far I'm 
the only contributor to these files, but I expect other people to throw 
PRs at me in the future and the history to end up with more names here)

> I guess Rob will comment on the dt-bindings more... but for me a generic
> "arm-platform" is too generic. What's the point of it? I didn't see any
> of such generic compatibles in other platforms.

This is a hack for patches #11/#12 to use, and I expect it will go away 
once we figure out how to properly handle that problem (which needs 
further discussion). Sorry for the noise, this should not be there in 
the final version.

>> +		bootargs = "earlycon";
> 
> This should not be hard-coded in DTS. Pass it from bootloader.

My apologies, this was garbage left over from before I had bootargs 
support in the bootloader. Will be gone for v2.

>> +	clk24: clk24 {
> 
> Just "clock". Node names should be generic.

Really? Almost every other device device tree uses unique clock node names.

>> +		compatible = "fixed-clock";
>> +		#clock-cells = <0>;
>> +		clock-frequency = <24000000>;
>> +		clock-output-names = "clk24";
> 
> What clock is it? Part of board or SoC? Isn't it a work-around for
> missing clock drivers?

The clock topology isn't entirely known yet; I'm submitting this as an 
initial bring-up patchset and indeed there should be a clockchip driver 
in the future. The UART driver wants a clock to be able to calculate 
baud rates. I figured we can get away with a fixed-clock for now while 
that part of the SoC gets figured out.

Ack on all the other comments, will fix for v2.

Thanks for the review!

-- 
Hector Martin "marcan" (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
  2021-02-08 11:56     ` Hector Martin 'marcan'
@ 2021-02-08 12:13       ` Krzysztof Kozlowski
       [not found]         ` <CAK8P3a0yBC3dui6vcz+NByWD-3LqRj-2MF89jpjb_k8r5xmNRA@mail.gmail.com>
  2021-02-08 19:14       ` Rob Herring
  2021-02-10 10:19       ` Tony Lindgren
  2 siblings, 1 reply; 82+ messages in thread
From: Krzysztof Kozlowski @ 2021-02-08 12:13 UTC (permalink / raw)
  To: Hector Martin 'marcan'
  Cc: soc, linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

On Mon, Feb 08, 2021 at 08:56:53PM +0900, Hector Martin 'marcan' wrote:
> On 08/02/2021 20.04, Krzysztof Kozlowski wrote:
> > apple
> > 
> > Don't make things different for this one platform (comparing to all
> > other platforms). Apple is not that special. :)
> 
> AAPL is the old vendor prefix used in the PowerPC era. I'm happy to use
> `apple`, as long as we're OK with having two different prefixes for the same
> vendor, one for PPC and one for ARM64. I've seen opinions go both ways on
> this one :)

Thanks for explanation. I propose to choose just "apple". Sticking to
old vendor name is not a requirement - we have few vendor prefixes which
were marked as deprecated because we switched to a better one.

> 
> > > + * Copyright 2021 Hector Martin <marcan@marcan.st>
> > 
> > A lot here might be difficult to reverse-egineer or figure out by
> > ourself, so usually people rely on vendor sources (the open source
> > compliance package). Didn't you receive such for the iOS (or whatever
> > was on your Mac)?
> 
> Apple source drops are sparse (they don't even include things like the
> irqchip driver, only the very core OS code) and APSL licensed, which is a
> license incompatible with the GPL. Worse, they've moved to a partial-blob
> model with the M1; M1-compatible XNU source code drops now include a .a blob
> with startup and CPU-specific code, for which no source code is provided.
> (to be clear: Apple does not ship Linux for these machines)
> 
> Honestly, beyond what's in this patchset and a few more details about CPU
> registers like performance monitoring stuff that exist in public XNU drops
> but I haven't looked into yet, Apple's source code drops are going to be
> practically useless to us from here on out. It's all binaries after this.
> 
> Apple device trees are not open source at all; those are provided by iBoot
> and ship with device firmware, which is not openly licensed. Those device
> trees are OF-inspired, but otherwise in a different format and structure to
> Linux device trees.
> 
> Since there is zero Apple-published code or data with a license compatible
> with the Linux kernel to be used here, there can be zero copyright lines
> claiming any submissions are copyright Apple from us, because that would
> imply a license violation has occurred. I am treating this as I would any
> other no-source reverse engineering project, that is, ensuring that I only
> look at Apple code (binaries, source, devicetrees, whatever) to understand
> how the hardware functions, build documentation for it (at least in my head,
> but I am also trying to document things on our wiki as I go), and then write
> original code to drive it from Linux, unrelated to whatever Apple was doing.

Makes sense. In such case it's indeed your work. Since you introduce it,
the DTSes are usually licensed with (GPL-2.0+ OR MIT).

> 
> We're also trying to avoid looking at any Apple stuff in general as much as
> possible, preferring black-box approaches where feasible, to minimize
> exposure. For example, I only looked at an (outdated, arm32 era) AIC
> register name list in XNU to write the AIC driver; there is no actual AIC
> driver code in the source, and instead of decompiling Apple's binary blob
> AIC driver module, I figured out how the hardware actually worked via
> probing and experimentation. The entire userspace GPU stack is being reverse
> engineered via a black-box approach, without any decompilation. I'm going to
> see what I can do about the kernel driver in the future, and prefer some
> kind of mmio tracing solution if I can get it all to work on macOS.
> 
> As for this file specifically: while I am obviously looking at Apple's DTs
> to figure out things like register offsets and what hardware exists, those
> are facts, and facts are not copyrightable, and thus Apple does not hold any
> copyright interest over this code as I submitted it. Short of verbatim
> copying and pasting of entire nodes with bespoke property names (which would
> never fly here anyway because Apple does things very differently from Linux
> DTs when you get down into the details), it would be extremely hard to argue
> that translating hardware information from decompiled Apple DTs to Linux DTs
> would constitute a copyright violation, since the entire purpose of DTs is
> to describe hardware facts.
> 
> You can read more about our reverse engineering and copyright policy at
> https://alx.sh/re - if you have any suggestions or spot anything
> problematic, please let me know.
> 
> (I'm actually probably going to change that copyright line to "The Asahi
> Linux Contributors" for v2, if that's okay with the kernel folks, to be in
> line with our other projects; I defaulted to my name since so far I'm the
> only contributor to these files, but I expect other people to throw PRs at
> me in the future and the history to end up with more names here)

The copyrights matter more in case the need to relicense the work or
some copyright-infringement cases. If you use generic alias - The Asahi
contributors - how it would be possible to find people with actual
copyrights? For example to ask them about relicense permission?  Unless
it's an official body (e.g. foundation or company).  Therefore I propose
to stick to real names and include other contributors once they
contribute.

However this are just my thoughts, not a really professional opinion
about copyright aspects.

> 
> > I guess Rob will comment on the dt-bindings more... but for me a generic
> > "arm-platform" is too generic. What's the point of it? I didn't see any
> > of such generic compatibles in other platforms.
> 
> This is a hack for patches #11/#12 to use, and I expect it will go away once
> we figure out how to properly handle that problem (which needs further
> discussion). Sorry for the noise, this should not be there in the final
> version.
> 
> > > +		bootargs = "earlycon";
> > 
> > This should not be hard-coded in DTS. Pass it from bootloader.
> 
> My apologies, this was garbage left over from before I had bootargs support
> in the bootloader. Will be gone for v2.
> 
> > > +	clk24: clk24 {
> > 
> > Just "clock". Node names should be generic.
> 
> Really? Almost every other device device tree uses unique clock node names.

Yes, really, devicetree/ePAPR spec:
"The name of a node should be somewhat generic, reflecting the function
of the device and not its precise programming model. If appropriate, the
name should be one of the following choices:"

Multiple other boards and people (including myself...) made the same
mistake of adding specific names. Even some platform maintainers still
don't get it or never cared to look at DT spec. :)

> 
> > > +		compatible = "fixed-clock";
> > > +		#clock-cells = <0>;
> > > +		clock-frequency = <24000000>;
> > > +		clock-output-names = "clk24";
> > 
> > What clock is it? Part of board or SoC? Isn't it a work-around for
> > missing clock drivers?
> 
> The clock topology isn't entirely known yet; I'm submitting this as an
> initial bring-up patchset and indeed there should be a clockchip driver in
> the future. The UART driver wants a clock to be able to calculate baud
> rates. I figured we can get away with a fixed-clock for now while that part
> of the SoC gets figured out.

Such workaround is ok, but maybe add a comment that it's a workaround so
far.

Best regards,
Krzysztof


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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
       [not found]         ` <CAK8P3a0yBC3dui6vcz+NByWD-3LqRj-2MF89jpjb_k8r5xmNRA@mail.gmail.com>
@ 2021-02-08 14:12           ` Hector Martin
  2021-02-08 17:58             ` Rob Herring
  0 siblings, 1 reply; 82+ messages in thread
From: Hector Martin @ 2021-02-08 14:12 UTC (permalink / raw)
  To: Arnd Bergmann, Krzysztof Kozlowski
  Cc: SoC Team, Linux ARM, Marc Zyngier, Rob Herring, linux-kernel,
	DTML, Olof Johansson

On 08/02/2021 21.40, Arnd Bergmann wrote:
> On Mon, Feb 8, 2021 at 1:13 PM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>>
>> On Mon, Feb 08, 2021 at 08:56:53PM +0900, Hector Martin 'marcan' wrote:
>>> On 08/02/2021 20.04, Krzysztof Kozlowski wrote:
>>>> apple
>>>>
>>>> Don't make things different for this one platform (comparing to all
>>>> other platforms). Apple is not that special. :)
>>>
>>> AAPL is the old vendor prefix used in the PowerPC era. I'm happy to use
>>> `apple`, as long as we're OK with having two different prefixes for the same
>>> vendor, one for PPC and one for ARM64. I've seen opinions go both ways on
>>> this one :)
>>
>> Thanks for explanation. I propose to choose just "apple". Sticking to
>> old vendor name is not a requirement - we have few vendor prefixes which
>> were marked as deprecated because we switched to a better one.
> 
> We've gone back and forth on this a few times already. My current
> preference would also be to go with "apple", not because it's somehow
> nicer or clearer but because it avoids the namespace conflict with
> what the Apple firmware uses:

Ack, I'll use 'apple' for v2.

Amusingly, Apple actually use 'apple,firestorm' and 'apple,icestorm' for 
the CPUs in their devicetrees for these machines, so those will end up 
identical :) (they don't use apple-related prefixes for any other 
compatible strings at all, it's a mess). But we don't care about what 
their ADTs (Apple DTs) do in Linux anyway, the bootloader abstracts all 
that out and we'll be dealing with mantaining proper DTs ourselves.

>> Makes sense. In such case it's indeed your work. Since you introduce it,
>> the DTSes are usually licensed with (GPL-2.0+ OR MIT).
> 
> Indeed, we do want other OSs to use our dts files, so the general
> preference is to have a permissive license, unless you have a strong
> reason yourself to require GPL-only.

Thanks for pointing this out; this was actually unintentional. I based 
it off of an old dts I'd written ages ago and forgot to revisit the 
license. I even have it marked GPL-2.0+ in the copy in our bootloader 
repo, which is otherwise supposed to be MIT for original code...

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
       [not found]   ` <a2825482e2f68c2f8cad7cb564414759@kernel.org>
@ 2021-02-08 14:53     ` Hector Martin
  0 siblings, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-08 14:53 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: soc, linux-arm-kernel, robh+dt, Arnd Bergmann, linux-kernel,
	devicetree, Olof Johansson

On 08/02/2021 21.27, Marc Zyngier wrote:
>> +	timer {
>> +		compatible = "arm,armv8-timer";
>> +		interrupt-parent = <&aic>;
>> +		interrupts = <AIC_FIQ 0 IRQ_TYPE_LEVEL_HIGH>,
>> +				<AIC_FIQ 0 IRQ_TYPE_LEVEL_HIGH>,
>> +				<AIC_FIQ 1 IRQ_TYPE_LEVEL_HIGH>,
>> +				<AIC_FIQ 0 IRQ_TYPE_LEVEL_HIGH>;
> 
> This unfortunately doesn't match the binding, which doesn't cater
> for systems without a secure physical timer, nor allows the description
> of the EL2 virtual timer.
> 
> You should also have *different* interrupts for EL1 and EL2 timers,
> although this is all a lie...

Well, we do - now that I confirmed all 4 timers work properly, the AIC 
driver should provide all 4. And ideally I find those EL1 timer mask 
bits and implement them in the aic driver too (for only the virt timers 
that have them and of course need them).

I just found the code in arm_arch_timer that forwards all this stuff to 
the kvm code, so it all makes sense now; if I can wire that up properly, 
heck, KVM might even just work here.

> 
> Looking at the only similar case, XGene lies about the secure timer
> (it doesn't have any), and of course doesn't have an EL2 virtual
> timer (ARMv8.0 only).
> 
> A sensible course of action could be to update the binding to at least:
> 
> - tell the kernel that there is no secure physical timer (and that
>     the interrupt should be ignored)
> - introduce a 5th possible interrupt for the EL2 virtual timer.

Sounds like I should be introducing interrupt-names support into this 
driver and using that, so we can just not specify IRQs that don't exist, 
instead of the hack with dummies. Falling back to indexes of course, to 
keep DT compat. i.e.

const char *names = {"phys-secure", "phys", "virt", "hyp-phys", "hyp-virt"};

bool has_names = of_property_read_bool(..., "interrupt-names");

for (each irq)
	if (has_names) foo = of_irq_get_byname(..., names[i])
	else foo = of_irq_get(..., i)

That said, is there a use case for the EL2 virtual timer? The driver 
always uses the EL2 physical timer with VHE right now. I guess it's 
worth describing it in the binding and dts, even if the driver never 
selects it...?

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 15/18] irqchip/apple-aic: Add support for the Apple Interrupt Controller
       [not found]       ` <87a6selrkt.wl-maz@kernel.org>
@ 2021-02-08 15:31         ` Hector Martin
  0 siblings, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-08 15:31 UTC (permalink / raw)
  To: Marc Zyngier, Arnd Bergmann
  Cc: SoC Team, Linux ARM, Rob Herring, linux-kernel, DTML, Olof Johansson

On 08/02/2021 20.36, Marc Zyngier wrote:
> On Mon, 08 Feb 2021 10:29:23 +0000,
> Arnd Bergmann <arnd@kernel.org> wrote:
>>
>> On Mon, Feb 8, 2021 at 10:25 AM Marc Zyngier <maz@kernel.org> wrote:
>>> On Thu, 04 Feb 2021 20:39:48 +0000, Hector Martin <marcan@marcan.st> wrote:
>>
>>>> +{
>>>> +     return readl(ic->base + reg);
>>>
>>> Please consider using the _relaxed accessors, as I don't think any of
>>> these interacts with memory (apart from IPIs, of course).
>>
>> MSI interrupts require serializing with DMA, so at the minimum I think there
>> needs to be something that ensures that DMA from device into memory
>> has completed before delivering the completion interrupt to a driver. This
>> may already be implied when the AIC is entered, but this is hard to know
>> without actual hardware specs.
> 
> If there is a sync with memory required, it should happen at the point
> where it is Acked, not when masked/unmasked or anything else. And
> given that you want to sync with an external agent (the DMA producer),
> the DMB generated by readl won't save you, as it only orders CPU
> accesses AFAICT.

Found an doc that talks about this, but then... how does the current 
Linux code work anyway for normal use cases?

https://elinux.org/images/7/73/Deacon-weak-to-weedy.pdf

That says dmb is not enough for DMA-control to DMA-data dependencies due 
to speculation, which is what we have here and the situation I described 
(with an IRQ along the way, but that's irrelevant). But that's what 
readl does: a read followed by a dmb(oshld) followed by a control 
dependency (but that needs an isb to take effect). How does this not 
break drivers that read DMA-accessed memory after a readl of a status 
register? I thought that was the point of the non-relaxed functions.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 11/18] arm64: Kconfig: Require FIQ support for ARCH_APPLE
       [not found]       ` <2a93bf0df74df8cb022e61d69d1de88e@kernel.org>
@ 2021-02-08 15:48         ` Hector Martin
  0 siblings, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-08 15:48 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: soc, linux-arm-kernel, robh+dt, Arnd Bergmann, linux-kernel,
	devicetree, Olof Johansson

On 08/02/2021 21.05, Marc Zyngier wrote:
>> I was trying to introduce the Kconfig before the code that depends on
>> it; is it kosher to have it in the other order, looking for CONFIG_
>> defines that don't exist yet?
> 
> Absolutely. The only requirement is to make sure that nothing breaks in
> the middle of a series.
> 
>> Though in this case the only user earlier in the series is the Samsung
>> stuff, which doesn't care about FIQs, so I can just sort things as
>> FIQ->ARCH_APPLE->samsung->AIC...
> 
> Seems fine to me. Sorting out the infrastructure first (FIQ, memory
> attributes) first is a requirement anyway, so the ordering of the
> series could reflect that priority.

Cool, that simplifies things.

>> I'm not sure about AIC vs. ARCH_APPLE though. Right now the pattern is
>> that AIC depends on ARCH_APPLE and also defaults to that. But then you
>> can build with ARCH_APPLE and AIC disabled if you so choose, which
>> does result in a broken system on these machines. AIC should build
>> without ARCH_APPLE (as long as we're on ARM64), so we could reverse
>> that.
> 
> As long as ARCH_APPLE selects AIC, you can make AIC selectable on
> its own. What I'm trying to avoid is people ending up with an unbootable
> system, and not having interrupts is one thing that makes it really hard
> to debug...

Sounds good, I'll flip it over.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 08/18] arm64: cpufeature: Add a feature for FIQ support
       [not found]       ` <87czxalrwc.wl-maz@kernel.org>
@ 2021-02-08 15:51         ` Hector Martin
  0 siblings, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-08 15:51 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: soc, linux-arm-kernel, robh+dt, Arnd Bergmann, linux-kernel,
	devicetree, Olof Johansson

On 08/02/2021 20.29, Marc Zyngier wrote:
> I'm not sure we want to trust the FW on that particular front (no
> offence intended...;-).

Hey, I don't even *use* the timers IRQs; if they are unmasked it's 
iBoot's fault! :-)

> That is my current take on this patch. Nothing in the arm64 kernel
> expects a FIQ today, so *when* a FIQ fires is pretty much irrelevant,
> as long as we handle it properly (panic). Keeping the two bits in sync
> is trivial, and shouldn't carry material overhead.

Sounds good then, and again that simplifies a ton of stuff. Will go for 
that in v2.

> Aside from the lack of programmable priority, the lack of convenient
> masking for per-CPU interrupts is a bit of an issue...

Yeah... we'll see how that goes.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 05/18] tty: serial: samsung_tty: add support for Apple UARTs
  2021-02-08 10:54   ` Krzysztof Kozlowski
@ 2021-02-08 16:10     ` Hector Martin
  2021-02-08 18:37       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 82+ messages in thread
From: Hector Martin @ 2021-02-08 16:10 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: soc, linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

On 08/02/2021 19.54, Krzysztof Kozlowski wrote:
>> +enum s3c24xx_irq_type {
>> +	IRQ_DISCRETE = 0,
>> +	IRQ_S3C6400 = 1,
>> +	IRQ_APPLE = 2,
> 
> It seems you add the third structure to differentiate type of UART.
> There is already port type and s3c24xx_serial_drv_data, no need for
> third structure (kind of similar to tries of Tamseel Shams in recent
> patches). It's too much. Instead, differentiate by port type or prepare
> own set of uart_ops if it's really different (like you did with startup
> op).

This ties into little changes in a bunch of places, so separate uart_ops 
  callbacks for every one of those would end up duplicating a lot of code :(

That list is just used to map the port type to something that only 
represents the type of IRQs, but its only real purpose for the 
indirection is so I can do "== IRQ_DISCRETE" in some codepaths to mean 
"not apple or S3C6400".

e.g.

     if (s3c24xx_irq_type(port) == IRQ_DISCRETE)
         free_irq(ourport->rx_irq, ourport);

Would have to become

     if (port->type != IRQ_S3C6400 && port->type != IRQ_APPLE)
         free_irq(ourport->rx_irq, ourport);

or

     switch (port->type) {
     case IRQ_S3C6400:
     case IRQ_APPLE:
         break;
     default:
         free_irq(ourport->rx_irq, ourport);
     }

Which one do you prefer?

Aside: Marc didn't like introducing new port types into uapi, but if we 
don't do that then we need a "real" port type in drv_data that isn't the 
uapi-exposed port or something along those lines, with a separate enum 
containing all the true port type values for that.

>>   	/* Startup sequence is different for s3c64xx and higher SoC's */
>> -	if (s3c24xx_serial_has_interrupt_mask(port))
>> +	case IRQ_S3C6400:
>>   		s3c24xx_serial_ops.startup = s3c64xx_serial_startup;
> 
> Don't overwrite specific ops. It's difficult to see then which ops are
> being used. Instead create a new set of uart_ops matching the needs.

s3c24xx_serial_ops was already doing that here, but I can move that to a 
a separate uart_ops too.

Ack on all the other comments, I'll make the changes for v2.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 05/18] tty: serial: samsung_tty: add support for Apple UARTs
  2021-02-08  9:36         ` Krzysztof Kozlowski
@ 2021-02-08 16:14           ` Hector Martin
  0 siblings, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-08 16:14 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Marc Zyngier, soc, linux-arm-kernel, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

On 08/02/2021 18.36, Krzysztof Kozlowski wrote:
> Please use the scripts/get_maintainers.pl to get the list of people to
> Cc. The script would point necessary folks.

I thought I'd try Thomas first since he introduced the IRQF_SHARED 
specifically, but I should've gone straight to maintainers (I did use 
get_maintainers.pl to find you).

> A different issue is that all your emails from this thread were marked
> by Google as spam.  I don't see any particular warning signs in the
> header so it looks more of content-based match for spam.

That's weird. Maybe it's because my server doesn't do DKIM yet, and they 
went through a mailing list? It's probably time to set that up...

>>> Either way, certainly not for Apple SoCs; I'll get rid of IRQF_SHARED
>>> for v2.
> 
> Please send a v2 after fixing issues pointed out by kbuild.

Will do, already have those fixed in my WIP tree.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 05/18] tty: serial: samsung_tty: add support for Apple UARTs
       [not found]       ` <73116feaa00de9173d1f2c35ce16e08f@kernel.org>
@ 2021-02-08 16:18         ` Hector Martin
       [not found]           ` <YCFq3DqOzv4//6Vw@kroah.com>
  0 siblings, 1 reply; 82+ messages in thread
From: Hector Martin @ 2021-02-08 16:18 UTC (permalink / raw)
  To: Marc Zyngier, Greg Kroah-Hartman
  Cc: soc, linux-arm-kernel, robh+dt, Arnd Bergmann, linux-kernel,
	devicetree, Olof Johansson, Krzysztof Kozlowski

On 08/02/2021 19.34, Marc Zyngier wrote:
> On 2021-02-07 09:12, Hector Martin 'marcan' wrote:
>> On 06/02/2021 22.15, Marc Zyngier wrote:
>>> Do you actually need a new port type here? Looking at the driver
>>> itself, it is mainly used to work out the IRQ model. Maybe introducing
>>> a new irq_type field in the port structure would be better than
>>> exposing this to userspace (which should see something that is exactly
>>> the same as a S3C UART).
>>
>> Well... every S3C variant already has its own port type here.
>>
>> #define PORT_S3C2410    55
>> #define PORT_S3C2440    61
>> #define PORT_S3C2400    67
>> #define PORT_S3C2412    73
>> #define PORT_S3C6400    84
>>
>> If we don't introduce a new one, which one should we pretend to be? :)
> 
> Pick one! :D

*queries /dev/urandom* :-)

>> I agree that it might make sense to merge all of these into one,
>> though; I don't know what the original reason for splitting them out
>> is. But now that they're part of the userspace API, this might not be
>> a good idea. Though, unsurprisingly, some googling suggests there are
>> zero users of these defines in userspace.
> 
> I don't think we can do that, but I don't think we should keep adding
> to this unless there is a very good reason. Greg would know, I expect.

Greg, what do you think? Add more PORT_ UART types for Samsung variants, 
or overload one of the existing ones and deal with it in the driver?

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 01/18] dt-bindings: vendor-prefixes: add AAPL prefix
  2021-02-08 10:27   ` Krzysztof Kozlowski
@ 2021-02-08 17:32     ` Rob Herring
  2021-02-08 18:12       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 82+ messages in thread
From: Rob Herring @ 2021-02-08 17:32 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Hector Martin, Arnd Bergmann, devicetree, Marc Zyngier,
	linux-kernel, soc, Olof Johansson, linux-arm-kernel

On Mon, Feb 08, 2021 at 11:27:30AM +0100, Krzysztof Kozlowski wrote:
> On Fri, Feb 05, 2021 at 05:39:34AM +0900, Hector Martin wrote:
> > Amusingly, this wasn't yet documented, even though this vendor prefix
> > has been used since time immemorial on PPC.
> > 
> > Signed-off-by: Hector Martin <marcan@marcan.st>
> > ---
> >  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> > index 041ae90b0d8f..d7950c723472 100644
> > --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
> > +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> > @@ -25,6 +25,8 @@ patternProperties:
> >    # Keep list in alphabetical order.
> >    "^70mai,.*":
> >      description: 70mai Co., Ltd.
> > +  "^AAPL,.*":
> 
> All prefixes are lower case... see ABB below (not mentioning that the
> company name is not APPLE), so just "apple".

Grep the kernel tree for 'AAPL,'. It comes from the the ticker symbol 
which early on was the preferred form, but we've tended to move away 
from that. The DT Apple ships (which is *very* different) uses both 
forms.

So keep what exists already or have old AAPL and new apple?

Rob

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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
  2021-02-08 14:12           ` Hector Martin
@ 2021-02-08 17:58             ` Rob Herring
  2021-02-09  0:32               ` Hector Martin
  0 siblings, 1 reply; 82+ messages in thread
From: Rob Herring @ 2021-02-08 17:58 UTC (permalink / raw)
  To: Hector Martin
  Cc: Arnd Bergmann, Krzysztof Kozlowski, DTML, Marc Zyngier,
	linux-kernel, SoC Team, Olof Johansson, Linux ARM

On Mon, Feb 08, 2021 at 11:12:52PM +0900, Hector Martin wrote:
> On 08/02/2021 21.40, Arnd Bergmann wrote:
> > On Mon, Feb 8, 2021 at 1:13 PM Krzysztof Kozlowski <krzk@kernel.org> wrote:
> > > 
> > > On Mon, Feb 08, 2021 at 08:56:53PM +0900, Hector Martin 'marcan' wrote:
> > > > On 08/02/2021 20.04, Krzysztof Kozlowski wrote:
> > > > > apple
> > > > > 
> > > > > Don't make things different for this one platform (comparing to all
> > > > > other platforms). Apple is not that special. :)
> > > > 
> > > > AAPL is the old vendor prefix used in the PowerPC era. I'm happy to use
> > > > `apple`, as long as we're OK with having two different prefixes for the same
> > > > vendor, one for PPC and one for ARM64. I've seen opinions go both ways on
> > > > this one :)
> > > 
> > > Thanks for explanation. I propose to choose just "apple". Sticking to
> > > old vendor name is not a requirement - we have few vendor prefixes which
> > > were marked as deprecated because we switched to a better one.
> > 
> > We've gone back and forth on this a few times already. My current
> > preference would also be to go with "apple", not because it's somehow
> > nicer or clearer but because it avoids the namespace conflict with
> > what the Apple firmware uses:

It's only AAPL,phandle and AAPL,unit-string (equivalent to unit-address) 
AFAICT which are really internal format details. So it's really 'apple' 
that could conflct, but I can't see that mattering.

> Ack, I'll use 'apple' for v2.

3 votes for 'apple'. You all get to pick the color of this shed.

> Amusingly, Apple actually use 'apple,firestorm' and 'apple,icestorm' for the
> CPUs in their devicetrees for these machines, so those will end up identical
> :) (they don't use apple-related prefixes for any other compatible strings
> at all, it's a mess). But we don't care about what their ADTs (Apple DTs) do
> in Linux anyway, the bootloader abstracts all that out and we'll be dealing
> with mantaining proper DTs ourselves.
> 
> > > Makes sense. In such case it's indeed your work. Since you introduce it,
> > > the DTSes are usually licensed with (GPL-2.0+ OR MIT).
> > 
> > Indeed, we do want other OSs to use our dts files, so the general
> > preference is to have a permissive license, unless you have a strong
> > reason yourself to require GPL-only.
> 
> Thanks for pointing this out; this was actually unintentional. I based it
> off of an old dts I'd written ages ago and forgot to revisit the license. I
> even have it marked GPL-2.0+ in the copy in our bootloader repo, which is
> otherwise supposed to be MIT for original code...

I'll also highlight there's a DT only tree[1] available to import DT 
related parts to other projects. It's generated from the kernel tree. 
Probably an overkill to copying at this point though.

Rob

[1] https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git/

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

* Re: [PATCH 01/18] dt-bindings: vendor-prefixes: add AAPL prefix
  2021-02-08 17:32     ` Rob Herring
@ 2021-02-08 18:12       ` Krzysztof Kozlowski
  2021-02-08 23:17         ` Hector Martin
  0 siblings, 1 reply; 82+ messages in thread
From: Krzysztof Kozlowski @ 2021-02-08 18:12 UTC (permalink / raw)
  To: Rob Herring
  Cc: Hector Martin, Arnd Bergmann, devicetree, Marc Zyngier,
	linux-kernel, soc, Olof Johansson, linux-arm-kernel

On Mon, Feb 08, 2021 at 11:32:15AM -0600, Rob Herring wrote:
> On Mon, Feb 08, 2021 at 11:27:30AM +0100, Krzysztof Kozlowski wrote:
> > On Fri, Feb 05, 2021 at 05:39:34AM +0900, Hector Martin wrote:
> > > Amusingly, this wasn't yet documented, even though this vendor prefix
> > > has been used since time immemorial on PPC.
> > > 
> > > Signed-off-by: Hector Martin <marcan@marcan.st>
> > > ---
> > >  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
> > >  1 file changed, 2 insertions(+)
> > > 
> > > diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> > > index 041ae90b0d8f..d7950c723472 100644
> > > --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
> > > +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> > > @@ -25,6 +25,8 @@ patternProperties:
> > >    # Keep list in alphabetical order.
> > >    "^70mai,.*":
> > >      description: 70mai Co., Ltd.
> > > +  "^AAPL,.*":
> > 
> > All prefixes are lower case... see ABB below (not mentioning that the
> > company name is not APPLE), so just "apple".
> 
> Grep the kernel tree for 'AAPL,'.

I know it's the ticker, but the point was - we don't use tickers here
for none of other platforms.

Mentioned grep brings only one result:
arch/powerpc/platforms/powermac/pic.c:   * cases where the APPL,interrupts property is completely

so hardly an argument for backwards consistency, within the kernel.

On the other hand, some DTs for iPhones mention "apple", not APPL:
https://www.theiphonewiki.com/wiki/D211AP/Device_Tree
https://www.theiphonewiki.com/wiki/D331AP/Device_Tree
https://gist.github.com/bazad/1faef1a6fe396b820a43170b43e38be1

Although I am not sure how reliable are the sources.

> It comes from the the ticker symbol 
> which early on was the preferred form, but we've tended to move away 
> from that. The DT Apple ships (which is *very* different) uses both 
> forms.
> 
> So keep what exists already or have old AAPL and new apple?

Hectore mention old PowerPC Apple sources were using the APPL, but it
seems they did not end up here. What would be the point to stick to the
old prefix if we cannot find it?

Maybe they exists in other systems? I could not find such in latest
FreeBSD, but there were not many DTSes inside.

Best regards,
Krzysztof

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

* Re: [PATCH 05/18] tty: serial: samsung_tty: add support for Apple UARTs
  2021-02-08 16:10     ` Hector Martin
@ 2021-02-08 18:37       ` Krzysztof Kozlowski
  2021-02-08 23:23         ` Hector Martin
  0 siblings, 1 reply; 82+ messages in thread
From: Krzysztof Kozlowski @ 2021-02-08 18:37 UTC (permalink / raw)
  To: Hector Martin
  Cc: soc, linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

On Tue, Feb 09, 2021 at 01:10:02AM +0900, Hector Martin wrote:
> On 08/02/2021 19.54, Krzysztof Kozlowski wrote:
> > > +enum s3c24xx_irq_type {
> > > +	IRQ_DISCRETE = 0,
> > > +	IRQ_S3C6400 = 1,
> > > +	IRQ_APPLE = 2,
> > 
> > It seems you add the third structure to differentiate type of UART.
> > There is already port type and s3c24xx_serial_drv_data, no need for
> > third structure (kind of similar to tries of Tamseel Shams in recent
> > patches). It's too much. Instead, differentiate by port type or prepare
> > own set of uart_ops if it's really different (like you did with startup
> > op).
> 
> This ties into little changes in a bunch of places, so separate uart_ops
> callbacks for every one of those would end up duplicating a lot of code :(
> 
> That list is just used to map the port type to something that only
> represents the type of IRQs, but its only real purpose for the indirection
> is so I can do "== IRQ_DISCRETE" in some codepaths to mean "not apple or
> S3C6400".
> 
> e.g.
> 
>     if (s3c24xx_irq_type(port) == IRQ_DISCRETE)
>         free_irq(ourport->rx_irq, ourport);
> 
> Would have to become
> 
>     if (port->type != IRQ_S3C6400 && port->type != IRQ_APPLE)
>         free_irq(ourport->rx_irq, ourport);
> 
> or
> 
>     switch (port->type) {
>     case IRQ_S3C6400:
>     case IRQ_APPLE:
>         break;
>     default:
>         free_irq(ourport->rx_irq, ourport);
>     }
> 
> Which one do you prefer?

The latter, especially that switches will appear quite a lot in such
case.

However this pattern (== IRQ_DISCRETE) appears only in three places so
it should not be the main case considered here.

However I saw later you actually replaced the
s3c24xx_serial_has_interrupt_mask(), so it's not that bad.

In most of your code, there will be actually a switch with all three
cases.

> 
> Aside: Marc didn't like introducing new port types into uapi, but if we
> don't do that then we need a "real" port type in drv_data that isn't the
> uapi-exposed port or something along those lines, with a separate enum
> containing all the true port type values for that.

Looking at Greg's comment, we can get rid of the PORT_ stuff entirely.
First of all, PORT_S3C2410 == PORT_S3C2412, so this define is not
accurate.

This leaves us with three types (s3c2400, s3c2440, s3c6410 and Apple).
The s3c2440 could be removed with adding a new "ucon_mask" field to
s3c24xx_serial_drv_data.

This would end with s3c24xx, s3c6410 and Apple - quite nice choice.

> 
> > >   	/* Startup sequence is different for s3c64xx and higher SoC's */
> > > -	if (s3c24xx_serial_has_interrupt_mask(port))
> > > +	case IRQ_S3C6400:
> > >   		s3c24xx_serial_ops.startup = s3c64xx_serial_startup;
> > 
> > Don't overwrite specific ops. It's difficult to see then which ops are
> > being used. Instead create a new set of uart_ops matching the needs.
> 
> s3c24xx_serial_ops was already doing that here, but I can move that to a a
> separate uart_ops too.

You're right. This one would have to be improved before your change.
Instead of replacing specific op calls in startup, I think it's better
to have entirely separate ops instance for each variant:

static const struct uart_ops s3c24xx_serial_ops;
static const struct uart_ops s3c64xx_serial_ops;
static const struct uart_ops s5l_serial_ops;

This allows to add a "const", since uart_port takes such const pointer.

Still during s3c24xx_serial_probe() correct ops would have to be
assigned, but at least all ops are easily visible.

Best regards,
Krzysztof


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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
  2021-02-08 11:56     ` Hector Martin 'marcan'
  2021-02-08 12:13       ` Krzysztof Kozlowski
@ 2021-02-08 19:14       ` Rob Herring
  2021-02-09  0:49         ` Hector Martin
  2021-02-10 10:19       ` Tony Lindgren
  2 siblings, 1 reply; 82+ messages in thread
From: Rob Herring @ 2021-02-08 19:14 UTC (permalink / raw)
  To: Hector Martin 'marcan'
  Cc: Krzysztof Kozlowski, Arnd Bergmann, devicetree, Marc Zyngier,
	linux-kernel, soc, Olof Johansson, linux-arm-kernel

On Mon, Feb 08, 2021 at 08:56:53PM +0900, Hector Martin 'marcan' wrote:
> On 08/02/2021 20.04, Krzysztof Kozlowski wrote:
> > apple
> > 
> > Don't make things different for this one platform (comparing to all
> > other platforms). Apple is not that special. :)
> 
> AAPL is the old vendor prefix used in the PowerPC era. I'm happy to use
> `apple`, as long as we're OK with having two different prefixes for the same
> vendor, one for PPC and one for ARM64. I've seen opinions go both ways on
> this one :)
> 
> > > + * Copyright 2021 Hector Martin <marcan@marcan.st>
> > 
> > A lot here might be difficult to reverse-egineer or figure out by
> > ourself, so usually people rely on vendor sources (the open source
> > compliance package). Didn't you receive such for the iOS (or whatever
> > was on your Mac)?
> 
> Apple source drops are sparse (they don't even include things like the
> irqchip driver, only the very core OS code) and APSL licensed, which is a
> license incompatible with the GPL. Worse, they've moved to a partial-blob
> model with the M1; M1-compatible XNU source code drops now include a .a blob
> with startup and CPU-specific code, for which no source code is provided.
> (to be clear: Apple does not ship Linux for these machines)
> 
> Honestly, beyond what's in this patchset and a few more details about CPU
> registers like performance monitoring stuff that exist in public XNU drops
> but I haven't looked into yet, Apple's source code drops are going to be
> practically useless to us from here on out. It's all binaries after this.
> 
> Apple device trees are not open source at all; those are provided by iBoot
> and ship with device firmware, which is not openly licensed. Those device
> trees are OF-inspired, but otherwise in a different format and structure to
> Linux device trees.
> 
> Since there is zero Apple-published code or data with a license compatible
> with the Linux kernel to be used here, there can be zero copyright lines
> claiming any submissions are copyright Apple from us, because that would
> imply a license violation has occurred. I am treating this as I would any
> other no-source reverse engineering project, that is, ensuring that I only
> look at Apple code (binaries, source, devicetrees, whatever) to understand
> how the hardware functions, build documentation for it (at least in my head,
> but I am also trying to document things on our wiki as I go), and then write
> original code to drive it from Linux, unrelated to whatever Apple was doing.
> 
> We're also trying to avoid looking at any Apple stuff in general as much as
> possible, preferring black-box approaches where feasible, to minimize
> exposure. For example, I only looked at an (outdated, arm32 era) AIC
> register name list in XNU to write the AIC driver; there is no actual AIC
> driver code in the source, and instead of decompiling Apple's binary blob
> AIC driver module, I figured out how the hardware actually worked via
> probing and experimentation. The entire userspace GPU stack is being reverse
> engineered via a black-box approach, without any decompilation. I'm going to
> see what I can do about the kernel driver in the future, and prefer some
> kind of mmio tracing solution if I can get it all to work on macOS.
> 
> As for this file specifically: while I am obviously looking at Apple's DTs
> to figure out things like register offsets and what hardware exists, those
> are facts, and facts are not copyrightable, and thus Apple does not hold any
> copyright interest over this code as I submitted it. Short of verbatim
> copying and pasting of entire nodes with bespoke property names (which would
> never fly here anyway because Apple does things very differently from Linux
> DTs when you get down into the details), it would be extremely hard to argue
> that translating hardware information from decompiled Apple DTs to Linux DTs
> would constitute a copyright violation, since the entire purpose of DTs is
> to describe hardware facts.
> 
> You can read more about our reverse engineering and copyright policy at
> https://alx.sh/re - if you have any suggestions or spot anything
> problematic, please let me know.
> 
> (I'm actually probably going to change that copyright line to "The Asahi
> Linux Contributors" for v2, if that's okay with the kernel folks, to be in
> line with our other projects; I defaulted to my name since so far I'm the
> only contributor to these files, but I expect other people to throw PRs at
> me in the future and the history to end up with more names here)

Does there need to be a legal entity behind 'The Asahi Linux 
Contributors' to be valid?

From a more practical standpoint, if we want to relicense something in 
say 5 years from now, who do we ask for an okay?

> > I guess Rob will comment on the dt-bindings more... but for me a generic
> > "arm-platform" is too generic. What's the point of it? I didn't see any
> > of such generic compatibles in other platforms.
> 
> This is a hack for patches #11/#12 to use, and I expect it will go away once
> we figure out how to properly handle that problem (which needs further
> discussion). Sorry for the noise, this should not be there in the final
> version.

I was going to ask on this. If you have a user of it, I'm okay with it. 
Generally though, 3 or 4 levels of compatible don't really have users.

> > > +		bootargs = "earlycon";
> > 
> > This should not be hard-coded in DTS. Pass it from bootloader.
> 
> My apologies, this was garbage left over from before I had bootargs support
> in the bootloader. Will be gone for v2.
> 
> > > +	clk24: clk24 {
> > 
> > Just "clock". Node names should be generic.
> 
> Really? Almost every other device device tree uses unique clock node names.

It's a WIP to be more consistent around node names. For actual
clock controllers we have 'clock-controller(@.*)?'. There's not really 
something established for 'fixed-clock'. We probably should define 
something, but that goes in the schema first.

> > > +		compatible = "fixed-clock";
> > > +		#clock-cells = <0>;
> > > +		clock-frequency = <24000000>;
> > > +		clock-output-names = "clk24";
> > 
> > What clock is it? Part of board or SoC? Isn't it a work-around for
> > missing clock drivers?
> 
> The clock topology isn't entirely known yet; I'm submitting this as an
> initial bring-up patchset and indeed there should be a clockchip driver in
> the future. The UART driver wants a clock to be able to calculate baud
> rates. I figured we can get away with a fixed-clock for now while that part
> of the SoC gets figured out.

That is normal. It does break compatibility between an old kernel 
and new DT. There's not really a good way to avoid that.

Rob

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

* Re: [PATCH 01/18] dt-bindings: vendor-prefixes: add AAPL prefix
  2021-02-08 18:12       ` Krzysztof Kozlowski
@ 2021-02-08 23:17         ` Hector Martin
  0 siblings, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-08 23:17 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Rob Herring
  Cc: Arnd Bergmann, devicetree, Marc Zyngier, linux-kernel, soc,
	Olof Johansson, linux-arm-kernel

On 09/02/2021 03.12, Krzysztof Kozlowski wrote:
> Mentioned grep brings only one result:
> arch/powerpc/platforms/powermac/pic.c:   * cases where the APPL,interrupts property is completely

You want to grep for 'AAPL', not 'APPL' :-)

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 13/18] arm64: ioremap: use nGnRnE mappings on platforms that require it
       [not found]   ` <CAK8P3a2Ad+xmmMWgznOHPpxgCXKWFYfpHBqt_49_UuxrwFSq+A@mail.gmail.com>
@ 2021-02-08 23:20     ` Mark Kettenis
  2021-02-09  0:25       ` Hector Martin
  2021-02-10 12:24     ` Hector Martin
  1 sibling, 1 reply; 82+ messages in thread
From: Mark Kettenis @ 2021-02-08 23:20 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: marcan, devicetree, maz, linux-kernel, soc, robh+dt, olof,
	linux-arm-kernel

> From: Arnd Bergmann <arnd@kernel.org>
> Date: Mon, 8 Feb 2021 23:57:20 +0100
> 
> On Thu, Feb 4, 2021 at 9:39 PM Hector Martin <marcan@marcan.st> wrote:
> 
> > (3) Do it at a lower level, in ioremap() itself. This requires that
> >     ioremap() somehow discriminates based on address range to pick what
> >     kind of mapping to make.
> >
> >     Declaring these address ranges would be an issue. Options:
> >
> >     a) An out of band list in a DT node, a la /reserved-memory
> >
> >     b) Something based on the existing DT hierarchy, where we can scan
> >        bus ranges and locate buses with a property that says "nGnRnE" or
> >        "nGnRE" and dynamically build the list based on that.
> >
> >     The advantage of this option is that it doesn't touch non-arch code.
> >     The disadvantage is that it adds a complete new bespoke mechanism to
> >     the DT, and that it does not let device drivers actually select the
> >     IO mode, which might be desirable in the future anyway for some
> >     devices.
> 
> I tried investigating further what this would look like, but scanning through
> the ADT dump for what nodes use which register ranges. At first it seemed
> the range 0x200000000-0x2ffffffff is used for all normal devices, while
> the three PCI buses fall into the 0x380000000-0x4ffffffff,
> 0x500000000-0x67fffffff and 0x680000000-0x6ffffffff ranges
> respectively. This would allow a nice abstraction where one node
> contains all the devices in the 0x200000000-0x2ffffffff, and we do a
> translation in of_address_to_resource(),  similar to what we have for
> pci and isa nodes with their special addresses.
> 
> However, I did find that there are several nodes that use mmio
> addresses next to the PCI addresses, e.g. apciec0, dart-apciec0,
> apciec0-piodma, dart-acio0, acio0, acio-cpu0, atc0-dpin0, atc-phy0,
> dart-usb0, and usb-drd0 in the 0x380000000-0x3ffffffff range, just
> before the MMIO space of the first PCIe bus, so it gets a little
> more complicated.
> 
> The actual device node could look something like
> 
> #define MAP_NONPOSTED 0x80000000
> 
> arm-io { /* name for adt, should be changed */
>      compatible = "apple,m1-internal-bus";
>      #address-cells = <2>; /* or maybe <3> if we want */
>      #size-cells = <2>;
>      ranges =
>                /* on-chip MMIO */
>                <(MAP_NONPOSTED | 0x2) 0x0   0x2 0x0 0x1 0x0>,
> 
>               /* first PCI: 2GB control, 4GB memory space */
>              <(MAP_NONPOSTED | 0x3) 0x80000000  0x3 0x80000000  0x0 0x80000000>,
>               <0x4 0x0   0x4 0x0  0x1 0x0>,
> 
>               /* second PCI: 2GB control, 4GB memory space */
>              <(MAP_NONPOSTED | 0x5) 0x0  0x5 0x0  0x0 0x80000000>,
>               <0x5 0x80000000  0x5 0x80000000  0x1>,
> 
>               /* third PCI  0.5GB control, 1.5GB memory space*/
>              <(MAP_NONPOSTED | 0x6) 0x80000000  0x6 0x80000000  0x0 0x20000000>,
>              <0x6 0xa0000000   0x6 0xa0000000  0x0 0x60000000>;
> }
> 
> The MAP_NONPOSTED flag then gets interpreted by the .translate() and
> .get_flags() callbacks of "struct of_bus" in the kernel, where it is put into
> a "struct resource" flag, and interpreted when the resource gets mapped.
> 
> The PCI host controller nests inside of the node above, and (in theory)
> uses the same trick to distinguish between prefetchable and non-prefetchable
> memory, except in practice this is handled in device drivers that already
> know whether to call ioremap() or ioremap_wc().

It is only PCI mmio space that needs to be nGnRE.  The PCI host
controller register space itself needs nGnRnE just like all other
integrated peripherals (or at least it works that way).

For U-Boot I'm using the following memory map:

static struct mm_region apple_mem_map[] = {
	{
		/* I/O */
		.virt = 0x200000000,
		.phys = 0x200000000,
		.size = 8UL * SZ_1G,
		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
			 PTE_BLOCK_NON_SHARE |
			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
	}, {
		/* I/O */
		.virt = 0x500000000,
		.phys = 0x500000000,
		.size = 2UL * SZ_1G,
		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
			 PTE_BLOCK_NON_SHARE |
			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
	}, {
		/* I/O */
		.virt = 0x680000000,
		.phys = 0x680000000,
		.size = SZ_512M,
		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
			 PTE_BLOCK_NON_SHARE |
			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
	}, {
		/* PCIE */
		.virt = 0x6a0000000,
		.phys = 0x6a0000000,
		.size = SZ_512M,
		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
			 PTE_BLOCK_INNER_SHARE |
			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
	}, {
		/* PCIE */
		.virt = 0x6c0000000,
		.phys = 0x6c0000000,
		.size = SZ_1G,
		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
			 PTE_BLOCK_INNER_SHARE |
			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
	}, {
		/* RAM */
		.virt = 0x800000000,
		.phys = 0x800000000,
		.size = 8UL * SZ_1G,
		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
			 PTE_BLOCK_INNER_SHARE
	}, {
		/* List terminator */
		0,
	}
};

struct mm_region *mem_map = apple_mem_map;

This seems to work so far.  It only has the regions for one PCIe
controller.  I suppose the other two are there to support the TB4
ports?

So there is one 512M region for "32-bit" mmio starting at 0x6a0000000
and one 1G region for "64-bit" mmio starting at 0x6c0000000.

Cheers,

Mark


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

* Re: [PATCH 05/18] tty: serial: samsung_tty: add support for Apple UARTs
       [not found]           ` <YCFq3DqOzv4//6Vw@kroah.com>
@ 2021-02-08 23:22             ` Hector Martin
  0 siblings, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-08 23:22 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Marc Zyngier, soc, linux-arm-kernel, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson, Greg Kroah-Hartman

On 09/02/2021 01.46, Greg Kroah-Hartman wrote:
> I HATE adding new PORT_ types, as I am almost positive no one uses them,
> but as they are in the uapi files, we can't delete them.
> 
> So, just use an existing one, why do you want a new one?  If you don't
> have a userspace tool that requires it, don't bother.
> 
> Just use PORT_8250 and be done with it.  I should force all new drivers
> to use that as well :)

Krzysztof: given this, I think it would be fair to add an enum to the 
driver to keep track of the actual hardware type (grouped into probably 
just 3, S3C24XX, S3C6400, APPLE), get rid of any code in there that 
cares about the uapi-visible port type (other than setting it correctly 
for those that do exist, to maintain current behavior), and just make 
everything else use PORT_8250 for that?

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 05/18] tty: serial: samsung_tty: add support for Apple UARTs
  2021-02-08 18:37       ` Krzysztof Kozlowski
@ 2021-02-08 23:23         ` Hector Martin
  0 siblings, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-08 23:23 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: soc, linux-arm-kernel, Marc Zyngier, robh+dt, Arnd Bergmann,
	linux-kernel, devicetree, Olof Johansson

On 09/02/2021 03.37, Krzysztof Kozlowski wrote:
> Looking at Greg's comment, we can get rid of the PORT_ stuff entirely.
> First of all, PORT_S3C2410 == PORT_S3C2412, so this define is not
> accurate.
> 
> This leaves us with three types (s3c2400, s3c2440, s3c6410 and Apple).
> The s3c2440 could be removed with adding a new "ucon_mask" field to
> s3c24xx_serial_drv_data.
> 
> This would end with s3c24xx, s3c6410 and Apple - quite nice choice.

Works for me :)

> You're right. This one would have to be improved before your change.
> Instead of replacing specific op calls in startup, I think it's better
> to have entirely separate ops instance for each variant:
> 
> static const struct uart_ops s3c24xx_serial_ops;
> static const struct uart_ops s3c64xx_serial_ops;
> static const struct uart_ops s5l_serial_ops;
> 
> This allows to add a "const", since uart_port takes such const pointer.
> 
> Still during s3c24xx_serial_probe() correct ops would have to be
> assigned, but at least all ops are easily visible.

Roger, will do this for v2.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 10/18] arm64: Introduce FIQ support
       [not found]             ` <CAK8P3a1vmUJ0EpzU2+u2gy8WHCVV5ur9u-oTzU2BP=ddbXQeLQ@mail.gmail.com>
@ 2021-02-08 23:34               ` Hector Martin
  0 siblings, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-08 23:34 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Marc Zyngier, SoC Team, Linux ARM, Rob Herring, linux-kernel,
	DTML, Olof Johansson

On 08/02/2021 03.49, Arnd Bergmann wrote:
> Ok, I had not realized the timer was level triggered. In case of the
> timer, I suppose it could be either masked or acknowledged from the
> fiq top-half handler when deferring to irq, but I agree that it means a
> layering violation in either case.
> 
> What might still work is an approach where FIQ is normally enabled,
> and local_irq_disable() leaves it on, while local_irq_enable() turns
> it on regardless of the current state.
> 
> In this case, the fiq handler could run the timer function if interrupts
> are enabled but just turn off fiqs when they are turned off, waiting
> for the next local_irq_enable() to get us back in the state where
> the handler can run.  Not sure if that would buy us anything though,
> or if that still requires platform specific conditionals in common code.

It looks like Marc is just leaning towards making the IRQ and FIQ masks 
track each other unconditionally on all platforms anyway, so I'm going 
to try that for v2 (which is certainly the simpler solution). If this 
ends up somehow breaking any other platform we can deal with it in the 
way that makes most sense, once we know how it breaks :)

>> * An exception seems to be non-HV timer interrupts firing while we have
>> a VM guest running (HCR_EL2.TGE=0). This causes a single FIQ, and no
>> more, which suggests there is a mask bit for guest timer FIQs somewhere
>> that gets automatically set when the FIQ is delivered to the CPU core.
>> I've yet to find where this bit lives, I'll be doing a brute force sweep
>> of system register space soon to see if I can find it, and if there is
>> anything else useful near it.
> 
> Right. Maybe you can even find a bit that switches between FIQ and
> IRQ mode for the timer, as that would solve the problem completely.
> I think it's not that rare for irqchips to be configurable to either route
> an interrupt one way or the other.

That seems increasingly unlikely here; I tried poking all the AIC config 
bits and nothing switched those to FIQ (which is the converse). It looks 
like Apple has done something like use FIQ for all core-internal 
interrupt sources, and IRQ for AIC, and this is all seemingly quite 
hardwired.

In particular, a subtlety I discovered about how flipping TGE to 1 with 
a guest timer interrupt pending only takes effect properly (i.e. FIQ 
fires, and you get a FIQ storm if unhandled, no auto-masking) after 
subsequently issuing an isb, makes me think all this FIQ stuff is 
seriously deeply tied into the instruction pipeline. It's probably not 
an IRQ line any more...

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 13/18] arm64: ioremap: use nGnRnE mappings on platforms that require it
  2021-02-08 23:20     ` Mark Kettenis
@ 2021-02-09  0:25       ` Hector Martin
       [not found]         ` <CAK8P3a043eO4p2o6tizR2x7a1TZHMqO7TdX53JC4bTZnbQd9iQ@mail.gmail.com>
  0 siblings, 1 reply; 82+ messages in thread
From: Hector Martin @ 2021-02-09  0:25 UTC (permalink / raw)
  To: Mark Kettenis, Arnd Bergmann
  Cc: devicetree, maz, linux-kernel, soc, robh+dt, olof, linux-arm-kernel

On 09/02/2021 08.20, Mark Kettenis wrote:
> It is only PCI mmio space that needs to be nGnRE.  The PCI host
> controller register space itself needs nGnRnE just like all other
> integrated peripherals (or at least it works that way).

This is correct. Actually, as I just discovered, nGnRE writes to MMIO 
are not silently blackholed, but rather raise an SError. A certain other 
Linux loader masks those SErrors in a vendor register completely 
unnecessarily, which is why this isn't apparent when you use it. I never 
noticed this myself until now because when I first ran into it, it was 
breaking the UART, so of course I'd never see the SErrors, and I didn't 
try again after I learned more about the L2C SError control mechanism :-)

Testing now, it seems we can actually fairly neatly figure out where 
nGnRE is allowed and where not, as writes that fail due to that raise a 
SError with L2C_ERR_INF=3.

I probed writing to i<<28 for i = [0..255], using nGnRE. This reveals 
that nGnRE writes are allowed (i.e. either succeed or error out 
differently) in the following ranges:

0x400000000 - 0x4ffffffff (apciec0)
0x580000000 - 0x67fffffff (apciec1)
0x6a0000000 - 0x6ffffffff (apcie)

Which matches the `ranges` properties of the respective apcie devices in 
the ADT. The first two are obviously the TB3 ports, amd have more 
features (three ranges instead of two, presumably IO port ranges are 
supported on those, there's some extra DMA stuff, etc).

So the hardware behavior is to block nGnRE everywhere except in those 
ranges (i.e. the nGnRnE fault takes precedence over other errors, like 
the address not existing at all).

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
  2021-02-08 17:58             ` Rob Herring
@ 2021-02-09  0:32               ` Hector Martin
  0 siblings, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-09  0:32 UTC (permalink / raw)
  To: Rob Herring
  Cc: Arnd Bergmann, Krzysztof Kozlowski, DTML, Marc Zyngier,
	linux-kernel, SoC Team, Olof Johansson, Linux ARM

On 09/02/2021 02.58, Rob Herring wrote:
> I'll also highlight there's a DT only tree[1] available to import DT
> related parts to other projects. It's generated from the kernel tree.
> Probably an overkill to copying at this point though.
> 
> Rob
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git/

This actually brings up something else: do we want (eventually) *all* 
Apple boards using these SoCs to have up-to-date devicetrees in the 
Linux kernel tree? Obviously not every device supported by mainline has 
proper ones in, but I don't know if that's expected or something to be 
avoided.

If this is intended to be kept in sync and be fully comprehensive, I 
might as well start planning out our longer term DT maintenance strategy 
around that (which might involve using that tree in our bootloader).

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
  2021-02-08 19:14       ` Rob Herring
@ 2021-02-09  0:49         ` Hector Martin
  0 siblings, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-09  0:49 UTC (permalink / raw)
  To: Rob Herring
  Cc: Krzysztof Kozlowski, Arnd Bergmann, devicetree, Marc Zyngier,
	linux-kernel, soc, Olof Johansson, linux-arm-kernel

On 09/02/2021 04.14, Rob Herring wrote:
> Does there need to be a legal entity behind 'The Asahi Linux
> Contributors' to be valid?

I don't think so, this seems to be common practice in other open source 
projects, and recommended these days.

Some recent discussion on the subject from the Linux Foundation:

https://www.linuxfoundation.org/en/blog/copyright-notices-in-open-source-software-projects/

>  From a more practical standpoint, if we want to relicense something in
> say 5 years from now, who do we ask for an okay?

I thought that's what Git history was for; certainly we aren't keeping 
file headers up to date every time someone touches a file (which for 
anything other than trivial changes gives them a copyright interest in a 
portion of the file).

Asahi Linux's policy for bespoke projects is to use "The Asahi Linux 
Contributors" for this reason, acknowledging that the copyright headers 
aren't up to date anyway (also the years...), and implicitly directing 
people to the orignal project (which is where Git history is kept and 
contains the true record of copyright owneship).

I'm not trying to shake up how we handle copyright lines in the kernel 
here, of course; if you prefer some nominal copyright line from "whoever 
first wrote the file or most of it" I can do that. But it certainly 
won't be the only person you have to ask if you want to relicense, if 
anyone else touched the file in a nontrivial way :)

There are a few examples of this style in the tree, mostly pulled from 
other projects:

arch/arm/oprofile/common.c
drivers/gpu/drm/vgem/vgem_drv.[ch]
drivers/md/dm-verity-target.c
drivers/md/dm-verity.h

>>> I guess Rob will comment on the dt-bindings more... but for me a generic
>>> "arm-platform" is too generic. What's the point of it? I didn't see any
>>> of such generic compatibles in other platforms.
>>
>> This is a hack for patches #11/#12 to use, and I expect it will go away once
>> we figure out how to properly handle that problem (which needs further
>> discussion). Sorry for the noise, this should not be there in the final
>> version.
> 
> I was going to ask on this. If you have a user of it, I'm okay with it.
> Generally though, 3 or 4 levels of compatible don't really have users.

The pattern here was board, soc, "arm-platform"; the first two seem to 
be a common (and useful) pattern, and I hope I can get rid of the third 
once we solve #11/#12 in a saner way.

> It's a WIP to be more consistent around node names. For actual
> clock controllers we have 'clock-controller(@.*)?'. There's not really
> something established for 'fixed-clock'. We probably should define
> something, but that goes in the schema first.

What do you suggest for this series?

> 
>>>> +		compatible = "fixed-clock";
>>>> +		#clock-cells = <0>;
>>>> +		clock-frequency = <24000000>;
>>>> +		clock-output-names = "clk24";
>>>
>>> What clock is it? Part of board or SoC? Isn't it a work-around for
>>> missing clock drivers?
>>
>> The clock topology isn't entirely known yet; I'm submitting this as an
>> initial bring-up patchset and indeed there should be a clockchip driver in
>> the future. The UART driver wants a clock to be able to calculate baud
>> rates. I figured we can get away with a fixed-clock for now while that part
>> of the SoC gets figured out.
> 
> That is normal. It does break compatibility between an old kernel
> and new DT. There's not really a good way to avoid that.

Ack. I hope we can basically acknowledge breaking DT changes without too 
much fuss at this early stage of bring-up, until things calm down a bit 
and we have real users who would complain :) (not that I won't try to 
avoid it).

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 15/18] irqchip/apple-aic: Add support for the Apple Interrupt Controller
       [not found]   ` <87eehqlxlr.wl-maz@kernel.org>
       [not found]     ` <CAK8P3a25eFFrMG-9QknFZ6Ckc3-gkiLK=jQdnyTMgn-z4X0RHQ@mail.gmail.com>
@ 2021-02-09  6:20     ` Hector Martin
  1 sibling, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-09  6:20 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: soc, linux-arm-kernel, robh+dt, Arnd Bergmann, linux-kernel,
	devicetree, Olof Johansson

On 08/02/2021 18.25, Marc Zyngier wrote:
> I really do not want to expose IPIs in the DT. The OS defines what
> IPIs are used for, not the firmware/HW. No other platform requires
> this either, so is there any reason to do so?

This is used internally by the chained IPI driver (patch #16), but it 
does not need to be ever used in the DT. I guess it would be appropriate 
to just not document it in the bindings, and also use a higher type than 
2 (e.g. 0xff), so that if we ever have to add another type to the 
binding (e.g. the timer on older SoCs) it doesn't have to skip the 
number 2 to avoid breaking compat between newer DTs and older drivers.

See irq-bcm2836.c for the same approach: a chained IPI controller using 
an otherwise undocumented IRQ binding.

Another approach is to do what irq-armada-370-xp.c does: just ditch the 
chained irqchip and call handle_domain_irq into the IPI domain directly 
from the main IRQ handler function.

>> +#include <linux/irqchip/chained_irq.h>
> 
> There isn't any chained interrupt controller here, AFAICT.

This goes with patch #16, I'll move it there.

> If these functions have no impact on the per-CPU interrupts, then
> maybe these interrupts should be given a different irqchip.

Same IRQ domain, different irqchip? That sounds reasonable and gets rid 
of the bounds check on the mask/unmask calls, I'll do it for v2. This 
chip would apply for both IPIs (where a different register set in AIC 
for  masking/unmasking applies, but that is handled at the chained 
irqchip level in #16) and FIQs (which have no masking).

>> +static void aic_irq_eoi(struct irq_data *d)
>> +{
>> +	/*
>> +	 * Reading the interrupt reason automatically acknowledges and masks
>> +	 * the IRQ, so we just unmask it here if needed.
>> +	 */
>> +	if (!irqd_irq_disabled(d) && !irqd_irq_masked(d))
>> +		aic_irq_unmask(d);
> 
> This doesn't apply to per-CPU interrupts, right? Or does it?

The auto-masking does apply to IPIs, but this code doesn't do the 
unmasking. That is handled in the chained IPI domain in #16

*Strictly speaking* if we separate the responsibility at AIC for the 
root handler and say the chained handler should purely be a multiplexer 
for IPIs that doesn't touch the hardware at all, then the 
masking/unmasking should move here (into another irqchip) and the IPI 
domain code should just call into the root domain to mask/unmask the 
sole used hardware IPI; the current approach is a minor layering 
violation but... I'm not sure how useful it is to keep the layering 
pristine when both drivers live in the same file and are instantiated 
together anyway.

If I switch to the irq-armada-370-xp.c model where there is no logical 
chaining, then this would be fine as-is as both domains would logically 
represent driving different parts of AIC in parallel, with no nesting 
relationship.

>> +		u32 type = event >> 16, irq = event & 0xffff;
> 
> Nit: please consider introducing masks and using the bitfield macros
> to extract the various fields.

Ack, will do.

>> +		/* AIC_EVENT is read-sensitive, ensure it happens before we proceed */
>> +		isb();
> 
> You seem to have a data dependency after this, so I can't see how the
> ISB influences the read from AIC_EVENT. However you need to order it
> with the read from the timer registers, and I believe it'd be better
> to move the barrier there.

(Keeping the barrier story in the other thread)

>> +		if (type == AIC_EVENT_TYPE_HW) {
>> +			handle_domain_irq(aic_irqc->hw_domain, irq, regs);
>> +		} else if (type == AIC_EVENT_TYPE_IPI) {
>> +			handle_domain_irq(aic_irqc->hw_domain,
>> +					  ic->nr_hw + AIC_NR_FIQ + irq - 1, regs);
> 
> nit: it would be slightly less cumbersome to compute the hwirq in a
> switch, and have a single call to handle_domain_irq().
> 
> I also wonder whether using two top-level domains would be better. Not
> a big deal though.

Exactly :) I can certainly switch to that if you have no objection. It 
should have lower overhead for IPIs anyway, and removes the fwspec step 
to glue it all together.

>> +		} else {
>> +			pr_err("spurious IRQ event %d, %d\n", type, irq);
> 
> Spurious interrupts aren't an error, in general. If you really want to
> keep this, at the very least make it rate-limited.

In this case it's more like "unknown IRQ event", which better be an 
error because it means the chip is doing something we don't know about - 
*except* the zero case, that's just a spurious IRQ which indeed isn't an 
error (peripheral asserted and deasserted IRQ before we could handle it; 
I need to check but I believe AIC would just withdraw the event in that 
case).

So the zero case should be ignored and the unknown case should be fine 
without rate limiting, because it really shouldn't happen, ever. I'll 
fix the zero case for v2.

> Consider turning the whole thing into a do{}while() so that there is
> only a single read of AIC_EVENT in the function.

Ack.

>> +	/*
>> +	 * It would be really nice to find a system register that lets us get the FIQ source
>> +	 * state without having to peek down into clients...
>> +	 */
> 
> nit: please try to keep comments within the 80 cols limit. I don't
> mind code being wider, but comments benefit from being more rigorously
> structured.

Ack, I'll keep it in mind. For this one I just used clang-format as a 
first-pass and made some minor changes, so please do point out any other 
style nits I missed so I can keep it in check. I know it doesn't enforce 
nor fully represent kernel style.

> And yes, having to poll each end-point IP is really a drag. How does
> the PMU work on this system? Is there any other per-CPU source?

PMU also ends up in FIQ, and it's nonstandard (not the ARM Performance 
Monitors extension). That means one more FIQ source is going to have to 
end up here, and one more downstream register to poll (a proprietary one 
in this case: SYS_PMCR0 is s3_1_c15_c0_0, not to be confused with the 
standard SYS_PMCR_EL0 which is completely different).

So the FIQ sources to be polled are the following:

1. HV timers
2. Guest timers (auto-masked, mask register TBD, I still have no idea 
how XNU routes these to the hypervisor framework... haven't found the 
code yet, or the mask register)
3. Fast IPIs (not currently implemented)
4 Apple PMU

We have #1, I'll look for the mask bits to properly implement #2, #3 can 
wait until we actually implement those, and #4 can wait until we 
implement that PMU. Does that sound OK?

If you think it's worth it, I could at least check the status registers 
for #3 and #4 and yell loudly, so that if we somehow end up with a FIQ 
storm because those paths went off unchecked, at least we have logs. Or 
just make sure to mask them in the AIC init code, or both.

Since these are per-CPU, setting the masks is a per-cpu call, so that 
needs to go via something like cpuhp_setup_state_nocalls to run on CPU 
bring-up.

That said: PMC seems to have IRQ settings to go via AIC instead of FIQ, 
but I have no idea if that works on these CPUs; XNU only uses it on 
older ones. That should probably be investigated later.

> This system runs VHE, so there is also CNT{P,V}_CTL_EL02 to consider.
> But I really wonder how the whole thing works once these two timers
> are assigned to a guest. Somehow, something must control the masking,
> otherwise you wouldn't be able to enter a guest with a timer firing.

Yeah, as I mentioned on IRC, there is auto-masking for the guest timers, 
somehow. I'll find that mask bit.

> It also means that there is no way to have threaded per-CPU
> interrupts, which means no Preempt-RT. You could wire the mask/unmask
> callbacks to mess with the IMASK bit in individual timers, but that
> doesn't solve the problem for guests.

For HV timers, we're probably have to mess with IMASK here if there is 
no other way... I need to read through the timer code and make sure that 
wouldn't confuse it, as that creates a bit of an implicit contract here.

It'd be great if I can find a true status/mask register for FIQs, but 
I'm not holding my breath that it exists...

> Are all interrupts level? How are MSIs implemented?

Seems a fixed set of MSIs are routed into AIC, presumably transformed 
into level lines? I need to look into this part in more detail.

>> +	irqc->hw_domain =
>> +		irq_domain_add_linear(node,
>> +				      irqc->nr_hw + AIC_NR_FIQ + AIC_NR_IPI,
>> +				      &aic_irq_domain_ops, irqc);
> 
> Please keep assignments on a single line.

I think this one was one of those clang-format things :-).

I'll fix it and watch out for similar things.

>> +	for (i = 0; i < BITS_TO_LONGS(irqc->nr_hw); i++)
> 
> long is 64bit on arm64, so this loop is unlikely to do what you
> want. Consider using BITS_TO_U32.

Ha, nice catch. Thanks!

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 13/18] arm64: ioremap: use nGnRnE mappings on platforms that require it
       [not found]         ` <CAK8P3a043eO4p2o6tizR2x7a1TZHMqO7TdX53JC4bTZnbQd9iQ@mail.gmail.com>
@ 2021-02-09  9:58           ` Mark Kettenis
  2021-02-09 11:22           ` Hector Martin
  1 sibling, 0 replies; 82+ messages in thread
From: Mark Kettenis @ 2021-02-09  9:58 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: marcan, devicetree, maz, linux-kernel, soc, robh+dt, olof,
	linux-arm-kernel

> From: Arnd Bergmann <arnd@kernel.org>
> Date: Tue, 9 Feb 2021 10:15:31 +0100
> 
> On Tue, Feb 9, 2021 at 1:25 AM Hector Martin <marcan@marcan.st> wrote:
> > On 09/02/2021 08.20, Mark Kettenis wrote:
> > I probed writing to i<<28 for i = [0..255], using nGnRE. This reveals
> > that nGnRE writes are allowed (i.e. either succeed or error out
> > differently) in the following ranges:
> >
> > 0x400000000 - 0x4ffffffff (apciec0)
> > 0x580000000 - 0x67fffffff (apciec1)
> > 0x6a0000000 - 0x6ffffffff (apcie)
> >
> > Which matches the `ranges` properties of the respective apcie devices in
> > the ADT.
> 
> Right, these are the same ranges that I found in the adt and that Mark
> listed in his code snippet, so it seems we all see the same partitioning
> of the address space. I also see them reflected in the
> /defaults/pmap-io-ranges property in ADT, which seems to have an entry
> for every register range that has some mmio registers, along with what
> appears to be a bitmask of some attributes, and it clearly shows
> the above ranges as having a distinct set of bits from the others
> (in little-endian):
> 
>  00000000 04000000 00000080 00000000 27000080 65494350
>  00000080 04000000 00000080 00000000 27000080 65494350
>  00000080 05000000 00000080 00000000 27000080 65494350
>  00000000 06000000 00000080 00000000 27000080 65494350
>  000000a0 06000000 00000020 00000000 27000080 65494350
>  000000c0 06000000 00000040 00000000 27000080 65494350
>    ^64-bit address       ^64-bit length            ^ 64-bit flags?
> 
> As opposed to e.g.
> 
>  0000f002 05000000 00400000 00000000 07400000 54524144
>  0000f802 05000000 00400000 00000000 07400000 54524144
>  00800021 05000000 00400000 00000000 07400000 44495344
>  0000a801 05000000 00400000 00000000 07400000 54524144
> 00000367 02000000 00400000 00000000 07400000 54524144
> ...
> 
> There is one more entry for the 0x700000000-0x7ffffffff range, which
> has yet another distinct bitmask, but does not seem to correspond
> to any registers listed in other nodes.
> 
> > The first two are obviously the TB3 ports, and have more
> > features (three ranges instead of two, presumably IO port ranges are
> > supported on those, there's some extra DMA stuff, etc).
> 
> The PCI ranges property identifies these as 64-bit prefetchable (0x43),
> 32-bit non-prefetchable (0x02), and 32-bit pre prefetchable (0x42)
> respectively. The third bus only lacks the 32-bit prefetchable range,
> that is normally ok. Is this the NVMe host or something else?

Third bus has Broadcom WiFi, Fresco Logic xHCI and Broadcom Ethernet,
so all the onboard PCIe devices.

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

* Re: [PATCH 13/18] arm64: ioremap: use nGnRnE mappings on platforms that require it
       [not found]         ` <CAK8P3a043eO4p2o6tizR2x7a1TZHMqO7TdX53JC4bTZnbQd9iQ@mail.gmail.com>
  2021-02-09  9:58           ` Mark Kettenis
@ 2021-02-09 11:22           ` Hector Martin
  1 sibling, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-09 11:22 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Mark Kettenis, DTML, Marc Zyngier, linux-kernel, SoC Team,
	Rob Herring, Olof Johansson, Linux ARM

On 09/02/2021 18.15, Arnd Bergmann wrote:
> Right, these are the same ranges that I found in the adt and that Mark
> listed in his code snippet, so it seems we all see the same partitioning
> of the address space. I also see them reflected in the
> /defaults/pmap-io-ranges property in ADT, which seems to have an entry
> for every register range that has some mmio registers, along with what
> appears to be a bitmask of some attributes, and it clearly shows
> the above ranges as having a distinct set of bits from the others
> (in little-endian):
> 
>   00000000 04000000 00000080 00000000 27000080 65494350
>   00000080 04000000 00000080 00000000 27000080 65494350
>   00000080 05000000 00000080 00000000 27000080 65494350
>   00000000 06000000 00000080 00000000 27000080 65494350
>   000000a0 06000000 00000020 00000000 27000080 65494350
>   000000c0 06000000 00000040 00000000 27000080 65494350
>     ^64-bit address       ^64-bit length            ^ 64-bit flags?

That's ASCII :-)

'PCIe'

> 
> As opposed to e.g.
> 
>   0000f002 05000000 00400000 00000000 07400000 54524144

'DART'

>   00800021 05000000 00400000 00000000 07400000 44495344

'DSID'

> Ok, so if we want this to get encoded in a 'struct resource' flag, the PCI
> resources should work just fine as these resources come from the
> PCI layer rather than of_address_to_resource(). I think it would be
> reasonable here to add something to of_address_to_resource() to
> set such a flag if we can find an unused one, and then require the
> drivers for this platform to go through devm_ioremap_resource()
> or similar.

This sounds reasonable. For setting such a flag, I guess looking for a 
property (inherited from parents) would make sense. `mmio-map-mode = 
"nonposted"` or something like that?

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 14/18] dt-bindings: interrupt-controller: Add DT bindings for apple-aic
  2021-02-04 20:39 ` [PATCH 14/18] dt-bindings: interrupt-controller: Add DT bindings for apple-aic Hector Martin
@ 2021-02-09 23:07   ` Rob Herring
  0 siblings, 0 replies; 82+ messages in thread
From: Rob Herring @ 2021-02-09 23:07 UTC (permalink / raw)
  To: Hector Martin
  Cc: soc, linux-arm-kernel, Marc Zyngier, Arnd Bergmann, linux-kernel,
	devicetree, Olof Johansson

On Fri, Feb 05, 2021 at 05:39:47AM +0900, Hector Martin wrote:
> AIC is the Apple Interrupt Controller found on Apple ARM SoCs, such as
> the M1.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>  .../interrupt-controller/AAPL,aic.yaml        | 88 +++++++++++++++++++
>  MAINTAINERS                                   |  2 +
>  .../interrupt-controller/apple-aic.h          | 14 +++
>  3 files changed, 104 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/AAPL,aic.yaml
>  create mode 100644 include/dt-bindings/interrupt-controller/apple-aic.h
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/AAPL,aic.yaml b/Documentation/devicetree/bindings/interrupt-controller/AAPL,aic.yaml
> new file mode 100644
> index 000000000000..7e119614275a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/AAPL,aic.yaml
> @@ -0,0 +1,88 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/interrupt-controller/AAPL,aic.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Apple Interrupt Controller
> +
> +maintainers:
> +  - Hector Martin <marcan@marcan.st>
> +
> +description: |
> +  The Apple Interrupt Controller is a simple interrupt controller present on
> +  Apple ARM SoC platforms, including various iPhone and iPad devices and the
> +  "Apple Silicon" M1 Macs.
> +
> +  It provides the following features:
> +
> +  - Level-triggered hardware IRQs wired to SoC blocks
> +    - Single mask bit per IRQ
> +    - Per-IRQ affinity setting
> +    - Automatic masking on event delivery (auto-ack)
> +    - Software triggering (ORed with hw line)
> +  - 2 per-CPU IPIs (meant as "self" and "other", but they are interchangeable
> +    if not symmetric)
> +  - Automatic prioritization (single event/ack register per CPU, lower IRQs =
> +    higher priority)
> +  - Automatic masking on ack
> +  - Default "this CPU" register view and explicit per-CPU views
> +
> +allOf:
> +  - $ref: /schemas/interrupt-controller.yaml#
> +
> +properties:
> +  compatible:
> +    contains:
> +      enum:
> +        - AAPL,aic
> +        - AAPL,m1-aic

Instead of 'contains', this should be:

items:
  - const: AAPL,m1-aic
  - const: AAPL,aic

With 'apple' instead...

> +
> +  interrupt-controller: true
> +
> +  '#interrupt-cells':
> +    const: 3
> +    description: |
> +      The 1st cell contains the interrupt type:
> +        - 0: Hardware IRQ
> +        - 1: FIQ
> +        - 2: IPI
> +
> +      The 2nd cell contains the interrupt number.
> +        - HW IRQs: interrupt number
> +        - FIQs:
> +          - 0: physical timer
> +          - 1: virtual timer
> +        - IPIs:
> +          - 0: normal/"other" IPI (used interanlly for virtual IPIs)
> +          - 1: self IPI (normally unused)
> +
> +      The 3rd cell contains the interrupt flags. This is normally
> +      IRQ_TYPE_LEVEL_HIGH (4).
> +
> +  reg:
> +    description: |
> +      Specifies base physical address and size of the AIC registers.
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - '#interrupt-cells'
> +  - interrupt-controller
> +  - reg
> +
> +unevaluatedProperties: false

additionalProperties: false

(stricter and actually has support implemented)

> +
> +examples:
> +  - |
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        aic: interrupt-controller@23b100000 {
> +            compatible = "AAPL,m1-aic", "AAPL,aic";
> +            #interrupt-cells = <3>;
> +            interrupt-controller;
> +            reg = <0x2 0x3b100000 0x0 0x8000>;
> +        };
> +    };
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 91a7b33834ac..f3d4661731c8 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1634,6 +1634,8 @@ B:	https://github.com/AsahiLinux/linux/issues
>  C:	irc://chat.freenode.net/asahi-dev
>  T:	git https://github.com/AsahiLinux/linux.git
>  F:	Documentation/devicetree/bindings/arm/AAPL.yaml
> +F:	Documentation/devicetree/bindings/interrupt-controller/AAPL,aic.yaml
> +F:	include/dt-bindings/interrupt-controller/apple-aic.h
>  
>  ARM/ARTPEC MACHINE SUPPORT
>  M:	Jesper Nilsson <jesper.nilsson@axis.com>
> diff --git a/include/dt-bindings/interrupt-controller/apple-aic.h b/include/dt-bindings/interrupt-controller/apple-aic.h
> new file mode 100644
> index 000000000000..f54dc0cd6e9a
> --- /dev/null
> +++ b/include/dt-bindings/interrupt-controller/apple-aic.h
> @@ -0,0 +1,14 @@
> +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
> +#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_APPLE_AIC_H
> +#define _DT_BINDINGS_INTERRUPT_CONTROLLER_APPLE_AIC_H
> +
> +#include <dt-bindings/interrupt-controller/irq.h>
> +
> +#define AIC_IRQ 0
> +#define AIC_FIQ 1
> +#define AIC_IPI 2
> +
> +#define AIC_TMR_PHYS 0
> +#define AIC_TMR_VIRT 1
> +
> +#endif
> -- 
> 2.30.0
> 

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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
  2021-02-08 11:56     ` Hector Martin 'marcan'
  2021-02-08 12:13       ` Krzysztof Kozlowski
  2021-02-08 19:14       ` Rob Herring
@ 2021-02-10 10:19       ` Tony Lindgren
  2021-02-10 11:07         ` Hector Martin
  2 siblings, 1 reply; 82+ messages in thread
From: Tony Lindgren @ 2021-02-10 10:19 UTC (permalink / raw)
  To: Hector Martin 'marcan'
  Cc: Krzysztof Kozlowski, Arnd Bergmann, devicetree, Marc Zyngier,
	linux-kernel, soc, robh+dt, Olof Johansson, linux-arm-kernel

* Hector Martin 'marcan' <marcan@marcan.st> [210208 12:05]:
> On 08/02/2021 20.04, Krzysztof Kozlowski wrote:
...

> > > +	clk24: clk24 {
> > 
> > Just "clock". Node names should be generic.
> 
> Really? Almost every other device device tree uses unique clock node names.

Yeah please just use generic node name "clock". FYI, we're still hurting
because of this for the TI clock node names years after because the drivers
got a chance to rely on the clock node name..

Using "clock" means your clock driver code won't get a chance to wrongly
use the node name and you avoid similar issues.

Regards,

Tony


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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
  2021-02-10 10:19       ` Tony Lindgren
@ 2021-02-10 11:07         ` Hector Martin
  2021-02-10 11:34           ` Tony Lindgren
  0 siblings, 1 reply; 82+ messages in thread
From: Hector Martin @ 2021-02-10 11:07 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Krzysztof Kozlowski, Arnd Bergmann, devicetree, Marc Zyngier,
	linux-kernel, soc, robh+dt, Olof Johansson, linux-arm-kernel

On 10/02/2021 19.19, Tony Lindgren wrote:
> * Hector Martin 'marcan' <marcan@marcan.st> [210208 12:05]:
>> On 08/02/2021 20.04, Krzysztof Kozlowski wrote:
> ...
> 
>>>> +	clk24: clk24 {
>>>
>>> Just "clock". Node names should be generic.
>>
>> Really? Almost every other device device tree uses unique clock node names.
> 
> Yeah please just use generic node name "clock". FYI, we're still hurting
> because of this for the TI clock node names years after because the drivers
> got a chance to rely on the clock node name..
> 
> Using "clock" means your clock driver code won't get a chance to wrongly
> use the node name and you avoid similar issues.

That means it'll end up like this (so that we can have more than one 
fixed-clock):

clocks {
     #address-cells = <1>;
     #size-cells = <0>;

     clk123: clock@0 {
         ...
         reg = <0>
     }

     clk456: clock@1 {
         ...
         reg = <1>
     }
}

Correct?

Incidentally, there is just one example in the kernel tree of doing this 
right (in arch/arm/boot/dts/imx6qdl-tx6.dtsi). All the others that use 
non-mmio clocks called `clock`, including the various tegra devicetrees, 
violate the DT spec by not including a dummy reg property matching the 
unit-address.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
  2021-02-10 11:07         ` Hector Martin
@ 2021-02-10 11:34           ` Tony Lindgren
  2021-02-10 11:43             ` Hector Martin
  2021-02-10 12:55             ` Krzysztof Kozlowski
  0 siblings, 2 replies; 82+ messages in thread
From: Tony Lindgren @ 2021-02-10 11:34 UTC (permalink / raw)
  To: Hector Martin
  Cc: Arnd Bergmann, devicetree, Marc Zyngier, linux-kernel,
	Krzysztof Kozlowski, soc, robh+dt, Olof Johansson,
	linux-arm-kernel

* Hector Martin <marcan@marcan.st> [210210 11:14]:
> On 10/02/2021 19.19, Tony Lindgren wrote:
> > * Hector Martin 'marcan' <marcan@marcan.st> [210208 12:05]:
> > > On 08/02/2021 20.04, Krzysztof Kozlowski wrote:
> > ...
> > 
> > > > > +	clk24: clk24 {
> > > > 
> > > > Just "clock". Node names should be generic.
> > > 
> > > Really? Almost every other device device tree uses unique clock node names.
> > 
> > Yeah please just use generic node name "clock". FYI, we're still hurting
> > because of this for the TI clock node names years after because the drivers
> > got a chance to rely on the clock node name..
> > 
> > Using "clock" means your clock driver code won't get a chance to wrongly
> > use the node name and you avoid similar issues.
> 
> That means it'll end up like this (so that we can have more than one
> fixed-clock):
> 
> clocks {
>     #address-cells = <1>;
>     #size-cells = <0>;
> 
>     clk123: clock@0 {
>         ...
>         reg = <0>
>     }
> 
>     clk456: clock@1 {
>         ...
>         reg = <1>
>     }
> }
> 
> Correct?

Yeah, just don't use an imaginary dummy index for the reg. Use a real
register offset from a clock controller instance base, and a register
bit offset too if needed.

That way if you discover a new clock inbetween somewhere, you don't have
renumber any imaginary lists in the driver or device tree. So try to
follow sort of what the standard interrupts binding is doing only
describing the hardware.

> Incidentally, there is just one example in the kernel tree of doing this
> right (in arch/arm/boot/dts/imx6qdl-tx6.dtsi). All the others that use
> non-mmio clocks called `clock`, including the various tegra devicetrees,
> violate the DT spec by not including a dummy reg property matching the
> unit-address.

Doing it right will save you tons of time later on ;)

FYI, for the TI clocks, we ended up redoing most of the clocks as
documented in Documentation/devicetree/bindings/clock/ti-clkctrl.txt.

Regards,

Tony

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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
  2021-02-10 11:34           ` Tony Lindgren
@ 2021-02-10 11:43             ` Hector Martin
  2021-02-10 12:24               ` Daniel Palmer
  2021-02-10 12:55             ` Krzysztof Kozlowski
  1 sibling, 1 reply; 82+ messages in thread
From: Hector Martin @ 2021-02-10 11:43 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Arnd Bergmann, devicetree, Marc Zyngier, linux-kernel,
	Krzysztof Kozlowski, soc, robh+dt, Olof Johansson,
	linux-arm-kernel

On 10/02/2021 20.34, Tony Lindgren wrote:
> * Hector Martin <marcan@marcan.st> [210210 11:14]:
>> That means it'll end up like this (so that we can have more than one
>> fixed-clock):
>>
>> clocks {
>>      #address-cells = <1>;
>>      #size-cells = <0>;
>>
>>      clk123: clock@0 {
>>          ...
>>          reg = <0>
>>      }
>>
>>      clk456: clock@1 {
>>          ...
>>          reg = <1>
>>      }
>> }
>>
>> Correct?
> 
> Yeah, just don't use an imaginary dummy index for the reg. Use a real
> register offset from a clock controller instance base, and a register
> bit offset too if needed.

I mean for fixed input clocks without any particular numbering, or for 
temporary fake clocks while we figure out the clock controller. Once a 
real clock controller is involved, if there are hardware indexes 
involved that are consistent then of course I'll use those in some way 
that makes sense.

The purpose of the clock in this particular case is just to make the 
uart driver work, since it wants to know its reference clock; there is 
work to be done here to figure out the real clock tree (e.g. we don't 
even know yet if the uart supports alternate clocks, that's tricky to 
test until we have some form of I/O other than uart!).

> Doing it right will save you tons of time later on ;)

Absolutely, I'm just pointing out that instances of it being done right 
are in short supply right now :-) (which makes it tricky for people like 
me, trying to put this together for a new soc, to guess what the right 
approach is by looking at existing examples)

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
  2021-02-10 11:43             ` Hector Martin
@ 2021-02-10 12:24               ` Daniel Palmer
  2021-02-10 12:54                 ` Tony Lindgren
  2021-02-10 12:56                 ` Hector Martin
  0 siblings, 2 replies; 82+ messages in thread
From: Daniel Palmer @ 2021-02-10 12:24 UTC (permalink / raw)
  To: Hector Martin
  Cc: Tony Lindgren, Arnd Bergmann, DTML, Marc Zyngier,
	Linux Kernel Mailing List, Krzysztof Kozlowski, SoC Team,
	Rob Herring, Olof Johansson, linux-arm-kernel

Hi Hector,

On Wed, 10 Feb 2021 at 20:49, Hector Martin <marcan@marcan.st> wrote:

> > Yeah, just don't use an imaginary dummy index for the reg. Use a real
> > register offset from a clock controller instance base, and a register
> > bit offset too if needed.
>
> I mean for fixed input clocks without any particular numbering, or for
> temporary fake clocks while we figure out the clock controller. Once a
> real clock controller is involved, if there are hardware indexes
> involved that are consistent then of course I'll use those in some way
> that makes sense.

This exact problem exists for MStar/SigmaStar too.
As it stands there is no documentation to show what the actual clock
tree looks like so everything is guess and I need to come up with numbers.
I'm interested to see what the solution to this is as it will come up again
when mainlining chips without documentation.


> The purpose of the clock in this particular case is just to make the
> uart driver work, since it wants to know its reference clock; there is
> work to be done here to figure out the real clock tree

FWIW arm/boot/dts/mstar-v7.dtsi has the same issue: Needs uart,
has no uart clock. In that instance the uart clock setup by u-boot
is passed to the uart driver as a property instead of creating a fake
clock.

Cheers,

Daniel

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

* Re: [PATCH 13/18] arm64: ioremap: use nGnRnE mappings on platforms that require it
       [not found]   ` <CAK8P3a2Ad+xmmMWgznOHPpxgCXKWFYfpHBqt_49_UuxrwFSq+A@mail.gmail.com>
  2021-02-08 23:20     ` Mark Kettenis
@ 2021-02-10 12:24     ` Hector Martin
  2021-02-10 13:40       ` Mark Kettenis
  1 sibling, 1 reply; 82+ messages in thread
From: Hector Martin @ 2021-02-10 12:24 UTC (permalink / raw)
  To: Will Deacon
  Cc: SoC Team, Linux ARM, Marc Zyngier, Rob Herring, linux-kernel,
	DTML, Olof Johansson, Arnd Bergmann, Mark Kettenis

Hi Will, I'm pulling you in at Marc's suggestion. Do you have an opinion 
on what the better solution to this problem is?

The executive summary is that Apple SoCs require nGnRnE memory mappings 
for MMIO, except for PCI space which uses nGnRE. ARM64 currently uses 
nGnRE everywhere. Solutions discussed in this thread and elsewhere include:

1. Something similar to the current hacky patch (which isn't really 
intended as a real solution...); change ioremap to default to nGnRnE 
using some kind of platform-level flag in the DT, then figure out how to 
get the PCI drivers to bypass that. This requires changing almost every 
PCI driver, since most of them use plain ioremap().

2. A per-device DT property that tells of_address_to_resource to set a 
flag in the struct resource, which is then used by 
devm_ioremap_resource/of_iomap to pick a new ioremap_ variant for nGnRnE 
(introduce ioremap_np() for nonposted?) (PCI would work with this 
inasmuch as it would not support it, and thus fall back to the current 
nGnRE default, which is correct for PCI...). This requires changing 
DT-binding drivers that we depend on to not use plain ioremap() (if any 
do so), but that is a finite subset (unlike PCI which involves 
potentially every driver, because thunderbolt).

3. Encode the mapping type in the address of child devices, either 
abusing the high bits of the reg or introducing an extra DT cell there, 
introduce a new OF bus type that strips those away via a ranges mapping 
and sets flags in the struct resource, similar to what the PCI bus does 
with its 3-cell ranges, then do as (2) above and make 
devm_ioremap_resource/of_iomap use it:

On 09/02/2021 07.57, Arnd Bergmann wrote:
> #define MAP_NONPOSTED 0x80000000
> 
> arm-io { /* name for adt, should be changed */
>       compatible = "apple,m1-internal-bus";
>       #address-cells = <2>; /* or maybe <3> if we want */
>       #size-cells = <2>;
>       ranges =
>                 /* on-chip MMIO */
>                 <(MAP_NONPOSTED | 0x2) 0x0   0x2 0x0 0x1 0x0>,
> 
>                /* first PCI: 2GB control, 4GB memory space */
>               <(MAP_NONPOSTED | 0x3) 0x80000000  0x3 0x80000000  0x0 0x80000000>,
>                <0x4 0x0   0x4 0x0  0x1 0x0>,
[...]

> The MAP_NONPOSTED flag then gets interpreted by the .translate() and
> .get_flags() callbacks of "struct of_bus" in the kernel, where it is put into
> a "struct resource" flag, and interpreted when the resource gets mapped.
> 
> The PCI host controller nests inside of the node above, and (in theory)
> uses the same trick to distinguish between prefetchable and non-prefetchable
> memory, except in practice this is handled in device drivers that already
> know whether to call ioremap() or ioremap_wc().

4. Introduce a new top-level DT element in the style of reserved-memory, 
that describes address ranges and the mapping type to use. This could be 
implemented entirely in arch code, having arm64's ioremap look up the 
address in a structure populated from this.

As an additional wrinkle, earlycon is almost certainly going to need a 
special path to handle this very early, before OF stuff is available; it 
also uses fixmap instead of ioremap, which has its own idea about what 
type of mapping to use.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
  2021-02-10 12:24               ` Daniel Palmer
@ 2021-02-10 12:54                 ` Tony Lindgren
  2021-02-10 12:56                 ` Hector Martin
  1 sibling, 0 replies; 82+ messages in thread
From: Tony Lindgren @ 2021-02-10 12:54 UTC (permalink / raw)
  To: Daniel Palmer
  Cc: Hector Martin, Arnd Bergmann, DTML, Marc Zyngier,
	Linux Kernel Mailing List, Krzysztof Kozlowski, SoC Team,
	Rob Herring, Olof Johansson, linux-arm-kernel, Stephen Boyd

* Daniel Palmer <daniel@0x0f.com> [210210 12:24]:
> Hi Hector,
> 
> On Wed, 10 Feb 2021 at 20:49, Hector Martin <marcan@marcan.st> wrote:
> 
> > > Yeah, just don't use an imaginary dummy index for the reg. Use a real
> > > register offset from a clock controller instance base, and a register
> > > bit offset too if needed.
> >
> > I mean for fixed input clocks without any particular numbering, or for
> > temporary fake clocks while we figure out the clock controller. Once a
> > real clock controller is involved, if there are hardware indexes
> > involved that are consistent then of course I'll use those in some way
> > that makes sense.
> 
> This exact problem exists for MStar/SigmaStar too.
> As it stands there is no documentation to show what the actual clock
> tree looks like so everything is guess and I need to come up with numbers.
> I'm interested to see what the solution to this is as it will come up again
> when mainlining chips without documentation.
> 
> 
> > The purpose of the clock in this particular case is just to make the
> > uart driver work, since it wants to know its reference clock; there is
> > work to be done here to figure out the real clock tree
> 
> FWIW arm/boot/dts/mstar-v7.dtsi has the same issue: Needs uart,
> has no uart clock. In that instance the uart clock setup by u-boot
> is passed to the uart driver as a property instead of creating a fake
> clock.

Using more local dts nodes for the fixed clocks might help a bit with
the dummy numbering problem but is still not a nice solution.

How about using node names like "clock-foo" for the fixed clocks?
This would be along what we do for with regulator names.

Rob and Stephen might have some better suggestions here.

Regards,

Tony

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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
  2021-02-10 11:34           ` Tony Lindgren
  2021-02-10 11:43             ` Hector Martin
@ 2021-02-10 12:55             ` Krzysztof Kozlowski
  2021-02-10 13:19               ` Tony Lindgren
  1 sibling, 1 reply; 82+ messages in thread
From: Krzysztof Kozlowski @ 2021-02-10 12:55 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Hector Martin, Arnd Bergmann, devicetree, Marc Zyngier,
	linux-kernel, soc, robh+dt, Olof Johansson, linux-arm-kernel

On Wed, Feb 10, 2021 at 01:34:50PM +0200, Tony Lindgren wrote:
> * Hector Martin <marcan@marcan.st> [210210 11:14]:
> > On 10/02/2021 19.19, Tony Lindgren wrote:
> > > * Hector Martin 'marcan' <marcan@marcan.st> [210208 12:05]:
> > > > On 08/02/2021 20.04, Krzysztof Kozlowski wrote:
> > > ...
> > > 
> > > > > > +	clk24: clk24 {
> > > > > 
> > > > > Just "clock". Node names should be generic.
> > > > 
> > > > Really? Almost every other device device tree uses unique clock node names.
> > > 
> > > Yeah please just use generic node name "clock". FYI, we're still hurting
> > > because of this for the TI clock node names years after because the drivers
> > > got a chance to rely on the clock node name..
> > > 
> > > Using "clock" means your clock driver code won't get a chance to wrongly
> > > use the node name and you avoid similar issues.
> > 
> > That means it'll end up like this (so that we can have more than one
> > fixed-clock):
> > 
> > clocks {
> >     #address-cells = <1>;
> >     #size-cells = <0>;
> > 
> >     clk123: clock@0 {
> >         ...
> >         reg = <0>
> >     }
> > 
> >     clk456: clock@1 {
> >         ...
> >         reg = <1>
> >     }
> > }
> > 
> > Correct?
> 
> Yeah, just don't use an imaginary dummy index for the reg. Use a real
> register offset from a clock controller instance base, and a register
> bit offset too if needed.

No, there is no need for fake "clocks" node with fake addresses. If you
have multiple clocks, the rules are the same as for other similar cases,
e.g. leds:

{
    clock-0 {
       ...
    };

    clock-1 {
        ..
    };

    soc@0 {
    };
}

This should not generate any dtc W=1 warnings and work with dtschema
(you need to check for both).

Best regards,
Krzysztof


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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
  2021-02-10 12:24               ` Daniel Palmer
  2021-02-10 12:54                 ` Tony Lindgren
@ 2021-02-10 12:56                 ` Hector Martin
  1 sibling, 0 replies; 82+ messages in thread
From: Hector Martin @ 2021-02-10 12:56 UTC (permalink / raw)
  To: Daniel Palmer
  Cc: Tony Lindgren, Arnd Bergmann, DTML, Marc Zyngier,
	Linux Kernel Mailing List, Krzysztof Kozlowski, SoC Team,
	Rob Herring, Olof Johansson, linux-arm-kernel

On 10/02/2021 21.24, Daniel Palmer wrote:
> This exact problem exists for MStar/SigmaStar too.
> As it stands there is no documentation to show what the actual clock
> tree looks like so everything is guess and I need to come up with numbers.
> I'm interested to see what the solution to this is as it will come up again
> when mainlining chips without documentation.

So far the answer seems to be to take the best guess available, and then 
we get to fix it until we have real users and breaking DT compatibility 
is no longer an option... :-)

>> The purpose of the clock in this particular case is just to make the
>> uart driver work, since it wants to know its reference clock; there is
>> work to be done here to figure out the real clock tree
> 
> FWIW arm/boot/dts/mstar-v7.dtsi has the same issue: Needs uart,
> has no uart clock. In that instance the uart clock setup by u-boot
> is passed to the uart driver as a property instead of creating a fake
> clock.

In our case it's an existing driver (with patches) that is already 
integrated with the clock infrastructure, so it makes sense to use a 
fixed-clock instead of just an ad-hoc property.

-- 
Hector Martin (marcan@marcan.st)
Public Key: https://mrcn.st/pub

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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
  2021-02-10 12:55             ` Krzysztof Kozlowski
@ 2021-02-10 13:19               ` Tony Lindgren
  2021-02-10 13:25                 ` Krzysztof Kozlowski
  0 siblings, 1 reply; 82+ messages in thread
From: Tony Lindgren @ 2021-02-10 13:19 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Hector Martin, Arnd Bergmann, devicetree, Marc Zyngier,
	linux-kernel, soc, robh+dt, Olof Johansson, linux-arm-kernel

* Krzysztof Kozlowski <krzk@kernel.org> [210210 12:56]:
> On Wed, Feb 10, 2021 at 01:34:50PM +0200, Tony Lindgren wrote:
> > * Hector Martin <marcan@marcan.st> [210210 11:14]:
> > > On 10/02/2021 19.19, Tony Lindgren wrote:
> > > > * Hector Martin 'marcan' <marcan@marcan.st> [210208 12:05]:
> > > > > On 08/02/2021 20.04, Krzysztof Kozlowski wrote:
> > > > ...
> > > > 
> > > > > > > +	clk24: clk24 {
> > > > > > 
> > > > > > Just "clock". Node names should be generic.
> > > > > 
> > > > > Really? Almost every other device device tree uses unique clock node names.
> > > > 
> > > > Yeah please just use generic node name "clock". FYI, we're still hurting
> > > > because of this for the TI clock node names years after because the drivers
> > > > got a chance to rely on the clock node name..
> > > > 
> > > > Using "clock" means your clock driver code won't get a chance to wrongly
> > > > use the node name and you avoid similar issues.
> > > 
> > > That means it'll end up like this (so that we can have more than one
> > > fixed-clock):
> > > 
> > > clocks {
> > >     #address-cells = <1>;
> > >     #size-cells = <0>;
> > > 
> > >     clk123: clock@0 {
> > >         ...
> > >         reg = <0>
> > >     }
> > > 
> > >     clk456: clock@1 {
> > >         ...
> > >         reg = <1>
> > >     }
> > > }
> > > 
> > > Correct?
> > 
> > Yeah, just don't use an imaginary dummy index for the reg. Use a real
> > register offset from a clock controller instance base, and a register
> > bit offset too if needed.
> 
> No, there is no need for fake "clocks" node with fake addresses. If you
> have multiple clocks, the rules are the same as for other similar cases,
> e.g. leds:
> 
> {
>     clock-0 {
>        ...
>     };
> 
>     clock-1 {
>         ..
>     };
> 
>     soc@0 {
>     };
> }
> 
> This should not generate any dtc W=1 warnings and work with dtschema
> (you need to check for both).

OK yeah so no need for the node name there after the "clock-" :)
Sounds good to me.

Regards,

Tony

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

* Re: [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree
  2021-02-10 13:19               ` Tony Lindgren
@ 2021-02-10 13:25                 ` Krzysztof Kozlowski
  0 siblings, 0 replies; 82+ messages in thread
From: Krzysztof Kozlowski @ 2021-02-10 13:25 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Hector Martin, Arnd Bergmann, devicetree, Marc Zyngier,
	linux-kernel, soc, robh+dt, Olof Johansson, linux-arm-kernel

On Wed, Feb 10, 2021 at 03:19:46PM +0200, Tony Lindgren wrote:
> * Krzysztof Kozlowski <krzk@kernel.org> [210210 12:56]:
> > On Wed, Feb 10, 2021 at 01:34:50PM +0200, Tony Lindgren wrote:
> > > * Hector Martin <marcan@marcan.st> [210210 11:14]:
> > > > On 10/02/2021 19.19, Tony Lindgren wrote:
> > > > > * Hector Martin 'marcan' <marcan@marcan.st> [210208 12:05]:
> > > > > > On 08/02/2021 20.04, Krzysztof Kozlowski wrote:
> > > > > ...
> > > > > 
> > > > > > > > +	clk24: clk24 {
> > > > > > > 
> > > > > > > Just "clock". Node names should be generic.
> > > > > > 
> > > > > > Really? Almost every other device device tree uses unique clock node names.
> > > > > 
> > > > > Yeah please just use generic node name "clock". FYI, we're still hurting
> > > > > because of this for the TI clock node names years after because the drivers
> > > > > got a chance to rely on the clock node name..
> > > > > 
> > > > > Using "clock" means your clock driver code won't get a chance to wrongly
> > > > > use the node name and you avoid similar issues.
> > > > 
> > > > That means it'll end up like this (so that we can have more than one
> > > > fixed-clock):
> > > > 
> > > > clocks {
> > > >     #address-cells = <1>;
> > > >     #size-cells = <0>;
> > > > 
> > > >     clk123: clock@0 {
> > > >         ...
> > > >         reg = <0>
> > > >     }
> > > > 
> > > >     clk456: clock@1 {
> > > >         ...
> > > >         reg = <1>
> > > >     }
> > > > }
> > > > 
> > > > Correct?
> > > 
> > > Yeah, just don't use an imaginary dummy index for the reg. Use a real
> > > register offset from a clock controller instance base, and a register
> > > bit offset too if needed.
> > 
> > No, there is no need for fake "clocks" node with fake addresses. If you
> > have multiple clocks, the rules are the same as for other similar cases,
> > e.g. leds:
> > 
> > {
> >     clock-0 {
> >        ...
> >     };
> > 
> >     clock-1 {
> >         ..
> >     };
> > 
> >     soc@0 {
> >     };
> > }
> > 
> > This should not generate any dtc W=1 warnings and work with dtschema
> > (you need to check for both).
> 
> OK yeah so no need for the node name there after the "clock-" :)
> Sounds good to me.

You also could add a suffix or prefix ("fixed-clock-0", "clock-ext").
There is no strict requirement and Rob admitted that as-is was good
enough.

From my point of view, the dt spec mentions "clock" as one of preferred
names, so I would stick to it.

Anyway, it's not that important. :)

Best regards,
Krzysztof


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

* Re: [PATCH 13/18] arm64: ioremap: use nGnRnE mappings on platforms that require it
  2021-02-10 12:24     ` Hector Martin
@ 2021-02-10 13:40       ` Mark Kettenis
  0 siblings, 0 replies; 82+ messages in thread
From: Mark Kettenis @ 2021-02-10 13:40 UTC (permalink / raw)
  To: Hector Martin
  Cc: will, soc, linux-arm-kernel, maz, robh+dt, linux-kernel,
	devicetree, olof, arnd

> From: Hector Martin <marcan@marcan.st>
> Date: Wed, 10 Feb 2021 21:24:15 +0900

Hi Hector,

Since device tree bindings are widely used outside the Linux tree,
here are some thoughts from a U-Boot and OpenBSD perspective.

> Hi Will, I'm pulling you in at Marc's suggestion. Do you have an opinion 
> on what the better solution to this problem is?
> 
> The executive summary is that Apple SoCs require nGnRnE memory mappings 
> for MMIO, except for PCI space which uses nGnRE. ARM64 currently uses 
> nGnRE everywhere. Solutions discussed in this thread and elsewhere include:
> 
> 1. Something similar to the current hacky patch (which isn't really 
> intended as a real solution...); change ioremap to default to nGnRnE 
> using some kind of platform-level flag in the DT, then figure out how to 
> get the PCI drivers to bypass that. This requires changing almost every 
> PCI driver, since most of them use plain ioremap().
> 
> 2. A per-device DT property that tells of_address_to_resource to set a 
> flag in the struct resource, which is then used by 
> devm_ioremap_resource/of_iomap to pick a new ioremap_ variant for nGnRnE 
> (introduce ioremap_np() for nonposted?) (PCI would work with this 
> inasmuch as it would not support it, and thus fall back to the current 
> nGnRE default, which is correct for PCI...). This requires changing 
> DT-binding drivers that we depend on to not use plain ioremap() (if any 
> do so), but that is a finite subset (unlike PCI which involves 
> potentially every driver, because thunderbolt).

That solution is not dissimilar to how "dma-coherent", "big-endian"
and "little-endian" properties work.  U-Boot could simply ignore the
property since it already has a memory map with the required memory
attributes for each SoC.  I don't see any issue with this for the
OpenBSD kernel either.

The number of existing drivers that would need to be changed is small.
The dwc3 core driver already uses devm_ioremap_resource().  The nvme
driver uses plain ioremap() in the PCI-specific part of the driver,
but that will need new glue for a platform driver anyway.

As things stand now that leaves us with the samsung serial driver
which uses devm_ioremap().  That could be turned into a
devm_iomap_resource() without much trouble I think.

> 3. Encode the mapping type in the address of child devices, either 
> abusing the high bits of the reg or introducing an extra DT cell there, 
> introduce a new OF bus type that strips those away via a ranges mapping 
> and sets flags in the struct resource, similar to what the PCI bus does 
> with its 3-cell ranges, then do as (2) above and make 
> devm_ioremap_resource/of_iomap use it:
> 
> On 09/02/2021 07.57, Arnd Bergmann wrote:
> > #define MAP_NONPOSTED 0x80000000
> > 
> > arm-io { /* name for adt, should be changed */
> >       compatible = "apple,m1-internal-bus";
> >       #address-cells = <2>; /* or maybe <3> if we want */
> >       #size-cells = <2>;
> >       ranges =
> >                 /* on-chip MMIO */
> >                 <(MAP_NONPOSTED | 0x2) 0x0   0x2 0x0 0x1 0x0>,
> > 
> >                /* first PCI: 2GB control, 4GB memory space */
> >               <(MAP_NONPOSTED | 0x3) 0x80000000  0x3 0x80000000  0x0 0x80000000>,
> >                <0x4 0x0   0x4 0x0  0x1 0x0>,
> [...]
> 
> > The MAP_NONPOSTED flag then gets interpreted by the .translate() and
> > .get_flags() callbacks of "struct of_bus" in the kernel, where it is put into
> > a "struct resource" flag, and interpreted when the resource gets mapped.
> > 
> > The PCI host controller nests inside of the node above, and (in theory)
> > uses the same trick to distinguish between prefetchable and non-prefetchable
> > memory, except in practice this is handled in device drivers that already
> > know whether to call ioremap() or ioremap_wc().

Using the high bit in the address would be awkward I think.  For
example in U-Boot I'd have to mask that bit away but doing so in a
per-SoC way would be ugly.  Unless you map the high bit away using a
ranges property for the bus.

Using #address-cells = <3> wll cause some fallout as well as it is
convenient to store addresses as 64-bit integers.  I've written code
that just panics if that isn't possible.

> 4. Introduce a new top-level DT element in the style of reserved-memory, 
> that describes address ranges and the mapping type to use. This could be 
> implemented entirely in arch code, having arm64's ioremap look up the 
> address in a structure populated from this.

This isn't a strange idea either.  For UEFI such a mapping already
exists as a separate table that encodes the cache attributes of
certain memory regions.
 
> As an additional wrinkle, earlycon is almost certainly going to need a 
> special path to handle this very early, before OF stuff is available; it 
> also uses fixmap instead of ioremap, which has its own idea about what 
> type of mapping to use.

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

end of thread, other threads:[~2021-02-10 13:41 UTC | newest]

Thread overview: 82+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-04 20:39 [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin
2021-02-04 20:39 ` [PATCH 01/18] dt-bindings: vendor-prefixes: add AAPL prefix Hector Martin
2021-02-08 10:27   ` Krzysztof Kozlowski
2021-02-08 17:32     ` Rob Herring
2021-02-08 18:12       ` Krzysztof Kozlowski
2021-02-08 23:17         ` Hector Martin
2021-02-04 20:39 ` [PATCH 02/18] dt-bindings: arm: cpus: Add AAPL,firestorm & icestorm compatibles Hector Martin
2021-02-04 20:39 ` [PATCH 03/18] dt-bindings: arm: AAPL: Add bindings for Apple ARM platforms Hector Martin
2021-02-04 20:39 ` [PATCH 04/18] arm64: Kconfig: Introduce CONFIG_ARCH_APPLE Hector Martin
     [not found]   ` <87k0rll4i8.wl-maz@kernel.org>
2021-02-07  8:05     ` Hector Martin 'marcan'
2021-02-04 20:39 ` [PATCH 05/18] tty: serial: samsung_tty: add support for Apple UARTs Hector Martin
2021-02-04 23:55   ` kernel test robot
2021-02-05  9:44     ` Hector Martin 'marcan'
2021-02-05  2:19   ` kernel test robot
     [not found]   ` <87lfc1l4lo.wl-maz@kernel.org>
2021-02-07  9:12     ` Hector Martin 'marcan'
2021-02-07  9:26       ` Hector Martin 'marcan'
2021-02-08  9:36         ` Krzysztof Kozlowski
2021-02-08 16:14           ` Hector Martin
     [not found]       ` <73116feaa00de9173d1f2c35ce16e08f@kernel.org>
2021-02-08 16:18         ` Hector Martin
     [not found]           ` <YCFq3DqOzv4//6Vw@kroah.com>
2021-02-08 23:22             ` Hector Martin
2021-02-08 10:54   ` Krzysztof Kozlowski
2021-02-08 16:10     ` Hector Martin
2021-02-08 18:37       ` Krzysztof Kozlowski
2021-02-08 23:23         ` Hector Martin
2021-02-04 20:39 ` [PATCH 06/18] dt-bindings: serial: samsung: Add AAPL,s5l-uart compatible Hector Martin
2021-02-04 20:39 ` [PATCH 07/18] tty: serial: samsung_tty: enable for ARCH_APPLE Hector Martin
     [not found]   ` <CAK8P3a1n+C5V5J24myy_h67DVp2YTN5Hd=tCWjPUYZcrAX4hCg@mail.gmail.com>
2021-02-04 21:27     ` Hector Martin 'marcan'
2021-02-04 20:39 ` [PATCH 08/18] arm64: cpufeature: Add a feature for FIQ support Hector Martin
     [not found]   ` <87im75l2lp.wl-maz@kernel.org>
2021-02-07  8:28     ` Hector Martin 'marcan'
     [not found]       ` <87czxalrwc.wl-maz@kernel.org>
2021-02-08 15:51         ` Hector Martin
2021-02-04 20:39 ` [PATCH 09/18] arm64: cputype: Add CPU types for the Apple M1 big/little cores Hector Martin
2021-02-04 20:39 ` [PATCH 10/18] arm64: Introduce FIQ support Hector Martin
     [not found]   ` <87h7mpky0f.wl-maz@kernel.org>
     [not found]     ` <CAK8P3a0-Qk1WAUaCWeX8Zypphpadan3YAOES9t7LFYBOJkXKog@mail.gmail.com>
2021-02-07  8:36       ` Hector Martin 'marcan'
     [not found]         ` <CAK8P3a1R51_nqfMWG7SxScJNJEQ3qvp-cynABKEDaQ4O9REM=Q@mail.gmail.com>
2021-02-07 15:38           ` Hector Martin 'marcan'
     [not found]             ` <CAK8P3a1vmUJ0EpzU2+u2gy8WHCVV5ur9u-oTzU2BP=ddbXQeLQ@mail.gmail.com>
2021-02-08 23:34               ` Hector Martin
2021-02-07  8:47     ` Hector Martin 'marcan'
2021-02-04 20:39 ` [PATCH 11/18] arm64: Kconfig: Require FIQ support for ARCH_APPLE Hector Martin
     [not found]   ` <87ft29kxmp.wl-maz@kernel.org>
2021-02-07  9:23     ` Hector Martin 'marcan'
     [not found]       ` <2a93bf0df74df8cb022e61d69d1de88e@kernel.org>
2021-02-08 15:48         ` Hector Martin
2021-02-04 20:39 ` [PATCH 12/18] arm64: setup: Use nGnRnE IO mappings for fixmap on Apple platforms Hector Martin
2021-02-04 20:39 ` [PATCH 13/18] arm64: ioremap: use nGnRnE mappings on platforms that require it Hector Martin
     [not found]   ` <CAK8P3a2Ad+xmmMWgznOHPpxgCXKWFYfpHBqt_49_UuxrwFSq+A@mail.gmail.com>
2021-02-08 23:20     ` Mark Kettenis
2021-02-09  0:25       ` Hector Martin
     [not found]         ` <CAK8P3a043eO4p2o6tizR2x7a1TZHMqO7TdX53JC4bTZnbQd9iQ@mail.gmail.com>
2021-02-09  9:58           ` Mark Kettenis
2021-02-09 11:22           ` Hector Martin
2021-02-10 12:24     ` Hector Martin
2021-02-10 13:40       ` Mark Kettenis
2021-02-04 20:39 ` [PATCH 14/18] dt-bindings: interrupt-controller: Add DT bindings for apple-aic Hector Martin
2021-02-09 23:07   ` Rob Herring
2021-02-04 20:39 ` [PATCH 15/18] irqchip/apple-aic: Add support for the Apple Interrupt Controller Hector Martin
     [not found]   ` <CAK8P3a1zbLM0s_GwkJ0AJQ8cocS-zcsWWKhOB7B99OtRYyDE7g@mail.gmail.com>
2021-02-04 22:04     ` Hector Martin 'marcan'
     [not found]       ` <CAK8P3a14vsLkCujd_XBAOAjL2h878gxkaoKPpaxL4jddZZcc-A@mail.gmail.com>
2021-02-05  7:41         ` Hector Martin 'marcan'
2021-02-05  2:27   ` kernel test robot
2021-02-05  9:45     ` Hector Martin 'marcan'
     [not found]   ` <87eehqlxlr.wl-maz@kernel.org>
     [not found]     ` <CAK8P3a25eFFrMG-9QknFZ6Ckc3-gkiLK=jQdnyTMgn-z4X0RHQ@mail.gmail.com>
2021-02-08 11:13       ` Hector Martin 'marcan'
     [not found]       ` <87a6selrkt.wl-maz@kernel.org>
2021-02-08 15:31         ` Hector Martin
2021-02-09  6:20     ` Hector Martin
2021-02-04 20:39 ` [PATCH 16/18] irqchip/apple-aic: Add SMP / IPI support Hector Martin
2021-02-04 20:39 ` [PATCH 17/18] dt-bindings: display: add AAPL,simple-framebuffer Hector Martin
2021-02-04 20:39 ` [PATCH 18/18] arm64: apple: Add initial Mac Mini 2020 (M1) devicetree Hector Martin
     [not found]   ` <CAK8P3a3v6emxavbyjFhY+WdvH1t4EPMZSjEsSx0M+cRqjRCO1g@mail.gmail.com>
2021-02-04 21:44     ` Hector Martin 'marcan'
     [not found]       ` <CAK8P3a2DawQA-PD5aqbkVPB7UxuohN0oe9mJPe8488pUryotJQ@mail.gmail.com>
2021-02-05  7:11         ` Hector Martin 'marcan'
2021-02-08 11:04   ` Krzysztof Kozlowski
2021-02-08 11:56     ` Hector Martin 'marcan'
2021-02-08 12:13       ` Krzysztof Kozlowski
     [not found]         ` <CAK8P3a0yBC3dui6vcz+NByWD-3LqRj-2MF89jpjb_k8r5xmNRA@mail.gmail.com>
2021-02-08 14:12           ` Hector Martin
2021-02-08 17:58             ` Rob Herring
2021-02-09  0:32               ` Hector Martin
2021-02-08 19:14       ` Rob Herring
2021-02-09  0:49         ` Hector Martin
2021-02-10 10:19       ` Tony Lindgren
2021-02-10 11:07         ` Hector Martin
2021-02-10 11:34           ` Tony Lindgren
2021-02-10 11:43             ` Hector Martin
2021-02-10 12:24               ` Daniel Palmer
2021-02-10 12:54                 ` Tony Lindgren
2021-02-10 12:56                 ` Hector Martin
2021-02-10 12:55             ` Krzysztof Kozlowski
2021-02-10 13:19               ` Tony Lindgren
2021-02-10 13:25                 ` Krzysztof Kozlowski
     [not found]   ` <a2825482e2f68c2f8cad7cb564414759@kernel.org>
2021-02-08 14:53     ` Hector Martin
2021-02-05 11:35 ` [PATCH 00/18] Apple M1 SoC platform bring-up Hector Martin 'marcan'

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).