Skip to content
Closed
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
119 changes: 119 additions & 0 deletions Documentation/devicetree/bindings/pci/apple,apif-pcie.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# SPDX-License-Identifier: GPL-2.0-only
%YAML 1.2
---
$id: http://devicetree.org/schemas/pci/apple,apif-pcie.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Preinitialized Apple PCIe host in an Aura guest
maintainers:
- Dj <hey@djdev.me>

description: |
The boot producer configures the controller, PHY, link, apertures and
RID-to-SID routing before guest entry. It disables endpoint bus mastering
and MSI before transferring ownership. Linux uses ECAM and allocates MSI
from the native AIC range; it does not run raw cold-init register sequences.

allOf:
- $ref: /schemas/pci/pci-host-bridge.yaml#
- if:
properties:
compatible:
contains:
const: apple,t6050-pcie-apif
then:
required:
- apple,rid-to-sid
- max-link-speed
- num-lanes
properties:
reg:
minItems: 5
reg-names:
minItems: 5
else:
properties:
reg:
maxItems: 1
reg-names:
maxItems: 1
apple,rid-to-sid: false

properties:
compatible:
oneOf:
- const: apple,apif-pcie
- items:
- const: apple,t6050-pcie-apif
- const: apple,apif-pcie
reg:
minItems: 1
items:
- description: ECAM configuration window
- description: T6050 port-0 control registers, at least 32 KiB
- description: T6050 port-0 PHY registers, at least 16 KiB
- description: Active-low PERST pad register, at least four bytes
- description: T6050 interrupt-to-AXI registers, at least 16 KiB
reg-names:
minItems: 1
items:
- const: ecam
- const: port
- const: phy
- const: perst
- const: intr2axi
apple,preinitialized:
type: boolean
description: Controller is initialized and endpoint DMA/MSI is stopped
apple,msi-address:
$ref: /schemas/types.yaml#/definitions/uint64
description: Native MSI doorbell; 4 KiB aligned for the T6050 layout
msi-ranges:
maxItems: 1
description: One four-cell native AIC edge interrupt range and vector count
apple,rid-to-sid:
$ref: /schemas/types.yaml#/definitions/uint32-matrix
minItems: 1
maxItems: 15
items:
items:
- description: Hardware routing slot
minimum: 1
maximum: 15
- description: Requester ID
maximum: 65535
- description: Firmware-assigned DART stream ID
maximum: 255
description: Restore existing routing after the optional preboot port cycle
iommu-map: true
iommu-map-mask: true
max-link-speed:
const: 3
num-lanes:
const: 1
dma-coherent: true

patternProperties:
'^apple,(apcie-config|pcie-rc|pcie-rc-gen[345]-shadow)-tunables$':
$ref: /schemas/types.yaml#/definitions/uint32-matrix
maxItems: 16
items:
items:
- description: Register offset
- const: 4
- description: Clear mask
- description: Set mask
description: Boot-producer register tuples for the matched layout

required:
- compatible
- reg
- reg-names
- ranges
- bus-range
- apple,preinitialized
- apple,msi-address
- msi-ranges
- iommu-map

unevaluatedProperties: false
30 changes: 30 additions & 0 deletions Documentation/driver-api/firmware/aurora-apif-pcie.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.. SPDX-License-Identifier: GPL-2.0-only

Preinitialized PCIe guests
=========================

``apple,apif-pcie`` admits an ECAM host whose producer has already configured
its clocks, PHY, link, address windows and RID-to-SID routes. The producer
must stop endpoint DMA and MSI before transferring ownership. Linux allocates
MSI vectors from the single native four-cell AIC edge range in ``msi-ranges``;
the doorbell is supplied by ``apple,msi-address``. Vector counts and addresses
are checked before the routing tables are touched. No polling interrupt path
or fixed IRQ assignment per function is introduced.

A second compatible, ``apple,t6050-pcie-apif``, selects the known port-0
register layout and supplies port, PHY, PERST and interrupt-to-AXI resources.
It restores explicit ``apple,rid-to-sid`` tuples and the same declared MSI
range after a controlled preboot cycle. Tunables come from the boot producer.
Unknown layouts use only ECAM/MSI; they cannot enter the T6050 reset sequence.

``apple_apif_pcie_cycle()`` is for the isolated N1 ROM/preboot function before
radio functions are enumerated or have live DMA. The caller must quiesce all
activity on that unit. PCI topology locking excludes sibling functions, and
DART transitions refuse other Linux groups or retained firmware streams.
Timeouts are bounded. A partial transition leaves bus mastering and bridge
decoding stopped; it does not attempt a speculative DMA restart. This is not
a general PCI bus reset API and does not add N1 Wi-Fi/Bluetooth drivers.

The generic host and its matched port sequence require hardware qualification
with the matching Aura monitor and boot description. Host sequence tests and
native builds do not establish link recovery or radio firmware behavior.
1 change: 1 addition & 0 deletions Documentation/driver-api/firmware/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Linux Firmware API

aurora-apif
aurora-apif-nvme
aurora-apif-pcie
introduction
core
efi/index
Expand Down
29 changes: 28 additions & 1 deletion drivers/iommu/apple-dart-apif.c
Original file line number Diff line number Diff line change
Expand Up @@ -1743,10 +1743,16 @@ static const struct iommu_ops apple_dart_apif_ops = {
/* Used only after the PCI host has stopped every endpoint on this DART.
* Native POWERDOWN/POWERUP retains the SPTM-owned tables and live mappings.
*/
static int apif_other_group_device(struct device *member, void *data)
{
return member == data ? 0 : -EBUSY;
}

int apple_dart_apif_set_power(struct device *dev, bool on)
{
struct apple_dart_apif_master *master;
struct apple_dart_apif *dart;
struct iommu_group *group;
unsigned long flags;
int ret;

Expand All @@ -1757,8 +1763,25 @@ int apple_dart_apif_set_power(struct device *dev, bool on)
if (!master || master->num_darts != 1)
return -ENODEV;
dart = master->streams[0].dart;
group = iommu_group_get(dev);
if (!group)
return -ENODEV;
ret = iommu_group_for_each_dev(group, dev, apif_other_group_device);
if (ret)
goto put_group;
mutex_lock(&apple_dart_apif_groups_lock);
/* Native DISABLE affects the entire unit. Retained firmware streams or
* another Linux group must never be stopped by one endpoint's reset.
*/
for (unsigned int sid = 0; sid < dart->num_streams; sid++) {
if (dart->retained[sid] ||
(dart->sid2group[sid] && dart->sid2group[sid] != group)) {
ret = -EBUSY;
goto unlock_groups;
}
}
mutex_lock(&dart->init_lock);
if (!dart->inited) {
if (!dart->inited || dart->ownership_uncertain) {
ret = -EINVAL;
goto out;
}
Expand All @@ -1769,6 +1792,10 @@ int apple_dart_apif_set_power(struct device *dev, bool on)
spin_unlock_irqrestore(&dart->batch_lock, flags);
out:
mutex_unlock(&dart->init_lock);
unlock_groups:
mutex_unlock(&apple_dart_apif_groups_lock);
put_group:
iommu_group_put(group);
return ret;
}
EXPORT_SYMBOL_GPL(apple_dart_apif_set_power);
Expand Down
11 changes: 11 additions & 0 deletions drivers/pci/controller/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -409,3 +409,14 @@ source "drivers/pci/controller/dwc/Kconfig"
source "drivers/pci/controller/mobiveil/Kconfig"
source "drivers/pci/controller/plda/Kconfig"
endmenu

config PCIE_APPLE_APIF
tristate "Preinitialized Apple PCIe host for Aura guests"
depends on ARM64 && OF && PCI_MSI
depends on APPLE_DART_APIF
select PCI_HOST_COMMON
help
Admit an ECAM host initialized by the boot producer. Allocate MSI
vectors from the native AIC range described in its guest device tree.
A matching T6050 layout additionally supports a controlled preboot
port transition; other layouts never enter that sequence.
1 change: 1 addition & 0 deletions drivers/pci/controller/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,4 @@ endif
endif

obj-$(CONFIG_PCIE_APPLE_PIODMA_DIAG) += pcie-apple-piodma-diag.o
obj-$(CONFIG_PCIE_APPLE_APIF) += apple-apif/
2 changes: 2 additions & 0 deletions drivers/pci/controller/apple-apif/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
obj-$(CONFIG_PCIE_APPLE_APIF) += pcie-apple-apif.o
pcie-apple-apif-y := host.o t6050.o t6050_pcie_port.o t6050_pcie_disable.o t6050_pcie_gpio.o t6050_pcie_msi.o
Loading