From c38fe0da9ec361ad27392a5938780815365c97a7 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 30 Apr 2026 21:21:09 +0200 Subject: [PATCH 01/41] nvme: apple: add "apple,t8103-nvme-ans2" compatible After discussion with the devicetree maintainers we agreed to not extend lists with the generic compatible "apple,nvme-ans2" anymore [1]. Add "apple,t8103-nvme-ans2" as fallback compatible as this is the SoC the driver and bindings were originally written for. The t602x (M2 Pro/Max/Ultra) devicetrees submitted in [2] use this compatible as fallback instead of "apple,t8103-nvme-ans2". Link: https://lore.kernel.org/asahi/12ab93b7-1fc2-4ce0-926e-c8141cfe81bf@kernel.org/ [1] Link: https://lore.kernel.org/asahi/20250828-dt-apple-t6020-v1-0-507ba4c4b98e@jannau.net/ [2] Signed-off-by: Janne Grunau --- drivers/nvme/nvme_apple.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/nvme/nvme_apple.c b/drivers/nvme/nvme_apple.c index 7e7538553e3..48f82bc826c 100644 --- a/drivers/nvme/nvme_apple.c +++ b/drivers/nvme/nvme_apple.c @@ -287,6 +287,7 @@ static const struct nvme_ops apple_nvme_ops = { }; static const struct udevice_id apple_nvme_ids[] = { + { .compatible = "apple,t8103-nvme-ans2" }, { .compatible = "apple,nvme-ans2" }, { /* sentinel */ } }; From 875354fcbfd9bf99884589499860fe0cda8d03fe Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 30 Apr 2026 21:52:39 +0200 Subject: [PATCH 02/41] pinctrl: apple: Add "apple,t8103-pinctrl" compatible After discussion with the devicetree maintainers we agreed to not extend lists with the generic compatible "apple,pinctrl" anymore [1]. Use "apple,t8103-pinctrl" as fallback compatible as it is the SoC driver and bindings were originally written for. The t602x (M2 Pro/Max/Ultra) devicetrees submitted in [2] use this compatible as fallback instead of "apple,t8103-pinctrl". Link: https://lore.kernel.org/asahi/12ab93b7-1fc2-4ce0-926e-c8141cfe81bf@kernel.org/ [1] Link: https://lore.kernel.org/asahi/20250828-dt-apple-t6020-v1-0-507ba4c4b98e@jannau.net/ [2] Signed-off-by: Janne Grunau --- drivers/pinctrl/pinctrl-apple.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/pinctrl-apple.c b/drivers/pinctrl/pinctrl-apple.c index f373afde58e..083ea6d6cd5 100644 --- a/drivers/pinctrl/pinctrl-apple.c +++ b/drivers/pinctrl/pinctrl-apple.c @@ -192,6 +192,7 @@ static struct pinctrl_ops apple_pinctrl_ops = { }; static const struct udevice_id apple_pinctrl_ids[] = { + { .compatible = "apple,t8103-pinctrl" }, { .compatible = "apple,pinctrl" }, { /* sentinel */ } }; From 25c40c21c5befeb9abc44c36c3293666108d0170 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 30 Apr 2026 21:55:35 +0200 Subject: [PATCH 03/41] power: domain: apple: Add "apple,t8103-pmgr-pwrstate" compatible After discussion with the devicetree maintainers we agreed to not extend lists with the generic compatible "apple,pmgr-pwrstate" anymore [1]. Use "apple,t8103-pmgr-pwrstate" as base compatible as it is the SoC driver and bindings were originally written for. The t602x (M2 Pro/Max/Ultra) devicetrees submitted in [2] use this compatible as fallback instead of "apple,pmgr-pwrstate". Link: https://lore.kernel.org/asahi/12ab93b7-1fc2-4ce0-926e-c8141cfe81bf@kernel.org/ [1] Link: https://lore.kernel.org/asahi/20250828-dt-apple-t6020-v1-0-507ba4c4b98e@jannau.net/ [2] Signed-off-by: Janne Grunau --- drivers/power/domain/apple-pmgr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/power/domain/apple-pmgr.c b/drivers/power/domain/apple-pmgr.c index bf9940621ee..71fedb405da 100644 --- a/drivers/power/domain/apple-pmgr.c +++ b/drivers/power/domain/apple-pmgr.c @@ -110,6 +110,7 @@ static int apple_pmgr_of_xlate(struct power_domain *power_domain, } static const struct udevice_id apple_pmgr_ids[] = { + { .compatible = "apple,t8103-pmgr-pwrstate" }, { .compatible = "apple,pmgr-pwrstate" }, { /* sentinel */ } }; From 39ee4f12d547eb2bfc726c99f1af22f7b5fcfdf4 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 30 Apr 2026 22:05:37 +0200 Subject: [PATCH 04/41] spi: apple: Add "apple,t8103-spi" compatible After discussion with the devicetree maintainers we agreed to not extend lists with the generic compatible "apple,spi" anymore [1]. Use "apple,t8103-spi" as base compatible as it is the SoC driver and bindings were originally written for. The t602x (M2 Pro/Max/Ultra) devicetrees submitted in [2] use this compatible as fallback instead of "apple,spi". Link: https://lore.kernel.org/asahi/12ab93b7-1fc2-4ce0-926e-c8141cfe81bf@kernel.org/ [1] Link: https://lore.kernel.org/asahi/20250828-dt-apple-t6020-v1-0-507ba4c4b98e@jannau.net/ [2] Signed-off-by: Janne Grunau --- drivers/spi/apple_spi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/spi/apple_spi.c b/drivers/spi/apple_spi.c index 5f94e9f7a74..088d02e3b90 100644 --- a/drivers/spi/apple_spi.c +++ b/drivers/spi/apple_spi.c @@ -270,6 +270,7 @@ static int apple_spi_probe(struct udevice *dev) } static const struct udevice_id apple_spi_of_match[] = { + { .compatible = "apple,t8103-spi" }, { .compatible = "apple,spi" }, { /* sentinel */ } }; From 8087a722706c758bf9d94e324753029c4f6f80d8 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 30 Apr 2026 22:09:32 +0200 Subject: [PATCH 05/41] watchdog: apple: Add "apple,t8103-wdt" compatible After discussion with the devicetree maintainers we agreed to not extend lists with the generic compatible "apple,wdt" anymore [1]. Use "apple,t8103-wdt" as base compatible as it is the SoC driver and bindings were originally written for. The t602x (M2 Pro/Max/Ultra) devicetrees submitted in [2] use this compatible as fallback instead of "apple,wdt". Link: https://lore.kernel.org/asahi/12ab93b7-1fc2-4ce0-926e-c8141cfe81bf@kernel.org/ [1] Link: https://lore.kernel.org/asahi/20250828-dt-apple-t6020-v1-0-507ba4c4b98e@jannau.net/ [2] Signed-off-by: Janne Grunau --- drivers/watchdog/apple_wdt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/watchdog/apple_wdt.c b/drivers/watchdog/apple_wdt.c index c7307f41cb7..9e998994216 100644 --- a/drivers/watchdog/apple_wdt.c +++ b/drivers/watchdog/apple_wdt.c @@ -78,6 +78,7 @@ static const struct wdt_ops apple_wdt_ops = { }; static const struct udevice_id apple_wdt_ids[] = { + { .compatible = "apple,t8103-wdt" }, { .compatible = "apple,wdt" }, { /* sentinel */ } }; From 069ee0692959ee29c6fed077ca82012f30ce93ed Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 16 Jan 2026 15:09:28 +0100 Subject: [PATCH 06/41] doc: board: apple: Mention M2 and M2 Pro/Max/Ultra SoCs These SoCs are supported since 2022/2023 but were never added to the documentation. The devices very similar to the equivalent M1 devices. The biggest difference is that the M2 and M2 Pro/Max based laptops no longer use SPI for the keyboard. Signed-off-by: Janne Grunau --- doc/board/apple/m1.rst | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/doc/board/apple/m1.rst b/doc/board/apple/m1.rst index 8fa7637629e..5d2cf750fde 100644 --- a/doc/board/apple/m1.rst +++ b/doc/board/apple/m1.rst @@ -8,14 +8,18 @@ developed by the Asahi Linux project. At this point the machines with the following SoCs work: - Apple M1 SoC (t8103) + - Apple M2 SoC (t8112) - Apple M1 Pro SoC (t6000) - Apple M1 Max SoC (t6001) - Apple M1 Ultra SoC (t6002) + - Apple M2 Pro SoC (t6020) + - Apple M2 Max SoC (t6021) + - Apple M2 Ultra SoC (t6022) On these SoCs the following hardware is supported: - S5L serial port - - SPI keyboard (on laptops) + - SPI keyboard (on M1 laptops) - Framebuffer - NVMe storage - USB 3.1 Type-C ports @@ -77,7 +81,7 @@ supported SoCs. * - SoC - Base Address - * - M1 (t8103) + * - M1 (t8103) and M2 (t8112) - 0x235200000 - * - M1 Pro/Max/Ultra (t6000/t6001/t6002) + * - M1 Pro/Max/Ultra (t6000/t6001/t6002) and M2 Pro/Max/Ultra (t6020/t6021/t6022) - 0x39b200000 From 65ebb5d2ce9a9e0e58c57f4ceac153a233320f65 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 9 Jan 2026 22:17:06 +0100 Subject: [PATCH 07/41] doc: device-tree-bindings: Remove apple,pinctrl.yaml Remove outdated apple,pinctrl.yaml. The dts/upstream contains the current version of this binding. Signed-off-by: Janne Grunau --- .../pinctrl/apple,pinctrl.yaml | 106 ------------------ 1 file changed, 106 deletions(-) delete mode 100644 doc/device-tree-bindings/pinctrl/apple,pinctrl.yaml diff --git a/doc/device-tree-bindings/pinctrl/apple,pinctrl.yaml b/doc/device-tree-bindings/pinctrl/apple,pinctrl.yaml deleted file mode 100644 index d50571affd1..00000000000 --- a/doc/device-tree-bindings/pinctrl/apple,pinctrl.yaml +++ /dev/null @@ -1,106 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/pinctrl/apple,pinctrl.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Apple GPIO controller - -maintainers: - - Mark Kettenis - -description: | - The Apple GPIO controller is a simple combined pin and GPIO - controller present on Apple ARM SoC platforms, including various - iPhone and iPad devices and the "Apple Silicon" Macs. - -properties: - compatible: - items: - - const: apple,t8103-pinctrl - - const: apple,pinctrl - - reg: - maxItems: 1 - - clocks: - maxItems: 1 - - gpio-controller: true - - '#gpio-cells': - const: 2 - - gpio-ranges: - maxItems: 1 - - interrupts: - description: One interrupt for each of the (up to 7) interrupt - groups supported by the controller sorted by interrupt group - number in ascending order. - minItems: 1 - maxItems: 7 - - interrupt-controller: true - -patternProperties: - '-pins$': - type: object - $ref: pinmux-node.yaml# - - properties: - pinmux: - description: - Values are constructed from pin number and alternate function - configuration number using the APPLE_PINMUX() helper macro - defined in include/dt-bindings/pinctrl/apple.h. - - required: - - pinmux - - additionalProperties: false - -required: - - compatible - - reg - - gpio-controller - - '#gpio-cells' - - gpio-ranges - -additionalProperties: false - -examples: - - | - #include - #include - - soc { - #address-cells = <2>; - #size-cells = <2>; - - pinctrl: pinctrl@23c100000 { - compatible = "apple,t8103-pinctrl", "apple,pinctrl"; - reg = <0x2 0x3c100000 0x0 0x100000>; - clocks = <&gpio_clk>; - - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pinctrl 0 0 212>; - - interrupt-controller; - interrupt-parent = <&aic>; - interrupts = , - , - , - , - , - , - ; - - pcie_pins: pcie-pins { - pinmux = , - , - ; - }; - }; - }; From 360ba4a4b3843b92438b62a9c5b9f02584821498 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 9 Jan 2026 22:22:37 +0100 Subject: [PATCH 08/41] arm: dts: Switch Apple silicon devices to dts/upstream The device tree on Apple silicon devices is passed from a previous bootloader stage. The bootloader fills in dynamic information so u-boot can not use its own device tree. As documented in doc/board/apple/m1.rst it is possible to build boot bundles (bootloader + device tree + gzipped u-boot binary). These are useful for testing. Instead of using u-boot's own device trees for M1 (t8103) devices use upstream device trees from dts/upstream/src/arm64/apple. The u-boot device trees have not seen updates since 2022. The upstream linux device trees have feature parity for the M1 devices. In addition linux has device trees for M1 Pro/Max/Ultra, M2 and M2 Pro/Max/Ultra devices. Keep t8103-j274 as default device tree to avoid further updates. Signed-off-by: Janne Grunau --- arch/arm/Kconfig | 1 + arch/arm/dts/Makefile | 7 - arch/arm/dts/t8103-j274-u-boot.dtsi | 1 - arch/arm/dts/t8103-j274.dts | 129 --- arch/arm/dts/t8103-j293-u-boot.dtsi | 1 - arch/arm/dts/t8103-j293.dts | 116 --- arch/arm/dts/t8103-j313-u-boot.dtsi | 1 - arch/arm/dts/t8103-j313.dts | 111 --- arch/arm/dts/t8103-j456-u-boot.dtsi | 1 - arch/arm/dts/t8103-j456.dts | 117 --- arch/arm/dts/t8103-j457-u-boot.dtsi | 1 - arch/arm/dts/t8103-j457.dts | 105 --- arch/arm/dts/t8103-jxxx.dtsi | 143 ---- arch/arm/dts/t8103-pmgr.dtsi | 1138 --------------------------- arch/arm/dts/t8103-u-boot.dtsi | 25 - arch/arm/dts/t8103.dtsi | 696 ---------------- configs/apple_m1_defconfig | 2 +- doc/board/apple/m1.rst | 5 +- 18 files changed, 4 insertions(+), 2596 deletions(-) delete mode 100644 arch/arm/dts/t8103-j274-u-boot.dtsi delete mode 100644 arch/arm/dts/t8103-j274.dts delete mode 100644 arch/arm/dts/t8103-j293-u-boot.dtsi delete mode 100644 arch/arm/dts/t8103-j293.dts delete mode 100644 arch/arm/dts/t8103-j313-u-boot.dtsi delete mode 100644 arch/arm/dts/t8103-j313.dts delete mode 100644 arch/arm/dts/t8103-j456-u-boot.dtsi delete mode 100644 arch/arm/dts/t8103-j456.dts delete mode 100644 arch/arm/dts/t8103-j457-u-boot.dtsi delete mode 100644 arch/arm/dts/t8103-j457.dts delete mode 100644 arch/arm/dts/t8103-jxxx.dtsi delete mode 100644 arch/arm/dts/t8103-pmgr.dtsi delete mode 100644 arch/arm/dts/t8103-u-boot.dtsi delete mode 100644 arch/arm/dts/t8103.dtsi diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index cd6a454fd60..3f9bbfe6c5b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1068,6 +1068,7 @@ config ARCH_APPLE imply CMD_GPT imply BOOTSTD_FULL imply OF_HAS_PRIOR_STAGE + imply OF_UPSTREAM config ARCH_OWL bool "Actions Semi OWL SoCs" diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 82ad3035308..3ff2577c605 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -32,13 +32,6 @@ dtb-$(CONFIG_TARGET_A5Y17LTE) += exynos78x0-axy17lte.dtb dtb-$(CONFIG_TARGET_A3Y17LTE) += exynos78x0-axy17lte.dtb dtb-$(CONFIG_TARGET_A7Y17LTE) += exynos78x0-axy17lte.dtb -dtb-$(CONFIG_ARCH_APPLE) += \ - t8103-j274.dtb \ - t8103-j293.dtb \ - t8103-j313.dtb \ - t8103-j456.dtb \ - t8103-j457.dtb - dtb-$(CONFIG_ARCH_DAVINCI) += \ da850-lcdk.dtb \ da850-lego-ev3.dtb diff --git a/arch/arm/dts/t8103-j274-u-boot.dtsi b/arch/arm/dts/t8103-j274-u-boot.dtsi deleted file mode 100644 index 6c8dd5a56f8..00000000000 --- a/arch/arm/dts/t8103-j274-u-boot.dtsi +++ /dev/null @@ -1 +0,0 @@ -#include "t8103-u-boot.dtsi" diff --git a/arch/arm/dts/t8103-j274.dts b/arch/arm/dts/t8103-j274.dts deleted file mode 100644 index 9bc592bcdbf..00000000000 --- a/arch/arm/dts/t8103-j274.dts +++ /dev/null @@ -1,129 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ OR MIT -/* - * Apple Mac mini (M1, 2020) - * - * target-type: J274 - * - * Copyright The Asahi Linux Contributors - */ - -/dts-v1/; - -#include "t8103.dtsi" -#include "t8103-jxxx.dtsi" - -/ { - compatible = "apple,j274", "apple,t8103", "apple,arm-platform"; - model = "Apple Mac mini (M1, 2020)"; - - aliases { - ethernet0 = ðernet0; - }; -}; - -&wifi0 { - brcm,board-type = "apple,atlantisb"; -}; - -/* - * Provide labels for the USB type C ports. - */ - -&typec0 { - label = "USB-C Back-left"; -}; - -&typec1 { - label = "USB-C Back-right"; -}; - -/* - * Force the bus number assignments so that we can declare some of the - * on-board devices and properties that are populated by the bootloader - * (such as MAC addresses). - */ - -&port01 { - bus-range = <2 2>; -}; - -&port02 { - bus-range = <3 3>; - ethernet0: ethernet@0,0 { - reg = <0x30000 0x0 0x0 0x0 0x0>; - /* To be filled by the loader */ - local-mac-address = [00 10 18 00 00 00]; - }; -}; - -&i2c1 { - clock-frequency = <50000>; - - speaker_amp: codec@31 { - compatible = "ti,tas5770l", "ti,tas2770"; - reg = <0x31>; - reset-gpios = <&pinctrl_ap 181 GPIO_ACTIVE_HIGH>; - #sound-dai-cells = <0>; - }; -}; - -&i2c2 { - status = "okay"; - - clock-frequency = <50000>; - - jack_codec: codec@48 { - compatible = "cirrus,cs42l83", "cirrus,cs42l42"; - reg = <0x48>; - reset-gpios = <&pinctrl_nub 11 GPIO_ACTIVE_HIGH>; - interrupt-parent = <&pinctrl_ap>; - interrupts = <183 IRQ_TYPE_LEVEL_LOW>; - #sound-dai-cells = <0>; - cirrus,ts-inv = <1>; - }; -}; - -/ { - sound { - compatible = "simple-audio-card"; - simple-audio-card,name = "Mac mini integrated audio"; - #address-cells = <1>; - #size-cells = <0>; - - simple-audio-card,dai-link@0 { - reg = <0>; - format = "left_j"; - tdm-slot-width = <32>; - mclk-fs = <64>; - - link0_cpu: cpu { - sound-dai = <&mca 0>; - bitclock-master; - frame-master; - }; - - link0_codec: codec { - sound-dai = <&speaker_amp>; - }; - }; - - simple-audio-card,dai-link@1 { - bitclock-inversion; - frame-inversion; - reg = <1>; - format = "i2s"; - mclk-fs = <64>; - tdm-slot-width = <32>; - - link1_cpu: cpu { - sound-dai = <&mca 2>; - bitclock-master; - frame-master; - }; - - link1_codec: codec { - sound-dai = <&jack_codec>; - }; - }; - }; -}; diff --git a/arch/arm/dts/t8103-j293-u-boot.dtsi b/arch/arm/dts/t8103-j293-u-boot.dtsi deleted file mode 100644 index 6c8dd5a56f8..00000000000 --- a/arch/arm/dts/t8103-j293-u-boot.dtsi +++ /dev/null @@ -1 +0,0 @@ -#include "t8103-u-boot.dtsi" diff --git a/arch/arm/dts/t8103-j293.dts b/arch/arm/dts/t8103-j293.dts deleted file mode 100644 index de1a21d97cd..00000000000 --- a/arch/arm/dts/t8103-j293.dts +++ /dev/null @@ -1,116 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ OR MIT -/* - * Apple MacBook Pro (13-inch, M1, 2020) - * - * target-type: J293 - * - * Copyright The Asahi Linux Contributors - */ - -/dts-v1/; - -#include "t8103.dtsi" -#include "t8103-jxxx.dtsi" - -/ { - compatible = "apple,j293", "apple,t8103", "apple,arm-platform"; - model = "Apple MacBook Pro (13-inch, M1, 2020)"; -}; - -&wifi0 { - brcm,board-type = "apple,honshu"; -}; - -/* - * Provide labels for the USB type C ports. - */ - -&typec0 { - label = "USB-C Left-back"; -}; - -&typec1 { - label = "USB-C Left-front"; -}; - -&spi3 { - status = "okay"; - - hid-transport@0 { - compatible = "apple,spi-hid-transport"; - reg = <0>; - spi-max-frequency = <8000000>; - /* - * cs-setup and cs-hold delays are derived from Apple's ADT - * Mac OS driver meta data secify 45 us for 'cs to clock' and - * 'clock to cs' delays. - */ - spi-cs-setup-delay-ns = <20000>; - spi-cs-hold-delay-ns = <20000>; - spi-cs-inactive-delay-ns = <250000>; - spien-gpios = <&pinctrl_ap 195 0>; - interrupts-extended = <&pinctrl_nub 13 IRQ_TYPE_LEVEL_LOW>; - }; -}; - -/* - * Remove unused PCIe ports and disable the associated DARTs. - */ - -&pcie0_dart_1 { - status = "disabled"; -}; - -&pcie0_dart_2 { - status = "disabled"; -}; - -/delete-node/ &port01; -/delete-node/ &port02; - -&i2c2 { - status = "okay"; - clock-frequency = <50000>; - - jack_codec: codec@48 { - compatible = "cirrus,cs42l83", "cirrus,cs42l42"; - reg = <0x48>; - reset-gpios = <&pinctrl_nub 11 GPIO_ACTIVE_HIGH>; - interrupt-parent = <&pinctrl_ap>; - interrupts = <183 IRQ_TYPE_LEVEL_LOW>; - #sound-dai-cells = <0>; - cirrus,ts-inv = <1>; - }; -}; - -&i2c4 { - status = "okay"; -}; - -/ { - sound { - compatible = "simple-audio-card"; - simple-audio-card,name = "MacBook integrated audio"; - #address-cells = <1>; - #size-cells = <0>; - - simple-audio-card,dai-link@0 { - bitclock-inversion; - frame-inversion; - reg = <0>; - format = "i2s"; - mclk-fs = <64>; - tdm-slot-width = <32>; - - link0_cpu: cpu { - sound-dai = <&mca 2>; - bitclock-master; - frame-master; - }; - - link0_codec: codec { - sound-dai = <&jack_codec>; - }; - }; - }; -}; diff --git a/arch/arm/dts/t8103-j313-u-boot.dtsi b/arch/arm/dts/t8103-j313-u-boot.dtsi deleted file mode 100644 index 6c8dd5a56f8..00000000000 --- a/arch/arm/dts/t8103-j313-u-boot.dtsi +++ /dev/null @@ -1 +0,0 @@ -#include "t8103-u-boot.dtsi" diff --git a/arch/arm/dts/t8103-j313.dts b/arch/arm/dts/t8103-j313.dts deleted file mode 100644 index 5efe8d7a63b..00000000000 --- a/arch/arm/dts/t8103-j313.dts +++ /dev/null @@ -1,111 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ OR MIT -/* - * Apple MacBook Air (M1, 2020) - * - * target-type: J313 - * - * Copyright The Asahi Linux Contributors - */ - -/dts-v1/; - -#include "t8103.dtsi" -#include "t8103-jxxx.dtsi" - -/ { - compatible = "apple,j313", "apple,t8103", "apple,arm-platform"; - model = "Apple MacBook Air (M1, 2020)"; -}; - -&wifi0 { - brcm,board-type = "apple,shikoku"; -}; - -/* - * Provide labels for the USB type C ports. - */ - -&typec0 { - label = "USB-C Left-back"; -}; - -&typec1 { - label = "USB-C Left-front"; -}; - -&spi3 { - status = "okay"; - - hid-transport@0 { - compatible = "apple,spi-hid-transport"; - reg = <0>; - spi-max-frequency = <8000000>; - /* - * cs-setup and cs-hold delays are derived from Apple's ADT - * Mac OS driver meta data secify 45 us for 'cs to clock' and - * 'clock to cs' delays. - */ - spi-cs-setup-delay-ns = <20000>; - spi-cs-hold-delay-ns = <20000>; - spi-cs-inactive-delay-ns = <250000>; - spien-gpios = <&pinctrl_ap 195 0>; - interrupts-extended = <&pinctrl_nub 13 IRQ_TYPE_LEVEL_LOW>; - }; -}; - -/* - * Remove unused PCIe ports and disable the associated DARTs. - */ - -&pcie0_dart_1 { - status = "disabled"; -}; - -&pcie0_dart_2 { - status = "disabled"; -}; - -/delete-node/ &port01; -/delete-node/ &port02; - -&i2c3 { - clock-frequency = <50000>; - - jack_codec: codec@48 { - compatible = "cirrus,cs42l83", "cirrus,cs42l42"; - reg = <0x48>; - reset-gpios = <&pinctrl_nub 11 GPIO_ACTIVE_HIGH>; - interrupt-parent = <&pinctrl_ap>; - interrupts = <183 IRQ_TYPE_LEVEL_LOW>; - #sound-dai-cells = <0>; - cirrus,ts-inv = <1>; - }; -}; - -/ { - sound { - compatible = "simple-audio-card"; - simple-audio-card,name = "MacBook integrated audio"; - #address-cells = <1>; - #size-cells = <0>; - - simple-audio-card,dai-link@0 { - bitclock-inversion; - frame-inversion; - reg = <0>; - format = "i2s"; - mclk-fs = <64>; - tdm-slot-width = <32>; - - link0_cpu: cpu { - sound-dai = <&mca 2>; - bitclock-master; - frame-master; - }; - - link0_codec: codec { - sound-dai = <&jack_codec>; - }; - }; - }; -}; diff --git a/arch/arm/dts/t8103-j456-u-boot.dtsi b/arch/arm/dts/t8103-j456-u-boot.dtsi deleted file mode 100644 index 6c8dd5a56f8..00000000000 --- a/arch/arm/dts/t8103-j456-u-boot.dtsi +++ /dev/null @@ -1 +0,0 @@ -#include "t8103-u-boot.dtsi" diff --git a/arch/arm/dts/t8103-j456.dts b/arch/arm/dts/t8103-j456.dts deleted file mode 100644 index 8624168bdb7..00000000000 --- a/arch/arm/dts/t8103-j456.dts +++ /dev/null @@ -1,117 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ OR MIT -/* - * Apple iMac (24-inch, 4x USB-C, M1, 2020) - * - * target-type: J456 - * - * Copyright The Asahi Linux Contributors - */ - -/dts-v1/; - -#include "t8103.dtsi" -#include "t8103-jxxx.dtsi" - -/ { - compatible = "apple,j456", "apple,t8103", "apple,arm-platform"; - model = "Apple iMac (24-inch, 4x USB-C, M1, 2020)"; - - aliases { - ethernet0 = ðernet0; - }; -}; - -&wifi0 { - brcm,board-type = "apple,capri"; -}; - -&i2c0 { - hpm2: usb-pd@3b { - compatible = "apple,cd321x"; - reg = <0x3b>; - interrupt-parent = <&pinctrl_ap>; - interrupts = <106 IRQ_TYPE_LEVEL_LOW>; - interrupt-names = "irq"; - }; - - hpm3: usb-pd@3c { - compatible = "apple,cd321x"; - reg = <0x3c>; - interrupt-parent = <&pinctrl_ap>; - interrupts = <106 IRQ_TYPE_LEVEL_LOW>; - interrupt-names = "irq"; - }; -}; - -/* - * Provide labels for the USB type C ports. - */ - -&typec0 { - label = "USB-C Back-right"; -}; - -&typec1 { - label = "USB-C Back-right-middle"; -}; - -/* - * Force the bus number assignments so that we can declare some of the - * on-board devices and properties that are populated by the bootloader - * (such as MAC addresses). - */ - -&port01 { - bus-range = <2 2>; -}; - -&port02 { - bus-range = <3 3>; - ethernet0: ethernet@0,0 { - reg = <0x30000 0x0 0x0 0x0 0x0>; - /* To be filled by the loader */ - local-mac-address = [00 10 18 00 00 00]; - }; -}; - -&i2c1 { - clock-frequency = <50000>; - - jack_codec: codec@48 { - compatible = "cirrus,cs42l83", "cirrus,cs42l42"; - reg = <0x48>; - reset-gpios = <&pinctrl_nub 11 GPIO_ACTIVE_HIGH>; - interrupt-parent = <&pinctrl_ap>; - interrupts = <183 IRQ_TYPE_LEVEL_LOW>; - #sound-dai-cells = <0>; - cirrus,ts-inv = <1>; - }; -}; - -/ { - sound { - compatible = "simple-audio-card"; - simple-audio-card,name = "iMac integrated audio"; - #address-cells = <1>; - #size-cells = <0>; - - simple-audio-card,dai-link@0 { - bitclock-inversion; - frame-inversion; - reg = <0>; - format = "i2s"; - mclk-fs = <64>; - tdm-slot-width = <32>; - - link0_cpu: cpu { - sound-dai = <&mca 2>; - bitclock-master; - frame-master; - }; - - link0_codec: codec { - sound-dai = <&jack_codec>; - }; - }; - }; -}; diff --git a/arch/arm/dts/t8103-j457-u-boot.dtsi b/arch/arm/dts/t8103-j457-u-boot.dtsi deleted file mode 100644 index 6c8dd5a56f8..00000000000 --- a/arch/arm/dts/t8103-j457-u-boot.dtsi +++ /dev/null @@ -1 +0,0 @@ -#include "t8103-u-boot.dtsi" diff --git a/arch/arm/dts/t8103-j457.dts b/arch/arm/dts/t8103-j457.dts deleted file mode 100644 index f3eec8d4729..00000000000 --- a/arch/arm/dts/t8103-j457.dts +++ /dev/null @@ -1,105 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ OR MIT -/* - * Apple iMac (24-inch, 2x USB-C, M1, 2020) - * - * target-type: J457 - * - * Copyright The Asahi Linux Contributors - */ - -/dts-v1/; - -#include "t8103.dtsi" -#include "t8103-jxxx.dtsi" - -/ { - compatible = "apple,j457", "apple,t8103", "apple,arm-platform"; - model = "Apple iMac (24-inch, 2x USB-C, M1, 2020)"; - - aliases { - ethernet0 = ðernet0; - }; -}; - -&wifi0 { - brcm,board-type = "apple,santorini"; -}; - -/* - * Provide labels for the USB type C ports. - */ - -&typec0 { - label = "USB-C Back-right"; -}; - -&typec1 { - label = "USB-C Back-left"; -}; - -/* - * Force the bus number assignments so that we can declare some of the - * on-board devices and properties that are populated by the bootloader - * (such as MAC addresses). - */ - -&port02 { - bus-range = <3 3>; - ethernet0: ethernet@0,0 { - reg = <0x30000 0x0 0x0 0x0 0x0>; - /* To be filled by the loader */ - local-mac-address = [00 10 18 00 00 00]; - }; -}; - -/* - * Remove unused PCIe port and disable the associated DART. - */ - -&pcie0_dart_1 { - status = "disabled"; -}; - -/delete-node/ &port01; - -&i2c1 { - clock-frequency = <50000>; - - jack_codec: codec@48 { - compatible = "cirrus,cs42l83", "cirrus,cs42l42"; - reg = <0x48>; - reset-gpios = <&pinctrl_nub 11 GPIO_ACTIVE_HIGH>; - interrupt-parent = <&pinctrl_ap>; - interrupts = <183 IRQ_TYPE_LEVEL_LOW>; - #sound-dai-cells = <0>; - cirrus,ts-inv = <1>; - }; -}; - -/ { - sound { - compatible = "simple-audio-card"; - simple-audio-card,name = "iMac integrated audio"; - #address-cells = <1>; - #size-cells = <0>; - - simple-audio-card,dai-link@0 { - bitclock-inversion; - frame-inversion; - reg = <0>; - format = "i2s"; - mclk-fs = <64>; - tdm-slot-width = <32>; - - link0_cpu: cpu { - sound-dai = <&mca 2>; - bitclock-master; - frame-master; - }; - - link0_codec: codec { - sound-dai = <&jack_codec>; - }; - }; - }; -}; diff --git a/arch/arm/dts/t8103-jxxx.dtsi b/arch/arm/dts/t8103-jxxx.dtsi deleted file mode 100644 index b4bd8c4238a..00000000000 --- a/arch/arm/dts/t8103-jxxx.dtsi +++ /dev/null @@ -1,143 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ OR MIT -/* - * Apple M1 Mac mini, MacBook Air/Pro, iMac 24" (M1, 2020/2021) - * - * This file contains parts common to all Apple M1 devices using the t8103. - * - * target-type: J274, J293, J313, J456, J457 - * - * Copyright The Asahi Linux Contributors - */ - -#include - -/ { - aliases { - serial0 = &serial0; - serial2 = &serial2; - wifi0 = &wifi0; - }; - - chosen { - #address-cells = <2>; - #size-cells = <2>; - ranges; - - stdout-path = "serial0"; - - framebuffer0: framebuffer@0 { - compatible = "apple,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 = <0x8 0 0x2 0>; /* To be filled by loader */ - }; -}; - -&serial0 { - status = "okay"; -}; - -&serial2 { - status = "okay"; -}; - -&i2c0 { - hpm0: usb-pd@38 { - compatible = "apple,cd321x"; - reg = <0x38>; - interrupt-parent = <&pinctrl_ap>; - interrupts = <106 IRQ_TYPE_LEVEL_LOW>; - interrupt-names = "irq"; - - typec0: connector { - compatible = "usb-c-connector"; - power-role = "dual"; - data-role = "dual"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { - reg = <0>; - typec0_con_hs: endpoint { - remote-endpoint = <&typec0_usb_hs>; - }; - }; - }; - }; - }; - - hpm1: usb-pd@3f { - compatible = "apple,cd321x"; - reg = <0x3f>; - interrupt-parent = <&pinctrl_ap>; - interrupts = <106 IRQ_TYPE_LEVEL_LOW>; - interrupt-names = "irq"; - - typec1: connector { - compatible = "usb-c-connector"; - power-role = "dual"; - data-role = "dual"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { - reg = <0>; - typec1_con_hs: endpoint { - remote-endpoint = <&typec1_usb_hs>; - }; - }; - }; - }; - }; -}; - -/* USB controllers */ -&dwc3_0 { - port { - typec0_usb_hs: endpoint { - remote-endpoint = <&typec0_con_hs>; - }; - }; -}; - -&dwc3_1 { - port { - typec1_usb_hs: endpoint { - remote-endpoint = <&typec1_con_hs>; - }; - }; -}; - -/* - * Force the bus number assignments so that we can declare some of the - * on-board devices and properties that are populated by the bootloader - * (such as MAC addresses). - */ -&port00 { - bus-range = <1 1>; - pwren-gpios = <&smc 13 0>; - wifi0: network@0,0 { - compatible = "pci14e4,4425"; - reg = <0x10000 0x0 0x0 0x0 0x0>; - /* To be filled by the loader */ - local-mac-address = [00 00 00 00 00 00]; - apple,antenna-sku = "XX"; - }; -}; - -&spmi { - status = "okay"; - - pmu@f { - compatible = "apple,sera-pmu"; - reg = <0xf SPMI_USID>; - }; -}; diff --git a/arch/arm/dts/t8103-pmgr.dtsi b/arch/arm/dts/t8103-pmgr.dtsi deleted file mode 100644 index 82ea4aa322e..00000000000 --- a/arch/arm/dts/t8103-pmgr.dtsi +++ /dev/null @@ -1,1138 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ OR MIT -/* - * PMGR Power domains for the Apple T8103 "M1" SoC - * - * Copyright The Asahi Linux Contributors - */ - - -&pmgr { - ps_sbr: power-controller@100 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x100 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "sbr"; - apple,always-on; /* Core device */ - }; - - ps_aic: power-controller@108 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x108 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "aic"; - apple,always-on; /* Core device */ - }; - - ps_dwi: power-controller@110 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x110 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "dwi"; - apple,always-on; /* Core device */ - }; - - ps_soc_spmi0: power-controller@118 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x118 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "soc_spmi0"; - }; - - ps_soc_spmi1: power-controller@120 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x120 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "soc_spmi1"; - }; - - ps_soc_spmi2: power-controller@128 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x128 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "soc_spmi2"; - }; - - ps_gpio: power-controller@130 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x130 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "gpio"; - }; - - ps_pms_busif: power-controller@138 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x138 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "pms_busif"; - apple,always-on; /* Core device */ - }; - - ps_pms: power-controller@140 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x140 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "pms"; - apple,always-on; /* Core device */ - }; - - ps_pms_fpwm0: power-controller@148 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x148 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "pms_fpwm0"; - power-domains = <&ps_pms>; - }; - - ps_pms_fpwm1: power-controller@150 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x150 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "pms_fpwm1"; - power-domains = <&ps_pms>; - }; - - ps_pms_fpwm2: power-controller@158 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x158 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "pms_fpwm2"; - power-domains = <&ps_pms>; - }; - - ps_pms_fpwm3: power-controller@160 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x160 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "pms_fpwm3"; - power-domains = <&ps_pms>; - }; - - ps_pms_fpwm4: power-controller@168 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x168 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "pms_fpwm4"; - power-domains = <&ps_pms>; - }; - - ps_soc_dpe: power-controller@170 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x170 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "soc_dpe"; - apple,always-on; /* Core device */ - }; - - ps_pmgr_soc_ocla: power-controller@178 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x178 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "pmgr_soc_ocla"; - }; - - ps_ispsens0: power-controller@180 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x180 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "ispsens0"; - }; - - ps_ispsens1: power-controller@188 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x188 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "ispsens1"; - }; - - ps_ispsens2: power-controller@190 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x190 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "ispsens2"; - }; - - ps_ispsens3: power-controller@198 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x198 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "ispsens3"; - }; - - ps_pcie_ref: power-controller@1a0 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x1a0 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "pcie_ref"; - }; - - ps_aft0: power-controller@1a8 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x1a8 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "aft0"; - }; - - ps_devc0_ivdmc: power-controller@1b0 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x1b0 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "devc0_ivdmc"; - }; - - ps_imx: power-controller@1b8 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x1b8 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "imx"; - apple,always-on; /* Apple fabric, critical block */ - }; - - ps_sio_busif: power-controller@1c0 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x1c0 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "sio_busif"; - }; - - ps_sio: power-controller@1c8 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x1c8 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "sio"; - power-domains = <&ps_sio_busif>; - }; - - ps_sio_cpu: power-controller@1d0 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x1d0 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "sio_cpu"; - power-domains = <&ps_sio>; - }; - - ps_fpwm0: power-controller@1d8 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x1d8 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "fpwm0"; - }; - - ps_fpwm1: power-controller@1e0 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x1e0 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "fpwm1"; - }; - - ps_fpwm2: power-controller@1e8 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x1e8 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "fpwm2"; - }; - - ps_i2c0: power-controller@1f0 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x1f0 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "i2c0"; - power-domains = <&ps_sio>; - }; - - ps_i2c1: power-controller@1f8 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x1f8 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "i2c1"; - power-domains = <&ps_sio>; - }; - - ps_i2c2: power-controller@200 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x200 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "i2c2"; - power-domains = <&ps_sio>; - }; - - ps_i2c3: power-controller@208 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x208 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "i2c3"; - power-domains = <&ps_sio>; - }; - - ps_i2c4: power-controller@210 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x210 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "i2c4"; - power-domains = <&ps_sio>; - }; - - ps_spi_p: power-controller@218 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x218 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "spi_p"; - power-domains = <&ps_sio>; - }; - - ps_uart_p: power-controller@220 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x220 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "uart_p"; - power-domains = <&ps_sio>; - }; - - ps_audio_p: power-controller@228 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x228 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "audio_p"; - power-domains = <&ps_sio>; - }; - - ps_sio_adma: power-controller@230 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x230 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "sio_adma"; - power-domains = <&ps_sio>, <&ps_pms>; - }; - - ps_aes: power-controller@238 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x238 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "aes"; - power-domains = <&ps_sio>; - }; - - ps_spi0: power-controller@240 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x240 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "spi0"; - power-domains = <&ps_sio>, <&ps_spi_p>; - }; - - ps_spi1: power-controller@248 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x248 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "spi1"; - power-domains = <&ps_sio>, <&ps_spi_p>; - }; - - ps_spi2: power-controller@250 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x250 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "spi2"; - power-domains = <&ps_sio>, <&ps_spi_p>; - }; - - ps_spi3: power-controller@258 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x258 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "spi3"; - power-domains = <&ps_sio>, <&ps_spi_p>; - }; - - ps_uart_n: power-controller@268 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x268 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "uart_n"; - power-domains = <&ps_uart_p>; - }; - - ps_uart0: power-controller@270 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x270 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "uart0"; - power-domains = <&ps_uart_p>; - }; - - ps_uart1: power-controller@278 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x278 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "uart1"; - power-domains = <&ps_uart_p>; - }; - - ps_uart2: power-controller@280 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x280 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "uart2"; - power-domains = <&ps_uart_p>; - }; - - ps_uart3: power-controller@288 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x288 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "uart3"; - power-domains = <&ps_uart_p>; - }; - - ps_uart4: power-controller@290 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x290 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "uart4"; - power-domains = <&ps_uart_p>; - }; - - ps_uart5: power-controller@298 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x298 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "uart5"; - power-domains = <&ps_uart_p>; - }; - - ps_uart6: power-controller@2a0 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x2a0 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "uart6"; - power-domains = <&ps_uart_p>; - }; - - ps_uart7: power-controller@2a8 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x2a8 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "uart7"; - power-domains = <&ps_uart_p>; - }; - - ps_uart8: power-controller@2b0 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x2b0 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "uart8"; - power-domains = <&ps_uart_p>; - }; - - ps_mca0: power-controller@2b8 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x2b8 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "mca0"; - power-domains = <&ps_audio_p>, <&ps_sio_adma>, <&ps_mca1>, <&ps_mca2>, <&ps_mca3>, <&ps_mca4>, <&ps_mca5>; - }; - - ps_mca1: power-controller@2c0 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x2c0 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "mca1"; - power-domains = <&ps_audio_p>, <&ps_sio_adma>; - }; - - ps_mca2: power-controller@2c8 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x2c8 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "mca2"; - power-domains = <&ps_audio_p>, <&ps_sio_adma>; - }; - - ps_mca3: power-controller@2d0 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x2d0 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "mca3"; - power-domains = <&ps_audio_p>, <&ps_sio_adma>; - }; - - ps_mca4: power-controller@2d8 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x2d8 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "mca4"; - power-domains = <&ps_audio_p>, <&ps_sio_adma>; - }; - - ps_mca5: power-controller@2e0 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x2e0 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "mca5"; - power-domains = <&ps_audio_p>, <&ps_sio_adma>; - }; - - ps_dpa0: power-controller@2e8 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x2e8 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "dpa0"; - power-domains = <&ps_audio_p>; - }; - - ps_dpa1: power-controller@2f0 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x2f0 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "dpa1"; - power-domains = <&ps_audio_p>; - }; - - ps_mcc: power-controller@2f8 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x2f8 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "mcc"; - apple,always-on; /* Memory controller */ - }; - - ps_spi4: power-controller@260 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x260 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "spi4"; - power-domains = <&ps_sio>, <&ps_spi_p>; - }; - - ps_dcs0: power-controller@300 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x300 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "dcs0"; - apple,always-on; /* LPDDR4 interface */ - }; - - ps_dcs1: power-controller@310 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x310 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "dcs1"; - apple,always-on; /* LPDDR4 interface */ - }; - - ps_dcs2: power-controller@308 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x308 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "dcs2"; - apple,always-on; /* LPDDR4 interface */ - }; - - ps_dcs3: power-controller@318 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x318 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "dcs3"; - apple,always-on; /* LPDDR4 interface */ - }; - - ps_smx: power-controller@340 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x340 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "smx"; - apple,always-on; /* Apple fabric, critical block */ - }; - - ps_apcie: power-controller@348 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x348 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "apcie"; - power-domains = <&ps_imx>, <&ps_pcie_ref>; - }; - - ps_rmx: power-controller@350 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x350 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "rmx"; - /* Apple Fabric, display/image stuff: this can power down */ - }; - - ps_mmx: power-controller@358 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x358 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "mmx"; - /* Apple Fabric, media stuff: this can power down */ - }; - - ps_disp0_fe: power-controller@360 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x360 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "disp0_fe"; - power-domains = <&ps_rmx>; - apple,always-on; /* TODO: figure out if we can enable PM here */ - }; - - ps_dispext_fe: power-controller@368 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x368 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "dispext_fe"; - power-domains = <&ps_rmx>; - }; - - ps_dispext_cpu0: power-controller@378 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x378 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "dispext_cpu0"; - power-domains = <&ps_dispext_fe>; - apple,min-state = <4>; - }; - - ps_jpg: power-controller@3c0 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x3c0 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "jpg"; - power-domains = <&ps_mmx>; - }; - - ps_msr: power-controller@3c8 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x3c8 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "msr"; - power-domains = <&ps_mmx>; - }; - - ps_msr_ase_core: power-controller@3d0 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x3d0 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "msr_ase_core"; - }; - - ps_pmp: power-controller@3d8 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x3d8 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "pmp"; - }; - - ps_pms_sram: power-controller@3e0 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x3e0 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "pms_sram"; - }; - - ps_apcie_gp: power-controller@3e8 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x3e8 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "apcie_gp"; - power-domains = <&ps_apcie>; - }; - - ps_ans2: power-controller@3f0 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x3f0 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "ans2"; - /* - * The ADT makes ps_apcie_st depend on ps_ans2 instead, but this - * doesn't make much sense since ANS2 uses APCIE_ST. - */ - power-domains = <&ps_apcie_st>; - }; - - ps_gfx: power-controller@3f8 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x3f8 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "gfx"; - }; - - ps_dcs4: power-controller@320 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x320 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "dcs4"; - apple,always-on; /* LPDDR4 interface */ - }; - - ps_dcs5: power-controller@330 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x330 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "dcs5"; - apple,always-on; /* LPDDR4 interface */ - }; - - ps_dcs6: power-controller@328 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x328 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "dcs6"; - apple,always-on; /* LPDDR4 interface */ - }; - - ps_dcs7: power-controller@338 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x338 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "dcs7"; - apple,always-on; /* LPDDR4 interface */ - }; - - ps_dispdfr_fe: power-controller@3a8 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x3a8 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "dispdfr_fe"; - power-domains = <&ps_rmx>; - }; - - ps_dispdfr_be: power-controller@3b0 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x3b0 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "dispdfr_be"; - power-domains = <&ps_dispdfr_fe>; - }; - - ps_mipi_dsi: power-controller@3b8 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x3b8 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "mipi_dsi"; - power-domains = <&ps_dispdfr_be>; - }; - - ps_isp_sys: power-controller@400 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x400 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "isp_sys"; - power-domains = <&ps_rmx>; - }; - - ps_venc_sys: power-controller@408 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x408 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "venc_sys"; - power-domains = <&ps_mmx>; - }; - - ps_avd_sys: power-controller@410 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x410 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "avd_sys"; - power-domains = <&ps_mmx>; - }; - - ps_apcie_st: power-controller@418 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x418 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "apcie_st"; - power-domains = <&ps_apcie>; - }; - - ps_ane_sys: power-controller@470 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x470 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "ane_sys"; - }; - - ps_atc0_common: power-controller@420 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x420 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "atc0_common"; - }; - - ps_atc0_pcie: power-controller@428 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x428 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "atc0_pcie"; - power-domains = <&ps_atc0_common>; - }; - - ps_atc0_cio: power-controller@430 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x430 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "atc0_cio"; - power-domains = <&ps_atc0_common>; - }; - - ps_atc0_cio_pcie: power-controller@438 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x438 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "atc0_cio_pcie"; - power-domains = <&ps_atc0_cio>; - }; - - ps_atc0_cio_usb: power-controller@440 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x440 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "atc0_cio_usb"; - power-domains = <&ps_atc0_cio>; - }; - - ps_atc1_common: power-controller@448 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x448 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "atc1_common"; - }; - - ps_atc1_pcie: power-controller@450 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x450 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "atc1_pcie"; - power-domains = <&ps_atc1_common>; - }; - - ps_atc1_cio: power-controller@458 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x458 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "atc1_cio"; - power-domains = <&ps_atc1_common>; - }; - - ps_atc1_cio_pcie: power-controller@460 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x460 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "atc1_cio_pcie"; - power-domains = <&ps_atc1_cio>; - }; - - ps_atc1_cio_usb: power-controller@468 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x468 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "atc1_cio_usb"; - power-domains = <&ps_atc1_cio>; - }; - - ps_sep: power-controller@c00 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0xc00 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "sep"; - apple,always-on; /* Locked on */ - }; - - ps_venc_dma: power-controller@8000 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x8000 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "venc_dma"; - power-domains = <&ps_venc_sys>; - }; - - ps_venc_pipe4: power-controller@8008 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x8008 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "venc_pipe4"; - power-domains = <&ps_venc_dma>; - }; - - ps_venc_pipe5: power-controller@8010 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x8010 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "venc_pipe5"; - power-domains = <&ps_venc_dma>; - }; - - ps_venc_me0: power-controller@8018 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x8018 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "venc_me0"; - power-domains = <&ps_venc_pipe4>, <&ps_venc_pipe5>; - }; - - ps_venc_me1: power-controller@8020 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x8020 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "venc_me1"; - power-domains = <&ps_venc_pipe4>, <&ps_venc_pipe5>; - }; - - ps_ane_sys_cpu: power-controller@c000 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0xc000 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "ane_sys_cpu"; - power-domains = <&ps_ane_sys>; - }; - - ps_disp0_cpu0: power-controller@10018 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x10018 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "disp0_cpu0"; - power-domains = <&ps_disp0_fe>; - apple,always-on; /* TODO: figure out if we can enable PM here */ - apple,min-state = <4>; - }; -}; - -&pmgr_mini { - ps_debug: power-controller@58 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x58 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "debug"; - apple,always-on; /* Core AON device */ - }; - - ps_nub_spmi0: power-controller@60 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x60 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "nub_spmi0"; - apple,always-on; /* Core AON device */ - }; - - ps_nub_aon: power-controller@70 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x70 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "nub_aon"; - apple,always-on; /* Core AON device */ - }; - - ps_nub_gpio: power-controller@80 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x80 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "nub_gpio"; - apple,always-on; /* Core AON device */ - }; - - ps_nub_fabric: power-controller@a8 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0xa8 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "nub_fabric"; - apple,always-on; /* Core AON device */ - }; - - ps_nub_sram: power-controller@b0 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0xb0 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "nub_sram"; - apple,always-on; /* Core AON device */ - }; - - ps_debug_usb: power-controller@b8 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0xb8 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "debug_usb"; - apple,always-on; /* Core AON device */ - power-domains = <&ps_debug>; - }; - - ps_debug_auth: power-controller@c0 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0xc0 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "debug_auth"; - apple,always-on; /* Core AON device */ - power-domains = <&ps_debug>; - }; - - ps_nub_spmi1: power-controller@68 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x68 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "nub_spmi1"; - apple,always-on; /* Core AON device */ - }; - - ps_msg: power-controller@78 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x78 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "msg"; - }; - - ps_atc0_usb_aon: power-controller@88 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x88 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "atc0_usb_aon"; - }; - - ps_atc1_usb_aon: power-controller@90 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x90 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "atc1_usb_aon"; - }; - - ps_atc0_usb: power-controller@98 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0x98 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "atc0_usb"; - power-domains = <&ps_atc0_usb_aon>, <&ps_atc0_common>; - }; - - ps_atc1_usb: power-controller@a0 { - compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; - reg = <0xa0 4>; - #power-domain-cells = <0>; - #reset-cells = <0>; - label = "atc1_usb"; - power-domains = <&ps_atc1_usb_aon>, <&ps_atc1_common>; - }; -}; diff --git a/arch/arm/dts/t8103-u-boot.dtsi b/arch/arm/dts/t8103-u-boot.dtsi deleted file mode 100644 index e9e593a00cf..00000000000 --- a/arch/arm/dts/t8103-u-boot.dtsi +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ OR MIT - -&serial0 { - bootph-all; -}; - -&pmgr { - bootph-all; -}; - -&ps_sio_busif { - bootph-all; -}; - -&ps_sio { - bootph-all; -}; - -&ps_uart_p { - bootph-all; -}; - -&ps_uart0 { - bootph-all; -}; diff --git a/arch/arm/dts/t8103.dtsi b/arch/arm/dts/t8103.dtsi deleted file mode 100644 index ed7840f94b6..00000000000 --- a/arch/arm/dts/t8103.dtsi +++ /dev/null @@ -1,696 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ OR MIT -/* - * Apple T8103 "M1" SoC - * - * Other names: H13G, "Tonga" - * - * Copyright The Asahi Linux Contributors - */ - -#include -#include -#include -#include - -/ { - compatible = "apple,t8103", "apple,arm-platform"; - - #address-cells = <2>; - #size-cells = <2>; - - cpus { - #address-cells = <2>; - #size-cells = <0>; - - cpu0: cpu@0 { - compatible = "apple,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 = "apple,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 = "apple,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 = "apple,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 = "apple,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 = "apple,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 = "apple,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 = "apple,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>; - interrupt-names = "phys", "virt", "hyp-phys", "hyp-virt"; - interrupts = , - , - , - ; - }; - - clkref: clock-ref { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <24000000>; - clock-output-names = "clkref"; - }; - - clk_120m: clock-120m { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <120000000>; - clock-output-names = "clk_120m"; - }; - - soc { - compatible = "simple-bus"; - #address-cells = <2>; - #size-cells = <2>; - - ranges; - nonposted-mmio; - - i2c0: i2c@235010000 { - compatible = "apple,t8103-i2c", "apple,i2c"; - reg = <0x2 0x35010000 0x0 0x4000>; - clocks = <&clkref>; - interrupt-parent = <&aic>; - interrupts = ; - pinctrl-0 = <&i2c0_pins>; - pinctrl-names = "default"; - #address-cells = <0x1>; - #size-cells = <0x0>; - power-domains = <&ps_i2c0>; - }; - - i2c1: i2c@235014000 { - compatible = "apple,t8103-i2c", "apple,i2c"; - reg = <0x2 0x35014000 0x0 0x4000>; - clocks = <&clkref>; - interrupt-parent = <&aic>; - interrupts = ; - pinctrl-0 = <&i2c1_pins>; - pinctrl-names = "default"; - #address-cells = <0x1>; - #size-cells = <0x0>; - power-domains = <&ps_i2c1>; - }; - - i2c2: i2c@235018000 { - compatible = "apple,t8103-i2c", "apple,i2c"; - reg = <0x2 0x35018000 0x0 0x4000>; - clocks = <&clkref>; - interrupt-parent = <&aic>; - interrupts = ; - pinctrl-0 = <&i2c2_pins>; - pinctrl-names = "default"; - #address-cells = <0x1>; - #size-cells = <0x0>; - power-domains = <&ps_i2c2>; - status = "disabled"; /* not used in all devices */ - }; - - i2c3: i2c@23501c000 { - compatible = "apple,t8103-i2c", "apple,i2c"; - reg = <0x2 0x3501c000 0x0 0x4000>; - clocks = <&clkref>; - interrupt-parent = <&aic>; - interrupts = ; - pinctrl-0 = <&i2c3_pins>; - pinctrl-names = "default"; - #address-cells = <0x1>; - #size-cells = <0x0>; - power-domains = <&ps_i2c3>; - }; - - i2c4: i2c@235020000 { - compatible = "apple,t8103-i2c", "apple,i2c"; - reg = <0x2 0x35020000 0x0 0x4000>; - clocks = <&clkref>; - interrupt-parent = <&aic>; - interrupts = ; - pinctrl-0 = <&i2c4_pins>; - pinctrl-names = "default"; - #address-cells = <0x1>; - #size-cells = <0x0>; - power-domains = <&ps_i2c4>; - status = "disabled"; /* only used in J293 */ - }; - - spi3: spi@23510c000 { - compatible = "apple,t8103-spi", "apple,spi"; - reg = <0x2 0x3510c000 0x0 0x4000>; - interrupt-parent = <&aic>; - interrupts = ; - clocks = <&clk_120m>; - pinctrl-0 = <&spi3_pins>; - pinctrl-names = "default"; - power-domains = <&ps_spi3>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; /* only used in J293/J313 */ - }; - - serial0: serial@235200000 { - compatible = "apple,s5l-uart"; - reg = <0x2 0x35200000 0x0 0x1000>; - reg-io-width = <4>; - interrupt-parent = <&aic>; - interrupts = ; - /* - * TODO: figure out the clocking properly, there may - * be a third selectable clock. - */ - clocks = <&clkref>, <&clkref>; - clock-names = "uart", "clk_uart_baud0"; - power-domains = <&ps_uart0>; - status = "disabled"; - }; - - serial2: serial@235208000 { - compatible = "apple,s5l-uart"; - reg = <0x2 0x35208000 0x0 0x1000>; - reg-io-width = <4>; - interrupt-parent = <&aic>; - interrupts = ; - clocks = <&clkref>, <&clkref>; - clock-names = "uart", "clk_uart_baud0"; - power-domains = <&ps_uart2>; - status = "disabled"; - }; - - aic: interrupt-controller@23b100000 { - compatible = "apple,t8103-aic", "apple,aic"; - #interrupt-cells = <3>; - interrupt-controller; - reg = <0x2 0x3b100000 0x0 0x8000>; - power-domains = <&ps_aic>; - }; - - pmgr: power-management@23b700000 { - compatible = "apple,t8103-pmgr", "apple,pmgr", "syscon", "simple-mfd"; - #address-cells = <1>; - #size-cells = <1>; - reg = <0x2 0x3b700000 0 0x14000>; - }; - - pinctrl_ap: pinctrl@23c100000 { - compatible = "apple,t8103-pinctrl", "apple,pinctrl"; - reg = <0x2 0x3c100000 0x0 0x100000>; - power-domains = <&ps_gpio>; - - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pinctrl_ap 0 0 212>; - apple,npins = <212>; - - interrupt-controller; - #interrupt-cells = <2>; - interrupt-parent = <&aic>; - interrupts = , - , - , - , - , - , - ; - - i2c0_pins: i2c0-pins { - pinmux = , - ; - }; - - i2c1_pins: i2c1-pins { - pinmux = , - ; - }; - - i2c2_pins: i2c2-pins { - pinmux = , - ; - }; - - i2c3_pins: i2c3-pins { - pinmux = , - ; - }; - - i2c4_pins: i2c4-pins { - pinmux = , - ; - }; - - spi3_pins: spi3-pins { - pinmux = , - , - , - ; - }; - - pcie_pins: pcie-pins { - pinmux = , - , - ; - }; - }; - - spmi: spmi@23d0d9300 { - compatible = "apple,t8103-spmi", "apple,spmi"; - reg = <0x2 0x3d0d9300 0x0 0x100>; - interrupt-parent = <&aic>; - interrupts = ; - #address-cells = <2>; - #size-cells = <0>; - status = "disabled"; - }; - - pinctrl_nub: pinctrl@23d1f0000 { - compatible = "apple,t8103-pinctrl", "apple,pinctrl"; - reg = <0x2 0x3d1f0000 0x0 0x4000>; - power-domains = <&ps_nub_gpio>; - - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pinctrl_nub 0 0 23>; - apple,npins = <23>; - - interrupt-controller; - #interrupt-cells = <2>; - interrupt-parent = <&aic>; - interrupts = , - , - , - , - , - , - ; - }; - - pmgr_mini: power-management@23d280000 { - compatible = "apple,t8103-pmgr", "apple,pmgr", "syscon", "simple-mfd"; - #address-cells = <1>; - #size-cells = <1>; - reg = <0x2 0x3d280000 0 0x4000>; - }; - - wdt: watchdog@23d2b0000 { - compatible = "apple,t8103-wdt", "apple,wdt"; - reg = <0x2 0x3d2b0000 0x0 0x4000>; - clocks = <&clkref>; - interrupt-parent = <&aic>; - interrupts = ; - }; - - pinctrl_smc: pinctrl@23e820000 { - compatible = "apple,t8103-pinctrl", "apple,pinctrl"; - reg = <0x2 0x3e820000 0x0 0x4000>; - - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pinctrl_smc 0 0 16>; - apple,npins = <16>; - - interrupt-controller; - #interrupt-cells = <2>; - interrupt-parent = <&aic>; - interrupts = , - , - , - , - , - , - ; - }; - - smc_mbox: mbox@23e408000 { - compatible = "apple,t8103-asc-mailbox", "apple,asc-mailbox-v4"; - reg = <0x2 0x3e408000 0x0 0x4000>; - interrupt-parent = <&aic>; - interrupts = , - , - , - ; - interrupt-names = "send-empty", "send-not-empty", - "recv-empty", "recv-not-empty"; - #mbox-cells = <0>; - }; - - smc: smc@23e050000 { - compatible = "apple,smc"; - reg = <0x2 0x3e050000 0x0 0x4000>; - mboxes = <&smc_mbox>; - gpio-controller; - #gpio-cells = <2>; - gpio-13 = <0x00800000>; - }; - - pinctrl_aop: pinctrl@24a820000 { - compatible = "apple,t8103-pinctrl", "apple,pinctrl"; - reg = <0x2 0x4a820000 0x0 0x4000>; - - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pinctrl_aop 0 0 42>; - apple,npins = <42>; - - interrupt-controller; - #interrupt-cells = <2>; - interrupt-parent = <&aic>; - interrupts = , - , - , - , - , - , - ; - }; - - ans_mbox: mbox@277408000 { - compatible = "apple,t8103-asc-mailbox", "apple,asc-mailbox-v4"; - reg = <0x2 0x77408000 0x0 0x4000>; - interrupt-parent = <&aic>; - interrupts = , - , - , - ; - interrupt-names = "send-empty", "send-not-empty", - "recv-empty", "recv-not-empty"; - #mbox-cells = <0>; - power-domains = <&ps_ans2>; - }; - - sart: sart@27bc50000 { - compatible = "apple,t8103-sart", "apple,sart2"; - reg = <0x2 0x7bc50000 0x0 0x10000>; - power-domains = <&ps_ans2>; - }; - - nvme@27bcc0000 { - compatible = "apple,t8103-nvme-ans2", "apple,nvme-ans2"; - reg = <0x2 0x7bcc0000 0x0 0x40000>, - <0x2 0x77400000 0x0 0x4000>; - reg-names = "nvme", "ans"; - interrupt-parent = <&aic>; - interrupts = ; - mboxes = <&ans_mbox>; - apple,sart = <&sart>; - power-domains = <&ps_ans2>; - resets = <&ps_ans2>; - }; - - dwc3_0: usb@382280000 { - compatible = "apple,t8103-dwc3", "apple,dwc3", "snps,dwc3"; - reg = <0x3 0x82280000 0x0 0x100000>; - interrupt-parent = <&aic>; - interrupts = ; - usb-role-switch; - role-switch-default-mode = "host"; - iommus = <&dwc3_0_dart_0 0>, <&dwc3_0_dart_1 1>; - power-domains = <&ps_atc0_usb>; - }; - - dwc3_0_dart_0: iommu@382f00000 { - compatible = "apple,t8103-dart"; - reg = <0x3 0x82f00000 0x0 0x4000>; - interrupt-parent = <&aic>; - interrupts = ; - #iommu-cells = <1>; - power-domains = <&ps_atc0_usb>; - }; - - dwc3_0_dart_1: iommu@382f80000 { - compatible = "apple,t8103-dart"; - reg = <0x3 0x82f80000 0x0 0x4000>; - interrupt-parent = <&aic>; - interrupts = ; - #iommu-cells = <1>; - power-domains = <&ps_atc0_usb>; - }; - - dwc3_1: usb@502280000 { - compatible = "apple,t8103-dwc3", "apple,dwc3", "snps,dwc3"; - reg = <0x5 0x02280000 0x0 0x100000>; - interrupt-parent = <&aic>; - interrupts = ; - usb-role-switch; - role-switch-default-mode = "host"; - iommus = <&dwc3_1_dart_0 0>, <&dwc3_1_dart_1 1>; - power-domains = <&ps_atc1_usb>; - }; - - dwc3_1_dart_0: iommu@502f00000 { - compatible = "apple,t8103-dart"; - reg = <0x5 0x02f00000 0x0 0x4000>; - interrupt-parent = <&aic>; - interrupts = ; - #iommu-cells = <1>; - power-domains = <&ps_atc1_usb>; - }; - - dwc3_1_dart_1: iommu@502f80000 { - compatible = "apple,t8103-dart"; - reg = <0x5 0x02f80000 0x0 0x4000>; - interrupt-parent = <&aic>; - interrupts = ; - #iommu-cells = <1>; - power-domains = <&ps_atc1_usb>; - }; - - pcie0_dart_0: dart@681008000 { - compatible = "apple,t8103-dart"; - reg = <0x6 0x81008000 0x0 0x4000>; - #iommu-cells = <1>; - interrupt-parent = <&aic>; - interrupts = ; - power-domains = <&ps_apcie_gp>; - }; - - pcie0_dart_1: dart@682008000 { - compatible = "apple,t8103-dart"; - reg = <0x6 0x82008000 0x0 0x4000>; - #iommu-cells = <1>; - interrupt-parent = <&aic>; - interrupts = ; - power-domains = <&ps_apcie_gp>; - }; - - pcie0_dart_2: dart@683008000 { - compatible = "apple,t8103-dart"; - reg = <0x6 0x83008000 0x0 0x4000>; - #iommu-cells = <1>; - interrupt-parent = <&aic>; - interrupts = ; - power-domains = <&ps_apcie_gp>; - }; - - pcie0: pcie@690000000 { - compatible = "apple,t8103-pcie", "apple,pcie"; - device_type = "pci"; - - reg = <0x6 0x90000000 0x0 0x1000000>, - <0x6 0x80000000 0x0 0x100000>, - <0x6 0x81000000 0x0 0x4000>, - <0x6 0x82000000 0x0 0x4000>, - <0x6 0x83000000 0x0 0x4000>; - reg-names = "config", "rc", "port0", "port1", "port2"; - - interrupt-parent = <&aic>; - interrupts = , - , - ; - - msi-controller; - msi-parent = <&pcie0>; - msi-ranges = <&aic AIC_IRQ 704 IRQ_TYPE_EDGE_RISING 32>; - - - iommu-map = <0x100 &pcie0_dart_0 1 1>, - <0x200 &pcie0_dart_1 1 1>, - <0x300 &pcie0_dart_2 1 1>; - iommu-map-mask = <0xff00>; - - bus-range = <0 3>; - #address-cells = <3>; - #size-cells = <2>; - ranges = <0x43000000 0x6 0xa0000000 0x6 0xa0000000 0x0 0x20000000>, - <0x02000000 0x0 0xc0000000 0x6 0xc0000000 0x0 0x40000000>; - - power-domains = <&ps_apcie_gp>; - pinctrl-0 = <&pcie_pins>; - pinctrl-names = "default"; - - port00: pci@0,0 { - device_type = "pci"; - reg = <0x0 0x0 0x0 0x0 0x0>; - reset-gpios = <&pinctrl_ap 152 GPIO_ACTIVE_LOW>; - - #address-cells = <3>; - #size-cells = <2>; - ranges; - - interrupt-controller; - #interrupt-cells = <1>; - - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &port00 0 0 0 0>, - <0 0 0 2 &port00 0 0 0 1>, - <0 0 0 3 &port00 0 0 0 2>, - <0 0 0 4 &port00 0 0 0 3>; - }; - - port01: pci@1,0 { - device_type = "pci"; - reg = <0x800 0x0 0x0 0x0 0x0>; - reset-gpios = <&pinctrl_ap 153 GPIO_ACTIVE_LOW>; - - #address-cells = <3>; - #size-cells = <2>; - ranges; - - interrupt-controller; - #interrupt-cells = <1>; - - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &port01 0 0 0 0>, - <0 0 0 2 &port01 0 0 0 1>, - <0 0 0 3 &port01 0 0 0 2>, - <0 0 0 4 &port01 0 0 0 3>; - }; - - port02: pci@2,0 { - device_type = "pci"; - reg = <0x1000 0x0 0x0 0x0 0x0>; - reset-gpios = <&pinctrl_ap 33 GPIO_ACTIVE_LOW>; - - #address-cells = <3>; - #size-cells = <2>; - ranges; - - interrupt-controller; - #interrupt-cells = <1>; - - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &port02 0 0 0 0>, - <0 0 0 2 &port02 0 0 0 1>, - <0 0 0 3 &port02 0 0 0 2>, - <0 0 0 4 &port02 0 0 0 3>; - }; - }; - - dart_sio: iommu@235004000 { - compatible = "apple,t8103-dart", "apple,dart"; - reg = <0x2 0x35004000 0x0 0x4000>; - interrupt-parent = <&aic>; - interrupts = ; - #iommu-cells = <1>; - power-domains = <&ps_sio_cpu>; - }; - - nco_inp: clock-ref { - compatible = "fixed-factor-clock"; - clocks = <&clkref>; - #clock-cells = <0>; - clock-mult = <75>; - clock-div = <2>; // 24 MHz * (75/2) = 900 MHz - clock-output-names = "nco_inp"; - }; - - nco: nco@23b044000 { - compatible = "apple,t8103-nco", "apple,nco"; - reg = <0x2 0x3b044000 0x0 0x14000>; - clocks = <&nco_inp>; - #clock-cells = <1>; - apple,nchannels = <5>; - }; - - admac: dma-controller@238200000 { - compatible = "apple,t8103-admac", "apple,admac"; - reg = <0x2 0x38200000 0x0 0x34000>; - dma-channels = <12>; - interrupt-parent = <&aic>; - interrupts = ; - #dma-cells = <1>; - iommus = <&dart_sio 2>; - power-domains = <&ps_sio_adma>; - }; - - mca: mca { - compatible = "apple,t8103-mca", "apple,mca"; - reg = <0x2 0x38400000 0x0 0x18000>, - <0x2 0x38300000 0x0 0x30000>; - reg-names = "clusters", "switch"; - clocks = <&nco 0>, <&nco 1>, <&nco 2>, <&nco 3>; - power-domains = <&ps_mca0>; //, <&ps_mca1>, <&ps_mca2>, <&ps_mca3>, <&ps_mca4>, <&ps_mca5>; - resets = <&ps_mca0>, <&ps_mca1>, <&ps_mca2>, <&ps_mca3>, <&ps_mca4>, <&ps_mca5>; - - #sound-dai-cells = <1>; - apple,nclusters = <6>; - apple,mclk-range = <2600000 25000000>; - - route { - dmas = <&admac 2>; - dma-names = "tx"; - apple,serdes = <1>; - sound-dai = <&mca 0>; - }; - - route2 { - dmas = <&admac 6>; - dma-names = "tx"; - apple,serdes = <3>; - sound-dai = <&mca 2>; - }; - }; - }; -}; - -#include "t8103-pmgr.dtsi" diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig index 1ce69f2882a..d0cfd5f5591 100644 --- a/configs/apple_m1_defconfig +++ b/configs/apple_m1_defconfig @@ -1,6 +1,6 @@ CONFIG_ARM=y CONFIG_ARCH_APPLE=y -CONFIG_DEFAULT_DEVICE_TREE="t8103-j274" +CONFIG_DEFAULT_DEVICE_TREE="apple/t8103-j274" CONFIG_SYS_BOOTM_LEN=0x800000 CONFIG_SYS_LOAD_ADDR=0x0 CONFIG_BOOTCOMMAND="bootflow scan -b" diff --git a/doc/board/apple/m1.rst b/doc/board/apple/m1.rst index 5d2cf750fde..900c5e6d91e 100644 --- a/doc/board/apple/m1.rst +++ b/doc/board/apple/m1.rst @@ -24,9 +24,8 @@ On these SoCs the following hardware is supported: - NVMe storage - USB 3.1 Type-C ports -Device trees are currently provided for the M1 Mac mini (2020, J274), -M1 MacBook Pro 13" (2020, J293), M1 MacBook Air (2020, J313) and M1 -iMac (2021, J456/J457). +Device trees are provided in dts/upstream/src/arm64/apple/ and available +for all M1 and M2 (t8103, t8112, t600x and t602x) devices. Building U-Boot --------------- From c183a8e502834d95831ae5b629b5eac4e7b65ccb Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 30 Apr 2026 23:39:17 +0200 Subject: [PATCH 09/41] MAINTAINERS: Add missing Apple M1 specific files The files weren't added to MAINTAINERS but clearly belong to Apple silicon (M1) support. Signed-off-by: Janne Grunau --- MAINTAINERS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index d4b527560aa..2fc41a79dac 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -132,11 +132,16 @@ S: Maintained F: arch/arm/include/asm/arch-apple/ F: arch/arm/mach-apple/ F: configs/apple_m1_defconfig +F: doc/board/apple/ +F: drivers/input/apple_spi_kbd.c F: drivers/iommu/apple_dart.c +F: drivers/mailbox/apple-mbox.c F: drivers/nvme/nvme_apple.c F: drivers/pci/pcie_apple.c F: drivers/phy/phy-apple-atc.c F: drivers/pinctrl/pinctrl-apple.c +F: drivers/power/domain/apple-pmgr.c +F: drivers/spi/apple_spi.c F: drivers/watchdog/apple_wdt.c F: include/configs/apple.h From dea067f48029c437334de42aebe080540432eb09 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 30 Apr 2026 19:55:11 +0200 Subject: [PATCH 10/41] arm: apple: Switch to board based text env The main use case for u-boot on Apple silicon based devices is to provide an EFI based bootloader for operating systems. This uses a generic u-boot image with DTBs passed from an earlier boot loader (m1n1). Use the generic board name "mac" for this purpose. Signed-off-by: Janne Grunau --- MAINTAINERS | 1 + arch/arm/mach-apple/Kconfig | 14 ++++++++++++-- arch/arm/mach-apple/rtkit_helper.c | 1 + board/apple/mac/mac.env | 4 ++++ configs/apple_m1_defconfig | 2 ++ drivers/iommu/apple_dart.c | 1 + drivers/nvme/nvme_apple.c | 1 + include/configs/apple.h | 18 ------------------ 8 files changed, 22 insertions(+), 20 deletions(-) create mode 100644 board/apple/mac/mac.env delete mode 100644 include/configs/apple.h diff --git a/MAINTAINERS b/MAINTAINERS index 2fc41a79dac..5ea3e4e55ec 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -131,6 +131,7 @@ M: Mark Kettenis S: Maintained F: arch/arm/include/asm/arch-apple/ F: arch/arm/mach-apple/ +F: board/apple/ F: configs/apple_m1_defconfig F: doc/board/apple/ F: drivers/input/apple_spi_kbd.c diff --git a/arch/arm/mach-apple/Kconfig b/arch/arm/mach-apple/Kconfig index 294690ec0e8..fdc8c32152f 100644 --- a/arch/arm/mach-apple/Kconfig +++ b/arch/arm/mach-apple/Kconfig @@ -3,12 +3,22 @@ if ARCH_APPLE config TEXT_BASE default 0x00000000 -config SYS_CONFIG_NAME +config SYS_SOC default "apple" -config SYS_SOC +config SYS_VENDOR default "apple" +config SYS_BOARD + string "Board name" + default "mac" + help + This option contains information about board name. + Based on this option board// will + be used. + Apple silicon based devices are expected to use the generic board name + "mac". + config SYS_MALLOC_LEN default 0x4000000 diff --git a/arch/arm/mach-apple/rtkit_helper.c b/arch/arm/mach-apple/rtkit_helper.c index b7d60e15700..cbdc204f141 100644 --- a/arch/arm/mach-apple/rtkit_helper.c +++ b/arch/arm/mach-apple/rtkit_helper.c @@ -11,6 +11,7 @@ #include #include #include +#include /* ASC registers */ #define REG_CPU_CTRL 0x0044 diff --git a/board/apple/mac/mac.env b/board/apple/mac/mac.env new file mode 100644 index 00000000000..109379c8c67 --- /dev/null +++ b/board/apple/mac/mac.env @@ -0,0 +1,4 @@ +stdin=serial,usbkbd,spikbd +stdout=vidconsole,serial +stderr=vidconsole,serial +boot_targets=nvme usb diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig index d0cfd5f5591..26d722265aa 100644 --- a/configs/apple_m1_defconfig +++ b/configs/apple_m1_defconfig @@ -29,3 +29,5 @@ CONFIG_SYS_WHITE_ON_BLACK=y CONFIG_NO_FB_CLEAR=y CONFIG_VIDEO_SIMPLE=y CONFIG_GENERATE_SMBIOS_TABLE_VERBOSE=y +CONFIG_SYS_VENDOR=apple +CONFIG_SYS_BOARD=mac diff --git a/drivers/iommu/apple_dart.c b/drivers/iommu/apple_dart.c index bfd4ad20105..ebef28d0b9d 100644 --- a/drivers/iommu/apple_dart.c +++ b/drivers/iommu/apple_dart.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/nvme/nvme_apple.c b/drivers/nvme/nvme_apple.c index 48f82bc826c..3e7d95c2b54 100644 --- a/drivers/nvme/nvme_apple.c +++ b/drivers/nvme/nvme_apple.c @@ -13,6 +13,7 @@ #include #include #include +#include /* ASC registers */ #define REG_CPU_CTRL 0x0044 diff --git a/include/configs/apple.h b/include/configs/apple.h deleted file mode 100644 index 1e08b114480..00000000000 --- a/include/configs/apple.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __CONFIG_H -#define __CONFIG_H - -#include - -/* Environment */ -#define ENV_DEVICE_SETTINGS \ - "stdin=serial,usbkbd,spikbd\0" \ - "stdout=vidconsole,serial\0" \ - "stderr=vidconsole,serial\0" - -#define BOOT_TARGETS "nvme usb" - -#define CFG_EXTRA_ENV_SETTINGS \ - ENV_DEVICE_SETTINGS \ - "boot_targets=" BOOT_TARGETS "\0" - -#endif From db27d8c07f0a574c4289b7d09bc5c7df2d7833af Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sat, 30 Jul 2022 17:07:29 +0900 Subject: [PATCH 11/41] input: apple: Split off report handling into a separate file The MTP HID driver will reuse this code, so split it off into another file. Signed-off-by: Hector Martin --- drivers/input/Kconfig | 5 ++ drivers/input/Makefile | 1 + drivers/input/apple_kbd.c | 138 ++++++++++++++++++++++++++++++++++ drivers/input/apple_kbd.h | 30 ++++++++ drivers/input/apple_spi_kbd.c | 137 ++------------------------------- 5 files changed, 182 insertions(+), 129 deletions(-) create mode 100644 drivers/input/apple_kbd.c create mode 100644 drivers/input/apple_kbd.h diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 47ce0ea690f..ffea5ac5004 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -38,8 +38,13 @@ config TPL_DM_KEYBOARD includes methods to start/stop the device, check for available input and update LEDs if the keyboard has them. +config APPLE_KEYB + bool + depends on DM_KEYBOARD + config APPLE_SPI_KEYB bool "Enable Apple SPI keyboard support" + select APPLE_KEYB depends on DM_KEYBOARD && DM_SPI help This adds a driver for the keyboards found on various diff --git a/drivers/input/Makefile b/drivers/input/Makefile index 1303fcdb0b7..0465635c876 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_CPCAP_POWER_BUTTON) += cpcap_pwrbutton.o ifndef CONFIG_XPL_BUILD +obj-$(CONFIG_APPLE_KEYB) += apple_kbd.o obj-$(CONFIG_APPLE_SPI_KEYB) += apple_spi_kbd.o obj-$(CONFIG_I8042_KEYB) += i8042.o obj-$(CONFIG_TEGRA_KEYBOARD) += input.o tegra-kbc.o diff --git a/drivers/input/apple_kbd.c b/drivers/input/apple_kbd.c new file mode 100644 index 00000000000..71e242af719 --- /dev/null +++ b/drivers/input/apple_kbd.c @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 Mark Kettenis + */ + +#include +#include +#include +#include +#include +#include +#include +#include "apple_kbd.h" + +/* + * The Apple keyboard controllers implement a protocol that + * closely resembles HID Keyboard Boot protocol. The key codes are + * mapped according to the HID Keyboard/Keypad Usage Table. + */ + +/* Modifier key bits */ +#define HID_MOD_LEFTCTRL BIT(0) +#define HID_MOD_LEFTSHIFT BIT(1) +#define HID_MOD_LEFTALT BIT(2) +#define HID_MOD_LEFTGUI BIT(3) +#define HID_MOD_RIGHTCTRL BIT(4) +#define HID_MOD_RIGHTSHIFT BIT(5) +#define HID_MOD_RIGHTALT BIT(6) +#define HID_MOD_RIGHTGUI BIT(7) + +static const u8 hid_kbd_keymap[] = { + KEY_RESERVED, 0xff, 0xff, 0xff, + KEY_A, KEY_B, KEY_C, KEY_D, + KEY_E, KEY_F, KEY_G, KEY_H, + KEY_I, KEY_J, KEY_K, KEY_L, + KEY_M, KEY_N, KEY_O, KEY_P, + KEY_Q, KEY_R, KEY_S, KEY_T, + KEY_U, KEY_V, KEY_W, KEY_X, + KEY_Y, KEY_Z, KEY_1, KEY_2, + KEY_3, KEY_4, KEY_5, KEY_6, + KEY_7, KEY_8, KEY_9, KEY_0, + KEY_ENTER, KEY_ESC, KEY_BACKSPACE, KEY_TAB, + KEY_SPACE, KEY_MINUS, KEY_EQUAL, KEY_LEFTBRACE, + KEY_RIGHTBRACE, KEY_BACKSLASH, 0xff, KEY_SEMICOLON, + KEY_APOSTROPHE, KEY_GRAVE, KEY_COMMA, KEY_DOT, + KEY_SLASH, KEY_CAPSLOCK, KEY_F1, KEY_F2, + KEY_F3, KEY_F4, KEY_F5, KEY_F6, + KEY_F7, KEY_F8, KEY_F9, KEY_F10, + KEY_F11, KEY_F12, KEY_SYSRQ, KEY_SCROLLLOCK, + KEY_PAUSE, KEY_INSERT, KEY_HOME, KEY_PAGEUP, + KEY_DELETE, KEY_END, KEY_PAGEDOWN, KEY_RIGHT, + KEY_LEFT, KEY_DOWN, KEY_UP, KEY_NUMLOCK, + KEY_KPSLASH, KEY_KPASTERISK, KEY_KPMINUS, KEY_KPPLUS, + KEY_KPENTER, KEY_KP1, KEY_KP2, KEY_KP3, + KEY_KP4, KEY_KP5, KEY_KP6, KEY_KP7, + KEY_KP8, KEY_KP9, KEY_KP0, KEY_KPDOT, + KEY_BACKSLASH, KEY_COMPOSE, KEY_POWER, KEY_KPEQUAL, +}; + +/* Report ID used for keyboard input reports. */ +#define KBD_REPORTID 0x01 + +static void apple_kbd_service_modifiers(struct input_config *input, + struct apple_kbd_priv *priv) +{ + u8 new = priv->new.modifiers; + u8 old = priv->old.modifiers; + + if ((new ^ old) & HID_MOD_LEFTCTRL) + input_add_keycode(input, KEY_LEFTCTRL, + old & HID_MOD_LEFTCTRL); + if ((new ^ old) & HID_MOD_RIGHTCTRL) + input_add_keycode(input, KEY_RIGHTCTRL, + old & HID_MOD_RIGHTCTRL); + if ((new ^ old) & HID_MOD_LEFTSHIFT) + input_add_keycode(input, KEY_LEFTSHIFT, + old & HID_MOD_LEFTSHIFT); + if ((new ^ old) & HID_MOD_RIGHTSHIFT) + input_add_keycode(input, KEY_RIGHTSHIFT, + old & HID_MOD_RIGHTSHIFT); + if ((new ^ old) & HID_MOD_LEFTALT) + input_add_keycode(input, KEY_LEFTALT, + old & HID_MOD_LEFTALT); + if ((new ^ old) & HID_MOD_RIGHTALT) + input_add_keycode(input, KEY_RIGHTALT, + old & HID_MOD_RIGHTALT); + if ((new ^ old) & HID_MOD_LEFTGUI) + input_add_keycode(input, KEY_LEFTMETA, + old & HID_MOD_LEFTGUI); + if ((new ^ old) & HID_MOD_RIGHTGUI) + input_add_keycode(input, KEY_RIGHTMETA, + old & HID_MOD_RIGHTGUI); +} + +static void apple_kbd_service_key(struct input_config *input, + struct apple_kbd_priv *priv, + int i, int released) +{ + u8 *new; + u8 *old; + + if (released) { + new = priv->new.keycode; + old = priv->old.keycode; + } else { + new = priv->old.keycode; + old = priv->new.keycode; + } + + if (memscan(new, old[i], sizeof(priv->new.keycode)) == + new + sizeof(priv->new.keycode) && + old[i] < ARRAY_SIZE(hid_kbd_keymap)) + input_add_keycode(input, hid_kbd_keymap[old[i]], released); +} + +int apple_kbd_handle_report(struct input_config *input, + struct apple_kbd_priv *priv, + void *data, size_t size) +{ + struct apple_kbd_report *report = data; + int i; + + if (size < sizeof(struct apple_kbd_report)) + return -1; + + if (report->reportid != KBD_REPORTID) + return 0; + + memcpy(&priv->new, report, sizeof(struct apple_kbd_report)); + apple_kbd_service_modifiers(input, priv); + for (i = 0; i < sizeof(priv->new.keycode); i++) { + apple_kbd_service_key(input, priv, i, 1); + apple_kbd_service_key(input, priv, i, 0); + } + memcpy(&priv->old, &priv->new, sizeof(struct apple_kbd_report)); + + return 1; +} diff --git a/drivers/input/apple_kbd.h b/drivers/input/apple_kbd.h new file mode 100644 index 00000000000..2a9d0021735 --- /dev/null +++ b/drivers/input/apple_kbd.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Common code for handling Apple laptop keyboards + * + * Copyright The Asahi Linux Contributors + */ + +#ifndef _APPLE_KBD_H +#define _APPLE_KBD_H + +#include + +struct apple_kbd_report { + u8 reportid; + u8 modifiers; + u8 reserved; + u8 keycode[6]; + u8 fn; +}; + +struct apple_kbd_priv { + struct apple_kbd_report old; /* previous keyboard input report */ + struct apple_kbd_report new; /* current keyboard input report */ +}; + +int apple_kbd_handle_report(struct input_config *input, + struct apple_kbd_priv *priv, + void *data, size_t size); + +#endif diff --git a/drivers/input/apple_spi_kbd.c b/drivers/input/apple_spi_kbd.c index 5b30cec2dcb..957e43a5d43 100644 --- a/drivers/input/apple_spi_kbd.c +++ b/drivers/input/apple_spi_kbd.c @@ -10,68 +10,7 @@ #include #include #include - -/* - * The Apple SPI keyboard controller implements a protocol that - * closely resembles HID Keyboard Boot protocol. The key codes are - * mapped according to the HID Keyboard/Keypad Usage Table. - */ - -/* Modifier key bits */ -#define HID_MOD_LEFTCTRL BIT(0) -#define HID_MOD_LEFTSHIFT BIT(1) -#define HID_MOD_LEFTALT BIT(2) -#define HID_MOD_LEFTGUI BIT(3) -#define HID_MOD_RIGHTCTRL BIT(4) -#define HID_MOD_RIGHTSHIFT BIT(5) -#define HID_MOD_RIGHTALT BIT(6) -#define HID_MOD_RIGHTGUI BIT(7) - -static const u8 hid_kbd_keymap[] = { - KEY_RESERVED, 0xff, 0xff, 0xff, - KEY_A, KEY_B, KEY_C, KEY_D, - KEY_E, KEY_F, KEY_G, KEY_H, - KEY_I, KEY_J, KEY_K, KEY_L, - KEY_M, KEY_N, KEY_O, KEY_P, - KEY_Q, KEY_R, KEY_S, KEY_T, - KEY_U, KEY_V, KEY_W, KEY_X, - KEY_Y, KEY_Z, KEY_1, KEY_2, - KEY_3, KEY_4, KEY_5, KEY_6, - KEY_7, KEY_8, KEY_9, KEY_0, - KEY_ENTER, KEY_ESC, KEY_BACKSPACE, KEY_TAB, - KEY_SPACE, KEY_MINUS, KEY_EQUAL, KEY_LEFTBRACE, - KEY_RIGHTBRACE, KEY_BACKSLASH, 0xff, KEY_SEMICOLON, - KEY_APOSTROPHE, KEY_GRAVE, KEY_COMMA, KEY_DOT, - KEY_SLASH, KEY_CAPSLOCK, KEY_F1, KEY_F2, - KEY_F3, KEY_F4, KEY_F5, KEY_F6, - KEY_F7, KEY_F8, KEY_F9, KEY_F10, - KEY_F11, KEY_F12, KEY_SYSRQ, KEY_SCROLLLOCK, - KEY_PAUSE, KEY_INSERT, KEY_HOME, KEY_PAGEUP, - KEY_DELETE, KEY_END, KEY_PAGEDOWN, KEY_RIGHT, - KEY_LEFT, KEY_DOWN, KEY_UP, KEY_NUMLOCK, - KEY_KPSLASH, KEY_KPASTERISK, KEY_KPMINUS, KEY_KPPLUS, - KEY_KPENTER, KEY_KP1, KEY_KP2, KEY_KP3, - KEY_KP4, KEY_KP5, KEY_KP6, KEY_KP7, - KEY_KP8, KEY_KP9, KEY_KP0, KEY_KPDOT, - KEY_BACKSLASH, KEY_COMPOSE, KEY_POWER, KEY_KPEQUAL, -}; - -/* Report ID used for keyboard input reports. */ -#define KBD_REPORTID 0x01 - -struct apple_spi_kbd_report { - u8 reportid; - u8 modifiers; - u8 reserved; - u8 keycode[6]; - u8 fn; -}; - -struct apple_spi_kbd_priv { - struct gpio_desc enable; - struct apple_spi_kbd_report old; /* previous keyboard input report */ - struct apple_spi_kbd_report new; /* current keyboard input report */ -}; +#include "apple_kbd.h" /* Keyboard device. */ #define KBD_DEVICE 0x01 @@ -100,58 +39,10 @@ struct apple_spi_kbd_msg { u8 data[0]; }; -static void apple_spi_kbd_service_modifiers(struct input_config *input) -{ - struct apple_spi_kbd_priv *priv = dev_get_priv(input->dev); - u8 new = priv->new.modifiers; - u8 old = priv->old.modifiers; - - if ((new ^ old) & HID_MOD_LEFTCTRL) - input_add_keycode(input, KEY_LEFTCTRL, - old & HID_MOD_LEFTCTRL); - if ((new ^ old) & HID_MOD_RIGHTCTRL) - input_add_keycode(input, KEY_RIGHTCTRL, - old & HID_MOD_RIGHTCTRL); - if ((new ^ old) & HID_MOD_LEFTSHIFT) - input_add_keycode(input, KEY_LEFTSHIFT, - old & HID_MOD_LEFTSHIFT); - if ((new ^ old) & HID_MOD_RIGHTSHIFT) - input_add_keycode(input, KEY_RIGHTSHIFT, - old & HID_MOD_RIGHTSHIFT); - if ((new ^ old) & HID_MOD_LEFTALT) - input_add_keycode(input, KEY_LEFTALT, - old & HID_MOD_LEFTALT); - if ((new ^ old) & HID_MOD_RIGHTALT) - input_add_keycode(input, KEY_RIGHTALT, - old & HID_MOD_RIGHTALT); - if ((new ^ old) & HID_MOD_LEFTGUI) - input_add_keycode(input, KEY_LEFTMETA, - old & HID_MOD_LEFTGUI); - if ((new ^ old) & HID_MOD_RIGHTGUI) - input_add_keycode(input, KEY_RIGHTMETA, - old & HID_MOD_RIGHTGUI); -} - -static void apple_spi_kbd_service_key(struct input_config *input, int i, - int released) -{ - struct apple_spi_kbd_priv *priv = dev_get_priv(input->dev); - u8 *new; - u8 *old; - - if (released) { - new = priv->new.keycode; - old = priv->old.keycode; - } else { - new = priv->old.keycode; - old = priv->new.keycode; - } - - if (memscan(new, old[i], sizeof(priv->new.keycode)) == - new + sizeof(priv->new.keycode) && - old[i] < ARRAY_SIZE(hid_kbd_keymap)) - input_add_keycode(input, hid_kbd_keymap[old[i]], released); -} +struct apple_spi_kbd_priv { + struct gpio_desc enable; + struct apple_kbd_priv kbd; +}; static int apple_spi_kbd_check(struct input_config *input) { @@ -160,7 +51,7 @@ static int apple_spi_kbd_check(struct input_config *input) struct apple_spi_kbd_packet packet; struct apple_spi_kbd_msg *msg; struct apple_spi_kbd_report *report; - int i, ret; + int ret; memset(&packet, 0, sizeof(packet)); @@ -195,20 +86,8 @@ static int apple_spi_kbd_check(struct input_config *input) msg = (struct apple_spi_kbd_msg *)packet.data; report = (struct apple_spi_kbd_report *)msg->data; if (packet.flags == PACKET_READ && packet.device == KBD_DEVICE && - msg->type == MSG_REPORT && msg->device == KBD_DEVICE && - msg->cmdlen == sizeof(struct apple_spi_kbd_report) && - report->reportid == KBD_REPORTID) { - memcpy(&priv->new, report, - sizeof(struct apple_spi_kbd_report)); - apple_spi_kbd_service_modifiers(input); - for (i = 0; i < sizeof(priv->new.keycode); i++) { - apple_spi_kbd_service_key(input, i, 1); - apple_spi_kbd_service_key(input, i, 0); - } - memcpy(&priv->old, &priv->new, - sizeof(struct apple_spi_kbd_report)); - return 1; - } + msg->type == MSG_REPORT && msg->device == KBD_DEVICE) + return apple_kbd_handle_report(input, &priv->kbd, msg->data, msg->cmdlen); return 0; From dd20f5e6cb98ee19aa0d73353df9d3c83e281c43 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Mon, 1 Aug 2022 22:14:12 +0900 Subject: [PATCH 12/41] input: apple: Add support for Apple MTP keyboard Apple M2 devices have an MTP coprocessor in charge of keyboard/trackpad handling, communicating over a DockChannel interface. Add a simple driver for this. The keyboard does not require any initialization messages, but we have a problem: we cannot reset the MTP so Linux can start it fresh, and it delivers a number of informative packets on startup. To work around this, we buffer those messages and re-inject them into the FIFO (which is big enough to hold all of them) on shutdown, so Linux finds them when it initializes its driver. The actual MTP coprocessor is quiesced, which does work properly. Signed-off-by: Hector Martin --- board/apple/mac/mac.env | 2 +- drivers/input/Kconfig | 9 ++ drivers/input/Makefile | 1 + drivers/input/apple_mtp_kbd.c | 261 ++++++++++++++++++++++++++++++++++ 4 files changed, 272 insertions(+), 1 deletion(-) create mode 100644 drivers/input/apple_mtp_kbd.c diff --git a/board/apple/mac/mac.env b/board/apple/mac/mac.env index 109379c8c67..345b67a7445 100644 --- a/board/apple/mac/mac.env +++ b/board/apple/mac/mac.env @@ -1,4 +1,4 @@ -stdin=serial,usbkbd,spikbd +stdin=serial,usbkbd,spikbd,mtpkbd stdout=vidconsole,serial stderr=vidconsole,serial boot_targets=nvme usb diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index ffea5ac5004..af2e050462a 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -66,6 +66,15 @@ config CPCAP_POWER_BUTTON help Enable support for a dedicated power button of the CPCAP PMIC. +config APPLE_MTP_KEYB + bool "Enable Apple MTP keyboard support" + select APPLE_KEYB + depends on DM_KEYBOARD && MISC + help + This adds a driver for the keyboards found on various + laptops based on Apple M2 and newer SoCs. These keyboards use an + Apple-specific HID-over-DockChannel protocol. + config CROS_EC_KEYB bool "Enable Chrome OS EC keyboard support" depends on INPUT diff --git a/drivers/input/Makefile b/drivers/input/Makefile index 0465635c876..d52552206e7 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -13,6 +13,7 @@ ifndef CONFIG_XPL_BUILD obj-$(CONFIG_APPLE_KEYB) += apple_kbd.o obj-$(CONFIG_APPLE_SPI_KEYB) += apple_spi_kbd.o +obj-$(CONFIG_APPLE_MTP_KEYB) += apple_mtp_kbd.o obj-$(CONFIG_I8042_KEYB) += i8042.o obj-$(CONFIG_TEGRA_KEYBOARD) += input.o tegra-kbc.o obj-$(CONFIG_TWL4030_INPUT) += twl4030.o diff --git a/drivers/input/apple_mtp_kbd.c b/drivers/input/apple_mtp_kbd.c new file mode 100644 index 00000000000..e80e9a01c6f --- /dev/null +++ b/drivers/input/apple_mtp_kbd.c @@ -0,0 +1,261 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright The Asahi Linux Contributors + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "apple_kbd.h" + +struct apple_mtp_kbd_priv { + struct apple_kbd_priv kbd; + struct udevice *helper; + void *local; + void *rmt; + + u8 *init_data; + u32 init_size; + u32 fifo_size; +}; + +#define DATA_TX8 0x4 +#define DATA_TX_FREE 0x14 +#define DATA_RX8 0x1c +#define DATA_RX_COUNT 0x2c + +struct dchid_hdr { + u8 hdr_len; + u8 channel; + __le16 length; + u8 seq; + u8 iface; + __le16 pad; +} __packed; + +static int dockchannel_read(struct udevice *dev, void *buf, size_t size) +{ + struct apple_mtp_kbd_priv *priv = dev_get_priv(dev); + int ret = 0; + u8 b; + u8 *p = buf; + + while (size--) { + ulong start; + start = get_timer(0); + while (get_timer(start) < 100) { + if (readl(priv->local + DATA_RX_COUNT) != 0) + break; + } + + if (readl(priv->local + DATA_RX_COUNT) == 0) { + return -ETIME; + } + + b = readl(priv->local + DATA_RX8) >> 8; + if (buf) + *p++ = b; + + ret++; + } + + return ret; +} + +static int apple_mtp_kbd_check(struct input_config *input) +{ + struct udevice *dev = input->dev; + struct apple_mtp_kbd_priv *priv = dev_get_priv(dev); + struct dchid_hdr hdr; + int ret; + + /* Poll for syslogs if RTKit is up */ + if (priv->helper) + apple_rtkit_helper_poll(priv->helper, 0); + + u32 pending = readl(priv->local + DATA_RX_COUNT); + if (pending < 8) + return 0; + + ret = dockchannel_read(dev, &hdr, sizeof(hdr)); + if (ret < 0) { + dev_err(dev, "failed to read packet header\n"); + return ret; + } + + /* Save comm init messages for the next stage */ + if (hdr.iface == 0) { + int space = priv->fifo_size - priv->init_size; + int need = hdr.length + sizeof(hdr) + 4; + + if (space < need) { + dev_err(dev, "out of buf space (%d > %d)\n", + need, space); + ret = dockchannel_read(dev, NULL, hdr.length + 4); + if (ret < 0) + return ret; + } else { + u8 *p = &priv->init_data[priv->init_size]; + + memcpy(p, &hdr, sizeof(hdr)); + ret = dockchannel_read(dev, p + sizeof(hdr), hdr.length + 4); + if (ret < 0) + return ret; + priv->init_size += need; + } + } else if (hdr.channel == 0x12 && hdr.length == 0x14) { + u8 buf[0x18]; + + ret = dockchannel_read(dev, buf, 0x18); + if (ret < 0) + return ret; + + if (!priv->helper) + return 1; /* Ignore if shutting down */ + + /* Just assume it's a keyboard report */ + return apple_kbd_handle_report(input, &priv->kbd, buf + 8, 0xc); + } else { + printk("mtp: unknown message ch=%02x l=%04x if=%02x\n", + hdr.channel, hdr.length, hdr.iface); + ret = dockchannel_read(dev, NULL, hdr.length + 4); + if (ret < 0) + return ret; + } + + return 0; +} + +static int get_rtkit_helper(struct udevice *dev) +{ + struct apple_mtp_kbd_priv *priv = dev_get_priv(dev); + int ret; + u32 phandle; + ofnode of_mtp; + + ret = dev_read_u32(dev, "apple,helper-cpu", &phandle); + if (ret < 0) + return ret; + + of_mtp = ofnode_get_by_phandle(phandle); + ret = uclass_get_device_by_ofnode(UCLASS_MISC, of_mtp, &priv->helper); + if (ret < 0) + return ret; + + return 0; +} + +static int apple_mtp_kbd_probe(struct udevice *dev) +{ + struct apple_mtp_kbd_priv *priv = dev_get_priv(dev); + struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev); + struct stdio_dev *sdev = &uc_priv->sdev; + struct input_config *input = &uc_priv->input; + int ret; + fdt_addr_t reg; + + printf("mtp_kbd_probe\n"); + + reg = dev_read_addr_name(dev, "data"); + if (reg == FDT_ADDR_T_NONE) { + dev_err(dev, "no reg property for local FIFO data registers\n"); + return -EINVAL; + } + priv->local = (void *)reg; + + reg = dev_read_addr_name(dev, "rmt-data"); + if (reg == FDT_ADDR_T_NONE) { + dev_err(dev, "no reg property for remote FIFO data registers\n"); + return -EINVAL; + } + priv->rmt = (void *)reg; + + ret = dev_read_u32(dev, "apple,fifo-size", &priv->fifo_size); + if (ret < 0 || !priv->fifo_size) { + dev_err(dev, "no apple,fifo-size property\n"); + return ret; + } + + ret = get_rtkit_helper(dev); + if (ret < 0) { + dev_err(dev, "Failed to get helper device (%d)\n", ret); + return ret; + } + + priv->init_data = malloc(priv->fifo_size); + if (!priv->init_data) + return -ENOMEM; + + input->dev = dev; + input->read_keys = apple_mtp_kbd_check; + input_add_tables(input, false); + strcpy(sdev->name, "mtpkbd"); + + return input_stdio_register(sdev); +} + +static int apple_mtp_kbd_remove(struct udevice *dev) +{ + struct apple_mtp_kbd_priv *priv = dev_get_priv(dev); + struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev); + struct input_config *input = &uc_priv->input; + int i; + + if (priv->helper) { + device_remove(priv->helper, DM_REMOVE_NORMAL); + priv->helper = NULL; + } + + /* Drain the FIFO */ + while (readl(priv->local + DATA_RX_COUNT)) { + if (apple_mtp_kbd_check(input) < 0) { + dev_err(dev, "Failed to drain FIFO\n"); + break; + } + } + + /* Stuff init messages back into FIFO for the next stage to find */ + for (i = 0; i < priv->init_size; i++) + writel(priv->init_data[i], priv->rmt + DATA_TX8); + + return 0; +} + +static const struct keyboard_ops apple_mtp_kbd_ops = { +}; + +static const struct udevice_id apple_mtp_kbd_of_match[] = { + { .compatible = "apple,dockchannel-hid" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(apple_mtp_kbd) = { + .name = "apple_mtp_kbd", + .id = UCLASS_KEYBOARD, + .of_match = apple_mtp_kbd_of_match, + .probe = apple_mtp_kbd_probe, + .remove = apple_mtp_kbd_remove, + .priv_auto = sizeof(struct apple_mtp_kbd_priv), + .ops = &apple_mtp_kbd_ops, + .flags = DM_FLAG_OS_PREPARE, +}; + +/* Treat dockchannel as a simple-bus, since we don't use the IRQ stuff */ + +static const struct udevice_id dockchannel_bus_ids[] = { + { .compatible = "apple,dockchannel" }, + { } +}; + +U_BOOT_DRIVER(dockchannel) = { + .name = "dockchannel", + .id = UCLASS_SIMPLE_BUS, + .of_match = of_match_ptr(dockchannel_bus_ids), +}; From 3b197c83142f643e73a1881eeaa2c69168cd7ade Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Tue, 2 Aug 2022 15:11:14 +0900 Subject: [PATCH 13/41] arm: apple: Add MTP keyboard options to defconfig Signed-off-by: Hector Martin --- configs/apple_m1_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig index 26d722265aa..7b21d0090db 100644 --- a/configs/apple_m1_defconfig +++ b/configs/apple_m1_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_MISC=y CONFIG_ARCH_APPLE=y CONFIG_DEFAULT_DEVICE_TREE="apple/t8103-j274" CONFIG_SYS_BOOTM_LEN=0x800000 @@ -15,6 +16,7 @@ CONFIG_CMD_SELECT_FONT=y CONFIG_NO_NET=y CONFIG_SYS_64BIT_LBA=y CONFIG_APPLE_SPI_KEYB=y +CONFIG_APPLE_MTP_KEYB=y # CONFIG_MMC is not set CONFIG_NVME_APPLE=y CONFIG_SYSINFO=y From e18c2cc68ad3917dff37a15a69be06805c2ca792 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Tue, 2 May 2023 20:14:20 +0200 Subject: [PATCH 14/41] apple: Set up file system firmware loader Find the appropriate EFI system partition on the internal NVMe storage and set the U-Boot environment variables such that the file system firmware loader can load firmware from it. Signed-off-by: Mark Kettenis --- arch/arm/mach-apple/board.c | 60 +++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c index 4cd8979bdc2..0bb20f5e1ff 100644 --- a/arch/arm/mach-apple/board.c +++ b/arch/arm/mach-apple/board.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include @@ -771,6 +773,61 @@ u64 get_page_table_size(void) return SZ_256K; } +static char *asahi_esp_devpart(void) +{ + struct disk_partition info; + struct blk_desc *nvme_blk; + const char *uuid = NULL; + int devnum, len, p, part, ret; + static char devpart[64]; + struct udevice *dev; + ofnode node; + + if (devpart[0]) + return devpart; + + node = ofnode_path("/chosen"); + if (ofnode_valid(node)) { + uuid = ofnode_get_property(node, "asahi,efi-system-partition", + &len); + } + + nvme_scan_namespace(); + for (devnum = 0, part = 0; ; devnum++) { + nvme_blk = blk_get_devnum_by_uclass_id(UCLASS_NVME, devnum); + if (!nvme_blk) + break; + + dev = dev_get_parent(nvme_blk->bdev); + if (!device_is_compatible(dev, "apple,nvme-ans2") && + !device_is_compatible(dev, "apple,t8103-nvme-ans2")) + continue; + + for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) { + ret = part_get_info(nvme_blk, p, &info); + if (ret < 0) + break; + + if (info.bootable & PART_EFI_SYSTEM_PARTITION) { + if (uuid && strcasecmp(uuid, info.uuid) == 0) { + part = p; + break; + } + if (part == 0) + part = p; + } + } + + if (part > 0) + break; + } + + if (part > 0) + snprintf(devpart, sizeof(devpart), "%x:%x", devnum, part); + + return devpart; +} + #define KERNEL_COMP_SIZE SZ_128M #define lmb_alloc(size, addr) lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, addr, size, LMB_NONE) @@ -780,6 +837,9 @@ int board_late_init(void) u32 status = 0; phys_addr_t addr; + env_set("storage_interface", blk_get_uclass_name(UCLASS_NVME)); + env_set("fw_dev_part", asahi_esp_devpart()); + /* somewhat based on the Linux Kernel boot requirements: * align by 2M and maximal FDT size 2M */ From 01878d7691bd2e8b4dc53bd7386b82ff231acc3b Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Fri, 14 Apr 2023 21:24:04 +0200 Subject: [PATCH 15/41] iopoll: Add readb_poll_sleep_timeout Add a variant of readl_poll_sleep_timeout that reads a single byte to match the readb_poll_timeout API that Linux has. Signed-off-by: Mark Kettenis Reviewed-by: Tom Rini --- include/linux/iopoll.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/linux/iopoll.h b/include/linux/iopoll.h index 0ee2bddaa83..955ab881006 100644 --- a/include/linux/iopoll.h +++ b/include/linux/iopoll.h @@ -46,6 +46,9 @@ #define readx_poll_sleep_timeout(op, addr, val, cond, sleep_us, timeout_us) \ read_poll_timeout(op, val, cond, sleep_us, timeout_us, addr) +#define readb_poll_sleep_timeout(addr, val, cond, sleep_us, timeout_us) \ + readx_poll_sleep_timeout(readb, addr, val, cond, sleep_us, timeout_us) + #define readl_poll_sleep_timeout(addr, val, cond, sleep_us, timeout_us) \ readx_poll_sleep_timeout(readl, addr, val, cond, sleep_us, timeout_us) From f9e0240c5693be7859e5d142a39ed59892a13576 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Fri, 14 Apr 2023 21:27:16 +0200 Subject: [PATCH 16/41] usb: xhci-pci: Load ASMedia XHCI controller firmware The ASMedia XHCI controller found on some of the Apple Silicon machines needs firmware to operate. Use the file system firmware loader interface to read the firmware and load it onto the controller. This allows keyboards connected to the type-A ports on these machines to function in U-Boot. Signed-off-by: Mark Kettenis --- MAINTAINERS | 1 + drivers/usb/host/Kconfig | 11 + drivers/usb/host/Makefile | 1 + drivers/usb/host/xhci-pci-asmedia.c | 411 ++++++++++++++++++++++++++++ drivers/usb/host/xhci-pci.c | 9 + include/usb/xhci.h | 3 + 6 files changed, 436 insertions(+) create mode 100644 drivers/usb/host/xhci-pci-asmedia.c diff --git a/MAINTAINERS b/MAINTAINERS index 5ea3e4e55ec..b59c9840468 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -143,6 +143,7 @@ F: drivers/phy/phy-apple-atc.c F: drivers/pinctrl/pinctrl-apple.c F: drivers/power/domain/apple-pmgr.c F: drivers/spi/apple_spi.c +F: drivers/usb/host/xhci-pci-asmedia.c F: drivers/watchdog/apple_wdt.c F: include/configs/apple.h diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index d75883e2865..1feed309919 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -102,6 +102,17 @@ config USB_XHCI_PCI help Enables support for the PCI-based xHCI controller. +config USB_XHCI_PCI_ASMEDIA + bool "Support for ASMedia xHCI USB controller" + depends on USB_XHCI_PCI + default y if ARCH_APPLE + select FS_LOADER + help + Enables support for loading firmware for the ASMedia xHCI + controller. This is needed on Apple Silicon machines that + contain ASMedia xHCI controllers without the full USB + firmware. + config USB_XHCI_RCAR bool "Renesas R-Car USB 3.0 support" default y diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index ef4ce62a680..d74174213b0 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -53,6 +53,7 @@ obj-$(CONFIG_USB_XHCI_MVEBU) += xhci-mvebu.o obj-$(CONFIG_USB_XHCI_GENERIC) += xhci-generic.o obj-$(CONFIG_USB_XHCI_OMAP) += xhci-omap.o obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o +obj-$(CONFIG_USB_XHCI_PCI_ASMEDIA) += xhci-pci-asmedia.o obj-$(CONFIG_USB_XHCI_RCAR) += xhci-rcar.o obj-$(CONFIG_USB_XHCI_OCTEON) += dwc3-octeon-glue.o diff --git a/drivers/usb/host/xhci-pci-asmedia.c b/drivers/usb/host/xhci-pci-asmedia.c new file mode 100644 index 00000000000..d48b83e3ee9 --- /dev/null +++ b/drivers/usb/host/xhci-pci-asmedia.c @@ -0,0 +1,411 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * ASMedia xHCI firmware loader + * Copyright (C) The Asahi Linux Contributors + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Configuration space registers */ +#define ASMT_CFG_CONTROL 0xe0 +#define ASMT_CFG_CONTROL_WRITE BIT(1) +#define ASMT_CFG_CONTROL_READ BIT(0) + +#define ASMT_CFG_SRAM_ADDR 0xe2 + +#define ASMT_CFG_SRAM_ACCESS 0xef +#define ASMT_CFG_SRAM_ACCESS_READ BIT(6) +#define ASMT_CFG_SRAM_ACCESS_ENABLE BIT(7) + +#define ASMT_CFG_DATA_READ0 0xf0 +#define ASMT_CFG_DATA_READ1 0xf4 + +#define ASMT_CFG_DATA_WRITE0 0xf8 +#define ASMT_CFG_DATA_WRITE1 0xfc + +#define ASMT_CMD_GET_FWVER 0x8000060840 +#define ASMT_FWVER_ROM 0x010250090816 + +/* BAR0 registers */ +#define ASMT_REG_ADDR 0x3000 + +#define ASMT_REG_WDATA 0x3004 +#define ASMT_REG_RDATA 0x3008 + +#define ASMT_REG_STATUS 0x3009 +#define ASMT_REG_STATUS_BUSY BIT(7) + +#define ASMT_REG_CODE_WDATA 0x3010 +#define ASMT_REG_CODE_RDATA 0x3018 + +#define ASMT_MMIO_CPU_MISC 0x500e +#define ASMT_MMIO_CPU_MISC_CODE_RAM_WR BIT(0) + +#define ASMT_MMIO_CPU_MODE_NEXT 0x5040 +#define ASMT_MMIO_CPU_MODE_CUR 0x5041 + +#define ASMT_MMIO_CPU_MODE_RAM BIT(0) +#define ASMT_MMIO_CPU_MODE_HALFSPEED BIT(1) + +#define ASMT_MMIO_CPU_EXEC_CTRL 0x5042 +#define ASMT_MMIO_CPU_EXEC_CTRL_RESET BIT(0) +#define ASMT_MMIO_CPU_EXEC_CTRL_HALT BIT(1) + +#define TIMEOUT_USEC 10000 +#define RESET_TIMEOUT_USEC 500000 + +static int asmedia_mbox_tx(struct udevice *pdev, u64 data) +{ + u8 op; + int ret, err; + + ret = read_poll_timeout(dm_pci_read_config8, err, + err || !(op & ASMT_CFG_CONTROL_WRITE), + 1, TIMEOUT_USEC, pdev, ASMT_CFG_CONTROL, &op); + if (ret) { + dev_err(pdev, + "Timed out on mailbox tx: 0x%llx\n", + data); + return ret; + } + if (err) + return err; + + dm_pci_write_config32(pdev, ASMT_CFG_DATA_WRITE0, data); + dm_pci_write_config32(pdev, ASMT_CFG_DATA_WRITE1, data >> 32); + dm_pci_write_config8(pdev, ASMT_CFG_CONTROL, ASMT_CFG_CONTROL_WRITE); + + return 0; +} + +static int asmedia_mbox_rx(struct udevice *pdev, u64 *data) +{ + u8 op; + u32 low, high; + int ret, err; + + ret = read_poll_timeout(dm_pci_read_config8, err, + err || (op & ASMT_CFG_CONTROL_READ), + 1, TIMEOUT_USEC, pdev, ASMT_CFG_CONTROL, &op); + if (ret) { + dev_err(pdev, "Timed out on mailbox rx\n"); + return ret; + } + if (err) + return err; + + dm_pci_read_config32(pdev, ASMT_CFG_DATA_READ0, &low); + dm_pci_read_config32(pdev, ASMT_CFG_DATA_READ1, &high); + dm_pci_write_config8(pdev, ASMT_CFG_CONTROL, ASMT_CFG_CONTROL_READ); + + *data = ((u64)high << 32) | low; + return 0; +} + +static int asmedia_get_fw_version(struct udevice *pdev, u64 *version) +{ + int err = 0; + u64 cmd; + + err = asmedia_mbox_tx(pdev, ASMT_CMD_GET_FWVER); + if (err) + return err; + err = asmedia_mbox_tx(pdev, 0); + if (err) + return err; + + err = asmedia_mbox_rx(pdev, &cmd); + if (err) + return err; + err = asmedia_mbox_rx(pdev, version); + if (err) + return err; + + if (cmd != ASMT_CMD_GET_FWVER) { + dev_err(pdev, "Unexpected reply command 0x%llx\n", cmd); + return -EIO; + } + + return 0; +} + +static bool asmedia_check_firmware(struct udevice *pdev) +{ + u64 fwver; + int ret; + + ret = asmedia_get_fw_version(pdev, &fwver); + if (ret) + return ret; + + dev_info(pdev, "Firmware version: 0x%llx\n", fwver); + + return fwver != ASMT_FWVER_ROM; +} + +static int asmedia_wait_reset(struct udevice *pdev, struct xhci_hcor *hcor) +{ + u32 val; + int ret; + + ret = readl_poll_sleep_timeout(&hcor->or_usbcmd, + val, !(val & CMD_RESET), + 1000, RESET_TIMEOUT_USEC); + + if (!ret) + return 0; + + dev_err(pdev, "Reset timed out, trying to kick it\n"); + + dm_pci_write_config8(pdev, ASMT_CFG_SRAM_ACCESS, + ASMT_CFG_SRAM_ACCESS_ENABLE); + + dm_pci_write_config8(pdev, ASMT_CFG_SRAM_ACCESS, 0); + + ret = readl_poll_sleep_timeout(&hcor->or_usbcmd, + val, !(val & CMD_RESET), + 1000, RESET_TIMEOUT_USEC); + + if (ret) + dev_err(pdev, "Reset timed out, giving up\n"); + + return ret; +} + +static int asmedia_read_reg(struct udevice *pdev, struct xhci_hccr *hccr, + u16 addr, u8 *val) +{ + void __iomem *regs = (void *)hccr; + u8 status; + int ret; + + ret = readb_poll_sleep_timeout(regs + ASMT_REG_STATUS, status, + !(status & ASMT_REG_STATUS_BUSY), + 1000, TIMEOUT_USEC); + + if (ret) { + dev_err(pdev, + "Read reg wait timed out ([%04x])\n", addr); + return ret; + } + + writew_relaxed(addr, regs + ASMT_REG_ADDR); + + ret = readb_poll_sleep_timeout(regs + ASMT_REG_STATUS, status, + !(status & ASMT_REG_STATUS_BUSY), + 1000, TIMEOUT_USEC); + + if (ret) { + dev_err(pdev, + "Read reg addr timed out ([%04x])\n", addr); + return ret; + } + + *val = readb_relaxed(regs + ASMT_REG_RDATA); + return 0; +} + +static int asmedia_write_reg(struct udevice *pdev, struct xhci_hccr *hccr, + u16 addr, u8 data, bool wait) +{ + void __iomem *regs = (void *)hccr; + u8 status, val; + int ret, err; + + writew_relaxed(addr, regs + ASMT_REG_ADDR); + + ret = readb_poll_sleep_timeout(regs + ASMT_REG_STATUS, status, + !(status & ASMT_REG_STATUS_BUSY), + 1000, TIMEOUT_USEC); + + if (ret) { + dev_err(pdev, + "Write reg addr timed out ([%04x] = %02x)\n", + addr, data); + return ret; + } + + writeb_relaxed(data, regs + ASMT_REG_WDATA); + + ret = readb_poll_sleep_timeout(regs + ASMT_REG_STATUS, status, + !(status & ASMT_REG_STATUS_BUSY), + 1000, TIMEOUT_USEC); + + if (ret) { + dev_err(pdev, + "Write reg data timed out ([%04x] = %02x)\n", + addr, data); + return ret; + } + + if (!wait) + return 0; + + ret = read_poll_timeout(asmedia_read_reg, err, err || val == data, + 0, TIMEOUT_USEC, pdev, hccr, addr, &val); + if (ret) { + dev_err(pdev, + "Verify register timed out ([%04x] = %02x)\n", + addr, data); + return ret; + } + if (err) { + dev_err(pdev, + "Verify register read error ([%04x] = %02x)\n", + addr, data); + return err; + } + + return 0; +} + +static int asmedia_load_fw(struct udevice *pdev, struct xhci_hccr *hccr, + struct xhci_hcor *hcor, void *fwdata, size_t fwsize) +{ + void __iomem *regs = (void *)hccr; + const u16 *fw_data = (const u16 *)fwdata; + u16 raddr; + u32 data; + size_t index = 0, addr = 0; + size_t words = fwsize >> 1; + int ret, err; + + ret = asmedia_write_reg(pdev, hccr, ASMT_MMIO_CPU_MODE_NEXT, + ASMT_MMIO_CPU_MODE_HALFSPEED, false); + if (ret) + return ret; + + ret = asmedia_write_reg(pdev, hccr, ASMT_MMIO_CPU_EXEC_CTRL, + ASMT_MMIO_CPU_EXEC_CTRL_RESET, false); + if (ret) + return ret; + + ret = asmedia_wait_reset(pdev, hcor); + if (ret) { + dev_err(pdev, "Failed pre-upload reset\n"); + return ret; + } + + ret = asmedia_write_reg(pdev, hccr, ASMT_MMIO_CPU_EXEC_CTRL, + ASMT_MMIO_CPU_EXEC_CTRL_HALT, false); + if (ret) + return ret; + + ret = asmedia_write_reg(pdev, hccr, ASMT_MMIO_CPU_MISC, + ASMT_MMIO_CPU_MISC_CODE_RAM_WR, true); + if (ret) + return ret; + + dm_pci_write_config8(pdev, ASMT_CFG_SRAM_ACCESS, + ASMT_CFG_SRAM_ACCESS_ENABLE); + + /* The firmware upload is interleaved in 0x4000 word blocks */ + while (index < words) { + data = fw_data[index]; + if ((index | 0x4000) < words) + data |= fw_data[index | 0x4000] << 16; + + dm_pci_write_config16(pdev, ASMT_CFG_SRAM_ADDR, + addr); + + writel_relaxed(data, regs + ASMT_REG_CODE_WDATA); + + ret = read_poll_timeout(dm_pci_read_config16, err, + err || (raddr != addr), + 1, TIMEOUT_USEC, pdev, + ASMT_CFG_SRAM_ADDR, &raddr); + if (ret) { + dev_err(pdev, "Word write timed out\n"); + return ret; + } + if (err) + return err; + + if (++index & 0x4000) + index += 0x4000; + addr += 2; + } + + dm_pci_write_config8(pdev, ASMT_CFG_SRAM_ACCESS, 0); + + ret = asmedia_write_reg(pdev, hccr, ASMT_MMIO_CPU_MISC, 0, true); + if (ret) + return ret; + + ret = asmedia_write_reg(pdev, hccr, ASMT_MMIO_CPU_MODE_NEXT, + ASMT_MMIO_CPU_MODE_RAM | + ASMT_MMIO_CPU_MODE_HALFSPEED, false); + if (ret) + return ret; + + ret = asmedia_write_reg(pdev, hccr, ASMT_MMIO_CPU_EXEC_CTRL, 0, false); + if (ret) + return ret; + + ret = asmedia_wait_reset(pdev, hcor); + if (ret) { + dev_err(pdev, "Failed post-upload reset\n"); + return ret; + } + + return 0; +} + +int asmedia_xhci_check_request_fw(struct udevice *pdev, + struct xhci_hccr *hccr, + struct xhci_hcor *hcor) +{ + const char *fw_name = "vendorfw/u-boot/asmedia/asm2214a-apple.bin"; + struct udevice *fsdev; + void *data; + int ret; + + /* Check if device has firmware, if so skip everything */ + ret = asmedia_check_firmware(pdev); + if (ret < 0) + return ret; + else if (ret == 1) + return 0; + + ret = get_fs_loader(&fsdev); + if (ret) { + dev_err(pdev, "Could not load firmware %s: %d\n", + fw_name, ret); + return ret; + } + + data = malloc(SZ_256K); + ret = request_firmware_into_buf(fsdev, fw_name, data, SZ_256K, 0); + if (ret < 0) { + dev_err(pdev, "Could not load firmware %s: %d\n", + fw_name, ret); + return ret; + } + + ret = asmedia_load_fw(pdev, hccr, hcor, data, ret); + if (ret) { + dev_err(pdev, "Firmware upload failed: %d\n", ret); + goto err; + } + + ret = asmedia_check_firmware(pdev); + if (ret < 0) { + goto err; + } else if (ret != 1) { + dev_err(pdev, "Firmware version is too old after upload\n"); + ret = -EIO; + } else { + ret = 0; + } + +err: + free(data); + return ret; +} diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index f6972af7963..09d0abfd5af 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -52,6 +52,7 @@ static int xhci_pci_init(struct udevice *dev, struct xhci_hccr **ret_hccr, static int xhci_pci_probe(struct udevice *dev) { struct xhci_pci_plat *plat = dev_get_plat(dev); + struct pci_child_plat *pplat = dev_get_parent_plat(dev); struct xhci_hccr *hccr; struct xhci_hcor *hcor; int ret; @@ -76,6 +77,14 @@ static int xhci_pci_probe(struct udevice *dev) if (ret) goto err_reset; + if (IS_ENABLED(CONFIG_USB_XHCI_PCI_ASMEDIA) && + pplat->vendor == PCI_VENDOR_ID_ASMEDIA && + pplat->device == 0x2142) { + ret = asmedia_xhci_check_request_fw(dev, hccr, hcor); + if (ret) + goto err_reset; + } + ret = xhci_register(dev, hccr, hcor); if (ret) goto err_reset; diff --git a/include/usb/xhci.h b/include/usb/xhci.h index ba065311df5..14de983b152 100644 --- a/include/usb/xhci.h +++ b/include/usb/xhci.h @@ -1308,4 +1308,7 @@ static inline void xhci_dma_unmap(struct xhci_ctrl *ctrl, dma_addr_t addr, #endif } +int asmedia_xhci_check_request_fw(struct udevice *, struct xhci_hccr *, + struct xhci_hcor *); + #endif /* HOST_XHCI_H_ */ From f5787c26ae35f5b10d808073e19b9c81ab4e93a7 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Tue, 2 May 2023 20:41:01 +0200 Subject: [PATCH 17/41] env: apple: Enable ENV_IS_IN_FAT Now that we have a way to find the appropriate EFI system partition on the internal NVMe storage, store the U-Boot environment there. Signed-off-by: Mark Kettenis --- arch/arm/mach-apple/board.c | 10 ++++++++++ env/Kconfig | 1 + 2 files changed, 11 insertions(+) diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c index 0bb20f5e1ff..7a71a57b249 100644 --- a/arch/arm/mach-apple/board.c +++ b/arch/arm/mach-apple/board.c @@ -828,6 +828,16 @@ static char *asahi_esp_devpart(void) return devpart; } +const char *env_fat_get_intf(void) +{ + return blk_get_uclass_name(UCLASS_NVME); +} + +char *env_fat_get_dev_part(void) +{ + return asahi_esp_devpart(); +} + #define KERNEL_COMP_SIZE SZ_128M #define lmb_alloc(size, addr) lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, addr, size, LMB_NONE) diff --git a/env/Kconfig b/env/Kconfig index b312f9b5324..c21f9ea56b7 100644 --- a/env/Kconfig +++ b/env/Kconfig @@ -109,6 +109,7 @@ config ENV_IS_IN_EEPROM config ENV_IS_IN_FAT bool "Environment is in a FAT filesystem" depends on !CHAIN_OF_TRUST + default y if ARCH_APPLE default y if ARCH_BCM283X default y if ARCH_SUNXI && MMC default y if MMC_OMAP_HS && TI_COMMON_CMD_OPTIONS From 91ea578fe3ab3ef48b87d18607c015d7e280be5b Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Tue, 2 May 2023 20:46:52 +0200 Subject: [PATCH 18/41] apple: Nail down the EFI system partition Now that we have a way to find the appropriate EFI system partition on the internal NVMe storage, nail it down as the preferred EFI system partition such that we can use it to store EFI variables. This allows multiple OS installations to exist on Apple Silicon machines without interfering with eachother. Signed-off-by: Mark Kettenis --- arch/arm/mach-apple/board.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c index 7a71a57b249..bc563136b52 100644 --- a/arch/arm/mach-apple/board.c +++ b/arch/arm/mach-apple/board.c @@ -822,8 +822,12 @@ static char *asahi_esp_devpart(void) break; } - if (part > 0) + if (part > 0) { snprintf(devpart, sizeof(devpart), "%x:%x", devnum, part); + efi_system_partition.uclass_id = UCLASS_NVME; + efi_system_partition.devnum = devnum; + efi_system_partition.part = part; + } return devpart; } From c659e88a7024a51ce898e64fc53073d94ae55d9b Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Sun, 7 Apr 2024 10:04:19 +0200 Subject: [PATCH 19/41] efi_loader: prefer EFI system partition When booting from a block io device, prefer the EFI system partition over other partitions. Signed-off-by: Mark Kettenis --- lib/efi_loader/efi_bootmgr.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index a687f4d8e85..48ff5d80b29 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -315,6 +315,7 @@ static efi_status_t search_default_file(struct udevice *dev, static efi_status_t fill_default_file_path(struct udevice *blk, struct efi_device_path **dp) { + struct blk_desc *desc = dev_get_uclass_plat(blk); efi_status_t ret; struct udevice *partition; @@ -323,6 +324,26 @@ static efi_status_t fill_default_file_path(struct udevice *blk, if (ret == EFI_SUCCESS) return ret; + /* try EFI system partition */ + if (desc->uclass_id == efi_system_partition.uclass_id && + desc->devnum == efi_system_partition.devnum) { + device_foreach_child(partition, blk) { + struct disk_part *part; + enum uclass_id id; + + id = device_get_uclass_id(partition); + if (id != UCLASS_PARTITION) + continue; + + part = dev_get_uclass_plat(partition); + if (part->partnum == efi_system_partition.part) { + ret = search_default_file(partition, dp); + if (ret == EFI_SUCCESS) + return ret; + } + } + } + /* try the partitions */ device_foreach_child(partition, blk) { enum uclass_id id; From 02c4a3d0a32f108200856948a9566a4138879698 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Thu, 18 May 2023 20:11:04 +0900 Subject: [PATCH 20/41] usb: xhci: Add more debugging A bunch of miscellaneous debug messages to aid in working out USB issues. Signed-off-by: Hector Martin --- drivers/usb/host/xhci-ring.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 6f5c4ec97b6..55f69c89c8c 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -214,6 +214,9 @@ static dma_addr_t queue_trb(struct xhci_ctrl *ctrl, struct xhci_ring *ring, addr = xhci_trb_virt_to_dma(ring->enq_seg, (union xhci_trb *)trb); + debug("trb @ %llx: %08x %08x %08x %08x\n", addr, + trb_fields[0], trb_fields[1], trb_fields[2], trb_fields[3]); + inc_enq(ctrl, ring, more_trbs_coming); return addr; @@ -296,6 +299,8 @@ void xhci_queue_command(struct xhci_ctrl *ctrl, dma_addr_t addr, u32 slot_id, { u32 fields[4]; + debug("CMD: %llx 0x%x 0x%x %d\n", addr, slot_id, ep_index, cmd); + BUG_ON(prepare_ring(ctrl, ctrl->cmd_ring, EP_STATE_RUNNING)); fields[0] = lower_32_bits(addr); @@ -471,8 +476,14 @@ union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected) type = TRB_FIELD_TO_TYPE(le32_to_cpu(event->event_cmd.flags)); if (type == expected || - (expected == TRB_NONE && type != TRB_PORT_STATUS)) + (expected == TRB_NONE && type != TRB_PORT_STATUS)) { + debug("Event: %08x %08x %08x %08x\n", + le32_to_cpu(event->generic.field[0]), + le32_to_cpu(event->generic.field[1]), + le32_to_cpu(event->generic.field[2]), + le32_to_cpu(event->generic.field[3])); return event; + } if (type == TRB_PORT_STATUS) /* TODO: remove this once enumeration has been reworked */ @@ -484,8 +495,9 @@ union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected) le32_to_cpu(event->generic.field[2])) != COMP_SUCCESS); else - printf("Unexpected XHCI event TRB, skipping... " + printf("Unexpected XHCI event TRB, expected %d... " "(%08x %08x %08x %08x)\n", + expected, le32_to_cpu(event->generic.field[0]), le32_to_cpu(event->generic.field[1]), le32_to_cpu(event->generic.field[2]), @@ -596,10 +608,13 @@ static void abort_td(struct usb_device *udev, int ep_index) static void record_transfer_result(struct usb_device *udev, union xhci_trb *event, int length) { + xhci_comp_code code = GET_COMP_CODE( + le32_to_cpu(event->trans_event.transfer_len)); + udev->act_len = min(length, length - (int)EVENT_TRB_LEN(le32_to_cpu(event->trans_event.transfer_len))); - switch (GET_COMP_CODE(le32_to_cpu(event->trans_event.transfer_len))) { + switch (code) { case COMP_SUCCESS: BUG_ON(udev->act_len != length); /* fallthrough */ @@ -607,16 +622,23 @@ static void record_transfer_result(struct usb_device *udev, udev->status = 0; break; case COMP_STALL: + debug("Xfer STALL\n"); udev->status = USB_ST_STALLED; break; case COMP_DB_ERR: + debug("Xfer DB_ERR\n"); + udev->status = USB_ST_BUF_ERR; + break; case COMP_TRB_ERR: + debug("Xfer TRB_ERR\n"); udev->status = USB_ST_BUF_ERR; break; case COMP_BABBLE: + debug("Xfer BABBLE\n"); udev->status = USB_ST_BABBLE_DET; break; default: + debug("Xfer error: %d\n", code); udev->status = 0x80; /* USB_ST_TOO_LAZY_TO_MAKE_A_NEW_MACRO */ } } @@ -1017,6 +1039,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, record_transfer_result(udev, event, length); xhci_acknowledge_event(ctrl); if (udev->status == USB_ST_STALLED) { + debug("EP %d stalled\n", ep_index); reset_ep(udev, ep_index); return -EPIPE; } From 01382cc455b6fd9d8ae8bf3363523d9e6cebf61c Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Thu, 18 May 2023 20:40:52 +0900 Subject: [PATCH 21/41] usb: storage: Clear endpoint stalls properly I have no idea what usb_stor_BBB_clear_endpt_stall was intended to do, but it obviously can't work. When an endpoint stalls, the USB controller stops it and needs to be told to restart it, you can't just send a control message. Signed-off-by: Hector Martin --- common/usb_storage.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/common/usb_storage.c b/common/usb_storage.c index ac331f1c1b0..4f405775715 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -708,15 +708,6 @@ static int usb_stor_CBI_get_status(struct scsi_cmd *srb, struct us_data *us) #define USB_TRANSPORT_UNKNOWN_RETRY 5 #define USB_TRANSPORT_NOT_READY_RETRY 10 -/* clear a stall on an endpoint - special for BBB devices */ -static int usb_stor_BBB_clear_endpt_stall(struct us_data *us, __u8 endpt) -{ - /* ENDPOINT_HALT = 0, so set value to 0 */ - return usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev, 0), - USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, - endpt, NULL, 0, USB_CNTL_TIMEOUT * 5); -} - static int usb_stor_BBB_transport(struct scsi_cmd *srb, struct us_data *us) { int result, retry; @@ -761,8 +752,7 @@ static int usb_stor_BBB_transport(struct scsi_cmd *srb, struct us_data *us) if ((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) { debug("DATA:stall\n"); /* clear the STALL on the endpoint */ - result = usb_stor_BBB_clear_endpt_stall(us, - dir_in ? us->ep_in : us->ep_out); + result = usb_clear_halt(us->pusb_dev, pipe); if (result >= 0) /* continue on to STATUS phase */ goto st; @@ -791,7 +781,7 @@ static int usb_stor_BBB_transport(struct scsi_cmd *srb, struct us_data *us) (us->pusb_dev->status & USB_ST_STALLED)) { debug("STATUS:stall\n"); /* clear the STALL on the endpoint */ - result = usb_stor_BBB_clear_endpt_stall(us, us->ep_in); + result = usb_clear_halt(us->pusb_dev, pipein); if (result >= 0 && (retry++ < 1)) /* do a retry */ goto again; From ce24899757a20a0cd1d0337527bf0b5916b4be3c Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Thu, 18 May 2023 23:07:18 +0900 Subject: [PATCH 22/41] usb: Pass through timeout to drivers The old USB code was interrupt-driven and just polled at the top level. This has been obsolete since interrupts were removed, which means the timeout support has been completely broken. Rip out the top-level polling and just pass through the timeout parameter to host controller drivers. Right now this is ignored in the individual drivers. Signed-off-by: Hector Martin --- common/usb.c | 21 ++------------------- drivers/usb/emul/sandbox_flash.c | 5 +++-- drivers/usb/emul/sandbox_hub.c | 2 +- drivers/usb/emul/sandbox_keyb.c | 2 +- drivers/usb/emul/usb-emul-uclass.c | 10 +++++----- drivers/usb/host/dwc2.c | 5 +++-- drivers/usb/host/ehci-hcd.c | 5 +++-- drivers/usb/host/ohci-hcd.c | 5 +++-- drivers/usb/host/r8a66597-hcd.c | 5 +++-- drivers/usb/host/usb-sandbox.c | 10 ++++++---- drivers/usb/host/usb-uclass.c | 9 +++++---- drivers/usb/host/xhci.c | 5 +++-- drivers/usb/isp1760/isp1760-uboot.c | 6 ++++-- drivers/usb/musb-new/musb_uboot.c | 5 +++-- include/usb.h | 14 ++++++++------ 15 files changed, 53 insertions(+), 56 deletions(-) diff --git a/common/usb.c b/common/usb.c index 6a4ad346f4b..b9ecf2a3353 100644 --- a/common/usb.c +++ b/common/usb.c @@ -242,22 +242,10 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, request, requesttype, value, index, size); dev->status = USB_ST_NOT_PROC; /*not yet processed */ - err = submit_control_msg(dev, pipe, data, size, setup_packet); + err = submit_control_msg(dev, pipe, data, size, setup_packet, timeout); if (err < 0) return err; - if (timeout == 0) - return (int)size; - /* - * Wait for status to update until timeout expires, USB driver - * interrupt handler may set the status when the USB operation has - * been completed. - */ - while (timeout--) { - if (!((volatile unsigned long)dev->status & USB_ST_NOT_PROC)) - break; - mdelay(1); - } if (timeout == 0) return -ETIMEDOUT; @@ -279,13 +267,8 @@ int usb_bulk_msg(struct usb_device *dev, unsigned int pipe, if (len < 0) return -EINVAL; dev->status = USB_ST_NOT_PROC; /*not yet processed */ - if (submit_bulk_msg(dev, pipe, data, len) < 0) + if (submit_bulk_msg(dev, pipe, data, len, timeout) < 0) return -EIO; - while (timeout--) { - if (!((volatile unsigned long)dev->status & USB_ST_NOT_PROC)) - break; - mdelay(1); - } *actual_length = dev->act_len; if (dev->status == 0) return 0; diff --git a/drivers/usb/emul/sandbox_flash.c b/drivers/usb/emul/sandbox_flash.c index b5176bb30ce..485133b0213 100644 --- a/drivers/usb/emul/sandbox_flash.c +++ b/drivers/usb/emul/sandbox_flash.c @@ -132,7 +132,7 @@ static void *flash_desc_list[] = { static int sandbox_flash_control(struct udevice *dev, struct usb_device *udev, unsigned long pipe, void *buff, int len, - struct devrequest *setup) + struct devrequest *setup, int timeout) { struct sandbox_flash_priv *priv = dev_get_priv(dev); @@ -208,7 +208,8 @@ static int handle_ufi_command(struct sandbox_flash_priv *priv, const void *buff, } static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev, - unsigned long pipe, void *buff, int len) + unsigned long pipe, void *buff, int len, + int timeout) { struct sandbox_flash_priv *priv = dev_get_priv(dev); struct scsi_emul_info *info = &priv->eminfo; diff --git a/drivers/usb/emul/sandbox_hub.c b/drivers/usb/emul/sandbox_hub.c index 3b3e59f978f..9a46944e071 100644 --- a/drivers/usb/emul/sandbox_hub.c +++ b/drivers/usb/emul/sandbox_hub.c @@ -202,7 +202,7 @@ static int sandbox_hub_submit_control_msg(struct udevice *bus, struct usb_device *udev, unsigned long pipe, void *buffer, int length, - struct devrequest *setup) + struct devrequest *setup, int timeout) { struct sandbox_hub_priv *priv = dev_get_priv(bus); int ret = 0; diff --git a/drivers/usb/emul/sandbox_keyb.c b/drivers/usb/emul/sandbox_keyb.c index 5ed8c2c799a..e03ca231055 100644 --- a/drivers/usb/emul/sandbox_keyb.c +++ b/drivers/usb/emul/sandbox_keyb.c @@ -176,7 +176,7 @@ int sandbox_usb_keyb_add_string(struct udevice *dev, static int sandbox_keyb_control(struct udevice *dev, struct usb_device *udev, unsigned long pipe, void *buff, int len, - struct devrequest *setup) + struct devrequest *setup, int timeout) { debug("pipe=%lx\n", pipe); diff --git a/drivers/usb/emul/usb-emul-uclass.c b/drivers/usb/emul/usb-emul-uclass.c index cdc18d6cbb9..f24facfc30c 100644 --- a/drivers/usb/emul/usb-emul-uclass.c +++ b/drivers/usb/emul/usb-emul-uclass.c @@ -176,7 +176,7 @@ int usb_emul_find_for_dev(struct udevice *dev, struct udevice **emulp) int usb_emul_control(struct udevice *emul, struct usb_device *udev, unsigned long pipe, void *buffer, int length, - struct devrequest *setup) + struct devrequest *setup, int timeout) { struct dm_usb_ops *ops = usb_get_emul_ops(emul); struct usb_dev_plat *plat; @@ -198,7 +198,7 @@ int usb_emul_control(struct udevice *emul, struct usb_device *udev, if (ret) return ret; return ops->control(emul, udev, pipe, buffer, length, - setup); + setup, timeout); } } else if (pipe == usb_snddefctrl(udev)) { switch (setup->request) { @@ -221,7 +221,7 @@ int usb_emul_control(struct udevice *emul, struct usb_device *udev, if (ret) return ret; return ops->control(emul, udev, pipe, buffer, length, - setup); + setup, timeout); } } debug("pipe=%lx\n", pipe); @@ -230,7 +230,7 @@ int usb_emul_control(struct udevice *emul, struct usb_device *udev, } int usb_emul_bulk(struct udevice *emul, struct usb_device *udev, - unsigned long pipe, void *buffer, int length) + unsigned long pipe, void *buffer, int length, int timeout) { struct dm_usb_ops *ops = usb_get_emul_ops(emul); int ret; @@ -242,7 +242,7 @@ int usb_emul_bulk(struct udevice *emul, struct usb_device *udev, ret = device_probe(emul); if (ret) return ret; - return ops->bulk(emul, udev, pipe, buffer, length); + return ops->bulk(emul, udev, pipe, buffer, length, timeout); } int usb_emul_int(struct udevice *emul, struct usb_device *udev, diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c index 16f21fa9083..85b54313438 100644 --- a/drivers/usb/host/dwc2.c +++ b/drivers/usb/host/dwc2.c @@ -1196,7 +1196,7 @@ int usb_lowlevel_stop(int index) #if CONFIG_IS_ENABLED(DM_USB) static int dwc2_submit_control_msg(struct udevice *dev, struct usb_device *udev, unsigned long pipe, void *buffer, int length, - struct devrequest *setup) + struct devrequest *setup, int timeout) { struct dwc2_priv *priv = dev_get_priv(dev); @@ -1207,7 +1207,8 @@ static int dwc2_submit_control_msg(struct udevice *dev, struct usb_device *udev, } static int dwc2_submit_bulk_msg(struct udevice *dev, struct usb_device *udev, - unsigned long pipe, void *buffer, int length) + unsigned long pipe, void *buffer, int length, + int timeout) { struct dwc2_priv *priv = dev_get_priv(dev); diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 7d5519c65a9..0674d49aa1c 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1626,7 +1626,7 @@ int usb_lock_async(struct usb_device *dev, int lock) #if CONFIG_IS_ENABLED(DM_USB) static int ehci_submit_control_msg(struct udevice *dev, struct usb_device *udev, unsigned long pipe, void *buffer, int length, - struct devrequest *setup) + struct devrequest *setup, int timeout) { debug("%s: dev='%s', udev=%p, udev->dev='%s', portnr=%d\n", __func__, dev->name, udev, udev->dev->name, udev->portnr); @@ -1635,7 +1635,8 @@ static int ehci_submit_control_msg(struct udevice *dev, struct usb_device *udev, } static int ehci_submit_bulk_msg(struct udevice *dev, struct usb_device *udev, - unsigned long pipe, void *buffer, int length) + unsigned long pipe, void *buffer, int length, + int timeout) { debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev); return _ehci_submit_bulk_msg(udev, pipe, buffer, length); diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 1d6711ccec4..b435e8887d7 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -2050,7 +2050,7 @@ int submit_control_msg(struct usb_device *dev, unsigned long pipe, #if CONFIG_IS_ENABLED(DM_USB) static int ohci_submit_control_msg(struct udevice *dev, struct usb_device *udev, unsigned long pipe, void *buffer, int length, - struct devrequest *setup) + struct devrequest *setup, int timeout) { ohci_t *ohci = dev_get_priv(usb_get_bus(dev)); @@ -2059,7 +2059,8 @@ static int ohci_submit_control_msg(struct udevice *dev, struct usb_device *udev, } static int ohci_submit_bulk_msg(struct udevice *dev, struct usb_device *udev, - unsigned long pipe, void *buffer, int length) + unsigned long pipe, void *buffer, int length, + int timeout) { ohci_t *ohci = dev_get_priv(usb_get_bus(dev)); diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index f0b18bffba4..45b08317972 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -704,7 +704,8 @@ static int r8a66597_submit_rh_msg(struct udevice *udev, struct usb_device *dev, static int r8a66597_submit_control_msg(struct udevice *udev, struct usb_device *dev, unsigned long pipe, void *buffer, - int length, struct devrequest *setup) + int length, struct devrequest *setup, + int timeout) { struct r8a66597 *r8a66597 = dev_get_priv(udev); u16 r8a66597_address = setup->request == USB_REQ_SET_ADDRESS ? @@ -742,7 +743,7 @@ static int r8a66597_submit_control_msg(struct udevice *udev, static int r8a66597_submit_bulk_msg(struct udevice *udev, struct usb_device *dev, unsigned long pipe, - void *buffer, int length) + void *buffer, int length, int timeout) { struct r8a66597 *r8a66597 = dev_get_priv(udev); int ret = 0; diff --git a/drivers/usb/host/usb-sandbox.c b/drivers/usb/host/usb-sandbox.c index f687fe2c430..e9e2a9ed674 100644 --- a/drivers/usb/host/usb-sandbox.c +++ b/drivers/usb/host/usb-sandbox.c @@ -46,7 +46,8 @@ static int sandbox_submit_control(struct udevice *bus, struct usb_device *udev, unsigned long pipe, void *buffer, int length, - struct devrequest *setup) + struct devrequest *setup, + int timeout) { struct sandbox_usb_ctrl *ctrl = dev_get_priv(bus); struct udevice *emul; @@ -66,7 +67,7 @@ static int sandbox_submit_control(struct udevice *bus, } } - ret = usb_emul_control(emul, udev, pipe, buffer, length, setup); + ret = usb_emul_control(emul, udev, pipe, buffer, length, setup, timeout); if (ret < 0) { debug("ret=%d\n", ret); udev->status = ret; @@ -80,7 +81,8 @@ static int sandbox_submit_control(struct udevice *bus, } static int sandbox_submit_bulk(struct udevice *bus, struct usb_device *udev, - unsigned long pipe, void *buffer, int length) + unsigned long pipe, void *buffer, int length, + int timeout) { struct udevice *emul; int ret; @@ -91,7 +93,7 @@ static int sandbox_submit_bulk(struct udevice *bus, struct usb_device *udev, usbmon_trace(bus, pipe, NULL, emul); if (ret) return ret; - ret = usb_emul_bulk(emul, udev, pipe, buffer, length); + ret = usb_emul_bulk(emul, udev, pipe, buffer, length, timeout); if (ret < 0) { debug("ret=%d\n", ret); udev->status = ret; diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c index 7247245a702..d1c699fe60f 100644 --- a/drivers/usb/host/usb-uclass.c +++ b/drivers/usb/host/usb-uclass.c @@ -59,7 +59,8 @@ int submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer, } int submit_control_msg(struct usb_device *udev, unsigned long pipe, - void *buffer, int length, struct devrequest *setup) + void *buffer, int length, struct devrequest *setup, + int timeout) { struct udevice *bus = udev->controller_dev; struct dm_usb_ops *ops = usb_get_ops(bus); @@ -69,7 +70,7 @@ int submit_control_msg(struct usb_device *udev, unsigned long pipe, if (!ops->control) return -ENOSYS; - err = ops->control(bus, udev, pipe, buffer, length, setup); + err = ops->control(bus, udev, pipe, buffer, length, setup, timeout); if (setup->request == USB_REQ_SET_FEATURE && setup->requesttype == USB_RT_PORT && setup->value == cpu_to_le16(USB_PORT_FEAT_RESET) && @@ -82,7 +83,7 @@ int submit_control_msg(struct usb_device *udev, unsigned long pipe, } int submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer, - int length) + int length, int timeout) { struct udevice *bus = udev->controller_dev; struct dm_usb_ops *ops = usb_get_ops(bus); @@ -90,7 +91,7 @@ int submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer, if (!ops->bulk) return -ENOSYS; - return ops->bulk(bus, udev, pipe, buffer, length); + return ops->bulk(bus, udev, pipe, buffer, length, timeout); } struct int_queue *create_int_queue(struct usb_device *udev, diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index c3986dac3e8..957b483849e 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1295,7 +1295,7 @@ static int xhci_lowlevel_stop(struct xhci_ctrl *ctrl) static int xhci_submit_control_msg(struct udevice *dev, struct usb_device *udev, unsigned long pipe, void *buffer, int length, - struct devrequest *setup) + struct devrequest *setup, int timeout) { struct usb_device *uhop; struct udevice *hub; @@ -1327,7 +1327,8 @@ static int xhci_submit_control_msg(struct udevice *dev, struct usb_device *udev, } static int xhci_submit_bulk_msg(struct udevice *dev, struct usb_device *udev, - unsigned long pipe, void *buffer, int length) + unsigned long pipe, void *buffer, int length, + int timeout) { debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev); return _xhci_submit_bulk_msg(udev, pipe, buffer, length); diff --git a/drivers/usb/isp1760/isp1760-uboot.c b/drivers/usb/isp1760/isp1760-uboot.c index 8dcb7768a2c..f36e5027fcc 100644 --- a/drivers/usb/isp1760/isp1760-uboot.c +++ b/drivers/usb/isp1760/isp1760-uboot.c @@ -27,7 +27,8 @@ static int isp1760_msg_submit_control(struct udevice *dev, struct usb_device *udev, unsigned long pipe, void *buffer, - int length, struct devrequest *setup) + int length, struct devrequest *setup, + int timeout) { struct isp1760_host_data *host = dev_get_priv(dev); @@ -37,7 +38,8 @@ static int isp1760_msg_submit_control(struct udevice *dev, } static int isp1760_msg_submit_bulk(struct udevice *dev, struct usb_device *udev, - unsigned long pipe, void *buffer, int length) + unsigned long pipe, void *buffer, int length, + int timeout) { struct isp1760_host_data *host = dev_get_priv(dev); diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c index 43ab3245e5c..37600256e70 100644 --- a/drivers/usb/musb-new/musb_uboot.c +++ b/drivers/usb/musb-new/musb_uboot.c @@ -309,14 +309,15 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) #if CONFIG_IS_ENABLED(DM_USB) static int musb_submit_control_msg(struct udevice *dev, struct usb_device *udev, unsigned long pipe, void *buffer, int length, - struct devrequest *setup) + struct devrequest *setup, int timeout) { struct musb_host_data *host = dev_get_priv(dev); return _musb_submit_control_msg(host, udev, pipe, buffer, length, setup); } static int musb_submit_bulk_msg(struct udevice *dev, struct usb_device *udev, - unsigned long pipe, void *buffer, int length) + unsigned long pipe, void *buffer, int length, + int timeout) { struct musb_host_data *host = dev_get_priv(dev); return _musb_submit_bulk_msg(host, udev, pipe, buffer, length); diff --git a/include/usb.h b/include/usb.h index be37ed272e1..a0e13f711cb 100644 --- a/include/usb.h +++ b/include/usb.h @@ -190,9 +190,10 @@ int usb_reset_root_port(struct usb_device *dev); #endif int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, - void *buffer, int transfer_len); + void *buffer, int transfer_len, int timeout); int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, struct devrequest *setup); + int transfer_len, struct devrequest *setup, + int timeout); int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int transfer_len, int interval, bool nonblock); @@ -705,14 +706,15 @@ struct dm_usb_ops { */ int (*control)(struct udevice *bus, struct usb_device *udev, unsigned long pipe, void *buffer, int length, - struct devrequest *setup); + struct devrequest *setup, int timeout); /** * bulk() - Send a bulk message * * Parameters are as above. */ int (*bulk)(struct udevice *bus, struct usb_device *udev, - unsigned long pipe, void *buffer, int length); + unsigned long pipe, void *buffer, int length, + int timeout); /** * interrupt() - Send an interrupt message * @@ -1025,7 +1027,7 @@ int usb_emul_setup_device(struct udevice *dev, struct usb_string *strings, */ int usb_emul_control(struct udevice *emul, struct usb_device *udev, unsigned long pipe, void *buffer, int length, - struct devrequest *setup); + struct devrequest *setup, int timeout); /** * usb_emul_bulk() - Send a bulk packet to an emulator @@ -1036,7 +1038,7 @@ int usb_emul_control(struct udevice *emul, struct usb_device *udev, * Return: 0 if OK, -ve on error */ int usb_emul_bulk(struct udevice *emul, struct usb_device *udev, - unsigned long pipe, void *buffer, int length); + unsigned long pipe, void *buffer, int length, int timeout); /** * usb_emul_int() - Send an interrupt packet to an emulator From ba71e64f6f9619c7e896da94d7aeb4d9dfcad2eb Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Thu, 18 May 2023 23:18:08 +0900 Subject: [PATCH 23/41] usb: xhci: Hook up timeouts Now that the USB core passes through timeout info to the host controller, actually hook it up. Signed-off-by: Hector Martin --- drivers/usb/host/xhci-ring.c | 32 ++++++++++++++++++++------------ drivers/usb/host/xhci.c | 23 +++++++++++++---------- include/usb/xhci.h | 14 ++++++++++---- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 55f69c89c8c..d4cd12401d9 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -463,11 +463,16 @@ static int event_ready(struct xhci_ctrl *ctrl) * @param expected TRB type expected from Event TRB * Return: pointer to event trb */ -union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected) +union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected, + int timeout) { trb_type type; unsigned long ts = get_timer(0); + /* Fallback in case someone passes in 0 */ + if (!timeout) + timeout = XHCI_TIMEOUT; + do { union xhci_trb *event = ctrl->event_ring->dequeue; @@ -504,7 +509,7 @@ union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected) le32_to_cpu(event->generic.field[3])); xhci_acknowledge_event(ctrl); - } while (get_timer(ts) < XHCI_TIMEOUT); + } while (get_timer(ts) < timeout); if (expected == TRB_TRANSFER) return NULL; @@ -528,7 +533,7 @@ static void reset_ep(struct usb_device *udev, int ep_index) printf("Resetting EP %d...\n", ep_index); xhci_queue_command(ctrl, 0, udev->slot_id, ep_index, TRB_RESET_EP); - event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + event = xhci_wait_for_event(ctrl, TRB_COMPLETION, XHCI_SYS_TIMEOUT); if (!event) return; @@ -538,7 +543,7 @@ static void reset_ep(struct usb_device *udev, int ep_index) addr = xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue) | ring->cycle_state; xhci_queue_command(ctrl, addr, udev->slot_id, ep_index, TRB_SET_DEQ); - event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + event = xhci_wait_for_event(ctrl, TRB_COMPLETION, XHCI_SYS_TIMEOUT); if (!event) return; @@ -567,7 +572,7 @@ static void abort_td(struct usb_device *udev, int ep_index) xhci_queue_command(ctrl, 0, udev->slot_id, ep_index, TRB_STOP_RING); - event = xhci_wait_for_event(ctrl, TRB_NONE); + event = xhci_wait_for_event(ctrl, TRB_NONE, XHCI_SYS_TIMEOUT); if (!event) return; @@ -579,7 +584,8 @@ static void abort_td(struct usb_device *udev, int ep_index) BUG_ON(GET_COMP_CODE(le32_to_cpu(event->trans_event.transfer_len != COMP_STOP))); xhci_acknowledge_event(ctrl); - event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + event = xhci_wait_for_event(ctrl, TRB_COMPLETION, + XHCI_SYS_TIMEOUT); if (!event) return; type = TRB_FIELD_TO_TYPE(le32_to_cpu(event->event_cmd.flags)); @@ -596,7 +602,7 @@ static void abort_td(struct usb_device *udev, int ep_index) addr = xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue) | ring->cycle_state; xhci_queue_command(ctrl, addr, udev->slot_id, ep_index, TRB_SET_DEQ); - event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + event = xhci_wait_for_event(ctrl, TRB_COMPLETION, XHCI_SYS_TIMEOUT); if (!event) return; @@ -651,10 +657,11 @@ static void record_transfer_result(struct usb_device *udev, * @param pipe contains the DIR_IN or OUT , devnum * @param length length of the buffer * @param buffer buffer to be read/written based on the request + * @param timeout timeout in milliseconds * Return: returns 0 if successful else -1 on failure */ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, - int length, void *buffer) + int length, void *buffer, int timeout) { int num_trbs = 0; struct xhci_generic_trb *start_trb; @@ -824,7 +831,7 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, giveback_first_trb(udev, ep_index, start_cycle, start_trb); again: - event = xhci_wait_for_event(ctrl, TRB_TRANSFER); + event = xhci_wait_for_event(ctrl, TRB_TRANSFER, timeout); if (!event) { debug("XHCI bulk transfer timed out, aborting...\n"); abort_td(udev, ep_index); @@ -861,11 +868,12 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, * @param req request type * @param length length of the buffer * @param buffer buffer to be read/written based on the request + * @param timeout timeout in milliseconds * Return: returns 0 if successful else error code on failure */ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, struct devrequest *req, int length, - void *buffer) + void *buffer, int timeout) { int ret; int start_cycle; @@ -1028,7 +1036,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, giveback_first_trb(udev, ep_index, start_cycle, start_trb); - event = xhci_wait_for_event(ctrl, TRB_TRANSFER); + event = xhci_wait_for_event(ctrl, TRB_TRANSFER, timeout); if (!event) goto abort; field = le32_to_cpu(event->trans_event.flags); @@ -1053,7 +1061,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, if (GET_COMP_CODE(le32_to_cpu(event->trans_event.transfer_len)) == COMP_SHORT_TX) { /* Short data stage, clear up additional status stage event */ - event = xhci_wait_for_event(ctrl, TRB_TRANSFER); + event = xhci_wait_for_event(ctrl, TRB_TRANSFER, XHCI_SYS_TIMEOUT); if (!event) goto abort; BUG_ON(TRB_TO_SLOT_ID(field) != slot_id); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 957b483849e..9dd8ca81ec8 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -449,7 +449,7 @@ static int xhci_configure_endpoints(struct usb_device *udev, bool ctx_change) xhci_flush_cache((uintptr_t)in_ctx->bytes, in_ctx->size); xhci_queue_command(ctrl, in_ctx->dma, udev->slot_id, 0, ctx_change ? TRB_EVAL_CONTEXT : TRB_CONFIG_EP); - event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + event = xhci_wait_for_event(ctrl, TRB_COMPLETION, XHCI_SYS_TIMEOUT); if (!event) return -ETIMEDOUT; @@ -682,7 +682,7 @@ static int xhci_address_device(struct usb_device *udev, int root_portnr) xhci_queue_command(ctrl, virt_dev->in_ctx->dma, slot_id, 0, TRB_ADDR_DEV); - event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + event = xhci_wait_for_event(ctrl, TRB_COMPLETION, XHCI_SYS_TIMEOUT); if (!event) return -ETIMEDOUT; @@ -760,7 +760,7 @@ static int _xhci_alloc_device(struct usb_device *udev) } xhci_queue_command(ctrl, 0, 0, 0, TRB_ENABLE_SLOT); - event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + event = xhci_wait_for_event(ctrl, TRB_COMPLETION, XHCI_SYS_TIMEOUT); if (!event) return -ETIMEDOUT; @@ -1158,7 +1158,7 @@ static int _xhci_submit_int_msg(struct usb_device *udev, unsigned long pipe, * (at most) one TD. A TD (comprised of sg list entries) can * take several service intervals to transmit. */ - return xhci_bulk_tx(udev, pipe, length, buffer); + return xhci_bulk_tx(udev, pipe, length, buffer, XHCI_INT_TIMEOUT); } /** @@ -1168,17 +1168,18 @@ static int _xhci_submit_int_msg(struct usb_device *udev, unsigned long pipe, * @param pipe contains the DIR_IN or OUT , devnum * @param buffer buffer to be read/written based on the request * @param length length of the buffer + * @param timeout timeout in milliseconds * Return: returns 0 if successful else -1 on failure */ static int _xhci_submit_bulk_msg(struct usb_device *udev, unsigned long pipe, - void *buffer, int length) + void *buffer, int length, int timeout) { if (usb_pipetype(pipe) != PIPE_BULK) { printf("non-bulk pipe (type=%lu)", usb_pipetype(pipe)); return -EINVAL; } - return xhci_bulk_tx(udev, pipe, length, buffer); + return xhci_bulk_tx(udev, pipe, length, buffer, timeout); } /** @@ -1190,11 +1191,13 @@ static int _xhci_submit_bulk_msg(struct usb_device *udev, unsigned long pipe, * @param length length of the buffer * @param setup Request type * @param root_portnr Root port number that this device is on + * @param timeout timeout in milliseconds * Return: returns 0 if successful else -1 on failure */ static int _xhci_submit_control_msg(struct usb_device *udev, unsigned long pipe, void *buffer, int length, - struct devrequest *setup, int root_portnr) + struct devrequest *setup, int root_portnr, + int timeout) { struct xhci_ctrl *ctrl = xhci_get_ctrl(udev); int ret = 0; @@ -1220,7 +1223,7 @@ static int _xhci_submit_control_msg(struct usb_device *udev, unsigned long pipe, } } - return xhci_ctrl_tx(udev, pipe, setup, length, buffer); + return xhci_ctrl_tx(udev, pipe, setup, length, buffer, timeout); } static int xhci_lowlevel_init(struct xhci_ctrl *ctrl) @@ -1323,7 +1326,7 @@ static int xhci_submit_control_msg(struct udevice *dev, struct usb_device *udev, hop = hop->parent; */ return _xhci_submit_control_msg(udev, pipe, buffer, length, setup, - root_portnr); + root_portnr, timeout); } static int xhci_submit_bulk_msg(struct udevice *dev, struct usb_device *udev, @@ -1331,7 +1334,7 @@ static int xhci_submit_bulk_msg(struct udevice *dev, struct usb_device *udev, int timeout) { debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev); - return _xhci_submit_bulk_msg(udev, pipe, buffer, length); + return _xhci_submit_bulk_msg(udev, pipe, buffer, length, timeout); } static int xhci_submit_int_msg(struct udevice *dev, struct usb_device *udev, diff --git a/include/usb/xhci.h b/include/usb/xhci.h index 14de983b152..dfbb68757bd 100644 --- a/include/usb/xhci.h +++ b/include/usb/xhci.h @@ -27,7 +27,11 @@ #define MAX_EP_CTX_NUM 31 #define XHCI_ALIGNMENT 64 /* Generic timeout for XHCI events */ -#define XHCI_TIMEOUT 5000 +#define XHCI_TIMEOUT 1000 +/* Timeout for interrupt messages */ +#define XHCI_INT_TIMEOUT 1000 +/* Timeout for system commands */ +#define XHCI_SYS_TIMEOUT 200 /* Max number of USB devices for any host controller - limit in section 6.1 */ #define MAX_HC_SLOTS 256 /* Section 5.3.3 - MaxPorts */ @@ -1252,11 +1256,13 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, void xhci_queue_command(struct xhci_ctrl *ctrl, dma_addr_t addr, u32 slot_id, u32 ep_index, trb_type cmd); void xhci_acknowledge_event(struct xhci_ctrl *ctrl); -union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected); +union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected, + int timeout); int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, - int length, void *buffer); + int length, void *buffer, int timeout); int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, - struct devrequest *req, int length, void *buffer); + struct devrequest *req, int length, void *buffer, + int timeout); int xhci_check_maxpacket(struct usb_device *udev); void xhci_flush_cache(uintptr_t addr, u32 type_len); void xhci_inval_cache(uintptr_t addr, u32 type_len); From 2c343e36671511c04683602db6f8f30200ccf7d2 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Thu, 18 May 2023 23:39:32 +0900 Subject: [PATCH 24/41] scsi: Fix a bunch of SCSI definitions. 0x9e isn't Read Capacity, it's a service action and the read capacity command is a subcommand. READ16 is not 0x48, it's 0x88. 0x48 is SANITIZE and that sounds like we might have been destroying data instead of reading data. No bueno. Signed-off-by: Hector Martin --- drivers/ata/ahci.c | 9 ++++++--- drivers/scsi/scsi.c | 4 ++-- include/scsi.h | 8 ++++++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 38e953ee79c..242262de924 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -823,9 +823,6 @@ static int ahci_scsi_exec(struct udevice *dev, struct scsi_cmd *pccb) case SCSI_RD_CAPAC10: ret = ata_scsiop_read_capacity10(uc_priv, pccb); break; - case SCSI_RD_CAPAC16: - ret = ata_scsiop_read_capacity16(uc_priv, pccb); - break; case SCSI_TST_U_RDY: ret = ata_scsiop_test_unit_ready(uc_priv, pccb); break; @@ -835,6 +832,12 @@ static int ahci_scsi_exec(struct udevice *dev, struct scsi_cmd *pccb) case SCSI_SYNC_CACHE: ret = ata_io_flush(uc_priv, pccb->target); break; + case SCSI_SRV_ACTION_IN: + if ((pccb->cmd[1] & 0x1f) == SCSI_SAI_RD_CAPAC16) { + ret = ata_scsiop_read_capacity16(uc_priv, pccb); + break; + } + /* Fallthrough */ default: printf("Unsupport SCSI command 0x%02x\n", pccb->cmd[0]); return -ENOTSUPP; diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 8fe6b38a8c7..a5f8b4064c0 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -424,8 +424,8 @@ static int scsi_read_capacity(struct udevice *dev, struct scsi_cmd *pccb, /* Read capacity (10) was insufficient. Use read capacity (16). */ memset(pccb->cmd, '\0', sizeof(pccb->cmd)); - pccb->cmd[0] = SCSI_RD_CAPAC16; - pccb->cmd[1] = 0x10; + pccb->cmd[0] = SCSI_SRV_ACTION_IN; + pccb->cmd[1] = SCSI_SAI_RD_CAPAC16; pccb->cmdlen = 16; pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */ diff --git a/include/scsi.h b/include/scsi.h index 8d6c5116419..e304b2d9098 100644 --- a/include/scsi.h +++ b/include/scsi.h @@ -157,10 +157,9 @@ struct scsi_cmd { #define SCSI_MED_REMOVL 0x1E /* Prevent/Allow medium Removal (O) */ #define SCSI_READ6 0x08 /* Read 6-byte (MANDATORY) */ #define SCSI_READ10 0x28 /* Read 10-byte (MANDATORY) */ -#define SCSI_READ16 0x48 +#define SCSI_READ16 0x88 /* Read 16-byte */ #define SCSI_RD_CAPAC 0x25 /* Read Capacity (MANDATORY) */ #define SCSI_RD_CAPAC10 SCSI_RD_CAPAC /* Read Capacity (10) */ -#define SCSI_RD_CAPAC16 0x9e /* Read Capacity (16) */ #define SCSI_RD_DEFECT 0x37 /* Read Defect Data (O) */ #define SCSI_READ_LONG 0x3E /* Read Long (O) */ #define SCSI_REASS_BLK 0x07 /* Reassign Blocks (O) */ @@ -174,16 +173,21 @@ struct scsi_cmd { #define SCSI_SEEK10 0x2B /* Seek 10-Byte (O) */ #define SCSI_SEND_DIAG 0x1D /* Send Diagnostics (MANDATORY) */ #define SCSI_SET_LIMIT 0x33 /* Set Limits (O) */ +#define SCSI_SRV_ACTION_IN 0x9E /* Service Action In */ +#define SCSI_SRV_ACTION_OUT 0x9F /* Service Action Out */ #define SCSI_START_STP 0x1B /* Start/Stop Unit (O) */ #define SCSI_SYNC_CACHE 0x35 /* Synchronize Cache (O) */ #define SCSI_VERIFY 0x2F /* Verify (O) */ #define SCSI_WRITE6 0x0A /* Write 6-Byte (MANDATORY) */ #define SCSI_WRITE10 0x2A /* Write 10-Byte (MANDATORY) */ +#define SCSI_WRITE16 0x8A /* Write 16-byte */ #define SCSI_WRT_VERIFY 0x2E /* Write and Verify (O) */ #define SCSI_WRITE_LONG 0x3F /* Write Long (O) */ #define SCSI_WRITE_SAME 0x41 /* Write Same (O) */ #define SCSI_UNMAP 0x42 /* Write 10-Byte (MANDATORY) */ +#define SCSI_SAI_RD_CAPAC16 0x10 /* Service Action: Read Capacity (16) */ + /** * enum scsi_cmd_phase - current phase of the SCSI protocol * From b85792fb5982acb1c6e8894fb23cce8e3b85d8d4 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Thu, 18 May 2023 23:23:13 +0900 Subject: [PATCH 25/41] usb: storage: Increase read/write timeout Some USB devices (like hard disks) can take a long time to initially respond to read/write requests. Explicitly specify a much longer timeout than normal. Signed-off-by: Hector Martin --- common/usb_storage.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/common/usb_storage.c b/common/usb_storage.c index 4f405775715..0a26c112c30 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -52,6 +52,12 @@ #undef BBB_COMDAT_TRACE #undef BBB_XPORT_TRACE +/* + * Timeout for read/write transfers. This needs to be able to handle very slow + * devices, such as hard disks that are spinning up. + */ +#define US_XFER_TIMEOUT 15000 + #include /* direction table -- this indicates the direction of the data * transfer for each command code -- a 1 indicates input @@ -408,7 +414,7 @@ static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length) 11 - maxtry); result = usb_bulk_msg(us->pusb_dev, pipe, buf, this_xfer, &partial, - USB_CNTL_TIMEOUT * 5); + US_XFER_TIMEOUT); debug("bulk_msg returned %d xferred %d/%d\n", result, partial, this_xfer); if (us->pusb_dev->status != 0) { @@ -747,7 +753,7 @@ static int usb_stor_BBB_transport(struct scsi_cmd *srb, struct us_data *us) pipe = pipeout; result = usb_bulk_msg(us->pusb_dev, pipe, srb->pdata, srb->datalen, - &data_actlen, USB_CNTL_TIMEOUT * 5); + &data_actlen, US_XFER_TIMEOUT); /* special handling of STALL in DATA phase */ if ((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) { debug("DATA:stall\n"); From a68d8fb458b62c0ce10fc5dfc514f81eaf3672a9 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Thu, 18 May 2023 23:26:00 +0900 Subject: [PATCH 26/41] usb: storage: Implement 64-bit LBA support This makes things work properly on devices with >= 2 TiB capacity. If u-boot is built without CONFIG_SYS_64BIT_LBA, the capacity will be clamped at 2^32 - 1 sectors. Signed-off-by: Hector Martin --- common/usb_storage.c | 134 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 115 insertions(+), 19 deletions(-) diff --git a/common/usb_storage.c b/common/usb_storage.c index 0a26c112c30..97bf413bf77 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -65,7 +65,7 @@ static const unsigned char us_direction[256/8] = { 0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77, 0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, + 0x00, 0x01, 0x00, 0x40, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; #define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1) @@ -1075,6 +1075,27 @@ static int usb_read_capacity(struct scsi_cmd *srb, struct us_data *ss) return -1; } +#ifdef CONFIG_SYS_64BIT_LBA +static int usb_read_capacity64(struct scsi_cmd *srb, struct us_data *ss) +{ + int retry; + /* XXX retries */ + retry = 3; + do { + memset(&srb->cmd[0], 0, 16); + srb->cmd[0] = SCSI_SRV_ACTION_IN; + srb->cmd[1] = (srb->lun << 5) | SCSI_SAI_RD_CAPAC16; + srb->cmd[13] = 32; /* Allocation length */ + srb->datalen = 32; + srb->cmdlen = 16; + if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD) + return 0; + } while (retry--); + + return -1; +} +#endif + static int usb_read_10(struct scsi_cmd *srb, struct us_data *ss, unsigned long start, unsigned short blocks) { @@ -1108,6 +1129,49 @@ static int usb_write_10(struct scsi_cmd *srb, struct us_data *ss, debug("write10: start %lx blocks %x\n", start, blocks); return ss->transport(srb, ss); } +#ifdef CONFIG_SYS_64BIT_LBA +static int usb_read_16(struct scsi_cmd *srb, struct us_data *ss, + uint64_t start, unsigned short blocks) +{ + memset(&srb->cmd[0], 0, 16); + srb->cmd[0] = SCSI_READ16; + srb->cmd[1] = srb->lun << 5; + srb->cmd[2] = ((unsigned char) (start >> 56)) & 0xff; + srb->cmd[3] = ((unsigned char) (start >> 48)) & 0xff; + srb->cmd[4] = ((unsigned char) (start >> 40)) & 0xff; + srb->cmd[5] = ((unsigned char) (start >> 32)) & 0xff; + srb->cmd[6] = ((unsigned char) (start >> 24)) & 0xff; + srb->cmd[7] = ((unsigned char) (start >> 16)) & 0xff; + srb->cmd[8] = ((unsigned char) (start >> 8)) & 0xff; + srb->cmd[9] = ((unsigned char) (start)) & 0xff; + srb->cmd[12] = ((unsigned char) (blocks >> 8)) & 0xff; + srb->cmd[13] = (unsigned char) blocks & 0xff; + srb->cmdlen = 16; + debug("read16: start %llx blocks %x\n", (long long)start, blocks); + return ss->transport(srb, ss); +} + +static int usb_write_16(struct scsi_cmd *srb, struct us_data *ss, + uint64_t start, unsigned short blocks) +{ + memset(&srb->cmd[0], 0, 16); + srb->cmd[0] = SCSI_WRITE16; + srb->cmd[1] = srb->lun << 5; + srb->cmd[2] = ((unsigned char) (start >> 56)) & 0xff; + srb->cmd[3] = ((unsigned char) (start >> 48)) & 0xff; + srb->cmd[4] = ((unsigned char) (start >> 40)) & 0xff; + srb->cmd[5] = ((unsigned char) (start >> 32)) & 0xff; + srb->cmd[6] = ((unsigned char) (start >> 24)) & 0xff; + srb->cmd[7] = ((unsigned char) (start >> 16)) & 0xff; + srb->cmd[8] = ((unsigned char) (start >> 8)) & 0xff; + srb->cmd[9] = ((unsigned char) (start)) & 0xff; + srb->cmd[12] = ((unsigned char) (blocks >> 8)) & 0xff; + srb->cmd[13] = (unsigned char) blocks & 0xff; + srb->cmdlen = 16; + debug("write16: start %llx blocks %x\n", (long long)start, blocks); + return ss->transport(srb, ss); +} +#endif #ifdef CONFIG_USB_BIN_FIXUP /* @@ -1146,6 +1210,7 @@ static unsigned long usb_stor_read(struct blk_desc *block_dev, lbaint_t blknr, struct usb_device *udev; struct us_data *ss; int retry; + int ret; struct scsi_cmd *srb = &usb_ccb; #if CONFIG_IS_ENABLED(BLK) struct blk_desc *block_dev; @@ -1191,7 +1256,13 @@ static unsigned long usb_stor_read(struct blk_desc *block_dev, lbaint_t blknr, usb_show_progress(); srb->datalen = block_dev->blksz * smallblks; srb->pdata = (unsigned char *)buf_addr; - if (usb_read_10(srb, ss, start, smallblks)) { +#ifdef CONFIG_SYS_64BIT_LBA + if (block_dev->lba > ((lbaint_t)0x100000000)) + ret = usb_read_16(srb, ss, start, smallblks); + else +#endif + ret = usb_read_10(srb, ss, start, smallblks); + if (ret) { debug("Read ERROR\n"); ss->flags &= ~USB_READY; usb_request_sense(srb, ss); @@ -1229,6 +1300,7 @@ static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr, struct usb_device *udev; struct us_data *ss; int retry; + int ret; struct scsi_cmd *srb = &usb_ccb; #if CONFIG_IS_ENABLED(BLK) struct blk_desc *block_dev; @@ -1278,7 +1350,13 @@ static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr, usb_show_progress(); srb->datalen = block_dev->blksz * smallblks; srb->pdata = (unsigned char *)buf_addr; - if (usb_write_10(srb, ss, start, smallblks)) { +#ifdef CONFIG_SYS_64BIT_LBA + if (block_dev->lba > ((lbaint_t)0x100000000)) + ret = usb_write_16(srb, ss, start, smallblks); + else +#endif + ret = usb_write_10(srb, ss, start, smallblks); + if (ret) { debug("Write ERROR\n"); ss->flags &= ~USB_READY; usb_request_sense(srb, ss); @@ -1435,9 +1513,10 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss, struct blk_desc *dev_desc) { unsigned char perq, modi; - ALLOC_CACHE_ALIGN_BUFFER(u32, cap, 2); + ALLOC_CACHE_ALIGN_BUFFER(u32, cap, 8); ALLOC_CACHE_ALIGN_BUFFER(u8, usb_stor_buf, 36); - u32 capacity, blksz; + lbaint_t capacity; + u32 blksz; struct scsi_cmd *pccb = &usb_ccb; pccb->pdata = usb_stor_buf; @@ -1488,26 +1567,43 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss, return 0; } pccb->pdata = (unsigned char *)cap; - memset(pccb->pdata, 0, 8); + memset(pccb->pdata, 0, 32); if (usb_read_capacity(pccb, ss) != 0) { - printf("READ_CAP ERROR\n"); + puts("READ_CAP ERROR\n"); ss->flags &= ~USB_READY; - cap[0] = 2880; - cap[1] = 0x200; + capacity = 2880; + blksz = 512; + } else { + debug("Read Capacity returns: 0x%08x, 0x%08x\n", + cap[0], cap[1]); + capacity = ((lbaint_t)be32_to_cpu(cap[0])) + 1; + blksz = be32_to_cpu(cap[1]); } - debug("Read Capacity returns: 0x%08x, 0x%08x\n", cap[0], cap[1]); -#if 0 - if (cap[0] > (0x200000 * 10)) /* greater than 10 GByte */ - cap[0] >>= 16; - cap[0] = cpu_to_be32(cap[0]); - cap[1] = cpu_to_be32(cap[1]); +#ifdef CONFIG_SYS_64BIT_LBA + if (capacity == 0x100000000) { + if (usb_read_capacity64(pccb, ss) != 0) { + puts("READ_CAP64 ERROR\n"); + } else { + debug("Read Capacity 64 returns: 0x%08x, 0x%08x, 0x%08x\n", + cap[0], cap[1], cap[2]); + capacity = be64_to_cpu(*(uint64_t *)cap) + 1; + blksz = be32_to_cpu(cap[2]); + } + } +#else + /* + * READ CAPACITY will return 0xffffffff when limited, + * which wraps to 0 with the +1 above + */ + if (!capacity) { + puts("LBA exceeds 32 bits but 64-bit LBA is disabled.\n"); + capacity = ~0; + } #endif - capacity = be32_to_cpu(cap[0]) + 1; - blksz = be32_to_cpu(cap[1]); - - debug("Capacity = 0x%08x, blocksz = 0x%08x\n", capacity, blksz); + debug("Capacity = 0x%llx, blocksz = 0x%08x\n", + (long long)capacity, blksz); dev_desc->lba = capacity; dev_desc->blksz = blksz; dev_desc->log2blksz = LOG2(dev_desc->blksz); From afc509b957da47872c98ddbe90f4a226a122f451 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Thu, 18 May 2023 23:59:17 +0900 Subject: [PATCH 27/41] usb: Ignore endpoints in non-zero altsettings We currently do not really handle altsettings properly, and no driver uses them. Ignore the respective endpoint descriptors for secondary altsettings, to avoid creating duplicate endpoint records in the interface. This will have to be revisited if/when we have a driver that needs altsettings to work properly. Signed-off-by: Hector Martin --- common/usb.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/common/usb.c b/common/usb.c index b9ecf2a3353..1483cb82808 100644 --- a/common/usb.c +++ b/common/usb.c @@ -445,6 +445,15 @@ static int usb_parse_config(struct usb_device *dev, puts("Endpoint descriptor out of order!\n"); break; } + if (if_desc->num_altsetting > 1) { + /* + * Ignore altsettings, which can trigger duplicate + * endpoint errors below. Revisit this when some + * driver actually needs altsettings with differing + * endpoint setups. + */ + break; + } epno = dev->config.if_desc[ifno].no_of_ep; if_desc = &dev->config.if_desc[ifno]; if (epno >= USB_MAXENDPOINTS) { From 239fb952613ec04ff9f226aafd60aef8428e6acf Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 11 Jan 2024 00:50:43 +0100 Subject: [PATCH 28/41] video: console: Select default font based on video_priv.font_size Signed-off-by: Janne Grunau --- drivers/video/console_core.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/video/console_core.c b/drivers/video/console_core.c index 939363653f6..96509ed8afd 100644 --- a/drivers/video/console_core.c +++ b/drivers/video/console_core.c @@ -209,6 +209,14 @@ int draw_cursor_vertically(void **line, struct video_priv *vid_priv, int console_probe(struct udevice *dev) { + struct video_fontdata *font; + struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); + + for (font = fonts; font->name; font++) { + if (font->height == vid_priv->font_size) + return console_set_font(dev, font); + } + return console_set_font(dev, fonts); } From 95c091294521f63845ed0018cafd1ae775e3543e Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 11 Jan 2024 00:48:12 +0100 Subject: [PATCH 29/41] video: simplefb: HACK: Set video font size Request the 16x32 font for display resolutions strictly larger than FullHD. Signed-off-by: Janne Grunau --- drivers/video/simplefb.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/video/simplefb.c b/drivers/video/simplefb.c index 8d0772d4e51..2eb209c29f4 100644 --- a/drivers/video/simplefb.c +++ b/drivers/video/simplefb.c @@ -84,6 +84,17 @@ static int simple_video_probe(struct udevice *dev) return -EINVAL; } + /* Apple silicon specific hack, should calculate DPI from "panel" + * phandle reference. + */ + if (uc_priv->xsize > 1920 && uc_priv->ysize > 1080) + uc_priv->font_size = 32; + /* + panel_node = fdtdec_lookup_phandle(blob_, node, "panel"); + if (panel_node > 0) { + uint dpi = fdtdec_get_uint(blob, node, "width-mm"); + } + */ return 0; } From 20d67f319421dcd955f146abdea8944b7946f407 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sun, 17 Mar 2024 17:12:24 +0100 Subject: [PATCH 30/41] configs: apple: Do not show the boot menu automatically It is empty and automatic boot does not work. This is a defensive commit against the fedora package which caries a patch to default CONFIG_AUTOBOOT_MENU_SHOW to y. Signed-off-by: Janne Grunau --- configs/apple_m1_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig index 7b21d0090db..6306e0c1e8c 100644 --- a/configs/apple_m1_defconfig +++ b/configs/apple_m1_defconfig @@ -4,6 +4,7 @@ CONFIG_ARCH_APPLE=y CONFIG_DEFAULT_DEVICE_TREE="apple/t8103-j274" CONFIG_SYS_BOOTM_LEN=0x800000 CONFIG_SYS_LOAD_ADDR=0x0 +# CONFIG_AUTOBOOT_MENU_SHOW is not set CONFIG_BOOTCOMMAND="bootflow scan -b" CONFIG_USE_PREBOOT=y CONFIG_SYS_CBSIZE=256 From 3aea66db69f0aca940e24aac172ecf27cd030228 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sat, 20 Apr 2024 08:59:29 +0200 Subject: [PATCH 31/41] FEDORA: configs: apple: Disable AUTOBOOT_KEYED Fedora patches this to 'default y' but the behavior on Fedora-Asahi-Remix was to interrupt boot with any key. Keep this behavior. Signed-off-by: Janne Grunau --- configs/apple_m1_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig index 6306e0c1e8c..a4db416aa46 100644 --- a/configs/apple_m1_defconfig +++ b/configs/apple_m1_defconfig @@ -4,6 +4,7 @@ CONFIG_ARCH_APPLE=y CONFIG_DEFAULT_DEVICE_TREE="apple/t8103-j274" CONFIG_SYS_BOOTM_LEN=0x800000 CONFIG_SYS_LOAD_ADDR=0x0 +# CONFIG_AUTOBOOT_KEYED is not set # CONFIG_AUTOBOOT_MENU_SHOW is not set CONFIG_BOOTCOMMAND="bootflow scan -b" CONFIG_USE_PREBOOT=y From ab751ea6edc26fa86cbe6d4ed7eb9f240a9ebeec Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sun, 24 Aug 2025 21:32:20 +0200 Subject: [PATCH 32/41] configs: apple: decrease boot delay to 1 second On Apple silicon machines u-boot's primary use is providing an UEFI boot environment. It's not expected that AUTOBOOT is interrupted but it's still desired to provide a clue that it is possible. Thios allows booting from USB storage devices. Signed-off-by: Janne Grunau --- configs/apple_m1_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig index a4db416aa46..eb2eb31121b 100644 --- a/configs/apple_m1_defconfig +++ b/configs/apple_m1_defconfig @@ -4,6 +4,7 @@ CONFIG_ARCH_APPLE=y CONFIG_DEFAULT_DEVICE_TREE="apple/t8103-j274" CONFIG_SYS_BOOTM_LEN=0x800000 CONFIG_SYS_LOAD_ADDR=0x0 +CONFIG_BOOTDELAY=1 # CONFIG_AUTOBOOT_KEYED is not set # CONFIG_AUTOBOOT_MENU_SHOW is not set CONFIG_BOOTCOMMAND="bootflow scan -b" From 595eafa2bdcd249f80fd52041388ba69ab010777 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 30 Apr 2026 22:15:32 +0200 Subject: [PATCH 33/41] arm: apple: Add Apple M3 (t8122) support Apple's M3 SoC is similar to M1 and M2 but uses a different memory map. The main difference is that RAM starts at 0x100_0000_0000 like on t600x and t602x (M1 and M2 Pro/Max/Ultra). Otherwise IO blocks have been rearranged. U-boot's existing drivers are compatible with the hardware and M3 device trees will carry "apple,t8103-*" compatible strings. Only apple-atcphy-reset might need a new compatible due to USB4 / DisplayPort changes the Linux driver has to deal with. Signed-off-by: Janne Grunau --- arch/arm/mach-apple/board.c | 71 +++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c index bc563136b52..042e8fa0c26 100644 --- a/arch/arm/mach-apple/board.c +++ b/arch/arm/mach-apple/board.c @@ -87,6 +87,75 @@ static struct mm_region t8103_mem_map[] = { } }; +/* Apple M3 */ + +static struct mm_region t8122_mem_map[] = { + { + /* I/O */ + .virt = 0x210000000, + .phys = 0x210000000, + .size = 4UL * SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O */ + .virt = 0x700000000, + .phys = 0x700000000, + .size = SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O */ + .virt = 0xb00000000, + .phys = 0xb00000000, + .size = SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O */ + .virt = 0x580000000, + .phys = 0x580000000, + .size = SZ_512M, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* PCIE */ + .virt = 0x5a0000000, + .phys = 0x5a0000000, + .size = SZ_512M, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) | + PTE_BLOCK_INNER_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* PCIE */ + .virt = 0x5c0000000, + .phys = 0x5c0000000, + .size = SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) | + PTE_BLOCK_INNER_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* RAM */ + .virt = 0x10000000000, + .phys = 0x10000000000, + .size = 8UL * SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { + /* Framebuffer */ + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) | + PTE_BLOCK_INNER_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* List terminator */ + 0, + } +}; + /* Apple M1 Pro/Max */ static struct mm_region t6000_mem_map[] = { @@ -712,6 +781,8 @@ void build_mem_map(void) if (of_machine_is_compatible("apple,t8103") || of_machine_is_compatible("apple,t8112")) mem_map = t8103_mem_map; + else if (of_machine_is_compatible("apple,t8122")) + mem_map = t8122_mem_map; else if (of_machine_is_compatible("apple,t6000") || of_machine_is_compatible("apple,t6001")) mem_map = t6000_mem_map; From 3fa16d88dce40faf60b55863bb6dc51fbd670362 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 1 May 2026 18:21:14 +0200 Subject: [PATCH 34/41] fixup! arm: dts: Switch Apple silicon devices to dts/upstream Signed-off-by: Janne Grunau --- configs/apple_m1_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig index eb2eb31121b..758c112eff3 100644 --- a/configs/apple_m1_defconfig +++ b/configs/apple_m1_defconfig @@ -16,6 +16,8 @@ CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_BOARD_LATE_INIT=y CONFIG_CMD_SMBIOS=y CONFIG_CMD_SELECT_FONT=y +CONFIG_OF_UPSTREAM_BUILD_VENDOR=y +CONFIG_OF_UPSTREAM_VENDOR="apple" CONFIG_NO_NET=y CONFIG_SYS_64BIT_LBA=y CONFIG_APPLE_SPI_KEYB=y From 10c5e0e5f01bf7360ecb8dc06e02daba4c6b60e4 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Fri, 14 Apr 2023 13:14:41 +0200 Subject: [PATCH 35/41] scripts/dtc: Add support for floating-point literals Signed-off-by: Asahi Lina --- scripts/dtc/data.c | 27 +++++++++++++++++++++++++++ scripts/dtc/dtc-lexer.l | 22 ++++++++++++++++++++++ scripts/dtc/dtc-parser.y | 16 ++++++++++++++++ scripts/dtc/dtc.h | 1 + 4 files changed, 66 insertions(+) diff --git a/scripts/dtc/data.c b/scripts/dtc/data.c index 5b25aa06041..ce449824c80 100644 --- a/scripts/dtc/data.c +++ b/scripts/dtc/data.c @@ -184,6 +184,33 @@ struct data data_append_integer(struct data d, uint64_t value, int bits) } } +struct data data_append_float(struct data d, double value, int bits) +{ + float f32; + uint32_t u32; + double f64; + uint64_t u64; + fdt32_t value_32; + fdt64_t value_64; + + switch (bits) { + case 32: + f32 = value; + memcpy(&u32, &f32, sizeof(u32)); + value_32 = cpu_to_fdt32(u32); + return data_append_data(d, &value_32, 4); + + case 64: + f64 = value; + memcpy(&u64, &f64, sizeof(u64)); + value_64 = cpu_to_fdt64(u64); + return data_append_data(d, &value_64, 8); + + default: + die("Invalid literal size (%d)\n", bits); + } +} + struct data data_append_re(struct data d, uint64_t address, uint64_t size) { struct fdt_reserve_entry re; diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l index 15d585c8079..6aa42f356c3 100644 --- a/scripts/dtc/dtc-lexer.l +++ b/scripts/dtc/dtc-lexer.l @@ -166,6 +166,28 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...); return DT_LITERAL; } +[-+]?(([0-9]+\.[0-9]*)|([0-9]*\.[0-9]+))(e[-+]?[0-9]+)?f? { + char *e; + DPRINT("Floating-point Literal: '%s'\n", yytext); + + errno = 0; + yylval.floating = strtod(yytext, &e); + + if (*e && (*e != 'f' || e[1])) { + lexical_error("Bad floating-point literal '%s'", + yytext); + } + + if (errno == ERANGE) + lexical_error("Floating-point literal '%s' out of range", + yytext); + else + /* ERANGE is the only strtod error triggerable + * by strings matching the pattern */ + assert(errno == 0); + return DT_FP_LITERAL; + } + ([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? { char *e; DPRINT("Integer Literal: '%s'\n", yytext); diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y index 4d5eece5262..225a6b41b14 100644 --- a/scripts/dtc/dtc-parser.y +++ b/scripts/dtc/dtc-parser.y @@ -48,6 +48,7 @@ static bool is_ref_relative(const char *ref) struct node *nodelist; struct reserve_info *re; uint64_t integer; + double floating; unsigned int flags; } @@ -61,6 +62,7 @@ static bool is_ref_relative(const char *ref) %token DT_OMIT_NO_REF %token DT_PROPNODENAME %token DT_LITERAL +%token DT_FP_LITERAL %token DT_CHAR_LITERAL %token DT_BYTE %token DT_STRING @@ -86,6 +88,7 @@ static bool is_ref_relative(const char *ref) %type subnode %type subnodes +%type floating_prim %type integer_prim %type integer_unary %type integer_mul @@ -395,6 +398,15 @@ arrayprefix: $$.data = data_add_marker(empty_data, TYPE_UINT32, NULL); $$.bits = 32; } + | arrayprefix floating_prim + { + if ($1.bits < 32) { + ERROR(&@2, "Floating-point values must be" + " 32-bit or 64-bit"); + } + + $$.data = data_append_float($1.data, $2, $1.bits); + } | arrayprefix integer_prim { if ($1.bits < 64) { @@ -439,6 +451,10 @@ arrayprefix: } ; +floating_prim: + DT_FP_LITERAL + ; + integer_prim: DT_LITERAL | DT_CHAR_LITERAL diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h index fcc97bbc70e..09e42490062 100644 --- a/scripts/dtc/dtc.h +++ b/scripts/dtc/dtc.h @@ -176,6 +176,7 @@ struct data data_insert_at_marker(struct data d, struct marker *m, struct data data_merge(struct data d1, struct data d2); struct data data_append_cell(struct data d, cell_t word); struct data data_append_integer(struct data d, uint64_t word, int bits); +struct data data_append_float(struct data d, double value, int bits); struct data data_append_re(struct data d, uint64_t address, uint64_t size); struct data data_append_addr(struct data d, uint64_t addr); struct data data_append_byte(struct data d, uint8_t byte); From d7263c63a95ecd3cba539f8b92fb0058db0bb303 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 21 May 2026 23:44:41 +0200 Subject: [PATCH 36/41] Revert "arm: apple: Add Apple M3 (t8122) support" This reverts commit 595eafa2bdcd249f80fd52041388ba69ab010777. --- arch/arm/mach-apple/board.c | 71 ------------------------------------- 1 file changed, 71 deletions(-) diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c index 042e8fa0c26..bc563136b52 100644 --- a/arch/arm/mach-apple/board.c +++ b/arch/arm/mach-apple/board.c @@ -87,75 +87,6 @@ static struct mm_region t8103_mem_map[] = { } }; -/* Apple M3 */ - -static struct mm_region t8122_mem_map[] = { - { - /* I/O */ - .virt = 0x210000000, - .phys = 0x210000000, - .size = 4UL * SZ_1G, - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE | - PTE_BLOCK_PXN | PTE_BLOCK_UXN - }, { - /* I/O */ - .virt = 0x700000000, - .phys = 0x700000000, - .size = SZ_1G, - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE | - PTE_BLOCK_PXN | PTE_BLOCK_UXN - }, { - /* I/O */ - .virt = 0xb00000000, - .phys = 0xb00000000, - .size = SZ_1G, - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE | - PTE_BLOCK_PXN | PTE_BLOCK_UXN - }, { - /* I/O */ - .virt = 0x580000000, - .phys = 0x580000000, - .size = SZ_512M, - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE | - PTE_BLOCK_PXN | PTE_BLOCK_UXN - }, { - /* PCIE */ - .virt = 0x5a0000000, - .phys = 0x5a0000000, - .size = SZ_512M, - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) | - PTE_BLOCK_INNER_SHARE | - PTE_BLOCK_PXN | PTE_BLOCK_UXN - }, { - /* PCIE */ - .virt = 0x5c0000000, - .phys = 0x5c0000000, - .size = SZ_1G, - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) | - PTE_BLOCK_INNER_SHARE | - PTE_BLOCK_PXN | PTE_BLOCK_UXN - }, { - /* RAM */ - .virt = 0x10000000000, - .phys = 0x10000000000, - .size = 8UL * SZ_1G, - .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | - PTE_BLOCK_INNER_SHARE - }, { - /* Framebuffer */ - .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) | - PTE_BLOCK_INNER_SHARE | - PTE_BLOCK_PXN | PTE_BLOCK_UXN - }, { - /* List terminator */ - 0, - } -}; - /* Apple M1 Pro/Max */ static struct mm_region t6000_mem_map[] = { @@ -781,8 +712,6 @@ void build_mem_map(void) if (of_machine_is_compatible("apple,t8103") || of_machine_is_compatible("apple,t8112")) mem_map = t8103_mem_map; - else if (of_machine_is_compatible("apple,t8122")) - mem_map = t8122_mem_map; else if (of_machine_is_compatible("apple,t6000") || of_machine_is_compatible("apple,t6001")) mem_map = t6000_mem_map; From 01c2642c3a86e343915042eeaf2f47bda62781d4 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 30 Apr 2026 22:15:32 +0200 Subject: [PATCH 37/41] arm: apple: Add Apple M3 (t8122) support Apple's M3 SoC is similar to M1 and M2 but uses a different memory map. The main difference is that RAM starts at 0x100_0000_0000 like on t600x and t602x (M1 and M2 Pro/Max/Ultra). Otherwise IO blocks have been rearranged. U-boot's existing drivers are compatible with the hardware and M3 device trees will carry "apple,t8103-*" compatible strings. Only apple-atcphy-reset might need a new compatible due to USB4 / DisplayPort changes the Linux driver has to deal with. Signed-off-by: Janne Grunau --- arch/arm/mach-apple/board.c | 79 +++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c index bc563136b52..d4d0936574c 100644 --- a/arch/arm/mach-apple/board.c +++ b/arch/arm/mach-apple/board.c @@ -675,6 +675,83 @@ static struct mm_region t6022_mem_map[] = { } }; +/* Apple M3 */ + +static struct mm_region t8122_mem_map[] = { + { + /* I/O */ + .virt = 0x200000000, + .phys = 0x200000000, + .size = 4UL * SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* NVMe */ + .virt = 0x300000000, + .phys = 0x300000000, + .size = SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* PCIE */ + .virt = 0x580000000, + .phys = 0x580000000, + .size = SZ_512M, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* PCIE */ + .virt = 0x5a0000000, + .phys = 0x5a0000000, + .size = SZ_512M, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) | + PTE_BLOCK_INNER_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* PCIE */ + .virt = 0x5c0000000, + .phys = 0x5c0000000, + .size = SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) | + PTE_BLOCK_INNER_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O ATC0 */ + .virt = 0x700000000, + .phys = 0x700000000, + .size = SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O ATC1 */ + .virt = 0xb00000000, + .phys = 0xb00000000, + .size = SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* RAM */ + .virt = 0x10000000000, + .phys = 0x10000000000, + .size = 8UL * SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { + /* Framebuffer */ + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) | + PTE_BLOCK_INNER_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* List terminator */ + 0, + } +}; + struct mm_region *mem_map; int board_init(void) @@ -722,6 +799,8 @@ void build_mem_map(void) mem_map = t6020_mem_map; else if (of_machine_is_compatible("apple,t6022")) mem_map = t6022_mem_map; + else if (of_machine_is_compatible("apple,t8122")) + mem_map = t8122_mem_map; else panic("Unsupported SoC\n"); From cf58ab5d145c9ab586a4c018b17221cc09555343 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 21 May 2026 21:04:55 +0200 Subject: [PATCH 38/41] arm: apple: Add Apple M3 Pro and Max (t603[014]) support Apple's M3 Pro (t6030) and Max (t6031 and t6034) SoCs are similar to their M1 and M2 predecessors. The MMIO blocks have been extended but M3 Pro and M3 Max still share the same overall layout although they aren't as similar as M1/M2 Pro and Max. U-boot's existing drivers are compatible with the hardware and M3 Pro and Max device trees will carry "apple,t8103-*" as fallback compatible strings. Only apple-atcphy-reset might need a new compatible due to USB4 and DisplayPort changes the Linux driver has to deal with. Signed-off-by: Janne Grunau --- arch/arm/mach-apple/board.c | 97 +++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c index d4d0936574c..4d962f99c77 100644 --- a/arch/arm/mach-apple/board.c +++ b/arch/arm/mach-apple/board.c @@ -752,6 +752,99 @@ static struct mm_region t8122_mem_map[] = { } }; +/* Apple M3 Pro and Max */ + +static struct mm_region t6030_mem_map[] = { + { + /* I/O */ + .virt = 0x280000000, + .phys = 0x280000000, + .size = 2UL * SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O */ + .virt = 0x300000000, + .phys = 0x300000000, + .size = 3UL * SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* PCIE */ + .virt = 0x580000000, + .phys = 0x580000000, + .size = SZ_512M, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* PCIE */ + .virt = 0x5a0000000, + .phys = 0x5a0000000, + .size = SZ_512M, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) | + PTE_BLOCK_INNER_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* PCIE */ + .virt = 0x5c0000000, + .phys = 0x5c0000000, + .size = SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) | + PTE_BLOCK_INNER_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O ATC0 */ + .virt = 0x700000000, + .phys = 0x700000000, + .size = SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O ATC1 */ + .virt = 0xb00000000, + .phys = 0xb00000000, + .size = SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O ATC2 */ + .virt = 0xf00000000, + .phys = 0xf00000000, + .size = SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O ATC3 */ + .virt = 0x1300000000, + .phys = 0x1300000000, + .size = SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* RAM */ + .virt = 0x10000000000, + .phys = 0x10000000000, + .size = 16UL * SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { + /* Framebuffer */ + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) | + PTE_BLOCK_INNER_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* List terminator */ + 0, + } +}; + struct mm_region *mem_map; int board_init(void) @@ -801,6 +894,10 @@ void build_mem_map(void) mem_map = t6022_mem_map; else if (of_machine_is_compatible("apple,t8122")) mem_map = t8122_mem_map; + else if (of_machine_is_compatible("apple,t6030") || + of_machine_is_compatible("apple,t6031") || + of_machine_is_compatible("apple,t6034")) + mem_map = t6030_mem_map; else panic("Unsupported SoC\n"); From 79cc635b73dbae8535558ebaf74d8bf841c35765 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 21 May 2026 21:16:38 +0200 Subject: [PATCH 39/41] arm: apple: Add Apple M3 Ultra (t6032) support Apple's M3 Ultra (t6032) SoC consists like its M1 and M2 predecessors of two M3 Max dies with an "UltraFusion" interconnect. Since it is only used in the Mac Studio the mem map does not need to duplicate all entries. Two of the USB4 / Thunderbolt complexes on the second die are unused. Only PCIe host controller on the first die is used directly. The PCIe IO on the second die is used internally to connect the NVMe controller with the NAND flash. U-boot's existing drivers are compatible with the hardware and the M3 Ultra device tree will carry "apple,t8103-*" as fallback compatible strings. Only apple-atcphy-reset might need a new compatible due to USB4 and DisplayPort changes the Linux driver has to deal with. Signed-off-by: Janne Grunau --- arch/arm/mach-apple/board.c | 127 ++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c index 4d962f99c77..5efd5f5a826 100644 --- a/arch/arm/mach-apple/board.c +++ b/arch/arm/mach-apple/board.c @@ -845,6 +845,131 @@ static struct mm_region t6030_mem_map[] = { } }; +/* Apple M3 Ultra */ + +static struct mm_region t6032_mem_map[] = { + { + /* I/O */ + .virt = 0x280000000, + .phys = 0x280000000, + .size = 2UL * SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O */ + .virt = 0x300000000, + .phys = 0x300000000, + .size = 3UL * SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* PCIE */ + .virt = 0x580000000, + .phys = 0x580000000, + .size = SZ_512M, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* PCIE */ + .virt = 0x5a0000000, + .phys = 0x5a0000000, + .size = SZ_512M, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) | + PTE_BLOCK_INNER_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* PCIE */ + .virt = 0x5c0000000, + .phys = 0x5c0000000, + .size = SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) | + PTE_BLOCK_INNER_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O ATC0 */ + .virt = 0x700000000, + .phys = 0x700000000, + .size = SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O ATC1 */ + .virt = 0xb00000000, + .phys = 0xb00000000, + .size = SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O ATC2 */ + .virt = 0xf00000000, + .phys = 0xf00000000, + .size = SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O ATC3 */ + .virt = 0x1300000000, + .phys = 0x1300000000, + .size = SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O */ + .virt = 0x2280000000, + .phys = 0x2280000000, + .size = 2UL * SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O */ + .virt = 0x2300000000, + .phys = 0x2300000000, + .size = 3UL * SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O ATC4 */ + .virt = 0x2700000000, + .phys = 0x2700000000, + .size = SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O ATC5 */ + .virt = 0x2b00000000, + .phys = 0x2b00000000, + .size = SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* RAM */ + .virt = 0x10000000000, + .phys = 0x10000000000, + .size = 16UL * SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { + /* Framebuffer */ + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) | + PTE_BLOCK_INNER_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* List terminator */ + 0, + } +}; + struct mm_region *mem_map; int board_init(void) @@ -898,6 +1023,8 @@ void build_mem_map(void) of_machine_is_compatible("apple,t6031") || of_machine_is_compatible("apple,t6034")) mem_map = t6030_mem_map; + else if (of_machine_is_compatible("apple,t6032")) + mem_map = t6032_mem_map; else panic("Unsupported SoC\n"); From 3b233f59d0b6b57eae5add46a6fa7787ea11388e Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sun, 24 May 2026 00:04:57 +0200 Subject: [PATCH 40/41] power: domain: apple: Ignore power states with auto enable flag The current code timeouts while trying to enable the "apcie_sys_st" NVMe power states on Apple M3 Pro/Max SoCs. Ignoring these power states which are marked as auto enable avoids the timeout with a working NVMe. The Linux driver clears the auto enable bit but preserving the initial boot state from Apple's iboot/mboot in u-boot seems preferable. Signed-off-by: Janne Grunau --- drivers/power/domain/apple-pmgr.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/power/domain/apple-pmgr.c b/drivers/power/domain/apple-pmgr.c index 71fedb405da..3f74b5a277a 100644 --- a/drivers/power/domain/apple-pmgr.c +++ b/drivers/power/domain/apple-pmgr.c @@ -14,6 +14,8 @@ #include #define APPLE_PMGR_RESET BIT(31) +#define APPLE_PMGR_AUTO_ENABLE BIT(28) +#define APPLE_PMGR_PS_RESET BIT(12) #define APPLE_PMGR_DEV_DISABLE BIT(10) #define APPLE_PMGR_WAS_CLKGATED BIT(9) #define APPLE_PMGR_WAS_PWRGATED BIT(8) @@ -83,6 +85,14 @@ static int apple_pmgr_ps_set(struct power_domain *power_domain, u32 pstate) { struct apple_pmgr_priv *priv = dev_get_priv(power_domain->dev); uint reg; + int ret; + + ret = regmap_read(priv->regmap, priv->offset, ®); + if (ret < 0) + return ret; + + if (FIELD_GET(APPLE_PMGR_AUTO_ENABLE, reg)) + return 0; regmap_update_bits(priv->regmap, priv->offset, APPLE_PMGR_PS_TARGET, FIELD_PREP(APPLE_PMGR_PS_TARGET, pstate)); From cf58d98bb35eda9b6517c8964ab59341d20c7ed1 Mon Sep 17 00:00:00 2001 From: Yureka Date: Sun, 28 Jun 2026 18:09:54 +0200 Subject: [PATCH 41/41] power: domain: Add Apple PMP reporting driver The Power Management Processor (PMP) is a coprocessor found on certain Apple SoCs. This is a dummy driver which allows for devices bound to a PMGR domain through a PMP reporting domain to be powered on. Powering on the PMP itself is not necessary during boot. Tested on M3 Max (T6034) with the nvme device tree node using one of the PMP reporting power domains. Signed-off-by: Yureka --- MAINTAINERS | 1 + drivers/power/domain/Kconfig | 13 +++++++ drivers/power/domain/Makefile | 1 + drivers/power/domain/apple-pmp-report.c | 45 +++++++++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 drivers/power/domain/apple-pmp-report.c diff --git a/MAINTAINERS b/MAINTAINERS index b59c9840468..14516a805be 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -142,6 +142,7 @@ F: drivers/pci/pcie_apple.c F: drivers/phy/phy-apple-atc.c F: drivers/pinctrl/pinctrl-apple.c F: drivers/power/domain/apple-pmgr.c +F: drivers/power/domain/apple-pmp-report.c F: drivers/spi/apple_spi.c F: drivers/usb/host/xhci-pci-asmedia.c F: drivers/watchdog/apple_wdt.c diff --git a/drivers/power/domain/Kconfig b/drivers/power/domain/Kconfig index 935f282d6c5..1020988101d 100644 --- a/drivers/power/domain/Kconfig +++ b/drivers/power/domain/Kconfig @@ -18,6 +18,19 @@ config APPLE_PMGR_POWER_DOMAIN This driver is needed to power on parts of the SoC that have not been powered on by previous boot stages. +config APPLE_PMP_REPORT_POWER_DOMAIN + bool "Enable the Apple PMP reporting power domain driver" + depends on POWER_DOMAIN + default y if ARCH_APPLE + help + Enable support for reporting power states to the Apple Power + Management Processor (PMP). + + This is a dummy driver since the PMP is entirely optional and + enabling is not necessary during boot. However, it allows for + devices bound to a PMGR domain through a PMP reporting domain to be + powered on. + config AGILEX5_PMGR_POWER_DOMAIN bool "Enable the Agilex5 PMGR power domain driver" depends on SPL_POWER_DOMAIN && TARGET_SOCFPGA_SOC64 diff --git a/drivers/power/domain/Makefile b/drivers/power/domain/Makefile index b2c0bd8a61a..25681072052 100644 --- a/drivers/power/domain/Makefile +++ b/drivers/power/domain/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_$(PHASE_)POWER_DOMAIN) += power-domain-uclass.o obj-$(CONFIG_APPLE_PMGR_POWER_DOMAIN) += apple-pmgr.o +obj-$(CONFIG_APPLE_PMP_REPORT_POWER_DOMAIN) += apple-pmp-report.o obj-$(CONFIG_AGILEX5_PMGR_POWER_DOMAIN) += altr-pmgr-agilex5.o obj-$(CONFIG_BCM6328_POWER_DOMAIN) += bcm6328-power-domain.o obj-$(CONFIG_IMX8_POWER_DOMAIN) += imx8-power-domain-legacy.o imx8-power-domain.o diff --git a/drivers/power/domain/apple-pmp-report.c b/drivers/power/domain/apple-pmp-report.c new file mode 100644 index 00000000000..89fd81a7bd8 --- /dev/null +++ b/drivers/power/domain/apple-pmp-report.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2026 Yureka + */ + +#include +#include + +static const struct udevice_id apple_pmp_report_ids[] = { + { .compatible = "apple,t6000-pmp-v2-report" }, + { .compatible = "apple,t6020-pmp-v2-report" }, + { .compatible = "apple,t6030-pmp-v2-report" }, + { .compatible = "apple,t8112-pmp-v2-report" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(apple_pmp_report) = { + .name = "apple_pmp_report", + .id = UCLASS_NOP, + .of_match = apple_pmp_report_ids, + .bind = dm_scan_fdt_dev, +}; + +static int apple_pmp_report_entry_of_xlate(struct power_domain *power_domain, + struct ofnode_phandle_args *args) +{ + return 0; +} + +static const struct udevice_id apple_pmp_report_entry_ids[] = { + { .compatible = "apple,t6000-pmp-v2-report-entry" }, + { .compatible = "apple-pmp-report-entry" }, + { /* sentinel */ } +}; + +struct power_domain_ops apple_pmp_report_entry_ops = { + .of_xlate = apple_pmp_report_entry_of_xlate, +}; + +U_BOOT_DRIVER(apple_pmp_report_entry) = { + .name = "apple_pmp_report_entry", + .id = UCLASS_POWER_DOMAIN, + .of_match = apple_pmp_report_entry_ids, + .ops = &apple_pmp_report_entry_ops, +};