diff --git a/Documentation/devicetree/bindings/iommu/apple,dart.yaml b/Documentation/devicetree/bindings/iommu/apple,dart.yaml index 350e077e779b4..401b41f8ff18b 100644 --- a/Documentation/devicetree/bindings/iommu/apple,dart.yaml +++ b/Documentation/devicetree/bindings/iommu/apple,dart.yaml @@ -45,6 +45,7 @@ properties: - apple,t8132-dart - apple,t8140-dart - apple,t8142-dart + - apple,t8152-dart - const: apple,t8110-dart apple,managed-sids: diff --git a/Documentation/devicetree/bindings/pci/apple,pcie.yaml b/Documentation/devicetree/bindings/pci/apple,pcie.yaml index 3a499f802b8f6..d5510bafbef11 100644 --- a/Documentation/devicetree/bindings/pci/apple,pcie.yaml +++ b/Documentation/devicetree/bindings/pci/apple,pcie.yaml @@ -62,6 +62,7 @@ properties: - const: apple,t6020-pcie - const: apple,t6020-pcie - const: apple,t8140-pcie + - const: apple,t8152-pcie - const: apple,t8132-pcie - const: apple,t8103-pciec - items: @@ -319,20 +320,38 @@ allOf: interrupts: maxItems: 3 else: - properties: - reg-names: - minItems: 3 - items: - - const: config - - const: rc - - const: port0 - - const: port1 - - const: port2 - - const: port3 - - const: phy0 - - const: phy1 - - const: phy2 - - const: phy3 + if: + properties: + compatible: + contains: + const: apple,t8152-pcie + then: + properties: + reg: + minItems: 4 + maxItems: 8 + reg-names: + minItems: 4 + maxItems: 8 + items: + enum: [config, rc, port0, phy0, port1, phy1, port2, phy2] + interrupts: + maxItems: 3 + else: + properties: + reg-names: + minItems: 3 + items: + - const: config + - const: rc + - const: port0 + - const: port1 + - const: port2 + - const: port3 + - const: phy0 + - const: phy1 + - const: phy2 + - const: phy3 patternProperties: "^pci@": properties: diff --git a/Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml index edae16e33adbd..1c74f8ccc37a2 100644 --- a/Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml @@ -26,6 +26,7 @@ properties: - apple,t8122-pinctrl - apple,t8132-pinctrl - apple,t8140-pinctrl + - apple,t8152-pinctrl - const: apple,t8103-pinctrl - items: # Do not add additional SoC to this list. diff --git a/arch/arm64/boot/dts/apple/t8152-j873-n1.dtsi b/arch/arm64/boot/dts/apple/t8152-j873-n1.dtsi new file mode 100644 index 0000000000000..ffa33863f782b --- /dev/null +++ b/arch/arm64/boot/dts/apple/t8152-j873-n1.dtsi @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * J873g N1 on APCIE port 0. Aura releases the SMC-controlled N1 reset, + * initializes the common PHY and applies the inactive DART's tunables. + * Linux owns port training and the three function-specific DMA streams. + * Resources follow the J873g ADT and the public J873 PCIe bring-up tree. + */ +#include + +/ { + soc { + pinctrl_ap: pinctrl@31a000000 { + compatible = "apple,t8152-pinctrl", "apple,t8103-pinctrl"; + reg = <0x3 0x1a000000 0x0 0x100000>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl_ap 0 0 224>; + apple,npins = <224>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = , + , + , + , + , + , + ; + }; + + pcie0_dart: iommu@388000000 { + compatible = "apple,t8152-dart", "apple,t8110-dart"; + reg = <0x3 0x88000000 0x0 0xc000>; + #iommu-cells = <1>; + interrupts = ; + }; + + pcie: pcie@1cb0000000 { + compatible = "apple,t8152-pcie"; + device_type = "pci"; + reg = <0x1c 0xb0000000 0x0 0x1000000>, + <0x3 0x8c000000 0x0 0x4000>, + <0x3 0x88028000 0x0 0x4000>, + <0x3 0x8f010000 0x0 0x4000>; + reg-names = "config", "rc", "port0", "phy0"; + interrupts = ; + msi-controller; + msi-parent = <&pcie>; + msi-ranges = <&aic AIC_IRQ 1879 IRQ_TYPE_EDGE_RISING 32>; + iommu-map = <0x100 &pcie0_dart 1 1>, + <0x101 &pcie0_dart 2 1>, + <0x102 &pcie0_dart 3 1>; + iommu-map-mask = <0xffff>; + bus-range = <0 1>; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x43000000 0xb 0xc0000000 0xb 0xc0000000 0x0 0x20000000>, + <0x02000000 0x0 0x80000000 0xb 0x80000000 0x0 0x40000000>; + dma-coherent; + + port00: pci@0,0 { + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + reset-gpios = <&pinctrl_ap 3 GPIO_ACTIVE_LOW>; + bus-range = <1 1>; + #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>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apple/t8152-j873g.dts b/arch/arm64/boot/dts/apple/t8152-j873g.dts index 4bb70a95ec1db..f4ccb05ba0aab 100644 --- a/arch/arm64/boot/dts/apple/t8152-j873g.dts +++ b/arch/arm64/boot/dts/apple/t8152-j873g.dts @@ -20,7 +20,7 @@ #size-cells = <2>; interrupt-parent = <&aic>; - /* Request the m1n1 RAM-only handoff, without PCIe/DAPF setup. */ + /* Retain the RAM handoff and secondary CPU park contract. */ aurora,minimal-boot; aliases { @@ -282,3 +282,4 @@ }; #include "t8152-j873-gpu.dtsi" +#include "t8152-j873-n1.dtsi" diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c index 8664a9fd3b7c4..48453fd72e46b 100644 --- a/drivers/pci/controller/pcie-apple.c +++ b/drivers/pci/controller/pcie-apple.c @@ -88,6 +88,7 @@ MODULE_PARM_DESC(link_up_timeout, "PCIe link training timeout in milliseconds"); #define PHY_LANE_CFG_REFCLK1REQ BIT(1) #define PHY_LANE_CFG_REFCLK0ACK BIT(2) #define PHY_LANE_CFG_REFCLK1ACK BIT(3) +#define PHY_LANE_CFG_REFBUF_OFF BIT(4) #define PHY_LANE_CFG_REFCLKEN (BIT(9) | BIT(10)) #define PHY_LANE_CFG_REFCLKCGEN (BIT(30) | BIT(31)) #define PHY_LANE_CTL 0x00004 @@ -172,6 +173,10 @@ MODULE_PARM_DESC(link_up_timeout, "PCIe link training timeout in milliseconds"); #define PORT_T602X_MSIADDR 0x016c #define PORT_T602X_MSIADDR_HI 0x0170 #define PORT_T602X_PERST 0x082c +/* T8152: lane PIPE reset is released by clearing this after PERST#. */ +#define PORT_T8152_PIPE_RST BIT(16) +#define PORT_T8152_PIPE_RST_STS 0x00a8 +#define PORT_T8152_PIPE_RST_STS_LANES GENMASK(3, 0) #define PORT_T602X_RID2SID 0x3000 #define PORT_T602X_MSIMAP 0x3800 @@ -209,6 +214,13 @@ struct hw_info { * keeps its link while the domain stays on, see apple_pcie_hold_domain(). */ bool s2idle_hold_domain; + /* AppleT8152PCIePort::_initializeRefclkBuffer clears REFBUF_OFF. */ + bool refbuf_off; + /* + * APCIECoreRCGen5Port::enablePortHardware: after PERST#, wait for the + * lane PIPE reset status, then release PORT_T8152_PIPE_RST. + */ + bool pipe_rst; }; static const struct hw_info t8103_hw = { @@ -252,6 +264,20 @@ static const struct hw_info t8140_hw = { .root_bus_only = true, }; +/* T8152 (M6) apcie: T602x port layout, refclk buffer powered down by iBoot. */ +static const struct hw_info t8152_hw = { + .phy_lane_ctl = 0, + .port_msiaddr = PORT_T602X_MSIADDR, + .port_msiaddr_hi = PORT_T602X_MSIADDR_HI, + .port_refclk = 0, + .port_perst = PORT_T602X_PERST, + .port_rid2sid = PORT_T602X_RID2SID, + .port_msimap = PORT_T602X_MSIMAP, + .max_rid2sid = 512, + .refbuf_off = true, + .pipe_rst = true, +}; + static const struct hw_info t8103_pciec_hw = { .port_msiaddr = PORT_MSIADDR, .port_perst = PORT_PERST, @@ -1521,6 +1547,11 @@ static int apple_pcie_setup_refclk(struct apple_pcie *pcie, if (pcie->hw->phy_lane_ctl) rmw_clear(PHY_LANE_CTL_CFGACC, port->phy + pcie->hw->phy_lane_ctl); + if (pcie->hw->refbuf_off) { + rmw_clear(PHY_LANE_CFG_REFBUF_OFF, port->phy + PHY_LANE_CFG); + udelay(1); + } + rmw_set(PHY_LANE_CFG_REFCLKEN, port->phy + PHY_LANE_CFG); if (pcie->hw->port_refclk) @@ -1635,6 +1666,17 @@ static int apple_pcie_setup_link(struct apple_pcie *pcie, for (u32 idx = 0; idx < num_aux_resets; idx++) gpiod_set_value_cansleep(aux_reset[idx], 0); + if (pcie->hw->pipe_rst) { + ret = readl_relaxed_poll_timeout(port->base + PORT_T8152_PIPE_RST_STS, + stat, stat & PORT_T8152_PIPE_RST_STS_LANES, + 1, 20000); + if (ret < 0) { + dev_err(pcie->dev, "port %pOF lanes stuck in PIPE reset\n", np); + return ret; + } + rmw_clear(PORT_T8152_PIPE_RST, port->base + pcie->hw->port_perst); + } + /* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */ msleep(100); @@ -3941,6 +3983,7 @@ static const struct of_device_id apple_pcie_of_match[] = { { .compatible = "apple,t6000-pciec", .data = &t8112_pciec_hw }, /* T8132 currently inherits controller and PHY setup from m1n1. */ { .compatible = "apple,t8132-pcie", .data = &t602x_hw }, + { .compatible = "apple,t8152-pcie", .data = &t8152_hw }, { .compatible = "apple,t6020-pcie", .data = &t602x_hw }, { .compatible = "apple,t8140-pcie", .data = &t8140_hw }, { .compatible = "apple,pcie", .data = &t8103_hw },