Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
237 changes: 237 additions & 0 deletions Documentation/devicetree/bindings/pci/apple,t8010-pcie.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/pci/apple,t8010-pcie.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Apple H9P/T8010 PCIe Host Controller

maintainers:
- Hector Martin <marcan@marcan.st>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. Please do not lie about maintainer.


description:
Apple A10/T8010 devices use an older H9P PCIe root complex for the
internal storage path. It exposes one ECAM window shared by up to four
root ports, controller-specific PHY and port register windows, and a
controller-local MSI block.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please mention complications with NVMMU regarding the storage device in the main description.

allOf:
- $ref: /schemas/pci/pci-host-bridge.yaml#
- $ref: /schemas/interrupt-controller/msi-controller.yaml#

properties:
compatible:
const: apple,t8010-pcie

reg:
minItems: 10
maxItems: 10

reg-names:
items:
- const: config
- const: phy0

@asdfugil asdfugil Jun 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The second memory region 0x6_0000_0000 is rc registers corresponding to rc_base in m1n1's reg info, not phy0.

- const: phy1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is only one phy, so this needs a better name. I believe this range corresponds to phy_base in m1n1's reg info, so maybe name this phy.

- const: phy2

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is only one phy, so this needs a better name. I believe this range corresponds to phyip_base in m1n1's reg info, so maybe name this phy-ip.

- const: port0
- const: port1
- const: port2
- const: port3
- const: nvmmu0
- const: pcieclk-postup

interrupts:
description:
Four port state interrupts followed by 32 MSI interrupts and the
optional NVMMU fault interrupt for the active storage port.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use msi-ranges like in pcie-apple.c to specify a range of interrupts instead of writing out 32 consecutive interrupts.

minItems: 37
maxItems: 37

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maxItems without minItems implies identical minItems, so minItems here should be removed

also for clocks, clock-names, power-domains


clocks:
minItems: 3
maxItems: 3

clock-names:
items:
- const: core
- const: aux
- const: ref

power-domains:
minItems: 3
maxItems: 3

power-domain-names:
items:
- const: core
- const: aux
- const: ref

reset-gpios:
description:
PERST# GPIOs indexed by PCIe root port.
minItems: 1
maxItems: 4

clkreq-gpios:
description:
CLKREQ# GPIOs indexed by PCIe root port.
minItems: 1
maxItems: 4

msi-controller: true

msi-parent: true

apple,msi-doorbell:
$ref: /schemas/types.yaml#/definitions/uint32
description:
MSI doorbell address programmed into downstream endpoints.

apple,enabled-ports:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Bitmask of root ports that should be powered and trained.
minimum: 1
maximum: 15

apple,nvmmu-iova:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Base device-visible address for the reserved NVMMU/SART window.

memory-region:
description:
Reserved physical window programmed into the H9P NVMMU/SART path.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be prefixed with apple,. I believe apple,nvme-hmb is a more appropriate name combined with above reviews.

When a node is referencing another node, please word like this in the description, Phandle of <another node description>

maxItems: 1

interrupt-controller: true

'#interrupt-cells':
const: 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of hardcoding the port and port count, each port should be represented as a device tree node (similar to pcie-apple), then the driver should scan the nodes to determine the number of ports. This will be required for things like wifi to have a device tree node to store properties like firmware name.

required:
- compatible
- reg
- reg-names
- interrupts
- clocks
- clock-names
- power-domains
- power-domain-names
- reset-gpios
- clkreq-gpios
- bus-range
- ranges
- msi-controller
- msi-parent
- apple,enabled-ports
- apple,nvmmu-iova
- memory-region
- '#interrupt-cells'

unevaluatedProperties: false

examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/apple-aic.h>

reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;

pcie0_nvmmu_window: nvmmu-window@8bee00000 {
reg = <0x8 0xbee00000 0x0 0x01200000>;
no-map;
};
};

soc {
#address-cells = <2>;
#size-cells = <2>;

pcie0: pcie@610000000 {
compatible = "apple,t8010-pcie";
device_type = "pci";

reg = <0x6 0x10000000 0x0 0x1000000>,
<0x6 0x00000000 0x0 0x8000>,
<0x6 0x00008000 0x0 0x4000>,
<0x6 0x0a000000 0x0 0x40000>,
<0x6 0x01000000 0x0 0x4000>,
<0x6 0x02000000 0x0 0x4000>,
<0x6 0x03000000 0x0 0x4000>,
<0x6 0x04000000 0x0 0x4000>,
<0x6 0x01004000 0x0 0x4000>,
<0x6 0x00010000 0x0 0x8000>;
reg-names = "config", "phy0", "phy1", "phy2",
"port0", "port1", "port2", "port3",
"nvmmu0", "pcieclk-postup";

interrupt-parent = <&aic>;
interrupts = <AIC_IRQ 270 IRQ_TYPE_LEVEL_HIGH>,
<AIC_IRQ 273 IRQ_TYPE_LEVEL_HIGH>,
<AIC_IRQ 276 IRQ_TYPE_LEVEL_HIGH>,
<AIC_IRQ 279 IRQ_TYPE_LEVEL_HIGH>,
<AIC_IRQ 288 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 289 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 290 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 291 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 292 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 293 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 294 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 295 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 296 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 297 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 298 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 299 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 300 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 301 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 302 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 303 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 304 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 305 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 306 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 307 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 308 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 309 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 310 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 311 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 312 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 313 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 314 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 315 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 316 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 317 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 318 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 319 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 272 IRQ_TYPE_EDGE_RISING>;

msi-controller;
msi-parent = <&pcie0>;
apple,msi-doorbell = <0xbffff000>;
apple,enabled-ports = <0x1>;
apple,nvmmu-iova = <0xbc000000>;
memory-region = <&pcie0_nvmmu_window>;

#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
bus-range = <0x00 0x0f>;
ranges = <0x03000000 0x0 0xc0000000
0x7 0xc0000000 0x0 0x40000000>;

clocks = <&clkref>, <&clkref>, <&clkref>;
clock-names = "core", "aux", "ref";
power-domains = <&ps_pcie>, <&ps_pcie_aux>,
<&ps_pcie_ref>;
power-domain-names = "core", "aux", "ref";

reset-gpios = <&pinctrl_ap 12 GPIO_ACTIVE_HIGH>;
clkreq-gpios = <&pinctrl_ap 16 GPIO_ACTIVE_HIGH>;
};
};

...
117 changes: 117 additions & 0 deletions arch/arm64/boot/dts/apple/t8010-ipad7.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,120 @@
* now.
*/
#include "t8010-ipad6.dtsi"

/ {
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;

pcie0_nvmmu_window: nvmmu-window@8bee00000 {
reg = <0x8 0xbee00000 0x0 0x01200000>;
no-map;
};

@asdfugil asdfugil Jun 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this part goes into t8010-common.dtsi.

This part should be made to be filled by bootloader (m1n1) based on /arm-io/nvme-mmu0 in ADT,
make sure you have a /* To be filled by loader */ comment.

This memory region is for the NVMe controller's private use, so the name should be based on that, perhaps nvme-hmb@0? (0 because filled by loader)
Use an alias like nvme_hmb in the aliases node to make it easier for the loader to get the node.

};

soc {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

everything here in soc {} belongs to t8010.dtsi, not here.

pcie0_dart0: iommu@601008000 {
compatible = "apple,t8010-dart", "apple,s5l8960x-dart";
reg = <0x6 0x01008000 0x0 0x4000>;
#iommu-cells = <1>;
interrupt-parent = <&aic>;
interrupts = <AIC_IRQ 271 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&ps_pcie>;
apple,dma-range = <0x0 0x80000000 0x0 0x3c000000>;
};

pcie0: pcie@610000000 {
compatible = "apple,t8010-pcie";
device_type = "pci";
status = "okay";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use status unless it is disabled in a .dtsi file but is overriden to okay in another file.


reg = <0x6 0x10000000 0x0 0x1000000>,
<0x6 0x00000000 0x0 0x8000>,
<0x6 0x00008000 0x0 0x4000>,
<0x6 0x0a000000 0x0 0x40000>,
<0x6 0x01000000 0x0 0x4000>,
<0x6 0x02000000 0x0 0x4000>,
<0x6 0x03000000 0x0 0x4000>,
<0x6 0x04000000 0x0 0x4000>,
<0x6 0x01004000 0x0 0x4000>,
<0x6 0x00010000 0x0 0x8000>;
reg-names = "config", "phy0", "phy1", "phy2",
"port0", "port1", "port2", "port3",
"nvmmu0", "pcieclk-postup";

interrupt-parent = <&aic>;
interrupts = <AIC_IRQ 270 IRQ_TYPE_LEVEL_HIGH>,
<AIC_IRQ 273 IRQ_TYPE_LEVEL_HIGH>,
<AIC_IRQ 276 IRQ_TYPE_LEVEL_HIGH>,
<AIC_IRQ 279 IRQ_TYPE_LEVEL_HIGH>,
<AIC_IRQ 288 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 289 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 290 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 291 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 292 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 293 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 294 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 295 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 296 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 297 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 298 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 299 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 300 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 301 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 302 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 303 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 304 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 305 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 306 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 307 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 308 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 309 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 310 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 311 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 312 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 313 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 314 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 315 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 316 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 317 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 318 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 319 IRQ_TYPE_EDGE_RISING>,
<AIC_IRQ 272 IRQ_TYPE_EDGE_RISING>;

msi-controller;
msi-parent = <&pcie0>;
apple,msi-doorbell = <0xbffff000>;
apple,enabled-ports = <0x1>;
apple,nvmmu-iova = <0xbc000000>;
memory-region = <&pcie0_nvmmu_window>;

iommu-map = <0x100 &pcie0_dart0 0 1>;
iommu-map-mask = <0xff00>;

#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
interrupt-controller;
bus-range = <0x00 0x0f>;
ranges = <0x03000000 0x0 0xc0000000
0x7 0xc0000000 0x0 0x40000000>;

clocks = <&clkref>, <&clkref>, <&clkref>;
clock-names = "core", "aux", "ref";
power-domains = <&ps_pcie>, <&ps_pcie_aux>,
<&ps_pcie_ref>;
power-domain-names = "core", "aux", "ref";

reset-gpios = <&pinctrl_ap 12 GPIO_ACTIVE_HIGH>,
<&pinctrl_ap 13 GPIO_ACTIVE_HIGH>,
<&pinctrl_ap 14 GPIO_ACTIVE_HIGH>,
<&pinctrl_ap 15 GPIO_ACTIVE_HIGH>;
clkreq-gpios = <&pinctrl_ap 16 GPIO_ACTIVE_HIGH>,
<&pinctrl_ap 17 GPIO_ACTIVE_HIGH>,
<&pinctrl_ap 18 GPIO_ACTIVE_HIGH>,
<&pinctrl_ap 19 GPIO_ACTIVE_HIGH>;
};
};
};
2 changes: 1 addition & 1 deletion drivers/nvme/host/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ nvme-core-$(CONFIG_FAULT_INJECTION_DEBUG_FS) += fault_inject.o
nvme-core-$(CONFIG_NVME_HWMON) += hwmon.o
nvme-core-$(CONFIG_NVME_HOST_AUTH) += auth.o

nvme-y += pci.o
nvme-y += pci.o pci-apple-h9p.o

nvme-fabrics-y += fabrics.o

Expand Down
Loading