diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-sa8775p.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-sa8775p.yaml index 63630a814f287..cd9c1aa5ad065 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie-sa8775p.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-sa8775p.yaml @@ -20,6 +20,7 @@ properties: - const: qcom,pcie-sa8775p - items: - enum: + - qcom,pcie-nord - qcom,pcie-qcs8300 - const: qcom,pcie-sa8775p diff --git a/Documentation/devicetree/bindings/phy/qcom,glymur-qmp-gen5x8-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,glymur-qmp-gen5x8-pcie-phy.yaml new file mode 100644 index 0000000000000..759f7f979dc6a --- /dev/null +++ b/Documentation/devicetree/bindings/phy/qcom,glymur-qmp-gen5x8-pcie-phy.yaml @@ -0,0 +1,177 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/qcom,glymur-qmp-gen5x8-pcie-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm QMP PCIe multiple link-mode PHY controller (PCIe, Glymur) + +maintainers: + - Qiang Yu + - Manivannan Sadhasivam + +description: | + The Glymur SoC uses a single PCIe Gen5 PHY hardware block for the + PCIe3a/PCIe3b controllers. This block supports two link modes, selected + at runtime via a TCSR syscon register: + + 1. x8 - a single 8-lane PHY instance is exposed (PCIe3a only) + 2. x4+x4 - two independent 4-lane PHY instances are exposed (PCIe3a and + PCIe3b) + + The node always describes both PHY instances ("port a" and "port b"), + regardless of which link mode is active on the board. + +properties: + compatible: + enum: + - qcom,glymur-qmp-gen5x8-pcie-phy + + reg: + maxItems: 2 + + reg-names: + items: + - const: port_a + - const: port_b + + clocks: + maxItems: 10 + + clock-names: + items: + - const: aux + - const: cfg_ahb + - const: ref + - const: rchng + - const: pipe + - const: phy_b_aux + - const: cfg_ahb_b + - const: rchng_b + - const: pipe_b + - const: pipediv2_b + + power-domains: + maxItems: 2 + + power-domain-names: + items: + - const: port_a + - const: port_b + + resets: + maxItems: 4 + + reset-names: + items: + - const: port_a + - const: port_a_nocsr + - const: port_b + - const: port_b_nocsr + + vdda-phy-supply: true + + vdda-pll-supply: true + + vdda-refgen0p9-supply: true + + vdda-refgen1p2-supply: true + + qcom,link-mode: + description: + Reference to a register in the TCSR syscon that reports the link + mode the PCIe PHY is currently configured for, either a single x8 + link or two independent x4 links. The link mode is programmed by + firmware before Linux boots; this property is only used to read + the active link mode, specified as a phandle to the syscon and + the register offset. + $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle of TCSR syscon + - description: offset of link mode register + + "#clock-cells": + const: 1 + + clock-output-names: + items: + - description: Name of the PHY A pipe clock output. + - description: Name of the PHY B pipe clock output. + + "#phy-cells": + const: 1 + description: + The cell is the index of the sub-PHY within the active link + mode, e.g. on Glymur, 0 for "port a" and 1 for "port b" in + x4x4 mode, and only index 0 (the single wide PHY) is valid in + x8 mode. + +required: + - compatible + - reg + - reg-names + - clocks + - clock-names + - power-domains + - power-domain-names + - resets + - reset-names + - vdda-phy-supply + - vdda-pll-supply + - vdda-refgen0p9-supply + - vdda-refgen1p2-supply + - qcom,link-mode + - "#clock-cells" + - clock-output-names + - "#phy-cells" + +additionalProperties: false + +examples: + - | + #include + #include + + phy@f00000 { + compatible = "qcom,glymur-qmp-gen5x8-pcie-phy"; + reg = <0x00f00000 0x10000>, <0x00f10000 0x10000>; + reg-names = "port_a", "port_b"; + + clocks = <&gcc GCC_PCIE_PHY_3A_AUX_CLK>, + <&gcc GCC_PCIE_3A_CFG_AHB_CLK>, + <&tcsr TCSR_PCIE_3_CLKREF_EN>, + <&gcc GCC_PCIE_3A_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_3A_PIPE_CLK>, + <&gcc GCC_PCIE_PHY_3B_AUX_CLK>, + <&gcc GCC_PCIE_3B_CFG_AHB_CLK>, + <&gcc GCC_PCIE_3B_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_3B_PIPE_CLK>, + <&gcc GCC_PCIE_3B_PIPE_DIV2_CLK>; + clock-names = "aux", "cfg_ahb", "ref", "rchng", "pipe", + "phy_b_aux", "cfg_ahb_b", "rchng_b", "pipe_b", + "pipediv2_b"; + + resets = <&gcc GCC_PCIE_3A_PHY_BCR>, + <&gcc GCC_PCIE_3A_NOCSR_COM_PHY_BCR>, + <&gcc GCC_PCIE_3B_PHY_BCR>, + <&gcc GCC_PCIE_3B_NOCSR_COM_PHY_BCR>; + reset-names = "port_a", "port_a_nocsr", "port_b", "port_b_nocsr"; + + power-domains = <&gcc GCC_PCIE_3A_PHY_GDSC>, + <&gcc GCC_PCIE_3B_PHY_GDSC>; + power-domain-names = "port_a", "port_b"; + + vdda-phy-supply = <&vreg_l3c>; + vdda-pll-supply = <&vreg_l2c>; + + vdda-refgen0p9-supply = <&vreg_l3c>; + vdda-refgen1p2-supply = <&vreg_l2c>; + + qcom,link-mode = <&tcsr 0x5000>; + + #clock-cells = <1>; + clock-output-names = "pcie3a_pipe_clk", "pcie3b_pipe_clk"; + + #phy-cells = <1>; + }; diff --git a/Documentation/devicetree/bindings/phy/qcom,nord-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,nord-qmp-pcie-phy.yaml new file mode 100644 index 0000000000000..6ac892fc1245b --- /dev/null +++ b/Documentation/devicetree/bindings/phy/qcom,nord-qmp-pcie-phy.yaml @@ -0,0 +1,292 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/qcom,nord-qmp-pcie-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm QMP Bifurcated PCIe PHY (Nord) + +maintainers: + - Krishna Chaitanya Chundru > + +description: | + The Nord PCIe PHY is a single bifurcated QMP (Qualcomm Multi-Protocol) + PHY with four independently-configurable lane segments (A/B/C/D). + A single DT node exposes all four segments via named register + regions. The active link mode is selected at boot time through the + qcom,link-mode syscon property: + + QMP_PCIE_NORD_MODE_X16 (0) — all four segments ganged as a single + x16 PHY; the consuming controller references segment 0. + + QMP_PCIE_NORD_MODE_X8_X8 (1) — segment A (x8) + segments B+C+D + ganged (x8); each group is referenced through its own + #phy-cells = <1> argument (0 or 1). + + QMP_PCIE_NORD_MODE_X8_X4_X4 (2) — segment A (x8) + segment B (x4) + + segments C+D ganged (x4). + + QMP_PCIE_NORD_MODE_X8_X4_X2_X2 (3) — default: four independent PHY + instances (x8 + x4 + x2 + x2); each PCIe controller references + its own segment through a #phy-cells = <1> argument (0–3). + + All four segments share a single auxiliary-clock domain gate + (gcc_pcie_a_phy_aux_clk) and a single master GDSC + (GCC_PCIE_A_PHY_GDSC). Segments B/C/D additionally vote their own + per-segment GDSC sub-gate alongside the master. + +properties: + compatible: + enum: + - qcom,nord-qmp-gen5x16-pcie-phy + + reg: + maxItems: 4 + + reg-names: + items: + - const: seg_a + - const: seg_b + - const: seg_c + - const: seg_d + + clocks: + maxItems: 13 + + clock-names: + items: + - const: aux_a + - const: rchng_a + - const: pipe_a + - const: aux_b + - const: rchng_b + - const: pipe_b + - const: aux_c + - const: rchng_c + - const: pipe_c + - const: aux_d + - const: rchng_d + - const: pipe_d + - const: ref + + power-domains: + maxItems: 4 + + power-domain-names: + items: + - const: phy_a_gdsc + - const: phy_b_gdsc + - const: phy_c_gdsc + - const: phy_d_gdsc + + resets: + maxItems: 12 + + reset-names: + items: + - const: phy_a + - const: phy_cfg_ahb_a + - const: nocsr_a + - const: phy_b + - const: phy_cfg_ahb_b + - const: nocsr_b + - const: phy_c + - const: phy_cfg_ahb_c + - const: nocsr_c + - const: phy_d + - const: phy_cfg_ahb_d + - const: nocsr_d + + vdda-phy-a-supply: true + + vdda-phy-b-supply: true + + vdda-phy-c-supply: true + + vdda-phy-d-supply: true + + vdda-pll-a-supply: true + + vdda-pll-b-supply: true + + vdda-pll-c-supply: true + + vdda-pll-d-supply: true + + vdda-qref-a-supply: true + + vdda-qref-b-supply: true + + vdda-qref-c-supply: true + + vdda-qref-d-supply: true + + qcom,link-mode: + description: | + Reference to the TCSR syscon and the offset of the + TCSR_PCIE_LINK_CONFIG_MODE register (bits[1:0]). This register is + programmed by the bootloader; the Linux driver reads it at probe time + to discover the active lane topology: + 0 (QMP_PCIE_NORD_MODE_X16) — all segments ganged as x16 + 1 (QMP_PCIE_NORD_MODE_X8_X8) — x8 (seg A) + x8 (segs B+C+D) + 2 (QMP_PCIE_NORD_MODE_X8_X4_X4) — x8 (A) + x4 (B) + x4 (C+D) + 3 (QMP_PCIE_NORD_MODE_X8_X4_X2_X2)— x8 (A) + x4 (B) + x2 (C) + x2 (D) + $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: Phandle of the TCSR syscon + - description: Offset of TCSR_PCIE_LINK_CONFIG_MODE register + + "#clock-cells": + const: 1 + description: | + Selects the pipe clock output by segment index (0=A, 1=B, 2=C, 3=D). + GCC pipe-clock mux parents reference this provider. + + clock-output-names: + minItems: 1 + maxItems: 4 + description: Names for each segment pipe clock output. + + "#phy-cells": + const: 1 + description: | + Selects the PHY instance by segment index: + 0 — Segment A (up to Gen4 x8; anchor in x16 mode) + 1 — Segment B (up to Gen4 x4) + 2 — Segment C (up to Gen2 x2) + 3 — Segment D (up to Gen2 x2) + +required: + - compatible + - reg + - reg-names + - clocks + - clock-names + - power-domains + - power-domain-names + - resets + - reset-names + - qcom,link-mode + - "#clock-cells" + - clock-output-names + - "#phy-cells" + +additionalProperties: false + +examples: + - | + #include + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + pcie_phy: phy@1b00000 { + compatible = "qcom,nord-qmp-gen5x16-pcie-phy"; + + reg = <0x0 0x01b00000 0x0 0x10000>, + <0x0 0x01b10000 0x0 0x10000>, + <0x0 0x01b20000 0x0 0x10000>, + <0x0 0x01b30000 0x0 0x10000>; + reg-names = "seg_a", + "seg_b", + "seg_c", + "seg_d"; + + clocks = <&gcc GCC_PCIE_A_PHY_AUX_CLK>, + <&gcc GCC_PCIE_A_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_A_PIPE_CLK>, + <&gcc GCC_PCIE_B_PHY_AUX_CLK>, + <&gcc GCC_PCIE_B_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_B_PIPE_CLK>, + <&gcc GCC_PCIE_C_PHY_AUX_CLK>, + <&gcc GCC_PCIE_C_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_C_PIPE_CLK>, + <&gcc GCC_PCIE_D_PHY_AUX_CLK>, + <&gcc GCC_PCIE_D_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_D_PIPE_CLK>, + <&tcsrcc TCSR_PCIE_CLKREF_EN>; + clock-names = "aux_a", + "rchng_a", + "pipe_a", + "aux_b", + "rchng_b", + "pipe_b", + "aux_c", + "rchng_c", + "pipe_c", + "aux_d", + "rchng_d", + "pipe_d", + "ref"; + + assigned-clocks = <&gcc GCC_PCIE_A_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_B_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_C_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_D_PHY_RCHNG_CLK>; + assigned-clock-rates = <100000000>, <100000000>, + <100000000>, <100000000>; + + power-domains = <&gcc GCC_PCIE_A_PHY_GDSC>, + <&gcc GCC_PCIE_B_PHY_GDSC>, + <&gcc GCC_PCIE_C_PHY_GDSC>, + <&gcc GCC_PCIE_D_PHY_GDSC>; + power-domain-names = "phy_a_gdsc", + "phy_b_gdsc", + "phy_c_gdsc", + "phy_d_gdsc"; + + resets = <&gcc GCC_PCIE_A_PHY_COM_BCR>, + <&gcc GCC_PCIE_A_PHY_CFG_AHB_BCR>, + <&gcc GCC_PCIE_A_NOCSR_COM_PHY_BCR>, + <&gcc GCC_PCIE_B_PHY_COM_BCR>, + <&gcc GCC_PCIE_B_PHY_CFG_AHB_BCR>, + <&gcc GCC_PCIE_B_NOCSR_COM_PHY_BCR>, + <&gcc GCC_PCIE_C_PHY_COM_BCR>, + <&gcc GCC_PCIE_C_PHY_CFG_AHB_BCR>, + <&gcc GCC_PCIE_C_NOCSR_COM_PHY_BCR>, + <&gcc GCC_PCIE_D_PHY_COM_BCR>, + <&gcc GCC_PCIE_D_PHY_CFG_AHB_BCR>, + <&gcc GCC_PCIE_D_NOCSR_COM_PHY_BCR>; + reset-names = "phy_a", + "phy_cfg_ahb_a", + "nocsr_a", + "phy_b", + "phy_cfg_ahb_b", + "nocsr_b", + "phy_c", + "phy_cfg_ahb_c", + "nocsr_c", + "phy_d", + "phy_cfg_ahb_d", + "nocsr_d"; + + vdda-phy-a-supply = <&vreg_l6a_1p2>; + vdda-phy-b-supply = <&vreg_l4a_1p2>; + vdda-phy-c-supply = <&vreg_l4a_1p2>; + vdda-phy-d-supply = <&vreg_l4a_1p2>; + vdda-pll-a-supply = <&vreg_l1e_0p9>; + vdda-pll-b-supply = <&vreg_l1e_0p9>; + vdda-pll-c-supply = <&vreg_l1e_0p9>; + vdda-pll-d-supply = <&vreg_l1e_0p9>; + vdda-qref-a-supply = <&vreg_l2e_0p9>; + vdda-qref-b-supply = <&vreg_l2e_0p9>; + vdda-qref-c-supply = <&vreg_l2e_0p9>; + vdda-qref-d-supply = <&vreg_l2e_0p9>; + + /* TCSR_PCIE_LINK_CONFIG_MODE at TCSR base + 0x71050; driver reads this */ + qcom,link-mode = <&tcsr 0x71050>; + + #clock-cells = <1>; + clock-output-names = "pcie_a_pipe_clk", + "pcie_b_pipe_clk", + "pcie_c_pipe_clk", + "pcie_d_pipe_clk"; + + #phy-cells = <1>; + status = "disabled"; + }; + }; diff --git a/arch/arm64/boot/dts/qcom/nord-embedded.dtsi b/arch/arm64/boot/dts/qcom/nord-embedded.dtsi index 2eef33af5aa87..77e55615d0a26 100644 --- a/arch/arm64/boot/dts/qcom/nord-embedded.dtsi +++ b/arch/arm64/boot/dts/qcom/nord-embedded.dtsi @@ -635,10 +635,10 @@ reg = <0x0 0x00100000 0x0 0x1f4200>; clocks = <&bi_tcxo_div2>, <&sleep_clk>, - <0>, - <0>, - <0>, - <0>; + <&pcie_phy 0>, + <&pcie_phy 1>, + <&pcie_phy 2>, + <&pcie_phy 3>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; @@ -1213,6 +1213,1119 @@ #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; + + pcie_smmu: iommu@9980000 { + compatible = "arm,smmu-v3"; + reg = <0x0 0x9980000 0x0 0x20000>; + interrupts = , + , + ; + interrupt-names = "eventq", + "cmdq-sync", + "gerror"; + dma-coherent; + #iommu-cells = <1>; + }; + + pcie_phy: phy@1b00000 { + compatible = "qcom,nord-qmp-gen4x16-pcie-phy"; + + reg = <0x0 0x01b00000 0x0 0x10000>, + <0x0 0x01b10000 0x0 0x10000>, + <0x0 0x01b20000 0x0 0x10000>, + <0x0 0x01b30000 0x0 0x10000>; + reg-names = "seg_a", + "seg_b", + "seg_c", + "seg_d"; + + clocks = <&gcc GCC_PCIE_A_PHY_AUX_CLK>, + <&gcc GCC_PCIE_A_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_A_PIPE_CLK>, + <&gcc GCC_PCIE_B_PHY_AUX_CLK>, + <&gcc GCC_PCIE_B_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_B_PIPE_CLK>, + <&gcc GCC_PCIE_C_PHY_AUX_CLK>, + <&gcc GCC_PCIE_C_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_C_PIPE_CLK>, + <&gcc GCC_PCIE_D_PHY_AUX_CLK>, + <&gcc GCC_PCIE_D_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_D_PIPE_CLK>, + <&tcsrcc TCSR_PCIE_CLKREF_EN>; + + clock-names = "aux_a", + "rchng_a", + "pipe_a", + "aux_b", + "rchng_b", + "pipe_b", + "aux_c", + "rchng_c", + "pipe_c", + "aux_d", + "rchng_d", + "pipe_d", + "ref"; + + assigned-clocks = <&gcc GCC_PCIE_A_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_B_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_C_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_D_PHY_RCHNG_CLK>; + assigned-clock-rates = <100000000>, <100000000>, + <100000000>, <100000000>; + + power-domains = <&gcc GCC_PCIE_A_PHY_GDSC>, + <&gcc GCC_PCIE_B_PHY_GDSC>, + <&gcc GCC_PCIE_C_PHY_GDSC>, + <&gcc GCC_PCIE_D_PHY_GDSC>; + power-domain-names = "phy_a_gdsc", + "phy_b_gdsc", + "phy_c_gdsc", + "phy_d_gdsc"; + + resets = <&gcc GCC_PCIE_A_PHY_COM_BCR>, + <&gcc GCC_PCIE_A_PHY_CFG_AHB_BCR>, + <&gcc GCC_PCIE_A_NOCSR_COM_PHY_BCR>, + <&gcc GCC_PCIE_B_PHY_COM_BCR>, + <&gcc GCC_PCIE_B_PHY_CFG_AHB_BCR>, + <&gcc GCC_PCIE_B_NOCSR_COM_PHY_BCR>, + <&gcc GCC_PCIE_C_PHY_COM_BCR>, + <&gcc GCC_PCIE_C_PHY_CFG_AHB_BCR>, + <&gcc GCC_PCIE_C_NOCSR_COM_PHY_BCR>, + <&gcc GCC_PCIE_D_PHY_COM_BCR>, + <&gcc GCC_PCIE_D_PHY_CFG_AHB_BCR>, + <&gcc GCC_PCIE_D_NOCSR_COM_PHY_BCR>; + reset-names = "phy_a", + "phy_cfg_ahb_a", + "nocsr_a", + "phy_b", + "phy_cfg_ahb_b", + "nocsr_b", + "phy_c", + "phy_cfg_ahb_c", + "nocsr_c", + "phy_d", + "phy_cfg_ahb_d", + "nocsr_d"; + + qcom,link-mode = <&tcsr 0x71050>; + + #clock-cells = <1>; + clock-output-names = "pcie_a_pipe_clk", + "pcie_b_pipe_clk", + "pcie_c_pipe_clk", + "pcie_d_pipe_clk"; + #phy-cells = <1>; + + status = "disabled"; + }; + + pcie0: pci@1b80000 { + compatible = "qcom,pcie-nord", "qcom,pcie-sa8775p"; + + reg = <0x00 0x01b80000 0x00 0x00004000>, + <0x00 0x40000000 0x00 0x00000f20>, + <0x00 0x40000f20 0x00 0x000000a8>, + <0x00 0x40010000 0x00 0x00020000>, + <0x00 0x40100000 0x00 0x00100000>, + <0x00 0x01b84000 0x00 0x00001000>; + reg-names = "parf", + "dbi", + "elbi", + "atu", + "config", + "mhi"; + + ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>, + <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0xfd00000>; + + bus-range = <0x00 0xff>; + device_type = "pci"; + linux,pci-domain = <0>; + num-lanes = <8>; + + operating-points-v2 = <&pcie0_opp_table>; + + #address-cells = <3>; + #size-cells = <2>; + + clocks = <&gcc GCC_PCIE_A_AUX_CLK>, + <&gcc GCC_PCIE_A_CFG_AHB_CLK>, + <&gcc GCC_PCIE_A_MSTR_AXI_CLK>, + <&gcc GCC_PCIE_A_SLV_AXI_CLK>, + <&gcc GCC_PCIE_A_SLV_Q2A_AXI_CLK>; + clock-names = "aux", + "cfg", + "bus_master", + "bus_slave", + "slave_q2a"; + + assigned-clocks = <&gcc GCC_PCIE_A_AUX_CLK>; + assigned-clock-rates = <19200000>; + + dma-coherent; + + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "msi0", + "msi1", + "msi2", + "msi3", + "msi4", + "msi5", + "msi6", + "msi7", + "global"; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc 0 0 0 149 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc 0 0 0 150 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc 0 0 0 151 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc 0 0 0 152 IRQ_TYPE_LEVEL_HIGH>; + + interconnects = <&pcie_data_inbound MASTER_PCIE_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_PCIE_0 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "pcie-mem", + "cpu-pcie"; + + iommu-map = <0x0 &pcie_smmu 0x0000 0x10000>; + + msi-map = <0x0 &gic_its 0x80000 0x10000>; + + power-domains = <&gcc GCC_PCIE_A_GDSC>; + + resets = <&gcc GCC_PCIE_A_BCR>, + <&gcc GCC_PCIE_A_LINK_DOWN_BCR>; + reset-names = "pci", + "link_down"; + + pinctrl-0 = <&pcie0_default>; + pinctrl-names = "default"; + + status = "disabled"; + + pcie0_opp_table: opp-table { + compatible = "operating-points-v2"; + + /* GEN 1 x1 */ + opp-2500000-1 { + opp-hz = /bits/ 64 <2500000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <250000 1>; + opp-level = <1>; + }; + + /* GEN 1 x2 */ + opp-5000000-1 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <1>; + }; + + /* GEN 1 x4 */ + opp-10000000-1 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1000000 1>; + opp-level = <1>; + }; + + /* GEN 1 x8 */ + opp-20000000-1 { + opp-hz = /bits/ 64 <20000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <2000000 1>; + opp-level = <1>; + }; + + /* GEN 1 x16 */ + opp-40000000-1 { + opp-hz = /bits/ 64 <40000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <4000000 1>; + opp-level = <1>; + }; + + /* GEN 2 x1 */ + opp-5000000-2 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <2>; + }; + + /* GEN 2 x2 */ + opp-10000000-2 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1000000 1>; + opp-level = <2>; + }; + + /* GEN 2 x4 */ + opp-20000000-2 { + opp-hz = /bits/ 64 <20000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <2000000 1>; + opp-level = <2>; + }; + + /* GEN 2 x8 */ + opp-40000000-2 { + opp-hz = /bits/ 64 <40000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <4000000 1>; + opp-level = <2>; + }; + + /* GEN 2 x16 */ + opp-80000000-2 { + opp-hz = /bits/ 64 <80000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <8000000 1>; + opp-level = <2>; + }; + + /* GEN 3 x1 */ + opp-8000000-3 { + opp-hz = /bits/ 64 <8000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <984500 1>; + opp-level = <3>; + }; + + /* GEN 3 x2 */ + opp-16000000-3 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1969000 1>; + opp-level = <3>; + }; + + /* GEN 3 x4 */ + opp-32000000-3 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <3938000 1>; + opp-level = <3>; + }; + + /* GEN 3 x8 */ + opp-64000000-3 { + opp-hz = /bits/ 64 <64000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <7876000 1>; + opp-level = <3>; + }; + + /* GEN 3 x16 */ + opp-128000000-3 { + opp-hz = /bits/ 64 <128000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <15753000 1>; + opp-level = <3>; + }; + + /* GEN 4 x1 */ + opp-16000000-4 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <1969000 1>; + opp-level = <4>; + }; + + /* GEN 4 x2 */ + opp-32000000-4 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <3938000 1>; + opp-level = <4>; + }; + + /* GEN 4 x4 */ + opp-64000000-4 { + opp-hz = /bits/ 64 <64000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <7876000 1>; + opp-level = <4>; + }; + + /* GEN 4 x8 */ + opp-128000000-4 { + opp-hz = /bits/ 64 <128000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <15753000 1>; + opp-level = <4>; + }; + + /* GEN 4 x16 */ + opp-256000000-4 { + opp-hz = /bits/ 64 <256000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <31506000 1>; + opp-level = <4>; + }; + + /* GEN 5 x1 */ + opp-32000000-5 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <3938000 1>; + opp-level = <5>; + }; + + /* GEN 5 x2 */ + opp-64000000-5 { + opp-hz = /bits/ 64 <64000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <7876000 1>; + opp-level = <5>; + }; + + /* GEN 5 x4 */ + opp-128000000-5 { + opp-hz = /bits/ 64 <128000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <15753000 1>; + opp-level = <5>; + }; + + /* GEN 5 x8 */ + opp-256000000-5 { + opp-hz = /bits/ 64 <256000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <31506000 1>; + opp-level = <5>; + }; + + /* GEN 5 x16 */ + opp-512000000-5 { + opp-hz = /bits/ 64 <512000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <63012000 1>; + opp-level = <5>; + }; + }; + + pcie0_port0: pcie@0 { + compatible = "pciclass,0604"; + + reg = <0 0 0 0 0>; + + bus-range = <0x01 0xff>; + + device_type = "pci"; + + phys = <&pcie_phy QMP_PHY_SELECTOR_0>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + }; + }; + + pcie1: pci@1b88000 { + compatible = "qcom,pcie-nord", "qcom,pcie-sa8775p"; + + reg = <0x00 0x01b88000 0x00 0x00004000>, + <0x00 0x50000000 0x00 0x00000f20>, + <0x00 0x50000f20 0x00 0x000000a8>, + <0x00 0x50010000 0x00 0x00010000>, + <0x00 0x50100000 0x00 0x00100000>, + <0x00 0x01b8c000 0x00 0x00001000>; + reg-names = "parf", + "dbi", + "elbi", + "atu", + "config", + "mhi"; + + ranges = <0x01000000 0x0 0x00000000 0x0 0x50200000 0x0 0x100000>, + <0x02000000 0x0 0x50300000 0x0 0x50300000 0x0 0xfd00000>; + + bus-range = <0x00 0xff>; + device_type = "pci"; + linux,pci-domain = <1>; + num-lanes = <4>; + + operating-points-v2 = <&pcie1_opp_table>; + + #address-cells = <3>; + #size-cells = <2>; + + clocks = <&gcc GCC_PCIE_B_AUX_CLK>, + <&gcc GCC_PCIE_B_CFG_AHB_CLK>, + <&gcc GCC_PCIE_B_MSTR_AXI_CLK>, + <&gcc GCC_PCIE_B_SLV_AXI_CLK>, + <&gcc GCC_PCIE_B_SLV_Q2A_AXI_CLK>; + clock-names = "aux", + "cfg", + "bus_master", + "bus_slave", + "slave_q2a"; + + assigned-clocks = <&gcc GCC_PCIE_B_AUX_CLK>; + assigned-clock-rates = <19200000>; + + dma-coherent; + + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "msi0", + "msi1", + "msi2", + "msi3", + "msi4", + "msi5", + "msi6", + "msi7", + "global"; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc 0 0 0 835 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc 0 0 0 351 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc 0 0 0 830 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc 0 0 0 348 IRQ_TYPE_LEVEL_HIGH>; + + msi-map = <0x0 &gic_its 0x90000 0x10000>; + + interconnects = <&pcie_data_inbound MASTER_PCIE_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_PCIE_1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "pcie-mem", + "cpu-pcie"; + + iommu-map = <0x0 &pcie_smmu 0x10000 0x10000>; + + power-domains = <&gcc GCC_PCIE_B_GDSC>; + + resets = <&gcc GCC_PCIE_B_BCR>, + <&gcc GCC_PCIE_B_LINK_DOWN_BCR>; + reset-names = "pci", + "link_down"; + + pinctrl-0 = <&pcie1_default>; + pinctrl-names = "default"; + + status = "disabled"; + + pcie1_opp_table: opp-table { + compatible = "operating-points-v2"; + + /* GEN 1 x1 */ + opp-2500000-1 { + opp-hz = /bits/ 64 <2500000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <250000 1>; + opp-level = <1>; + }; + + /* GEN 1 x2 */ + opp-5000000-1 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <1>; + }; + + /* GEN 1 x4 */ + opp-10000000-1 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1000000 1>; + opp-level = <1>; + }; + + /* GEN 1 x8 */ + opp-20000000-1 { + opp-hz = /bits/ 64 <20000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <2000000 1>; + opp-level = <1>; + }; + + /* GEN 2 x1 */ + opp-5000000-2 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <2>; + }; + + /* GEN 2 x2 */ + opp-10000000-2 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1000000 1>; + opp-level = <2>; + }; + + /* GEN 2 x4 */ + opp-20000000-2 { + opp-hz = /bits/ 64 <20000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <2000000 1>; + opp-level = <2>; + }; + + /* GEN 2 x8 */ + opp-40000000-2 { + opp-hz = /bits/ 64 <40000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <4000000 1>; + opp-level = <2>; + }; + + /* GEN 3 x1 */ + opp-8000000-3 { + opp-hz = /bits/ 64 <8000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <984500 1>; + opp-level = <3>; + }; + + /* GEN 3 x2 */ + opp-16000000-3 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1969000 1>; + opp-level = <3>; + }; + + /* GEN 3 x4 */ + opp-32000000-3 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <3938000 1>; + opp-level = <3>; + }; + + /* GEN 3 x8 */ + opp-64000000-3 { + opp-hz = /bits/ 64 <64000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <7876000 1>; + opp-level = <3>; + }; + + /* GEN 4 x1 */ + opp-16000000-4 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <1969000 1>; + opp-level = <4>; + }; + + /* GEN 4 x2 */ + opp-32000000-4 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <3938000 1>; + opp-level = <4>; + }; + + /* GEN 4 x4 */ + opp-64000000-4 { + opp-hz = /bits/ 64 <64000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <7876000 1>; + opp-level = <4>; + }; + + /* GEN 4 x8 */ + opp-128000000-4 { + opp-hz = /bits/ 64 <128000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <15753000 1>; + opp-level = <4>; + }; + + /* GEN 5 x1 */ + opp-32000000-5 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <3938000 1>; + opp-level = <5>; + }; + + /* GEN 5 x2 */ + opp-64000000-5 { + opp-hz = /bits/ 64 <64000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <7876000 1>; + opp-level = <5>; + }; + + /* GEN 5 x4 */ + opp-128000000-5 { + opp-hz = /bits/ 64 <128000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <15753000 1>; + opp-level = <5>; + }; + + /* GEN 5 x8 */ + opp-256000000-5 { + opp-hz = /bits/ 64 <256000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <31506000 1>; + opp-level = <5>; + }; + }; + + pcie1_port0: pcie@0 { + device_type = "pci"; + compatible = "pciclass,0604"; + reg = <0 0 0 0 0>; + bus-range = <0x01 0xff>; + + phys = <&pcie_phy QMP_PHY_SELECTOR_1>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + }; + }; + + pcie2: pci@1b90000 { + compatible = "qcom,pcie-nord", "qcom,pcie-sa8775p"; + + reg = <0x00 0x01b90000 0x00 0x00004000>, + <0x00 0x60000000 0x00 0x00000f20>, + <0x00 0x60000f20 0x00 0x000000a8>, + <0x00 0x60010000 0x00 0x00010000>, + <0x00 0x60100000 0x00 0x00100000>, + <0x00 0x01b94000 0x00 0x00001000>; + reg-names = "parf", + "dbi", + "elbi", + "atu", + "config", + "mhi"; + + ranges = <0x01000000 0x0 0x00000000 0x0 0x60200000 0x0 0x100000>, + <0x02000000 0x0 0x60300000 0x0 0x60300000 0x0 0xfd00000>; + + bus-range = <0x00 0xff>; + device_type = "pci"; + linux,pci-domain = <2>; + num-lanes = <2>; + + operating-points-v2 = <&pcie2_opp_table>; + + #address-cells = <3>; + #size-cells = <2>; + + clocks = <&gcc GCC_PCIE_C_AUX_CLK>, + <&gcc GCC_PCIE_C_CFG_AHB_CLK>, + <&gcc GCC_PCIE_C_MSTR_AXI_CLK>, + <&gcc GCC_PCIE_C_SLV_AXI_CLK>, + <&gcc GCC_PCIE_C_SLV_Q2A_AXI_CLK>; + clock-names = "aux", + "cfg", + "bus_master", + "bus_slave", + "slave_q2a"; + + assigned-clocks = <&gcc GCC_PCIE_C_AUX_CLK>; + assigned-clock-rates = <19200000>; + + dma-coherent; + + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "msi0", + "msi1", + "msi2", + "msi3", + "msi4", + "msi5", + "msi6", + "msi7", + "global"; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc 0 0 0 263 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc 0 0 0 154 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc 0 0 0 110 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc 0 0 0 258 IRQ_TYPE_LEVEL_HIGH>; + + interconnects = <&pcie_data_inbound MASTER_PCIE_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_PCIE_2 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "pcie-mem", + "cpu-pcie"; + + iommu-map = <0x0 &pcie_smmu 0x20000 0x10000>; + + msi-map = <0x0 &gic_its 0xa0000 0x10000>; + + power-domains = <&gcc GCC_PCIE_C_GDSC>; + + resets = <&gcc GCC_PCIE_C_BCR>, + <&gcc GCC_PCIE_C_LINK_DOWN_BCR>; + reset-names = "pci", + "link_down"; + + pinctrl-0 = <&pcie2_default>; + pinctrl-names = "default"; + + status = "disabled"; + + pcie2_opp_table: opp-table { + compatible = "operating-points-v2"; + + /* GEN 1 x1 */ + opp-2500000-1 { + opp-hz = /bits/ 64 <2500000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <250000 1>; + opp-level = <1>; + }; + + /* GEN 1 x2 */ + opp-5000000-1 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <1>; + }; + + /* GEN 1 x4 */ + opp-10000000-1 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1000000 1>; + opp-level = <1>; + }; + + /* GEN 2 x1 */ + opp-5000000-2 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <2>; + }; + + /* GEN 2 x2 */ + opp-10000000-2 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1000000 1>; + opp-level = <2>; + }; + + /* GEN 2 x4 */ + opp-20000000-2 { + opp-hz = /bits/ 64 <20000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <2000000 1>; + opp-level = <2>; + }; + + /* GEN 3 x1 */ + opp-8000000-3 { + opp-hz = /bits/ 64 <8000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <984500 1>; + opp-level = <3>; + }; + + /* GEN 3 x2 */ + opp-16000000-3 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1969000 1>; + opp-level = <3>; + }; + + /* GEN 3 x4 */ + opp-32000000-3 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <3938000 1>; + opp-level = <3>; + }; + + /* GEN 4 x1 */ + opp-16000000-4 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <1969000 1>; + opp-level = <4>; + }; + + /* GEN 4 x2 */ + opp-32000000-4 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <3938000 1>; + opp-level = <4>; + }; + + /* GEN 4 x4 */ + opp-64000000-4 { + opp-hz = /bits/ 64 <64000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <7876000 1>; + opp-level = <4>; + }; + + /* GEN 5 x1 */ + opp-32000000-5 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <3938000 1>; + opp-level = <5>; + }; + + /* GEN 5 x2 */ + opp-64000000-5 { + opp-hz = /bits/ 64 <64000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <7876000 1>; + opp-level = <5>; + }; + + /* GEN 5 x4 */ + opp-128000000-5 { + opp-hz = /bits/ 64 <128000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <15753000 1>; + opp-level = <5>; + }; + }; + + pcie2_port0: pcie@0 { + device_type = "pci"; + compatible = "pciclass,0604"; + reg = <0 0 0 0 0>; + bus-range = <0x01 0xff>; + + phys = <&pcie_phy QMP_PHY_SELECTOR_2>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + }; + }; + + pcie3: pci@1b98000 { + compatible = "qcom,pcie-nord", "qcom,pcie-sa8775p"; + + reg = <0x00 0x01b98000 0x00 0x00004000>, + <0x00 0x70000000 0x00 0x00000f20>, + <0x00 0x70000f20 0x00 0x000000a8>, + <0x00 0x70010000 0x00 0x00010000>, + <0x00 0x70100000 0x00 0x00100000>, + <0x00 0x01b9c000 0x00 0x00001000>; + reg-names = "parf", + "dbi", + "elbi", + "atu", + "config", + "mhi"; + + ranges = <0x01000000 0x0 0x00000000 0x0 0x70200000 0x0 0x100000>, + <0x02000000 0x0 0x70300000 0x0 0x70300000 0x0 0xfd00000>; + + bus-range = <0x00 0xff>; + device_type = "pci"; + linux,pci-domain = <3>; + num-lanes = <2>; + + operating-points-v2 = <&pcie3_opp_table>; + + #address-cells = <3>; + #size-cells = <2>; + + clocks = <&gcc GCC_PCIE_D_AUX_CLK>, + <&gcc GCC_PCIE_D_CFG_AHB_CLK>, + <&gcc GCC_PCIE_D_MSTR_AXI_CLK>, + <&gcc GCC_PCIE_D_SLV_AXI_CLK>, + <&gcc GCC_PCIE_D_SLV_Q2A_AXI_CLK>; + clock-names = "aux", + "cfg", + "bus_master", + "bus_slave", + "slave_q2a"; + + assigned-clocks = <&gcc GCC_PCIE_D_AUX_CLK>; + assigned-clock-rates = <19200000>; + + dma-coherent; + + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "msi0", + "msi1", + "msi2", + "msi3", + "msi4", + "msi5", + "msi6", + "msi7", + "global"; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc 0 0 0 111 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc 0 0 0 246 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc 0 0 0 239 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc 0 0 0 234 IRQ_TYPE_LEVEL_HIGH>; + + interconnects = <&pcie_data_inbound MASTER_PCIE_3 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_PCIE_3 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "pcie-mem", + "cpu-pcie"; + + msi-map = <0x0 &gic_its 0xb0000 0x10000>; + + iommu-map = <0x0 &pcie_smmu 0x30000 0x10000>; + + power-domains = <&gcc GCC_PCIE_D_GDSC>; + + resets = <&gcc GCC_PCIE_D_BCR>, + <&gcc GCC_PCIE_D_LINK_DOWN_BCR>; + reset-names = "pci", + "link_down"; + + pinctrl-0 = <&pcie3_default>; + pinctrl-names = "default"; + + status = "disabled"; + + pcie3_opp_table: opp-table { + compatible = "operating-points-v2"; + + /* GEN 1 x1 */ + opp-2500000-1 { + opp-hz = /bits/ 64 <2500000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <250000 1>; + opp-level = <1>; + }; + + /* GEN 1 x2 */ + opp-5000000-1 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <1>; + }; + + /* GEN 2 x1 */ + opp-5000000-2 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <2>; + }; + + /* GEN 2 x2 */ + opp-10000000-2 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1000000 1>; + opp-level = <2>; + }; + + /* GEN 3 x1 */ + opp-8000000-3 { + opp-hz = /bits/ 64 <8000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <984500 1>; + opp-level = <3>; + }; + + /* GEN 3 x2 */ + opp-16000000-3 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1969000 1>; + opp-level = <3>; + }; + + /* GEN 4 x1 */ + opp-16000000-4 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <1969000 1>; + opp-level = <4>; + }; + + /* GEN 4 x2 */ + opp-32000000-4 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <3938000 1>; + opp-level = <4>; + }; + + /* GEN 5 x1 */ + opp-32000000-5 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <3938000 1>; + opp-level = <5>; + }; + + /* GEN 5 x2 */ + opp-64000000-5 { + opp-hz = /bits/ 64 <64000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <7876000 1>; + opp-level = <5>; + }; + }; + + pcie3_port0: pcie@0 { + device_type = "pci"; + compatible = "pciclass,0604"; + reg = <0 0 0 0 0>; + bus-range = <0x01 0xff>; + + phys = <&pcie_phy QMP_PHY_SELECTOR_3>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + }; + }; }; &tlmm { @@ -1760,6 +2873,98 @@ drive-strength = <2>; bias-disable; }; + + pcie0_default: pcie0-default-state { + wake-pins { + pins = "gpio0"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + clkreq-pins { + pins = "gpio1"; + function = "pcie0_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-pins { + pins = "gpio2"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + }; + + pcie1_default: pcie1-default-state { + wake-pins { + pins = "gpio3"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + clkreq-pins { + pins = "gpio4"; + function = "pcie1_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-pins { + pins = "gpio5"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + }; + + pcie2_default: pcie2-default-state { + wake-pins { + pins = "gpio6"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + clkreq-pins { + pins = "gpio7"; + function = "pcie2_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-pins { + pins = "gpio8"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + }; + + pcie3_default: pcie3-default-state { + wake-pins { + pins = "gpio9"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + clkreq-pins { + pins = "gpio10"; + function = "pcie3_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-pins { + pins = "gpio11"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + }; }; &uart0 { diff --git a/arch/arm64/boot/dts/qcom/nord-rrd.dts b/arch/arm64/boot/dts/qcom/nord-rrd.dts index ddc534e2214b4..d88f29f38b4c8 100644 --- a/arch/arm64/boot/dts/qcom/nord-rrd.dts +++ b/arch/arm64/boot/dts/qcom/nord-rrd.dts @@ -586,6 +586,55 @@ status = "okay"; }; +&pcie_phy { + vdda-phy-a-supply = <&vreg_l6a_1p2>; + vdda-phy-b-supply = <&vreg_l4a_1p2>; + vdda-phy-c-supply = <&vreg_l4a_1p2>; + vdda-phy-d-supply = <&vreg_l4a_1p2>; + vdda-pll-a-supply = <&vreg_l1e_0p9>; + vdda-pll-b-supply = <&vreg_l1e_0p9>; + vdda-pll-c-supply = <&vreg_l1e_0p9>; + vdda-pll-d-supply = <&vreg_l1e_0p9>; + vdda-qref-a-supply = <&vreg_l2e_0p9>; + vdda-qref-b-supply = <&vreg_l2e_0p9>; + vdda-qref-c-supply = <&vreg_l2e_0p9>; + vdda-qref-d-supply = <&vreg_l2e_0p9>; + + status = "okay"; +}; + +&pcie0 { + status = "okay"; +}; + +&pcie0_port0 { + reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; +}; + +&pcie1 { + status = "okay"; +}; + +&pcie1_port0 { + reset-gpios = <&tlmm 5 GPIO_ACTIVE_LOW>; +}; + +&pcie2 { + status = "okay"; +}; + +&pcie2_port0 { + reset-gpios = <&tlmm 8 GPIO_ACTIVE_LOW>; +}; + +&pcie3 { + status = "okay"; +}; + +&pcie3_port0 { + reset-gpios = <&tlmm 11 GPIO_ACTIVE_LOW>; +}; + &ufs_mem_hc { reset-gpios = <&tlmm 181 GPIO_ACTIVE_LOW>; diff --git a/arch/arm64/boot/dts/qcom/nord.dtsi b/arch/arm64/boot/dts/qcom/nord.dtsi index 34393c63a4c0e..cff9d1e286475 100644 --- a/arch/arm64/boot/dts/qcom/nord.dtsi +++ b/arch/arm64/boot/dts/qcom/nord.dtsi @@ -1051,8 +1051,8 @@ compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; - dma-ranges = <0 0 0 0 0x10 0>; - ranges = <0 0 0 0 0x10 0>; + dma-ranges = <0 0 0 0 0x100 0>; + ranges = <0 0 0 0 0x100 0>; qupv3_2: geniqup@8c0000 { compatible = "qcom,geni-se-qup"; diff --git a/drivers/clk/qcom/gcc-nord.c b/drivers/clk/qcom/gcc-nord.c index 5c9d25f53a6d2..0066f9b1586f7 100644 --- a/drivers/clk/qcom/gcc-nord.c +++ b/drivers/clk/qcom/gcc-nord.c @@ -1824,11 +1824,24 @@ static const u32 gcc_nord_critical_cbcrs[] = { 0x52468, /* GCC_PCIE_LINK_XO_CLK */ }; +static void clk_nord_regs_configure(struct device *dev, struct regmap *regmap) +{ + qcom_branch_set_force_mem_core(regmap, gcc_pcie_a_pipe_clk, true); + qcom_branch_set_force_periph_on(regmap, gcc_pcie_a_pipe_clk, true); + qcom_branch_set_force_mem_core(regmap, gcc_pcie_b_pipe_clk, true); + qcom_branch_set_force_periph_on(regmap, gcc_pcie_b_pipe_clk, true); + qcom_branch_set_force_mem_core(regmap, gcc_pcie_c_pipe_clk, true); + qcom_branch_set_force_periph_on(regmap, gcc_pcie_c_pipe_clk, true); + qcom_branch_set_force_mem_core(regmap, gcc_pcie_d_pipe_clk, true); + qcom_branch_set_force_periph_on(regmap, gcc_pcie_d_pipe_clk, true); +} + static const struct qcom_cc_driver_data gcc_nord_driver_data = { .dfs_rcgs = gcc_nord_dfs_clocks, .num_dfs_rcgs = ARRAY_SIZE(gcc_nord_dfs_clocks), .clk_cbcrs = gcc_nord_critical_cbcrs, .num_clk_cbcrs = ARRAY_SIZE(gcc_nord_critical_cbcrs), + .clk_regs_configure = clk_nord_regs_configure, }; static const struct qcom_cc_desc gcc_nord_desc = { diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 19daadee65f7c..365feb5de4f49 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -266,6 +266,14 @@ struct qcom_pcie_cfg { bool override_no_snoop; bool firmware_managed; bool no_l0s; + /* + * QCTDD11972446: some SA8775p-family instances (e.g. Nord) require + * PARF_SYS_CTRL CORE_CLK_CGC_DIS and AUX_PWR_DET to be set to work + * around a timing-convergence issue in PD. POR value of + * SLV_ACLK_CGC_DIS is already 1; this additionally sets + * CORE_CLK_CGC_DIS and AUX_PWR_DET. + */ + bool cgc_dis_workaround; }; struct qcom_pcie_perst { @@ -1073,11 +1081,18 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie) static int qcom_pcie_post_init_2_7_0(struct qcom_pcie *pcie) { const struct qcom_pcie_cfg *pcie_cfg = pcie->cfg; + int val; if (pcie_cfg->override_no_snoop) writel(WR_NO_SNOOP_OVERRIDE_EN | RD_NO_SNOOP_OVERRIDE_EN, pcie->parf + PARF_NO_SNOOP_OVERRIDE); + if (pcie_cfg->cgc_dis_workaround) { + val = readl(pcie->parf + PARF_SYS_CTRL); + val |= CORE_CLK_CGC_DIS | AUX_PWR_DET; + writel(val, pcie->parf + PARF_SYS_CTRL); + } + qcom_pcie_set_slot_nccs(pcie->pci); return 0; @@ -1577,6 +1592,7 @@ static const struct qcom_pcie_cfg cfg_1_34_0 = { .ops = &ops_1_9_0, .override_no_snoop = true, .no_l0s = true, + .cgc_dis_workaround = true, }; static const struct qcom_pcie_cfg cfg_2_1_0 = { diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig index ea33025a40fd0..02d809535694a 100644 --- a/drivers/phy/qualcomm/Kconfig +++ b/drivers/phy/qualcomm/Kconfig @@ -90,6 +90,17 @@ config PHY_QCOM_QMP_PCIE Enable this to support the QMP PCIe PHY transceiver that is used with PCIe controllers on Qualcomm chips. +config PHY_QCOM_QMP_PCIE_MULTIPHY + tristate "Qualcomm QMP PCIe Multi PHY Driver" + depends on PCI || COMPILE_TEST + select GENERIC_PHY + default PHY_QCOM_QMP + help + Enable this to support the QMP PCIe PHY transceiver that is used + with PCIe controllers on Qualcomm chips. This PHY is a single + multi-lane QMP block that can be configured either as one wide + link or as multiple narrower independent links (bifurcation). + config PHY_QCOM_QMP_PCIE_8996 tristate "Qualcomm QMP PCIe 8996 PHY Driver" depends on PCI || COMPILE_TEST diff --git a/drivers/phy/qualcomm/Makefile b/drivers/phy/qualcomm/Makefile index 382cb594b06b6..4b5e6640a6faa 100644 --- a/drivers/phy/qualcomm/Makefile +++ b/drivers/phy/qualcomm/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_PHY_QCOM_PCIE2) += phy-qcom-pcie2.o obj-$(CONFIG_PHY_QCOM_QMP_COMBO) += phy-qcom-qmp-combo.o phy-qcom-qmp-usbc.o obj-$(CONFIG_PHY_QCOM_QMP_PCIE) += phy-qcom-qmp-pcie.o +obj-$(CONFIG_PHY_QCOM_QMP_PCIE_MULTIPHY) += phy-qcom-qmp-pcie-multiphy.o obj-$(CONFIG_PHY_QCOM_QMP_PCIE_8996) += phy-qcom-qmp-pcie-msm8996.o obj-$(CONFIG_PHY_QCOM_QMP_UFS) += phy-qcom-qmp-ufs.o obj-$(CONFIG_PHY_QCOM_QMP_USB) += phy-qcom-qmp-usb.o diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie-multiphy.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie-multiphy.c new file mode 100644 index 0000000000000..8b2ca95de40d2 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie-multiphy.c @@ -0,0 +1,1953 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "phy-qcom-qmp.h" +#include "phy-qcom-qmp-common.h" +#include "phy-qcom-qmp-pcs-pcie5.h" +#include "phy-qcom-qmp-pcs-v8_50-nord.h" +#include "phy-qcom-qmp-qserdes-com-pcie5.h" +#include "phy-qcom-qmp-qserdes-txrxz-pcie5.h" + +#define PHY_INIT_COMPLETE_TIMEOUT_US 10000 + +enum qmp_pcie_glymur_link_mode { + QMP_PCIE_GLYMUR_MODE_X8, + QMP_PCIE_GLYMUR_MODE_X4X4, +}; + +enum qphy_reg_layout { + QPHY_PCS_STATUS, + QPHY_PCS_START_CONTROL, + QPHY_PCS_SW_RESET, + QPHY_PCS_POWER_DOWN_CONTROL, + QPHY_LAYOUT_SIZE +}; + +static const unsigned int pciephy_v8_50_regs_layout[QPHY_LAYOUT_SIZE] = { + [QPHY_PCS_STATUS] = QPHY_V8_50_PCS_STATUS1, +}; + +static const unsigned int nord_pciephy_v8_50_regs_layout[QPHY_LAYOUT_SIZE] = { + [QPHY_PCS_STATUS] = QPHY_NORD_V8_50_PCS_STATUS1, + [QPHY_PCS_START_CONTROL] = QPHY_NORD_V8_50_PCS_START_CONTROL, + [QPHY_PCS_SW_RESET] = QPHY_NORD_V8_50_PCS_SW_RESET, + [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_NORD_V8_50_PCS_POWER_DOWN_CONTROL, +}; + +struct qmp_pcie_offsets { + u16 pcs; + u16 pll; + u16 txrxz; + u16 pcs_lanez; +}; + +struct qmp_phy_cfg_tbls { + const struct qmp_phy_init_tbl *txrxz; int txrxz_num; + const struct qmp_phy_init_tbl *pcs; int pcs_num; + const struct qmp_phy_init_tbl *pcs_lanez; int pcs_lanez_num; +}; + +struct qmp_phy_cfg { + const struct qmp_pcie_offsets *offsets; + struct qmp_phy_cfg_tbls tbls; + + /* + * Per-segment PLL tables, indexed the same way as reg_names/pd_names + * (one entry per cfg->num_regs). Each physical segment (A/B/C/D) + * carries its own full table because a couple of DCC_CAL registers + * differ per segment; unlike txrxz/pcs/pcs_lanez these can't be + * shared across a group. NULL for configs with no Linux-driven PLL + * init (e.g. Glymur firmware-first). + */ + struct qmp_phy_init_tbl **pll_tbls; + int *pll_nums; + + /* + * True for every segment/group except the fully-ganged x16 config. + * Gates gearvm's pcie_bifurcated_phy_{pre_pwrup,post_pwrup,post_cfg}_seq, + * which are only present when a segment runs solo or ganged with less + * than all four PHYs (see qmp_pcie_init_seg_registers()). + * + * Not redundant with the BCR/NOCSR resets in qmp_pcie_init(): those + * only reset each segment's digital logic. Segments A/B/C/D are + * register-windowed views into one shared analog block (shared bias + * generator, shared lane LDO rails), so a digital reset can't stop + * one segment's analog power-up transient from bleeding onto an + * electrically adjacent but logically independent sibling. Confirmed + * load-bearing: omitting it reproduced a PLL-lock timeout with + * active_link_mode=3 (all segments solo). + */ + bool bifurcated; + + const char * const *reg_names; + int num_regs; + + const char * const *pd_names; + int num_pds; + + const char * const *reset_list; + int num_resets; + + const char * const *nocsr_reset_list; + int num_nocsr_resets; + + const char * const *vreg_list; + int num_vregs; + + const unsigned int *regs; + + unsigned int phy_status; + + const char * const *clk_list; + int num_clks; + const char * const *pipe_clk_list; + + int num_pipe_clks; +}; + +struct qmp_pcie { + struct device *dev; + + const struct qmp_phy_cfg *cfg; + + void __iomem **base; + + struct clk_bulk_data *clks; + struct clk_bulk_data *pipe_clks; + + struct reset_control_bulk_data *resets; + struct reset_control_bulk_data *nocsr_resets; + + struct regulator_bulk_data *vregs; + + struct device **pd_devs; + /* Borrowed pointer to the shared PD device, not owned by this segment */ + struct device *shared_pd_dev; +}; + +struct qmp_pcie_multiphy { + struct phy **phys; + const struct qmp_pcie_link_mode_cfg *mode_cfg; + + int num_pipe_outputs; + struct clk_fixed_rate *pipe_out_clks; + + /* + * Nord's "phy_a_gdsc" is voted by every segment group (see + * nord_pciephy_seg_*_pd_l below). Attaching it once here and + * sharing the virtual PM domain device across segments avoids + * calling dev_pm_domain_attach_by_name() more than once for the + * same (dev, name) pair, which would try to register a second + * "genpd::" device and fail with -EEXIST. + */ + struct device *shared_pd_dev; +}; + +struct qmp_pcie_link_mode_cfg { + const struct qmp_phy_cfg * const *cfgs; + u32 num_phys; +}; + +struct qmp_pcie_match_data { + const struct qmp_pcie_link_mode_cfg *mode_cfgs; + u32 num_modes; + + /* + * power-domain-names entry that multiple segment groups vote on in + * common (e.g. Nord's "phy_a_gdsc"). Attached once up front instead + * of once per segment. NULL if no domain is shared across segments. + */ + const char *shared_pd_name; +}; + +static const char * const glymur_pciephy_clk_l[] = { + "aux", "cfg_ahb", "ref", "rchng", "phy_b_aux", +}; + +static const char * const glymur_pciephy_a_clk_l[] = { + "aux", "cfg_ahb", "ref", "rchng", +}; + +static const char * const glymur_pciephy_b_clk_l[] = { + "phy_b_aux", "cfg_ahb_b", "ref", "rchng_b", +}; + +static const char * const glymur_pciephy_pipeclk_l[] = { + "pipe", +}; + +static const char * const glymur_pipephy_b_pipeclk_l[] = { + "pipe_b", "pipediv2_b", +}; + +static const char * const glymur_vreg_l[] = { + "vdda-phy", "vdda-pll", "vdda-refgen0p9", "vdda-refgen1p2", +}; + +static const char * const glymur_pciephy_a_reg_l[] = { + "port_a", +}; + +static const char * const glymur_pciephy_b_reg_l[] = { + "port_b", +}; + +static const char * const glymur_pciephy_reg_l[] = { + "port_a", "port_b", +}; + +static const char * const glymur_pciephy_a_pd_l[] = { + "port_a", +}; + +static const char * const glymur_pciephy_b_pd_l[] = { + "port_b", +}; + +static const char * const glymur_pciephy_pd_l[] = { + "port_a", "port_b", +}; + +static const char * const glymur_pciephy_a_nocsr_reset_l[] = { + "port_a_nocsr", +}; + +static const char * const glymur_pciephy_nocsr_reset_l[] = { + "port_a_nocsr", "port_b_nocsr", +}; + +static const char * const glymur_pciephy_b_nocsr_reset_l[] = { + "port_b_nocsr", +}; + +static const struct qmp_pcie_offsets glymur_pcie_offsets_v8_50 = { + .pcs = 0x9000, +}; + +static const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_a_cfg = { + .offsets = &glymur_pcie_offsets_v8_50, + .reg_names = glymur_pciephy_a_reg_l, + .num_regs = ARRAY_SIZE(glymur_pciephy_a_reg_l), + .pd_names = glymur_pciephy_a_pd_l, + .num_pds = ARRAY_SIZE(glymur_pciephy_a_pd_l), + .nocsr_reset_list = glymur_pciephy_a_nocsr_reset_l, + .num_nocsr_resets = ARRAY_SIZE(glymur_pciephy_a_nocsr_reset_l), + .vreg_list = glymur_vreg_l, + .num_vregs = ARRAY_SIZE(glymur_vreg_l), + .regs = pciephy_v8_50_regs_layout, + .phy_status = PHYSTATUS_4_20, + .pipe_clk_list = glymur_pciephy_pipeclk_l, + .num_pipe_clks = ARRAY_SIZE(glymur_pciephy_pipeclk_l), + .clk_list = glymur_pciephy_a_clk_l, + .num_clks = ARRAY_SIZE(glymur_pciephy_a_clk_l), +}; + +static const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_b_cfg = { + .offsets = &glymur_pcie_offsets_v8_50, + .reg_names = glymur_pciephy_b_reg_l, + .num_regs = ARRAY_SIZE(glymur_pciephy_b_reg_l), + .pd_names = glymur_pciephy_b_pd_l, + .num_pds = ARRAY_SIZE(glymur_pciephy_b_pd_l), + .nocsr_reset_list = glymur_pciephy_b_nocsr_reset_l, + .num_nocsr_resets = ARRAY_SIZE(glymur_pciephy_b_nocsr_reset_l), + .vreg_list = glymur_vreg_l, + .num_vregs = ARRAY_SIZE(glymur_vreg_l), + .regs = pciephy_v8_50_regs_layout, + .phy_status = PHYSTATUS_4_20, + .pipe_clk_list = glymur_pipephy_b_pipeclk_l, + .num_pipe_clks = ARRAY_SIZE(glymur_pipephy_b_pipeclk_l), + .clk_list = glymur_pciephy_b_clk_l, + .num_clks = ARRAY_SIZE(glymur_pciephy_b_clk_l), +}; + +static const struct qmp_phy_cfg glymur_qmp_gen5x8_pciephy_cfg = { + .offsets = &glymur_pcie_offsets_v8_50, + .reg_names = glymur_pciephy_reg_l, + .num_regs = ARRAY_SIZE(glymur_pciephy_reg_l), + .pd_names = glymur_pciephy_pd_l, + .num_pds = ARRAY_SIZE(glymur_pciephy_pd_l), + .nocsr_reset_list = glymur_pciephy_nocsr_reset_l, + .num_nocsr_resets = ARRAY_SIZE(glymur_pciephy_nocsr_reset_l), + .vreg_list = glymur_vreg_l, + .num_vregs = ARRAY_SIZE(glymur_vreg_l), + .regs = pciephy_v8_50_regs_layout, + .phy_status = PHYSTATUS_4_20, + .pipe_clk_list = glymur_pciephy_pipeclk_l, + .num_pipe_clks = ARRAY_SIZE(glymur_pciephy_pipeclk_l), + .clk_list = glymur_pciephy_clk_l, + .num_clks = ARRAY_SIZE(glymur_pciephy_clk_l), +}; + +static const struct qmp_phy_cfg * const glymur_qmp_gen5x8_mode_x8_cfgs[] = { + &glymur_qmp_gen5x8_pciephy_cfg, +}; + +static const struct qmp_phy_cfg * const glymur_qmp_gen5x8_mode_x4x4_cfgs[] = { + &glymur_qmp_gen5x4_pciephy_a_cfg, + &glymur_qmp_gen5x4_pciephy_b_cfg, +}; + +static const struct qmp_pcie_link_mode_cfg glymur_qmp_gen5x8_mode_cfgs[] = { + [QMP_PCIE_GLYMUR_MODE_X8] = { + .cfgs = glymur_qmp_gen5x8_mode_x8_cfgs, + .num_phys = ARRAY_SIZE(glymur_qmp_gen5x8_mode_x8_cfgs), + }, + [QMP_PCIE_GLYMUR_MODE_X4X4] = { + .cfgs = glymur_qmp_gen5x8_mode_x4x4_cfgs, + .num_phys = ARRAY_SIZE(glymur_qmp_gen5x8_mode_x4x4_cfgs), + }, +}; + +static const struct qmp_pcie_match_data glymur_qmp_gen5x8_match_data = { + .mode_cfgs = glymur_qmp_gen5x8_mode_cfgs, + .num_modes = ARRAY_SIZE(glymur_qmp_gen5x8_mode_cfgs), +}; + +/* ---------------------------------------------------------------- + * Nord (SA8797P) Gen4x16 bifurcated PCIe PHY + * + * Register map is split into four interchangeable segments (a..d) that + * the bootloader gangs together per TCSR_PCIE_LINK_CONFIG_MODE: + * 0x0 — x16: segs A+B+C+D ganged → 1 PHY + * 0x1 — x8+x8: seg A + segs B+C+D ganged → 2 PHYs + * 0x2 — x8+x4+x4: seg A + seg B + segs C+D ganged → 3 PHYs + * 0x3 — x8+x4+x2+x2: all segs independent → 4 PHYs (default) + * The set of distinct segment groupings across all four modes is fixed + * and small (a, b, c, d, cd, bcd, abcd), so each is a static qmp_phy_cfg + * below, same as Glymur's per-mode configs. + * + * reg: "seg_{id}" + * aux clk: "aux" (anchor seg A), "aux_{id}" (B/C/D) + * rchng clk: "rchng_{id}" + * pipe clk: "pipe_{id}" + * BCR reset: "phy_{id}", "phy_cfg_ahb_{id}" + * NOCSR: "nocsr_{id}" + * GDSC: "phy_a_gdsc" (+ "phy_{id}_gdsc" for B/C/D) + * ---------------------------------------------------------------- + */ + +/* + * Per gearvm ldo_config[] (pcie_settings_0..3.c): + * seg A (port 0): L6A_E0 (1200 mV) + L1E_E0 (936 mV) + L2E_E0 (936 mV) + * segs B/C/D (1..3): L4A_E0 (1200 mV) + L1E_E0 (936 mV) + L2E_E0 (936 mV) + * L1E and L2E are each a single physical rail voted by every segment. + * The "big" PHY bias rail is given its own supply property per segment + * (vdda-phy, vdda-phy-b, vdda-phy-c, vdda-phy-d) rather than reusing one + * property across B/C/D, even though they all point at L4A on Nord today + * — this lets a platform DTS override any one segment's bias rail + * independently without touching the others. + */ +static const char * const nord_pciephy_seg_a_vreg_l[] = { + "vdda-phy-a", "vdda-pll-a", "vdda-qref-a", +}; + +static const char * const nord_pciephy_seg_b_vreg_l[] = { + "vdda-phy-b", "vdda-pll-b", "vdda-qref-b", +}; + +static const char * const nord_pciephy_seg_c_vreg_l[] = { + "vdda-phy-c", "vdda-pll-c", "vdda-qref-c", +}; + +static const char * const nord_pciephy_seg_d_vreg_l[] = { + "vdda-phy-d", "vdda-pll-d", "vdda-qref-d", +}; + +static const char * const nord_pciephy_seg_cd_vreg_l[] = { + "vdda-phy-c", "vdda-phy-d", "vdda-pll-c", "vdda-pll-d", "vdda-qref-c", "vdda-qref-d", +}; + +static const char * const nord_pciephy_seg_bcd_vreg_l[] = { + "vdda-phy-b", "vdda-phy-c", "vdda-phy-d", + "vdda-pll-b", "vdda-pll-c", "vdda-pll-d", + "vdda-qref-b", "vdda-qref-c", "vdda-qref-d", +}; + +static const char * const nord_pciephy_seg_abcd_vreg_l[] = { + "vdda-phy-a", "vdda-phy-b", "vdda-phy-c", "vdda-phy-d", + "vdda-pll-a", "vdda-pll-b", "vdda-pll-c", "vdda-pll-d", + "vdda-qref-a", "vdda-qref-b", "vdda-qref-c", "vdda-qref-d", +}; + +static const struct qmp_pcie_offsets nord_pcie_offsets_v8_50 = { + .pll = 0x8000, + .pcs = 0x9000, + .txrxz = 0xd000, + .pcs_lanez = 0xe800, +}; + +/* ---------------------------------------------------------------- + * Nord PCIe5 PHY init tables + * Source: NORDSCHLEIFE_2.0 QMP PCIe 5.0 16lane PHY HSR for n4_30.0 + * (phy_cfg.c from gearvm pcie_rp_config_lib/src/nord_gearvm, + * pcie_phy_cfg_seq_v2_common[] + per-segment pcie_phy_cfg_seq_v2_{a,b,c,d}[]) + * + * TODO: these values are taken directly from the gearvm firmware reference + * and must be validated on first Si. Work with the PHY team to confirm + * register values before taping out or shipping production firmware. + * + * The PLL/COM tables below are mode-independent: all four pcie_settings_N.c + * files in gearvm reference the identical pcie_phy_cfg_seq_v2_common, + * applied once per segment window regardless of link topology (x16/ + * x8+x8/x8+x4+x4/x8+x4+x2+x2). qmp_pcie_init_seg_registers() iterates + * cfg->num_regs to cover every segment in the active group for all four + * link modes, writing each segment's own nord_qmp_pcie_pll_{a,b,c,d}_tbl. + * ---------------------------------------------------------------- + */ + +/* + * PLL / COM block — written at seg_base + 0x8000, one full table per + * physical segment (A/B/C/D). Each is the shared pcie_phy_cfg_seq_v2_common + * sequence with that segment's DCC_CAL_7/DCC_CAL_9 values from gearvm's + * pcie_phy_cfg_seq_v2_{a,b,c,d}[] appended at the end. To add a new + * per-segment setting, append it to the end of the relevant table(s) below. + */ +static struct qmp_phy_init_tbl nord_qmp_pcie_pll_a_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CLK_FWD_CONFIG_1, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE1_MODE2, 0xab), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE2_MODE2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CP_CTRL_MODE2, 0x06), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_RCTRL_MODE2, 0x16), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_CCTRL_MODE2, 0x36), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CORECLK_DIV_MODE2, 0x04), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP1_MODE2, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP2_MODE2, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DEC_START_MODE2, 0x68), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START1_MODE2, 0xab), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START2_MODE2, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START3_MODE2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE1_MODE2, 0xa4), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE2_MODE2, 0x18), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE1_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE2_MODE1, 0x03), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CP_CTRL_MODE1, 0x06), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_RCTRL_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_CCTRL_MODE1, 0x36), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CORECLK_DIV_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP1_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP2_MODE1, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DEC_START_MODE1, 0x68), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START1_MODE1, 0xab), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START2_MODE1, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START3_MODE1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x52), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_HSCLK_SEL_1, 0x3c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_HSCLK_SEL_2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x3c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_HSCLK_SEL_2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE1_MODE0, 0xe0), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE2_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CP_CTRL_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CORECLK_DIV_MODE0, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP1_MODE0, 0x40), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP2_MODE0, 0x03), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DEC_START_MODE0, 0x41), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START1_MODE0, 0xab), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START2_MODE0, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START3_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xd4), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x03), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_HSCLK_HS_SWITCH_SEL_1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_HSCLK_HS_SWITCH_SEL_2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BG_TIMER, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_VCO_TUNE_CTRL, 0x40), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_EN_CENTER, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_PER1, 0x62), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_PER2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_POST_DIV_MUX, 0xc0), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIAS_EN_CLKBUFLR_EN, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CLK_ENABLE1, 0x90), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SYS_CLK_CTRL, 0x82), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_IVCO, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_IVCO_MODE1, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_IVCO_MODE2, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SYSCLK_EN_SEL, 0x08), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP_EN, 0x46), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP_CFG, 0x04), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_VCO_TUNE_MAP, 0x24), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CLK_SELECT, 0x34), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CORE_CLK_EN, 0xe0), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CMN_CONFIG_1, 0x86), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CMN_MISC1, 0x88), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CMN_MODE, 0x14), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_VCO_DC_LEVEL_CTRL, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CMN_CONFIG_2, 0x10), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CLK_EP_DIV_MODE1, 0x14), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CLK_EP_DIV_MODE0, 0x32), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PSM_CAL_EN, 0x05), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_SPARE_FOR_ECO, 0x40), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_1, 0x40), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_2, 0x07), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_3, 0x60), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_8, 0x32), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_IP_CTRL_AND_DP_SEL, 0xaf), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CMN_IETRIM, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_7, 0x31), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_9, 0x31), +}; + +static struct qmp_phy_init_tbl nord_qmp_pcie_pll_b_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CLK_FWD_CONFIG_1, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE1_MODE2, 0xab), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE2_MODE2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CP_CTRL_MODE2, 0x06), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_RCTRL_MODE2, 0x16), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_CCTRL_MODE2, 0x36), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CORECLK_DIV_MODE2, 0x04), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP1_MODE2, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP2_MODE2, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DEC_START_MODE2, 0x68), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START1_MODE2, 0xab), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START2_MODE2, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START3_MODE2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE1_MODE2, 0xa4), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE2_MODE2, 0x18), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE1_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE2_MODE1, 0x03), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CP_CTRL_MODE1, 0x06), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_RCTRL_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_CCTRL_MODE1, 0x36), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CORECLK_DIV_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP1_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP2_MODE1, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DEC_START_MODE1, 0x68), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START1_MODE1, 0xab), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START2_MODE1, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START3_MODE1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x52), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_HSCLK_SEL_1, 0x3c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_HSCLK_SEL_2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x3c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_HSCLK_SEL_2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE1_MODE0, 0xe0), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE2_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CP_CTRL_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CORECLK_DIV_MODE0, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP1_MODE0, 0x40), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP2_MODE0, 0x03), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DEC_START_MODE0, 0x41), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START1_MODE0, 0xab), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START2_MODE0, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START3_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xd4), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x03), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_HSCLK_HS_SWITCH_SEL_1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_HSCLK_HS_SWITCH_SEL_2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BG_TIMER, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_VCO_TUNE_CTRL, 0x40), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_EN_CENTER, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_PER1, 0x62), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_PER2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_POST_DIV_MUX, 0xc0), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIAS_EN_CLKBUFLR_EN, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CLK_ENABLE1, 0x90), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SYS_CLK_CTRL, 0x82), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_IVCO, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_IVCO_MODE1, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_IVCO_MODE2, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SYSCLK_EN_SEL, 0x08), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP_EN, 0x46), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP_CFG, 0x04), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_VCO_TUNE_MAP, 0x24), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CLK_SELECT, 0x34), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CORE_CLK_EN, 0xe0), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CMN_CONFIG_1, 0x86), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CMN_MISC1, 0x88), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CMN_MODE, 0x14), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_VCO_DC_LEVEL_CTRL, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CMN_CONFIG_2, 0x10), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CLK_EP_DIV_MODE1, 0x14), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CLK_EP_DIV_MODE0, 0x32), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PSM_CAL_EN, 0x05), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_SPARE_FOR_ECO, 0x40), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_1, 0x40), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_2, 0x07), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_3, 0x60), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_8, 0x32), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_IP_CTRL_AND_DP_SEL, 0xaf), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CMN_IETRIM, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_7, 0x32), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_9, 0x22), +}; + +static struct qmp_phy_init_tbl nord_qmp_pcie_pll_c_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CLK_FWD_CONFIG_1, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE1_MODE2, 0xab), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE2_MODE2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CP_CTRL_MODE2, 0x06), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_RCTRL_MODE2, 0x16), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_CCTRL_MODE2, 0x36), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CORECLK_DIV_MODE2, 0x04), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP1_MODE2, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP2_MODE2, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DEC_START_MODE2, 0x68), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START1_MODE2, 0xab), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START2_MODE2, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START3_MODE2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE1_MODE2, 0xa4), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE2_MODE2, 0x18), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE1_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE2_MODE1, 0x03), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CP_CTRL_MODE1, 0x06), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_RCTRL_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_CCTRL_MODE1, 0x36), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CORECLK_DIV_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP1_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP2_MODE1, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DEC_START_MODE1, 0x68), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START1_MODE1, 0xab), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START2_MODE1, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START3_MODE1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x52), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_HSCLK_SEL_1, 0x3c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_HSCLK_SEL_2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x3c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_HSCLK_SEL_2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE1_MODE0, 0xe0), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE2_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CP_CTRL_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CORECLK_DIV_MODE0, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP1_MODE0, 0x40), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP2_MODE0, 0x03), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DEC_START_MODE0, 0x41), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START1_MODE0, 0xab), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START2_MODE0, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START3_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xd4), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x03), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_HSCLK_HS_SWITCH_SEL_1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_HSCLK_HS_SWITCH_SEL_2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BG_TIMER, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_VCO_TUNE_CTRL, 0x40), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_EN_CENTER, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_PER1, 0x62), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_PER2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_POST_DIV_MUX, 0xc0), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIAS_EN_CLKBUFLR_EN, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CLK_ENABLE1, 0x90), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SYS_CLK_CTRL, 0x82), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_IVCO, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_IVCO_MODE1, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_IVCO_MODE2, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SYSCLK_EN_SEL, 0x08), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP_EN, 0x46), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP_CFG, 0x04), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_VCO_TUNE_MAP, 0x24), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CLK_SELECT, 0x34), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CORE_CLK_EN, 0xe0), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CMN_CONFIG_1, 0x86), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CMN_MISC1, 0x88), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CMN_MODE, 0x14), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_VCO_DC_LEVEL_CTRL, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CMN_CONFIG_2, 0x10), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CLK_EP_DIV_MODE1, 0x14), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CLK_EP_DIV_MODE0, 0x32), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PSM_CAL_EN, 0x05), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_SPARE_FOR_ECO, 0x40), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_1, 0x40), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_2, 0x07), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_3, 0x60), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_8, 0x32), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_IP_CTRL_AND_DP_SEL, 0xaf), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CMN_IETRIM, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_7, 0x20), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_9, 0x31), +}; + +static struct qmp_phy_init_tbl nord_qmp_pcie_pll_d_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CLK_FWD_CONFIG_1, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE1_MODE2, 0xab), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE2_MODE2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CP_CTRL_MODE2, 0x06), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_RCTRL_MODE2, 0x16), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_CCTRL_MODE2, 0x36), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CORECLK_DIV_MODE2, 0x04), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP1_MODE2, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP2_MODE2, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DEC_START_MODE2, 0x68), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START1_MODE2, 0xab), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START2_MODE2, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START3_MODE2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE1_MODE2, 0xa4), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE2_MODE2, 0x18), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE1_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE2_MODE1, 0x03), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CP_CTRL_MODE1, 0x06), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_RCTRL_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_CCTRL_MODE1, 0x36), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CORECLK_DIV_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP1_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP2_MODE1, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DEC_START_MODE1, 0x68), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START1_MODE1, 0xab), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START2_MODE1, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START3_MODE1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x52), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_HSCLK_SEL_1, 0x3c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_HSCLK_SEL_2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x3c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_HSCLK_SEL_2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE1_MODE0, 0xe0), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_STEP_SIZE2_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CP_CTRL_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CORECLK_DIV_MODE0, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP1_MODE0, 0x40), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP2_MODE0, 0x03), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DEC_START_MODE0, 0x41), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START1_MODE0, 0xab), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START2_MODE0, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DIV_FRAC_START3_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xd4), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x03), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_HSCLK_HS_SWITCH_SEL_1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_HSCLK_HS_SWITCH_SEL_2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BG_TIMER, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_VCO_TUNE_CTRL, 0x40), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_EN_CENTER, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_PER1, 0x62), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SSC_PER2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_POST_DIV_MUX, 0xc0), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_BIAS_EN_CLKBUFLR_EN, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CLK_ENABLE1, 0x90), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SYS_CLK_CTRL, 0x82), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_IVCO, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_IVCO_MODE1, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_IVCO_MODE2, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_SYSCLK_EN_SEL, 0x08), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP_EN, 0x46), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_LOCK_CMP_CFG, 0x04), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_VCO_TUNE_MAP, 0x24), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CLK_SELECT, 0x34), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CORE_CLK_EN, 0xe0), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CMN_CONFIG_1, 0x86), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CMN_MISC1, 0x88), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CMN_MODE, 0x14), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_VCO_DC_LEVEL_CTRL, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CMN_CONFIG_2, 0x10), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CLK_EP_DIV_MODE1, 0x14), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CLK_EP_DIV_MODE0, 0x32), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PSM_CAL_EN, 0x05), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_PLL_SPARE_FOR_ECO, 0x40), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_1, 0x40), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_2, 0x07), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_3, 0x60), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_8, 0x32), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_IP_CTRL_AND_DP_SEL, 0xaf), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_CMN_IETRIM, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_7, 0x22), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_COM_DCC_CAL_9, 0x22), +}; + +/* TXRXZ block — written at seg_base + 0xd000 */ +static const struct qmp_phy_init_tbl nord_qmp_pcie_txrxz_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_SIGDET_ENABLES, 0x1c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE2_B0, 0xcd), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE2_B1, 0x34), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE2_B2, 0x55), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE2_B3, 0x50), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE2_B4, 0xac), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE2_B5, 0xdb), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE2_B6, 0x52), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE2_B7, 0x3e), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE3_B0, 0xce), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE3_B1, 0x55), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE3_B2, 0x6d), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE3_B3, 0x60), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE3_B4, 0x8c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE3_B5, 0x9d), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE3_B6, 0x6d), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE3_B7, 0x26), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE4_B0, 0xfb), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE4_B1, 0xea), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE4_B2, 0xe8), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE4_B3, 0x70), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE4_B4, 0x9c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE4_B5, 0xf4), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE4_B6, 0x6d), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE4_B7, 0x3b), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_SUMMER_CAL_SPD_MODE_RATE_0123, 0x6f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_TX_ADAPT_POST_THRESH1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_TX_ADAPT_POST_THRESH2, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_PHPRE_CTRL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_TX_ADPT_CTRL, 0x30), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE_0_1_B0, 0xff), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE_0_1_B1, 0x4a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE_0_1_B2, 0x77), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE_0_1_B3, 0x50), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE_0_1_B4, 0x9a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE_0_1_B5, 0x47), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE_0_1_B6, 0x52), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_MODE_RATE_0_1_B7, 0x1d), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_LANE_MODE_1, 0x05), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_LANE_MODE_2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_LANE_MODE_3, 0x41), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_LANE_MODE_4, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_PCIE5_TOP_LDO_CODE_CTRL1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_PCIE5_TOP_LDO_CODE_CTRL2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_PCIE5_TOP_LDO_CODE_CTRL3, 0x81), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_PCIE5_TOP_LDO_CODE_CTRL4, 0x8d), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_LOCK_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_DFE_TAP1_DAC_ENABLE, 0x1c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_DFE_TAP2_DAC_ENABLE, 0x1c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_DFE_TAP345_DAC_ENABLE, 0x18), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_DFE_TAP67_DAC_ENABLE, 0x10), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_CP_CUR_FLL_RATE0, 0x07), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_CP_CUR_FLL_RATE1, 0x07), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_CP_CUR_FLL_RATE2, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_CP_CUR_FLL_RATE3, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_CP_CUR_FLL_RATE4, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_CP_CUR_PLL_RATE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_CP_CUR_PLL_RATE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_CP_CUR_PLL_RATE2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_CP_CUR_PLL_RATE3, 0x03), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_CP_CUR_PLL_RATE4, 0x03), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_FLL_DIV_RATIO_RATE_0123, 0x94), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_LOOP_CCODE_RATE_01, 0x66), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_LOOP_CCODE_RATE_23, 0x77), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_LOOP_CCODE_RATE4, 0x07), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_IQTUNE_CTRL, 0x58), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_IQTUNE_MAN_INDEX, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_IQTUNE_ANA_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_LOOP_FUNC_CTRL, 0xd0), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE0, 0xff), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE1, 0xff), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE2, 0xff), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE3, 0xff), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE4, 0xff), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KP_CAL_LOWER_FREQ_DIFF_BND_RATE0, 0x15), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KP_CAL_LOWER_FREQ_DIFF_BND_RATE1, 0x15), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KP_CAL_LOWER_FREQ_DIFF_BND_RATE2, 0x10), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KP_CAL_LOWER_FREQ_DIFF_BND_RATE3, 0x07), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KP_CAL_LOWER_FREQ_DIFF_BND_RATE4, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KP_CODE_OVRD_RATE_2_3, 0x24), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_IVCM_CAL_CTRL2, 0x83), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_IVCM_CAL_CTRL3, 0x44), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_IVCM_CAL_CTRL4, 0x04), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_LOOP_RCODE_PLL_RATE_0_1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_LOOP_RCODE_PLL_RATE_2_3, 0x11), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_LOOP_RCODE_PLL_RATE4, 0x02), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_LOOP_RCODE_FLL_RATE_0_1, 0x33), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_LOOP_RCODE_FLL_RATE_2_3, 0x33), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_LOOP_RCODE_FLL_RATE4, 0x03), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_LOOP_RCODE_FAST_RATE_0_1, 0x22), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_LOOP_RCODE_FAST_RATE_2_3, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_LOOP_RCODE_FAST_RATE4, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_IQTUNE_DIV2_CTRL_RATE0123, 0x7f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_VCO_CTUNE_MEAS_CNT1_RATE0, 0x13), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_VCO_CTUNE_MEAS_CNT2_RATE0, 0x13), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_VCO_CTUNE_MEAS_CNT1_RATE1, 0x26), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_VCO_CTUNE_MEAS_CNT2_RATE1, 0x26), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_VCO_CTUNE_MEAS_CNT1_RATE2, 0x9c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_VCO_CTUNE_MEAS_CNT2_RATE2, 0x3d), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_VCO_CTUNE_MEAS_CNT1_RATE3, 0x9c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_VCO_CTUNE_MEAS_CNT2_RATE3, 0x3d), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_VCO_CTUNE_MEAS_CNT1_RATE4, 0x09), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_VCO_CTUNE_MEAS_CNT2_RATE4, 0x3d), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_EQU_ADAPTOR_CNTRL3, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_EQU_ADAPTOR_CNTRL4, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RX_EQU_ADAPTOR_CNTRL5, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_VGA_CAL_CNTRL1, 0xe1), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_VGA_CAL_MAN_VAL_RATE0_1, 0xdd), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_VGA_CAL_MAN_VAL_RATE2_3, 0xdc), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_VGA_CAL_MAN_VAL_RATE4, 0x05), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_VCO_CAP_CODE_OVRD_MUXES, 0x11), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_VCO_CAP_CODE_RATE_0123, 0x55), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_VCO_CAP_CODE_RATE4, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KVCO_IDEAL_FREQ_DIFF1_RATE0, 0x4b), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KVCO_IDEAL_FREQ_DIFF2_RATE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KVCO_IDEAL_FREQ_DIFF1_RATE1, 0x4b), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KVCO_IDEAL_FREQ_DIFF2_RATE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KVCO_IDEAL_FREQ_DIFF1_RATE2, 0x35), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KVCO_IDEAL_FREQ_DIFF2_RATE2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KVCO_IDEAL_FREQ_DIFF1_RATE3, 0x28), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KVCO_IDEAL_FREQ_DIFF1_RATE4, 0x14), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KVCO_INIT_RATE_0_1, 0x11), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KVCO_INIT_RATE_2_3, 0x22), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KVCO_INIT_RATE_4, 0x04), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KVCO_CODE_OVRD_RATE0, 0x04), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KVCO_CODE_OVRD_RATE1, 0x03), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_KVCO_CODE_OVRD_RATE2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_FREQ_LOCK_DET_DLY_RATE0, 0xff), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_FREQ_LOCK_DET_DLY_RATE1, 0xff), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_FREQ_LOCK_DET_DLY_RATE2, 0xff), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_FREQ_LOCK_DET_DLY_RATE3, 0xff), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_FREQ_LOCK_DET_DLY_RATE4, 0xff), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_VCTRL_RATE_0_1, 0x43), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_VCTRL_RATE_2_3, 0x44), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_VCO_TYPE_CONFIG, 0x03), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CTLE_POST_CAL_OFFSET_RATE_0_1_2, 0x67), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CDR_VCO_EN_LOWFREQ, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RES_CODE_LANE_OFFSET_RX, 0x18), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_GM_CAL_RES_RATE0_1, 0x88), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_GM_CAL_RES_RATE2_3, 0x88), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_GM_CAL_RES_RATE4, 0x09), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_VTHRESH_CAL_MAN_VAL_RATE4, 0x56), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_CLKBUF_ENABLE, 0x40), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_VCO_CTUNE_UPPER_BND_RATE0, 0x1e), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_VCO_CTUNE_UPPER_BND_RATE1, 0x1e), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_VCO_CTUNE_UPPER_BND_RATE2, 0x1e), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_VCO_CTUNE_UPPER_BND_RATE3, 0x1e), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_VCO_CTUNE_UPPER_BND_RATE4, 0x1e), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_SIGDET_CNTRL, 0x2f), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_SIGDET_LVL, 0x84), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_SIGDET_CAL_CTRL1, 0x10), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_DIG_BKUP_CTRL15, 0x00), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_DIG_BKUP_CTRL16, 0x52), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RESTRIM_CAL_CTRL, 0x08), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RESTRIM_POST_CAL_OFFSET, 0x10), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_RESTRIM_VREF_SEL, 0x16), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_BLW_CTRL, 0x3c), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_BLW_MAN_VAL_RATE3, 0x17), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_BLW_MAN_VAL_RATE4, 0x17), +}; + +/* + * PCS COM block — written at seg_base + 0x9000. POWER_DOWN_CONTROL (the + * pcie_phy_pwrup_seq write) is issued directly in + * qmp_pcie_init_seg_registers(), not via this table, so it can be + * sequenced between the bifurcated pre/post-pwrup steps. + */ +static const struct qmp_phy_init_tbl nord_qmp_pcie_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_POWER_STATE_CONFIG2, 0x3d), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_POWER_STATE_CONFIG5, 0xe4), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_POWER_STATE_CONFIG6, 0x1f), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_POWER_STATE_CONFIG7, 0x0d), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_MULTIPHY_CONFIG2, 0x01), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_PCS_TX_RX_CONFIG2, 0xe4), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_PCS_TX_RX_CONFIG3, 0x30), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_PCS_TX_RX_CONFIG5, 0x05), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_PCS_TX_RX_CONFIG6, 0x08), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_PCS_TX_RX_CONFIG7, 0x20), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_PCS_TX_RX_CONFIG8, 0x20), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_PCS_TX_RX_CONFIG10, 0x40), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_DIVTX_CLK_DCC_CAL_CONFIG2, 0x00), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_DIVTX_CLK_DCC_CAL_CONFIG3, 0x00), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_DIVTX_CLK_DCC_CAL_CONFIG4, 0x00), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_ENDPOINT_REFCLK_DRIVE, 0xc1), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_RX_SIGDET_LVL, 0x66), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_OSC_DTCT_ACTIONS, 0x00), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_LOCK_DETECT_CONFIG1, 0xff), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_ALIGN_DETECT_CONFIG1, 0x00), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_ALIGN_DETECT_CONFIG2, 0x04), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_ALIGN_DETECT_CONFIG3, 0x1f), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_ALIGN_DETECT_CONFIG7, 0x35), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_ALIGN_DETECT_CONFIG8, 0x3e), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_EQ_CONFIG1, 0x06), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_EQ_CONFIG2, 0x1c), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_G345_EQ_CONFIG1, 0x03), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_G345_EQ_CONFIG3, 0x00), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_G3_EQ_CONFIG1, 0x00), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_G3_EQ_CONFIG5, 0x90), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_G3_EQ_CONFIG7, 0x0d), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_G4_EQ_CONFIG1, 0x00), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_G4_EQ_CONFIG5, 0x90), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_G4_EQ_CONFIG7, 0x0d), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_G5_EQ_CONFIG1, 0x00), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_G5_EQ_CONFIG5, 0x90), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_G5_EQ_CONFIG7, 0x0d), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_COM_TEST_CONTROL1, 0x08), +}; + +/* PCS LANEZ block — written at seg_base + 0xe800 */ +static const struct qmp_phy_init_tbl nord_qmp_pcie_pcs_lanez_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_LANEZ_OUTSIG_MX_CTRL2, 0x00), + QMP_PHY_INIT_CFG(QPHY_PCIE5_PCS_LANEZ_OUTSIG_MX_CTRL5, 0x00), +}; + +static const struct qmp_phy_cfg_tbls nord_qmp_pcie_tbls = { + .txrxz = nord_qmp_pcie_txrxz_tbl, + .txrxz_num = ARRAY_SIZE(nord_qmp_pcie_txrxz_tbl), + .pcs = nord_qmp_pcie_pcs_tbl, + .pcs_num = ARRAY_SIZE(nord_qmp_pcie_pcs_tbl), + .pcs_lanez = nord_qmp_pcie_pcs_lanez_tbl, + .pcs_lanez_num = ARRAY_SIZE(nord_qmp_pcie_pcs_lanez_tbl), +}; + +/* + * Bifurcated-only PHY sequences — gearvm's pcie_bifurcated_phy_{pre_pwrup, + * post_pwrup,post_cfg}_seq[] run for every segment/group EXCEPT the fully + * ganged x16 config (PcieQcSoCVer_All, i.e. version-independent). They + * bracket the PLL/TXRXZ/PCS/PCS_LANEZ tables and pcie_phy_pwrup_seq: + * pre_pwrup -- before POWER_DOWN_CONTROL is written + * post_pwrup -- immediately after POWER_DOWN_CONTROL is written + * post_cfg -- after the PLL/TXRXZ/PCS/PCS_LANEZ tables, before SW_RESET + * is released (pcie_phy_start_seq) + * These are the exact solo-vs-ganged axis our reported PLL-lock timeout is + * gated on (active_link_mode=3, all segments solo). + */ +static const struct qmp_phy_init_tbl nord_qmp_pcie_bifurcated_pre_pwrup_tbl[] = { + /* Ensure Lane LDOs are disabled before asserting POWER_DOWN_CONTROL */ + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_PRE_STALL_LDO_BOOST_EN, 0x80), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_LDO_TIMER_CTRL, 0x91), +}; + +static const struct qmp_phy_init_tbl nord_qmp_pcie_bifurcated_post_cfg_tbl[] = { + /* Enable Lane LDOs before releasing SW_RESET */ + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_LDO_TIMER_CTRL, 0x11), + QMP_PHY_INIT_CFG(QSERDES_PCIE5_TXRXZ_PRE_STALL_LDO_BOOST_EN, 0x00), +}; + +/* + * Per-group pll_tbls/nums arrays, indexed the same way as each group's + * reg_names (segment order). Solo configs carry one entry; ganged configs + * carry one table per member segment. + */ +static struct qmp_phy_init_tbl *nord_qmp_pcie_pll_a[] = { + nord_qmp_pcie_pll_a_tbl, +}; + +static int nord_qmp_pcie_pll_a_nums[] = { + ARRAY_SIZE(nord_qmp_pcie_pll_a_tbl), +}; + +static struct qmp_phy_init_tbl *nord_qmp_pcie_pll_b[] = { + nord_qmp_pcie_pll_b_tbl, +}; + +static int nord_qmp_pcie_pll_b_nums[] = { + ARRAY_SIZE(nord_qmp_pcie_pll_b_tbl), +}; + +static struct qmp_phy_init_tbl *nord_qmp_pcie_pll_c[] = { + nord_qmp_pcie_pll_c_tbl, +}; + +static int nord_qmp_pcie_pll_c_nums[] = { + ARRAY_SIZE(nord_qmp_pcie_pll_c_tbl), +}; + +static struct qmp_phy_init_tbl *nord_qmp_pcie_pll_d[] = { + nord_qmp_pcie_pll_d_tbl, +}; + +static int nord_qmp_pcie_pll_d_nums[] = { + ARRAY_SIZE(nord_qmp_pcie_pll_d_tbl), +}; + +static struct qmp_phy_init_tbl *nord_qmp_pcie_pll_cd[] = { + nord_qmp_pcie_pll_c_tbl, nord_qmp_pcie_pll_d_tbl, +}; + +static int nord_qmp_pcie_pll_cd_nums[] = { + ARRAY_SIZE(nord_qmp_pcie_pll_c_tbl), ARRAY_SIZE(nord_qmp_pcie_pll_d_tbl), +}; + +static struct qmp_phy_init_tbl *nord_qmp_pcie_pll_bcd[] = { + nord_qmp_pcie_pll_b_tbl, nord_qmp_pcie_pll_c_tbl, nord_qmp_pcie_pll_d_tbl, +}; + +static int nord_qmp_pcie_pll_bcd_nums[] = { + ARRAY_SIZE(nord_qmp_pcie_pll_b_tbl), ARRAY_SIZE(nord_qmp_pcie_pll_c_tbl), + ARRAY_SIZE(nord_qmp_pcie_pll_d_tbl), +}; + +static struct qmp_phy_init_tbl *nord_qmp_pcie_pll_abcd[] = { + nord_qmp_pcie_pll_a_tbl, nord_qmp_pcie_pll_b_tbl, + nord_qmp_pcie_pll_c_tbl, nord_qmp_pcie_pll_d_tbl, +}; + +static int nord_qmp_pcie_pll_abcd_nums[] = { + ARRAY_SIZE(nord_qmp_pcie_pll_a_tbl), ARRAY_SIZE(nord_qmp_pcie_pll_b_tbl), + ARRAY_SIZE(nord_qmp_pcie_pll_c_tbl), ARRAY_SIZE(nord_qmp_pcie_pll_d_tbl), +}; + +/* Single-segment reg/clk/reset name lists, one per segment id */ +static const char * const nord_pciephy_seg_a_reg_l[] = { "seg_a" }; +static const char * const nord_pciephy_seg_b_reg_l[] = { "seg_b" }; +static const char * const nord_pciephy_seg_c_reg_l[] = { "seg_c" }; +static const char * const nord_pciephy_seg_d_reg_l[] = { "seg_d" }; +static const char * const nord_pciephy_seg_cd_reg_l[] = { "seg_c", "seg_d" }; +static const char * const nord_pciephy_seg_bcd_reg_l[] = { "seg_b", "seg_c", "seg_d" }; +static const char * const nord_pciephy_seg_abcd_reg_l[] = { "seg_a", "seg_b", "seg_c", "seg_d" }; + +static const char * const nord_pciephy_seg_a_clk_l[] = { "aux_a", "rchng_a", "ref" }; +static const char * const nord_pciephy_seg_b_clk_l[] = { "aux_a", "aux_b", "rchng_b", "ref" }; +static const char * const nord_pciephy_seg_c_clk_l[] = { "aux_a", "aux_c", "rchng_c", "ref" }; +static const char * const nord_pciephy_seg_d_clk_l[] = { "aux_a", "aux_d", "rchng_d", "ref" }; +static const char * const nord_pciephy_seg_cd_clk_l[] = { + "aux_a", "aux_c", "rchng_c", "aux_d", "rchng_d", "ref", +}; + +static const char * const nord_pciephy_seg_bcd_clk_l[] = { + "aux_a", "aux_b", "rchng_b", "aux_c", "rchng_c", "aux_d", "rchng_d", "ref", +}; + +static const char * const nord_pciephy_seg_abcd_clk_l[] = { + "aux_a", "rchng_a", "aux_b", "rchng_b", "aux_c", "rchng_c", "aux_d", "rchng_d", "ref", +}; + +static const char * const nord_pciephy_seg_a_pipeclk_l[] = { "pipe_a" }; +static const char * const nord_pciephy_seg_b_pipeclk_l[] = { "pipe_b" }; +static const char * const nord_pciephy_seg_c_pipeclk_l[] = { "pipe_c" }; +static const char * const nord_pciephy_seg_d_pipeclk_l[] = { "pipe_d" }; + +static const char * const nord_pciephy_seg_a_reset_l[] = { "phy_a", "phy_cfg_ahb_a" }; +static const char * const nord_pciephy_seg_b_reset_l[] = { "phy_b", "phy_cfg_ahb_b" }; +static const char * const nord_pciephy_seg_c_reset_l[] = { "phy_c", "phy_cfg_ahb_c" }; +static const char * const nord_pciephy_seg_d_reset_l[] = { "phy_d", "phy_cfg_ahb_d" }; +static const char * const nord_pciephy_seg_cd_reset_l[] = { + "phy_c", "phy_cfg_ahb_c", "phy_d", "phy_cfg_ahb_d", +}; + +static const char * const nord_pciephy_seg_bcd_reset_l[] = { + "phy_b", "phy_cfg_ahb_b", "phy_c", "phy_cfg_ahb_c", "phy_d", "phy_cfg_ahb_d", +}; + +static const char * const nord_pciephy_seg_abcd_reset_l[] = { + "phy_a", "phy_cfg_ahb_a", "phy_b", "phy_cfg_ahb_b", + "phy_c", "phy_cfg_ahb_c", "phy_d", "phy_cfg_ahb_d", +}; + +static const char * const nord_pciephy_seg_a_nocsr_reset_l[] = { "nocsr_a" }; +static const char * const nord_pciephy_seg_b_nocsr_reset_l[] = { "nocsr_b" }; +static const char * const nord_pciephy_seg_c_nocsr_reset_l[] = { "nocsr_c" }; +static const char * const nord_pciephy_seg_d_nocsr_reset_l[] = { "nocsr_d" }; +static const char * const nord_pciephy_seg_cd_nocsr_reset_l[] = { "nocsr_c", "nocsr_d" }; +static const char * const nord_pciephy_seg_bcd_nocsr_reset_l[] = { + "nocsr_b", "nocsr_c", "nocsr_d", +}; + +static const char * const nord_pciephy_seg_abcd_nocsr_reset_l[] = { + "nocsr_a", "nocsr_b", "nocsr_c", "nocsr_d", +}; + +/* GDSC "phy_a_gdsc" is the shared master, voted by every group */ +static const char * const nord_pciephy_seg_a_pd_l[] = { "phy_a_gdsc" }; +static const char * const nord_pciephy_seg_b_pd_l[] = { "phy_a_gdsc", "phy_b_gdsc" }; +static const char * const nord_pciephy_seg_c_pd_l[] = { "phy_a_gdsc", "phy_c_gdsc" }; +static const char * const nord_pciephy_seg_d_pd_l[] = { "phy_a_gdsc", "phy_d_gdsc" }; +static const char * const nord_pciephy_seg_cd_pd_l[] = { + "phy_a_gdsc", "phy_c_gdsc", "phy_d_gdsc", +}; + +static const char * const nord_pciephy_seg_bcd_pd_l[] = { + "phy_a_gdsc", "phy_b_gdsc", "phy_c_gdsc", "phy_d_gdsc", +}; + +#define nord_pciephy_seg_abcd_pd_l nord_pciephy_seg_bcd_pd_l + +#define NORD_QMP_PCIE_SEG_CFG(_seg, _pipeclk_l, _bifurcated) \ +static const struct qmp_phy_cfg nord_qmp_pcie_seg_##_seg##_cfg = { \ + .offsets = &nord_pcie_offsets_v8_50, \ + .tbls = nord_qmp_pcie_tbls, \ + .pll_tbls = nord_qmp_pcie_pll_##_seg, \ + .pll_nums = nord_qmp_pcie_pll_##_seg##_nums, \ + .bifurcated = _bifurcated, \ + .reg_names = nord_pciephy_seg_##_seg##_reg_l, \ + .num_regs = ARRAY_SIZE(nord_pciephy_seg_##_seg##_reg_l), \ + .pd_names = nord_pciephy_seg_##_seg##_pd_l, \ + .num_pds = ARRAY_SIZE(nord_pciephy_seg_##_seg##_pd_l), \ + .reset_list = nord_pciephy_seg_##_seg##_reset_l, \ + .num_resets = ARRAY_SIZE(nord_pciephy_seg_##_seg##_reset_l), \ + .nocsr_reset_list = nord_pciephy_seg_##_seg##_nocsr_reset_l, \ + .num_nocsr_resets = ARRAY_SIZE(nord_pciephy_seg_##_seg##_nocsr_reset_l), \ + .vreg_list = nord_pciephy_seg_##_seg##_vreg_l, \ + .num_vregs = ARRAY_SIZE(nord_pciephy_seg_##_seg##_vreg_l), \ + .regs = nord_pciephy_v8_50_regs_layout, \ + .phy_status = PHYSTATUS_4_20, \ + .clk_list = nord_pciephy_seg_##_seg##_clk_l, \ + .num_clks = ARRAY_SIZE(nord_pciephy_seg_##_seg##_clk_l), \ + .pipe_clk_list = _pipeclk_l, \ + .num_pipe_clks = 1, \ +} + +NORD_QMP_PCIE_SEG_CFG(a, nord_pciephy_seg_a_pipeclk_l, true); +NORD_QMP_PCIE_SEG_CFG(b, nord_pciephy_seg_b_pipeclk_l, true); +NORD_QMP_PCIE_SEG_CFG(c, nord_pciephy_seg_c_pipeclk_l, true); +NORD_QMP_PCIE_SEG_CFG(d, nord_pciephy_seg_d_pipeclk_l, true); +/* Ganged (non-anchor) groups pipe off their first member's pipe clock */ +NORD_QMP_PCIE_SEG_CFG(cd, nord_pciephy_seg_c_pipeclk_l, true); +NORD_QMP_PCIE_SEG_CFG(bcd, nord_pciephy_seg_b_pipeclk_l, true); +/* Fully-ganged x16 config — not bifurcated */ +NORD_QMP_PCIE_SEG_CFG(abcd, nord_pciephy_seg_a_pipeclk_l, false); + +#undef NORD_QMP_PCIE_SEG_CFG + +/* + * Nord link-mode table — maps the 2-bit TCSR_PCIE_LINK_CONFIG_MODE register + * value to the static per-group PHY configs above. + * + * Encoding from firmware (pcie_settings_{0,1,2,3}.c): + * 0x0 — x16: segs A+B+C+D ganged → 1 PHY + * 0x1 — x8+x8: seg A + segs B+C+D ganged → 2 PHYs + * 0x2 — x8+x4+x4: seg A + seg B + segs C+D ganged → 3 PHYs + * 0x3 — x8+x4+x2+x2: all segs independent → 4 PHYs (default) + */ +static const struct qmp_phy_cfg * const nord_qmp_gen4x16_mode_x16_cfgs[] = { + &nord_qmp_pcie_seg_abcd_cfg, +}; + +static const struct qmp_phy_cfg * const nord_qmp_gen4x16_mode_x8x8_cfgs[] = { + &nord_qmp_pcie_seg_a_cfg, + &nord_qmp_pcie_seg_bcd_cfg, +}; + +static const struct qmp_phy_cfg * const nord_qmp_gen4x16_mode_x8x4x4_cfgs[] = { + &nord_qmp_pcie_seg_a_cfg, + &nord_qmp_pcie_seg_b_cfg, + &nord_qmp_pcie_seg_cd_cfg, +}; + +static const struct qmp_phy_cfg * const nord_qmp_gen4x16_mode_x8x4x2x2_cfgs[] = { + &nord_qmp_pcie_seg_a_cfg, + &nord_qmp_pcie_seg_b_cfg, + &nord_qmp_pcie_seg_c_cfg, + &nord_qmp_pcie_seg_d_cfg, +}; + +static const struct qmp_pcie_link_mode_cfg nord_qmp_gen4x16_mode_cfgs[] = { + [QMP_PCIE_NORD_MODE_X16] = { + .cfgs = nord_qmp_gen4x16_mode_x16_cfgs, + .num_phys = ARRAY_SIZE(nord_qmp_gen4x16_mode_x16_cfgs), + }, + [QMP_PCIE_NORD_MODE_X8_X8] = { + .cfgs = nord_qmp_gen4x16_mode_x8x8_cfgs, + .num_phys = ARRAY_SIZE(nord_qmp_gen4x16_mode_x8x8_cfgs), + }, + [QMP_PCIE_NORD_MODE_X8_X4_X4] = { + .cfgs = nord_qmp_gen4x16_mode_x8x4x4_cfgs, + .num_phys = ARRAY_SIZE(nord_qmp_gen4x16_mode_x8x4x4_cfgs), + }, + [QMP_PCIE_NORD_MODE_X8_X4_X2_X2] = { + .cfgs = nord_qmp_gen4x16_mode_x8x4x2x2_cfgs, + .num_phys = ARRAY_SIZE(nord_qmp_gen4x16_mode_x8x4x2x2_cfgs), + }, +}; + +static const struct qmp_pcie_match_data nord_qmp_gen4x16_match_data = { + .mode_cfgs = nord_qmp_gen4x16_mode_cfgs, + .num_modes = ARRAY_SIZE(nord_qmp_gen4x16_mode_cfgs), + .shared_pd_name = "phy_a_gdsc", +}; + +/* + * Write PHY init tables to all segment windows in the group. Segment + * registers sit behind the per-group aux/rchng AHB clocks, so this must + * run after those clocks are enabled (see qmp_pcie_init()), not before. + * Mirrors gearvm sequence: pcie_phy_pwrup_seq + pcie_phy_cfg_seq. + * + * For Nord, the same tables are applied to each segment regardless of + * link mode: + * mode 0x0 (x16): 1 group, num_regs=4 — writes A,B,C,D + * mode 0x1 (x8+x8): group1 num_regs=3 — writes B,C,D + * mode 0x2 (x8+x4+x4): group2 num_regs=2 — writes C,D + * mode 0x3 (x8+x4+x2+x2): each num_regs=1 — writes one seg each + */ +static void qmp_pcie_init_seg_registers(struct qmp_pcie *qmp) +{ + const struct qmp_phy_cfg *cfg = qmp->cfg; + const struct qmp_pcie_offsets *offs = cfg->offsets; + const struct qmp_phy_cfg_tbls *tbls = &cfg->tbls; + int i; + + for (i = 0; i < cfg->num_regs; i++) { + void __iomem *seg = qmp->base[i]; + u32 val; + + /* + * Mirrors gearvm pcie_bifurcated_phy_pre_pwrup_seq: stall the + * lane LDOs before POWER_DOWN_CONTROL is written below, for + * every segment/group except the fully-ganged x16 config. + */ + if (cfg->bifurcated) + qmp_configure(qmp->dev, seg + offs->txrxz, + nord_qmp_pcie_bifurcated_pre_pwrup_tbl, + ARRAY_SIZE(nord_qmp_pcie_bifurcated_pre_pwrup_tbl)); + + /* Remove PHY from powerdown mode and allow refclk drive */ + writel(0x03, seg + offs->pcs + cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]); + + /* + * Mirrors gearvm pcie_bifurcated_phy_post_pwrup_seq: assert + * PLL_BIAS_EN across PHY instances to suppress PDN noise + * across link boundaries, for bifurcated segments/groups only. + */ + if (cfg->bifurcated) { + val = readl(seg + offs->pll + QSERDES_PCIE5_COM_BIAS_EN_CLKBUFLR_EN); + val |= BIT(1) | BIT(0); + writel(val, seg + offs->pll + QSERDES_PCIE5_COM_BIAS_EN_CLKBUFLR_EN); + } + + qmp_configure(qmp->dev, seg + offs->pll, + cfg->pll_tbls[i], cfg->pll_nums[i]); + qmp_configure(qmp->dev, seg + offs->txrxz, + tbls->txrxz, tbls->txrxz_num); + qmp_configure(qmp->dev, seg + offs->pcs, + tbls->pcs, tbls->pcs_num); + qmp_configure(qmp->dev, seg + offs->pcs_lanez, + tbls->pcs_lanez, tbls->pcs_lanez_num); + + /* + * Mirrors gearvm pcie_bifurcated_phy_post_cfg_seq: re-enable + * the lane LDOs before SW_RESET is released in + * qmp_pcie_power_on(), for bifurcated segments/groups only. + */ + if (cfg->bifurcated) + qmp_configure(qmp->dev, seg + offs->txrxz, + nord_qmp_pcie_bifurcated_post_cfg_tbl, + ARRAY_SIZE(nord_qmp_pcie_bifurcated_post_cfg_tbl)); + } +} + +static int qmp_pcie_pd_power_on(struct qmp_pcie *qmp) +{ + const struct qmp_phy_cfg *cfg = qmp->cfg; + int i, ret; + + for (i = 0; i < cfg->num_pds; i++) { + ret = pm_runtime_resume_and_get(qmp->pd_devs[i]); + if (ret < 0) { + dev_err(qmp->dev, "failed to power on %s domain: %d\n", + cfg->pd_names[i], ret); + goto err_power_off; + } + } + + return 0; + +err_power_off: + while (--i >= 0) + pm_runtime_put(qmp->pd_devs[i]); + + return ret; +} + +static void qmp_pcie_pd_power_off(struct qmp_pcie *qmp) +{ + const struct qmp_phy_cfg *cfg = qmp->cfg; + int i; + + for (i = cfg->num_pds - 1; i >= 0; i--) + pm_runtime_put(qmp->pd_devs[i]); +} + +static int qmp_pcie_init(struct phy *phy) +{ + struct qmp_pcie *qmp = phy_get_drvdata(phy); + const struct qmp_phy_cfg *cfg = qmp->cfg; + int ret; + + ret = qmp_pcie_pd_power_on(qmp); + if (ret) + return ret; + + ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs); + if (ret) { + dev_err(qmp->dev, "failed to enable regulators: %d\n", ret); + goto err_pd_power_off; + } + + ret = reset_control_bulk_assert(cfg->num_resets, qmp->resets); + if (ret) { + dev_err(qmp->dev, "reset assert failed: %d\n", ret); + goto err_disable_regulators; + } + + ret = reset_control_bulk_assert(qmp->cfg->num_nocsr_resets, qmp->nocsr_resets); + if (ret) { + dev_err(qmp->dev, "no-csr reset assert failed: %d\n", ret); + goto err_assert_reset; + } + + usleep_range(200, 300); + + ret = reset_control_bulk_deassert(cfg->num_resets, qmp->resets); + if (ret) { + dev_err(qmp->dev, "reset deassert failed: %d\n", ret); + goto err_assert_reset; + } + + ret = clk_bulk_prepare_enable(qmp->cfg->num_clks, qmp->clks); + if (ret) + goto err_assert_reset; + + if (cfg->pll_tbls) + qmp_pcie_init_seg_registers(qmp); + + return 0; + +err_assert_reset: + reset_control_bulk_assert(cfg->num_resets, qmp->resets); +err_disable_regulators: + regulator_bulk_disable(cfg->num_vregs, qmp->vregs); +err_pd_power_off: + qmp_pcie_pd_power_off(qmp); + + return ret; +} + +static int qmp_pcie_exit(struct phy *phy) +{ + struct qmp_pcie *qmp = phy_get_drvdata(phy); + const struct qmp_phy_cfg *cfg = qmp->cfg; + const struct qmp_pcie_offsets *offs = cfg->offsets; + int i; + + /* + * Linux-first only: power-down the PHY analog before asserting resets. + * Mirrors gearvm pcie_phy_de_init_seq: + * POWER_DOWN_CONTROL = 0x00 + */ + if (cfg->pll_tbls) { + for (i = 0; i < cfg->num_regs; i++) + writel(0x00, qmp->base[i] + offs->pcs + + cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]); + } + + if (qmp->nocsr_resets) + reset_control_bulk_assert(qmp->cfg->num_nocsr_resets, qmp->nocsr_resets); + else + reset_control_bulk_assert(cfg->num_resets, qmp->resets); + + clk_bulk_disable_unprepare(qmp->cfg->num_clks, qmp->clks); + regulator_bulk_disable(cfg->num_vregs, qmp->vregs); + qmp_pcie_pd_power_off(qmp); + + return 0; +} + +static int qmp_pcie_power_on(struct phy *phy) +{ + struct qmp_pcie *qmp = phy_get_drvdata(phy); + const struct qmp_phy_cfg *cfg = qmp->cfg; + const struct qmp_pcie_offsets *offs = cfg->offsets; + void __iomem *status; + unsigned int val; + int i, ret; + + ret = clk_bulk_prepare_enable(qmp->cfg->num_pipe_clks, qmp->pipe_clks); + if (ret) + return ret; + + ret = reset_control_bulk_deassert(qmp->cfg->num_nocsr_resets, qmp->nocsr_resets); + if (ret) { + dev_err(qmp->dev, "no-csr reset deassert failed: %d\n", ret); + goto err_disable_pipe_clk; + } + + /* + * Linux-first only: release SW_RESET then assert START_CONTROL to + * begin PHY power-up. Mirrors gearvm pcie_phy_start_seq: + * SW_RESET = 0x00 (de-assert soft reset) + * START_CONTROL = 0x03 (SERDES_START | PCS_START) + * Firmware-first (Glymur) skips this — firmware already started the PHY. + */ + if (cfg->pll_tbls) { + for (i = 0; i < cfg->num_regs; i++) { + writel(0x00, qmp->base[i] + offs->pcs + cfg->regs[QPHY_PCS_SW_RESET]); + writel(0x03, qmp->base[i] + offs->pcs + cfg->regs[QPHY_PCS_START_CONTROL]); + } + + /* Mirrors gearvm pcie_phy_delay_seq: settle time before polling PHYSTATUS */ + usleep_range(2000, 2500); + } + + for (i = 0; i < cfg->num_regs; i++) { + status = qmp->base[i] + offs->pcs + cfg->regs[QPHY_PCS_STATUS]; + ret = readl_poll_timeout(status, val, !(val & cfg->phy_status), 200, + PHY_INIT_COMPLETE_TIMEOUT_US); + if (ret) { + dev_err(qmp->dev, "PHY power on timed-out (%s): %d\n", + cfg->reg_names[i], ret); + goto err_disable_pipe_clk; + } + + } + + return 0; + +err_disable_pipe_clk: + clk_bulk_disable_unprepare(qmp->cfg->num_pipe_clks, qmp->pipe_clks); + + return ret; +} + +static int qmp_pcie_power_off(struct phy *phy) +{ + struct qmp_pcie *qmp = phy_get_drvdata(phy); + const struct qmp_phy_cfg *cfg = qmp->cfg; + const struct qmp_pcie_offsets *offs = cfg->offsets; + int i; + + /* + * Linux-first only: assert SW_RESET before stopping pipe clocks so + * the PHY state machine returns to a known idle state. + * Mirrors gearvm's power-down ordering before pcie_phy_de_init_seq. + */ + if (cfg->pll_tbls) { + for (i = 0; i < cfg->num_regs; i++) + writel(0x01, qmp->base[i] + offs->pcs + cfg->regs[QPHY_PCS_SW_RESET]); + } + + clk_bulk_disable_unprepare(qmp->cfg->num_pipe_clks, qmp->pipe_clks); + + return 0; +} + +static int qmp_pcie_enable(struct phy *phy) +{ + int ret; + + ret = qmp_pcie_init(phy); + if (ret) + return ret; + + ret = qmp_pcie_power_on(phy); + if (ret) + qmp_pcie_exit(phy); + + return ret; +} + +static int qmp_pcie_disable(struct phy *phy) +{ + int ret; + + ret = qmp_pcie_power_off(phy); + if (ret) + return ret; + + return qmp_pcie_exit(phy); +} + +static const struct phy_ops qmp_pcie_phy_ops = { + .power_on = qmp_pcie_enable, + .power_off = qmp_pcie_disable, + .owner = THIS_MODULE, +}; + +static void qmp_pcie_pd_detach(void *data) +{ + struct qmp_pcie *qmp = data; + const struct qmp_phy_cfg *cfg = qmp->cfg; + int i; + + for (i = 0; i < cfg->num_pds; i++) { + /* Shared domain is attached/detached once at the top level */ + if (qmp->shared_pd_dev && qmp->pd_devs[i] == qmp->shared_pd_dev) + continue; + if (!IS_ERR_OR_NULL(qmp->pd_devs[i])) + dev_pm_domain_detach(qmp->pd_devs[i], true); + } +} + +static int qmp_pcie_pd_init(struct qmp_pcie *qmp, const char *shared_pd_name) +{ + const struct qmp_phy_cfg *cfg = qmp->cfg; + struct device *dev = qmp->dev; + int i, ret; + + if (!cfg->num_pds) + return 0; + + qmp->pd_devs = devm_kcalloc(dev, cfg->num_pds, sizeof(*qmp->pd_devs), + GFP_KERNEL); + if (!qmp->pd_devs) + return -ENOMEM; + + for (i = 0; i < cfg->num_pds; i++) { + if (shared_pd_name && !strcmp(cfg->pd_names[i], shared_pd_name)) { + qmp->pd_devs[i] = qmp->shared_pd_dev; + continue; + } + + qmp->pd_devs[i] = dev_pm_domain_attach_by_name(dev, + cfg->pd_names[i]); + if (IS_ERR_OR_NULL(qmp->pd_devs[i])) { + ret = PTR_ERR(qmp->pd_devs[i]) ? : -ENODATA; + goto err_detach; + } + } + + return devm_add_action_or_reset(dev, qmp_pcie_pd_detach, qmp); + +err_detach: + while (--i >= 0) { + if (qmp->pd_devs[i] == qmp->shared_pd_dev) + continue; + dev_pm_domain_detach(qmp->pd_devs[i], false); + } + + return ret; +} + +static int qmp_pcie_vreg_init(struct qmp_pcie *qmp) +{ + const struct qmp_phy_cfg *cfg = qmp->cfg; + struct device *dev = qmp->dev; + int i; + + qmp->vregs = devm_kcalloc(dev, cfg->num_vregs, sizeof(*qmp->vregs), + GFP_KERNEL); + if (!qmp->vregs) + return -ENOMEM; + + for (i = 0; i < cfg->num_vregs; i++) + qmp->vregs[i].supply = cfg->vreg_list[i]; + + return devm_regulator_bulk_get(dev, cfg->num_vregs, qmp->vregs); +} + +static int qmp_pcie_reset_init(struct qmp_pcie *qmp) +{ + const struct qmp_phy_cfg *cfg = qmp->cfg; + struct device *dev = qmp->dev; + int i, ret; + + if (cfg->num_resets) { + qmp->resets = devm_kcalloc(dev, cfg->num_resets, + sizeof(*qmp->resets), GFP_KERNEL); + if (!qmp->resets) + return -ENOMEM; + + for (i = 0; i < cfg->num_resets; i++) + qmp->resets[i].id = cfg->reset_list[i]; + + ret = devm_reset_control_bulk_get_exclusive(dev, cfg->num_resets, + qmp->resets); + if (ret) + return dev_err_probe(dev, ret, "failed to get resets\n"); + } + + if (cfg->num_nocsr_resets) { + qmp->nocsr_resets = devm_kcalloc(dev, cfg->num_nocsr_resets, + sizeof(*qmp->nocsr_resets), + GFP_KERNEL); + if (!qmp->nocsr_resets) + return -ENOMEM; + + for (i = 0; i < cfg->num_nocsr_resets; i++) + qmp->nocsr_resets[i].id = cfg->nocsr_reset_list[i]; + + ret = devm_reset_control_bulk_get_exclusive(dev, + cfg->num_nocsr_resets, + qmp->nocsr_resets); + if (ret) + return dev_err_probe(dev, ret, "failed to get no-csr resets\n"); + } + + return 0; +} + +static int qmp_pcie_clk_init(struct qmp_pcie *qmp) +{ + const struct qmp_phy_cfg *cfg = qmp->cfg; + struct device *dev = qmp->dev; + int i, ret; + + qmp->clks = devm_kcalloc(dev, cfg->num_clks, sizeof(*qmp->clks), + GFP_KERNEL); + if (!qmp->clks) + return -ENOMEM; + + for (i = 0; i < cfg->num_clks; i++) + qmp->clks[i].id = cfg->clk_list[i]; + + ret = devm_clk_bulk_get_optional(dev, cfg->num_clks, qmp->clks); + if (ret) + return ret; + + qmp->pipe_clks = devm_kcalloc(dev, cfg->num_pipe_clks, + sizeof(*qmp->pipe_clks), GFP_KERNEL); + if (!qmp->pipe_clks) + return -ENOMEM; + + for (i = 0; i < cfg->num_pipe_clks; i++) + qmp->pipe_clks[i].id = cfg->pipe_clk_list[i]; + + return devm_clk_bulk_get_optional(dev, cfg->num_pipe_clks, + qmp->pipe_clks); +} + +static int __phy_pipe_clk_register(struct device *dev, struct device_node *np, + int idx, struct clk_fixed_rate *fixed) +{ + struct clk_init_data init = { }; + int ret; + + ret = of_property_read_string_index(np, "clock-output-names", idx, + &init.name); + if (ret) { + dev_err(dev, "%pOFn: No clock-output-names\n", np); + return ret; + } + + init.ops = &clk_fixed_rate_ops; + + fixed->fixed_rate = 125000000; + + fixed->hw.init = &init; + + return devm_clk_hw_register(dev, &fixed->hw); +} + +static struct clk_hw *qmp_pcie_multiphy_clk_hw_get(struct of_phandle_args *clkspec, + void *data) +{ + struct qmp_pcie_multiphy *qmp_data = data; + unsigned int idx = 0; + + if (clkspec->args_count) + idx = clkspec->args[0]; + + if (idx < (unsigned int)qmp_data->num_pipe_outputs) + return &qmp_data->pipe_out_clks[idx].hw; + + return ERR_PTR(-EINVAL); +} + +static int qmp_pcie_multiphy_register_clocks(struct device *dev, + struct device_node *np, + struct qmp_pcie_multiphy *qmp_data) +{ + int num_pipe_outputs; + int i, ret; + + num_pipe_outputs = of_property_count_strings(np, "clock-output-names"); + + qmp_data->num_pipe_outputs = num_pipe_outputs; + qmp_data->pipe_out_clks = devm_kcalloc(dev, num_pipe_outputs, + sizeof(*qmp_data->pipe_out_clks), + GFP_KERNEL); + if (!qmp_data->pipe_out_clks) + return -ENOMEM; + + for (i = 0; i < num_pipe_outputs; i++) { + ret = __phy_pipe_clk_register(dev, np, i, + &qmp_data->pipe_out_clks[i]); + if (ret) + return ret; + } + + return devm_of_clk_add_hw_provider(dev, qmp_pcie_multiphy_clk_hw_get, qmp_data); +} + +static int qmp_pcie_get_mmio(struct qmp_pcie *qmp) +{ + struct platform_device *pdev = to_platform_device(qmp->dev); + const struct qmp_phy_cfg *cfg = qmp->cfg; + struct device *dev = qmp->dev; + void __iomem *base; + int i; + + qmp->base = devm_kcalloc(dev, cfg->num_regs, sizeof(*qmp->base), + GFP_KERNEL); + if (!qmp->base) + return -ENOMEM; + + for (i = 0; i < cfg->num_regs; i++) { + base = devm_platform_ioremap_resource_byname(pdev, cfg->reg_names[i]); + if (IS_ERR(base)) + return PTR_ERR(base); + + qmp->base[i] = base; + } + + return 0; +} + +static int qmp_pcie_read_link_mode(struct device *dev, unsigned int *link_mode) +{ + struct regmap *map; + unsigned int args[1]; + + map = syscon_regmap_lookup_by_phandle_args(dev->of_node, "qcom,link-mode", + ARRAY_SIZE(args), args); + if (IS_ERR(map)) + return PTR_ERR(map); + + return regmap_read(map, args[0], link_mode); +} + +static struct phy *qmp_pcie_multiphy_xlate(struct device *dev, + const struct of_phandle_args *args) +{ + struct qmp_pcie_multiphy *qmp_data = dev_get_drvdata(dev); + unsigned int idx; + + if (!qmp_data || args->args_count < 1) + return ERR_PTR(-EINVAL); + + idx = args->args[0]; + + if (idx < (unsigned int)qmp_data->mode_cfg->num_phys) + return qmp_data->phys[idx] ?: ERR_PTR(-EINVAL); + + return ERR_PTR(-EINVAL); +} + +static int qmp_pcie_probe_phy(struct qmp_pcie *qmp, struct device_node *np, + struct phy **out_phy, const char *shared_pd_name) +{ + int ret; + + ret = qmp_pcie_get_mmio(qmp); + if (ret) + return ret; + + ret = qmp_pcie_clk_init(qmp); + if (ret) + return ret; + + ret = qmp_pcie_reset_init(qmp); + if (ret) + return ret; + + ret = qmp_pcie_vreg_init(qmp); + if (ret) + return ret; + + ret = qmp_pcie_pd_init(qmp, shared_pd_name); + if (ret) + return ret; + + *out_phy = devm_phy_create(qmp->dev, np, &qmp_pcie_phy_ops); + if (IS_ERR(*out_phy)) + return PTR_ERR(*out_phy); + + phy_set_drvdata(*out_phy, qmp); + + return 0; +} + +static void qmp_pcie_shared_pd_detach(void *data) +{ + struct qmp_pcie_multiphy *qmp_data = data; + + dev_pm_domain_detach(qmp_data->shared_pd_dev, true); +} + +static int qmp_pcie_multiphy_probe(struct platform_device *pdev) +{ + const struct qmp_pcie_match_data *match_data; + struct qmp_pcie_multiphy *qmp_data; + struct phy_provider *phy_provider; + struct device *dev = &pdev->dev; + unsigned int link_mode; + struct qmp_pcie *qmp; + struct phy **phys; + int phy_index; + int ret; + + qmp_data = devm_kzalloc(dev, sizeof(*qmp_data), GFP_KERNEL); + + match_data = of_device_get_match_data(dev); + if (!match_data) + return -EINVAL; + + if (!qmp_data) + return -ENOMEM; + + ret = qmp_pcie_read_link_mode(dev, &link_mode); + if (ret) + return dev_err_probe(dev, ret, "failed to read qcom,link-mode\n"); + + if (link_mode >= match_data->num_modes) + return dev_err_probe(dev, -EINVAL, "invalid qcom,link-mode: %u\n", + link_mode); + + qmp_data->mode_cfg = &match_data->mode_cfgs[link_mode]; + + qmp = devm_kcalloc(dev, qmp_data->mode_cfg->num_phys, sizeof(*qmp), GFP_KERNEL); + if (!qmp) + return -ENOMEM; + + phys = devm_kcalloc(dev, qmp_data->mode_cfg->num_phys, sizeof(*phys), GFP_KERNEL); + if (!phys) + return -ENOMEM; + + qmp_data->phys = phys; + dev_set_drvdata(dev, qmp_data); + + if (match_data->shared_pd_name) { + qmp_data->shared_pd_dev = dev_pm_domain_attach_by_name(dev, + match_data->shared_pd_name); + if (IS_ERR(qmp_data->shared_pd_dev)) + return PTR_ERR(qmp_data->shared_pd_dev); + + ret = devm_add_action_or_reset(dev, qmp_pcie_shared_pd_detach, + qmp_data); + if (ret) + return ret; + } + + for (phy_index = 0; phy_index < qmp_data->mode_cfg->num_phys; phy_index++) { + qmp[phy_index].dev = dev; + qmp[phy_index].cfg = qmp_data->mode_cfg->cfgs[phy_index]; + qmp[phy_index].shared_pd_dev = qmp_data->shared_pd_dev; + ret = qmp_pcie_probe_phy(&qmp[phy_index], dev->of_node, &phys[phy_index], + match_data->shared_pd_name); + if (ret) + return ret; + } + + ret = qmp_pcie_multiphy_register_clocks(dev, dev->of_node, qmp_data); + if (ret) + return ret; + + phy_provider = devm_of_phy_provider_register(dev, qmp_pcie_multiphy_xlate); + + return PTR_ERR_OR_ZERO(phy_provider); +} + +static const struct of_device_id qmp_pcie_multiphy_of_match_table[] = { + { + .compatible = "qcom,glymur-qmp-gen5x8-pcie-phy", + .data = &glymur_qmp_gen5x8_match_data, + }, + { + .compatible = "qcom,nord-qmp-gen4x16-pcie-phy", + .data = &nord_qmp_gen4x16_match_data, + }, + { } +}; +MODULE_DEVICE_TABLE(of, qmp_pcie_multiphy_of_match_table); + +static struct platform_driver qmp_pcie_multiphy_driver = { + .probe = qmp_pcie_multiphy_probe, + .driver = { + .name = "qcom-qmp-pcie-multiphy", + .of_match_table = qmp_pcie_multiphy_of_match_table, + }, +}; +module_platform_driver(qmp_pcie_multiphy_driver); + +MODULE_AUTHOR("Qiang Yu "); +MODULE_DESCRIPTION("Qualcomm QMP PCIe Multi-PHY driver for Glymur and Nord"); +MODULE_LICENSE("GPL"); diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie5.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie5.h new file mode 100644 index 0000000000000..e129c5bf609ff --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie5.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * + * Nord PCIe5 16-lane PHY — PCS COM and PCS LANE-Z registers. + * + * PCS COM offsets are relative to PCS sub-region base (segment_base + 0x9000). + * PCS LANEZ offsets are relative to LANEZ sub-region base (segment_base + 0xe800). + * Source: NORDSCHLEIFE_2.0 QMP PCIe 5.0 16lane PHY HSR for n4_30.0 + */ + +#ifndef QCOM_PHY_QMP_PCS_PCIE5_H_ +#define QCOM_PHY_QMP_PCS_PCIE5_H_ + +/* PCS COM — power, start, clocks */ +#define QPHY_PCIE5_PCS_COM_POWER_STATE_CONFIG2 0x06c +#define QPHY_PCIE5_PCS_COM_POWER_STATE_CONFIG5 0x078 +#define QPHY_PCIE5_PCS_COM_POWER_STATE_CONFIG6 0x07c +#define QPHY_PCIE5_PCS_COM_POWER_STATE_CONFIG7 0x080 +#define QPHY_PCIE5_PCS_COM_MULTIPHY_CONFIG2 0x088 +#define QPHY_PCIE5_PCS_COM_PCS_TX_RX_CONFIG2 0x0a0 +#define QPHY_PCIE5_PCS_COM_PCS_TX_RX_CONFIG3 0x0a4 +#define QPHY_PCIE5_PCS_COM_PCS_TX_RX_CONFIG5 0x0ac +#define QPHY_PCIE5_PCS_COM_PCS_TX_RX_CONFIG6 0x0b0 +#define QPHY_PCIE5_PCS_COM_PCS_TX_RX_CONFIG7 0x0b4 +#define QPHY_PCIE5_PCS_COM_PCS_TX_RX_CONFIG8 0x0b8 +#define QPHY_PCIE5_PCS_COM_PCS_TX_RX_CONFIG10 0x0c0 +#define QPHY_PCIE5_PCS_COM_ENDPOINT_REFCLK_DRIVE 0x0c8 +#define QPHY_PCIE5_PCS_COM_RX_SIGDET_LVL 0x0ec +#define QPHY_PCIE5_PCS_COM_DIVTX_CLK_DCC_CAL_CONFIG2 0x0f8 +#define QPHY_PCIE5_PCS_COM_DIVTX_CLK_DCC_CAL_CONFIG3 0x0fc +#define QPHY_PCIE5_PCS_COM_DIVTX_CLK_DCC_CAL_CONFIG4 0x100 +#define QPHY_PCIE5_PCS_COM_OSC_DTCT_ACTIONS 0x194 +#define QPHY_PCIE5_PCS_COM_LOCK_DETECT_CONFIG1 0x1bc +#define QPHY_PCIE5_PCS_COM_LOCK_DETECT_CONFIG2 0x1c0 +#define QPHY_PCIE5_PCS_COM_ALIGN_DETECT_CONFIG1 0x1dc +#define QPHY_PCIE5_PCS_COM_ALIGN_DETECT_CONFIG2 0x1e0 +#define QPHY_PCIE5_PCS_COM_ALIGN_DETECT_CONFIG3 0x1e4 +#define QPHY_PCIE5_PCS_COM_ALIGN_DETECT_CONFIG7 0x1f4 +#define QPHY_PCIE5_PCS_COM_ALIGN_DETECT_CONFIG8 0x1f8 + +/* PCS COM — EQ config */ +#define QPHY_PCIE5_PCS_COM_EQ_CONFIG1 0x380 +#define QPHY_PCIE5_PCS_COM_EQ_CONFIG2 0x384 +#define QPHY_PCIE5_PCS_COM_G345_EQ_CONFIG1 0x38c +#define QPHY_PCIE5_PCS_COM_G345_EQ_CONFIG3 0x394 +#define QPHY_PCIE5_PCS_COM_G3_EQ_CONFIG1 0x3a4 +#define QPHY_PCIE5_PCS_COM_G3_EQ_CONFIG5 0x3b4 +#define QPHY_PCIE5_PCS_COM_G3_EQ_CONFIG7 0x3bc +#define QPHY_PCIE5_PCS_COM_G4_EQ_CONFIG1 0x3c8 +#define QPHY_PCIE5_PCS_COM_G4_EQ_CONFIG5 0x3d8 +#define QPHY_PCIE5_PCS_COM_G4_EQ_CONFIG7 0x3e0 +#define QPHY_PCIE5_PCS_COM_G5_EQ_CONFIG1 0x3ec +#define QPHY_PCIE5_PCS_COM_G5_EQ_CONFIG5 0x3fc +#define QPHY_PCIE5_PCS_COM_G5_EQ_CONFIG7 0x404 +#define QPHY_PCIE5_PCS_COM_TEST_CONTROL1 0x468 + +/* PCS LANEZ — output signal mux control */ +#define QPHY_PCIE5_PCS_LANEZ_OUTSIG_MX_CTRL2 0x0e0 +#define QPHY_PCIE5_PCS_LANEZ_OUTSIG_MX_CTRL5 0x0f8 + +#endif /* QCOM_PHY_QMP_PCS_PCIE5_H_ */ diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50-nord.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50-nord.h new file mode 100644 index 0000000000000..ff661531a8aca --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50-nord.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * + * Nord PCIe Gen4 16-lane PHY — PCS v8.50 registers. + * + * Offsets are relative to PCS sub-region base (segment_base + 0x9000). + * Source: NORDSCHLEIFE_2.0 QMP PCIe 4.0 16lane PHY HSR for n4_30.0 + */ + +#ifndef QCOM_PHY_QMP_PCS_V8_50_NORD_H_ +#define QCOM_PHY_QMP_PCS_V8_50_NORD_H_ + +#define QPHY_NORD_V8_50_PCS_STATUS1 0x010 +#define QPHY_NORD_V8_50_PCS_START_CONTROL 0x05c +#define QPHY_NORD_V8_50_PCS_SW_RESET 0x060 +#define QPHY_NORD_V8_50_PCS_POWER_DOWN_CONTROL 0x064 + +#endif /* QCOM_PHY_QMP_PCS_V8_50_NORD_H_ */ diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-pcie5.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-pcie5.h new file mode 100644 index 0000000000000..0ee93fe7cbfac --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-pcie5.h @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * + * Nord PCIe5 16-lane PHY — PLL / COM block registers. + * Offsets are relative to the PLL sub-region base (segment_base + 0x8000). + * Source: NORDSCHLEIFE_2.0 QMP PCIe 5.0 16lane PHY HSR for n4_30.0 + */ + +#ifndef QCOM_PHY_QMP_QSERDES_COM_PCIE5_H_ +#define QCOM_PHY_QMP_QSERDES_COM_PCIE5_H_ + +#define QSERDES_PCIE5_COM_SSC_STEP_SIZE1_MODE1 0x000 +#define QSERDES_PCIE5_COM_SSC_STEP_SIZE2_MODE1 0x004 +#define QSERDES_PCIE5_COM_CLK_EP_DIV_MODE1 0x00c +#define QSERDES_PCIE5_COM_CP_CTRL_MODE1 0x010 +#define QSERDES_PCIE5_COM_PLL_RCTRL_MODE1 0x014 +#define QSERDES_PCIE5_COM_PLL_CCTRL_MODE1 0x018 +#define QSERDES_PCIE5_COM_CORECLK_DIV_MODE1 0x01c +#define QSERDES_PCIE5_COM_LOCK_CMP1_MODE1 0x020 +#define QSERDES_PCIE5_COM_LOCK_CMP2_MODE1 0x024 +#define QSERDES_PCIE5_COM_DEC_START_MODE1 0x028 +#define QSERDES_PCIE5_COM_DIV_FRAC_START1_MODE1 0x030 +#define QSERDES_PCIE5_COM_DIV_FRAC_START2_MODE1 0x034 +#define QSERDES_PCIE5_COM_DIV_FRAC_START3_MODE1 0x038 +#define QSERDES_PCIE5_COM_HSCLK_SEL_1 0x03c +#define QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE1_MODE1 0x050 +#define QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE2_MODE1 0x054 +#define QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x058 +#define QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x05c +#define QSERDES_PCIE5_COM_SSC_STEP_SIZE1_MODE0 0x060 +#define QSERDES_PCIE5_COM_SSC_STEP_SIZE2_MODE0 0x064 +#define QSERDES_PCIE5_COM_CLK_EP_DIV_MODE0 0x06c +#define QSERDES_PCIE5_COM_CP_CTRL_MODE0 0x070 +#define QSERDES_PCIE5_COM_PLL_RCTRL_MODE0 0x074 +#define QSERDES_PCIE5_COM_PLL_CCTRL_MODE0 0x078 +#define QSERDES_PCIE5_COM_CORECLK_DIV_MODE0 0x07c +#define QSERDES_PCIE5_COM_LOCK_CMP1_MODE0 0x080 +#define QSERDES_PCIE5_COM_LOCK_CMP2_MODE0 0x084 +#define QSERDES_PCIE5_COM_DEC_START_MODE0 0x088 +#define QSERDES_PCIE5_COM_DIV_FRAC_START1_MODE0 0x090 +#define QSERDES_PCIE5_COM_DIV_FRAC_START2_MODE0 0x094 +#define QSERDES_PCIE5_COM_DIV_FRAC_START3_MODE0 0x098 +#define QSERDES_PCIE5_COM_HSCLK_HS_SWITCH_SEL_1 0x09c +#define QSERDES_PCIE5_COM_BG_TIMER 0x0bc +#define QSERDES_PCIE5_COM_SSC_EN_CENTER 0x0c0 +#define QSERDES_PCIE5_COM_SSC_PER1 0x0cc +#define QSERDES_PCIE5_COM_SSC_PER2 0x0d0 +#define QSERDES_PCIE5_COM_POST_DIV_MUX 0x0d8 +#define QSERDES_PCIE5_COM_BIAS_EN_CLKBUFLR_EN 0x0dc +#define QSERDES_PCIE5_COM_CLK_ENABLE1 0x0e0 +#define QSERDES_PCIE5_COM_SYS_CLK_CTRL 0x0e4 +#define QSERDES_PCIE5_COM_PLL_IVCO 0x0f4 +#define QSERDES_PCIE5_COM_CMN_IETRIM 0x0fc +#define QSERDES_PCIE5_COM_SYSCLK_EN_SEL 0x110 +#define QSERDES_PCIE5_COM_LOCK_CMP_EN 0x120 +#define QSERDES_PCIE5_COM_LOCK_CMP_CFG 0x124 +#define QSERDES_PCIE5_COM_VCO_TUNE_CTRL 0x13c +#define QSERDES_PCIE5_COM_VCO_TUNE_MAP 0x140 +#define QSERDES_PCIE5_COM_CLK_SELECT 0x164 +#define QSERDES_PCIE5_COM_CORE_CLK_EN 0x170 +#define QSERDES_PCIE5_COM_CMN_CONFIG_1 0x174 +#define QSERDES_PCIE5_COM_CMN_MISC1 0x188 +#define QSERDES_PCIE5_COM_CMN_MODE 0x18c +#define QSERDES_PCIE5_COM_BIN_VCOCAL_HSCLK_SEL_1 0x1a0 +#define QSERDES_PCIE5_COM_VCO_DC_LEVEL_CTRL 0x19c +#define QSERDES_PCIE5_COM_HSCLK_SEL_2 0x21c +#define QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE1_MODE2 0x220 +#define QSERDES_PCIE5_COM_BIN_VCOCAL_CMP_CODE2_MODE2 0x224 +#define QSERDES_PCIE5_COM_HSCLK_HS_SWITCH_SEL_2 0x228 +#define QSERDES_PCIE5_COM_BIN_VCOCAL_HSCLK_SEL_2 0x230 +#define QSERDES_PCIE5_COM_CMN_CONFIG_2 0x22c +#define QSERDES_PCIE5_COM_SSC_STEP_SIZE1_MODE2 0x1cc +#define QSERDES_PCIE5_COM_SSC_STEP_SIZE2_MODE2 0x1d0 +#define QSERDES_PCIE5_COM_CP_CTRL_MODE2 0x1dc +#define QSERDES_PCIE5_COM_PLL_RCTRL_MODE2 0x1e0 +#define QSERDES_PCIE5_COM_PLL_CCTRL_MODE2 0x1e4 +#define QSERDES_PCIE5_COM_CORECLK_DIV_MODE2 0x1e8 +#define QSERDES_PCIE5_COM_LOCK_CMP1_MODE2 0x1ec +#define QSERDES_PCIE5_COM_LOCK_CMP2_MODE2 0x1f0 +#define QSERDES_PCIE5_COM_DEC_START_MODE2 0x1f4 +#define QSERDES_PCIE5_COM_DIV_FRAC_START1_MODE2 0x1fc +#define QSERDES_PCIE5_COM_DIV_FRAC_START2_MODE2 0x200 +#define QSERDES_PCIE5_COM_DIV_FRAC_START3_MODE2 0x204 +#define QSERDES_PCIE5_COM_DCC_CAL_1 0x2d8 +#define QSERDES_PCIE5_COM_DCC_CAL_2 0x2dc +#define QSERDES_PCIE5_COM_DCC_CAL_3 0x2e0 +#define QSERDES_PCIE5_COM_PSM_CAL_EN 0x2f0 +#define QSERDES_PCIE5_COM_CLK_FWD_CONFIG_1 0x2f4 +#define QSERDES_PCIE5_COM_IP_CTRL_AND_DP_SEL 0x2fc +#define QSERDES_PCIE5_COM_PLL_SPARE_FOR_ECO 0x2b8 +#define QSERDES_PCIE5_COM_PLL_IVCO_MODE1 0x0f8 +#define QSERDES_PCIE5_COM_PLL_IVCO_MODE2 0x218 +#define QSERDES_PCIE5_COM_DCC_CAL_7 0x300 +#define QSERDES_PCIE5_COM_DCC_CAL_8 0x304 +#define QSERDES_PCIE5_COM_DCC_CAL_9 0x308 + +#endif /* QCOM_PHY_QMP_QSERDES_COM_PCIE5_H_ */ diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrxz-pcie5.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrxz-pcie5.h new file mode 100644 index 0000000000000..98a804681c26a --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrxz-pcie5.h @@ -0,0 +1,198 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * + * Nord PCIe5 16-lane PHY — TXRXZ combined TX/RX zone block registers. + * Offsets are relative to the TXRXZ sub-region base (segment_base + 0xd000). + * Source: NORDSCHLEIFE_2.0 QMP PCIe 5.0 16lane PHY HSR for n4_30.0 + */ + +#ifndef QCOM_PHY_QMP_QSERDES_TXRXZ_PCIE5_H_ +#define QCOM_PHY_QMP_QSERDES_TXRXZ_PCIE5_H_ + +/* Lane mode / LDO */ +#define QSERDES_PCIE5_TXRXZ_PCIE5_TOP_LDO_CODE_CTRL1 0x070 +#define QSERDES_PCIE5_TXRXZ_PCIE5_TOP_LDO_CODE_CTRL2 0x074 +#define QSERDES_PCIE5_TXRXZ_PCIE5_TOP_LDO_CODE_CTRL3 0x078 +#define QSERDES_PCIE5_TXRXZ_PCIE5_TOP_LDO_CODE_CTRL4 0x07c +#define QSERDES_PCIE5_TXRXZ_LANE_MODE_1 0x094 +#define QSERDES_PCIE5_TXRXZ_LANE_MODE_2 0x098 +#define QSERDES_PCIE5_TXRXZ_LANE_MODE_3 0x09c +#define QSERDES_PCIE5_TXRXZ_LANE_MODE_4 0x0a0 +#define QSERDES_PCIE5_TXRXZ_RESTRIM_VREF_SEL 0x0bc +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE_0_1_B0 0x0f4 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE_0_1_B1 0x0f8 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE_0_1_B2 0x0fc +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE_0_1_B3 0x100 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE_0_1_B4 0x104 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE_0_1_B5 0x108 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE_0_1_B6 0x10c +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE_0_1_B7 0x110 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE2_B0 0x114 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE2_B1 0x118 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE2_B2 0x11c +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE2_B3 0x120 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE2_B4 0x124 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE2_B5 0x128 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE2_B6 0x12c +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE2_B7 0x130 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE3_B0 0x134 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE3_B1 0x138 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE3_B2 0x13c +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE3_B3 0x140 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE3_B4 0x144 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE3_B5 0x148 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE3_B6 0x14c +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE3_B7 0x150 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE4_B0 0x154 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE4_B1 0x158 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE4_B2 0x15c +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE4_B3 0x160 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE4_B4 0x164 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE4_B5 0x168 +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE4_B6 0x16c +#define QSERDES_PCIE5_TXRXZ_RX_MODE_RATE4_B7 0x170 + +/* VCO / KVCO calibration */ +#define QSERDES_PCIE5_TXRXZ_CDR_VCO_CTUNE_MEAS_CNT1_RATE0 0x1b4 +#define QSERDES_PCIE5_TXRXZ_CDR_VCO_CTUNE_MEAS_CNT2_RATE0 0x1b8 +#define QSERDES_PCIE5_TXRXZ_CDR_VCO_CTUNE_MEAS_CNT1_RATE1 0x1bc +#define QSERDES_PCIE5_TXRXZ_CDR_VCO_CTUNE_MEAS_CNT2_RATE1 0x1c0 +#define QSERDES_PCIE5_TXRXZ_CDR_VCO_CTUNE_MEAS_CNT1_RATE2 0x1c4 +#define QSERDES_PCIE5_TXRXZ_CDR_VCO_CTUNE_MEAS_CNT2_RATE2 0x1c8 +#define QSERDES_PCIE5_TXRXZ_CDR_VCO_CTUNE_MEAS_CNT1_RATE3 0x1cc +#define QSERDES_PCIE5_TXRXZ_CDR_VCO_CTUNE_MEAS_CNT2_RATE3 0x1d0 +#define QSERDES_PCIE5_TXRXZ_CDR_VCO_CTUNE_MEAS_CNT1_RATE4 0x1d4 +#define QSERDES_PCIE5_TXRXZ_CDR_VCO_CTUNE_MEAS_CNT2_RATE4 0x1d8 +#define QSERDES_PCIE5_TXRXZ_CDR_VCTRL_RATE_0_1 0x1dc +#define QSERDES_PCIE5_TXRXZ_CDR_VCTRL_RATE_2_3 0x1e0 +#define QSERDES_PCIE5_TXRXZ_KVCO_INIT_RATE_0_1 0x1e8 +#define QSERDES_PCIE5_TXRXZ_KVCO_INIT_RATE_2_3 0x1ec +#define QSERDES_PCIE5_TXRXZ_KVCO_INIT_RATE_4 0x1f0 +#define QSERDES_PCIE5_TXRXZ_KVCO_CODE_OVRD_RATE0 0x1f4 +#define QSERDES_PCIE5_TXRXZ_KVCO_CODE_OVRD_RATE1 0x1f8 +#define QSERDES_PCIE5_TXRXZ_KVCO_CODE_OVRD_RATE2 0x1fc +#define QSERDES_PCIE5_TXRXZ_KVCO_IDEAL_FREQ_DIFF1_RATE0 0x220 +#define QSERDES_PCIE5_TXRXZ_KVCO_IDEAL_FREQ_DIFF2_RATE0 0x224 +#define QSERDES_PCIE5_TXRXZ_KVCO_IDEAL_FREQ_DIFF1_RATE1 0x228 +#define QSERDES_PCIE5_TXRXZ_KVCO_IDEAL_FREQ_DIFF2_RATE1 0x22c +#define QSERDES_PCIE5_TXRXZ_KVCO_IDEAL_FREQ_DIFF1_RATE2 0x230 +#define QSERDES_PCIE5_TXRXZ_KVCO_IDEAL_FREQ_DIFF2_RATE2 0x234 +#define QSERDES_PCIE5_TXRXZ_KVCO_IDEAL_FREQ_DIFF1_RATE3 0x238 +#define QSERDES_PCIE5_TXRXZ_KVCO_IDEAL_FREQ_DIFF1_RATE4 0x240 +#define QSERDES_PCIE5_TXRXZ_KP_CODE_OVRD_RATE_2_3 0x250 +#define QSERDES_PCIE5_TXRXZ_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE0 0x258 +#define QSERDES_PCIE5_TXRXZ_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE1 0x260 +#define QSERDES_PCIE5_TXRXZ_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE2 0x268 +#define QSERDES_PCIE5_TXRXZ_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE3 0x270 +#define QSERDES_PCIE5_TXRXZ_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE4 0x278 +#define QSERDES_PCIE5_TXRXZ_KP_CAL_LOWER_FREQ_DIFF_BND_RATE0 0x280 +#define QSERDES_PCIE5_TXRXZ_KP_CAL_LOWER_FREQ_DIFF_BND_RATE1 0x284 +#define QSERDES_PCIE5_TXRXZ_KP_CAL_LOWER_FREQ_DIFF_BND_RATE2 0x288 +#define QSERDES_PCIE5_TXRXZ_KP_CAL_LOWER_FREQ_DIFF_BND_RATE3 0x28c +#define QSERDES_PCIE5_TXRXZ_KP_CAL_LOWER_FREQ_DIFF_BND_RATE4 0x290 +#define QSERDES_PCIE5_TXRXZ_RX_SUMMER_CAL_SPD_MODE_RATE_0123 0x2a8 +#define QSERDES_PCIE5_TXRXZ_RX_IVCM_CAL_CTRL2 0x2c8 +#define QSERDES_PCIE5_TXRXZ_RX_IVCM_CAL_CTRL3 0x2cc +#define QSERDES_PCIE5_TXRXZ_RX_IVCM_CAL_CTRL4 0x2d0 + +/* Signal detect */ +#define QSERDES_PCIE5_TXRXZ_SIGDET_ENABLES 0x31c +#define QSERDES_PCIE5_TXRXZ_FREQ_LOCK_DET_DLY_RATE0 0x33c +#define QSERDES_PCIE5_TXRXZ_FREQ_LOCK_DET_DLY_RATE1 0x340 +#define QSERDES_PCIE5_TXRXZ_FREQ_LOCK_DET_DLY_RATE2 0x344 +#define QSERDES_PCIE5_TXRXZ_FREQ_LOCK_DET_DLY_RATE3 0x348 +#define QSERDES_PCIE5_TXRXZ_FREQ_LOCK_DET_DLY_RATE4 0x34c + +/* CDR */ +#define QSERDES_PCIE5_TXRXZ_CDR_LOCK_CTRL 0x364 +#define QSERDES_PCIE5_TXRXZ_CDR_CP_CUR_FLL_RATE0 0x368 +#define QSERDES_PCIE5_TXRXZ_CDR_CP_CUR_FLL_RATE1 0x36c +#define QSERDES_PCIE5_TXRXZ_CDR_CP_CUR_FLL_RATE2 0x370 +#define QSERDES_PCIE5_TXRXZ_CDR_CP_CUR_FLL_RATE3 0x374 +#define QSERDES_PCIE5_TXRXZ_CDR_CP_CUR_FLL_RATE4 0x378 +#define QSERDES_PCIE5_TXRXZ_CDR_CP_CUR_PLL_RATE0 0x37c +#define QSERDES_PCIE5_TXRXZ_CDR_CP_CUR_PLL_RATE1 0x380 +#define QSERDES_PCIE5_TXRXZ_CDR_CP_CUR_PLL_RATE2 0x384 +#define QSERDES_PCIE5_TXRXZ_CDR_CP_CUR_PLL_RATE3 0x388 +#define QSERDES_PCIE5_TXRXZ_CDR_CP_CUR_PLL_RATE4 0x38c +#define QSERDES_PCIE5_TXRXZ_CDR_FLL_DIV_RATIO_RATE_0123 0x390 +#define QSERDES_PCIE5_TXRXZ_CDR_LOOP_CCODE_RATE_01 0x398 +#define QSERDES_PCIE5_TXRXZ_CDR_LOOP_CCODE_RATE_23 0x39c +#define QSERDES_PCIE5_TXRXZ_CDR_LOOP_CCODE_RATE4 0x3a0 +#define QSERDES_PCIE5_TXRXZ_CDR_LOOP_RCODE_FAST_RATE_0_1 0x3a4 +#define QSERDES_PCIE5_TXRXZ_CDR_LOOP_RCODE_FAST_RATE_2_3 0x3a8 +#define QSERDES_PCIE5_TXRXZ_CDR_LOOP_RCODE_FAST_RATE4 0x3ac +#define QSERDES_PCIE5_TXRXZ_CDR_LOOP_RCODE_FLL_RATE_0_1 0x3b0 +#define QSERDES_PCIE5_TXRXZ_CDR_LOOP_RCODE_FLL_RATE_2_3 0x3b4 +#define QSERDES_PCIE5_TXRXZ_CDR_LOOP_RCODE_FLL_RATE4 0x3b8 +#define QSERDES_PCIE5_TXRXZ_CDR_LOOP_RCODE_PLL_RATE_0_1 0x3bc +#define QSERDES_PCIE5_TXRXZ_CDR_LOOP_RCODE_PLL_RATE_2_3 0x3c0 +#define QSERDES_PCIE5_TXRXZ_CDR_LOOP_RCODE_PLL_RATE4 0x3c4 +#define QSERDES_PCIE5_TXRXZ_CDR_VCO_CAP_CODE_RATE_0123 0x3c8 +#define QSERDES_PCIE5_TXRXZ_CDR_VCO_TYPE_CONFIG 0x3d0 +#define QSERDES_PCIE5_TXRXZ_CDR_VCO_EN_LOWFREQ 0x3d4 +#define QSERDES_PCIE5_TXRXZ_CDR_LOOP_FUNC_CTRL 0x3dc + +/* Rescode / residuals */ +#define QSERDES_PCIE5_TXRXZ_RES_CODE_LANE_OFFSET_RX 0x3f4 + +/* VGA / GM calibration */ +#define QSERDES_PCIE5_TXRXZ_GM_CAL_RES_RATE0_1 0x404 +#define QSERDES_PCIE5_TXRXZ_GM_CAL_RES_RATE2_3 0x408 +#define QSERDES_PCIE5_TXRXZ_GM_CAL_RES_RATE4 0x40c + +/* RX equalizer */ +#define QSERDES_PCIE5_TXRXZ_RX_EQU_ADAPTOR_CNTRL3 0x454 +#define QSERDES_PCIE5_TXRXZ_RX_EQU_ADAPTOR_CNTRL4 0x458 +#define QSERDES_PCIE5_TXRXZ_RX_EQU_ADAPTOR_CNTRL5 0x45c +#define QSERDES_PCIE5_TXRXZ_CTLE_POST_CAL_OFFSET_RATE_0_1_2 0x478 +#define QSERDES_PCIE5_TXRXZ_VGA_CAL_MAN_VAL_RATE0_1 0x490 +#define QSERDES_PCIE5_TXRXZ_VGA_CAL_MAN_VAL_RATE2_3 0x494 +#define QSERDES_PCIE5_TXRXZ_VGA_CAL_MAN_VAL_RATE4 0x498 +#define QSERDES_PCIE5_TXRXZ_VTHRESH_CAL_MAN_VAL_RATE4 0x4bc + +/* DFE */ +#define QSERDES_PCIE5_TXRXZ_DFE_TAP1_DAC_ENABLE 0x50c +#define QSERDES_PCIE5_TXRXZ_DFE_TAP2_DAC_ENABLE 0x510 +#define QSERDES_PCIE5_TXRXZ_DFE_TAP345_DAC_ENABLE 0x514 +#define QSERDES_PCIE5_TXRXZ_DFE_TAP67_DAC_ENABLE 0x518 +#define QSERDES_PCIE5_TXRXZ_PHPRE_CTRL 0x51c +#define QSERDES_PCIE5_TXRXZ_TX_ADAPT_POST_THRESH1 0x52c +#define QSERDES_PCIE5_TXRXZ_TX_ADAPT_POST_THRESH2 0x530 +#define QSERDES_PCIE5_TXRXZ_TX_ADPT_CTRL 0x53c +#define QSERDES_PCIE5_TXRXZ_CDR_IQTUNE_CTRL 0x548 +#define QSERDES_PCIE5_TXRXZ_CDR_IQTUNE_MAN_INDEX 0x550 +#define QSERDES_PCIE5_TXRXZ_CDR_IQTUNE_ANA_CTRL 0x584 +#define QSERDES_PCIE5_TXRXZ_CDR_IQTUNE_DIV2_CTRL_RATE0123 0x58c +#define QSERDES_PCIE5_TXRXZ_CDR_VCO_CAP_CODE_OVRD_MUXES 0x5ac +#define QSERDES_PCIE5_TXRXZ_CDR_VCO_CAP_CODE_RATE4 0x3cc + +/* Clock buffer / LDO stall control (used by bifurcated pre/post-pwrup sequences) */ +#define QSERDES_PCIE5_TXRXZ_CLKBUF_ENABLE 0x04c +#define QSERDES_PCIE5_TXRXZ_PRE_STALL_LDO_BOOST_EN 0x06c +#define QSERDES_PCIE5_TXRXZ_LDO_TIMER_CTRL 0x0d8 + +/* Restrim / VGA / signal-detect (v2-only) */ +#define QSERDES_PCIE5_TXRXZ_RESTRIM_CAL_CTRL 0x0b0 +#define QSERDES_PCIE5_TXRXZ_RESTRIM_POST_CAL_OFFSET 0x0b8 +#define QSERDES_PCIE5_TXRXZ_SIGDET_CNTRL 0x320 +#define QSERDES_PCIE5_TXRXZ_SIGDET_LVL 0x324 +#define QSERDES_PCIE5_TXRXZ_SIGDET_CAL_CTRL1 0x32c +#define QSERDES_PCIE5_TXRXZ_VGA_CAL_CNTRL1 0x488 + +/* BLW / VCO coarse-tune bands (v2-only) */ +#define QSERDES_PCIE5_TXRXZ_BLW_CTRL 0x594 +#define QSERDES_PCIE5_TXRXZ_BLW_MAN_VAL_RATE3 0x5a4 +#define QSERDES_PCIE5_TXRXZ_BLW_MAN_VAL_RATE4 0x5a8 +#define QSERDES_PCIE5_TXRXZ_VCO_CTUNE_UPPER_BND_RATE0 0x5c4 +#define QSERDES_PCIE5_TXRXZ_VCO_CTUNE_UPPER_BND_RATE1 0x5c8 +#define QSERDES_PCIE5_TXRXZ_VCO_CTUNE_UPPER_BND_RATE2 0x5cc +#define QSERDES_PCIE5_TXRXZ_VCO_CTUNE_UPPER_BND_RATE3 0x5d0 +#define QSERDES_PCIE5_TXRXZ_VCO_CTUNE_UPPER_BND_RATE4 0x5d4 + +/* Analog backup control (v2-only) */ +#define QSERDES_PCIE5_TXRXZ_DIG_BKUP_CTRL15 0x7e8 +#define QSERDES_PCIE5_TXRXZ_DIG_BKUP_CTRL16 0x7ec + +#endif /* QCOM_PHY_QMP_QSERDES_TXRXZ_PCIE5_H_ */ diff --git a/include/dt-bindings/phy/phy-qcom-qmp.h b/include/dt-bindings/phy/phy-qcom-qmp.h index 6b43ea9e00518..64fccac529129 100644 --- a/include/dt-bindings/phy/phy-qcom-qmp.h +++ b/include/dt-bindings/phy/phy-qcom-qmp.h @@ -21,4 +21,21 @@ #define QMP_PCIE_PIPE_CLK 0 #define QMP_PCIE_PHY_AUX_CLK 1 +/* Generic QMP logical PHY selectors */ +#define QMP_PHY_SELECTOR_0 0 +#define QMP_PHY_SELECTOR_1 1 +#define QMP_PHY_SELECTOR_2 2 +#define QMP_PHY_SELECTOR_3 3 + +/* + * Nord (SA8797P) QMP PCIe link-mode values (TCSR_PCIE_LINK_CONFIG_MODE bits[1:0]) + * These match the hardware register encoding programmed by the bootloader. + * The Linux driver reads this register at probe time; these constants are + * provided for documentation and for board firmware that writes the register. + */ +#define QMP_PCIE_NORD_MODE_X16 0 /* all 16 lanes -> single x16 port */ +#define QMP_PCIE_NORD_MODE_X8_X8 1 /* x8 (seg A) + x8 (segs B+C+D ganged) */ +#define QMP_PCIE_NORD_MODE_X8_X4_X4 2 /* x8 (A) + x4 (B) + x4 (C+D ganged) */ +#define QMP_PCIE_NORD_MODE_X8_X4_X2_X2 3 /* x8 (A) + x4 (B) + x2 (C) + x2 (D) */ + #endif /* _DT_BINDINGS_PHY_QMP */