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
144 changes: 129 additions & 15 deletions arch/arm64/boot/dts/apple/t6050-j716s.dts
Original file line number Diff line number Diff line change
Expand Up @@ -83,30 +83,52 @@
/*
* PCIe port 0: the N1 (Wi-Fi and Bluetooth). Port 1 is the SD reader, not yet
* described. The registers, interrupt, DART streams and PERST# pin are the
* J716c's: the J716s ADT has the same port. Disabled with its DART until the
* boot loader trains it.
* J716c's: the J716s ADT has the same port. Port 0 and its DART stay disabled
* until the boot loader enables them: once it trained the port, or with the
* port down because the kernel can train it (port00 names the N1's power
* line, the DART waits for its root complex). The kernel's train uses the
* shared PHY (ADT reg[3]), its common block (reg[2] + 0x4000) and the windows
* of the host tunable lists the boot loader copies from the ADT: axi2af
* (reg[5]), pcieclkgen (reg[6]), phy-window (reg[2]) and phy-ip (reg[4]),
* the same as the J714c's; the PHY and axi2af windows are cut to what their
* lists reach.
*/
&pcie0 {
reg = <0x1c 0xb0000000 0x0 0x10000000>,
<0x4 0x14000000 0x0 0x4000>,
<0x4 0x10028000 0x0 0x8000>,
<0x4 0x17010000 0x0 0x4000>,
<0x4 0x10024000 0x0 0x4000>;
reg-names = "config", "rc", "port0", "phy0", "intr2axi0";
<0x4 0x10024000 0x0 0x4000>,
<0x4 0x17020000 0x0 0x4000>,
<0x4 0x17004000 0x0 0x4000>,
<0x4 0x16000000 0x0 0x24000>,
<0x4 0x15044000 0x0 0x4000>,
<0x4 0x17000000 0x0 0x24000>,
<0x4 0x17800000 0x0 0x1b4000>;
reg-names = "config", "rc", "port0", "phy0", "intr2axi0",
"phy-shared", "phy-common", "axi2af", "pcieclkgen",
"phy-window", "phy-ip";
interrupts = <AIC_IRQ 0 1523 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "port0";

/* The N1's three functions are on DART streams 1-3 */
iommu-map = <0x100 &dart_apcie0 1 3>;
bus-range = <0 4>;
/*
* dart_apcie0 probes only once this host has the port up: fw_devlink
* must not make the host wait for it (strict mode enforces iommu-map)
*/
post-init-providers = <&dart_apcie0>;

port00: pci@0,0 {
device_type = "pci";
reg = <0x0 0 0 0 0>;
bus-range = <1 1>;
apple,link-trained-by-bootloader;
/* The N1's power: ADT pci-bridge0 function-reset, gP13 */
pwren-gpios = <&smc_gpio 0x13 GPIO_ACTIVE_HIGH>;
/* PERST#: ADT pci-bridge0 function-perst, GPIO 80 */
reset-gpios = <&pinctrl_ap 80 GPIO_ACTIVE_LOW>;
apple,link-trained-by-bootloader;
status = "disabled";

#address-cells = <3>;
Expand Down Expand Up @@ -144,6 +166,108 @@
};
};

/* It answers only once port 0's root complex is up: pcie-apple then enables it */
&dart_apcie0 {
apple,manual-availability;
};

/*
* Nothing here drives the SMC pcIO outputs (apple,smc-pcio-gpio), and the AFE
* reset above uses gp1c, so the node goes. This board's templates,
* pKW8('pcIO', lo, hi) as (hi << 32) | lo, are the J716c's:
* 0 dp2hdmi_pwr_en (0x0, 0x1a0000)
* 1 hdmi_pwr_en (0x800000, 0xf0000)
* 2 afe-reset (0x10000, 0x11c0000)
*/
/delete-node/ &smc_pcio;

/*
* The SMC's first GPIO bank, the gP keys: the N1's power line is gP13.
* gpio-macsmc drives it with the line's ADT template, pKW4("gP13",
* 0x00800000): 0x00800000 | level, as m1n1 does.
*/
&smc {
smc_gpio: gpio {
compatible = "apple,smc-gpio";
#gpio-cells = <2>;
gpio-controller;
};
};

/*
* The power of the N1's port. iBoot leaves APCIE_SYS_GP, APCIE_PHY_SW and
* APHY_GP_AUS5 in automatic power management with the block gated (boot
* state 0x1000030f, 0x1400024f, 0x1000030f); the train needs them on and
* staying on, as m1n1 raises them (target active, auto-PM off). Always on:
* the port's link is kept through suspend-to-idle, and the host has no
* power domain of its own. Parents as the ADT names them, the
* register-less APCIE_SYS_GE left out. ADT pmgr devices APCIE_GP +0x118,
* FAB6_SOC +0x138, APCIE_SYS_GP +0x148, APCIE_PHY_SW +0x1b0,
* APHY_GP_AUS5_A +0x258, APHY_GP_AUS5 +0x280 (group 1).
*/
&pmgr1 {
ps_apcie_gp: power-controller@118 {
compatible = "apple,t6050-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate";
reg = <0x118 4>;
label = "apcie_gp";
#power-domain-cells = <0>;
#reset-cells = <0>;
apple,always-on;
};

ps_fab6_soc: power-controller@138 {
compatible = "apple,t6050-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate";
reg = <0x138 4>;
label = "fab6_soc";
#power-domain-cells = <0>;
#reset-cells = <0>;
apple,always-on;
};

ps_apcie_sys_gp: power-controller@148 {
compatible = "apple,t6050-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate";
reg = <0x148 4>;
label = "apcie_sys_gp";
power-domains = <&ps_apcie_gp>, <&ps_fab6_soc>;
#power-domain-cells = <0>;
#reset-cells = <0>;
apple,always-on;
apple,no-auto-pm;
};

ps_apcie_phy_sw: power-controller@1b0 {
compatible = "apple,t6050-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate";
reg = <0x1b0 4>;
label = "apcie_phy_sw";
power-domains = <&ps_apcie_sys_gp>;
#power-domain-cells = <0>;
#reset-cells = <0>;
apple,always-on;
apple,no-auto-pm;
};

ps_aphy_gp_aus5_a: power-controller@258 {
compatible = "apple,t6050-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate";
reg = <0x258 4>;
label = "aphy_gp_aus5_a";
power-domains = <&ps_apcie_phy_sw>;
#power-domain-cells = <0>;
#reset-cells = <0>;
apple,always-on;
};

power-controller@280 {
compatible = "apple,t6050-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate";
reg = <0x280 4>;
label = "aphy_gp_aus5";
power-domains = <&ps_aphy_gp_aus5_a>;
#power-domain-cells = <0>;
#reset-cells = <0>;
apple,always-on;
apple,no-auto-pm;
};
};

/*
* Type-C, from the ADT:
* ATC0 usb-drd0 left-back hpm0 nub-spmi-a0 0x0c (the debug port, not described)
Expand Down Expand Up @@ -444,15 +568,5 @@
};
};

/*
* Nothing here drives the SMC pcIO outputs (apple,smc-pcio-gpio), and the AFE
* reset above uses gp1c, so the node goes. This board's templates,
* pKW8('pcIO', lo, hi) as (hi << 32) | lo, are the J716c's:
* 0 dp2hdmi_pwr_en (0x0, 0x1a0000)
* 1 hdmi_pwr_en (0x800000, 0xf0000)
* 2 afe-reset (0x10000, 0x11c0000)
*/
/delete-node/ &smc_pcio;

#define T6050_J716S
#include "t6050-peripherals.dtsi"
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
Loading
Loading