Skip to content
Merged
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
10 changes: 10 additions & 0 deletions Documentation/devicetree/bindings/iommu/apple,dart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,16 @@ properties:
before the domain powers off, and the slice is enabled again when it
powers up. Only the J713 internal display DARTs use it.

apple,manual-availability:
type: boolean
description: >
The DART's registers answer only once its client, a PCIe root complex,
is up. The client's driver makes the DART available after bringing the
root complex up, and the DART probes then. The root complex lists the DART
in its post-init-providers property as well as in iommu-map: otherwise
fw_devlink.strict=1 makes the root complex wait for a DART that waits for
it.

apple,tunable:
$ref: /schemas/types.yaml#/definitions/uint32-matrix
items:
Expand Down
87 changes: 75 additions & 12 deletions Documentation/devicetree/bindings/pci/apple,pcie.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@ $defs:
- description: Bits to set
description: Register initialization tuples for one controller region.

t6050-tunable:
$ref: /schemas/types.yaml#/definitions/uint32-matrix
items:
items:
- description: Register offset in the named window
- description: Access width in bytes
const: 4
- description: Mask of the bits to replace
- description: Value of those bits
description:
A T6050 host tunable list, copied by the boot loader from the Apple
device tree.

properties:
compatible:
oneOf:
Expand Down Expand Up @@ -99,11 +112,11 @@ properties:

reg:
minItems: 3
maxItems: 14
maxItems: 20

reg-names:
minItems: 3
maxItems: 14
maxItems: 20

ranges:
minItems: 2
Expand Down Expand Up @@ -134,6 +147,13 @@ properties:
iommu-map: true
iommu-map-mask: true

post-init-providers:
description:
The DART of a host whose iommu-map names a DART marked
apple,manual-availability, so that fw_devlink does not make the host wait
for a DART that probes only after the host has brought up its port.
$ref: /schemas/types.yaml#/definitions/phandle-array

power-domains:
description:
The power domains the controller needs. Internal controllers on some
Expand Down Expand Up @@ -175,6 +195,30 @@ properties:
$ref: '#/$defs/tunable'
description: Initialization tuples for the oe-fabric register region.

apple,tunable-axi2af:
$ref: '#/$defs/t6050-tunable'
description: T6050 tuples for the axi2af window, applied before a train.

apple,tunable-cio3pllcore:
$ref: '#/$defs/t6050-tunable'
description: T6050 tuples for the CIO3 PLL core, in the pcieclkgen window.

apple,tunable-pcieclkgen:
$ref: '#/$defs/t6050-tunable'
description: T6050 tuples for the pcieclkgen window.

apple,tunable-phy:
$ref: '#/$defs/t6050-tunable'
description: T6050 tuples for the phy-window window.

apple,tunable-phy-ip-pll:
$ref: '#/$defs/t6050-tunable'
description: T6050 PHY PLL tuples for the phy-ip window.

apple,tunable-phy-ip-auspma:
$ref: '#/$defs/t6050-tunable'
description: T6050 PHY lane tuples for the phy-ip window.

apple,piodma:
$ref: /schemas/types.yaml#/definitions/phandle
description:
Expand All @@ -201,7 +245,9 @@ patternProperties:
description:
The boot loader trained this port's link and handed it over up. The
driver adopts the link as it is instead of resetting the port, so
the port needs no PERST# line.
the port needs no PERST# line. A T6050 port that also names
pwren-gpios may be left untrained; the OS then trains it first and
adopts it the same way.

apple,tunable:
$ref: '#/$defs/tunable'
Expand Down Expand Up @@ -249,15 +295,18 @@ allOf:
properties:
reg:
minItems: 5
maxItems: 14
maxItems: 20
reg-names:
description:
config and rc, then port<n>, phy<n> and intr2axi<n> for each
bootloader-trained root port 00:<n>.0.
adopted root port 00:<n>.0. A host with a port the OS trains
itself (pwren-gpios) also names the shared PHY (phy-shared), its
common block (phy-common) and the windows its tunable lists
apply to (axi2af, pcieclkgen, phy-window, phy-ip).
minItems: 5
maxItems: 14
maxItems: 20
items:
pattern: "^(config|rc|(port|phy|intr2axi)[0-3])$"
pattern: "^(config|rc|(port|phy|intr2axi)[0-3]|phy-shared|phy-common|axi2af|pcieclkgen|phy-window|phy-ip)$"
interrupts:
maxItems: 4
interrupt-names:
Expand All @@ -277,11 +326,24 @@ allOf:
description:
The PERST# line of a port whose endpoint needs a root-port
reset after the bootloader trained the link. Left as the
bootloader set it until that reset.
pwren-gpios: false
bootloader set it until that reset, or until the OS trains
the port itself.
pwren-gpios:
description:
The endpoint's power line. A port that names it may be left
untrained by the bootloader; the OS then powers the endpoint
and trains the link itself (the host then needs phy-shared
and phy-common), and adopts it as a bootloader-trained one.
required:
- apple,link-trained-by-bootloader
else:
properties:
apple,tunable-axi2af: false
apple,tunable-cio3pllcore: false
apple,tunable-pcieclkgen: false
apple,tunable-phy: false
apple,tunable-phy-ip-pll: false
apple,tunable-phy-ip-auspma: false
patternProperties:
"^pci@":
properties:
Expand Down Expand Up @@ -443,14 +505,15 @@ allOf:
properties:
reg:
minItems: 5
maxItems: 14
maxItems: 20
reg-names:
minItems: 5
maxItems: 14
maxItems: 20
items:
enum: [config, rc, port0, phy0, intr2axi0, port1, phy1,
intr2axi1, port2, phy2, intr2axi2, port3, phy3,
intr2axi3]
intr2axi3, phy-shared, phy-common, axi2af,
pcieclkgen, phy-window, phy-ip]
interrupts:
maxItems: 4
else:
Expand Down
6 changes: 4 additions & 2 deletions drivers/gpio/gpio-macsmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
* pKW4("gP13", 0x00800000) (apple_t8132_managed_radio()). The firmware
* function preserves the template's upper 16 bits and inserts the level into
* its low 16 bits. This does not establish generic CMD_OUTPUT semantics, a
* pin-mode command, or a readback operation for this line.
* pin-mode command, or a readback operation for this line. The J716s N1's
* power, /arm-io/apcie0/pci-bridge0 function-reset, is the same descriptor.
*/
#define MACSMC_J713_RADIO_REG_ON_GPIO 0x13
#define MACSMC_J713_RADIO_REG_ON_TEMPLATE 0x00800000
Expand Down Expand Up @@ -526,7 +527,8 @@ static int macsmc_gpio_probe(struct platform_device *pdev)
smcgp->base_key = data ? data->base_key : _SMC_KEY("gP\0\0");
smcgp->j700_pcio = of_machine_is_compatible("apple,j700") &&
device_is_compatible(&pdev->dev, "apple,smc-gpio");
smcgp->j713 = apple_t8132_managed_radio();
smcgp->j713 = apple_t8132_managed_radio() ||
of_machine_is_compatible("apple,j716s");
mutex_init(&smcgp->j713_reg_on_lock);
ret = macsmc_gpio_parse_templates(smcgp);
if (ret)
Expand Down
41 changes: 41 additions & 0 deletions drivers/iommu/apple-dart.c
Original file line number Diff line number Diff line change
Expand Up @@ -4372,6 +4372,43 @@ static int apple_dart_parse_own_setup(struct apple_dart *dart, struct resource *
return 0;
}

struct apple_dart_available {
struct list_head list;
struct device_node *np;
};

static DEFINE_MUTEX(apple_dart_available_lock);
static LIST_HEAD(apple_dart_available_list);

void apple_dart_make_available(struct device_node *np)
{
struct apple_dart_available *a;

guard(mutex)(&apple_dart_available_lock);
list_for_each_entry(a, &apple_dart_available_list, list)
if (a->np == np)
return;
a = kzalloc_obj(*a);
if (!a)
return;
a->np = of_node_get(np);
list_add(&a->list, &apple_dart_available_list);
}
EXPORT_SYMBOL_GPL(apple_dart_make_available);

static bool apple_dart_is_available(struct device_node *np)
{
struct apple_dart_available *a;

if (!of_property_read_bool(np, "apple,manual-availability"))
return true;
guard(mutex)(&apple_dart_available_lock);
list_for_each_entry(a, &apple_dart_available_list, list)
if (a->np == np)
return true;
return false;
}

static int apple_dart_probe(struct platform_device *pdev)
{
int ret, sid;
Expand Down Expand Up @@ -4475,6 +4512,10 @@ static int apple_dart_probe(struct platform_device *pdev)
}
}

/* Its registers answer only once its client is up */
if (!apple_dart_is_available(dev->of_node))
return dev_err_probe(dev, -EPROBE_DEFER, "waiting for its client\n");

dart = kzalloc(sizeof(*dart), GFP_KERNEL);
if (!dart)
return -ENOMEM;
Expand Down
Loading
Loading